Changeset 18f0b70


Ignore:
Timestamp:
Nov 10, 2020, 12:21:21 AM (11 months ago)
Author:
Fangren Yu <f37yu@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
0dd9a5e
Parents:
16ba4a6 (diff), 75baaa3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
1 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • benchmark/readyQ/cycle.cfa

    r16ba4a6 r18f0b70  
    8484                }
    8585
    86                 printf("Duration (ms)        : %'ld\n", (end - start)`ms);
     86                printf("Duration (ms)        : %'ld\n", (end - start)`dms);
    8787                printf("Number of processors : %'d\n", nprocs);
    8888                printf("Number of threads    : %'d\n", tthreads);
     
    9090                printf("Total Operations(ops): %'15llu\n", global_counter);
    9191                printf("Total blocks         : %'15llu\n", global_blocks);
    92                 printf("Ops per second       : %'18.2lf\n", ((double)global_counter) / (end - start)`s);
    93                 printf("ns per ops           : %'18.2lf\n", ((double)(end - start)`ns) / global_counter);
     92                printf("Ops per second       : %'18.2lf\n", ((double)global_counter) / (end - start)`ds);
     93                printf("ns per ops           : %'18.2lf\n", (end - start)`dns / global_counter);
    9494                printf("Ops per threads      : %'15llu\n", global_counter / tthreads);
    9595                printf("Ops per procs        : %'15llu\n", global_counter / nprocs);
    96                 printf("Ops/sec/procs        : %'18.2lf\n", (((double)global_counter) / nprocs) / (end - start)`s);
    97                 printf("ns per ops/procs     : %'18.2lf\n", ((double)(end - start)`ns) / (global_counter / nprocs));
     96                printf("Ops/sec/procs        : %'18.2lf\n", (((double)global_counter) / nprocs) / (end - start)`ds);
     97                printf("ns per ops/procs     : %'18.2lf\n", (end - start)`dns / (global_counter / nprocs));
    9898                fflush(stdout);
    9999        }
  • benchmark/readyQ/cycle.go

    r16ba4a6 r18f0b70  
    7272        p.Printf("Cycle size (# thrds) : %d\n", ring_size);
    7373        p.Printf("Total Operations(ops): %15d\n", global_counter)
    74         p.Printf("Yields per second    : %18.2f\n", float64(global_counter) / delta.Seconds())
     74        p.Printf("Ops per second       : %18.2f\n", float64(global_counter) / delta.Seconds())
    7575        p.Printf("ns per ops           : %18.2f\n", float64(delta.Nanoseconds()) / float64(global_counter))
    7676        p.Printf("Ops per threads      : %15d\n", global_counter / uint64(tthreads))
  • benchmark/readyQ/rq_bench.hfa

    r16ba4a6 r18f0b70  
    8888}
    8989
    90 struct bench_sem {
     90struct __attribute__((aligned(128))) bench_sem {
    9191        struct $thread * volatile ptr;
    9292};
  • benchmark/readyQ/rq_bench.hpp

    r16ba4a6 r18f0b70  
    7575}
    7676
    77 class bench_sem {
     77class __attribute__((aligned(128))) bench_sem {
    7878        Fibre * volatile ptr = nullptr;
    7979public:
  • benchmark/rmit.py

    r16ba4a6 r18f0b70  
    173173        # ================================================================================
    174174        # Prepare to run
    175         print(actions)
    176175
    177176        # find expected time
     
    226225                        d = [r[0], r[1]]
    227226                        for k in headers[2:]:
    228                                 d.append(r[2][k])
     227                                try:
     228                                        d.append(r[2][k])
     229                                except:
     230                                        d.append(0.0)
    229231
    230232                        data.append(d)
  • libcfa/src/concurrency/coroutine.cfa

    r16ba4a6 r18f0b70  
    134134void ^?{}($coroutine& this) {
    135135        if(this.state != Halted && this.state != Start && this.state != Primed) {
    136                 $coroutine * src = TL_GET( this_thread )->curr_cor;
     136                $coroutine * src = active_coroutine();
    137137                $coroutine * dst = &this;
    138138
     
    240240
    241241        struct $coroutine * __cfactx_cor_finish(void) {
    242                 struct $coroutine * cor = kernelTLS.this_thread->curr_cor;
     242                struct $coroutine * cor = active_coroutine();
    243243
    244244                if(cor->state == Primed) {
  • libcfa/src/concurrency/coroutine.hfa

    r16ba4a6 r18f0b70  
    6363void prime(T & cor);
    6464
    65 static inline struct $coroutine * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
     65static inline struct $coroutine * active_coroutine() { return active_thread()->curr_cor; }
    6666
    6767//-----------------------------------------------------------------------------
     
    8787
    8888        // set new coroutine that task is executing
    89         TL_GET( this_thread )->curr_cor = dst;
     89        active_thread()->curr_cor = dst;
    9090
    9191        // context switch to specified coroutine
     
    112112                // will also migrate which means this value will
    113113                // stay in syn with the TLS
    114                 $coroutine * src = TL_GET( this_thread )->curr_cor;
     114                $coroutine * src = active_coroutine();
    115115
    116116                assertf( src->last != 0,
     
    138138        // will also migrate which means this value will
    139139        // stay in syn with the TLS
    140         $coroutine * src = TL_GET( this_thread )->curr_cor;
     140        $coroutine * src = active_coroutine();
    141141        $coroutine * dst = get_coroutine(cor);
    142142
    143143        if( unlikely(dst->context.SP == 0p) ) {
    144                 TL_GET( this_thread )->curr_cor = dst;
     144                active_thread()->curr_cor = dst;
    145145                __stack_prepare(&dst->stack, 65000);
    146146                __cfactx_start(main, dst, cor, __cfactx_invoke_coroutine);
    147                 TL_GET( this_thread )->curr_cor = src;
     147                active_thread()->curr_cor = src;
    148148        }
    149149
     
    175175        // will also migrate which means this value will
    176176        // stay in syn with the TLS
    177         $coroutine * src = TL_GET( this_thread )->curr_cor;
     177        $coroutine * src = active_coroutine();
    178178
    179179        // not resuming self ?
  • libcfa/src/concurrency/exception.cfa

    r16ba4a6 r18f0b70  
    7272        void * stop_param;
    7373
    74         struct $thread * this_thread = TL_GET( this_thread );
     74        struct $thread * this_thread = active_thread();
    7575        if ( &this_thread->self_cor != this_thread->curr_cor ) {
    7676                struct $coroutine * cor = this_thread->curr_cor;
  • libcfa/src/concurrency/io.cfa

    r16ba4a6 r18f0b70  
    7676
    7777        static inline bool next( __leaderlock_t & this ) {
    78                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     78                /* paranoid */ verify( ! __preemption_enabled() );
    7979                struct $thread * nextt;
    8080                for() {
     
    168168        // This is NOT thread-safe
    169169        static [int, bool] __drain_io( & struct __io_data ring ) {
    170                 /* paranoid */ verify( !kernelTLS.preemption_state.enabled );
     170                /* paranoid */ verify( ! __preemption_enabled() );
    171171
    172172                unsigned to_submit = 0;
     
    404404                                        return;
    405405                                }
    406                                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     406                                /* paranoid */ verify( ! __preemption_enabled() );
    407407                                __STATS__( true,
    408408                                        io.submit_q.leader += 1;
     
    442442
    443443                        #if defined(LEADER_LOCK)
    444                                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     444                                /* paranoid */ verify( ! __preemption_enabled() );
    445445                                next(ring.submit_q.submit_lock);
    446446                        #else
  • libcfa/src/concurrency/io/setup.cfa

    r16ba4a6 r18f0b70  
    149149                id.full_proc = false;
    150150                id.id = doregister(&id);
    151                 kernelTLS.this_proc_id = &id;
     151                __cfaabi_tls.this_proc_id = &id;
    152152                __cfaabi_dbg_print_safe( "Kernel : IO poller thread starting\n" );
    153153
     
    179179                                __cfadbg_print_safe(io_core, "Kernel I/O : Unparking io poller %p\n", io_ctx);
    180180                                #if !defined( __CFA_NO_STATISTICS__ )
    181                                         kernelTLS.this_stats = io_ctx->self.curr_cluster->stats;
     181                                        __cfaabi_tls.this_stats = io_ctx->self.curr_cluster->stats;
    182182                                #endif
    183183                                post( io_ctx->sem );
  • libcfa/src/concurrency/kernel.cfa

    r16ba4a6 r18f0b70  
    122122        // Because of a bug, we couldn't initialized the seed on construction
    123123        // Do it here
    124         kernelTLS.rand_seed ^= rdtscl();
    125         kernelTLS.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&runner);
     124        __cfaabi_tls.rand_seed ^= rdtscl();
     125        __cfaabi_tls.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&runner);
    126126        __tls_rand_advance_bck();
    127127
     
    217217                // and it make sense for it to be set in all other cases except here
    218218                // fake it
    219                 kernelTLS.this_thread = mainThread;
     219                __cfaabi_tls.this_thread = mainThread;
    220220        }
    221221
     
    230230// from the processor coroutine to the target thread
    231231static void __run_thread(processor * this, $thread * thrd_dst) {
    232         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     232        /* paranoid */ verify( ! __preemption_enabled() );
    233233        /* paranoid */ verifyf( thrd_dst->state == Ready || thrd_dst->preempted != __NO_PREEMPTION, "state : %d, preempted %d\n", thrd_dst->state, thrd_dst->preempted);
    234234        /* paranoid */ verifyf( thrd_dst->link.next == 0p, "Expected null got %p", thrd_dst->link.next );
     
    247247
    248248                // Update global state
    249                 kernelTLS.this_thread = thrd_dst;
    250 
    251                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    252                 /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
     249                kernelTLS().this_thread = thrd_dst;
     250
     251                /* paranoid */ verify( ! __preemption_enabled() );
     252                /* paranoid */ verify( kernelTLS().this_thread == thrd_dst );
    253253                /* paranoid */ verify( thrd_dst->context.SP );
    254254                /* paranoid */ verify( thrd_dst->state != Halted );
     
    267267                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst );
    268268                /* paranoid */ verify( thrd_dst->context.SP );
    269                 /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
    270                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     269                /* paranoid */ verify( kernelTLS().this_thread == thrd_dst );
     270                /* paranoid */ verify( ! __preemption_enabled() );
    271271
    272272                // Reset global state
    273                 kernelTLS.this_thread = 0p;
     273                kernelTLS().this_thread = 0p;
    274274
    275275                // We just finished running a thread, there are a few things that could have happened.
     
    315315        proc_cor->state = Active;
    316316
    317         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     317        /* paranoid */ verify( ! __preemption_enabled() );
    318318}
    319319
    320320// KERNEL_ONLY
    321321void returnToKernel() {
    322         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    323         $coroutine * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
    324         $thread * thrd_src = kernelTLS.this_thread;
     322        /* paranoid */ verify( ! __preemption_enabled() );
     323        $coroutine * proc_cor = get_coroutine(kernelTLS().this_processor->runner);
     324        $thread * thrd_src = kernelTLS().this_thread;
    325325
    326326        #if !defined(__CFA_NO_STATISTICS__)
    327                 struct processor * last_proc = kernelTLS.this_processor;
     327                struct processor * last_proc = kernelTLS().this_processor;
    328328        #endif
    329329
     
    345345
    346346        #if !defined(__CFA_NO_STATISTICS__)
    347                 if(last_proc != kernelTLS.this_processor) {
     347                if(last_proc != kernelTLS().this_processor) {
    348348                        __tls_stats()->ready.threads.migration++;
    349349                }
    350350        #endif
    351351
    352         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     352        /* paranoid */ verify( ! __preemption_enabled() );
    353353        /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) < ((uintptr_t)__get_stack(thrd_src->curr_cor)->base ), "ERROR : Returning $thread %p has been corrupted.\n StackPointer too small.\n", thrd_src );
    354354        /* paranoid */ verifyf( ((uintptr_t)thrd_src->context.SP) > ((uintptr_t)__get_stack(thrd_src->curr_cor)->limit), "ERROR : Returning $thread %p has been corrupted.\n StackPointer too large.\n", thrd_src );
     
    359359// KERNEL ONLY
    360360void __schedule_thread( $thread * thrd ) {
     361        /* paranoid */ verify( ! __preemption_enabled() );
    361362        /* paranoid */ verify( thrd );
    362363        /* paranoid */ verify( thrd->state != Halted );
    363         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    364         /* paranoid */ verify( kernelTLS.this_proc_id );
     364        /* paranoid */ verify( kernelTLS().this_proc_id );
    365365        /* paranoid */ #if defined( __CFA_WITH_VERIFY__ )
    366366        /* paranoid */  if( thrd->state == Blocked || thrd->state == Start ) assertf( thrd->preempted == __NO_PREEMPTION,
     
    380380        ready_schedule_unlock();
    381381
    382         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     382        /* paranoid */ verify( ! __preemption_enabled() );
    383383}
    384384
    385385// KERNEL ONLY
    386386static inline $thread * __next_thread(cluster * this) with( *this ) {
    387         /* paranoid */ verify( kernelTLS.this_proc_id );
    388         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     387        /* paranoid */ verify( ! __preemption_enabled() );
     388        /* paranoid */ verify( kernelTLS().this_proc_id );
    389389
    390390        ready_schedule_lock();
     
    392392        ready_schedule_unlock();
    393393
    394         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    395         /* paranoid */ verify( kernelTLS.this_proc_id );
     394        /* paranoid */ verify( kernelTLS().this_proc_id );
     395        /* paranoid */ verify( ! __preemption_enabled() );
    396396        return thrd;
    397397}
     
    399399// KERNEL ONLY
    400400static inline $thread * __next_thread_slow(cluster * this) with( *this ) {
    401         /* paranoid */ verify( kernelTLS.this_proc_id );
    402         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     401        /* paranoid */ verify( ! __preemption_enabled() );
     402        /* paranoid */ verify( kernelTLS().this_proc_id );
    403403
    404404        ready_schedule_lock();
     
    406406        ready_schedule_unlock();
    407407
    408         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    409         /* paranoid */ verify( kernelTLS.this_proc_id );
     408        /* paranoid */ verify( kernelTLS().this_proc_id );
     409        /* paranoid */ verify( ! __preemption_enabled() );
    410410        return thrd;
    411411}
     
    414414        if( !thrd ) return;
    415415
    416         /* paranoid */ verify( kernelTLS.this_proc_id );
    417         bool full = kernelTLS.this_proc_id->full_proc;
    418         if(full) disable_interrupts();
    419 
    420         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    421416        int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST);
    422417        switch(old_ticket) {
     
    428423                        /* paranoid */ verify( thrd->state == Blocked );
    429424
    430                         // Wake lost the race,
    431                         __schedule_thread( thrd );
     425                        {
     426                                /* paranoid */ verify( publicTLS_get(this_proc_id) );
     427                                bool full = publicTLS_get(this_proc_id)->full_proc;
     428                                if(full) disable_interrupts();
     429
     430                                /* paranoid */ verify( ! __preemption_enabled() );
     431
     432                                // Wake lost the race,
     433                                __schedule_thread( thrd );
     434
     435                                /* paranoid */ verify( ! __preemption_enabled() );
     436
     437                                if(full) enable_interrupts( __cfaabi_dbg_ctx );
     438                                /* paranoid */ verify( publicTLS_get(this_proc_id) );
     439                        }
     440
    432441                        break;
    433442                default:
     
    435444                        abort("Thread %p (%s) has mismatch park/unpark\n", thrd, thrd->self_cor.name);
    436445        }
    437         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    438 
    439         if(full) enable_interrupts( __cfaabi_dbg_ctx );
    440         /* paranoid */ verify( kernelTLS.this_proc_id );
    441446}
    442447
    443448void park( void ) {
    444         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
     449        /* paranoid */ verify( __preemption_enabled() );
    445450        disable_interrupts();
    446         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    447         /* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION );
     451        /* paranoid */ verify( ! __preemption_enabled() );
     452        /* paranoid */ verify( kernelTLS().this_thread->preempted == __NO_PREEMPTION );
    448453
    449454        returnToKernel();
    450455
    451         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     456        /* paranoid */ verify( ! __preemption_enabled() );
    452457        enable_interrupts( __cfaabi_dbg_ctx );
    453         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
     458        /* paranoid */ verify( __preemption_enabled() );
    454459
    455460}
     
    460465        // Should never return
    461466        void __cfactx_thrd_leave() {
    462                 $thread * thrd = TL_GET( this_thread );
     467                $thread * thrd = active_thread();
    463468                $monitor * this = &thrd->self_mon;
    464469
     
    473478
    474479                // Leave the thread
    475                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     480                /* paranoid */ verify( ! __preemption_enabled() );
    476481                returnToKernel();
    477482                abort();
     
    483488// KERNEL ONLY
    484489bool force_yield( __Preemption_Reason reason ) {
    485         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
     490        /* paranoid */ verify( __preemption_enabled() );
    486491        disable_interrupts();
    487         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    488 
    489         $thread * thrd = kernelTLS.this_thread;
     492        /* paranoid */ verify( ! __preemption_enabled() );
     493
     494        $thread * thrd = kernelTLS().this_thread;
    490495        /* paranoid */ verify(thrd->state == Active);
    491496
     
    501506        }
    502507
    503         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     508        /* paranoid */ verify( ! __preemption_enabled() );
    504509        enable_interrupts_noPoll();
    505         /* paranoid */ verify( kernelTLS.preemption_state.enabled );
     510        /* paranoid */ verify( __preemption_enabled() );
    506511
    507512        return preempted;
     
    513518// Wake a thread from the front if there are any
    514519static void __wake_one(cluster * this) {
    515         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     520        /* paranoid */ verify( ! __preemption_enabled() );
    516521        /* paranoid */ verify( ready_schedule_islocked() );
    517522
     
    533538
    534539        /* paranoid */ verify( ready_schedule_islocked() );
    535         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     540        /* paranoid */ verify( ! __preemption_enabled() );
    536541
    537542        return;
     
    543548
    544549        disable_interrupts();
    545                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     550                /* paranoid */ verify( ! __preemption_enabled() );
    546551                post( this->idle );
    547552        enable_interrupts( __cfaabi_dbg_ctx );
     
    549554
    550555static void push  (__cluster_idles & this, processor & proc) {
    551         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     556        /* paranoid */ verify( ! __preemption_enabled() );
    552557        lock( this );
    553558                this.idle++;
     
    556561                insert_first(this.list, proc);
    557562        unlock( this );
    558         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     563        /* paranoid */ verify( ! __preemption_enabled() );
    559564}
    560565
    561566static void remove(__cluster_idles & this, processor & proc) {
    562         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     567        /* paranoid */ verify( ! __preemption_enabled() );
    563568        lock( this );
    564569                this.idle--;
     
    567572                remove(proc);
    568573        unlock( this );
    569         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     574        /* paranoid */ verify( ! __preemption_enabled() );
    570575}
    571576
     
    611616        }
    612617
    613         return kernelTLS.this_thread;
     618        return __cfaabi_tls.this_thread;
    614619}
    615620
     
    636641
    637642int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    638         return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
     643        return get_coroutine(kernelTLS().this_thread) == get_coroutine(mainThread) ? 4 : 2;
    639644}
    640645
     
    668673        if ( count < 0 ) {
    669674                // queue current task
    670                 append( waiting, kernelTLS.this_thread );
     675                append( waiting, active_thread() );
    671676
    672677                // atomically release spin lock and block
     
    718723                void __cfaabi_dbg_record_lock(__spinlock_t & this, const char prev_name[]) {
    719724                        this.prev_name = prev_name;
    720                         this.prev_thrd = kernelTLS.this_thread;
     725                        this.prev_thrd = kernelTLS().this_thread;
    721726                }
    722727        }
  • libcfa/src/concurrency/kernel.hfa

    r16ba4a6 r18f0b70  
    275275static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
    276276
    277 static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE
    278 static inline struct cluster   * active_cluster  () { return TL_GET( this_processor )->cltr; }
     277static inline struct processor * active_processor() { return publicTLS_get( this_processor ); } // UNSAFE
     278static inline struct cluster   * active_cluster  () { return publicTLS_get( this_processor )->cltr; }
    279279
    280280#if !defined(__CFA_NO_STATISTICS__)
     281        void print_stats_now( cluster & this, int flags );
     282
    281283        static inline void print_stats_at_exit( cluster & this, int flags ) {
    282284                this.print_stats |= flags;
  • libcfa/src/concurrency/kernel/fwd.hfa

    r16ba4a6 r18f0b70  
    5555                                uint64_t bck_seed;
    5656                        } ready_rng;
    57                 } kernelTLS __attribute__ ((tls_model ( "initial-exec" )));
     57                } __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" )));
    5858
     59                extern bool __preemption_enabled();
    5960
     61                static inline KernelThreadData & kernelTLS( void ) {
     62                        /* paranoid */ verify( ! __preemption_enabled() );
     63                        return __cfaabi_tls;
     64                }
     65
     66                extern uintptr_t __cfatls_get( unsigned long int member );
     67                // #define publicTLS_get( member ) ((typeof(__cfaabi_tls.member))__cfatls_get( __builtin_offsetof(KernelThreadData, member) ))
     68                #define publicTLS_get( member ) (__cfaabi_tls.member)
     69                // extern forall(otype T) T __cfatls_get( T * member, T value );
     70                // #define publicTLS_set( member, value ) __cfatls_set( (typeof(member)*)__builtin_offsetof(KernelThreadData, member), value );
    6071
    6172                static inline uint64_t __tls_rand() {
    6273                        #if defined(__SIZEOF_INT128__)
    63                                 return __lehmer64( kernelTLS.rand_seed );
     74                                return __lehmer64( kernelTLS().rand_seed );
    6475                        #else
    65                                 return __xorshift64( kernelTLS.rand_seed );
     76                                return __xorshift64( kernelTLS().rand_seed );
    6677                        #endif
    6778                }
     
    7586                static inline unsigned __tls_rand_fwd() {
    7687
    77                         kernelTLS.ready_rng.fwd_seed = (A * kernelTLS.ready_rng.fwd_seed + C) & (M - 1);
    78                         return kernelTLS.ready_rng.fwd_seed >> D;
     88                        kernelTLS().ready_rng.fwd_seed = (A * kernelTLS().ready_rng.fwd_seed + C) & (M - 1);
     89                        return kernelTLS().ready_rng.fwd_seed >> D;
    7990                }
    8091
    8192                static inline unsigned __tls_rand_bck() {
    82                         unsigned int r = kernelTLS.ready_rng.bck_seed >> D;
    83                         kernelTLS.ready_rng.bck_seed = AI * (kernelTLS.ready_rng.bck_seed - C) & (M - 1);
     93                        unsigned int r = kernelTLS().ready_rng.bck_seed >> D;
     94                        kernelTLS().ready_rng.bck_seed = AI * (kernelTLS().ready_rng.bck_seed - C) & (M - 1);
    8495                        return r;
    8596                }
     
    92103
    93104                static inline void __tls_rand_advance_bck(void) {
    94                         kernelTLS.ready_rng.bck_seed = kernelTLS.ready_rng.fwd_seed;
     105                        kernelTLS().ready_rng.bck_seed = kernelTLS().ready_rng.fwd_seed;
    95106                }
    96107        }
    97108
    98         #if 0 // def __ARM_ARCH
    99                 // function prototypes are only really used by these macros on ARM
    100                 void disable_global_interrupts();
    101                 void enable_global_interrupts();
    102109
    103                 #define TL_GET( member ) ( { __typeof__( kernelTLS.member ) target; \
    104                         disable_global_interrupts(); \
    105                         target = kernelTLS.member; \
    106                         enable_global_interrupts(); \
    107                         target; } )
    108                 #define TL_SET( member, value ) disable_global_interrupts(); \
    109                         kernelTLS.member = value; \
    110                         enable_global_interrupts();
    111         #else
    112                 #define TL_GET( member ) kernelTLS.member
    113                 #define TL_SET( member, value ) kernelTLS.member = value;
    114         #endif
    115110
    116111        extern void disable_interrupts();
     
    121116                extern void park( void );
    122117                extern void unpark( struct $thread * this );
    123                 static inline struct $thread * active_thread () { return TL_GET( this_thread ); }
     118                static inline struct $thread * active_thread () {
     119                        struct $thread * t = publicTLS_get( this_thread );
     120                        /* paranoid */ verify( t );
     121                        return t;
     122                }
    124123
    125124                extern bool force_yield( enum __Preemption_Reason );
     
    140139                #if !defined(__CFA_NO_STATISTICS__)
    141140                        static inline struct __stats_t * __tls_stats() {
    142                                 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    143                                 /* paranoid */ verify( kernelTLS.this_stats );
    144                                 return kernelTLS.this_stats;
     141                                /* paranoid */ verify( ! __preemption_enabled() );
     142                                /* paranoid */ verify( kernelTLS().this_stats );
     143                                return kernelTLS().this_stats;
    145144                        }
    146145
  • libcfa/src/concurrency/kernel/startup.cfa

    r16ba4a6 r18f0b70  
    118118//-----------------------------------------------------------------------------
    119119// Global state
    120 thread_local struct KernelThreadData kernelTLS __attribute__ ((tls_model ( "initial-exec" ))) @= {
     120thread_local struct KernelThreadData __cfaabi_tls __attribute__ ((tls_model ( "initial-exec" ))) @= {
    121121        NULL,                                                                                           // cannot use 0p
    122122        NULL,
     
    156156// Kernel boot procedures
    157157static void __kernel_startup(void) {
    158         verify( ! kernelTLS.preemption_state.enabled );
     158        /* paranoid */ verify( ! __preemption_enabled() );
    159159        __cfadbg_print_safe(runtime_core, "Kernel : Starting\n");
    160160
     
    212212
    213213        //initialize the global state variables
    214         kernelTLS.this_processor = mainProcessor;
    215         kernelTLS.this_proc_id   = (__processor_id_t*)mainProcessor;
    216         kernelTLS.this_thread    = mainThread;
     214        __cfaabi_tls.this_processor = mainProcessor;
     215        __cfaabi_tls.this_proc_id   = (__processor_id_t*)mainProcessor;
     216        __cfaabi_tls.this_thread    = mainThread;
    217217
    218218        #if !defined( __CFA_NO_STATISTICS__ )
    219                 kernelTLS.this_stats = (__stats_t *)& storage_mainProcStats;
    220                 __init_stats( kernelTLS.this_stats );
     219                __cfaabi_tls.this_stats = (__stats_t *)& storage_mainProcStats;
     220                __init_stats( __cfaabi_tls.this_stats );
    221221        #endif
    222222
     
    234234        // context. Hence, the main thread does not begin through __cfactx_invoke_thread, like all other threads. The trick here is that
    235235        // mainThread is on the ready queue when this call is made.
    236         __kernel_first_resume( kernelTLS.this_processor );
     236        __kernel_first_resume( __cfaabi_tls.this_processor );
    237237
    238238
     
    251251        __cfadbg_print_safe(runtime_core, "Kernel : Started\n--------------------------------------------------\n\n");
    252252
    253         verify( ! kernelTLS.preemption_state.enabled );
     253        /* paranoid */ verify( ! __preemption_enabled() );
    254254        enable_interrupts( __cfaabi_dbg_ctx );
    255         verify( TL_GET( preemption_state.enabled ) );
     255        /* paranoid */ verify( __preemption_enabled() );
     256
    256257}
    257258
     
    262263        mainCluster->io.ctxs = 0p;
    263264
    264         /* paranoid */ verify( TL_GET( preemption_state.enabled ) );
     265        /* paranoid */ verify( __preemption_enabled() );
    265266        disable_interrupts();
    266         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     267        /* paranoid */ verify( ! __preemption_enabled() );
    267268
    268269        __cfadbg_print_safe(runtime_core, "\n--------------------------------------------------\nKernel : Shutting down\n");
     
    272273        // which is currently here
    273274        __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE);
    274         __kernel_last_resume( kernelTLS.this_processor );
     275        __kernel_last_resume( __cfaabi_tls.this_processor );
    275276        mainThread->self_cor.state = Halted;
    276277
     
    321322                __stats_t local_stats;
    322323                __init_stats( &local_stats );
    323                 kernelTLS.this_stats = &local_stats;
     324                __cfaabi_tls.this_stats = &local_stats;
    324325        #endif
    325326
    326327        processor * proc = (processor *) arg;
    327         kernelTLS.this_processor = proc;
    328         kernelTLS.this_proc_id   = (__processor_id_t*)proc;
    329         kernelTLS.this_thread    = 0p;
    330         kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
     328        __cfaabi_tls.this_processor = proc;
     329        __cfaabi_tls.this_proc_id   = (__processor_id_t*)proc;
     330        __cfaabi_tls.this_thread    = 0p;
     331        __cfaabi_tls.preemption_state.[enabled, disable_count] = [false, 1];
    331332        // SKULLDUGGERY: We want to create a context for the processor coroutine
    332333        // which is needed for the 2-step context switch. However, there is no reason
     
    340341
    341342        //Set global state
    342         kernelTLS.this_thread = 0p;
     343        __cfaabi_tls.this_thread = 0p;
    343344
    344345        //We now have a proper context from which to schedule threads
     
    370371        $coroutine * dst = get_coroutine(this->runner);
    371372
    372         verify( ! kernelTLS.preemption_state.enabled );
    373 
    374         kernelTLS.this_thread->curr_cor = dst;
     373        /* paranoid */ verify( ! __preemption_enabled() );
     374
     375        __cfaabi_tls.this_thread->curr_cor = dst;
    375376        __stack_prepare( &dst->stack, 65000 );
    376377        __cfactx_start(main, dst, this->runner, __cfactx_invoke_coroutine);
    377378
    378         verify( ! kernelTLS.preemption_state.enabled );
     379        /* paranoid */ verify( ! __preemption_enabled() );
    379380
    380381        dst->last = &src->self_cor;
     
    394395        /* paranoid */ verify(src->state == Active);
    395396
    396         verify( ! kernelTLS.preemption_state.enabled );
     397        /* paranoid */ verify( ! __preemption_enabled() );
    397398}
    398399
     
    402403        $coroutine * dst = get_coroutine(this->runner);
    403404
    404         verify( ! kernelTLS.preemption_state.enabled );
    405         verify( dst->starter == src );
    406         verify( dst->context.SP );
     405        /* paranoid */ verify( ! __preemption_enabled() );
     406        /* paranoid */ verify( dst->starter == src );
     407        /* paranoid */ verify( dst->context.SP );
    407408
    408409        // SKULLDUGGERY in debug the processors check that the
     
    546547
    547548                P( terminated );
    548                 verify( kernelTLS.this_processor != &this);
     549                /* paranoid */ verify( active_processor() != &this);
    549550        }
    550551
     
    696697#if defined(__CFA_WITH_VERIFY__)
    697698static bool verify_fwd_bck_rng(void) {
    698         kernelTLS.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&verify_fwd_bck_rng);
     699        __cfaabi_tls.ready_rng.fwd_seed = 25214903917_l64u * (rdtscl() ^ (uintptr_t)&verify_fwd_bck_rng);
    699700
    700701        unsigned values[10];
  • libcfa/src/concurrency/kernel_private.hfa

    r16ba4a6 r18f0b70  
    3838#endif
    3939;
     40
     41extern bool __preemption_enabled();
    4042
    4143//release/wake-up the following resources
     
    181183//  creating/destroying queues
    182184static inline void ready_schedule_lock(void) with(*__scheduler_lock) {
    183         /*paranoid*/ verify( kernelTLS.this_proc_id );
    184 
    185         unsigned iproc = kernelTLS.this_proc_id->id;
    186         /*paranoid*/ verify(data[iproc].handle == kernelTLS.this_proc_id);
     185        /* paranoid */ verify( ! __preemption_enabled() );
     186        /* paranoid */ verify( kernelTLS().this_proc_id );
     187
     188        unsigned iproc = kernelTLS().this_proc_id->id;
     189        /*paranoid*/ verify(data[iproc].handle == kernelTLS().this_proc_id);
    187190        /*paranoid*/ verify(iproc < ready);
    188191
     
    207210
    208211static inline void ready_schedule_unlock(void) with(*__scheduler_lock) {
    209         /*paranoid*/ verify( kernelTLS.this_proc_id );
    210 
    211         unsigned iproc = kernelTLS.this_proc_id->id;
    212         /*paranoid*/ verify(data[iproc].handle == kernelTLS.this_proc_id);
     212        /* paranoid */ verify( ! __preemption_enabled() );
     213        /* paranoid */ verify( kernelTLS().this_proc_id );
     214
     215        unsigned iproc = kernelTLS().this_proc_id->id;
     216        /*paranoid*/ verify(data[iproc].handle == kernelTLS().this_proc_id);
    213217        /*paranoid*/ verify(iproc < ready);
    214218        /*paranoid*/ verify(data[iproc].lock);
     
    223227#ifdef __CFA_WITH_VERIFY__
    224228        static inline bool ready_schedule_islocked(void) {
    225                 /*paranoid*/ verify( kernelTLS.this_proc_id );
    226                 __processor_id_t * proc = kernelTLS.this_proc_id;
     229                /* paranoid */ verify( ! __preemption_enabled() );
     230                /*paranoid*/ verify( kernelTLS().this_proc_id );
     231                __processor_id_t * proc = kernelTLS().this_proc_id;
    227232                return __scheduler_lock->data[proc->id].owned;
    228233        }
  • libcfa/src/concurrency/locks.cfa

    r16ba4a6 r18f0b70  
    7676
    7777void lock( blocking_lock & this ) with( this ) {
     78        $thread * thrd = active_thread();
    7879        lock( lock __cfaabi_dbg_ctx2 );
    79         if ( owner == kernelTLS.this_thread && !multi_acquisition) {
     80        if ( owner == thrd && !multi_acquisition) {
    8081                fprintf(stderr, "A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); // Possibly throw instead
    8182        exit(EXIT_FAILURE);
    82         } else if ( owner != 0p && owner != kernelTLS.this_thread ) {
    83                 append( blocked_threads, kernelTLS.this_thread );
     83        } else if ( owner != 0p && owner != thrd ) {
     84                append( blocked_threads, thrd );
    8485                wait_count++;
    8586                unlock( lock );
    8687                park( );
    87         } else if ( owner == kernelTLS.this_thread && multi_acquisition ) {
     88        } else if ( owner == thrd && multi_acquisition ) {
    8889                recursion_count++;
    8990                unlock( lock );
    9091        } else {
    91                 owner = kernelTLS.this_thread;
     92                owner = thrd;
    9293                recursion_count = 1;
    9394                unlock( lock );
     
    9697
    9798bool try_lock( blocking_lock & this ) with( this ) {
     99        $thread * thrd = active_thread();
    98100        bool ret = false;
    99101        lock( lock __cfaabi_dbg_ctx2 );
    100102        if ( owner == 0p ) {
    101                 owner = kernelTLS.this_thread;
     103                owner = thrd;
    102104                if ( multi_acquisition ) recursion_count = 1;
    103105                ret = true;
    104         } else if ( owner == kernelTLS.this_thread && multi_acquisition ) {
     106        } else if ( owner == thrd && multi_acquisition ) {
    105107                recursion_count++;
    106108                ret = true;
     
    113115        lock( lock __cfaabi_dbg_ctx2 );
    114116        if ( owner == 0p ){ // no owner implies lock isn't held
    115                 fprintf( stderr, "There was an attempt to release a lock that isn't held" ); 
     117                fprintf( stderr, "There was an attempt to release a lock that isn't held" );
    116118                return;
    117         } else if ( strict_owner && owner != kernelTLS.this_thread ) {
    118                 fprintf( stderr, "A thread other than the owner attempted to release an owner lock" ); 
     119        } else if ( strict_owner && active_thread() ) {
     120                fprintf( stderr, "A thread other than the owner attempted to release an owner lock" );
    119121                return;
    120122        }
     
    163165    lock( lock __cfaabi_dbg_ctx2 );
    164166        if ( owner == 0p ){ // no owner implies lock isn't held
    165                 fprintf( stderr, "A lock that is not held was passed to a synchronization lock" ); 
    166         } else if ( strict_owner && owner != kernelTLS.this_thread ) {
    167                 fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" ); 
     167                fprintf( stderr, "A lock that is not held was passed to a synchronization lock" );
     168        } else if ( strict_owner && active_thread() ) {
     169                fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" );
    168170        } else {
    169171                $thread * thrd = pop_head( blocked_threads );
     
    246248                                unlock( cond->lock );
    247249                                #if !defined( __CFA_NO_STATISTICS__ )
     250                                        #warning unprotected access to tls TODO discuss this
    248251                                        kernelTLS.this_stats = copy->t->curr_cluster->stats;
    249252                                #endif
     
    338341                        remove_( *i.lock );
    339342                }
    340                
     343
    341344                unlock( lock );
    342345                park( ); // blocks here
     
    374377
    375378        void wait( condition_variable(L) & this ) with(this) {
    376                 info_thread( L ) i = { kernelTLS.this_thread };
     379                info_thread( L ) i = { active_thread() };
    377380                queue_info_thread( this, i );
    378381        }
    379382
    380383        void wait( condition_variable(L) & this, uintptr_t info ) with(this) {
    381                 info_thread( L ) i = { kernelTLS.this_thread, info };
     384                info_thread( L ) i = { active_thread(), info };
    382385                queue_info_thread( this, i );
    383386        }
    384        
     387
    385388        void wait( condition_variable(L) & this, Duration duration ) with(this) {
    386                 info_thread( L ) i = { kernelTLS.this_thread };
     389                info_thread( L ) i = { active_thread() };
    387390                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
    388391        }
    389392
    390         void wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) { 
    391                 info_thread( L ) i = { kernelTLS.this_thread, info };
     393        void wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) {
     394                info_thread( L ) i = { active_thread(), info };
    392395                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
    393396        }
    394397
    395398        void wait( condition_variable(L) & this, Time time ) with(this) {
    396                 info_thread( L ) i = { kernelTLS.this_thread };
     399                info_thread( L ) i = { active_thread() };
    397400                queue_info_thread_timeout(this, i, time);
    398401        }
    399402
    400403        void wait( condition_variable(L) & this, uintptr_t info, Time time ) with(this) {
    401                 info_thread( L ) i = { kernelTLS.this_thread, info };
     404                info_thread( L ) i = { active_thread(), info };
    402405                queue_info_thread_timeout(this, i, time);
    403406        }
    404407
    405408        void wait( condition_variable(L) & this, L & l ) with(this) {
    406                 info_thread(L) i = { kernelTLS.this_thread };
     409                info_thread(L) i = { active_thread() };
    407410                i.lock = &l;
    408411                queue_info_thread( this, i );
     
    410413
    411414        void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) {
    412                 info_thread(L) i = { kernelTLS.this_thread, info };
     415                info_thread(L) i = { active_thread(), info };
    413416                i.lock = &l;
    414417                queue_info_thread( this, i );
    415418        }
    416        
     419
    417420        void wait( condition_variable(L) & this, L & l, Duration duration ) with(this) {
    418                 info_thread(L) i = { kernelTLS.this_thread };
     421                info_thread(L) i = { active_thread() };
    419422                i.lock = &l;
    420423                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
    421424        }
    422        
     425
    423426        void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) {
    424                 info_thread(L) i = { kernelTLS.this_thread, info };
     427                info_thread(L) i = { active_thread(), info };
    425428                i.lock = &l;
    426429                queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
    427430        }
    428        
     431
    429432        void wait( condition_variable(L) & this, L & l, Time time ) with(this) {
    430                 info_thread(L) i = { kernelTLS.this_thread };
     433                info_thread(L) i = { active_thread() };
    431434                i.lock = &l;
    432435                queue_info_thread_timeout(this, i, time );
    433436        }
    434        
     437
    435438        void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) {
    436                 info_thread(L) i = { kernelTLS.this_thread, info };
     439                info_thread(L) i = { active_thread(), info };
    437440                i.lock = &l;
    438441                queue_info_thread_timeout(this, i, time );
  • libcfa/src/concurrency/monitor.cfa

    r16ba4a6 r18f0b70  
    8282// Enter single monitor
    8383static void __enter( $monitor * this, const __monitor_group_t & group ) {
     84        $thread * thrd = active_thread();
     85
    8486        // Lock the monitor spinlock
    8587        lock( this->lock __cfaabi_dbg_ctx2 );
    86         // Interrupts disable inside critical section
    87         $thread * thrd = kernelTLS.this_thread;
    8888
    8989        __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     
    126126                __cfaabi_dbg_print_safe( "Kernel : %10p Entered  mon %p\n", thrd, this);
    127127
    128                 /* paranoid */ 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 );
     128                /* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    129129                return;
    130130        }
     
    132132        __cfaabi_dbg_print_safe( "Kernel : %10p Entered  mon %p\n", thrd, this);
    133133
    134         /* paranoid */ 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 );
     134        /* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    135135        /* paranoid */ verify( this->lock.lock );
    136136
     
    141141
    142142static void __dtor_enter( $monitor * this, fptr_t func, bool join ) {
     143        $thread * thrd = active_thread();
     144
    143145        // Lock the monitor spinlock
    144146        lock( this->lock __cfaabi_dbg_ctx2 );
    145         // Interrupts disable inside critical section
    146         $thread * thrd = kernelTLS.this_thread;
    147147
    148148        __cfaabi_dbg_print_safe( "Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
     
    155155                __set_owner( this, thrd );
    156156
    157                 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 );
     157                verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    158158
    159159                unlock( this->lock );
     
    174174                this->owner = thrd;
    175175
    176                 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 );
     176                verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    177177
    178178                unlock( this->lock );
     
    200200
    201201                // Release the next thread
    202                 /* paranoid */ verifyf( urgent->owner->waiting_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     202                /* paranoid */ verifyf( urgent->owner->waiting_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    203203                unpark( urgent->owner->waiting_thread );
    204204
     
    207207
    208208                // Some one was waiting for us, enter
    209                 /* paranoid */ 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 );
     209                /* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    210210        }
    211211        else {
     
    224224                park();
    225225
    226                 /* paranoid */ 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 );
     226                /* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    227227                return;
    228228        }
     
    237237        lock( this->lock __cfaabi_dbg_ctx2 );
    238238
    239         __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", kernelTLS.this_thread, this, this->owner);
    240 
    241         /* paranoid */ 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 );
     239        __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", active_thread(), this, this->owner);
     240
     241        /* paranoid */ verifyf( active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    242242
    243243        // Leaving a recursion level, decrement the counter
     
    270270void __dtor_leave( $monitor * this, bool join ) {
    271271        __cfaabi_dbg_debug_do(
    272                 if( TL_GET( this_thread ) != this->owner ) {
    273                         abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, TL_GET( this_thread ), this->owner);
     272                if( active_thread() != this->owner ) {
     273                        abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, active_thread(), this->owner);
    274274                }
    275275                if( this->recursion != 1  && !join ) {
     
    287287        /* paranoid */ verify( this->lock.lock );
    288288        /* paranoid */ verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", thrd, this->owner, this->recursion, this );
    289         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     289        /* paranoid */ verify( ! __preemption_enabled() );
    290290        /* paranoid */ verify( thrd->state == Halted );
    291291        /* paranoid */ verify( this->recursion == 1 );
     
    303303        // Unpark the next owner if needed
    304304        /* paranoid */ verifyf( !new_owner || new_owner == this->owner, "Expected owner to be %p, got %p (m: %p)", new_owner, this->owner, this );
    305         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     305        /* paranoid */ verify( ! __preemption_enabled() );
    306306        /* paranoid */ verify( thrd->state == Halted );
    307307        unpark( new_owner );
     
    327327// Sorts monitors before entering
    328328void ?{}( monitor_guard_t & this, $monitor * m [], __lock_size_t count, fptr_t func ) {
    329         $thread * thrd = TL_GET( this_thread );
     329        $thread * thrd = active_thread();
    330330
    331331        // Store current array
     
    362362
    363363        // Restore thread context
    364         TL_GET( this_thread )->monitors = this.prev;
     364        active_thread()->monitors = this.prev;
    365365}
    366366
     
    369369void ?{}( monitor_dtor_guard_t & this, $monitor * m [], fptr_t func, bool join ) {
    370370        // optimization
    371         $thread * thrd = TL_GET( this_thread );
     371        $thread * thrd = active_thread();
    372372
    373373        // Store current array
     
    392392
    393393        // Restore thread context
    394         TL_GET( this_thread )->monitors = this.prev;
     394        active_thread()->monitors = this.prev;
    395395}
    396396
     
    432432
    433433        // Create the node specific to this wait operation
    434         wait_ctx( TL_GET( this_thread ), user_info );
     434        wait_ctx( active_thread(), user_info );
    435435
    436436        // Append the current wait operation to the ones already queued on the condition
     
    483483        //Some more checking in debug
    484484        __cfaabi_dbg_debug_do(
    485                 $thread * this_thrd = TL_GET( this_thread );
     485                $thread * this_thrd = active_thread();
    486486                if ( this.monitor_count != this_thrd->monitors.size ) {
    487487                        abort( "Signal on condition %p made with different number of monitor(s), expected %zi got %zi", &this, this.monitor_count, this_thrd->monitors.size );
     
    531531
    532532        // Create the node specific to this wait operation
    533         wait_ctx_primed( kernelTLS.this_thread, 0 )
     533        wait_ctx_primed( active_thread(), 0 )
    534534
    535535        //save contexts
     
    630630
    631631                                // Create the node specific to this wait operation
    632                                 wait_ctx_primed( kernelTLS.this_thread, 0 );
     632                                wait_ctx_primed( active_thread(), 0 );
    633633
    634634                                // Save monitor states
     
    682682
    683683        // Create the node specific to this wait operation
    684         wait_ctx_primed( kernelTLS.this_thread, 0 );
     684        wait_ctx_primed( active_thread(), 0 );
    685685
    686686        monitor_save;
     
    688688
    689689        for( __lock_size_t i = 0; i < count; i++) {
    690                 verify( monitors[i]->owner == kernelTLS.this_thread );
     690                verify( monitors[i]->owner == active_thread() );
    691691        }
    692692
     
    724724static inline void __set_owner( $monitor * monitors [], __lock_size_t count, $thread * owner ) {
    725725        /* paranoid */ verify ( monitors[0]->lock.lock );
    726         /* paranoid */ verifyf( monitors[0]->owner == kernelTLS.this_thread, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, monitors[0]->owner, monitors[0]->recursion, monitors[0] );
     726        /* paranoid */ verifyf( monitors[0]->owner == active_thread(), "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), monitors[0]->owner, monitors[0]->recursion, monitors[0] );
    727727        monitors[0]->owner        = owner;
    728728        monitors[0]->recursion    = 1;
    729729        for( __lock_size_t i = 1; i < count; i++ ) {
    730730                /* paranoid */ verify ( monitors[i]->lock.lock );
    731                 /* paranoid */ verifyf( monitors[i]->owner == kernelTLS.this_thread, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, monitors[i]->owner, monitors[i]->recursion, monitors[i] );
     731                /* paranoid */ verifyf( monitors[i]->owner == active_thread(), "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), monitors[i]->owner, monitors[i]->recursion, monitors[i] );
    732732                monitors[i]->owner        = owner;
    733733                monitors[i]->recursion    = 0;
     
    755755                //regardless of if we are ready to baton pass,
    756756                //we need to set the monitor as in use
    757                 /* paranoid */ verifyf( !this->owner || kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     757                /* paranoid */ verifyf( !this->owner || active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    758758                __set_owner( this,  urgent->owner->waiting_thread );
    759759
     
    764764        // Get the next thread in the entry_queue
    765765        $thread * new_owner = pop_head( this->entry_queue );
    766         /* paranoid */ verifyf( !this->owner || kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
     766        /* paranoid */ verifyf( !this->owner || active_thread() == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", active_thread(), this->owner, this->recursion, this );
    767767        /* paranoid */ verify( !new_owner || new_owner->link.next == 0p );
    768768        __set_owner( this, new_owner );
     
    892892
    893893static inline void brand_condition( condition & this ) {
    894         $thread * thrd = TL_GET( this_thread );
     894        $thread * thrd = active_thread();
    895895        if( !this.monitors ) {
    896896                // __cfaabi_dbg_print_safe( "Branding\n" );
  • libcfa/src/concurrency/mutex.cfa

    r16ba4a6 r18f0b70  
    4040        lock( lock __cfaabi_dbg_ctx2 );
    4141        if( is_locked ) {
    42                 append( blocked_threads, kernelTLS.this_thread );
     42                append( blocked_threads, active_thread() );
    4343                unlock( lock );
    4444                park();
     
    8686        lock( lock __cfaabi_dbg_ctx2 );
    8787        if( owner == 0p ) {
    88                 owner = kernelTLS.this_thread;
     88                owner = active_thread();
    8989                recursion_count = 1;
    9090                unlock( lock );
    9191        }
    92         else if( owner == kernelTLS.this_thread ) {
     92        else if( owner == active_thread() ) {
    9393                recursion_count++;
    9494                unlock( lock );
    9595        }
    9696        else {
    97                 append( blocked_threads, kernelTLS.this_thread );
     97                append( blocked_threads, active_thread() );
    9898                unlock( lock );
    9999                park();
     
    105105        lock( lock __cfaabi_dbg_ctx2 );
    106106        if( owner == 0p ) {
    107                 owner = kernelTLS.this_thread;
     107                owner = active_thread();
    108108                recursion_count = 1;
    109109                ret = true;
    110110        }
    111         else if( owner == kernelTLS.this_thread ) {
     111        else if( owner == active_thread() ) {
    112112                recursion_count++;
    113113                ret = true;
     
    159159void wait(condition_variable & this) {
    160160        lock( this.lock __cfaabi_dbg_ctx2 );
    161         append( this.blocked_threads, kernelTLS.this_thread );
     161        append( this.blocked_threads, active_thread() );
    162162        unlock( this.lock );
    163163        park();
     
    167167void wait(condition_variable & this, L & l) {
    168168        lock( this.lock __cfaabi_dbg_ctx2 );
    169         append( this.blocked_threads, kernelTLS.this_thread );
     169        append( this.blocked_threads, active_thread() );
    170170        unlock(l);
    171171        unlock(this.lock);
  • libcfa/src/concurrency/preemption.cfa

    r16ba4a6 r18f0b70  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 26 16:46:03 2020
    13 // Update Count     : 53
     12// Last Modified On : Fri Nov  6 07:42:13 2020
     13// Update Count     : 54
    1414//
    1515
     
    163163// Kernel Signal Tools
    164164//=============================================================================================
    165 
    166 __cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; )
     165// In a user-level threading system, there are handful of thread-local variables where this problem occurs on the ARM.
     166//
     167// For each kernel thread running user-level threads, there is a flag variable to indicate if interrupts are
     168// enabled/disabled for that kernel thread. Therefore, this variable is made thread local.
     169//
     170// For example, this code fragment sets the state of the "interrupt" variable in thread-local memory.
     171//
     172// _Thread_local volatile int interrupts;
     173// int main() {
     174//     interrupts = 0; // disable interrupts }
     175//
     176// which generates the following code on the ARM
     177//
     178// (gdb) disassemble main
     179// Dump of assembler code for function main:
     180//    0x0000000000000610 <+0>:  mrs     x1, tpidr_el0
     181//    0x0000000000000614 <+4>:  mov     w0, #0x0                        // #0
     182//    0x0000000000000618 <+8>:  add     x1, x1, #0x0, lsl #12
     183//    0x000000000000061c <+12>: add     x1, x1, #0x10
     184//    0x0000000000000620 <+16>: str     wzr, [x1]
     185//    0x0000000000000624 <+20>: ret
     186//
     187// The mrs moves a pointer from coprocessor register tpidr_el0 into register x1.  Register w0 is set to 0. The two adds
     188// increase the TLS pointer with the displacement (offset) 0x10, which is the location in the TSL of variable
     189// "interrupts".  Finally, 0 is stored into "interrupts" through the pointer in register x1 that points into the
     190// TSL. Now once x1 has the pointer to the location of the TSL for kernel thread N, it can be be preempted at a
     191// user-level and the user thread is put on the user-level ready-queue. When the preempted thread gets to the front of
     192// the user-level ready-queue it is run on kernel thread M. It now stores 0 into "interrupts" back on kernel thread N,
     193// turning off interrupt on the wrong kernel thread.
     194//
     195// On the x86, the following code is generated for the same code fragment.
     196//
     197// (gdb) disassemble main
     198// Dump of assembler code for function main:
     199//    0x0000000000400420 <+0>:  movl   $0x0,%fs:0xfffffffffffffffc
     200//    0x000000000040042c <+12>: xor    %eax,%eax
     201//    0x000000000040042e <+14>: retq
     202//
     203// and there is base-displacement addressing used to atomically reset variable "interrupts" off of the TSL pointer in
     204// register "fs".
     205//
     206// Hence, the ARM has base-displacement address for the general purpose registers, BUT not to the coprocessor
     207// registers. As a result, generating the address for the write into variable "interrupts" is no longer atomic.
     208//
     209// Note this problem does NOT occur when just using multiple kernel threads because the preemption ALWAYS restarts the
     210// thread on the same kernel thread.
     211//
     212// The obvious question is why does ARM use a coprocessor register to store the TSL pointer given that coprocessor
     213// registers are second-class registers with respect to the instruction set. One possible answer is that they did not
     214// want to dedicate one of the general registers to hold the TLS pointer and there was a free coprocessor register
     215// available.
     216
     217//----------
     218// special case for preemption since used often
     219bool __preemption_enabled() {
     220        // create a assembler label before
     221        // marked as clobber all to avoid movement
     222        asm volatile("__cfaasm_check_before:":::"memory");
     223
     224        // access tls as normal
     225        bool enabled = __cfaabi_tls.preemption_state.enabled;
     226
     227        // create a assembler label after
     228        // marked as clobber all to avoid movement
     229        asm volatile("__cfaasm_check_after:":::"memory");
     230        return enabled;
     231}
     232
     233//----------
     234// Get data from the TLS block
     235uintptr_t __cfatls_get( unsigned long int offset ) __attribute__((__noinline__)); //no inline to avoid problems
     236uintptr_t __cfatls_get( unsigned long int offset ) {
     237        // create a assembler label before
     238        // marked as clobber all to avoid movement
     239        asm volatile("__cfaasm_get_before:":::"memory");
     240
     241        // access tls as normal (except for pointer arithmetic)
     242        uintptr_t val = *(uintptr_t*)((uintptr_t)&__cfaabi_tls + offset);
     243
     244        // create a assembler label after
     245        // marked as clobber all to avoid movement
     246        asm volatile("__cfaasm_get_after:":::"memory");
     247        return val;
     248}
    167249
    168250extern "C" {
    169251        // Disable interrupts by incrementing the counter
    170252        void disable_interrupts() {
    171                 with( kernelTLS.preemption_state ) {
     253                // create a assembler label before
     254                // marked as clobber all to avoid movement
     255                asm volatile("__cfaasm_disable_before:":::"memory");
     256
     257                with( __cfaabi_tls.preemption_state ) {
    172258                        #if GCC_VERSION > 50000
    173259                        static_assert(__atomic_always_lock_free(sizeof(enabled), &enabled), "Must be lock-free");
     
    186272                        verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
    187273                }
     274
     275                // create a assembler label after
     276                // marked as clobber all to avoid movement
     277                asm volatile("__cfaasm_disable_after:":::"memory");
    188278        }
    189279
     
    191281        // If counter reaches 0, execute any pending __cfactx_switch
    192282        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    193                 processor   * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic store
     283                // create a assembler label before
     284                // marked as clobber all to avoid movement
     285                asm volatile("__cfaasm_enable_before:":::"memory");
     286
     287                processor   * proc = __cfaabi_tls.this_processor; // Cache the processor now since interrupts can start happening after the atomic store
    194288                /* paranoid */ verify( proc );
    195289
    196                 with( kernelTLS.preemption_state ){
     290                with( __cfaabi_tls.preemption_state ){
    197291                        unsigned short prev = disable_count;
    198292                        disable_count -= 1;
     
    221315                // For debugging purposes : keep track of the last person to enable the interrupts
    222316                __cfaabi_dbg_debug_do( proc->last_enable = caller; )
     317
     318                // create a assembler label after
     319                // marked as clobber all to avoid movement
     320                asm volatile("__cfaasm_enable_after:":::"memory");
    223321        }
    224322
     
    226324        // Don't execute any pending __cfactx_switch even if counter reaches 0
    227325        void enable_interrupts_noPoll() {
    228                 unsigned short prev = kernelTLS.preemption_state.disable_count;
    229                 kernelTLS.preemption_state.disable_count -= 1;
     326                // create a assembler label before
     327                // marked as clobber all to avoid movement
     328                asm volatile("__cfaasm_nopoll_before:":::"memory");
     329
     330                unsigned short prev = __cfaabi_tls.preemption_state.disable_count;
     331                __cfaabi_tls.preemption_state.disable_count -= 1;
    230332                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    231333                if( prev == 1 ) {
    232334                        #if GCC_VERSION > 50000
    233                         static_assert(__atomic_always_lock_free(sizeof(kernelTLS.preemption_state.enabled), &kernelTLS.preemption_state.enabled), "Must be lock-free");
     335                        static_assert(__atomic_always_lock_free(sizeof(__cfaabi_tls.preemption_state.enabled), &__cfaabi_tls.preemption_state.enabled), "Must be lock-free");
    234336                        #endif
    235337                        // Set enabled flag to true
    236338                        // should be atomic to avoid preemption in the middle of the operation.
    237339                        // use memory order RELAXED since there is no inter-thread on this variable requirements
    238                         __atomic_store_n(&kernelTLS.preemption_state.enabled, true, __ATOMIC_RELAXED);
     340                        __atomic_store_n(&__cfaabi_tls.preemption_state.enabled, true, __ATOMIC_RELAXED);
    239341
    240342                        // Signal the compiler that a fence is needed but only for signal handlers
    241343                        __atomic_signal_fence(__ATOMIC_RELEASE);
    242344                }
     345
     346                // create a assembler label after
     347                // marked as clobber all to avoid movement
     348                asm volatile("__cfaasm_nopoll_after:":::"memory");
    243349        }
    244350}
     
    275381static void timeout( $thread * this ) {
    276382        #if !defined( __CFA_NO_STATISTICS__ )
    277                 kernelTLS.this_stats = this->curr_cluster->stats;
     383                kernelTLS().this_stats = this->curr_cluster->stats;
    278384        #endif
    279385        unpark( this );
     
    286392static inline bool preemption_ready() {
    287393        // Check if preemption is safe
    288         bool ready = kernelTLS.preemption_state.enabled && ! kernelTLS.preemption_state.in_progress;
     394        bool ready = __cfaabi_tls.preemption_state.enabled && ! __cfaabi_tls.preemption_state.in_progress;
    289395
    290396        // Adjust the pending flag accordingly
    291         kernelTLS.this_processor->pending_preemption = !ready;
     397        __cfaabi_tls.this_processor->pending_preemption = !ready;
    292398        return ready;
    293399}
     
    303409
    304410        // Start with preemption disabled until ready
    305         kernelTLS.preemption_state.enabled = false;
    306         kernelTLS.preemption_state.disable_count = 1;
     411        __cfaabi_tls.preemption_state.enabled = false;
     412        __cfaabi_tls.preemption_state.disable_count = 1;
    307413
    308414        // Initialize the event kernel
     
    362468// Kernel Signal Handlers
    363469//=============================================================================================
     470struct asm_region {
     471        void * before;
     472        void * after;
     473};
     474
     475//-----------------------------------------------------------------------------
     476// Some assembly required
     477#if defined( __i386 )
     478        #define __cfaasm_label( label ) \
     479                ({ \
     480                        struct asm_region region; \
     481                        asm( \
     482                                "movl $__cfaasm_" #label "_before, %[vb]\n\t" \
     483                                "movl $__cfaasm_" #label "_after , %[va]\n\t" \
     484                                 : [vb]"=r"(region.before), [vb]"=r"(region.before) \
     485                        ); \
     486                        region; \
     487                });
     488#elif defined( __x86_64 )
     489        #ifdef __PIC__
     490                #define PLT "@PLT"
     491        #else
     492                #define PLT ""
     493        #endif
     494        #define __cfaasm_label( label ) \
     495                ({ \
     496                        struct asm_region region; \
     497                        asm( \
     498                                "movq $__cfaasm_" #label "_before" PLT ", %[vb]\n\t" \
     499                                "movq $__cfaasm_" #label "_after"  PLT ", %[va]\n\t" \
     500                                 : [vb]"=r"(region.before), [va]"=r"(region.after) \
     501                        ); \
     502                        region; \
     503                });
     504#elif defined( __aarch64__ )
     505        #error __cfaasm_label undefined for arm
     506#else
     507        #error unknown hardware architecture
     508#endif
     509
     510__cfaabi_dbg_debug_do( static thread_local void * last_interrupt = 0; )
    364511
    365512// Context switch signal handler
    366513// Receives SIGUSR1 signal and causes the current thread to yield
    367514static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
    368         __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.CFA_REG_IP); )
     515        void * ip = (void *)(cxt->uc_mcontext.CFA_REG_IP);
     516        __cfaabi_dbg_debug_do( last_interrupt = ip; )
    369517
    370518        // SKULLDUGGERY: if a thread creates a processor and the immediately deletes it,
     
    372520        // before the kernel thread has even started running. When that happens, an interrupt
    373521        // with a null 'this_processor' will be caught, just ignore it.
    374         if(! kernelTLS.this_processor ) return;
     522        if(! __cfaabi_tls.this_processor ) return;
    375523
    376524        choose(sfp->si_value.sival_int) {
    377525                case PREEMPT_NORMAL   : ;// Normal case, nothing to do here
    378                 case PREEMPT_TERMINATE: verify( __atomic_load_n( &kernelTLS.this_processor->do_terminate, __ATOMIC_SEQ_CST ) );
     526                case PREEMPT_TERMINATE: verify( __atomic_load_n( &__cfaabi_tls.this_processor->do_terminate, __ATOMIC_SEQ_CST ) );
    379527                default:
    380528                        abort( "internal error, signal value is %d", sfp->si_value.sival_int );
     
    384532        if( !preemption_ready() ) { return; }
    385533
    386         __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p @ %p).\n", kernelTLS.this_processor, kernelTLS.this_thread, (void *)(cxt->uc_mcontext.CFA_REG_IP) );
     534        struct asm_region region;
     535        region = __cfaasm_label( get     ); if( ip >= region.before && ip <= region.after ) return;
     536        region = __cfaasm_label( check   ); if( ip >= region.before && ip <= region.after ) return;
     537        region = __cfaasm_label( disable ); if( ip >= region.before && ip <= region.after ) return;
     538        region = __cfaasm_label( enable  ); if( ip >= region.before && ip <= region.after ) return;
     539        region = __cfaasm_label( nopoll  ); if( ip >= region.before && ip <= region.after ) return;
     540
     541        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p @ %p).\n", __cfaabi_tls.this_processor, __cfaabi_tls.this_thread, (void *)(cxt->uc_mcontext.CFA_REG_IP) );
    387542
    388543        // Sync flag : prevent recursive calls to the signal handler
    389         kernelTLS.preemption_state.in_progress = true;
     544        __cfaabi_tls.preemption_state.in_progress = true;
    390545
    391546        // Clear sighandler mask before context switching.
     
    397552        }
    398553
    399         // TODO: this should go in finish action
    400554        // Clear the in progress flag
    401         kernelTLS.preemption_state.in_progress = false;
     555        __cfaabi_tls.preemption_state.in_progress = false;
    402556
    403557        // Preemption can occur here
     
    416570        id.full_proc = false;
    417571        id.id = doregister(&id);
    418         kernelTLS.this_proc_id = &id;
     572        __cfaabi_tls.this_proc_id = &id;
    419573
    420574        // Block sigalrms to control when they arrive
     
    484638
    485639void __cfaabi_check_preemption() {
    486         bool ready = kernelTLS.preemption_state.enabled;
     640        bool ready = __preemption_enabled();
    487641        if(!ready) { abort("Preemption should be ready"); }
    488642
     
    507661#ifdef __CFA_WITH_VERIFY__
    508662bool __cfaabi_dbg_in_kernel() {
    509         return !kernelTLS.preemption_state.enabled;
     663        return !__preemption_enabled();
    510664}
    511665#endif
  • libcfa/src/concurrency/ready_queue.cfa

    r16ba4a6 r18f0b70  
    150150//  queues or removing them.
    151151uint_fast32_t ready_mutate_lock( void ) with(*__scheduler_lock) {
    152         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     152        /* paranoid */ verify( ! __preemption_enabled() );
    153153
    154154        // Step 1 : lock global lock
     
    166166        }
    167167
    168         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     168        /* paranoid */ verify( ! __preemption_enabled() );
    169169        return s;
    170170}
    171171
    172172void ready_mutate_unlock( uint_fast32_t last_s ) with(*__scheduler_lock) {
    173         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     173        /* paranoid */ verify( ! __preemption_enabled() );
    174174
    175175        // Step 1 : release local locks
     
    188188        __atomic_store_n(&lock, (bool)false, __ATOMIC_RELEASE);
    189189
    190         /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     190        /* paranoid */ verify( ! __preemption_enabled() );
    191191}
    192192
     
    252252                preferred =
    253253                        //*
    254                         kernelTLS.this_processor ? kernelTLS.this_processor->id * 4 : -1;
     254                        kernelTLS().this_processor ? kernelTLS().this_processor->id * 4 : -1;
    255255                        /*/
    256256                        thrd->link.preferred * 4;
     
    331331                // Don't bother trying locally too much
    332332                int local_tries = 8;
    333                 preferred = kernelTLS.this_processor->id * 4;
     333                preferred = kernelTLS().this_processor->id * 4;
    334334        #endif
    335335
  • libcfa/src/stdlib.hfa

    r16ba4a6 r18f0b70  
    101101                return (T *)pvalloc( sizeof(T) );                               // C pvalloc
    102102        } // pvalloc
     103
     104        void free( T * addr ) {
     105                free( (void *) addr );                                                  // C free
     106        } // free
     107} // distribution
     108
     109static inline forall( ttype TT | { void free( TT ); } ) {
     110        // T* does not take void* and vice-versa
     111
     112        void free( void * addr, TT rest ) {
     113                free( addr );
     114                free( rest );
     115        } // free
     116
     117        forall( dtype T | sized(T) )
     118        void free( T * addr, TT rest ) {
     119                free( addr );
     120                free( rest );
     121        } // free
    103122} // distribution
    104123
  • tests/alloc.cfa

    r16ba4a6 r18f0b70  
    208208
    209209
     210        int const_count, dest_count;
    210211        struct Struct { int x; double y; };
     212        void  ?{}( Struct & a ) {                                       // construct
     213                a.[ x, y ] = [ -1, -1.0 ];
     214        }
     215        void  ?{}( Struct & a, int x, double y ) {      // initialize
     216                a.[ x, y ] = [ x, y ];
     217                const_count++;
     218        }
     219        void ^?{}( Struct & a ) {  dest_count++; }      // destruct
    211220        Struct st, st1, sta[dim], sta1[dim], * stp, * stp1;
    212221
     
    329338        printf( "\n" );
    330339
     340        const_count = dest_count = 0;
    331341        stp = new( 42, 42.5 );
     342        assert( const_count == 1 && dest_count == 0 );                                          // assertion for testing
    332343        stp1 = new( 42, 42.5 );
     344        assert( const_count == 2 && dest_count == 0 );                                          // assertion for testing
     345
    333346        printf( "CFA new initialize\n%d %g %d %g\n", stp->x, stp->y, stp1->x, stp1->y );
    334347        delete( stp, stp1 );
     348        assert( const_count == 2 && dest_count == 2 );                                          // assertion for testing
    335349
    336350        // new, array types
    337351        stp = anew( dim, 42, 42.5 );
     352        assert( const_count == 2 + dim && dest_count == 2 );                            // assertion for testing
    338353        printf( "CFA array new initialize\n" );
    339354        for ( i; dim ) { printf( "%d %g, ", stp[i].x, stp[i].y ); }
    340355        printf( "\n" );
     356
    341357        stp1 = anew( dim, 42, 42.5 );
     358        assert( const_count == 2 + 2 * dim && dest_count == 2 );                        // assertion for testing
    342359        for ( i; dim ) { printf( "%d %g, ", stp1[i].x, stp1[i].y ); }
    343360        printf( "\n" );
    344361        adelete( stp, stp1 );
     362        assert( const_count == 2 + 2 * dim && dest_count == 2 + 2 * dim);       // assertion for testing
    345363
    346364        // extras
     
    354372        *ip = 0xdeadbeef;
    355373        printf( "CFA deep malloc %#x\n", *ip );
    356         free( ip );
     374
     375        dp = alloc(5.0`fill); // just for testing multiple free
     376        assert(*dp == 5.0);
     377        free( ip, dp );
    357378
    358379#ifdef ERR1
  • tests/malloc.cfa

    r16ba4a6 r18f0b70  
    319319        free(ip);
    320320
    321         free( 0p ); // sanity check
     321        free( (void*) 0p ); // sanity check
    322322        free( NULL ); // sanity check
    323323
  • tools/stat.py

    r16ba4a6 r18f0b70  
    1 #!/usr/bin/python
     1#!/usr/bin/python3
    22
    33import sys
     
    1717                avg = numpy.mean  (content)
    1818                std = numpy.std   (content)
    19                 print "median {0:.1f} avg {1:.1f} stddev {2:.1f}".format( med, avg, std )
     19                print("median {0:.1f} avg {1:.1f} stddev {2:.1f}".format( med, avg, std ))
    2020
    2121
Note: See TracChangeset for help on using the changeset viewer.