Ignore:
Timestamp:
Jun 8, 2022, 4:23:08 PM (23 months ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
55422cf
Parents:
ced5e2a
Message:

added pthread_cond_var

File:
1 edited

Legend:

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

    rced5e2a rae06e0b  
    366366static inline void ?=?( simple_owner_lock & this, simple_owner_lock this2 ) = void;
    367367
     368static inline void lock(simple_owner_lock & this) with(this) {
     369        if (owner == active_thread()) {
     370                recursion_count++;
     371                return;
     372        }
     373        lock( lock __cfaabi_dbg_ctx2 );
     374
     375        if (owner != 0p) {
     376                insert_last( blocked_threads, *active_thread() );
     377                unlock( lock );
     378                park( );
     379                return;
     380        }
     381        owner = active_thread();
     382        recursion_count = 1;
     383        unlock( lock );
     384}
     385
     386// TODO: fix duplicate def issue and bring this back
     387// void pop_and_set_new_owner( simple_owner_lock & this ) with( this ) {
     388        // thread$ * t = &try_pop_front( blocked_threads );
     389        // owner = t;
     390        // recursion_count = ( t ? 1 : 0 );
     391        // unpark( t );
     392// }
     393
     394static inline void unlock(simple_owner_lock & this) with(this) {
     395        lock( lock __cfaabi_dbg_ctx2 );
     396        /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
     397        /* paranoid */ verifyf( owner == active_thread(), "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
     398        // if recursion count is zero release lock and set new owner if one is waiting
     399        recursion_count--;
     400        if ( recursion_count == 0 ) {
     401                // pop_and_set_new_owner( this );
     402                thread$ * t = &try_pop_front( blocked_threads );
     403                owner = t;
     404                recursion_count = ( t ? 1 : 0 );
     405                unpark( t );
     406        }
     407        unlock( lock );
     408}
     409
     410static inline void on_notify(simple_owner_lock & this, struct thread$ * t ) with(this) {
     411        lock( lock __cfaabi_dbg_ctx2 );
     412        // lock held
     413        if ( owner != 0p ) {
     414                insert_last( blocked_threads, *t );
     415                unlock( lock );
     416        }
     417        // lock not held
     418        else {
     419                owner = t;
     420                recursion_count = 1;
     421                unpark( t );
     422                unlock( lock );
     423        }
     424}
     425
     426static inline size_t on_wait(simple_owner_lock & this) with(this) {
     427        lock( lock __cfaabi_dbg_ctx2 );
     428        /* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
     429        /* paranoid */ verifyf( owner == active_thread(), "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
     430
     431        size_t ret = recursion_count;
     432
     433        // pop_and_set_new_owner( this );
     434
     435        thread$ * t = &try_pop_front( blocked_threads );
     436        owner = t;
     437        recursion_count = ( t ? 1 : 0 );
     438        unpark( t );
     439
     440        unlock( lock );
     441        return ret;
     442}
     443
     444static inline void on_wakeup(simple_owner_lock & this, size_t recursion ) with(this) { recursion_count = recursion; }
     445
    368446//-----------------------------------------------------------------------------
    369447// Spin Queue Lock
     
    606684        // - signalling without holding branded lock is UNSAFE!
    607685        // - only allows usage of one lock, cond var is branded after usage
     686
    608687        struct fast_cond_var {
    609688                // List of blocked threads
    610689                dlist( info_thread(L) ) blocked_threads;
    611 
    612690                #ifdef __CFA_DEBUG__
    613691                L * lock_used;
     
    615693        };
    616694
    617 
    618695        void  ?{}( fast_cond_var(L) & this );
    619696        void ^?{}( fast_cond_var(L) & this );
     
    623700
    624701        uintptr_t front( fast_cond_var(L) & this );
    625 
    626702        bool empty  ( fast_cond_var(L) & this );
    627703
    628704        void wait( fast_cond_var(L) & this, L & l );
    629705        void wait( fast_cond_var(L) & this, L & l, uintptr_t info );
    630 }
     706
     707
     708        //-----------------------------------------------------------------------------
     709        // pthread_cond_var
     710        //
     711        // - cond var with minimal footprint
     712        // - supports operations needed for phthread cond
     713
     714        struct pthread_cond_var {
     715                dlist( info_thread(L) ) blocked_threads;
     716                __spinlock_t lock;
     717        };
     718
     719        void  ?{}( pthread_cond_var(L) & this );
     720        void ^?{}( pthread_cond_var(L) & this );
     721
     722        bool notify_one( pthread_cond_var(L) & this );
     723        bool notify_all( pthread_cond_var(L) & this );
     724
     725        uintptr_t front( pthread_cond_var(L) & this );
     726        bool empty ( pthread_cond_var(L) & this );
     727
     728        void wait( pthread_cond_var(L) & this, L & l );
     729        void wait( pthread_cond_var(L) & this, L & l, uintptr_t info );
     730        bool wait( pthread_cond_var(L) & this, L & l, timespec t );
     731        bool wait( pthread_cond_var(L) & this, L & l, uintptr_t info, timespec t );
     732}
Note: See TracChangeset for help on using the changeset viewer.