Ignore:
Timestamp:
Dec 8, 2025, 11:29:33 AM (2 months ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
master
Children:
79ba50c
Parents:
8f448e0 (diff), 79ec8c3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge remote-tracking branch 'refs/remotes/origin/master'

File:
1 edited

Legend:

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

    r8f448e0 r5e0b6657  
    1111// Created On       : Thu Jan 21 19:46:50 2021
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Thu Aug 21 22:36:44 2025
    14 // Update Count     : 23
     13// Last Modified On : Sun Nov 23 22:38:45 2025
     14// Update Count     : 67
    1515//
    1616
     
    8181
    8282
    83 
    84 //-----------------------------------------------------------------------------
    85 // Semaphore
     83//-----------------------------------------------------------------------------
     84// Semaphore, counting
     85
    8686struct semaphore {
    87         __spinlock_t lock;
    88         int count;
    89         __queue_t( thread$) waiting;
    90 };
    91 
    92 void ?{}( semaphore & this, int count = 1 );
    93 void ^?{}( semaphore & this );
    94 bool P( semaphore & this );
    95 bool V( semaphore & this );
    96 bool V( semaphore & this, unsigned count );
    97 thread$ * V( semaphore & this, bool );
     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
     92void ?{}( 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.
     95bool P( semaphore & sem );
     96static inline bool P( semaphore & sem, uintptr_t shadow ) { active_thread()->shadow$ = shadow; return P( sem ); }
     97bool P( semaphore & sem, semaphore & lock );                    // atomic block and release
     98bool try_P( semaphore & sem );
     99static inline bool P( semaphore & sem, semaphore & lock, uintptr_t shadow ) { active_thread()->shadow$ = shadow; return P( sem, lock ); }
     100bool V( semaphore & sem );
     101size_t V( semaphore & sem, size_t count );
     102static 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}
     111static 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
     113static inline bool empty( semaphore & sem ) with( sem ) { return count$ == 0; } // empty waiting queue
     114
    98115
    99116//----------
     
    110127static inline void on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    111128static inline void on_notify( single_acquisition_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
    112 static inline bool register_select( single_acquisition_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
    113 static inline bool unregister_select( single_acquisition_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
    114 static inline bool on_selected( single_acquisition_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
     129static inline bool register_select$( single_acquisition_lock & this, select_node & node ) { return register_select$( (blocking_lock &)this, node ); }
     130static inline bool unregister_select$( single_acquisition_lock & this, select_node & node ) { return unregister_select$( (blocking_lock &)this, node ); }
     131static inline bool on_selected$( single_acquisition_lock & this, select_node & node ) { return on_selected$( (blocking_lock &)this, node ); }
    115132__CFA_SELECT_GET_TYPE( single_acquisition_lock );
    116133
     
    128145static inline void on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); }
    129146static inline void on_notify( owner_lock & this, struct thread$ * t ) { on_notify( (blocking_lock &)this, t ); }
    130 static inline bool register_select( owner_lock & this, select_node & node ) { return register_select( (blocking_lock &)this, node ); }
    131 static inline bool unregister_select( owner_lock & this, select_node & node ) { return unregister_select( (blocking_lock &)this, node ); }
    132 static inline bool on_selected( owner_lock & this, select_node & node ) { return on_selected( (blocking_lock &)this, node ); }
     147static inline bool register_select$( owner_lock & this, select_node & node ) { return register_select$( (blocking_lock &)this, node ); }
     148static inline bool unregister_select$( owner_lock & this, select_node & node ) { return unregister_select$( (blocking_lock &)this, node ); }
     149static inline bool on_selected$( owner_lock & this, select_node & node ) { return on_selected$( (blocking_lock &)this, node ); }
    133150__CFA_SELECT_GET_TYPE( owner_lock );
    134151
     
    594611
    595612// waituntil() support
    596 static inline bool register_select( simple_owner_lock & this, select_node & node ) with( this ) {
     613static inline bool register_select$( simple_owner_lock & this, select_node & node ) with( this ) {
    597614        lock( lock __cfaabi_dbg_ctx2 );
    598615
     
    626643}
    627644
    628 static inline bool unregister_select( simple_owner_lock & this, select_node & node ) with( this ) {
     645static inline bool unregister_select$( simple_owner_lock & this, select_node & node ) with( this ) {
    629646        lock( lock __cfaabi_dbg_ctx2 );
    630647        if ( isListed( node ) ) {
     
    644661}
    645662
    646 static inline bool on_selected( simple_owner_lock & /*this*/, select_node & /*node*/ ) { return true; }
     663static inline bool on_selected$( simple_owner_lock & /*this*/, select_node & /*node*/ ) { return true; }
    647664__CFA_SELECT_GET_TYPE( simple_owner_lock );
    648665
Note: See TracChangeset for help on using the changeset viewer.