Ignore:
File:
1 edited

Legend:

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

    rb10affd r094476d  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:26:11 2018
    13 // Update Count     : 23
     12// Last Modified On : Thu Feb  8 23:52:19 2018
     13// Update Count     : 5
    1414//
    1515
     
    5252// Global state
    5353
     54thread_local coroutine_desc * volatile this_coroutine;
     55thread_local thread_desc *    volatile this_thread;
     56thread_local processor *      volatile this_processor;
     57
    5458// volatile thread_local bool preemption_in_progress = 0;
    5559// volatile thread_local bool preemption_enabled = false;
    5660// volatile thread_local unsigned short disable_preempt_count = 1;
    5761
    58 thread_local struct KernelThreadData kernelThreadData = {
    59         NULL,
    60         NULL,
    61         NULL,
    62         { 1, false, false }
    63 };
     62volatile thread_local __cfa_kernel_preemption_state_t preemption_state = { false, false, 1 };
    6463
    6564//-----------------------------------------------------------------------------
     
    173172                terminate(&this);
    174173                verify(this.do_terminate);
    175                 verify(TL_GET( this_processor ) != &this);
     174                verify(this_processor != &this);
    176175                P( terminated );
    177                 verify(TL_GET( this_processor ) != &this);
     176                verify(this_processor != &this);
    178177                pthread_join( kernel_thread, NULL );
    179178        }
     
    214213                        if(readyThread)
    215214                        {
    216                                 verify( ! TL_GET( preemption_state ).enabled );
     215                                verify( !preemption_state.enabled );
    217216
    218217                                runThread(this, readyThread);
    219218
    220                                 verify( ! TL_GET( preemption_state ).enabled );
     219                                verify( !preemption_state.enabled );
    221220
    222221                                //Some actions need to be taken from the kernel
     
    250249
    251250        //Update global state
    252         TL_SET( this_thread, dst );
     251        this_thread = dst;
    253252
    254253        // Context Switch to the thread
     
    258257
    259258void returnToKernel() {
    260         coroutine_desc * proc_cor = get_coroutine(TL_GET( this_processor )->runner);
    261         coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );
     259        coroutine_desc * proc_cor = get_coroutine(this_processor->runner);
     260        coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine;
    262261        ThreadCtxSwitch(thrd_cor, proc_cor);
    263262}
     
    267266void finishRunning(processor * this) with( this->finish ) {
    268267        if( action_code == Release ) {
    269                 verify( ! TL_GET( preemption_state ).enabled );
     268                verify( !preemption_state.enabled );
    270269                unlock( *lock );
    271270        }
     
    274273        }
    275274        else if( action_code == Release_Schedule ) {
    276                 verify( ! TL_GET( preemption_state ).enabled );
     275                verify( !preemption_state.enabled );
    277276                unlock( *lock );
    278277                ScheduleThread( thrd );
    279278        }
    280279        else if( action_code == Release_Multi ) {
    281                 verify( ! TL_GET( preemption_state ).enabled );
     280                verify( !preemption_state.enabled );
    282281                for(int i = 0; i < lock_count; i++) {
    283282                        unlock( *locks[i] );
     
    308307void * CtxInvokeProcessor(void * arg) {
    309308        processor * proc = (processor *) arg;
    310         TL_SET( this_processor, proc );
    311         TL_SET( this_coroutine, NULL );
    312         TL_SET( this_thread, NULL );
    313         TL_GET( preemption_state ).enabled = false;
    314         TL_GET( preemption_state ).disable_count = 1;
     309        this_processor = proc;
     310        this_coroutine = NULL;
     311        this_thread = NULL;
     312        preemption_state.enabled = false;
     313        preemption_state.disable_count = 1;
    315314        // SKULLDUGGERY: We want to create a context for the processor coroutine
    316315        // which is needed for the 2-step context switch. However, there is no reason
     
    324323
    325324        //Set global state
    326         TL_SET( this_coroutine, get_coroutine(proc->runner) );
    327         TL_SET( this_thread, NULL );
     325        this_coroutine = get_coroutine(proc->runner);
     326        this_thread = NULL;
    328327
    329328        //We now have a proper context from which to schedule threads
     
    353352
    354353void kernel_first_resume(processor * this) {
    355         coroutine_desc * src = TL_GET( this_coroutine );
     354        coroutine_desc * src = this_coroutine;
    356355        coroutine_desc * dst = get_coroutine(this->runner);
    357356
    358         verify( ! TL_GET( preemption_state ).enabled );
     357        verify( !preemption_state.enabled );
    359358
    360359        create_stack(&dst->stack, dst->stack.size);
    361360        CtxStart(&this->runner, CtxInvokeCoroutine);
    362361
    363         verify( ! TL_GET( preemption_state ).enabled );
     362        verify( !preemption_state.enabled );
    364363
    365364        dst->last = src;
     
    370369
    371370        // set new coroutine that task is executing
    372         TL_SET( this_coroutine, dst );
     371        this_coroutine = dst;
    373372
    374373        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    387386        src->state = Active;
    388387
    389         verify( ! TL_GET( preemption_state ).enabled );
     388        verify( !preemption_state.enabled );
    390389}
    391390
     
    393392// Scheduler routines
    394393void ScheduleThread( thread_desc * thrd ) {
    395         // if( ! thrd ) return;
     394        // if( !thrd ) return;
    396395        verify( thrd );
    397396        verify( thrd->self_cor.state != Halted );
    398397
    399         verify( ! TL_GET( preemption_state ).enabled );
     398        verify( !preemption_state.enabled );
    400399
    401400        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    402401
    403         with( *TL_GET( this_processor )->cltr ) {
     402        with( *this_processor->cltr ) {
    404403                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    405404                append( ready_queue, thrd );
     
    407406        }
    408407
    409         verify( ! TL_GET( preemption_state ).enabled );
     408        verify( !preemption_state.enabled );
    410409}
    411410
    412411thread_desc * nextThread(cluster * this) with( *this ) {
    413         verify( ! TL_GET( preemption_state ).enabled );
     412        verify( !preemption_state.enabled );
    414413        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    415414        thread_desc * head = pop_head( ready_queue );
    416415        unlock( ready_queue_lock );
    417         verify( ! TL_GET( preemption_state ).enabled );
     416        verify( !preemption_state.enabled );
    418417        return head;
    419418}
     
    421420void BlockInternal() {
    422421        disable_interrupts();
    423         verify( ! TL_GET( preemption_state ).enabled );
     422        verify( !preemption_state.enabled );
    424423        returnToKernel();
    425         verify( ! TL_GET( preemption_state ).enabled );
     424        verify( !preemption_state.enabled );
    426425        enable_interrupts( __cfaabi_dbg_ctx );
    427426}
     
    429428void BlockInternal( __spinlock_t * lock ) {
    430429        disable_interrupts();
    431         TL_GET( this_processor )->finish.action_code = Release;
    432         TL_GET( this_processor )->finish.lock        = lock;
    433 
    434         verify( ! TL_GET( preemption_state ).enabled );
     430        this_processor->finish.action_code = Release;
     431        this_processor->finish.lock        = lock;
     432
     433        verify( !preemption_state.enabled );
    435434        returnToKernel();
    436         verify( ! TL_GET( preemption_state ).enabled );
     435        verify( !preemption_state.enabled );
    437436
    438437        enable_interrupts( __cfaabi_dbg_ctx );
     
    441440void BlockInternal( thread_desc * thrd ) {
    442441        disable_interrupts();
    443         TL_GET( this_processor )->finish.action_code = Schedule;
    444         TL_GET( this_processor )->finish.thrd        = thrd;
    445 
    446         verify( ! TL_GET( preemption_state ).enabled );
     442        this_processor->finish.action_code = Schedule;
     443        this_processor->finish.thrd        = thrd;
     444
     445        verify( !preemption_state.enabled );
    447446        returnToKernel();
    448         verify( ! TL_GET( preemption_state ).enabled );
     447        verify( !preemption_state.enabled );
    449448
    450449        enable_interrupts( __cfaabi_dbg_ctx );
     
    454453        assert(thrd);
    455454        disable_interrupts();
    456         TL_GET( this_processor )->finish.action_code = Release_Schedule;
    457         TL_GET( this_processor )->finish.lock        = lock;
    458         TL_GET( this_processor )->finish.thrd        = thrd;
    459 
    460         verify( ! TL_GET( preemption_state ).enabled );
     455        this_processor->finish.action_code = Release_Schedule;
     456        this_processor->finish.lock        = lock;
     457        this_processor->finish.thrd        = thrd;
     458
     459        verify( !preemption_state.enabled );
    461460        returnToKernel();
    462         verify( ! TL_GET( preemption_state ).enabled );
     461        verify( !preemption_state.enabled );
    463462
    464463        enable_interrupts( __cfaabi_dbg_ctx );
     
    467466void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    468467        disable_interrupts();
    469         TL_GET( this_processor )->finish.action_code = Release_Multi;
    470         TL_GET( this_processor )->finish.locks       = locks;
    471         TL_GET( this_processor )->finish.lock_count  = count;
    472 
    473         verify( ! TL_GET( preemption_state ).enabled );
     468        this_processor->finish.action_code = Release_Multi;
     469        this_processor->finish.locks       = locks;
     470        this_processor->finish.lock_count  = count;
     471
     472        verify( !preemption_state.enabled );
    474473        returnToKernel();
    475         verify( ! TL_GET( preemption_state ).enabled );
     474        verify( !preemption_state.enabled );
    476475
    477476        enable_interrupts( __cfaabi_dbg_ctx );
     
    480479void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    481480        disable_interrupts();
    482         TL_GET( this_processor )->finish.action_code = Release_Multi_Schedule;
    483         TL_GET( this_processor )->finish.locks       = locks;
    484         TL_GET( this_processor )->finish.lock_count  = lock_count;
    485         TL_GET( this_processor )->finish.thrds       = thrds;
    486         TL_GET( this_processor )->finish.thrd_count  = thrd_count;
    487 
    488         verify( ! TL_GET( preemption_state ).enabled );
     481        this_processor->finish.action_code = Release_Multi_Schedule;
     482        this_processor->finish.locks       = locks;
     483        this_processor->finish.lock_count  = lock_count;
     484        this_processor->finish.thrds       = thrds;
     485        this_processor->finish.thrd_count  = thrd_count;
     486
     487        verify( !preemption_state.enabled );
    489488        returnToKernel();
    490         verify( ! TL_GET( preemption_state ).enabled );
     489        verify( !preemption_state.enabled );
    491490
    492491        enable_interrupts( __cfaabi_dbg_ctx );
     
    494493
    495494void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    496         verify( ! TL_GET( preemption_state ).enabled );
    497         TL_GET( this_processor )->finish.action_code = thrd ? Release_Schedule : Release;
    498         TL_GET( this_processor )->finish.lock        = lock;
    499         TL_GET( this_processor )->finish.thrd        = thrd;
     495        verify( !preemption_state.enabled );
     496        this_processor->finish.action_code = thrd ? Release_Schedule : Release;
     497        this_processor->finish.lock        = lock;
     498        this_processor->finish.thrd        = thrd;
    500499
    501500        returnToKernel();
     
    508507// Kernel boot procedures
    509508void kernel_startup(void) {
    510         verify( ! TL_GET( preemption_state ).enabled );
     509        verify( !preemption_state.enabled );
    511510        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    512511
     
    532531
    533532        //initialize the global state variables
    534         TL_SET( this_processor, mainProcessor );
    535         TL_SET( this_thread, mainThread );
    536         TL_SET( this_coroutine, &mainThread->self_cor );
     533        this_processor = mainProcessor;
     534        this_thread = mainThread;
     535        this_coroutine = &mainThread->self_cor;
    537536
    538537        // Enable preemption
     
    546545        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    547546        // mainThread is on the ready queue when this call is made.
    548         kernel_first_resume( TL_GET( this_processor ) );
     547        kernel_first_resume( this_processor );
    549548
    550549
     
    553552        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    554553
    555         verify( ! TL_GET( preemption_state ).enabled );
     554        verify( !preemption_state.enabled );
    556555        enable_interrupts( __cfaabi_dbg_ctx );
    557         verify( TL_GET( preemption_state ).enabled );
     556        verify( preemption_state.enabled );
    558557}
    559558
     
    561560        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    562561
    563         verify( TL_GET( preemption_state ).enabled );
     562        verify( preemption_state.enabled );
    564563        disable_interrupts();
    565         verify( ! TL_GET( preemption_state ).enabled );
     564        verify( !preemption_state.enabled );
    566565
    567566        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    603602
    604603        // first task to abort ?
    605         if ( ! kernel_abort_called ) {                  // not first task to abort ?
     604        if ( !kernel_abort_called ) {                   // not first task to abort ?
    606605                kernel_abort_called = true;
    607606                unlock( kernel_abort_lock );
     
    618617        }
    619618
    620         return TL_GET( this_thread );
     619        return this_thread;
    621620}
    622621
     
    627626        __cfaabi_dbg_bits_write( abort_text, len );
    628627
    629         if ( thrd != TL_GET( this_coroutine ) ) {
    630                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", TL_GET( this_coroutine )->name, TL_GET( this_coroutine ) );
     628        if ( thrd != this_coroutine ) {
     629                len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
    631630                __cfaabi_dbg_bits_write( abort_text, len );
    632631        }
     
    637636
    638637int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    639         return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
     638        return get_coroutine(this_thread) == get_coroutine(mainThread) ? 4 : 2;
    640639}
    641640
     
    667666        if ( count < 0 ) {
    668667                // queue current task
    669                 append( waiting, (thread_desc *)TL_GET( this_thread ) );
     668                append( waiting, (thread_desc *)this_thread );
    670669
    671670                // atomically release spin lock and block
Note: See TracChangeset for help on using the changeset viewer.