Ignore:
File:
1 edited

Legend:

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

    r8c50aed re3fea42  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jan 30 22:55:50 2020
    13 // Update Count     : 56
     12// Last Modified On : Tue Feb  4 13:03:15 2020
     13// Update Count     : 58
    1414//
    1515
     
    110110//-----------------------------------------------------------------------------
    111111//Start and stop routine for the kernel, declared first to make sure they run first
    112 static void __kernel_startup (void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
    113 static void __kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
     112static void kernel_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     113static void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    114114
    115115//-----------------------------------------------------------------------------
     
    208208}
    209209
    210 static void * CtxInvokeProcessor(void * arg);
    211 
    212 void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {
     210static void start(processor * this);
     211void ?{}(processor & this, const char name[], cluster & cltr) with( this ) {
    213212        this.name = name;
    214213        this.cltr = &cltr;
    215214        terminated{ 0 };
    216         destroyer = 0p;
    217215        do_terminate = false;
    218216        preemption_alarm = 0p;
     
    222220        idleLock{};
    223221
    224         __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", &this);
    225 
    226         this.stack = __create_pthread( &this.kernel_thread, CtxInvokeProcessor, (void *)&this );
    227 
    228         __cfaabi_dbg_print_safe("Kernel : core %p started\n", &this);
     222        start( &this );
    229223}
    230224
     
    244238}
    245239
    246 void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) {
     240void ?{}(cluster & this, const char name[], Duration preemption_rate) with( this ) {
    247241        this.name = name;
    248242        this.preemption_rate = preemption_rate;
     
    264258// Kernel Scheduling logic
    265259//=============================================================================================
    266 static thread_desc * __next_thread(cluster * this);
    267 static void __run_thread(processor * this, thread_desc * dst);
    268 static void __halt(processor * this);
     260static void runThread(processor * this, thread_desc * dst);
     261static void finishRunning(processor * this);
     262static void halt(processor * this);
    269263
    270264//Main of the processor contexts
     
    289283                thread_desc * readyThread = 0p;
    290284                for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ ) {
    291                         readyThread = __next_thread( this->cltr );
     285                        readyThread = nextThread( this->cltr );
    292286
    293287                        if(readyThread) {
    294                                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    295                                 /* paranoid */ verifyf( readyThread->state == Inactive || readyThread->state == Start || readyThread->preempted != __NO_PREEMPTION, "state : %d, preempted %d\n", readyThread->state, readyThread->preempted);
    296                                 /* paranoid */ verifyf( readyThread->next == 0p, "Expected null got %p", readyThread->next );
    297 
    298                                 __run_thread(this, readyThread);
    299 
    300                                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     288                                verify( ! kernelTLS.preemption_state.enabled );
     289
     290                                runThread(this, readyThread);
     291
     292                                verify( ! kernelTLS.preemption_state.enabled );
     293
     294                                //Some actions need to be taken from the kernel
     295                                finishRunning(this);
    301296
    302297                                spin_count = 0;
    303298                        } else {
    304299                                // spin(this, &spin_count);
    305                                 __halt(this);
     300                                halt(this);
    306301                        }
    307302                }
     
    323318// runThread runs a thread by context switching
    324319// from the processor coroutine to the target thread
    325 static void __run_thread(processor * this, thread_desc * thrd_dst) {
     320static void runThread(processor * this, thread_desc * thrd_dst) {
    326321        coroutine_desc * proc_cor = get_coroutine(this->runner);
     322
     323        // Reset the terminating actions here
     324        this->finish.action_code = No_Action;
    327325
    328326        // Update global state
    329327        kernelTLS.this_thread = thrd_dst;
    330328
    331         // set state of processor coroutine to inactive
    332         verify(proc_cor->state == Active);
    333         proc_cor->state = Inactive;
    334 
    335         // Actually run the thread
    336         RUNNING:  while(true) {
    337                 if(unlikely(thrd_dst->preempted)) {
    338                         thrd_dst->preempted = __NO_PREEMPTION;
    339                         verify(thrd_dst->state == Active || thrd_dst->state == Rerun);
    340                 } else {
    341                         verify(thrd_dst->state == Start || thrd_dst->state == Primed || thrd_dst->state == Inactive);
    342                         thrd_dst->state = Active;
    343                 }
    344 
    345                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    346 
    347                 // set context switch to the thread that the processor is executing
    348                 verify( thrd_dst->context.SP );
    349                 CtxSwitch( &proc_cor->context, &thrd_dst->context );
    350                 // when CtxSwitch returns we are back in the processor coroutine
    351 
    352                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    353 
    354 
    355                 // We just finished running a thread, there are a few things that could have happened.
    356                 // 1 - Regular case : the thread has blocked and now one has scheduled it yet.
    357                 // 2 - Racy case    : the thread has blocked but someone has already tried to schedule it.
    358                 // 3 - Polite Racy case : the thread has blocked, someone has already tried to schedule it, but the thread is nice and wants to go through the ready-queue any way
    359                 // 4 - Preempted
    360                 // In case 1, we may have won a race so we can't write to the state again.
    361                 // In case 2, we lost the race so we now own the thread.
    362                 // In case 3, we lost the race but can just reschedule the thread.
    363 
    364                 if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
    365                         // The thread was preempted, reschedule it and reset the flag
    366                         __schedule_thread( thrd_dst );
    367                         break RUNNING;
    368                 }
    369 
    370                 // set state of processor coroutine to active and the thread to inactive
    371                 static_assert(sizeof(thrd_dst->state) == sizeof(int));
    372                 enum coroutine_state old_state = __atomic_exchange_n(&thrd_dst->state, Inactive, __ATOMIC_SEQ_CST);
    373                 switch(old_state) {
    374                         case Halted:
    375                                 // The thread has halted, it should never be scheduled/run again, leave it back to Halted and move on
    376                                 thrd_dst->state = Halted;
    377 
    378                                 // We may need to wake someone up here since
    379                                 unpark( this->destroyer );
    380                                 this->destroyer = 0p;
    381                                 break RUNNING;
    382                         case Active:
    383                                 // This is case 1, the regular case, nothing more is needed
    384                                 break RUNNING;
    385                         case Rerun:
    386                                 // This is case 2, the racy case, someone tried to run this thread before it finished blocking
    387                                 // In this case, just run it again.
    388                                 continue RUNNING;
    389                         default:
    390                                 // This makes no sense, something is wrong abort
    391                                 abort("Finished running a thread that was Inactive/Start/Primed %d\n", old_state);
    392                 }
    393         }
    394 
    395         // Just before returning to the processor, set the processor coroutine to active
     329        // set state of processor coroutine to inactive and the thread to active
     330        proc_cor->state = proc_cor->state == Halted ? Halted : Inactive;
     331        thrd_dst->state = Active;
     332
     333        // set context switch to the thread that the processor is executing
     334        verify( thrd_dst->context.SP );
     335        CtxSwitch( &proc_cor->context, &thrd_dst->context );
     336        // when CtxSwitch returns we are back in the processor coroutine
     337
     338        // set state of processor coroutine to active and the thread to inactive
     339        thrd_dst->state = thrd_dst->state == Halted ? Halted : Inactive;
    396340        proc_cor->state = Active;
    397341}
    398342
    399343// KERNEL_ONLY
    400 void returnToKernel() {
    401         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     344static void returnToKernel() {
    402345        coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
    403346        thread_desc * thrd_src = kernelTLS.this_thread;
    404347
    405         // Run the thread on this processor
    406         {
    407                 int local_errno = *__volatile_errno();
    408                 #if defined( __i386 ) || defined( __x86_64 )
    409                         __x87_store;
    410                 #endif
    411                 verify( proc_cor->context.SP );
    412                 CtxSwitch( &thrd_src->context, &proc_cor->context );
    413                 #if defined( __i386 ) || defined( __x86_64 )
    414                         __x87_load;
    415                 #endif
    416                 *__volatile_errno() = local_errno;
    417         }
    418 
    419         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     348        // set state of current coroutine to inactive
     349        thrd_src->state = thrd_src->state == Halted ? Halted : Inactive;
     350        proc_cor->state = Active;
     351        int local_errno = *__volatile_errno();
     352        #if defined( __i386 ) || defined( __x86_64 )
     353                __x87_store;
     354        #endif
     355
     356        // set new coroutine that the processor is executing
     357        // and context switch to it
     358        verify( proc_cor->context.SP );
     359        CtxSwitch( &thrd_src->context, &proc_cor->context );
     360
     361        // set state of new coroutine to active
     362        proc_cor->state = proc_cor->state == Halted ? Halted : Inactive;
     363        thrd_src->state = Active;
     364
     365        #if defined( __i386 ) || defined( __x86_64 )
     366                __x87_load;
     367        #endif
     368        *__volatile_errno() = local_errno;
     369}
     370
     371// KERNEL_ONLY
     372// Once a thread has finished running, some of
     373// its final actions must be executed from the kernel
     374static void finishRunning(processor * this) with( this->finish ) {
     375        verify( ! kernelTLS.preemption_state.enabled );
     376        choose( action_code ) {
     377        case No_Action:
     378                break;
     379        case Release:
     380                unlock( *lock );
     381        case Schedule:
     382                ScheduleThread( thrd );
     383        case Release_Schedule:
     384                unlock( *lock );
     385                ScheduleThread( thrd );
     386        case Release_Multi:
     387                for(int i = 0; i < lock_count; i++) {
     388                        unlock( *locks[i] );
     389                }
     390        case Release_Multi_Schedule:
     391                for(int i = 0; i < lock_count; i++) {
     392                        unlock( *locks[i] );
     393                }
     394                for(int i = 0; i < thrd_count; i++) {
     395                        ScheduleThread( thrds[i] );
     396                }
     397        case Callback:
     398                callback();
     399        default:
     400                abort("KERNEL ERROR: Unexpected action to run after thread");
     401        }
    420402}
    421403
     
    459441}
    460442
    461 static void Abort( int ret, const char * func ) {
     443static void Abort( int ret, const char func[] ) {
    462444        if ( ret ) {                                                                            // pthread routines return errno values
    463445                abort( "%s : internal error, error(%d) %s.", func, ret, strerror( ret ) );
     
    465447} // Abort
    466448
    467 void * __create_pthread( pthread_t * pthread, void * (*start)(void *), void * arg ) {
     449void * create_pthread( pthread_t * pthread, void * (*start)(void *), void * arg ) {
    468450        pthread_attr_t attr;
    469451
     
    487469        );
    488470
    489         Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );
     471        Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" ); 
    490472
    491473        Abort( pthread_create( pthread, &attr, start, arg ), "pthread_create" );
     
    493475}
    494476
     477static void start(processor * this) {
     478        __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", this);
     479
     480        this->stack = create_pthread( &this->kernel_thread, CtxInvokeProcessor, (void *)this );
     481
     482        __cfaabi_dbg_print_safe("Kernel : core %p started\n", this);
     483}
     484
    495485// KERNEL_ONLY
    496 static void __kernel_first_resume( processor * this ) {
     486void kernel_first_resume( processor * this ) {
    497487        thread_desc * src = mainThread;
    498488        coroutine_desc * dst = get_coroutine(this->runner);
     
    500490        verify( ! kernelTLS.preemption_state.enabled );
    501491
    502         kernelTLS.this_thread->curr_cor = dst;
    503492        __stack_prepare( &dst->stack, 65000 );
    504         CtxStart(main, dst, this->runner, CtxInvokeCoroutine);
     493        CtxStart(&this->runner, CtxInvokeCoroutine);
    505494
    506495        verify( ! kernelTLS.preemption_state.enabled );
     
    517506        // when CtxSwitch returns we are back in the src coroutine
    518507
    519         mainThread->curr_cor = &mainThread->self_cor;
    520 
    521508        // set state of new coroutine to active
    522509        src->state = Active;
     
    526513
    527514// KERNEL_ONLY
    528 static void __kernel_last_resume( processor * this ) {
     515void kernel_last_resume( processor * this ) {
    529516        coroutine_desc * src = &mainThread->self_cor;
    530517        coroutine_desc * dst = get_coroutine(this->runner);
     
    540527//-----------------------------------------------------------------------------
    541528// Scheduler routines
     529
    542530// KERNEL ONLY
    543 void __schedule_thread( thread_desc * thrd ) with( *thrd->curr_cluster ) {
    544         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    545         /* paranoid */ #if defined( __CFA_WITH_VERIFY__ )
    546         /* paranoid */ if( thrd->state == Inactive || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
    547                           "Error inactive thread marked as preempted, state %d, preemption %d\n", thrd->state, thrd->preempted );
    548         /* paranoid */ if( thrd->preempted != __NO_PREEMPTION ) assertf(thrd->state == Active || thrd->state == Rerun,
    549                           "Error preempted thread marked as not currently running, state %d, preemption %d\n", thrd->state, thrd->preempted );
    550         /* paranoid */ #endif
    551         /* paranoid */ verifyf( thrd->next == 0p, "Expected null got %p", thrd->next );
    552 
    553         lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    554         bool was_empty = !(ready_queue != 0);
    555         append( ready_queue, thrd );
    556         unlock( ready_queue_lock );
    557 
    558         if(was_empty) {
    559                 lock      (proc_list_lock __cfaabi_dbg_ctx2);
    560                 if(idles) {
    561                         wake_fast(idles.head);
     531void ScheduleThread( thread_desc * thrd ) {
     532        verify( thrd );
     533        verify( thrd->state != Halted );
     534
     535        verify( ! kernelTLS.preemption_state.enabled );
     536
     537        verifyf( thrd->next == 0p, "Expected null got %p", thrd->next );
     538
     539        with( *thrd->curr_cluster ) {
     540                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
     541                bool was_empty = !(ready_queue != 0);
     542                append( ready_queue, thrd );
     543                unlock( ready_queue_lock );
     544
     545                if(was_empty) {
     546                        lock      (proc_list_lock __cfaabi_dbg_ctx2);
     547                        if(idles) {
     548                                wake_fast(idles.head);
     549                        }
     550                        unlock    (proc_list_lock);
    562551                }
    563                 unlock    (proc_list_lock);
    564         }
    565         else if( struct processor * idle = idles.head ) {
    566                 wake_fast(idle);
    567         }
    568 
    569         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     552                else if( struct processor * idle = idles.head ) {
     553                        wake_fast(idle);
     554                }
     555
     556        }
     557
     558        verify( ! kernelTLS.preemption_state.enabled );
    570559}
    571560
    572561// KERNEL ONLY
    573 static thread_desc * __next_thread(cluster * this) with( *this ) {
    574         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    575 
     562thread_desc * nextThread(cluster * this) with( *this ) {
     563        verify( ! kernelTLS.preemption_state.enabled );
    576564        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    577565        thread_desc * head = pop_head( ready_queue );
    578566        unlock( ready_queue_lock );
    579 
    580         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     567        verify( ! kernelTLS.preemption_state.enabled );
    581568        return head;
    582569}
    583570
    584 void unpark( thread_desc * thrd ) {
    585         if( !thrd ) return;
    586 
     571void BlockInternal() {
    587572        disable_interrupts();
    588         static_assert(sizeof(thrd->state) == sizeof(int));
    589         enum coroutine_state old_state = __atomic_exchange_n(&thrd->state, Rerun, __ATOMIC_SEQ_CST);
    590         switch(old_state) {
    591                 case Active:
    592                         // Wake won the race, the thread will reschedule/rerun itself
    593                         break;
    594                 case Inactive:
    595                         /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
    596 
    597                         // Wake lost the race,
    598                         thrd->state = Inactive;
    599                         __schedule_thread( thrd );
    600                         break;
    601                 case Rerun:
    602                         abort("More than one thread attempted to schedule thread %p\n", thrd);
    603                         break;
    604                 case Halted:
    605                 case Start:
    606                 case Primed:
    607                 default:
    608                         // This makes no sense, something is wrong abort
    609                         abort();
    610         }
     573        verify( ! kernelTLS.preemption_state.enabled );
     574        returnToKernel();
     575        verify( ! kernelTLS.preemption_state.enabled );
    611576        enable_interrupts( __cfaabi_dbg_ctx );
    612577}
    613578
    614 void park( void ) {
    615         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
     579void BlockInternal( __spinlock_t * lock ) {
    616580        disable_interrupts();
    617         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    618         /* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION );
    619 
     581        with( *kernelTLS.this_processor ) {
     582                finish.action_code = Release;
     583                finish.lock        = lock;
     584        }
     585
     586        verify( ! kernelTLS.preemption_state.enabled );
    620587        returnToKernel();
    621 
    622         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     588        verify( ! kernelTLS.preemption_state.enabled );
     589
    623590        enable_interrupts( __cfaabi_dbg_ctx );
    624         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    625 
     591}
     592
     593void BlockInternal( thread_desc * thrd ) {
     594        disable_interrupts();
     595        with( * kernelTLS.this_processor ) {
     596                finish.action_code = Schedule;
     597                finish.thrd        = thrd;
     598        }
     599
     600        verify( ! kernelTLS.preemption_state.enabled );
     601        returnToKernel();
     602        verify( ! kernelTLS.preemption_state.enabled );
     603
     604        enable_interrupts( __cfaabi_dbg_ctx );
     605}
     606
     607void BlockInternal( __spinlock_t * lock, thread_desc * thrd ) {
     608        assert(thrd);
     609        disable_interrupts();
     610        with( * kernelTLS.this_processor ) {
     611                finish.action_code = Release_Schedule;
     612                finish.lock        = lock;
     613                finish.thrd        = thrd;
     614        }
     615
     616        verify( ! kernelTLS.preemption_state.enabled );
     617        returnToKernel();
     618        verify( ! kernelTLS.preemption_state.enabled );
     619
     620        enable_interrupts( __cfaabi_dbg_ctx );
     621}
     622
     623void BlockInternal(__spinlock_t * locks [], unsigned short count) {
     624        disable_interrupts();
     625        with( * kernelTLS.this_processor ) {
     626                finish.action_code = Release_Multi;
     627                finish.locks       = locks;
     628                finish.lock_count  = count;
     629        }
     630
     631        verify( ! kernelTLS.preemption_state.enabled );
     632        returnToKernel();
     633        verify( ! kernelTLS.preemption_state.enabled );
     634
     635        enable_interrupts( __cfaabi_dbg_ctx );
     636}
     637
     638void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
     639        disable_interrupts();
     640        with( *kernelTLS.this_processor ) {
     641                finish.action_code = Release_Multi_Schedule;
     642                finish.locks       = locks;
     643                finish.lock_count  = lock_count;
     644                finish.thrds       = thrds;
     645                finish.thrd_count  = thrd_count;
     646        }
     647
     648        verify( ! kernelTLS.preemption_state.enabled );
     649        returnToKernel();
     650        verify( ! kernelTLS.preemption_state.enabled );
     651
     652        enable_interrupts( __cfaabi_dbg_ctx );
     653}
     654
     655void BlockInternal(__finish_callback_fptr_t callback) {
     656        disable_interrupts();
     657        with( *kernelTLS.this_processor ) {
     658                finish.action_code = Callback;
     659                finish.callback    = callback;
     660        }
     661
     662        verify( ! kernelTLS.preemption_state.enabled );
     663        returnToKernel();
     664        verify( ! kernelTLS.preemption_state.enabled );
     665
     666        enable_interrupts( __cfaabi_dbg_ctx );
    626667}
    627668
    628669// KERNEL ONLY
    629 void __leave_thread() {
    630         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     670void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
     671        verify( ! kernelTLS.preemption_state.enabled );
     672        with( * kernelTLS.this_processor ) {
     673                finish.action_code = thrd ? Release_Schedule : Release;
     674                finish.lock        = lock;
     675                finish.thrd        = thrd;
     676        }
     677
    631678        returnToKernel();
    632         abort();
    633 }
    634 
    635 // KERNEL ONLY
    636 bool force_yield( __Preemption_Reason reason ) {
    637         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    638         disable_interrupts();
    639         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    640 
    641         thread_desc * thrd = kernelTLS.this_thread;
    642         /* paranoid */ verify(thrd->state == Active || thrd->state == Rerun);
    643 
    644         // SKULLDUGGERY: It is possible that we are preempting this thread just before
    645         // it was going to park itself. If that is the case and it is already using the
    646         // intrusive fields then we can't use them to preempt the thread
    647         // If that is the case, abandon the preemption.
    648         bool preempted = false;
    649         if(thrd->next == 0p) {
    650                 preempted = true;
    651                 thrd->preempted = reason;
    652                 returnToKernel();
    653         }
    654 
    655         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    656         enable_interrupts_noPoll();
    657         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    658 
    659         return preempted;
    660679}
    661680
     
    665684//-----------------------------------------------------------------------------
    666685// Kernel boot procedures
    667 static void __kernel_startup(void) {
     686static void kernel_startup(void) {
    668687        verify( ! kernelTLS.preemption_state.enabled );
    669688        __cfaabi_dbg_print_safe("Kernel : Starting\n");
     
    726745        // Add the main thread to the ready queue
    727746        // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread
    728         __schedule_thread(mainThread);
     747        ScheduleThread(mainThread);
    729748
    730749        // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX
    731750        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    732751        // mainThread is on the ready queue when this call is made.
    733         __kernel_first_resume( kernelTLS.this_processor );
     752        kernel_first_resume( kernelTLS.this_processor );
    734753
    735754
     
    743762}
    744763
    745 static void __kernel_shutdown(void) {
     764static void kernel_shutdown(void) {
    746765        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    747766
     
    754773        // which is currently here
    755774        __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE);
    756         __kernel_last_resume( kernelTLS.this_processor );
     775        kernel_last_resume( kernelTLS.this_processor );
    757776        mainThread->self_cor.state = Halted;
    758777
     
    780799// Kernel Quiescing
    781800//=============================================================================================
    782 static void __halt(processor * this) with( *this ) {
     801static void halt(processor * this) with( *this ) {
    783802        // verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
    784803
     
    891910
    892911                // atomically release spin lock and block
    893                 unlock( lock );
    894                 park();
     912                BlockInternal( &lock );
    895913        }
    896914        else {
     
    911929
    912930        // make new owner
    913         unpark( thrd );
     931        WakeThread( thrd );
    914932}
    915933
     
    960978__cfaabi_dbg_debug_do(
    961979        extern "C" {
    962                 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
     980                void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]) {
    963981                        this.prev_name = prev_name;
    964982                        this.prev_thrd = kernelTLS.this_thread;
     
    969987//-----------------------------------------------------------------------------
    970988// Debug
    971 bool threading_enabled(void) __attribute__((const)) {
     989bool threading_enabled(void) {
    972990        return true;
    973991}
Note: See TracChangeset for help on using the changeset viewer.