Ignore:
File:
1 edited

Legend:

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

    rde6319f rafd550c  
    5656// volatile thread_local unsigned short disable_preempt_count = 1;
    5757
    58 thread_local struct KernelThreadData kernelThreadData = {
     58thread_local struct KernelThreadData kernelTLS = {
    5959        NULL,
    6060        NULL,
     
    155155                terminate(&this);
    156156                verify(this.do_terminate);
    157                 verify(TL_GET( this_processor ) != &this);
     157                verify( kernelTLS.this_processor != &this);
    158158                P( terminated );
    159                 verify(TL_GET( this_processor ) != &this);
     159                verify( kernelTLS.this_processor != &this);
    160160                pthread_join( kernel_thread, NULL );
    161161        }
     
    196196                        if(readyThread)
    197197                        {
    198                                 verify( ! TL_GET( preemption_state ).enabled );
     198                                verify( ! kernelTLS.preemption_state.enabled );
    199199
    200200                                runThread(this, readyThread);
    201201
    202                                 verify( ! TL_GET( preemption_state ).enabled );
     202                                verify( ! kernelTLS.preemption_state.enabled );
    203203
    204204                                //Some actions need to be taken from the kernel
     
    221221}
    222222
     223// KERNEL ONLY
    223224// runThread runs a thread by context switching
    224225// from the processor coroutine to the target thread
     
    228229        coroutine_desc * thrd_cor = dst->curr_cor;
    229230
    230         //Reset the terminating actions here
     231        // Reset the terminating actions here
    231232        this->finish.action_code = No_Action;
    232233
    233         //Update global state
    234         TL_SET( this_thread, dst );
     234        // Update global state
     235        kernelTLS.this_thread = dst;
    235236
    236237        // Context Switch to the thread
     
    239240}
    240241
     242// KERNEL_ONLY
    241243void returnToKernel() {
    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 );
     244        coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
     245        coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine;
    244246        ThreadCtxSwitch(thrd_cor, proc_cor);
    245247}
    246248
     249// KERNEL_ONLY
    247250// Once a thread has finished running, some of
    248251// its final actions must be executed from the kernel
    249252void finishRunning(processor * this) with( this->finish ) {
    250253        if( action_code == Release ) {
    251                 verify( ! TL_GET( preemption_state ).enabled );
     254                verify( ! kernelTLS.preemption_state.enabled );
    252255                unlock( *lock );
    253256        }
     
    256259        }
    257260        else if( action_code == Release_Schedule ) {
    258                 verify( ! TL_GET( preemption_state ).enabled );
     261                verify( ! kernelTLS.preemption_state.enabled );
    259262                unlock( *lock );
    260263                ScheduleThread( thrd );
    261264        }
    262265        else if( action_code == Release_Multi ) {
    263                 verify( ! TL_GET( preemption_state ).enabled );
     266                verify( ! kernelTLS.preemption_state.enabled );
    264267                for(int i = 0; i < lock_count; i++) {
    265268                        unlock( *locks[i] );
     
    285288}
    286289
     290// KERNEL_ONLY
    287291// Context invoker for processors
    288292// This is the entry point for processors (kernel threads)
     
    290294void * CtxInvokeProcessor(void * arg) {
    291295        processor * proc = (processor *) arg;
    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];
     296        kernelTLS.this_processor = proc;
     297        kernelTLS.this_coroutine = NULL;
     298        kernelTLS.this_thread    = NULL;
     299        kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
    296300        // SKULLDUGGERY: We want to create a context for the processor coroutine
    297301        // which is needed for the 2-step context switch. However, there is no reason
     
    305309
    306310        //Set global state
    307         TL_SET( this_coroutine, get_coroutine(proc->runner) );
    308         TL_SET( this_thread, NULL );
     311        kernelTLS.this_coroutine = get_coroutine(proc->runner);
     312        kernelTLS.this_thread    = NULL;
    309313
    310314        //We now have a proper context from which to schedule threads
     
    333337}
    334338
     339// KERNEL_ONLY
    335340void kernel_first_resume(processor * this) {
    336         coroutine_desc * src = TL_GET( this_coroutine );
     341        coroutine_desc * src = kernelTLS.this_coroutine;
    337342        coroutine_desc * dst = get_coroutine(this->runner);
    338343
    339         verify( ! TL_GET( preemption_state ).enabled );
     344        verify( ! kernelTLS.preemption_state.enabled );
    340345
    341346        create_stack(&dst->stack, dst->stack.size);
    342347        CtxStart(&this->runner, CtxInvokeCoroutine);
    343348
    344         verify( ! TL_GET( preemption_state ).enabled );
     349        verify( ! kernelTLS.preemption_state.enabled );
    345350
    346351        dst->last = src;
     
    351356
    352357        // set new coroutine that task is executing
    353         TL_SET( this_coroutine, dst );
     358        kernelTLS.this_coroutine = dst;
    354359
    355360        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    368373        src->state = Active;
    369374
    370         verify( ! TL_GET( preemption_state ).enabled );
     375        verify( ! kernelTLS.preemption_state.enabled );
    371376}
    372377
    373378//-----------------------------------------------------------------------------
    374379// Scheduler routines
     380
     381// KERNEL ONLY
    375382void ScheduleThread( thread_desc * thrd ) {
    376         // if( ! thrd ) return;
    377383        verify( thrd );
    378384        verify( thrd->self_cor.state != Halted );
    379385
    380         verify( ! TL_GET( preemption_state ).enabled );
     386        verify( ! kernelTLS.preemption_state.enabled );
    381387
    382388        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
     
    388394        }
    389395
    390         verify( ! TL_GET( preemption_state ).enabled );
    391 }
    392 
     396        verify( ! kernelTLS.preemption_state.enabled );
     397}
     398
     399// KERNEL ONLY
    393400thread_desc * nextThread(cluster * this) with( *this ) {
    394         verify( ! TL_GET( preemption_state ).enabled );
     401        verify( ! kernelTLS.preemption_state.enabled );
    395402        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    396403        thread_desc * head = pop_head( ready_queue );
    397404        unlock( ready_queue_lock );
    398         verify( ! TL_GET( preemption_state ).enabled );
     405        verify( ! kernelTLS.preemption_state.enabled );
    399406        return head;
    400407}
     
    402409void BlockInternal() {
    403410        disable_interrupts();
    404         verify( ! TL_GET( preemption_state ).enabled );
     411        verify( ! kernelTLS.preemption_state.enabled );
    405412        returnToKernel();
    406         verify( ! TL_GET( preemption_state ).enabled );
     413        verify( ! kernelTLS.preemption_state.enabled );
    407414        enable_interrupts( __cfaabi_dbg_ctx );
    408415}
     
    410417void BlockInternal( __spinlock_t * lock ) {
    411418        disable_interrupts();
    412         with( *TL_GET( this_processor ) ) {
     419        with( *kernelTLS.this_processor ) {
    413420                finish.action_code = Release;
    414421                finish.lock        = lock;
    415422        }
    416423
    417         verify( ! TL_GET( preemption_state ).enabled );
     424        verify( ! kernelTLS.preemption_state.enabled );
    418425        returnToKernel();
    419         verify( ! TL_GET( preemption_state ).enabled );
     426        verify( ! kernelTLS.preemption_state.enabled );
    420427
    421428        enable_interrupts( __cfaabi_dbg_ctx );
     
    424431void BlockInternal( thread_desc * thrd ) {
    425432        disable_interrupts();
    426         with( *TL_GET( this_processor ) ) {
     433        with( * kernelTLS.this_processor ) {
    427434                finish.action_code = Schedule;
    428435                finish.thrd        = thrd;
    429436        }
    430437
    431         verify( ! TL_GET( preemption_state ).enabled );
     438        verify( ! kernelTLS.preemption_state.enabled );
    432439        returnToKernel();
    433         verify( ! TL_GET( preemption_state ).enabled );
     440        verify( ! kernelTLS.preemption_state.enabled );
    434441
    435442        enable_interrupts( __cfaabi_dbg_ctx );
     
    439446        assert(thrd);
    440447        disable_interrupts();
    441         with( *TL_GET( this_processor ) ) {
     448        with( * kernelTLS.this_processor ) {
    442449                finish.action_code = Release_Schedule;
    443450                finish.lock        = lock;
     
    445452        }
    446453
    447         verify( ! TL_GET( preemption_state ).enabled );
     454        verify( ! kernelTLS.preemption_state.enabled );
    448455        returnToKernel();
    449         verify( ! TL_GET( preemption_state ).enabled );
     456        verify( ! kernelTLS.preemption_state.enabled );
    450457
    451458        enable_interrupts( __cfaabi_dbg_ctx );
     
    454461void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    455462        disable_interrupts();
    456         with( *TL_GET( this_processor ) ) {
     463        with( * kernelTLS.this_processor ) {
    457464                finish.action_code = Release_Multi;
    458465                finish.locks       = locks;
     
    460467        }
    461468
    462         verify( ! TL_GET( preemption_state ).enabled );
     469        verify( ! kernelTLS.preemption_state.enabled );
    463470        returnToKernel();
    464         verify( ! TL_GET( preemption_state ).enabled );
     471        verify( ! kernelTLS.preemption_state.enabled );
    465472
    466473        enable_interrupts( __cfaabi_dbg_ctx );
     
    469476void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    470477        disable_interrupts();
    471         with( *TL_GET( this_processor ) ) {
     478        with( *kernelTLS.this_processor ) {
    472479                finish.action_code = Release_Multi_Schedule;
    473480                finish.locks       = locks;
     
    477484        }
    478485
    479         verify( ! TL_GET( preemption_state ).enabled );
     486        verify( ! kernelTLS.preemption_state.enabled );
    480487        returnToKernel();
    481         verify( ! TL_GET( preemption_state ).enabled );
     488        verify( ! kernelTLS.preemption_state.enabled );
    482489
    483490        enable_interrupts( __cfaabi_dbg_ctx );
    484491}
    485492
     493// KERNEL ONLY
    486494void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    487         verify( ! TL_GET( preemption_state ).enabled );
    488         with( *TL_GET( this_processor ) ) {
     495        verify( ! kernelTLS.preemption_state.enabled );
     496        with( * kernelTLS.this_processor ) {
    489497                finish.action_code = thrd ? Release_Schedule : Release;
    490498                finish.lock        = lock;
     
    501509// Kernel boot procedures
    502510void kernel_startup(void) {
    503         verify( ! TL_GET( preemption_state ).enabled );
     511        verify( ! kernelTLS.preemption_state.enabled );
    504512        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    505513
     
    547555
    548556        //initialize the global state variables
    549         TL_SET( this_processor, mainProcessor );
    550         TL_SET( this_thread, mainThread );
    551         TL_SET( this_coroutine, &mainThread->self_cor );
     557        kernelTLS.this_processor = mainProcessor;
     558        kernelTLS.this_thread    = mainThread;
     559        kernelTLS.this_coroutine = &mainThread->self_cor;
    552560
    553561        // Enable preemption
     
    561569        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    562570        // mainThread is on the ready queue when this call is made.
    563         kernel_first_resume( TL_GET( this_processor ) );
     571        kernel_first_resume( kernelTLS.this_processor );
    564572
    565573
     
    568576        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    569577
    570         verify( ! TL_GET( preemption_state ).enabled );
     578        verify( ! kernelTLS.preemption_state.enabled );
    571579        enable_interrupts( __cfaabi_dbg_ctx );
    572         verify( TL_GET( preemption_state ).enabled );
     580        verify( TL_GET( preemption_state.enabled ) );
    573581}
    574582
     
    576584        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    577585
    578         verify( TL_GET( preemption_state ).enabled );
     586        verify( TL_GET( preemption_state.enabled ) );
    579587        disable_interrupts();
    580         verify( ! TL_GET( preemption_state ).enabled );
     588        verify( ! kernelTLS.preemption_state.enabled );
    581589
    582590        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    604612
    605613//=============================================================================================
     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//=============================================================================================
    606636// Unexpected Terminating logic
    607637//=============================================================================================
     
    612642static bool kernel_abort_called = false;
    613643
    614 void * kernel_abort    (void) __attribute__ ((__nothrow__)) {
     644void * kernel_abort(void) __attribute__ ((__nothrow__)) {
    615645        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    616646        // the globalAbort flag is true.
     
    633663        }
    634664
    635         return TL_GET( this_thread );
     665        return kernelTLS.this_thread;
    636666}
    637667
     
    642672        __cfaabi_dbg_bits_write( abort_text, len );
    643673
    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 ) );
     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 );
    646676                __cfaabi_dbg_bits_write( abort_text, len );
    647677        }
     
    652682
    653683int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    654         return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
     684        return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
    655685}
    656686
     
    682712        if ( count < 0 ) {
    683713                // queue current task
    684                 append( waiting, (thread_desc *)TL_GET( this_thread ) );
     714                append( waiting, kernelTLS.this_thread );
    685715
    686716                // atomically release spin lock and block
     
    742772        void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
    743773                this.prev_name = prev_name;
    744                 this.prev_thrd = TL_GET( this_thread );
     774                this.prev_thrd = kernelTLS.this_thread;
    745775        }
    746776)
Note: See TracChangeset for help on using the changeset viewer.