Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/kernel.c

    rafd550c rde6319f  
    5656// volatile thread_local unsigned short disable_preempt_count = 1;
    5757
    58 thread_local struct KernelThreadData kernelTLS = {
     58thread_local struct KernelThreadData kernelThreadData = {
    5959        NULL,
    6060        NULL,
     
    155155                terminate(&this);
    156156                verify(this.do_terminate);
    157                 verify( kernelTLS.this_processor != &this);
     157                verify(TL_GET( this_processor ) != &this);
    158158                P( terminated );
    159                 verify( kernelTLS.this_processor != &this);
     159                verify(TL_GET( this_processor ) != &this);
    160160                pthread_join( kernel_thread, NULL );
    161161        }
     
    196196                        if(readyThread)
    197197                        {
    198                                 verify( ! kernelTLS.preemption_state.enabled );
     198                                verify( ! TL_GET( preemption_state ).enabled );
    199199
    200200                                runThread(this, readyThread);
    201201
    202                                 verify( ! kernelTLS.preemption_state.enabled );
     202                                verify( ! TL_GET( preemption_state ).enabled );
    203203
    204204                                //Some actions need to be taken from the kernel
     
    221221}
    222222
    223 // KERNEL ONLY
    224223// runThread runs a thread by context switching
    225224// from the processor coroutine to the target thread
     
    229228        coroutine_desc * thrd_cor = dst->curr_cor;
    230229
    231         // Reset the terminating actions here
     230        //Reset the terminating actions here
    232231        this->finish.action_code = No_Action;
    233232
    234         // Update global state
    235         kernelTLS.this_thread = dst;
     233        //Update global state
     234        TL_SET( this_thread, dst );
    236235
    237236        // Context Switch to the thread
     
    240239}
    241240
    242 // KERNEL_ONLY
    243241void returnToKernel() {
    244         coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
    245         coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine;
     242        coroutine_desc * proc_cor = get_coroutine(TL_GET( this_processor )->runner);
     243        coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );
    246244        ThreadCtxSwitch(thrd_cor, proc_cor);
    247245}
    248246
    249 // KERNEL_ONLY
    250247// Once a thread has finished running, some of
    251248// its final actions must be executed from the kernel
    252249void finishRunning(processor * this) with( this->finish ) {
    253250        if( action_code == Release ) {
    254                 verify( ! kernelTLS.preemption_state.enabled );
     251                verify( ! TL_GET( preemption_state ).enabled );
    255252                unlock( *lock );
    256253        }
     
    259256        }
    260257        else if( action_code == Release_Schedule ) {
    261                 verify( ! kernelTLS.preemption_state.enabled );
     258                verify( ! TL_GET( preemption_state ).enabled );
    262259                unlock( *lock );
    263260                ScheduleThread( thrd );
    264261        }
    265262        else if( action_code == Release_Multi ) {
    266                 verify( ! kernelTLS.preemption_state.enabled );
     263                verify( ! TL_GET( preemption_state ).enabled );
    267264                for(int i = 0; i < lock_count; i++) {
    268265                        unlock( *locks[i] );
     
    288285}
    289286
    290 // KERNEL_ONLY
    291287// Context invoker for processors
    292288// This is the entry point for processors (kernel threads)
     
    294290void * CtxInvokeProcessor(void * arg) {
    295291        processor * proc = (processor *) arg;
    296         kernelTLS.this_processor = proc;
    297         kernelTLS.this_coroutine = NULL;
    298         kernelTLS.this_thread    = NULL;
    299         kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
     292        TL_SET( this_processor, proc );
     293        TL_SET( this_coroutine, NULL );
     294        TL_SET( this_thread, NULL );
     295        TL_GET( preemption_state ).[enabled, disable_count] = [false, 1];
    300296        // SKULLDUGGERY: We want to create a context for the processor coroutine
    301297        // which is needed for the 2-step context switch. However, there is no reason
     
    309305
    310306        //Set global state
    311         kernelTLS.this_coroutine = get_coroutine(proc->runner);
    312         kernelTLS.this_thread    = NULL;
     307        TL_SET( this_coroutine, get_coroutine(proc->runner) );
     308        TL_SET( this_thread, NULL );
    313309
    314310        //We now have a proper context from which to schedule threads
     
    337333}
    338334
    339 // KERNEL_ONLY
    340335void kernel_first_resume(processor * this) {
    341         coroutine_desc * src = kernelTLS.this_coroutine;
     336        coroutine_desc * src = TL_GET( this_coroutine );
    342337        coroutine_desc * dst = get_coroutine(this->runner);
    343338
    344         verify( ! kernelTLS.preemption_state.enabled );
     339        verify( ! TL_GET( preemption_state ).enabled );
    345340
    346341        create_stack(&dst->stack, dst->stack.size);
    347342        CtxStart(&this->runner, CtxInvokeCoroutine);
    348343
    349         verify( ! kernelTLS.preemption_state.enabled );
     344        verify( ! TL_GET( preemption_state ).enabled );
    350345
    351346        dst->last = src;
     
    356351
    357352        // set new coroutine that task is executing
    358         kernelTLS.this_coroutine = dst;
     353        TL_SET( this_coroutine, dst );
    359354
    360355        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    373368        src->state = Active;
    374369
    375         verify( ! kernelTLS.preemption_state.enabled );
     370        verify( ! TL_GET( preemption_state ).enabled );
    376371}
    377372
    378373//-----------------------------------------------------------------------------
    379374// Scheduler routines
    380 
    381 // KERNEL ONLY
    382375void ScheduleThread( thread_desc * thrd ) {
     376        // if( ! thrd ) return;
    383377        verify( thrd );
    384378        verify( thrd->self_cor.state != Halted );
    385379
    386         verify( ! kernelTLS.preemption_state.enabled );
     380        verify( ! TL_GET( preemption_state ).enabled );
    387381
    388382        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
     
    394388        }
    395389
    396         verify( ! kernelTLS.preemption_state.enabled );
    397 }
    398 
    399 // KERNEL ONLY
     390        verify( ! TL_GET( preemption_state ).enabled );
     391}
     392
    400393thread_desc * nextThread(cluster * this) with( *this ) {
    401         verify( ! kernelTLS.preemption_state.enabled );
     394        verify( ! TL_GET( preemption_state ).enabled );
    402395        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    403396        thread_desc * head = pop_head( ready_queue );
    404397        unlock( ready_queue_lock );
    405         verify( ! kernelTLS.preemption_state.enabled );
     398        verify( ! TL_GET( preemption_state ).enabled );
    406399        return head;
    407400}
     
    409402void BlockInternal() {
    410403        disable_interrupts();
    411         verify( ! kernelTLS.preemption_state.enabled );
     404        verify( ! TL_GET( preemption_state ).enabled );
    412405        returnToKernel();
    413         verify( ! kernelTLS.preemption_state.enabled );
     406        verify( ! TL_GET( preemption_state ).enabled );
    414407        enable_interrupts( __cfaabi_dbg_ctx );
    415408}
     
    417410void BlockInternal( __spinlock_t * lock ) {
    418411        disable_interrupts();
    419         with( *kernelTLS.this_processor ) {
     412        with( *TL_GET( this_processor ) ) {
    420413                finish.action_code = Release;
    421414                finish.lock        = lock;
    422415        }
    423416
    424         verify( ! kernelTLS.preemption_state.enabled );
     417        verify( ! TL_GET( preemption_state ).enabled );
    425418        returnToKernel();
    426         verify( ! kernelTLS.preemption_state.enabled );
     419        verify( ! TL_GET( preemption_state ).enabled );
    427420
    428421        enable_interrupts( __cfaabi_dbg_ctx );
     
    431424void BlockInternal( thread_desc * thrd ) {
    432425        disable_interrupts();
    433         with( * kernelTLS.this_processor ) {
     426        with( *TL_GET( this_processor ) ) {
    434427                finish.action_code = Schedule;
    435428                finish.thrd        = thrd;
    436429        }
    437430
    438         verify( ! kernelTLS.preemption_state.enabled );
     431        verify( ! TL_GET( preemption_state ).enabled );
    439432        returnToKernel();
    440         verify( ! kernelTLS.preemption_state.enabled );
     433        verify( ! TL_GET( preemption_state ).enabled );
    441434
    442435        enable_interrupts( __cfaabi_dbg_ctx );
     
    446439        assert(thrd);
    447440        disable_interrupts();
    448         with( * kernelTLS.this_processor ) {
     441        with( *TL_GET( this_processor ) ) {
    449442                finish.action_code = Release_Schedule;
    450443                finish.lock        = lock;
     
    452445        }
    453446
    454         verify( ! kernelTLS.preemption_state.enabled );
     447        verify( ! TL_GET( preemption_state ).enabled );
    455448        returnToKernel();
    456         verify( ! kernelTLS.preemption_state.enabled );
     449        verify( ! TL_GET( preemption_state ).enabled );
    457450
    458451        enable_interrupts( __cfaabi_dbg_ctx );
     
    461454void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    462455        disable_interrupts();
    463         with( * kernelTLS.this_processor ) {
     456        with( *TL_GET( this_processor ) ) {
    464457                finish.action_code = Release_Multi;
    465458                finish.locks       = locks;
     
    467460        }
    468461
    469         verify( ! kernelTLS.preemption_state.enabled );
     462        verify( ! TL_GET( preemption_state ).enabled );
    470463        returnToKernel();
    471         verify( ! kernelTLS.preemption_state.enabled );
     464        verify( ! TL_GET( preemption_state ).enabled );
    472465
    473466        enable_interrupts( __cfaabi_dbg_ctx );
     
    476469void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    477470        disable_interrupts();
    478         with( *kernelTLS.this_processor ) {
     471        with( *TL_GET( this_processor ) ) {
    479472                finish.action_code = Release_Multi_Schedule;
    480473                finish.locks       = locks;
     
    484477        }
    485478
    486         verify( ! kernelTLS.preemption_state.enabled );
     479        verify( ! TL_GET( preemption_state ).enabled );
    487480        returnToKernel();
    488         verify( ! kernelTLS.preemption_state.enabled );
     481        verify( ! TL_GET( preemption_state ).enabled );
    489482
    490483        enable_interrupts( __cfaabi_dbg_ctx );
    491484}
    492485
    493 // KERNEL ONLY
    494486void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    495         verify( ! kernelTLS.preemption_state.enabled );
    496         with( * kernelTLS.this_processor ) {
     487        verify( ! TL_GET( preemption_state ).enabled );
     488        with( *TL_GET( this_processor ) ) {
    497489                finish.action_code = thrd ? Release_Schedule : Release;
    498490                finish.lock        = lock;
     
    509501// Kernel boot procedures
    510502void kernel_startup(void) {
    511         verify( ! kernelTLS.preemption_state.enabled );
     503        verify( ! TL_GET( preemption_state ).enabled );
    512504        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    513505
     
    555547
    556548        //initialize the global state variables
    557         kernelTLS.this_processor = mainProcessor;
    558         kernelTLS.this_thread    = mainThread;
    559         kernelTLS.this_coroutine = &mainThread->self_cor;
     549        TL_SET( this_processor, mainProcessor );
     550        TL_SET( this_thread, mainThread );
     551        TL_SET( this_coroutine, &mainThread->self_cor );
    560552
    561553        // Enable preemption
     
    569561        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    570562        // mainThread is on the ready queue when this call is made.
    571         kernel_first_resume( kernelTLS.this_processor );
     563        kernel_first_resume( TL_GET( this_processor ) );
    572564
    573565
     
    576568        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    577569
    578         verify( ! kernelTLS.preemption_state.enabled );
     570        verify( ! TL_GET( preemption_state ).enabled );
    579571        enable_interrupts( __cfaabi_dbg_ctx );
    580         verify( TL_GET( preemption_state.enabled ) );
     572        verify( TL_GET( preemption_state ).enabled );
    581573}
    582574
     
    584576        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    585577
    586         verify( TL_GET( preemption_state.enabled ) );
     578        verify( TL_GET( preemption_state ).enabled );
    587579        disable_interrupts();
    588         verify( ! kernelTLS.preemption_state.enabled );
     580        verify( ! TL_GET( preemption_state ).enabled );
    589581
    590582        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    612604
    613605//=============================================================================================
    614 // Kernel Quiescing
    615 //=============================================================================================
    616 
    617 // void halt(processor * this) with( this ) {
    618 //      pthread_mutex_lock( &idle.lock );
    619 
    620 
    621 
    622 //      // SKULLDUGGERY: Even if spurious wake-up is a thing
    623 //      // spuriously waking up a kernel thread is not a big deal
    624 //      // if it is very rare.
    625 //      pthread_cond_wait( &idle.cond, &idle.lock);
    626 //      pthread_mutex_unlock( &idle.lock );
    627 // }
    628 
    629 // void wake(processor * this) with( this ) {
    630 //      pthread_mutex_lock  (&idle.lock);
    631 //      pthread_cond_signal (&idle.cond);
    632 //      pthread_mutex_unlock(&idle.lock);
    633 // }
    634 
    635 //=============================================================================================
    636606// Unexpected Terminating logic
    637607//=============================================================================================
     
    642612static bool kernel_abort_called = false;
    643613
    644 void * kernel_abort(void) __attribute__ ((__nothrow__)) {
     614void * kernel_abort    (void) __attribute__ ((__nothrow__)) {
    645615        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    646616        // the globalAbort flag is true.
     
    663633        }
    664634
    665         return kernelTLS.this_thread;
     635        return TL_GET( this_thread );
    666636}
    667637
     
    672642        __cfaabi_dbg_bits_write( abort_text, len );
    673643
    674         if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) {
    675                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine );
     644        if ( get_coroutine(thrd) != TL_GET( this_coroutine ) ) {
     645                len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", TL_GET( this_coroutine )->name, TL_GET( this_coroutine ) );
    676646                __cfaabi_dbg_bits_write( abort_text, len );
    677647        }
     
    682652
    683653int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    684         return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
     654        return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
    685655}
    686656
     
    712682        if ( count < 0 ) {
    713683                // queue current task
    714                 append( waiting, kernelTLS.this_thread );
     684                append( waiting, (thread_desc *)TL_GET( this_thread ) );
    715685
    716686                // atomically release spin lock and block
     
    772742        void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
    773743                this.prev_name = prev_name;
    774                 this.prev_thrd = kernelTLS.this_thread;
     744                this.prev_thrd = TL_GET( this_thread );
    775745        }
    776746)
Note: See TracChangeset for help on using the changeset viewer.