Ignore:
Timestamp:
May 4, 2022, 3:28:00 PM (2 years ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
ec57856
Parents:
f6737ae1
Message:

added fast lock/cond var

File:
1 edited

Legend:

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

    rf6737ae1 r7f958c4  
    7373static inline void   on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
    7474
     75//-----------------------------------------------------------------------------
     76// MCS Lock
    7577struct mcs_node {
    7678        mcs_node * volatile next;
     
    98100}
    99101
     102//-----------------------------------------------------------------------------
     103// Linear backoff Spinlock
    100104struct linear_backoff_then_block_lock {
    101105        // Spin lock used for mutual exclusion
     
    199203
    200204//-----------------------------------------------------------------------------
     205// Fast Block Lock
     206
     207// High efficiency minimal blocking lock
     208// - No reacquire for cond var
     209// - No recursive acquisition
     210// - No ownership
     211struct fast_block_lock {
     212        // Spin lock used for mutual exclusion
     213        __spinlock_t lock;
     214
     215        // List of blocked threads
     216        dlist( thread$ ) blocked_threads;
     217
     218        bool held:1;
     219};
     220
     221static inline void  ?{}( fast_block_lock & this ) with(this) {
     222        lock{};
     223        blocked_threads{};
     224        held = false;
     225}
     226static inline void ^?{}( fast_block_lock & this ) {}
     227static inline void ?{}( fast_block_lock & this, fast_block_lock this2 ) = void;
     228static inline void ?=?( fast_block_lock & this, fast_block_lock this2 ) = void;
     229
     230// if this is called recursively IT WILL DEADLOCK!!!!!
     231static inline void lock(fast_block_lock & this) with(this) {
     232        lock( lock __cfaabi_dbg_ctx2 );
     233        if (held) {
     234                insert_last( blocked_threads, *active_thread() );
     235                unlock( lock );
     236                park( );
     237                return;
     238        }
     239        held = true;
     240        unlock( lock );
     241}
     242
     243static inline void unlock(fast_block_lock & this) with(this) {
     244        lock( lock __cfaabi_dbg_ctx2 );
     245        /* paranoid */ verifyf( held != false, "Attempt to release lock %p that isn't held", &this );
     246        thread$ * t = &try_pop_front( blocked_threads );
     247        held = ( t ? true : false );
     248        unpark( t );
     249        unlock( lock );
     250}
     251
     252static inline void on_notify(fast_block_lock & this, struct thread$ * t ) { unpark(t); }
     253static inline size_t on_wait(fast_block_lock & this) { unlock(this); return 0; }
     254static inline void on_wakeup(fast_block_lock & this, size_t recursion ) { }
     255
     256//-----------------------------------------------------------------------------
    201257// is_blocking_lock
    202258trait is_blocking_lock(L & | sized(L)) {
     
    226282// Synchronization Locks
    227283forall(L & | is_blocking_lock(L)) {
     284
     285        //-----------------------------------------------------------------------------
     286        // condition_variable
     287
     288        // The multi-tool condition variable
     289        // - can pass timeouts to wait for either a signal or timeout
     290        // - can wait without passing a lock
     291        // - can have waiters reacquire different locks while waiting on the same cond var
     292        // - has shadow queue
     293        // - can be signalled outside of critical sections with no locks held
    228294        struct condition_variable {
    229295                // Spin lock used for mutual exclusion
     
    258324        bool wait( condition_variable(L) & this, L & l, Duration duration );
    259325        bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
    260 }
     326
     327        //-----------------------------------------------------------------------------
     328        // fast_cond_var
     329
     330        // The trimmed and slim condition variable
     331        // - no internal lock so you must hold a lock while using this cond var
     332        // - signalling without holding branded lock is UNSAFE!
     333        // - only allows usage of one lock, cond var is branded after usage
     334        struct fast_cond_var {
     335                // List of blocked threads
     336                dlist( info_thread(L) ) blocked_threads;
     337
     338                #ifdef __CFA_DEBUG__
     339                L * lock_used;
     340                #endif
     341        };
     342
     343
     344        void  ?{}( fast_cond_var(L) & this );
     345        void ^?{}( fast_cond_var(L) & this );
     346
     347        bool notify_one( fast_cond_var(L) & this );
     348        bool notify_all( fast_cond_var(L) & this );
     349
     350        uintptr_t front( fast_cond_var(L) & this );
     351
     352        bool empty  ( fast_cond_var(L) & this );
     353
     354        void wait( fast_cond_var(L) & this, L & l );
     355        void wait( fast_cond_var(L) & this, L & l, uintptr_t info );
     356}
Note: See TracChangeset for help on using the changeset viewer.