Ignore:
File:
1 edited

Legend:

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

    r01963df rde94a60  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:26:11 2018
    13 // Update Count     : 23
     12// Last Modified On : Mon Apr  9 16:11:46 2018
     13// Update Count     : 24
    1414//
    1515
     
    2525
    2626//CFA Includes
     27#include "time"
    2728#include "kernel_private.h"
    2829#include "preemption.h"
     
    4142KERNEL_STORAGE(cluster,           mainCluster);
    4243KERNEL_STORAGE(processor,         mainProcessor);
    43 KERNEL_STORAGE(processorCtx_t,    mainProcessorCtx);
    4444KERNEL_STORAGE(thread_desc,       mainThread);
    4545KERNEL_STORAGE(machine_context_t, mainThreadCtx);
    4646
    47 cluster *    mainCluster;
    48 processor mainProcessor;
     47cluster     * mainCluster;
     48processor   * mainProcessor;
    4949thread_desc * mainThread;
     50
     51struct { __dllist_t(thread_desc) list; __spinlock_t lock; } global_threads ;
     52struct { __dllist_t(cluster    ) list; __spinlock_t lock; } global_clusters;
    5053
    5154//-----------------------------------------------------------------------------
     
    5659// volatile thread_local unsigned short disable_preempt_count = 1;
    5760
    58 thread_local struct KernelThreadData kernelThreadData = {
     61thread_local struct KernelThreadData kernelTLS = {
    5962        NULL,
    6063        NULL,
     
    6467
    6568//-----------------------------------------------------------------------------
    66 // Main thread construction
     69// Struct to steal stack
    6770struct current_stack_info_t {
    6871        machine_context_t ctx;
     
    8992}
    9093
     94//-----------------------------------------------------------------------------
     95// Main thread construction
    9196void ?{}( coStack_t & this, current_stack_info_t * info) with( this ) {
    9297        size      = info->size;
     
    110115        self_cor{ info };
    111116        curr_cor = &self_cor;
     117        curr_cluster = mainCluster;
    112118        self_mon.owner = &this;
    113119        self_mon.recursion = 1;
    114120        self_mon_p = &self_mon;
    115121        next = NULL;
    116         __cfaabi_dbg_debug_do(
    117                 dbg_next = NULL;
    118                 dbg_prev = NULL;
    119                 __cfaabi_dbg_thread_register(&this);
    120         )
     122
     123        node.next = NULL;
     124        node.prev = NULL;
     125        doregister(this);
    121126
    122127        monitors{ &self_mon_p, 1, (fptr_t)0 };
     
    125130//-----------------------------------------------------------------------------
    126131// Processor coroutine
    127 void ?{}(processorCtx_t & this) {}
    128 
    129 // Construct the processor context of the main processor
    130 void ?{}(processorCtx_t & this, processor * proc) {
    131         (this.__cor){ "Processor" };
    132         this.__cor.starter = NULL;
    133         this.proc = proc;
     132void ?{}(processorCtx_t & this) {
     133
    134134}
    135135
     
    140140}
    141141
    142 void ?{}(processor & this) {
    143         this{ mainCluster };
    144 }
    145 
    146 void ?{}(processor & this, cluster * cltr) with( this ) {
    147         this.cltr = cltr;
     142void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {
     143        this.name = name;
     144        this.cltr = &cltr;
    148145        terminated{ 0 };
    149146        do_terminate = false;
     
    155152}
    156153
    157 void ?{}(processor & this, cluster * cltr, processorCtx_t & runner) with( this ) {
    158         this.cltr = cltr;
    159         terminated{ 0 };
    160         do_terminate = false;
    161         preemption_alarm = NULL;
    162         pending_preemption = false;
    163         kernel_thread = pthread_self();
    164         runner.proc = &this;
    165 
    166         __cfaabi_dbg_print_safe("Kernel : constructing main processor context %p\n", &runner);
    167         runner{ &this };
    168 }
    169 
    170154void ^?{}(processor & this) with( this ){
    171155        if( ! do_terminate ) {
     
    173157                terminate(&this);
    174158                verify(this.do_terminate);
    175                 verify(TL_GET( this_processor ) != &this);
     159                verify( kernelTLS.this_processor != &this);
    176160                P( terminated );
    177                 verify(TL_GET( this_processor ) != &this);
     161                verify( kernelTLS.this_processor != &this);
    178162                pthread_join( kernel_thread, NULL );
    179163        }
    180164}
    181165
    182 void ?{}(cluster & this) with( this ) {
     166void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) {
     167        this.name = name;
     168        this.preemption_rate = preemption_rate;
    183169        ready_queue{};
    184170        ready_queue_lock{};
    185171
    186         preemption_rate = default_preemption();
     172        procs{ __get };
     173        idles{ __get };
     174
     175        doregister(this);
    187176}
    188177
    189178void ^?{}(cluster & this) {
    190 
     179        unregister(this);
    191180}
    192181
     
    201190        __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
    202191
     192        doregister(this->cltr, this);
     193
    203194        {
    204195                // Setup preemption data
     
    214205                        if(readyThread)
    215206                        {
    216                                 verify( ! TL_GET( preemption_state ).enabled );
     207                                verify( ! kernelTLS.preemption_state.enabled );
    217208
    218209                                runThread(this, readyThread);
    219210
    220                                 verify( ! TL_GET( preemption_state ).enabled );
     211                                verify( ! kernelTLS.preemption_state.enabled );
    221212
    222213                                //Some actions need to be taken from the kernel
     
    234225        }
    235226
     227        unregister(this->cltr, this);
     228
    236229        V( this->terminated );
    237230
     
    239232}
    240233
     234// KERNEL ONLY
    241235// runThread runs a thread by context switching
    242236// from the processor coroutine to the target thread
     
    246240        coroutine_desc * thrd_cor = dst->curr_cor;
    247241
    248         //Reset the terminating actions here
     242        // Reset the terminating actions here
    249243        this->finish.action_code = No_Action;
    250244
    251         //Update global state
    252         TL_SET( this_thread, dst );
     245        // Update global state
     246        kernelTLS.this_thread = dst;
    253247
    254248        // Context Switch to the thread
     
    257251}
    258252
     253// KERNEL_ONLY
    259254void returnToKernel() {
    260         coroutine_desc * proc_cor = get_coroutine(TL_GET( this_processor )->runner);
    261         coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );
     255        coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
     256        coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine;
    262257        ThreadCtxSwitch(thrd_cor, proc_cor);
    263258}
    264259
     260// KERNEL_ONLY
    265261// Once a thread has finished running, some of
    266262// its final actions must be executed from the kernel
    267263void finishRunning(processor * this) with( this->finish ) {
    268264        if( action_code == Release ) {
    269                 verify( ! TL_GET( preemption_state ).enabled );
     265                verify( ! kernelTLS.preemption_state.enabled );
    270266                unlock( *lock );
    271267        }
     
    274270        }
    275271        else if( action_code == Release_Schedule ) {
    276                 verify( ! TL_GET( preemption_state ).enabled );
     272                verify( ! kernelTLS.preemption_state.enabled );
    277273                unlock( *lock );
    278274                ScheduleThread( thrd );
    279275        }
    280276        else if( action_code == Release_Multi ) {
    281                 verify( ! TL_GET( preemption_state ).enabled );
     277                verify( ! kernelTLS.preemption_state.enabled );
    282278                for(int i = 0; i < lock_count; i++) {
    283279                        unlock( *locks[i] );
     
    303299}
    304300
     301// KERNEL_ONLY
    305302// Context invoker for processors
    306303// This is the entry point for processors (kernel threads)
     
    308305void * CtxInvokeProcessor(void * arg) {
    309306        processor * proc = (processor *) arg;
    310         TL_SET( this_processor, proc );
    311         TL_SET( this_coroutine, NULL );
    312         TL_SET( this_thread, NULL );
    313         TL_GET( preemption_state ).enabled = false;
    314         TL_GET( preemption_state ).disable_count = 1;
     307        kernelTLS.this_processor = proc;
     308        kernelTLS.this_coroutine = NULL;
     309        kernelTLS.this_thread    = NULL;
     310        kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
    315311        // SKULLDUGGERY: We want to create a context for the processor coroutine
    316312        // which is needed for the 2-step context switch. However, there is no reason
     
    324320
    325321        //Set global state
    326         TL_SET( this_coroutine, get_coroutine(proc->runner) );
    327         TL_SET( this_thread, NULL );
     322        kernelTLS.this_coroutine = get_coroutine(proc->runner);
     323        kernelTLS.this_thread    = NULL;
    328324
    329325        //We now have a proper context from which to schedule threads
     
    352348}
    353349
     350// KERNEL_ONLY
    354351void kernel_first_resume(processor * this) {
    355         coroutine_desc * src = TL_GET( this_coroutine );
     352        coroutine_desc * src = kernelTLS.this_coroutine;
    356353        coroutine_desc * dst = get_coroutine(this->runner);
    357354
    358         verify( ! TL_GET( preemption_state ).enabled );
     355        verify( ! kernelTLS.preemption_state.enabled );
    359356
    360357        create_stack(&dst->stack, dst->stack.size);
    361358        CtxStart(&this->runner, CtxInvokeCoroutine);
    362359
    363         verify( ! TL_GET( preemption_state ).enabled );
     360        verify( ! kernelTLS.preemption_state.enabled );
    364361
    365362        dst->last = src;
     
    370367
    371368        // set new coroutine that task is executing
    372         TL_SET( this_coroutine, dst );
     369        kernelTLS.this_coroutine = dst;
    373370
    374371        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    387384        src->state = Active;
    388385
    389         verify( ! TL_GET( preemption_state ).enabled );
     386        verify( ! kernelTLS.preemption_state.enabled );
    390387}
    391388
    392389//-----------------------------------------------------------------------------
    393390// Scheduler routines
     391
     392// KERNEL ONLY
    394393void ScheduleThread( thread_desc * thrd ) {
    395         // if( ! thrd ) return;
    396394        verify( thrd );
    397395        verify( thrd->self_cor.state != Halted );
    398396
    399         verify( ! TL_GET( preemption_state ).enabled );
     397        verify( ! kernelTLS.preemption_state.enabled );
    400398
    401399        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    402400
    403         with( *TL_GET( this_processor )->cltr ) {
     401        with( *thrd->curr_cluster ) {
    404402                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    405403                append( ready_queue, thrd );
     
    407405        }
    408406
    409         verify( ! TL_GET( preemption_state ).enabled );
    410 }
    411 
     407        verify( ! kernelTLS.preemption_state.enabled );
     408}
     409
     410// KERNEL ONLY
    412411thread_desc * nextThread(cluster * this) with( *this ) {
    413         verify( ! TL_GET( preemption_state ).enabled );
     412        verify( ! kernelTLS.preemption_state.enabled );
    414413        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    415414        thread_desc * head = pop_head( ready_queue );
    416415        unlock( ready_queue_lock );
    417         verify( ! TL_GET( preemption_state ).enabled );
     416        verify( ! kernelTLS.preemption_state.enabled );
    418417        return head;
    419418}
     
    421420void BlockInternal() {
    422421        disable_interrupts();
    423         verify( ! TL_GET( preemption_state ).enabled );
     422        verify( ! kernelTLS.preemption_state.enabled );
    424423        returnToKernel();
    425         verify( ! TL_GET( preemption_state ).enabled );
     424        verify( ! kernelTLS.preemption_state.enabled );
    426425        enable_interrupts( __cfaabi_dbg_ctx );
    427426}
     
    429428void BlockInternal( __spinlock_t * lock ) {
    430429        disable_interrupts();
    431         TL_GET( this_processor )->finish.action_code = Release;
    432         TL_GET( this_processor )->finish.lock        = lock;
    433 
    434         verify( ! TL_GET( preemption_state ).enabled );
     430        with( *kernelTLS.this_processor ) {
     431                finish.action_code = Release;
     432                finish.lock        = lock;
     433        }
     434
     435        verify( ! kernelTLS.preemption_state.enabled );
    435436        returnToKernel();
    436         verify( ! TL_GET( preemption_state ).enabled );
     437        verify( ! kernelTLS.preemption_state.enabled );
    437438
    438439        enable_interrupts( __cfaabi_dbg_ctx );
     
    441442void BlockInternal( thread_desc * thrd ) {
    442443        disable_interrupts();
    443         TL_GET( this_processor )->finish.action_code = Schedule;
    444         TL_GET( this_processor )->finish.thrd        = thrd;
    445 
    446         verify( ! TL_GET( preemption_state ).enabled );
     444        with( * kernelTLS.this_processor ) {
     445                finish.action_code = Schedule;
     446                finish.thrd        = thrd;
     447        }
     448
     449        verify( ! kernelTLS.preemption_state.enabled );
    447450        returnToKernel();
    448         verify( ! TL_GET( preemption_state ).enabled );
     451        verify( ! kernelTLS.preemption_state.enabled );
    449452
    450453        enable_interrupts( __cfaabi_dbg_ctx );
     
    454457        assert(thrd);
    455458        disable_interrupts();
    456         TL_GET( this_processor )->finish.action_code = Release_Schedule;
    457         TL_GET( this_processor )->finish.lock        = lock;
    458         TL_GET( this_processor )->finish.thrd        = thrd;
    459 
    460         verify( ! TL_GET( preemption_state ).enabled );
     459        with( * kernelTLS.this_processor ) {
     460                finish.action_code = Release_Schedule;
     461                finish.lock        = lock;
     462                finish.thrd        = thrd;
     463        }
     464
     465        verify( ! kernelTLS.preemption_state.enabled );
    461466        returnToKernel();
    462         verify( ! TL_GET( preemption_state ).enabled );
     467        verify( ! kernelTLS.preemption_state.enabled );
    463468
    464469        enable_interrupts( __cfaabi_dbg_ctx );
     
    467472void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    468473        disable_interrupts();
    469         TL_GET( this_processor )->finish.action_code = Release_Multi;
    470         TL_GET( this_processor )->finish.locks       = locks;
    471         TL_GET( this_processor )->finish.lock_count  = count;
    472 
    473         verify( ! TL_GET( preemption_state ).enabled );
     474        with( * kernelTLS.this_processor ) {
     475                finish.action_code = Release_Multi;
     476                finish.locks       = locks;
     477                finish.lock_count  = count;
     478        }
     479
     480        verify( ! kernelTLS.preemption_state.enabled );
    474481        returnToKernel();
    475         verify( ! TL_GET( preemption_state ).enabled );
     482        verify( ! kernelTLS.preemption_state.enabled );
    476483
    477484        enable_interrupts( __cfaabi_dbg_ctx );
     
    480487void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    481488        disable_interrupts();
    482         TL_GET( this_processor )->finish.action_code = Release_Multi_Schedule;
    483         TL_GET( this_processor )->finish.locks       = locks;
    484         TL_GET( this_processor )->finish.lock_count  = lock_count;
    485         TL_GET( this_processor )->finish.thrds       = thrds;
    486         TL_GET( this_processor )->finish.thrd_count  = thrd_count;
    487 
    488         verify( ! TL_GET( preemption_state ).enabled );
     489        with( *kernelTLS.this_processor ) {
     490                finish.action_code = Release_Multi_Schedule;
     491                finish.locks       = locks;
     492                finish.lock_count  = lock_count;
     493                finish.thrds       = thrds;
     494                finish.thrd_count  = thrd_count;
     495        }
     496
     497        verify( ! kernelTLS.preemption_state.enabled );
    489498        returnToKernel();
    490         verify( ! TL_GET( preemption_state ).enabled );
     499        verify( ! kernelTLS.preemption_state.enabled );
    491500
    492501        enable_interrupts( __cfaabi_dbg_ctx );
    493502}
    494503
     504// KERNEL ONLY
    495505void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    496         verify( ! TL_GET( preemption_state ).enabled );
    497         TL_GET( this_processor )->finish.action_code = thrd ? Release_Schedule : Release;
    498         TL_GET( this_processor )->finish.lock        = lock;
    499         TL_GET( this_processor )->finish.thrd        = thrd;
     506        verify( ! kernelTLS.preemption_state.enabled );
     507        with( * kernelTLS.this_processor ) {
     508                finish.action_code = thrd ? Release_Schedule : Release;
     509                finish.lock        = lock;
     510                finish.thrd        = thrd;
     511        }
    500512
    501513        returnToKernel();
     
    508520// Kernel boot procedures
    509521void kernel_startup(void) {
    510         verify( ! TL_GET( preemption_state ).enabled );
     522        verify( ! kernelTLS.preemption_state.enabled );
    511523        __cfaabi_dbg_print_safe("Kernel : Starting\n");
     524
     525        global_threads. list{ __get };
     526        global_threads. lock{};
     527        global_clusters.list{ __get };
     528        global_clusters.lock{};
     529
     530        // Initialize the main cluster
     531        mainCluster = (cluster *)&storage_mainCluster;
     532        (*mainCluster){"Main Cluster"};
     533
     534        __cfaabi_dbg_print_safe("Kernel : Main cluster ready\n");
    512535
    513536        // Start by initializing the main thread
     
    520543        __cfaabi_dbg_print_safe("Kernel : Main thread ready\n");
    521544
    522         // Initialize the main cluster
    523         mainCluster = (cluster *)&storage_mainCluster;
    524         (*mainCluster){};
    525 
    526         __cfaabi_dbg_print_safe("Kernel : main cluster ready\n");
     545
     546
     547        // Construct the processor context of the main processor
     548        void ?{}(processorCtx_t & this, processor * proc) {
     549                (this.__cor){ "Processor" };
     550                this.__cor.starter = NULL;
     551                this.proc = proc;
     552        }
     553
     554        void ?{}(processor & this) with( this ) {
     555                name = "Main Processor";
     556                cltr = mainCluster;
     557                terminated{ 0 };
     558                do_terminate = false;
     559                preemption_alarm = NULL;
     560                pending_preemption = false;
     561                kernel_thread = pthread_self();
     562
     563                runner{ &this };
     564                __cfaabi_dbg_print_safe("Kernel : constructed main processor context %p\n", &runner);
     565        }
    527566
    528567        // Initialize the main processor and the main processor ctx
    529568        // (the coroutine that contains the processing control flow)
    530569        mainProcessor = (processor *)&storage_mainProcessor;
    531         (*mainProcessor){ mainCluster, *(processorCtx_t *)&storage_mainProcessorCtx };
     570        (*mainProcessor){};
    532571
    533572        //initialize the global state variables
    534         TL_SET( this_processor, mainProcessor );
    535         TL_SET( this_thread, mainThread );
    536         TL_SET( this_coroutine, &mainThread->self_cor );
     573        kernelTLS.this_processor = mainProcessor;
     574        kernelTLS.this_thread    = mainThread;
     575        kernelTLS.this_coroutine = &mainThread->self_cor;
    537576
    538577        // Enable preemption
     
    546585        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    547586        // mainThread is on the ready queue when this call is made.
    548         kernel_first_resume( TL_GET( this_processor ) );
     587        kernel_first_resume( kernelTLS.this_processor );
    549588
    550589
     
    553592        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    554593
    555         verify( ! TL_GET( preemption_state ).enabled );
     594        verify( ! kernelTLS.preemption_state.enabled );
    556595        enable_interrupts( __cfaabi_dbg_ctx );
    557         verify( TL_GET( preemption_state ).enabled );
     596        verify( TL_GET( preemption_state.enabled ) );
    558597}
    559598
     
    561600        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    562601
    563         verify( TL_GET( preemption_state ).enabled );
     602        verify( TL_GET( preemption_state.enabled ) );
    564603        disable_interrupts();
    565         verify( ! TL_GET( preemption_state ).enabled );
     604        verify( ! kernelTLS.preemption_state.enabled );
    566605
    567606        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    589628
    590629//=============================================================================================
     630// Kernel Quiescing
     631//=============================================================================================
     632
     633// void halt(processor * this) with( this ) {
     634//      pthread_mutex_lock( &idle.lock );
     635
     636
     637
     638//      // SKULLDUGGERY: Even if spurious wake-up is a thing
     639//      // spuriously waking up a kernel thread is not a big deal
     640//      // if it is very rare.
     641//      pthread_cond_wait( &idle.cond, &idle.lock);
     642//      pthread_mutex_unlock( &idle.lock );
     643// }
     644
     645// void wake(processor * this) with( this ) {
     646//      pthread_mutex_lock  (&idle.lock);
     647//      pthread_cond_signal (&idle.cond);
     648//      pthread_mutex_unlock(&idle.lock);
     649// }
     650
     651//=============================================================================================
    591652// Unexpected Terminating logic
    592653//=============================================================================================
     
    594655
    595656static __spinlock_t kernel_abort_lock;
    596 static __spinlock_t kernel_debug_lock;
    597657static bool kernel_abort_called = false;
    598658
    599 void * kernel_abort    (void) __attribute__ ((__nothrow__)) {
     659void * kernel_abort(void) __attribute__ ((__nothrow__)) {
    600660        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    601661        // the globalAbort flag is true.
     
    603663
    604664        // first task to abort ?
    605         if ( ! kernel_abort_called ) {                  // not first task to abort ?
     665        if ( kernel_abort_called ) {                    // not first task to abort ?
     666                unlock( kernel_abort_lock );
     667
     668                sigset_t mask;
     669                sigemptyset( &mask );
     670                sigaddset( &mask, SIGALRM );            // block SIGALRM signals
     671                sigsuspend( &mask );                    // block the processor to prevent further damage during abort
     672                _exit( EXIT_FAILURE );                  // if processor unblocks before it is killed, terminate it
     673        }
     674        else {
    606675                kernel_abort_called = true;
    607676                unlock( kernel_abort_lock );
    608677        }
    609         else {
    610                 unlock( kernel_abort_lock );
    611 
    612                 sigset_t mask;
    613                 sigemptyset( &mask );
    614                 sigaddset( &mask, SIGALRM );                    // block SIGALRM signals
    615                 sigaddset( &mask, SIGUSR1 );                    // block SIGUSR1 signals
    616                 sigsuspend( &mask );                            // block the processor to prevent further damage during abort
    617                 _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
    618         }
    619 
    620         return TL_GET( this_thread );
     678
     679        return kernelTLS.this_thread;
    621680}
    622681
     
    624683        thread_desc * thrd = kernel_data;
    625684
    626         int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->self_cor.name, thrd );
    627         __cfaabi_dbg_bits_write( abort_text, len );
    628 
    629         if ( get_coroutine(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 ) );
     685        if(thrd) {
     686                int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd );
    631687                __cfaabi_dbg_bits_write( abort_text, len );
     688
     689                if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) {
     690                        len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine );
     691                        __cfaabi_dbg_bits_write( abort_text, len );
     692                }
     693                else {
     694                        __cfaabi_dbg_bits_write( ".\n", 2 );
     695                }
    632696        }
    633697        else {
    634                 __cfaabi_dbg_bits_write( ".\n", 2 );
     698                int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" );
    635699        }
    636700}
    637701
    638702int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    639         return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
    640 }
     703        return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
     704}
     705
     706static __spinlock_t kernel_debug_lock;
    641707
    642708extern "C" {
     
    667733        if ( count < 0 ) {
    668734                // queue current task
    669                 append( waiting, (thread_desc *)TL_GET( this_thread ) );
     735                append( waiting, kernelTLS.this_thread );
    670736
    671737                // atomically release spin lock and block
     
    693759
    694760//-----------------------------------------------------------------------------
     761// Global Queues
     762void doregister( thread_desc & thrd ) {
     763        // lock      ( global_thread.lock );
     764        // push_front( global_thread.list, thrd );
     765        // unlock    ( global_thread.lock );
     766}
     767
     768void unregister( thread_desc & thrd ) {
     769        // lock  ( global_thread.lock );
     770        // remove( global_thread.list, thrd );
     771        // unlock( global_thread.lock );
     772}
     773
     774void doregister( cluster     & cltr ) {
     775        // lock      ( global_cluster.lock );
     776        // push_front( global_cluster.list, cltr );
     777        // unlock    ( global_cluster.lock );
     778}
     779
     780void unregister( cluster     & cltr ) {
     781        // lock  ( global_cluster.lock );
     782        // remove( global_cluster.list, cltr );
     783        // unlock( global_cluster.lock );
     784}
     785
     786
     787void doregister( cluster * cltr, processor * proc ) {
     788        // lock      (cltr->proc_list_lock __cfaabi_dbg_ctx2);
     789        // push_front(cltr->procs, *proc);
     790        // unlock    (cltr->proc_list_lock);
     791}
     792
     793void unregister( cluster * cltr, processor * proc ) {
     794        // lock  (cltr->proc_list_lock __cfaabi_dbg_ctx2);
     795        // remove(cltr->procs, *proc );
     796        // unlock(cltr->proc_list_lock);
     797}
     798
     799//-----------------------------------------------------------------------------
    695800// Debug
    696801__cfaabi_dbg_debug_do(
    697         struct {
    698                 thread_desc * tail;
    699         } __cfaabi_dbg_thread_list = { NULL };
    700 
    701         void __cfaabi_dbg_thread_register( thread_desc * thrd ) {
    702                 if( !__cfaabi_dbg_thread_list.tail ) {
    703                         __cfaabi_dbg_thread_list.tail = thrd;
    704                         return;
    705                 }
    706                 __cfaabi_dbg_thread_list.tail->dbg_next = thrd;
    707                 thrd->dbg_prev = __cfaabi_dbg_thread_list.tail;
    708                 __cfaabi_dbg_thread_list.tail = thrd;
    709         }
    710 
    711         void __cfaabi_dbg_thread_unregister( thread_desc * thrd ) {
    712                 thread_desc * prev = thrd->dbg_prev;
    713                 thread_desc * next = thrd->dbg_next;
    714 
    715                 if( next ) { next->dbg_prev = prev; }
    716                 else       {
    717                         assert( __cfaabi_dbg_thread_list.tail == thrd );
    718                         __cfaabi_dbg_thread_list.tail = prev;
    719                 }
    720 
    721                 if( prev ) { prev->dbg_next = next; }
    722 
    723                 thrd->dbg_prev = NULL;
    724                 thrd->dbg_next = NULL;
     802        void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
     803                this.prev_name = prev_name;
     804                this.prev_thrd = kernelTLS.this_thread;
    725805        }
    726806)
Note: See TracChangeset for help on using the changeset viewer.