Ignore:
File:
1 edited

Legend:

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

    r094476d rb10affd  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  8 23:52:19 2018
    13 // Update Count     : 5
     12// Last Modified On : Fri Mar 30 18:26:11 2018
     13// Update Count     : 23
    1414//
    1515
     
    5252// Global state
    5353
    54 thread_local coroutine_desc * volatile this_coroutine;
    55 thread_local thread_desc *    volatile this_thread;
    56 thread_local processor *      volatile this_processor;
    57 
    5854// volatile thread_local bool preemption_in_progress = 0;
    5955// volatile thread_local bool preemption_enabled = false;
    6056// volatile thread_local unsigned short disable_preempt_count = 1;
    6157
    62 volatile thread_local __cfa_kernel_preemption_state_t preemption_state = { false, false, 1 };
     58thread_local struct KernelThreadData kernelThreadData = {
     59        NULL,
     60        NULL,
     61        NULL,
     62        { 1, false, false }
     63};
    6364
    6465//-----------------------------------------------------------------------------
     
    172173                terminate(&this);
    173174                verify(this.do_terminate);
    174                 verify(this_processor != &this);
     175                verify(TL_GET( this_processor ) != &this);
    175176                P( terminated );
    176                 verify(this_processor != &this);
     177                verify(TL_GET( this_processor ) != &this);
    177178                pthread_join( kernel_thread, NULL );
    178179        }
     
    213214                        if(readyThread)
    214215                        {
    215                                 verify( !preemption_state.enabled );
     216                                verify( ! TL_GET( preemption_state ).enabled );
    216217
    217218                                runThread(this, readyThread);
    218219
    219                                 verify( !preemption_state.enabled );
     220                                verify( ! TL_GET( preemption_state ).enabled );
    220221
    221222                                //Some actions need to be taken from the kernel
     
    249250
    250251        //Update global state
    251         this_thread = dst;
     252        TL_SET( this_thread, dst );
    252253
    253254        // Context Switch to the thread
     
    257258
    258259void returnToKernel() {
    259         coroutine_desc * proc_cor = get_coroutine(this_processor->runner);
    260         coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine;
     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 );
    261262        ThreadCtxSwitch(thrd_cor, proc_cor);
    262263}
     
    266267void finishRunning(processor * this) with( this->finish ) {
    267268        if( action_code == Release ) {
    268                 verify( !preemption_state.enabled );
     269                verify( ! TL_GET( preemption_state ).enabled );
    269270                unlock( *lock );
    270271        }
     
    273274        }
    274275        else if( action_code == Release_Schedule ) {
    275                 verify( !preemption_state.enabled );
     276                verify( ! TL_GET( preemption_state ).enabled );
    276277                unlock( *lock );
    277278                ScheduleThread( thrd );
    278279        }
    279280        else if( action_code == Release_Multi ) {
    280                 verify( !preemption_state.enabled );
     281                verify( ! TL_GET( preemption_state ).enabled );
    281282                for(int i = 0; i < lock_count; i++) {
    282283                        unlock( *locks[i] );
     
    307308void * CtxInvokeProcessor(void * arg) {
    308309        processor * proc = (processor *) arg;
    309         this_processor = proc;
    310         this_coroutine = NULL;
    311         this_thread = NULL;
    312         preemption_state.enabled = false;
    313         preemption_state.disable_count = 1;
     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;
    314315        // SKULLDUGGERY: We want to create a context for the processor coroutine
    315316        // which is needed for the 2-step context switch. However, there is no reason
     
    323324
    324325        //Set global state
    325         this_coroutine = get_coroutine(proc->runner);
    326         this_thread = NULL;
     326        TL_SET( this_coroutine, get_coroutine(proc->runner) );
     327        TL_SET( this_thread, NULL );
    327328
    328329        //We now have a proper context from which to schedule threads
     
    352353
    353354void kernel_first_resume(processor * this) {
    354         coroutine_desc * src = this_coroutine;
     355        coroutine_desc * src = TL_GET( this_coroutine );
    355356        coroutine_desc * dst = get_coroutine(this->runner);
    356357
    357         verify( !preemption_state.enabled );
     358        verify( ! TL_GET( preemption_state ).enabled );
    358359
    359360        create_stack(&dst->stack, dst->stack.size);
    360361        CtxStart(&this->runner, CtxInvokeCoroutine);
    361362
    362         verify( !preemption_state.enabled );
     363        verify( ! TL_GET( preemption_state ).enabled );
    363364
    364365        dst->last = src;
     
    369370
    370371        // set new coroutine that task is executing
    371         this_coroutine = dst;
     372        TL_SET( this_coroutine, dst );
    372373
    373374        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    386387        src->state = Active;
    387388
    388         verify( !preemption_state.enabled );
     389        verify( ! TL_GET( preemption_state ).enabled );
    389390}
    390391
     
    392393// Scheduler routines
    393394void ScheduleThread( thread_desc * thrd ) {
    394         // if( !thrd ) return;
     395        // if( ! thrd ) return;
    395396        verify( thrd );
    396397        verify( thrd->self_cor.state != Halted );
    397398
    398         verify( !preemption_state.enabled );
     399        verify( ! TL_GET( preemption_state ).enabled );
    399400
    400401        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    401402
    402         with( *this_processor->cltr ) {
     403        with( *TL_GET( this_processor )->cltr ) {
    403404                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    404405                append( ready_queue, thrd );
     
    406407        }
    407408
    408         verify( !preemption_state.enabled );
     409        verify( ! TL_GET( preemption_state ).enabled );
    409410}
    410411
    411412thread_desc * nextThread(cluster * this) with( *this ) {
    412         verify( !preemption_state.enabled );
     413        verify( ! TL_GET( preemption_state ).enabled );
    413414        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    414415        thread_desc * head = pop_head( ready_queue );
    415416        unlock( ready_queue_lock );
    416         verify( !preemption_state.enabled );
     417        verify( ! TL_GET( preemption_state ).enabled );
    417418        return head;
    418419}
     
    420421void BlockInternal() {
    421422        disable_interrupts();
    422         verify( !preemption_state.enabled );
     423        verify( ! TL_GET( preemption_state ).enabled );
    423424        returnToKernel();
    424         verify( !preemption_state.enabled );
     425        verify( ! TL_GET( preemption_state ).enabled );
    425426        enable_interrupts( __cfaabi_dbg_ctx );
    426427}
     
    428429void BlockInternal( __spinlock_t * lock ) {
    429430        disable_interrupts();
    430         this_processor->finish.action_code = Release;
    431         this_processor->finish.lock        = lock;
    432 
    433         verify( !preemption_state.enabled );
     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 );
    434435        returnToKernel();
    435         verify( !preemption_state.enabled );
     436        verify( ! TL_GET( preemption_state ).enabled );
    436437
    437438        enable_interrupts( __cfaabi_dbg_ctx );
     
    440441void BlockInternal( thread_desc * thrd ) {
    441442        disable_interrupts();
    442         this_processor->finish.action_code = Schedule;
    443         this_processor->finish.thrd        = thrd;
    444 
    445         verify( !preemption_state.enabled );
     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 );
    446447        returnToKernel();
    447         verify( !preemption_state.enabled );
     448        verify( ! TL_GET( preemption_state ).enabled );
    448449
    449450        enable_interrupts( __cfaabi_dbg_ctx );
     
    453454        assert(thrd);
    454455        disable_interrupts();
    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 );
     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 );
    460461        returnToKernel();
    461         verify( !preemption_state.enabled );
     462        verify( ! TL_GET( preemption_state ).enabled );
    462463
    463464        enable_interrupts( __cfaabi_dbg_ctx );
     
    466467void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    467468        disable_interrupts();
    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 );
     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 );
    473474        returnToKernel();
    474         verify( !preemption_state.enabled );
     475        verify( ! TL_GET( preemption_state ).enabled );
    475476
    476477        enable_interrupts( __cfaabi_dbg_ctx );
     
    479480void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    480481        disable_interrupts();
    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 );
     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 );
    488489        returnToKernel();
    489         verify( !preemption_state.enabled );
     490        verify( ! TL_GET( preemption_state ).enabled );
    490491
    491492        enable_interrupts( __cfaabi_dbg_ctx );
     
    493494
    494495void LeaveThread(__spinlock_t * lock, thread_desc * 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;
     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;
    499500
    500501        returnToKernel();
     
    507508// Kernel boot procedures
    508509void kernel_startup(void) {
    509         verify( !preemption_state.enabled );
     510        verify( ! TL_GET( preemption_state ).enabled );
    510511        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    511512
     
    531532
    532533        //initialize the global state variables
    533         this_processor = mainProcessor;
    534         this_thread = mainThread;
    535         this_coroutine = &mainThread->self_cor;
     534        TL_SET( this_processor, mainProcessor );
     535        TL_SET( this_thread, mainThread );
     536        TL_SET( this_coroutine, &mainThread->self_cor );
    536537
    537538        // Enable preemption
     
    545546        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    546547        // mainThread is on the ready queue when this call is made.
    547         kernel_first_resume( this_processor );
     548        kernel_first_resume( TL_GET( this_processor ) );
    548549
    549550
     
    552553        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    553554
    554         verify( !preemption_state.enabled );
     555        verify( ! TL_GET( preemption_state ).enabled );
    555556        enable_interrupts( __cfaabi_dbg_ctx );
    556         verify( preemption_state.enabled );
     557        verify( TL_GET( preemption_state ).enabled );
    557558}
    558559
     
    560561        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    561562
    562         verify( preemption_state.enabled );
     563        verify( TL_GET( preemption_state ).enabled );
    563564        disable_interrupts();
    564         verify( !preemption_state.enabled );
     565        verify( ! TL_GET( preemption_state ).enabled );
    565566
    566567        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    602603
    603604        // first task to abort ?
    604         if ( !kernel_abort_called ) {                   // not first task to abort ?
     605        if ( ! kernel_abort_called ) {                  // not first task to abort ?
    605606                kernel_abort_called = true;
    606607                unlock( kernel_abort_lock );
     
    617618        }
    618619
    619         return this_thread;
     620        return TL_GET( this_thread );
    620621}
    621622
     
    626627        __cfaabi_dbg_bits_write( abort_text, len );
    627628
    628         if ( thrd != this_coroutine ) {
    629                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
     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 ) );
    630631                __cfaabi_dbg_bits_write( abort_text, len );
    631632        }
     
    636637
    637638int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    638         return get_coroutine(this_thread) == get_coroutine(mainThread) ? 4 : 2;
     639        return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
    639640}
    640641
     
    666667        if ( count < 0 ) {
    667668                // queue current task
    668                 append( waiting, (thread_desc *)this_thread );
     669                append( waiting, (thread_desc *)TL_GET( this_thread ) );
    669670
    670671                // atomically release spin lock and block
Note: See TracChangeset for help on using the changeset viewer.