Ignore:
File:
1 edited

Legend:

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

    r0cee082 r0348fd8  
    3838#include <unistd.h>
    3939
    40 // C_TODO: cleanup this and locks.cfa
    41 // - appropriate separation of interface and impl
    42 // - clean up unused/unneeded locks
    43 // - change messy big blocking lock from inheritance to composition to remove need for flags
     40// undef to make a number of the locks not reacquire upon waking from a condlock
     41#define REACQ 1
    4442
    4543//-----------------------------------------------------------------------------
     
    251249static inline void on_notify(clh_lock & this, struct thread$ * t ) { unpark(t); }
    252250static inline size_t on_wait(clh_lock & this) { unlock(this); return 0; }
    253 static inline void on_wakeup(clh_lock & this, size_t recursion ) { lock(this); }
    254 
    255 
    256 //-----------------------------------------------------------------------------
    257 // Exponential backoff then block lock
    258 struct exp_backoff_then_block_lock {
     251static inline void on_wakeup(clh_lock & this, size_t recursion ) {
     252        #ifdef REACQ
     253        lock(this);
     254        #endif
     255}
     256
     257
     258//-----------------------------------------------------------------------------
     259// Linear backoff Spinlock
     260struct linear_backoff_then_block_lock {
    259261        // Spin lock used for mutual exclusion
    260262        __spinlock_t spinlock;
     
    267269};
    268270
    269 static inline void  ?{}( exp_backoff_then_block_lock & this ) {
     271static inline void  ?{}( linear_backoff_then_block_lock & this ) {
    270272        this.spinlock{};
    271273        this.blocked_threads{};
    272274        this.lock_value = 0;
    273275}
    274 static inline void ^?{}( exp_backoff_then_block_lock & this ) {}
    275 // static inline void ?{}( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;
    276 // static inline void ?=?( exp_backoff_then_block_lock & this, exp_backoff_then_block_lock this2 ) = void;
    277 
    278 static inline bool internal_try_lock(exp_backoff_then_block_lock & this, size_t & compare_val) with(this) {
     276static inline void ^?{}( linear_backoff_then_block_lock & this ) {}
     277// static inline void ?{}( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
     278// static inline void ?=?( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
     279
     280static inline bool internal_try_lock(linear_backoff_then_block_lock & this, size_t & compare_val) with(this) {
    279281        if (__atomic_compare_exchange_n(&lock_value, &compare_val, 1, false, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
    280282                return true;
     
    283285}
    284286
    285 static inline bool try_lock(exp_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }
    286 
    287 static inline bool try_lock_contention(exp_backoff_then_block_lock & this) with(this) {
     287static inline bool try_lock(linear_backoff_then_block_lock & this) { size_t compare_val = 0; return internal_try_lock(this, compare_val); }
     288
     289static inline bool try_lock_contention(linear_backoff_then_block_lock & this) with(this) {
    288290        if (__atomic_exchange_n(&lock_value, 2, __ATOMIC_ACQUIRE) == 0) {
    289291                return true;
     
    292294}
    293295
    294 static inline bool block(exp_backoff_then_block_lock & this) with(this) {
     296static inline bool block(linear_backoff_then_block_lock & this) with(this) {
    295297        lock( spinlock __cfaabi_dbg_ctx2 ); // TODO change to lockfree queue (MPSC)
    296298        if (lock_value != 2) {
     
    304306}
    305307
    306 static inline void lock(exp_backoff_then_block_lock & this) with(this) {
     308static inline void lock(linear_backoff_then_block_lock & this) with(this) {
    307309        size_t compare_val = 0;
    308310        int spin = 4;
     
    322324}
    323325
    324 static inline void unlock(exp_backoff_then_block_lock & this) with(this) {
     326static inline void unlock(linear_backoff_then_block_lock & this) with(this) {
    325327    if (__atomic_exchange_n(&lock_value, 0, __ATOMIC_RELEASE) == 1) return;
    326328        lock( spinlock __cfaabi_dbg_ctx2 );
     
    330332}
    331333
    332 static inline void on_notify(exp_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
    333 static inline size_t on_wait(exp_backoff_then_block_lock & this) { unlock(this); return 0; }
    334 static inline void on_wakeup(exp_backoff_then_block_lock & this, size_t recursion ) { lock(this); }
     334static inline void on_notify(linear_backoff_then_block_lock & this, struct thread$ * t ) { unpark(t); }
     335static inline size_t on_wait(linear_backoff_then_block_lock & this) { unlock(this); return 0; }
     336static inline void on_wakeup(linear_backoff_then_block_lock & this, size_t recursion ) {
     337        #ifdef REACQ
     338        lock(this);
     339        #endif
     340}
    335341
    336342//-----------------------------------------------------------------------------
     
    384390
    385391static inline void on_notify(fast_block_lock & this, struct thread$ * t ) with(this) {
    386     lock( lock __cfaabi_dbg_ctx2 );
    387     insert_last( blocked_threads, *t );
    388     unlock( lock );
     392        #ifdef REACQ
     393                lock( lock __cfaabi_dbg_ctx2 );
     394                insert_last( blocked_threads, *t );
     395                unlock( lock );
     396        #else
     397                unpark(t);
     398        #endif
    389399}
    390400static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; }
     
    543553}
    544554static inline size_t on_wait(spin_queue_lock & this) { unlock(this); return 0; }
    545 static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) { lock(this); }
     555static inline void on_wakeup(spin_queue_lock & this, size_t recursion ) {
     556        #ifdef REACQ
     557        lock(this);
     558        #endif
     559}
    546560
    547561
     
    584598static inline void on_notify(mcs_block_spin_lock & this, struct thread$ * t ) { unpark(t); }
    585599static inline size_t on_wait(mcs_block_spin_lock & this) { unlock(this); return 0; }
    586 static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {lock(this); }
     600static inline void on_wakeup(mcs_block_spin_lock & this, size_t recursion ) {
     601        #ifdef REACQ
     602        lock(this);
     603        #endif
     604}
    587605
    588606//-----------------------------------------------------------------------------
     
    622640
    623641static inline void on_notify(block_spin_lock & this, struct thread$ * t ) with(this.lock) {
     642  #ifdef REACQ
    624643        // first we acquire internal fast_block_lock
    625644        lock( lock __cfaabi_dbg_ctx2 );
     
    633652        unlock( lock );
    634653
     654  #endif
    635655        unpark(t);
     656       
    636657}
    637658static inline size_t on_wait(block_spin_lock & this) { unlock(this); return 0; }
    638659static inline void on_wakeup(block_spin_lock & this, size_t recursion ) with(this) {
     660  #ifdef REACQ
    639661        // now we acquire the entire block_spin_lock upon waking up
    640662        while(__atomic_load_n(&held, __ATOMIC_SEQ_CST)) Pause();
    641663        __atomic_store_n(&held, true, __ATOMIC_RELEASE);
    642664        unlock( lock ); // Now we release the internal fast_spin_lock
     665  #endif
    643666}
    644667
Note: See TracChangeset for help on using the changeset viewer.