- File:
-
- 1 edited
-
libcfa/src/concurrency/locks.hfa (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/locks.hfa
rfbaea970 r8dc8f68 11 11 // Created On : Thu Jan 21 19:46:50 2021 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Sun Nov 23 22:38:45202514 // Update Count : 6713 // Last Modified On : Thu Aug 21 22:36:44 2025 14 // Update Count : 23 15 15 // 16 16 … … 81 81 82 82 83 //----------------------------------------------------------------------------- 84 // Semaphore, counting85 83 84 //----------------------------------------------------------------------------- 85 // Semaphore 86 86 struct 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 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 ); 115 98 116 99 //---------- … … 127 110 static inline void on_wakeup( single_acquisition_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 128 111 static 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 ); }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 ); } 132 115 __CFA_SELECT_GET_TYPE( single_acquisition_lock ); 133 116 … … 145 128 static inline void on_wakeup( owner_lock & this, size_t v ) { on_wakeup ( (blocking_lock &)this, v ); } 146 129 static 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 ); }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 ); } 150 133 __CFA_SELECT_GET_TYPE( owner_lock ); 151 134 … … 611 594 612 595 // waituntil() support 613 static inline bool register_select $( simple_owner_lock & this, select_node & node ) with( this ) {596 static inline bool register_select( simple_owner_lock & this, select_node & node ) with( this ) { 614 597 lock( lock __cfaabi_dbg_ctx2 ); 615 598 … … 643 626 } 644 627 645 static inline bool unregister_select $( simple_owner_lock & this, select_node & node ) with( this ) {628 static inline bool unregister_select( simple_owner_lock & this, select_node & node ) with( this ) { 646 629 lock( lock __cfaabi_dbg_ctx2 ); 647 630 if ( isListed( node ) ) { … … 661 644 } 662 645 663 static inline bool on_selected $( simple_owner_lock & /*this*/, select_node & /*node*/ ) { return true; }646 static inline bool on_selected( simple_owner_lock & /*this*/, select_node & /*node*/ ) { return true; } 664 647 __CFA_SELECT_GET_TYPE( simple_owner_lock ); 665 648
Note:
See TracChangeset
for help on using the changeset viewer.