Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/locks.hfa

    reba9d27 rbbe3719  
    3939struct Semaphore0nary {
    4040        __spinlock_t lock; // needed to protect
    41         mpsc_queue($thread) queue;
    42 };
    43 
    44 static inline bool P(Semaphore0nary & this, $thread * thrd) {
     41        mpsc_queue(thread$) queue;
     42};
     43
     44static inline bool P(Semaphore0nary & this, thread$ * thrd) {
    4545        /* paranoid */ verify(!thrd`next);
    4646        /* paranoid */ verify(!(&(*thrd)`next));
     
    5151
    5252static inline bool P(Semaphore0nary & this) {
    53     $thread * thrd = active_thread();
     53    thread$ * thrd = active_thread();
    5454    P(this, thrd);
    5555    park();
     
    5757}
    5858
    59 static inline $thread * V(Semaphore0nary & this, bool doUnpark = true) {
    60         $thread * next;
     59static inline thread$ * V(Semaphore0nary & this, bool doUnpark = true) {
     60        thread$ * next;
    6161        lock(this.lock __cfaabi_dbg_ctx2);
    6262                for (;;) {
     
    124124static inline bool P(ThreadBenaphore & this, bool wait)   { return wait ? P(this) : tryP(this); }
    125125
    126 static inline $thread * V(ThreadBenaphore & this, bool doUnpark = true) {
     126static inline thread$ * V(ThreadBenaphore & this, bool doUnpark = true) {
    127127        if (V(this.ben)) return 0p;
    128128        return V(this.sem, doUnpark);
     
    134134        __spinlock_t lock;
    135135        int count;
    136         __queue_t($thread) waiting;
     136        __queue_t(thread$) waiting;
    137137};
    138138
     
    142142bool   V (semaphore & this);
    143143bool   V (semaphore & this, unsigned count);
    144 $thread * V (semaphore & this, bool );
     144thread$ * V (semaphore & this, bool );
    145145
    146146//----------
     
    156156static inline size_t on_wait  ( single_acquisition_lock & this ) { return on_wait ( (blocking_lock &)this ); }
    157157static inline void   on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    158 static inline void   on_notify( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
     158static inline void   on_notify( single_acquisition_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
    159159
    160160//----------
     
    170170static inline size_t on_wait  ( owner_lock & this ) { return on_wait ( (blocking_lock &)this ); }
    171171static inline void   on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    172 static inline void   on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
     172static inline void   on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
    173173
    174174struct fast_lock {
    175         $thread * volatile owner;
     175        thread$ * volatile owner;
    176176        ThreadBenaphore sem;
    177177};
     
    179179static inline void ?{}(fast_lock & this) { this.owner = 0p; }
    180180
    181 static inline bool $try_lock(fast_lock & this, $thread * thrd) {
    182     $thread * exp = 0p;
     181static inline bool $try_lock(fast_lock & this, thread$ * thrd) {
     182    thread$ * exp = 0p;
    183183    return __atomic_compare_exchange_n(&this.owner, &exp, thrd, false, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
    184184}
     
    186186static inline void lock( fast_lock & this ) __attribute__((artificial));
    187187static inline void lock( fast_lock & this ) {
    188         $thread * thrd = active_thread();
     188        thread$ * thrd = active_thread();
    189189        /* paranoid */verify(thrd != this.owner);
    190190
     
    197197static inline bool try_lock( fast_lock & this ) __attribute__((artificial));
    198198static inline bool try_lock ( fast_lock & this ) {
    199         $thread * thrd = active_thread();
     199        thread$ * thrd = active_thread();
    200200        /* paranoid */ verify(thrd != this.owner);
    201201        return $try_lock(this, thrd);
    202202}
    203203
    204 static inline $thread * unlock( fast_lock & this ) __attribute__((artificial));
    205 static inline $thread * unlock( fast_lock & this ) {
     204static inline thread$ * unlock( fast_lock & this ) __attribute__((artificial));
     205static inline thread$ * unlock( fast_lock & this ) {
    206206        /* paranoid */ verify(active_thread() == this.owner);
    207207
     
    216216static inline size_t on_wait( fast_lock & this ) { unlock(this); return 0; }
    217217static inline void on_wakeup( fast_lock & this, size_t ) { lock(this); }
    218 static inline void on_notify( fast_lock &, struct $thread * t ) { unpark(t); }
     218static inline void on_notify( fast_lock &, struct thread$ * t ) { unpark(t); }
    219219
    220220struct mcs_node {
     
    248248
    249249        // Current thread owning the lock
    250         struct $thread * owner;
     250        struct thread$ * owner;
    251251
    252252        // List of blocked threads
    253         dlist( $thread ) blocked_threads;
     253        dlist( thread$ ) blocked_threads;
    254254
    255255        // Used for comparing and exchanging
     
    324324        }
    325325
    326         // linear backoff bounded by spin_count
    327         spin = spin_start;
    328         int spin_counter = 0;
    329         int yield_counter = 0;
    330         for ( ;; ) {
    331                 if(try_lock_contention(this)) return true;
    332                 if(spin_counter < spin_count) {
    333                         for (int i = 0; i < spin; i++) Pause();
    334                         if (spin < spin_end) spin += spin;
    335                         else spin_counter++;
    336                 } else if (yield_counter < yield_count) {
    337                         // after linear backoff yield yield_count times
    338                         yield_counter++;
    339                         yield();
    340                 } else { break; }
    341         }
    342 
    343         // block until signalled
    344         while (block(this)) if(try_lock_contention(this)) return true;
    345        
    346         // this should never be reached as block(this) always returns true
    347         return false;
    348 }
    349 
    350 static inline bool lock_improved(linear_backoff_then_block_lock & this) with(this) {
    351         // if owner just return
    352         if (active_thread() == owner) return true;
    353         size_t compare_val = 0;
    354         int spin = spin_start;
    355         // linear backoff
    356         for( ;; ) {
    357                 compare_val = 0;
    358                 if (internal_try_lock(this, compare_val)) return true;
    359                 if (2 == compare_val) break;
    360                 for (int i = 0; i < spin; i++) Pause();
    361                 if (spin >= spin_end) break;
    362                 spin += spin;
    363         }
    364 
    365         // linear backoff bounded by spin_count
    366         spin = spin_start;
    367         int spin_counter = 0;
    368         int yield_counter = 0;
    369         for ( ;; ) {
    370                 compare_val = 0;
    371                 if(internal_try_lock(this, compare_val)) return true;
    372                 if (2 == compare_val) break;
    373                 if(spin_counter < spin_count) {
    374                         for (int i = 0; i < spin; i++) Pause();
    375                         if (spin < spin_end) spin += spin;
    376                         else spin_counter++;
    377                 } else if (yield_counter < yield_count) {
    378                         // after linear backoff yield yield_count times
    379                         yield_counter++;
    380                         yield();
    381                 } else { break; }
    382         }
    383 
    384326        if(2 != compare_val && try_lock_contention(this)) return true;
    385327        // block until signalled
    386328        while (block(this)) if(try_lock_contention(this)) return true;
    387        
     329
    388330        // this should never be reached as block(this) always returns true
    389331        return false;
     
    395337    if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return;
    396338        lock( spinlock __cfaabi_dbg_ctx2 );
    397         $thread * t = &try_pop_front( blocked_threads );
     339        thread$ * t = &try_pop_front( blocked_threads );
    398340        unlock( spinlock );
    399341        unpark( t );
    400342}
    401343
    402 static inline void on_notify(linear_backoff_then_block_lock & this, struct $thread * t ) { unpark(t); }
     344static inline void on_notify(linear_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
    403345static inline size_t on_wait(linear_backoff_then_block_lock & this) { unlock(this); return 0; }
    404 static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) { lock_improved(this); }
     346static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) { lock(this); }
    405347
    406348//-----------------------------------------------------------------------------
     
    408350trait is_blocking_lock(L & | sized(L)) {
    409351        // For synchronization locks to use when acquiring
    410         void on_notify( L &, struct $thread * );
     352        void on_notify( L &, struct thread$ * );
    411353
    412354        // For synchronization locks to use when releasing
     
    442384                int count;
    443385        };
    444        
     386
    445387
    446388        void  ?{}( condition_variable(L) & this );
Note: See TracChangeset for help on using the changeset viewer.