Ignore:
File:
1 edited

Legend:

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

    rfbaea970 r8dc8f68  
    1111// Created On       : Thu Jan 21 19:46:50 2021
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Sun Nov 23 22:38:45 2025
    14 // Update Count     : 67
     13// Last Modified On : Thu Aug 21 22:36:44 2025
     14// Update Count     : 23
    1515//
    1616
     
    8181
    8282
    83 //-----------------------------------------------------------------------------
    84 // Semaphore, counting
    85 
     83
     84//-----------------------------------------------------------------------------
     85// Semaphore
    8686struct semaphore {
    87         ssize_t count$;                                                                          // - => # waiting threads, 0 => block, + => acquire
    88         __spinlock_t lock$;                                                                      // protect blocking-lock critical sections
    89         __queue_t( thread$ ) waiting$;                                           // waiting threads
    90 };
    91 
    92 void ?{}( semaphore & sem, ssize_t count = 1 );
    93 // Return values are used for composition. Calling threads know if a thread is unblocked, which can be useful for
    94 // debugging, performance instrumentation and other metadata tracking purposes.
    95 bool P( semaphore & sem );
    96 static inline bool P( semaphore & sem, uintptr_t shadow ) { active_thread()->shadow$ = shadow; return P( sem ); }
    97 bool P( semaphore & sem, semaphore & lock );                    // atomic block and release
    98 bool try_P( semaphore & sem );
    99 static inline bool P( semaphore & sem, semaphore & lock, uintptr_t shadow ) { active_thread()->shadow$ = shadow; return P( sem, lock ); }
    100 bool V( semaphore & sem );
    101 size_t V( semaphore & sem, size_t count );
    102 static inline uintptr_t front( semaphore & sem ) with( sem ) { // return shadow information for first waiting thread
    103         #ifdef __CFA_DEBUG__
    104         if ( waiting$ ) {                                                                       // condition queue must not be empty
    105                 abort( "Attempt to access user data on an empty semaphore lock.\n"
    106                            "Possible cause is not checking if the condition lock is empty before reading stored data." );
    107         } // if
    108         #endif // __CFA_DEBUG__
    109         return waiting$.head->shadow$;                                          // return condition information stored with blocked task
    110 }
    111 static inline ssize_t counter( semaphore & sem ) with( sem ) { return count$; } // - => # waiting threads, 0 => block, + => acquire
    112 //static inline int ?!=?( semaphore & sem, zero_t ) with( sem ) { return count$ != 0; } // empty waiting queue
    113 static inline bool empty( semaphore & sem ) with( sem ) { return count$ == 0; } // empty waiting queue
    114 
     87        __spinlock_t lock;
     88        int count;
     89        __queue_t( thread$) waiting;
     90};
     91
     92void ?{}( semaphore & this, int count = 1 );
     93void ^?{}( semaphore & this );
     94bool P( semaphore & this );
     95bool V( semaphore & this );
     96bool V( semaphore & this, unsigned count );
     97thread$ * V( semaphore & this, bool );
    11598
    11699//----------
     
    127110static inline void on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    128111static inline void on_notify( single_acquisition_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
    129 static inline bool register_select$( single_acquisition_lock & this, select_node & node ) { return register_select$( (blocking_lock &)this, node ); }
    130 static inline bool unregister_select$( single_acquisition_lock & this, select_node & node ) { return unregister_select$( (blocking_lock &)this, node ); }
    131 static inline bool on_selected$( single_acquisition_lock & this, select_node & node ) { return on_selected$( (blocking_lock &)this, node ); }
     112static inline bool register_select( single_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
     113static inline bool unregister_select( single_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
     114static inline bool on_selected( single_acquisition_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
    132115__CFA_SELECT_GET_TYPE( single_acquisition_lock );
    133116
     
    145128static inline void on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    146129static inline void on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
    147 static inline bool register_select$( owner_lock & this, select_node & node ) { return register_select$( (blocking_lock &)this, node ); }
    148 static inline bool unregister_select$( owner_lock & this, select_node & node ) { return unregister_select$( (blocking_lock &)this, node ); }
    149 static inline bool on_selected$( owner_lock & this, select_node & node ) { return on_selected$( (blocking_lock &)this, node ); }
     130static inline bool register_select( owner_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
     131static inline bool unregister_select( owner_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
     132static inline bool on_selected( owner_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
    150133__CFA_SELECT_GET_TYPE( owner_lock );
    151134
     
    611594
    612595// waituntil() support
    613 static inline bool register_select$( simple_owner_lock & this, select_node & node ) with( this ) {
     596static inline bool register_select( simple_owner_lock & this, select_node & node ) with( this ) {
    614597        lock( lock __cfaabi_dbg_ctx2 );
    615598
     
    643626}
    644627
    645 static inline bool unregister_select$( simple_owner_lock & this, select_node & node ) with( this ) {
     628static inline bool unregister_select( simple_owner_lock & this, select_node & node ) with( this ) {
    646629        lock( lock __cfaabi_dbg_ctx2 );
    647630        if ( isListed( node ) ) {
     
    661644}
    662645
    663 static inline bool on_selected$( simple_owner_lock & /*this*/, select_node & /*node*/ ) { return true; }
     646static inline bool on_selected( simple_owner_lock & /*this*/, select_node & /*node*/ ) { return true; }
    664647__CFA_SELECT_GET_TYPE( simple_owner_lock );
    665648
Note: See TracChangeset for help on using the changeset viewer.