Ignore:
File:
1 edited

Legend:

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

    ra7b486b re3fea42  
    1515
    1616#define __cforall_thread__
    17 // #define __CFA_DEBUG_PRINT_RUNTIME_CORE__
    1817
    1918//C Includes
     
    4140#include "invoke.h"
    4241
    43 
    4442//-----------------------------------------------------------------------------
    4543// Some assembly required
     
    112110//-----------------------------------------------------------------------------
    113111//Start and stop routine for the kernel, declared first to make sure they run first
    114 static void __kernel_startup (void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
    115 static void __kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    116 
    117 //-----------------------------------------------------------------------------
    118 // Kernel Scheduling logic
    119 static $thread * __next_thread(cluster * this);
    120 static void __run_thread(processor * this, $thread * dst);
    121 static $thread * __halt(processor * this);
    122 static bool __wake_one(cluster * cltr, bool was_empty);
    123 static bool __wake_proc(processor *);
     112static void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     113static void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    124114
    125115//-----------------------------------------------------------------------------
     
    127117KERNEL_STORAGE(cluster,         mainCluster);
    128118KERNEL_STORAGE(processor,       mainProcessor);
    129 KERNEL_STORAGE($thread, mainThread);
     119KERNEL_STORAGE(thread_desc,     mainThread);
    130120KERNEL_STORAGE(__stack_t,       mainThreadCtx);
    131121
    132122cluster     * mainCluster;
    133123processor   * mainProcessor;
    134 $thread * mainThread;
     124thread_desc * mainThread;
    135125
    136126extern "C" {
     
    174164// Main thread construction
    175165
    176 void ?{}( $coroutine & this, current_stack_info_t * info) with( this ) {
     166void ?{}( coroutine_desc & this, current_stack_info_t * info) with( this ) {
    177167        stack.storage = info->storage;
    178168        with(*stack.storage) {
     
    189179}
    190180
    191 void ?{}( $thread & this, current_stack_info_t * info) with( this ) {
     181void ?{}( thread_desc & this, current_stack_info_t * info) with( this ) {
    192182        state = Start;
    193183        self_cor{ info };
     
    218208}
    219209
    220 static void * __invoke_processor(void * arg);
    221 
     210static void start(processor * this);
    222211void ?{}(processor & this, const char name[], cluster & cltr) with( this ) {
    223212        this.name = name;
    224213        this.cltr = &cltr;
    225214        terminated{ 0 };
    226         destroyer = 0p;
    227215        do_terminate = false;
    228216        preemption_alarm = 0p;
     
    230218        runner.proc = &this;
    231219
    232         idle{};
    233 
    234         __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this);
    235 
    236         this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this );
    237 
    238         __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this);
     220        idleLock{};
     221
     222        start( &this );
    239223}
    240224
    241225void ^?{}(processor & this) with( this ){
    242226        if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
    243                 __cfadbg_print_safe(runtime_core, "Kernel : core %p signaling termination\n", &this);
     227                __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);
    244228
    245229                __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED);
    246                 __wake_proc( &this );
     230                wake( &this );
    247231
    248232                P( terminated );
     
    250234        }
    251235
    252         int err = pthread_join( kernel_thread, 0p );
    253         if( err != 0 ) abort("KERNEL ERROR: joining processor %p caused error %s\n", &this, strerror(err));
    254 
     236        pthread_join( kernel_thread, 0p );
    255237        free( this.stack );
    256238}
    257239
    258 void ?{}(cluster & this, const char name[], Duration preemption_rate, int io_flags) with( this ) {
     240void ?{}(cluster & this, const char name[], Duration preemption_rate) with( this ) {
    259241        this.name = name;
    260242        this.preemption_rate = preemption_rate;
     
    262244        ready_queue_lock{};
    263245
    264         #if !defined(__CFA_NO_STATISTICS__)
    265                 print_stats = false;
    266         #endif
    267 
    268246        procs{ __get };
    269247        idles{ __get };
    270248        threads{ __get };
    271249
    272         __kernel_io_startup( this, io_flags, &this == mainCluster );
    273 
    274250        doregister(this);
    275251}
    276252
    277253void ^?{}(cluster & this) {
    278         __kernel_io_shutdown( this, &this == mainCluster );
    279 
    280254        unregister(this);
    281255}
     
    284258// Kernel Scheduling logic
    285259//=============================================================================================
     260static void runThread(processor * this, thread_desc * dst);
     261static void finishRunning(processor * this);
     262static void halt(processor * this);
     263
    286264//Main of the processor contexts
    287265void main(processorCtx_t & runner) {
     
    293271        verify(this);
    294272
    295         __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this);
     273        __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
    296274
    297275        doregister(this->cltr, this);
     
    301279                preemption_scope scope = { this };
    302280
    303                 __cfadbg_print_safe(runtime_core, "Kernel : core %p started\n", this);
    304 
    305                 $thread * readyThread = 0p;
     281                __cfaabi_dbg_print_safe("Kernel : core %p started\n", this);
     282
     283                thread_desc * readyThread = 0p;
    306284                for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ ) {
    307                         // Try to get the next thread
    308                         readyThread = __next_thread( this->cltr );
    309 
    310                         // If no ready thread
    311                         if( readyThread == 0p ) {
    312                                 // Block until a thread is ready
    313                                 readyThread = __halt(this);
    314                         }
    315 
    316                         // Check if we actually found a thread
    317                         if( readyThread ) {
    318                                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    319                                 /* paranoid */ verifyf( readyThread->state == Ready || readyThread->preempted != __NO_PREEMPTION, "state : %d, preempted %d\n", readyThread->state, readyThread->preempted);
    320                                 /* paranoid */ verifyf( readyThread->next == 0p, "Expected null got %p", readyThread->next );
    321 
    322                                 // We found a thread run it
    323                                 __run_thread(this, readyThread);
    324 
    325                                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     285                        readyThread = nextThread( this->cltr );
     286
     287                        if(readyThread) {
     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);
     296
     297                                spin_count = 0;
     298                        } else {
     299                                // spin(this, &spin_count);
     300                                halt(this);
    326301                        }
    327302                }
    328303
    329                 __cfadbg_print_safe(runtime_core, "Kernel : core %p stopping\n", this);
     304                __cfaabi_dbg_print_safe("Kernel : core %p stopping\n", this);
    330305        }
    331306
     
    334309        V( this->terminated );
    335310
    336         __cfadbg_print_safe(runtime_core, "Kernel : core %p terminated\n", this);
    337 
    338         // HACK : the coroutine context switch expects this_thread to be set
    339         // and it make sense for it to be set in all other cases except here
    340         // fake it
    341         if( this == mainProcessor ) kernelTLS.this_thread = mainThread;
     311        __cfaabi_dbg_print_safe("Kernel : core %p terminated\n", this);
    342312}
    343313
     
    348318// runThread runs a thread by context switching
    349319// from the processor coroutine to the target thread
    350 static void __run_thread(processor * this, $thread * thrd_dst) {
    351         $coroutine * proc_cor = get_coroutine(this->runner);
     320static void runThread(processor * this, thread_desc * thrd_dst) {
     321        coroutine_desc * proc_cor = get_coroutine(this->runner);
     322
     323        // Reset the terminating actions here
     324        this->finish.action_code = No_Action;
    352325
    353326        // Update global state
    354327        kernelTLS.this_thread = thrd_dst;
    355328
    356         // set state of processor coroutine to inactive
    357         verify(proc_cor->state == Active);
    358         proc_cor->state = Blocked;
    359 
    360         // Actually run the thread
    361         RUNNING:  while(true) {
    362                 if(unlikely(thrd_dst->preempted)) {
    363                         thrd_dst->preempted = __NO_PREEMPTION;
    364                         verify(thrd_dst->state == Active  || thrd_dst->state == Rerun);
    365                 } else {
    366                         verify(thrd_dst->state == Blocked || thrd_dst->state == Ready); // Ready means scheduled normally, blocked means rerun
    367                         thrd_dst->state = 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;
     340        proc_cor->state = Active;
     341}
     342
     343// KERNEL_ONLY
     344static void returnToKernel() {
     345        coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
     346        thread_desc * thrd_src = kernelTLS.this_thread;
     347
     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] );
    368389                }
    369 
    370                 __cfaabi_dbg_debug_do(
    371                         thrd_dst->park_stale   = true;
    372                         thrd_dst->unpark_stale = true;
    373                 )
    374 
    375                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    376                 /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
    377                 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor
    378                 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor
    379 
    380                 // set context switch to the thread that the processor is executing
    381                 verify( thrd_dst->context.SP );
    382                 __cfactx_switch( &proc_cor->context, &thrd_dst->context );
    383                 // when __cfactx_switch returns we are back in the processor coroutine
    384 
    385                 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst );
    386                 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst );
    387                 /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
    388                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    389 
    390 
    391                 // We just finished running a thread, there are a few things that could have happened.
    392                 // 1 - Regular case : the thread has blocked and now one has scheduled it yet.
    393                 // 2 - Racy case    : the thread has blocked but someone has already tried to schedule it.
    394                 // 4 - Preempted
    395                 // In case 1, we may have won a race so we can't write to the state again.
    396                 // In case 2, we lost the race so we now own the thread.
    397 
    398                 if(unlikely(thrd_dst->preempted != __NO_PREEMPTION)) {
    399                         // The thread was preempted, reschedule it and reset the flag
    400                         __schedule_thread( thrd_dst );
    401                         break RUNNING;
     390        case Release_Multi_Schedule:
     391                for(int i = 0; i < lock_count; i++) {
     392                        unlock( *locks[i] );
    402393                }
    403 
    404                 // set state of processor coroutine to active and the thread to inactive
    405                 static_assert(sizeof(thrd_dst->state) == sizeof(int));
    406                 enum coroutine_state old_state = __atomic_exchange_n(&thrd_dst->state, Blocked, __ATOMIC_SEQ_CST);
    407                 __cfaabi_dbg_debug_do( thrd_dst->park_result = old_state; )
    408                 switch(old_state) {
    409                         case Halted:
    410                                 // The thread has halted, it should never be scheduled/run again, leave it back to Halted and move on
    411                                 thrd_dst->state = Halted;
    412 
    413                                 // We may need to wake someone up here since
    414                                 unpark( this->destroyer __cfaabi_dbg_ctx2 );
    415                                 this->destroyer = 0p;
    416                                 break RUNNING;
    417                         case Active:
    418                                 // This is case 1, the regular case, nothing more is needed
    419                                 break RUNNING;
    420                         case Rerun:
    421                                 // This is case 2, the racy case, someone tried to run this thread before it finished blocking
    422                                 // In this case, just run it again.
    423                                 continue RUNNING;
    424                         default:
    425                                 // This makes no sense, something is wrong abort
    426                                 abort("Finished running a thread that was Blocked/Start/Primed %d\n", old_state);
     394                for(int i = 0; i < thrd_count; i++) {
     395                        ScheduleThread( thrds[i] );
    427396                }
    428         }
    429 
    430         // Just before returning to the processor, set the processor coroutine to active
    431         proc_cor->state = Active;
    432         kernelTLS.this_thread = 0p;
    433 }
    434 
    435 // KERNEL_ONLY
    436 void returnToKernel() {
    437         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    438         $coroutine * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
    439         $thread * thrd_src = kernelTLS.this_thread;
    440 
    441         // Run the thread on this processor
    442         {
    443                 int local_errno = *__volatile_errno();
    444                 #if defined( __i386 ) || defined( __x86_64 )
    445                         __x87_store;
    446                 #endif
    447                 verify( proc_cor->context.SP );
    448                 __cfactx_switch( &thrd_src->context, &proc_cor->context );
    449                 #if defined( __i386 ) || defined( __x86_64 )
    450                         __x87_load;
    451                 #endif
    452                 *__volatile_errno() = local_errno;
    453         }
    454 
    455         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    456         /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) < ((uintptr_t)__get_stack(thrd_src->curr_cor)->base ), "ERROR : Returning $thread %p has been corrupted.\n StackPointer too small.\n", thrd_src );
    457         /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) > ((uintptr_t)__get_stack(thrd_src->curr_cor)->limit), "ERROR : Returning $thread %p has been corrupted.\n StackPointer too large.\n", thrd_src );
     397        case Callback:
     398                callback();
     399        default:
     400                abort("KERNEL ERROR: Unexpected action to run after thread");
     401        }
    458402}
    459403
     
    462406// This is the entry point for processors (kernel threads)
    463407// It effectively constructs a coroutine by stealing the pthread stack
    464 static void * __invoke_processor(void * arg) {
     408static void * CtxInvokeProcessor(void * arg) {
    465409        processor * proc = (processor *) arg;
    466410        kernelTLS.this_processor = proc;
     
    481425
    482426        //We now have a proper context from which to schedule threads
    483         __cfadbg_print_safe(runtime_core, "Kernel : core %p created (%p, %p)\n", proc, &proc->runner, &ctx);
     427        __cfaabi_dbg_print_safe("Kernel : core %p created (%p, %p)\n", proc, &proc->runner, &ctx);
    484428
    485429        // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
     
    492436
    493437        // Main routine of the core returned, the core is now fully terminated
    494         __cfadbg_print_safe(runtime_core, "Kernel : core %p main ended (%p)\n", proc, &proc->runner);
     438        __cfaabi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, &proc->runner);
    495439
    496440        return 0p;
     
    503447} // Abort
    504448
    505 void * __create_pthread( pthread_t * pthread, void * (*start)(void *), void * arg ) {
     449void * create_pthread( pthread_t * pthread, void * (*start)(void *), void * arg ) {
    506450        pthread_attr_t attr;
    507451
     
    525469        );
    526470
    527         Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );
     471        Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" ); 
    528472
    529473        Abort( pthread_create( pthread, &attr, start, arg ), "pthread_create" );
     
    531475}
    532476
     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
    533485// KERNEL_ONLY
    534 static void __kernel_first_resume( processor * this ) {
    535         $thread * src = mainThread;
    536         $coroutine * dst = get_coroutine(this->runner);
    537 
    538         verify( ! kernelTLS.preemption_state.enabled );
    539 
    540         kernelTLS.this_thread->curr_cor = dst;
     486void kernel_first_resume( processor * this ) {
     487        thread_desc * src = mainThread;
     488        coroutine_desc * dst = get_coroutine(this->runner);
     489
     490        verify( ! kernelTLS.preemption_state.enabled );
     491
    541492        __stack_prepare( &dst->stack, 65000 );
    542         __cfactx_start(main, dst, this->runner, __cfactx_invoke_coroutine);
     493        CtxStart(&this->runner, CtxInvokeCoroutine);
    543494
    544495        verify( ! kernelTLS.preemption_state.enabled );
     
    547498        dst->starter = dst->starter ? dst->starter : &src->self_cor;
    548499
    549         // make sure the current state is still correct
    550         /* paranoid */ verify(src->state == Ready);
     500        // set state of current coroutine to inactive
     501        src->state = src->state == Halted ? Halted : Inactive;
    551502
    552503        // context switch to specified coroutine
    553504        verify( dst->context.SP );
    554         __cfactx_switch( &src->context, &dst->context );
    555         // when __cfactx_switch returns we are back in the src coroutine
    556 
    557         mainThread->curr_cor = &mainThread->self_cor;
    558 
    559         // make sure the current state has been update
    560         /* paranoid */ verify(src->state == Active);
     505        CtxSwitch( &src->context, &dst->context );
     506        // when CtxSwitch returns we are back in the src coroutine
     507
     508        // set state of new coroutine to active
     509        src->state = Active;
    561510
    562511        verify( ! kernelTLS.preemption_state.enabled );
     
    564513
    565514// KERNEL_ONLY
    566 static void __kernel_last_resume( processor * this ) {
    567         $coroutine * src = &mainThread->self_cor;
    568         $coroutine * dst = get_coroutine(this->runner);
     515void kernel_last_resume( processor * this ) {
     516        coroutine_desc * src = &mainThread->self_cor;
     517        coroutine_desc * dst = get_coroutine(this->runner);
    569518
    570519        verify( ! kernelTLS.preemption_state.enabled );
     
    572521        verify( dst->context.SP );
    573522
    574         // SKULLDUGGERY in debug the processors check that the
    575         // stack is still within the limit of the stack limits after running a thread.
    576         // that check doesn't make sense if we context switch to the processor using the
    577         // coroutine semantics. Since this is a special case, use the current context
    578         // info to populate these fields.
    579         __cfaabi_dbg_debug_do(
    580                 __stack_context_t ctx;
    581                 CtxGet( ctx );
    582                 mainThread->context.SP = ctx.SP;
    583                 mainThread->context.FP = ctx.FP;
    584         )
    585 
    586523        // context switch to the processor
    587         __cfactx_switch( &src->context, &dst->context );
     524        CtxSwitch( &src->context, &dst->context );
    588525}
    589526
    590527//-----------------------------------------------------------------------------
    591528// Scheduler routines
     529
    592530// KERNEL ONLY
    593 void __schedule_thread( $thread * thrd ) with( *thrd->curr_cluster ) {
    594         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    595         /* paranoid */ #if defined( __CFA_WITH_VERIFY__ )
    596         /* paranoid */ if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
    597                           "Error inactive thread marked as preempted, state %d, preemption %d\n", thrd->state, thrd->preempted );
    598         /* paranoid */ if( thrd->preempted != __NO_PREEMPTION ) assertf(thrd->state == Active || thrd->state == Rerun,
    599                           "Error preempted thread marked as not currently running, state %d, preemption %d\n", thrd->state, thrd->preempted );
    600         /* paranoid */ #endif
    601         /* paranoid */ verifyf( thrd->next == 0p, "Expected null got %p", thrd->next );
    602 
    603         if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready;
    604 
    605         lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    606         bool was_empty = !(ready_queue != 0);
    607         append( ready_queue, thrd );
     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);
     551                }
     552                else if( struct processor * idle = idles.head ) {
     553                        wake_fast(idle);
     554                }
     555
     556        }
     557
     558        verify( ! kernelTLS.preemption_state.enabled );
     559}
     560
     561// KERNEL ONLY
     562thread_desc * nextThread(cluster * this) with( *this ) {
     563        verify( ! kernelTLS.preemption_state.enabled );
     564        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
     565        thread_desc * head = pop_head( ready_queue );
    608566        unlock( ready_queue_lock );
    609 
    610         __wake_one(thrd->curr_cluster, was_empty);
    611 
    612         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     567        verify( ! kernelTLS.preemption_state.enabled );
     568        return head;
     569}
     570
     571void BlockInternal() {
     572        disable_interrupts();
     573        verify( ! kernelTLS.preemption_state.enabled );
     574        returnToKernel();
     575        verify( ! kernelTLS.preemption_state.enabled );
     576        enable_interrupts( __cfaabi_dbg_ctx );
     577}
     578
     579void BlockInternal( __spinlock_t * lock ) {
     580        disable_interrupts();
     581        with( *kernelTLS.this_processor ) {
     582                finish.action_code = Release;
     583                finish.lock        = lock;
     584        }
     585
     586        verify( ! kernelTLS.preemption_state.enabled );
     587        returnToKernel();
     588        verify( ! kernelTLS.preemption_state.enabled );
     589
     590        enable_interrupts( __cfaabi_dbg_ctx );
     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 );
    613667}
    614668
    615669// KERNEL ONLY
    616 static $thread * __next_thread(cluster * this) with( *this ) {
    617         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    618 
    619         lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    620         $thread * head = pop_head( ready_queue );
    621         unlock( ready_queue_lock );
    622 
    623         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    624         return head;
    625 }
    626 
    627 // KERNEL ONLY unpark with out disabling interrupts
    628 void __unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) {
    629         static_assert(sizeof(thrd->state) == sizeof(int));
    630 
    631         // record activity
    632         __cfaabi_dbg_record_thrd( *thrd, false, caller );
    633 
    634         enum coroutine_state old_state = __atomic_exchange_n(&thrd->state, Rerun, __ATOMIC_SEQ_CST);
    635         __cfaabi_dbg_debug_do( thrd->unpark_result = old_state; )
    636         switch(old_state) {
    637                 case Active:
    638                         // Wake won the race, the thread will reschedule/rerun itself
    639                         break;
    640                 case Blocked:
    641                         /* paranoid */ verify( ! thrd->preempted != __NO_PREEMPTION );
    642 
    643                         // Wake lost the race,
    644                         thrd->state = Blocked;
    645                         __schedule_thread( thrd );
    646                         break;
    647                 case Rerun:
    648                         abort("More than one thread attempted to schedule thread %p\n", thrd);
    649                         break;
    650                 case Halted:
    651                 case Start:
    652                 case Primed:
    653                 default:
    654                         // This makes no sense, something is wrong abort
    655                         abort();
    656         }
    657 }
    658 
    659 void unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) {
    660         if( !thrd ) return;
    661 
    662         disable_interrupts();
    663         __unpark( thrd __cfaabi_dbg_ctx_fwd2 );
    664         enable_interrupts( __cfaabi_dbg_ctx );
    665 }
    666 
    667 void park( __cfaabi_dbg_ctx_param ) {
    668         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    669         disable_interrupts();
    670         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    671         /* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION );
    672 
    673         // record activity
    674         __cfaabi_dbg_record_thrd( *kernelTLS.this_thread, true, caller );
     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        }
    675677
    676678        returnToKernel();
    677 
    678         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    679         enable_interrupts( __cfaabi_dbg_ctx );
    680         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    681 
    682 }
    683 
    684 // KERNEL ONLY
    685 void __leave_thread() {
    686         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    687         returnToKernel();
    688         abort();
    689 }
    690 
    691 // KERNEL ONLY
    692 bool force_yield( __Preemption_Reason reason ) {
    693         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    694         disable_interrupts();
    695         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    696 
    697         $thread * thrd = kernelTLS.this_thread;
    698         /* paranoid */ verify(thrd->state == Active || thrd->state == Rerun);
    699 
    700         // SKULLDUGGERY: It is possible that we are preempting this thread just before
    701         // it was going to park itself. If that is the case and it is already using the
    702         // intrusive fields then we can't use them to preempt the thread
    703         // If that is the case, abandon the preemption.
    704         bool preempted = false;
    705         if(thrd->next == 0p) {
    706                 preempted = true;
    707                 thrd->preempted = reason;
    708                 returnToKernel();
    709         }
    710 
    711         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    712         enable_interrupts_noPoll();
    713         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
    714 
    715         return preempted;
    716679}
    717680
     
    721684//-----------------------------------------------------------------------------
    722685// Kernel boot procedures
    723 static void __kernel_startup(void) {
    724         verify( ! kernelTLS.preemption_state.enabled );
    725         __cfadbg_print_safe(runtime_core, "Kernel : Starting\n");
     686static void kernel_startup(void) {
     687        verify( ! kernelTLS.preemption_state.enabled );
     688        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    726689
    727690        __page_size = sysconf( _SC_PAGESIZE );
     
    734697        (*mainCluster){"Main Cluster"};
    735698
    736         __cfadbg_print_safe(runtime_core, "Kernel : Main cluster ready\n");
     699        __cfaabi_dbg_print_safe("Kernel : Main cluster ready\n");
    737700
    738701        // Start by initializing the main thread
    739702        // SKULLDUGGERY: the mainThread steals the process main thread
    740703        // which will then be scheduled by the mainProcessor normally
    741         mainThread = ($thread *)&storage_mainThread;
     704        mainThread = (thread_desc *)&storage_mainThread;
    742705        current_stack_info_t info;
    743706        info.storage = (__stack_t*)&storage_mainThreadCtx;
    744707        (*mainThread){ &info };
    745708
    746         __cfadbg_print_safe(runtime_core, "Kernel : Main thread ready\n");
     709        __cfaabi_dbg_print_safe("Kernel : Main thread ready\n");
    747710
    748711
     
    765728
    766729                runner{ &this };
    767                 __cfadbg_print_safe(runtime_core, "Kernel : constructed main processor context %p\n", &runner);
     730                __cfaabi_dbg_print_safe("Kernel : constructed main processor context %p\n", &runner);
    768731        }
    769732
     
    782745        // Add the main thread to the ready queue
    783746        // once resume is called on mainProcessor->runner the mainThread needs to be scheduled like any normal thread
    784         __schedule_thread(mainThread);
     747        ScheduleThread(mainThread);
    785748
    786749        // SKULLDUGGERY: Force a context switch to the main processor to set the main thread's context to the current UNIX
    787         // context. Hence, the main thread does not begin through __cfactx_invoke_thread, like all other threads. The trick here is that
     750        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    788751        // mainThread is on the ready queue when this call is made.
    789         __kernel_first_resume( kernelTLS.this_processor );
     752        kernel_first_resume( kernelTLS.this_processor );
     753
    790754
    791755
    792756        // THE SYSTEM IS NOW COMPLETELY RUNNING
    793 
    794 
    795         // Now that the system is up, finish creating systems that need threading
    796         __kernel_io_finish_start( *mainCluster );
    797 
    798 
    799         __cfadbg_print_safe(runtime_core, "Kernel : Started\n--------------------------------------------------\n\n");
     757        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    800758
    801759        verify( ! kernelTLS.preemption_state.enabled );
     
    804762}
    805763
    806 static void __kernel_shutdown(void) {
    807         //Before we start shutting things down, wait for systems that need threading to shutdown
    808         __kernel_io_prepare_stop( *mainCluster );
    809 
    810         /* paranoid */ verify( TL_GET( preemption_state.enabled ) );
     764static void kernel_shutdown(void) {
     765        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
     766
     767        verify( TL_GET( preemption_state.enabled ) );
    811768        disable_interrupts();
    812         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    813 
    814         __cfadbg_print_safe(runtime_core, "\n--------------------------------------------------\nKernel : Shutting down\n");
     769        verify( ! kernelTLS.preemption_state.enabled );
    815770
    816771        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    818773        // which is currently here
    819774        __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE);
    820         __kernel_last_resume( kernelTLS.this_processor );
     775        kernel_last_resume( kernelTLS.this_processor );
    821776        mainThread->self_cor.state = Halted;
    822777
     
    828783        // Destroy the main processor and its context in reverse order of construction
    829784        // These were manually constructed so we need manually destroy them
    830         void ^?{}(processor & this) with( this ){
    831                 /* paranoid */ verify( this.do_terminate == true );
    832         }
    833 
    834         ^(*mainProcessor){};
     785        ^(mainProcessor->runner){};
     786        ^(mainProcessor){};
    835787
    836788        // Final step, destroy the main thread since it is no longer needed
    837789        // Since we provided a stack to this taxk it will not destroy anything
    838         /* paranoid */ verify(mainThread->self_cor.stack.storage == (__stack_t*)(((uintptr_t)&storage_mainThreadCtx)| 0x1));
    839         ^(*mainThread){};
    840 
    841         ^(*mainCluster){};
     790        ^(mainThread){};
    842791
    843792        ^(__cfa_dbg_global_clusters.list){};
    844793        ^(__cfa_dbg_global_clusters.lock){};
    845794
    846         __cfadbg_print_safe(runtime_core, "Kernel : Shutdown complete\n");
     795        __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n");
    847796}
    848797
    849798//=============================================================================================
    850 // Kernel Idle Sleep
     799// Kernel Quiescing
    851800//=============================================================================================
    852 static $thread * __halt(processor * this) with( *this ) {
    853         if( do_terminate ) return 0p;
    854 
    855         // First, lock the cluster idle
    856         lock( cltr->idle_lock __cfaabi_dbg_ctx2 );
    857 
    858         // Check if we can find a thread
    859         if( $thread * found = __next_thread( cltr ) ) {
    860                 unlock( cltr->idle_lock );
    861                 return found;
    862         }
    863 
    864         // Move this processor from the active list to the idle list
    865         move_to_front(cltr->procs, cltr->idles, *this);
    866 
    867         // Unlock the idle lock so we don't go to sleep with a lock
    868         unlock    (cltr->idle_lock);
    869 
    870         // We are ready to sleep
    871         __cfadbg_print_safe(runtime_core, "Kernel : Processor %p ready to sleep\n", this);
    872         wait( idle );
    873 
    874         // We have woken up
    875         __cfadbg_print_safe(runtime_core, "Kernel : Processor %p woke up and ready to run\n", this);
    876 
    877         // Get ourself off the idle list
     801static void halt(processor * this) with( *this ) {
     802        // verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
     803
    878804        with( *cltr ) {
    879                 lock  (idle_lock __cfaabi_dbg_ctx2);
    880                 move_to_front(idles, procs, *this);
    881                 unlock(idle_lock);
    882         }
    883 
    884         // Don't check the ready queue again, we may not be in a position to run a thread
    885         return 0p;
    886 }
    887 
    888 // Wake a thread from the front if there are any
    889 static bool __wake_one(cluster * this, __attribute__((unused)) bool force) {
    890         // if we don't want to force check if we know it's false
    891         // if( !this->idles.head && !force ) return false;
    892 
    893         // First, lock the cluster idle
    894         lock( this->idle_lock __cfaabi_dbg_ctx2 );
    895 
    896         // Check if there is someone to wake up
    897         if( !this->idles.head ) {
    898                 // Nope unlock and return false
    899                 unlock( this->idle_lock );
    900                 return false;
    901         }
    902 
    903         // Wake them up
    904         __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this->idles.head);
    905         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    906         post( this->idles.head->idle );
    907 
    908         // Unlock and return true
    909         unlock( this->idle_lock );
    910         return true;
    911 }
    912 
    913 // Unconditionnaly wake a thread
    914 static bool __wake_proc(processor * this) {
    915         __cfadbg_print_safe(runtime_core, "Kernel : waking Processor %p\n", this);
    916 
    917         disable_interrupts();
    918                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    919                 bool ret = post( this->idle );
    920         enable_interrupts( __cfaabi_dbg_ctx );
    921 
    922         return ret;
     805                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     806                remove    (procs, *this);
     807                push_front(idles, *this);
     808                unlock    (proc_list_lock);
     809        }
     810
     811        __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);
     812
     813        wait( idleLock );
     814
     815        __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this);
     816
     817        with( *cltr ) {
     818                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     819                remove    (idles, *this);
     820                push_front(procs, *this);
     821                unlock    (proc_list_lock);
     822        }
    923823}
    924824
     
    954854
    955855void kernel_abort_msg( void * kernel_data, char * abort_text, int abort_text_size ) {
    956         $thread * thrd = kernel_data;
     856        thread_desc * thrd = kernel_data;
    957857
    958858        if(thrd) {
     
    1002902void ^?{}(semaphore & this) {}
    1003903
    1004 bool P(semaphore & this) with( this ){
     904void P(semaphore & this) with( this ){
    1005905        lock( lock __cfaabi_dbg_ctx2 );
    1006906        count -= 1;
     
    1010910
    1011911                // atomically release spin lock and block
    1012                 unlock( lock );
    1013                 park( __cfaabi_dbg_ctx );
    1014                 return true;
     912                BlockInternal( &lock );
    1015913        }
    1016914        else {
    1017915            unlock( lock );
    1018             return false;
    1019         }
    1020 }
    1021 
    1022 bool V(semaphore & this) with( this ) {
    1023         $thread * thrd = 0p;
     916        }
     917}
     918
     919void V(semaphore & this) with( this ) {
     920        thread_desc * thrd = 0p;
    1024921        lock( lock __cfaabi_dbg_ctx2 );
    1025922        count += 1;
     
    1032929
    1033930        // make new owner
    1034         unpark( thrd __cfaabi_dbg_ctx2 );
    1035 
    1036         return thrd != 0p;
    1037 }
    1038 
    1039 bool V(semaphore & this, unsigned diff) with( this ) {
    1040         $thread * thrd = 0p;
    1041         lock( lock __cfaabi_dbg_ctx2 );
    1042         int release = max(-count, (int)diff);
    1043         count += diff;
    1044         for(release) {
    1045                 unpark( pop_head( waiting ) __cfaabi_dbg_ctx2 );
    1046         }
    1047 
    1048         unlock( lock );
    1049 
    1050         return thrd != 0p;
     931        WakeThread( thrd );
    1051932}
    1052933
     
    1065946}
    1066947
    1067 void doregister( cluster * cltr, $thread & thrd ) {
     948void doregister( cluster * cltr, thread_desc & thrd ) {
    1068949        lock      (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    1069950        cltr->nthreads += 1;
     
    1072953}
    1073954
    1074 void unregister( cluster * cltr, $thread & thrd ) {
     955void unregister( cluster * cltr, thread_desc & thrd ) {
    1075956        lock  (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    1076957        remove(cltr->threads, thrd );
     
    1080961
    1081962void doregister( cluster * cltr, processor * proc ) {
    1082         lock      (cltr->idle_lock __cfaabi_dbg_ctx2);
     963        lock      (cltr->proc_list_lock __cfaabi_dbg_ctx2);
    1083964        cltr->nprocessors += 1;
    1084965        push_front(cltr->procs, *proc);
    1085         unlock    (cltr->idle_lock);
     966        unlock    (cltr->proc_list_lock);
    1086967}
    1087968
    1088969void unregister( cluster * cltr, processor * proc ) {
    1089         lock  (cltr->idle_lock __cfaabi_dbg_ctx2);
     970        lock  (cltr->proc_list_lock __cfaabi_dbg_ctx2);
    1090971        remove(cltr->procs, *proc );
    1091972        cltr->nprocessors -= 1;
    1092         unlock(cltr->idle_lock);
     973        unlock(cltr->proc_list_lock);
    1093974}
    1094975
     
    1097978__cfaabi_dbg_debug_do(
    1098979        extern "C" {
    1099                 void __cfaabi_dbg_record_lock(__spinlock_t & this, const char prev_name[]) {
     980                void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]) {
    1100981                        this.prev_name = prev_name;
    1101982                        this.prev_thrd = kernelTLS.this_thread;
    1102983                }
    1103 
    1104                 void __cfaabi_dbg_record_thrd($thread & this, bool park, const char prev_name[]) {
    1105                         if(park) {
    1106                                 this.park_caller   = prev_name;
    1107                                 this.park_stale    = false;
    1108                         }
    1109                         else {
    1110                                 this.unpark_caller = prev_name;
    1111                                 this.unpark_stale  = false;
    1112                         }
    1113                 }
    1114984        }
    1115985)
     
    1117987//-----------------------------------------------------------------------------
    1118988// Debug
    1119 bool threading_enabled(void) __attribute__((const)) {
     989bool threading_enabled(void) {
    1120990        return true;
    1121991}
Note: See TracChangeset for help on using the changeset viewer.