Changes in / [5fec3f6:387c9a1]


Ignore:
Location:
src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • src/Common/Heap.cc

    r5fec3f6 r387c9a1  
    130130                                abort();
    131131                        }
    132 #endif // RTLD_NEXT
     132#endif
    133133                } // if
    134134
     
    144144                fptr = (generic_fptr_t)dlsym( library, symbol );
    145145#endif // _GNU_SOURCE
    146 
    147                 error = dlerror();
    148                 if ( error ) {
    149                         std::cerr << "interpose_symbol : internal error, " << error << std::endl;
    150                         abort();
    151                 }
    152 
    153                 return fptr;
    154         }
    155146
    156147        extern "C" {
  • src/libcfa/bits/containers.h

    r5fec3f6 r387c9a1  
    186186#endif
    187187
    188 
    189 //-----------------------------------------------------------------------------
    190 // Doubly Linked List
    191 //-----------------------------------------------------------------------------
    192 #ifdef __cforall
    193         trait is_db_node(dtype T) {
    194                 T*& get_next( T& );
    195                 T*& get_prev( T& );
    196         };
    197 #endif
    198 
    199 #ifdef __cforall
    200         forall(dtype TYPE | is_db_node(TYPE))
    201         #define T TYPE
    202 #else
    203         #define T void
    204 #endif
    205 struct __dllist {
    206         T * head;
    207 };
    208 #undef T
    209 
    210 #ifdef __cforall
    211 #define __dllist_t(T) __dllist(T)
    212 #else
    213 #define __dllist_t(T) struct __dllist
    214 #endif
    215 
    216 #ifdef __cforall
    217 
    218         forall(dtype T | is_db_node(T))
    219         static inline void ?{}( __dllist(T) & this ) with( this ) {
    220                 head{ NULL };
    221         }
    222 
    223         // forall(dtype T | is_db_node(T) | sized(T))
    224         // static inline void push_front( __dllist(T) & this, T & node ) with( this ) {
    225         //      if ( head ) {
    226         //              get_next( node ) = head;
    227         //              get_prev( node ) = get_prev( *head );
    228         //              // inserted node must be consistent before it is seen
    229         //              // prevent code movement across barrier
    230         //              asm( "" : : : "memory" );
    231         //              get_prev( *head ) = node;
    232         //              T & prev = *get_prev( node );
    233         //              get_next( prev ) = node;
    234         //      }
    235         //      else {
    236         //              get_next( node ) = &node;
    237         //              get_prev( node ) = &node;
    238         //      }
    239 
    240         //      // prevent code movement across barrier
    241         //      asm( "" : : : "memory" );
    242         //      head = val;
    243         // }
    244 
    245         // forall(dtype T | is_db_node(T) | sized(T))
    246         // static inline T * remove( __dllist(T) & this, T & node ) with( this ) {
    247         //      if ( &node == head ) {
    248         //              if ( get_next( *head ) == head ) {
    249         //                      head = NULL;
    250         //              }
    251         //              else {
    252         //                      head = get_next( *head );
    253         //              }
    254         //      }
    255         //      get_prev( *get_next( node ) ) = get_prev( node );
    256         //      get_next( *get_prev( node ) ) = get_next( node );
    257         //      get_next( node ) = NULL;
    258         //      get_prev( node ) = NULL;
    259         // }
    260 #endif
    261 
    262188//-----------------------------------------------------------------------------
    263189// Tools
  • src/libcfa/concurrency/coroutine

    r5fec3f6 r387c9a1  
    7272// Suspend implementation inlined for performance
    7373static inline void suspend() {
    74         // optimization : read TLS once and reuse it
    75         // Safety note: this is preemption safe since if
    76         // preemption occurs after this line, the pointer
    77         // will also migrate which means this value will
    78         // stay in syn with the TLS
    79         coroutine_desc * src = TL_GET( this_coroutine );
     74        coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
    8075
    8176        assertf( src->last != 0,
     
    9489forall(dtype T | is_coroutine(T))
    9590static inline void resume(T & cor) {
    96         // optimization : read TLS once and reuse it
    97         // Safety note: this is preemption safe since if
    98         // preemption occurs after this line, the pointer
    99         // will also migrate which means this value will
    100         // stay in syn with the TLS
    101         coroutine_desc * src = TL_GET( this_coroutine );
     91        coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
    10292        coroutine_desc * dst = get_coroutine(cor);
    10393
     
    117107                dst->last = src;
    118108                dst->starter = dst->starter ? dst->starter : src;
    119         }
     109        } // if
    120110
    121111        // always done for performance testing
     
    124114
    125115static inline void resume(coroutine_desc * dst) {
    126         // optimization : read TLS once and reuse it
    127         // Safety note: this is preemption safe since if
    128         // preemption occurs after this line, the pointer
    129         // will also migrate which means this value will
    130         // stay in syn with the TLS
    131         coroutine_desc * src = TL_GET( this_coroutine );
     116        coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
    132117
    133118        // not resuming self ?
     
    140125                // set last resumer
    141126                dst->last = src;
    142         }
     127        } // if
    143128
    144129        // always done for performance testing
  • src/libcfa/concurrency/coroutine.c

    r5fec3f6 r387c9a1  
    8484// Wrapper for co
    8585void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    86       // Safety note : This could cause some false positives due to preemption
    8786      verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
    8887      disable_interrupts();
     
    9291
    9392      // set new coroutine that task is executing
    94       kernelTLS.this_coroutine = dst;
     93      TL_SET( this_coroutine, dst );
    9594
    9695      // context switch to specified coroutine
     
    103102
    104103      enable_interrupts( __cfaabi_dbg_ctx );
    105       // Safety note : This could cause some false positives due to preemption
    106104      verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
    107105} //ctxSwitchDirect
  • src/libcfa/concurrency/invoke.h

    r5fec3f6 r387c9a1  
    1818#include "bits/locks.h"
    1919
    20 #define TL_GET( member ) kernelTLS.member
    21 #define TL_SET( member, value ) kernelTLS.member = value;
     20#define TL_GET( member ) kernelThreadData.member
     21#define TL_SET( member, value ) kernelThreadData.member = value;
    2222
    2323#ifdef __cforall
     
    4444                                volatile bool in_progress;
    4545                        } preemption_state;
    46                 } kernelTLS;
     46                } kernelThreadData;
    4747        }
    4848
    4949        static inline struct coroutine_desc * volatile active_coroutine() { return TL_GET( this_coroutine ); }
    50         static inline struct thread_desc    * volatile active_thread   () { return TL_GET( this_thread    ); }
    51         // static inline struct processor      * volatile active_processor() { return TL_GET( this_processor ); } // UNSAFE
     50        static inline struct thread_desc * volatile active_thread() { return TL_GET( this_thread ); }
     51        static inline struct processor * volatile active_processor() { return TL_GET( this_processor ); }
    5252        #endif
    5353
  • src/libcfa/concurrency/kernel

    r5fec3f6 r387c9a1  
    5353        // Preemption rate on this cluster
    5454        Duration preemption_rate;
    55 
    56         // List of idle processors
    57         // __dllist_t(struct processor) idles;
    5855};
    5956
     
    127124        bool pending_preemption;
    128125
    129         struct {
    130                 pthread_mutex_t lock;
    131                 pthread_cond_t  cond;
    132         } idle;
    133 
    134126#ifdef __CFA_DEBUG__
    135127        // Last function to enable preemption on this processor
  • src/libcfa/concurrency/kernel.c

    r5fec3f6 r387c9a1  
    5656// volatile thread_local unsigned short disable_preempt_count = 1;
    5757
    58 thread_local struct KernelThreadData kernelTLS = {
     58thread_local struct KernelThreadData kernelThreadData = {
    5959        NULL,
    6060        NULL,
     
    155155                terminate(&this);
    156156                verify(this.do_terminate);
    157                 verify( kernelTLS.this_processor != &this);
     157                verify(TL_GET( this_processor ) != &this);
    158158                P( terminated );
    159                 verify( kernelTLS.this_processor != &this);
     159                verify(TL_GET( this_processor ) != &this);
    160160                pthread_join( kernel_thread, NULL );
    161161        }
     
    196196                        if(readyThread)
    197197                        {
    198                                 verify( ! kernelTLS.preemption_state.enabled );
     198                                verify( ! TL_GET( preemption_state ).enabled );
    199199
    200200                                runThread(this, readyThread);
    201201
    202                                 verify( ! kernelTLS.preemption_state.enabled );
     202                                verify( ! TL_GET( preemption_state ).enabled );
    203203
    204204                                //Some actions need to be taken from the kernel
     
    221221}
    222222
    223 // KERNEL ONLY
    224223// runThread runs a thread by context switching
    225224// from the processor coroutine to the target thread
     
    229228        coroutine_desc * thrd_cor = dst->curr_cor;
    230229
    231         // Reset the terminating actions here
     230        //Reset the terminating actions here
    232231        this->finish.action_code = No_Action;
    233232
    234         // Update global state
    235         kernelTLS.this_thread = dst;
     233        //Update global state
     234        TL_SET( this_thread, dst );
    236235
    237236        // Context Switch to the thread
     
    240239}
    241240
    242 // KERNEL_ONLY
    243241void returnToKernel() {
    244         coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
    245         coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine;
     242        coroutine_desc * proc_cor = get_coroutine(TL_GET( this_processor )->runner);
     243        coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );
    246244        ThreadCtxSwitch(thrd_cor, proc_cor);
    247245}
    248246
    249 // KERNEL_ONLY
    250247// Once a thread has finished running, some of
    251248// its final actions must be executed from the kernel
    252249void finishRunning(processor * this) with( this->finish ) {
    253250        if( action_code == Release ) {
    254                 verify( ! kernelTLS.preemption_state.enabled );
     251                verify( ! TL_GET( preemption_state ).enabled );
    255252                unlock( *lock );
    256253        }
     
    259256        }
    260257        else if( action_code == Release_Schedule ) {
    261                 verify( ! kernelTLS.preemption_state.enabled );
     258                verify( ! TL_GET( preemption_state ).enabled );
    262259                unlock( *lock );
    263260                ScheduleThread( thrd );
    264261        }
    265262        else if( action_code == Release_Multi ) {
    266                 verify( ! kernelTLS.preemption_state.enabled );
     263                verify( ! TL_GET( preemption_state ).enabled );
    267264                for(int i = 0; i < lock_count; i++) {
    268265                        unlock( *locks[i] );
     
    288285}
    289286
    290 // KERNEL_ONLY
    291287// Context invoker for processors
    292288// This is the entry point for processors (kernel threads)
     
    294290void * CtxInvokeProcessor(void * arg) {
    295291        processor * proc = (processor *) arg;
    296         kernelTLS.this_processor = proc;
    297         kernelTLS.this_coroutine = NULL;
    298         kernelTLS.this_thread    = NULL;
    299         kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
     292        TL_SET( this_processor, proc );
     293        TL_SET( this_coroutine, NULL );
     294        TL_SET( this_thread, NULL );
     295        TL_GET( preemption_state ).[enabled, disable_count] = [false, 1];
    300296        // SKULLDUGGERY: We want to create a context for the processor coroutine
    301297        // which is needed for the 2-step context switch. However, there is no reason
     
    309305
    310306        //Set global state
    311         kernelTLS.this_coroutine = get_coroutine(proc->runner);
    312         kernelTLS.this_thread    = NULL;
     307        TL_SET( this_coroutine, get_coroutine(proc->runner) );
     308        TL_SET( this_thread, NULL );
    313309
    314310        //We now have a proper context from which to schedule threads
     
    337333}
    338334
    339 // KERNEL_ONLY
    340335void kernel_first_resume(processor * this) {
    341         coroutine_desc * src = kernelTLS.this_coroutine;
     336        coroutine_desc * src = TL_GET( this_coroutine );
    342337        coroutine_desc * dst = get_coroutine(this->runner);
    343338
    344         verify( ! kernelTLS.preemption_state.enabled );
     339        verify( ! TL_GET( preemption_state ).enabled );
    345340
    346341        create_stack(&dst->stack, dst->stack.size);
    347342        CtxStart(&this->runner, CtxInvokeCoroutine);
    348343
    349         verify( ! kernelTLS.preemption_state.enabled );
     344        verify( ! TL_GET( preemption_state ).enabled );
    350345
    351346        dst->last = src;
     
    356351
    357352        // set new coroutine that task is executing
    358         kernelTLS.this_coroutine = dst;
     353        TL_SET( this_coroutine, dst );
    359354
    360355        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    373368        src->state = Active;
    374369
    375         verify( ! kernelTLS.preemption_state.enabled );
     370        verify( ! TL_GET( preemption_state ).enabled );
    376371}
    377372
    378373//-----------------------------------------------------------------------------
    379374// Scheduler routines
    380 
    381 // KERNEL ONLY
    382375void ScheduleThread( thread_desc * thrd ) {
     376        // if( ! thrd ) return;
    383377        verify( thrd );
    384378        verify( thrd->self_cor.state != Halted );
    385379
    386         verify( ! kernelTLS.preemption_state.enabled );
     380        verify( ! TL_GET( preemption_state ).enabled );
    387381
    388382        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
     
    394388        }
    395389
    396         verify( ! kernelTLS.preemption_state.enabled );
    397 }
    398 
    399 // KERNEL ONLY
     390        verify( ! TL_GET( preemption_state ).enabled );
     391}
     392
    400393thread_desc * nextThread(cluster * this) with( *this ) {
    401         verify( ! kernelTLS.preemption_state.enabled );
     394        verify( ! TL_GET( preemption_state ).enabled );
    402395        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    403396        thread_desc * head = pop_head( ready_queue );
    404397        unlock( ready_queue_lock );
    405         verify( ! kernelTLS.preemption_state.enabled );
     398        verify( ! TL_GET( preemption_state ).enabled );
    406399        return head;
    407400}
     
    409402void BlockInternal() {
    410403        disable_interrupts();
    411         verify( ! kernelTLS.preemption_state.enabled );
     404        verify( ! TL_GET( preemption_state ).enabled );
    412405        returnToKernel();
    413         verify( ! kernelTLS.preemption_state.enabled );
     406        verify( ! TL_GET( preemption_state ).enabled );
    414407        enable_interrupts( __cfaabi_dbg_ctx );
    415408}
     
    417410void BlockInternal( __spinlock_t * lock ) {
    418411        disable_interrupts();
    419         with( *kernelTLS.this_processor ) {
     412        with( *TL_GET( this_processor ) ) {
    420413                finish.action_code = Release;
    421414                finish.lock        = lock;
    422415        }
    423416
    424         verify( ! preemption_state.enabled );
     417        verify( ! TL_GET( preemption_state ).enabled );
    425418        returnToKernel();
    426         verify( ! preemption_state.enabled );
     419        verify( ! TL_GET( preemption_state ).enabled );
    427420
    428421        enable_interrupts( __cfaabi_dbg_ctx );
     
    431424void BlockInternal( thread_desc * thrd ) {
    432425        disable_interrupts();
    433         with( * kernelTLS.this_processor ) {
     426        with( *TL_GET( this_processor ) ) {
    434427                finish.action_code = Schedule;
    435428                finish.thrd        = thrd;
    436429        }
    437430
    438         verify( ! kernelTLS.preemption_state.enabled );
     431        verify( ! TL_GET( preemption_state ).enabled );
    439432        returnToKernel();
    440         verify( ! kernelTLS.preemption_state.enabled );
     433        verify( ! TL_GET( preemption_state ).enabled );
    441434
    442435        enable_interrupts( __cfaabi_dbg_ctx );
     
    446439        assert(thrd);
    447440        disable_interrupts();
    448         with( * kernelTLS.this_processor ) {
     441        with( *TL_GET( this_processor ) ) {
    449442                finish.action_code = Release_Schedule;
    450443                finish.lock        = lock;
     
    452445        }
    453446
    454         verify( ! kernelTLS.preemption_state.enabled );
     447        verify( ! TL_GET( preemption_state ).enabled );
    455448        returnToKernel();
    456         verify( ! kernelTLS.preemption_state.enabled );
     449        verify( ! TL_GET( preemption_state ).enabled );
    457450
    458451        enable_interrupts( __cfaabi_dbg_ctx );
     
    461454void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    462455        disable_interrupts();
    463         with( * kernelTLS.this_processor ) {
     456        with( *TL_GET( this_processor ) ) {
    464457                finish.action_code = Release_Multi;
    465458                finish.locks       = locks;
     
    467460        }
    468461
    469         verify( ! kernelTLS.preemption_state.enabled );
     462        verify( ! TL_GET( preemption_state ).enabled );
    470463        returnToKernel();
    471         verify( ! kernelTLS.preemption_state.enabled );
     464        verify( ! TL_GET( preemption_state ).enabled );
    472465
    473466        enable_interrupts( __cfaabi_dbg_ctx );
     
    476469void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    477470        disable_interrupts();
    478         with( *kernelTLS.this_processor ) {
     471        with( *TL_GET( this_processor ) ) {
    479472                finish.action_code = Release_Multi_Schedule;
    480473                finish.locks       = locks;
     
    484477        }
    485478
    486         verify( ! kernelTLS.preemption_state.enabled );
     479        verify( ! TL_GET( preemption_state ).enabled );
    487480        returnToKernel();
    488         verify( ! kernelTLS.preemption_state.enabled );
     481        verify( ! TL_GET( preemption_state ).enabled );
    489482
    490483        enable_interrupts( __cfaabi_dbg_ctx );
    491484}
    492485
    493 // KERNEL ONLY
    494486void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    495         verify( ! kernelTLS.preemption_state.enabled );
    496         with( * kernelTLS.this_processor ) {
     487        verify( ! TL_GET( preemption_state ).enabled );
     488        with( *TL_GET( this_processor ) ) {
    497489                finish.action_code = thrd ? Release_Schedule : Release;
    498490                finish.lock        = lock;
     
    509501// Kernel boot procedures
    510502void kernel_startup(void) {
    511         verify( ! kernelTLS.preemption_state.enabled );
     503        verify( ! TL_GET( preemption_state ).enabled );
    512504        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    513505
     
    555547
    556548        //initialize the global state variables
    557         kernelTLS.this_processor = mainProcessor;
    558         kernelTLS.this_thread    = mainThread;
    559         kernelTLS.this_coroutine = &mainThread->self_cor;
     549        TL_SET( this_processor, mainProcessor );
     550        TL_SET( this_thread, mainThread );
     551        TL_SET( this_coroutine, &mainThread->self_cor );
    560552
    561553        // Enable preemption
     
    569561        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    570562        // mainThread is on the ready queue when this call is made.
    571         kernel_first_resume( kernelTLS.this_processor );
     563        kernel_first_resume( TL_GET( this_processor ) );
    572564
    573565
     
    576568        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    577569
    578         verify( ! kernelTLS.preemption_state.enabled );
     570        verify( ! TL_GET( preemption_state ).enabled );
    579571        enable_interrupts( __cfaabi_dbg_ctx );
    580572        verify( TL_GET( preemption_state ).enabled );
     
    586578        verify( TL_GET( preemption_state ).enabled );
    587579        disable_interrupts();
    588         verify( ! kernelTLS.preemption_state.enabled );
     580        verify( ! TL_GET( preemption_state ).enabled );
    589581
    590582        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    610602        __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n");
    611603}
    612 
    613 //=============================================================================================
    614 // Kernel Quiescing
    615 //=============================================================================================
    616 
    617 // void halt(processor * this) with( this ) {
    618 //      pthread_mutex_lock( &idle.lock );
    619 
    620 
    621 
    622 //      // SKULLDUGGERY: Even if spurious wake-up is a thing
    623 //      // spuriously waking up a kernel thread is not a big deal
    624 //      // if it is very rare.
    625 //      pthread_cond_wait( &idle.cond, &idle.lock);
    626 //      pthread_mutex_unlock( &idle.lock );
    627 // }
    628 
    629 // void wake(processor * this) with( this ) {
    630 //      pthread_mutex_lock  (&idle.lock);
    631 //      pthread_cond_signal (&idle.cond);
    632 //      pthread_mutex_unlock(&idle.lock);
    633 // }
    634604
    635605//=============================================================================================
     
    663633        }
    664634
    665         return kernelTLS.this_thread;
     635        return TL_GET( this_thread );
    666636}
    667637
     
    672642        __cfaabi_dbg_bits_write( abort_text, len );
    673643
    674         if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) {
    675                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine );
     644        if ( get_coroutine(thrd) != TL_GET( this_coroutine ) ) {
     645                len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", TL_GET( this_coroutine )->name, TL_GET( this_coroutine ) );
    676646                __cfaabi_dbg_bits_write( abort_text, len );
    677647        }
     
    682652
    683653int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    684         return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
     654        return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
    685655}
    686656
     
    712682        if ( count < 0 ) {
    713683                // queue current task
    714                 append( waiting, kernelTLS.this_thread );
     684                append( waiting, (thread_desc *)TL_GET( this_thread ) );
    715685
    716686                // atomically release spin lock and block
     
    772742        void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
    773743                this.prev_name = prev_name;
    774                 this.prev_thrd = kernelTLS.this_thread;
     744                this.prev_thrd = TL_GET( this_thread );
    775745        }
    776746)
  • src/libcfa/concurrency/monitor.c

    r5fec3f6 r387c9a1  
    8585                // Lock the monitor spinlock
    8686                lock( this->lock __cfaabi_dbg_ctx2 );
    87                 // Interrupts disable inside critical section
    88                 thread_desc * thrd = kernelTLS.this_thread;
     87                thread_desc * thrd = TL_GET( this_thread );
    8988
    9089                __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     
    135134                // Lock the monitor spinlock
    136135                lock( this->lock __cfaabi_dbg_ctx2 );
    137                 // Interrupts disable inside critical section
    138                 thread_desc * thrd = kernelTLS.this_thread;
     136                thread_desc * thrd = TL_GET( this_thread );
    139137
    140138                __cfaabi_dbg_print_safe( "Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
     
    170168
    171169                        // Create the node specific to this wait operation
    172                         wait_ctx_primed( thrd, 0 )
     170                        wait_ctx_primed( TL_GET( this_thread ), 0 )
    173171
    174172                        // Some one else has the monitor, wait for him to finish and then run
     
    181179                        __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
    182180
    183                         wait_ctx( thrd, 0 )
     181                        wait_ctx( TL_GET( this_thread ), 0 )
    184182                        this->dtor_node = &waiter;
    185183
     
    201199                lock( this->lock __cfaabi_dbg_ctx2 );
    202200
    203                 __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", kernelTLS.this_thread, this, this->owner);
    204 
    205                 verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     201                __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", TL_GET( this_thread ), this, this->owner);
     202
     203                verifyf( TL_GET( this_thread ) == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", TL_GET( this_thread ), this->owner, this->recursion, this );
    206204
    207205                // Leaving a recursion level, decrement the counter
     
    291289// Sorts monitors before entering
    292290void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {
    293         thread_desc * thrd = TL_GET( this_thread );
    294 
    295291        // Store current array
    296292        this.m = m;
     
    301297
    302298        // Save previous thread context
    303         this.prev = thrd->monitors;
     299        this.prev = TL_GET( this_thread )->monitors;
    304300
    305301        // Update thread context (needed for conditions)
    306         (thrd->monitors){m, count, func};
     302        (TL_GET( this_thread )->monitors){m, count, func};
    307303
    308304        // __cfaabi_dbg_print_safe( "MGUARD : enter %d\n", count);
     
    332328// Sorts monitors before entering
    333329void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) {
    334         // optimization
    335         thread_desc * thrd = TL_GET( this_thread );
    336 
    337330        // Store current array
    338331        this.m = *m;
    339332
    340333        // Save previous thread context
    341         this.prev = thrd->monitors;
     334        this.prev = TL_GET( this_thread )->monitors;
    342335
    343336        // Update thread context (needed for conditions)
    344         (thrd->monitors){m, 1, func};
     337        (TL_GET( this_thread )->monitors){m, 1, func};
    345338
    346339        __enter_monitor_dtor( this.m, func );
     
    573566
    574567                                // Create the node specific to this wait operation
    575                                 wait_ctx_primed( kernelTLS.this_thread, 0 );
     568                                wait_ctx_primed( TL_GET( this_thread ), 0 );
    576569
    577570                                // Save monitor states
     
    619612
    620613        // Create the node specific to this wait operation
    621         wait_ctx_primed( kernelTLS.this_thread, 0 );
     614        wait_ctx_primed( TL_GET( this_thread ), 0 );
    622615
    623616        monitor_save;
     
    625618
    626619        for( __lock_size_t i = 0; i < count; i++) {
    627                 verify( monitors[i]->owner == kernelTLS.this_thread );
     620                verify( monitors[i]->owner == TL_GET( this_thread ) );
    628621        }
    629622
  • src/libcfa/concurrency/preemption.c

    r5fec3f6 r387c9a1  
    234234}
    235235
    236 // KERNEL ONLY
     236
    237237// Check if a CtxSwitch signal handler shoud defer
    238238// If true  : preemption is safe
    239239// If false : preemption is unsafe and marked as pending
    240240static inline bool preemption_ready() {
    241         // Check if preemption is safe
    242         bool ready = kernelTLS.preemption_state.enabled && ! kernelTLS.preemption_state.in_progress;
    243 
    244         // Adjust the pending flag accordingly
    245         kernelTLS.this_processor->pending_preemption = !ready;
     241        bool ready = TL_GET( preemption_state ).enabled && !TL_GET( preemption_state ).in_progress; // Check if preemption is safe
     242        TL_GET( this_processor )->pending_preemption = !ready;                  // Adjust the pending flag accordingly
    246243        return ready;
    247244}
     
    257254
    258255        // Start with preemption disabled until ready
    259         kernelTLS.preemption_state.enabled = false;
    260         kernelTLS.preemption_state.disable_count = 1;
     256        TL_GET( preemption_state ).enabled = false;
     257        TL_GET( preemption_state ).disable_count = 1;
    261258
    262259        // Initialize the event kernel
     
    323320        // before the kernel thread has even started running. When that happens an iterrupt
    324321        // we a null 'this_processor' will be caught, just ignore it.
    325         if(! kernelTLS.this_processor ) return;
     322        if(!TL_GET( this_processor )) return;
    326323
    327324        choose(sfp->si_value.sival_int) {
    328325                case PREEMPT_NORMAL   : ;// Normal case, nothing to do here
    329                 case PREEMPT_TERMINATE: verify( kernelTLS.this_processor->do_terminate);
     326                case PREEMPT_TERMINATE: verify(TL_GET( this_processor )->do_terminate);
    330327                default:
    331328                        abort( "internal error, signal value is %d", sfp->si_value.sival_int );
     
    335332        if( !preemption_ready() ) { return; }
    336333
    337         __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", kernelTLS.this_processor, kernelTLS.this_thread );
    338 
    339         // Sync flag : prevent recursive calls to the signal handler
    340         kernelTLS.preemption_state.in_progress = true;
    341 
    342         // We are about to CtxSwitch out of the signal handler, let other handlers in
    343         signal_unblock( SIGUSR1 );
    344 
    345         // TODO: this should go in finish action
    346         // Clear the in progress flag
    347         kernelTLS.preemption_state.in_progress = false;
     334        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", TL_GET( this_processor ), TL_GET( this_thread ) );
     335
     336        TL_GET( preemption_state ).in_progress = true;  // Sync flag : prevent recursive calls to the signal handler
     337        signal_unblock( SIGUSR1 );                          // We are about to CtxSwitch out of the signal handler, let other handlers in
     338        TL_GET( preemption_state ).in_progress = false; // Clear the in progress flag
    348339
    349340        // Preemption can occur here
    350341
    351         BlockInternal( kernelTLS.this_thread ); // Do the actual CtxSwitch
     342        BlockInternal( (thread_desc*)TL_GET( this_thread ) ); // Do the actual CtxSwitch
    352343}
    353344
     
    418409
    419410void __cfaabi_check_preemption() {
    420         bool ready = kernelTLS.preemption_state.enabled;
     411        bool ready = TL_GET( preemption_state ).enabled;
    421412        if(!ready) { abort("Preemption should be ready"); }
    422413
  • src/libcfa/concurrency/thread.c

    r5fec3f6 r387c9a1  
    8181        disable_interrupts();
    8282        create_stack(&thrd_c->stack, thrd_c->stack.size);
    83         kernelTLS.this_coroutine = thrd_c;
     83        TL_SET( this_coroutine, thrd_c );
    8484        CtxStart(&this, CtxInvokeThread);
    8585        assert( thrd_c->last->stack.context );
     
    9191
    9292extern "C" {
    93         // KERNEL ONLY
    9493        void __finish_creation(void) {
    95                 coroutine_desc* thrd_c = kernelTLS.this_coroutine;
     94                coroutine_desc* thrd_c = TL_GET( this_coroutine );
    9695                ThreadCtxSwitch( thrd_c, thrd_c->last );
    9796        }
     
    9998
    10099void yield( void ) {
    101         // Safety note : This could cause some false positives due to preemption
    102       verify( TL_GET( preemption_state ).enabled );
     100        verify( TL_GET( preemption_state ).enabled );
    103101        BlockInternal( TL_GET( this_thread ) );
    104         // Safety note : This could cause some false positives due to preemption
    105       verify( TL_GET( preemption_state ).enabled );
     102        verify( TL_GET( preemption_state ).enabled );
    106103}
    107104
     
    112109}
    113110
    114 // KERNEL ONLY
    115111void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    116112        // set state of current coroutine to inactive
     
    120116        // set new coroutine that the processor is executing
    121117        // and context switch to it
    122         kernelTLS.this_coroutine = dst;
     118        TL_SET( this_coroutine, dst );
    123119        assert( src->stack.context );
    124120        CtxSwitch( src->stack.context, dst->stack.context );
    125         kernelTLS.this_coroutine = src;
     121        TL_SET( this_coroutine, src );
    126122
    127123        // set state of new coroutine to active
Note: See TracChangeset for help on using the changeset viewer.