Ignore:
File:
1 edited

Legend:

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

    rde94a60 r01963df  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr  9 16:11:46 2018
    13 // Update Count     : 24
     12// Last Modified On : Fri Mar 30 18:26:11 2018
     13// Update Count     : 23
    1414//
    1515
     
    2525
    2626//CFA Includes
    27 #include "time"
    2827#include "kernel_private.h"
    2928#include "preemption.h"
     
    4241KERNEL_STORAGE(cluster,           mainCluster);
    4342KERNEL_STORAGE(processor,         mainProcessor);
     43KERNEL_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 
    51 struct { __dllist_t(thread_desc) list; __spinlock_t lock; } global_threads ;
    52 struct { __dllist_t(cluster    ) list; __spinlock_t lock; } global_clusters;
    5350
    5451//-----------------------------------------------------------------------------
     
    5956// volatile thread_local unsigned short disable_preempt_count = 1;
    6057
    61 thread_local struct KernelThreadData kernelTLS = {
     58thread_local struct KernelThreadData kernelThreadData = {
    6259        NULL,
    6360        NULL,
     
    6764
    6865//-----------------------------------------------------------------------------
    69 // Struct to steal stack
     66// Main thread construction
    7067struct current_stack_info_t {
    7168        machine_context_t ctx;
     
    9289}
    9390
    94 //-----------------------------------------------------------------------------
    95 // Main thread construction
    9691void ?{}( coStack_t & this, current_stack_info_t * info) with( this ) {
    9792        size      = info->size;
     
    115110        self_cor{ info };
    116111        curr_cor = &self_cor;
    117         curr_cluster = mainCluster;
    118112        self_mon.owner = &this;
    119113        self_mon.recursion = 1;
    120114        self_mon_p = &self_mon;
    121115        next = NULL;
    122 
    123         node.next = NULL;
    124         node.prev = NULL;
    125         doregister(this);
     116        __cfaabi_dbg_debug_do(
     117                dbg_next = NULL;
     118                dbg_prev = NULL;
     119                __cfaabi_dbg_thread_register(&this);
     120        )
    126121
    127122        monitors{ &self_mon_p, 1, (fptr_t)0 };
     
    130125//-----------------------------------------------------------------------------
    131126// Processor coroutine
    132 void ?{}(processorCtx_t & this) {
    133 
     127void ?{}(processorCtx_t & this) {}
     128
     129// Construct the processor context of the main processor
     130void ?{}(processorCtx_t & this, processor * proc) {
     131        (this.__cor){ "Processor" };
     132        this.__cor.starter = NULL;
     133        this.proc = proc;
    134134}
    135135
     
    140140}
    141141
    142 void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {
    143         this.name = name;
    144         this.cltr = &cltr;
     142void ?{}(processor & this) {
     143        this{ mainCluster };
     144}
     145
     146void ?{}(processor & this, cluster * cltr) with( this ) {
     147        this.cltr = cltr;
    145148        terminated{ 0 };
    146149        do_terminate = false;
     
    152155}
    153156
     157void ?{}(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
    154170void ^?{}(processor & this) with( this ){
    155171        if( ! do_terminate ) {
     
    157173                terminate(&this);
    158174                verify(this.do_terminate);
    159                 verify( kernelTLS.this_processor != &this);
     175                verify(TL_GET( this_processor ) != &this);
    160176                P( terminated );
    161                 verify( kernelTLS.this_processor != &this);
     177                verify(TL_GET( this_processor ) != &this);
    162178                pthread_join( kernel_thread, NULL );
    163179        }
    164180}
    165181
    166 void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) {
    167         this.name = name;
    168         this.preemption_rate = preemption_rate;
     182void ?{}(cluster & this) with( this ) {
    169183        ready_queue{};
    170184        ready_queue_lock{};
    171185
    172         procs{ __get };
    173         idles{ __get };
    174 
    175         doregister(this);
     186        preemption_rate = default_preemption();
    176187}
    177188
    178189void ^?{}(cluster & this) {
    179         unregister(this);
     190
    180191}
    181192
     
    190201        __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
    191202
    192         doregister(this->cltr, this);
    193 
    194203        {
    195204                // Setup preemption data
     
    205214                        if(readyThread)
    206215                        {
    207                                 verify( ! kernelTLS.preemption_state.enabled );
     216                                verify( ! TL_GET( preemption_state ).enabled );
    208217
    209218                                runThread(this, readyThread);
    210219
    211                                 verify( ! kernelTLS.preemption_state.enabled );
     220                                verify( ! TL_GET( preemption_state ).enabled );
    212221
    213222                                //Some actions need to be taken from the kernel
     
    225234        }
    226235
    227         unregister(this->cltr, this);
    228 
    229236        V( this->terminated );
    230237
     
    232239}
    233240
    234 // KERNEL ONLY
    235241// runThread runs a thread by context switching
    236242// from the processor coroutine to the target thread
     
    240246        coroutine_desc * thrd_cor = dst->curr_cor;
    241247
    242         // Reset the terminating actions here
     248        //Reset the terminating actions here
    243249        this->finish.action_code = No_Action;
    244250
    245         // Update global state
    246         kernelTLS.this_thread = dst;
     251        //Update global state
     252        TL_SET( this_thread, dst );
    247253
    248254        // Context Switch to the thread
     
    251257}
    252258
    253 // KERNEL_ONLY
    254259void returnToKernel() {
    255         coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
    256         coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine;
     260        coroutine_desc * proc_cor = get_coroutine(TL_GET( this_processor )->runner);
     261        coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );
    257262        ThreadCtxSwitch(thrd_cor, proc_cor);
    258263}
    259264
    260 // KERNEL_ONLY
    261265// Once a thread has finished running, some of
    262266// its final actions must be executed from the kernel
    263267void finishRunning(processor * this) with( this->finish ) {
    264268        if( action_code == Release ) {
    265                 verify( ! kernelTLS.preemption_state.enabled );
     269                verify( ! TL_GET( preemption_state ).enabled );
    266270                unlock( *lock );
    267271        }
     
    270274        }
    271275        else if( action_code == Release_Schedule ) {
    272                 verify( ! kernelTLS.preemption_state.enabled );
     276                verify( ! TL_GET( preemption_state ).enabled );
    273277                unlock( *lock );
    274278                ScheduleThread( thrd );
    275279        }
    276280        else if( action_code == Release_Multi ) {
    277                 verify( ! kernelTLS.preemption_state.enabled );
     281                verify( ! TL_GET( preemption_state ).enabled );
    278282                for(int i = 0; i < lock_count; i++) {
    279283                        unlock( *locks[i] );
     
    299303}
    300304
    301 // KERNEL_ONLY
    302305// Context invoker for processors
    303306// This is the entry point for processors (kernel threads)
     
    305308void * CtxInvokeProcessor(void * arg) {
    306309        processor * proc = (processor *) arg;
    307         kernelTLS.this_processor = proc;
    308         kernelTLS.this_coroutine = NULL;
    309         kernelTLS.this_thread    = NULL;
    310         kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
     310        TL_SET( this_processor, proc );
     311        TL_SET( this_coroutine, NULL );
     312        TL_SET( this_thread, NULL );
     313        TL_GET( preemption_state ).enabled = false;
     314        TL_GET( preemption_state ).disable_count = 1;
    311315        // SKULLDUGGERY: We want to create a context for the processor coroutine
    312316        // which is needed for the 2-step context switch. However, there is no reason
     
    320324
    321325        //Set global state
    322         kernelTLS.this_coroutine = get_coroutine(proc->runner);
    323         kernelTLS.this_thread    = NULL;
     326        TL_SET( this_coroutine, get_coroutine(proc->runner) );
     327        TL_SET( this_thread, NULL );
    324328
    325329        //We now have a proper context from which to schedule threads
     
    348352}
    349353
    350 // KERNEL_ONLY
    351354void kernel_first_resume(processor * this) {
    352         coroutine_desc * src = kernelTLS.this_coroutine;
     355        coroutine_desc * src = TL_GET( this_coroutine );
    353356        coroutine_desc * dst = get_coroutine(this->runner);
    354357
    355         verify( ! kernelTLS.preemption_state.enabled );
     358        verify( ! TL_GET( preemption_state ).enabled );
    356359
    357360        create_stack(&dst->stack, dst->stack.size);
    358361        CtxStart(&this->runner, CtxInvokeCoroutine);
    359362
    360         verify( ! kernelTLS.preemption_state.enabled );
     363        verify( ! TL_GET( preemption_state ).enabled );
    361364
    362365        dst->last = src;
     
    367370
    368371        // set new coroutine that task is executing
    369         kernelTLS.this_coroutine = dst;
     372        TL_SET( this_coroutine, dst );
    370373
    371374        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    384387        src->state = Active;
    385388
    386         verify( ! kernelTLS.preemption_state.enabled );
     389        verify( ! TL_GET( preemption_state ).enabled );
    387390}
    388391
    389392//-----------------------------------------------------------------------------
    390393// Scheduler routines
    391 
    392 // KERNEL ONLY
    393394void ScheduleThread( thread_desc * thrd ) {
     395        // if( ! thrd ) return;
    394396        verify( thrd );
    395397        verify( thrd->self_cor.state != Halted );
    396398
    397         verify( ! kernelTLS.preemption_state.enabled );
     399        verify( ! TL_GET( preemption_state ).enabled );
    398400
    399401        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    400402
    401         with( *thrd->curr_cluster ) {
     403        with( *TL_GET( this_processor )->cltr ) {
    402404                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    403405                append( ready_queue, thrd );
     
    405407        }
    406408
    407         verify( ! kernelTLS.preemption_state.enabled );
    408 }
    409 
    410 // KERNEL ONLY
     409        verify( ! TL_GET( preemption_state ).enabled );
     410}
     411
    411412thread_desc * nextThread(cluster * this) with( *this ) {
    412         verify( ! kernelTLS.preemption_state.enabled );
     413        verify( ! TL_GET( preemption_state ).enabled );
    413414        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    414415        thread_desc * head = pop_head( ready_queue );
    415416        unlock( ready_queue_lock );
    416         verify( ! kernelTLS.preemption_state.enabled );
     417        verify( ! TL_GET( preemption_state ).enabled );
    417418        return head;
    418419}
     
    420421void BlockInternal() {
    421422        disable_interrupts();
    422         verify( ! kernelTLS.preemption_state.enabled );
     423        verify( ! TL_GET( preemption_state ).enabled );
    423424        returnToKernel();
    424         verify( ! kernelTLS.preemption_state.enabled );
     425        verify( ! TL_GET( preemption_state ).enabled );
    425426        enable_interrupts( __cfaabi_dbg_ctx );
    426427}
     
    428429void BlockInternal( __spinlock_t * lock ) {
    429430        disable_interrupts();
    430         with( *kernelTLS.this_processor ) {
    431                 finish.action_code = Release;
    432                 finish.lock        = lock;
    433         }
    434 
    435         verify( ! kernelTLS.preemption_state.enabled );
     431        TL_GET( this_processor )->finish.action_code = Release;
     432        TL_GET( this_processor )->finish.lock        = lock;
     433
     434        verify( ! TL_GET( preemption_state ).enabled );
    436435        returnToKernel();
    437         verify( ! kernelTLS.preemption_state.enabled );
     436        verify( ! TL_GET( preemption_state ).enabled );
    438437
    439438        enable_interrupts( __cfaabi_dbg_ctx );
     
    442441void BlockInternal( thread_desc * thrd ) {
    443442        disable_interrupts();
    444         with( * kernelTLS.this_processor ) {
    445                 finish.action_code = Schedule;
    446                 finish.thrd        = thrd;
    447         }
    448 
    449         verify( ! kernelTLS.preemption_state.enabled );
     443        TL_GET( this_processor )->finish.action_code = Schedule;
     444        TL_GET( this_processor )->finish.thrd        = thrd;
     445
     446        verify( ! TL_GET( preemption_state ).enabled );
    450447        returnToKernel();
    451         verify( ! kernelTLS.preemption_state.enabled );
     448        verify( ! TL_GET( preemption_state ).enabled );
    452449
    453450        enable_interrupts( __cfaabi_dbg_ctx );
     
    457454        assert(thrd);
    458455        disable_interrupts();
    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 );
     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 );
    466461        returnToKernel();
    467         verify( ! kernelTLS.preemption_state.enabled );
     462        verify( ! TL_GET( preemption_state ).enabled );
    468463
    469464        enable_interrupts( __cfaabi_dbg_ctx );
     
    472467void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    473468        disable_interrupts();
    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 );
     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 );
    481474        returnToKernel();
    482         verify( ! kernelTLS.preemption_state.enabled );
     475        verify( ! TL_GET( preemption_state ).enabled );
    483476
    484477        enable_interrupts( __cfaabi_dbg_ctx );
     
    487480void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    488481        disable_interrupts();
    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 );
     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 );
    498489        returnToKernel();
    499         verify( ! kernelTLS.preemption_state.enabled );
     490        verify( ! TL_GET( preemption_state ).enabled );
    500491
    501492        enable_interrupts( __cfaabi_dbg_ctx );
    502493}
    503494
    504 // KERNEL ONLY
    505495void LeaveThread(__spinlock_t * lock, thread_desc * 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         }
     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;
    512500
    513501        returnToKernel();
     
    520508// Kernel boot procedures
    521509void kernel_startup(void) {
    522         verify( ! kernelTLS.preemption_state.enabled );
     510        verify( ! TL_GET( preemption_state ).enabled );
    523511        __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");
    535512
    536513        // Start by initializing the main thread
     
    543520        __cfaabi_dbg_print_safe("Kernel : Main thread ready\n");
    544521
    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         }
     522        // Initialize the main cluster
     523        mainCluster = (cluster *)&storage_mainCluster;
     524        (*mainCluster){};
     525
     526        __cfaabi_dbg_print_safe("Kernel : main cluster ready\n");
    566527
    567528        // Initialize the main processor and the main processor ctx
    568529        // (the coroutine that contains the processing control flow)
    569530        mainProcessor = (processor *)&storage_mainProcessor;
    570         (*mainProcessor){};
     531        (*mainProcessor){ mainCluster, *(processorCtx_t *)&storage_mainProcessorCtx };
    571532
    572533        //initialize the global state variables
    573         kernelTLS.this_processor = mainProcessor;
    574         kernelTLS.this_thread    = mainThread;
    575         kernelTLS.this_coroutine = &mainThread->self_cor;
     534        TL_SET( this_processor, mainProcessor );
     535        TL_SET( this_thread, mainThread );
     536        TL_SET( this_coroutine, &mainThread->self_cor );
    576537
    577538        // Enable preemption
     
    585546        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    586547        // mainThread is on the ready queue when this call is made.
    587         kernel_first_resume( kernelTLS.this_processor );
     548        kernel_first_resume( TL_GET( this_processor ) );
    588549
    589550
     
    592553        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    593554
    594         verify( ! kernelTLS.preemption_state.enabled );
     555        verify( ! TL_GET( preemption_state ).enabled );
    595556        enable_interrupts( __cfaabi_dbg_ctx );
    596         verify( TL_GET( preemption_state.enabled ) );
     557        verify( TL_GET( preemption_state ).enabled );
    597558}
    598559
     
    600561        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    601562
    602         verify( TL_GET( preemption_state.enabled ) );
     563        verify( TL_GET( preemption_state ).enabled );
    603564        disable_interrupts();
    604         verify( ! kernelTLS.preemption_state.enabled );
     565        verify( ! TL_GET( preemption_state ).enabled );
    605566
    606567        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    628589
    629590//=============================================================================================
    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 //=============================================================================================
    652591// Unexpected Terminating logic
    653592//=============================================================================================
     
    655594
    656595static __spinlock_t kernel_abort_lock;
     596static __spinlock_t kernel_debug_lock;
    657597static bool kernel_abort_called = false;
    658598
    659 void * kernel_abort(void) __attribute__ ((__nothrow__)) {
     599void * kernel_abort    (void) __attribute__ ((__nothrow__)) {
    660600        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    661601        // the globalAbort flag is true.
     
    663603
    664604        // first task to abort ?
    665         if ( kernel_abort_called ) {                    // not first task to abort ?
     605        if ( ! kernel_abort_called ) {                  // not first task to abort ?
     606                kernel_abort_called = true;
     607                unlock( kernel_abort_lock );
     608        }
     609        else {
    666610                unlock( kernel_abort_lock );
    667611
    668612                sigset_t mask;
    669613                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 {
    675                 kernel_abort_called = true;
    676                 unlock( kernel_abort_lock );
    677         }
    678 
    679         return kernelTLS.this_thread;
     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 );
    680621}
    681622
     
    683624        thread_desc * thrd = kernel_data;
    684625
    685         if(thrd) {
    686                 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd );
     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 ) );
    687631                __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                 }
    696632        }
    697633        else {
    698                 int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" );
     634                __cfaabi_dbg_bits_write( ".\n", 2 );
    699635        }
    700636}
    701637
    702638int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    703         return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
    704 }
    705 
    706 static __spinlock_t kernel_debug_lock;
     639        return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
     640}
    707641
    708642extern "C" {
     
    733667        if ( count < 0 ) {
    734668                // queue current task
    735                 append( waiting, kernelTLS.this_thread );
     669                append( waiting, (thread_desc *)TL_GET( this_thread ) );
    736670
    737671                // atomically release spin lock and block
     
    759693
    760694//-----------------------------------------------------------------------------
    761 // Global Queues
    762 void doregister( thread_desc & thrd ) {
    763         // lock      ( global_thread.lock );
    764         // push_front( global_thread.list, thrd );
    765         // unlock    ( global_thread.lock );
    766 }
    767 
    768 void unregister( thread_desc & thrd ) {
    769         // lock  ( global_thread.lock );
    770         // remove( global_thread.list, thrd );
    771         // unlock( global_thread.lock );
    772 }
    773 
    774 void doregister( cluster     & cltr ) {
    775         // lock      ( global_cluster.lock );
    776         // push_front( global_cluster.list, cltr );
    777         // unlock    ( global_cluster.lock );
    778 }
    779 
    780 void unregister( cluster     & cltr ) {
    781         // lock  ( global_cluster.lock );
    782         // remove( global_cluster.list, cltr );
    783         // unlock( global_cluster.lock );
    784 }
    785 
    786 
    787 void 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 
    793 void 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 //-----------------------------------------------------------------------------
    800695// Debug
    801696__cfaabi_dbg_debug_do(
    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;
     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;
    805725        }
    806726)
Note: See TracChangeset for help on using the changeset viewer.