Changeset c4e3b507 for libcfa/src/concurrency
- Timestamp:
- Oct 30, 2025, 9:31:39 PM (12 days ago)
- Branches:
- master
- Children:
- b14d0d97
- Parents:
- 8920c6d
- File:
-
- 1 edited
-
libcfa/src/concurrency/barrier.hfa (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/barrier.hfa
r8920c6d rc4e3b507 11 11 // Created On : Sun Nov 10 08:07:35 2024 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Thu Apr 24 22:41:11202514 // Update Count : 1213 // Last Modified On : Thu Oct 30 21:20:18 2025 14 // Update Count : 67 15 15 // 16 16 17 17 #pragma once 18 18 19 #include <locks.hfa> 19 20 #include <monitor.hfa> 20 21 21 22 // Plan 9 inheritance does not work with monitors. Two monitor locks are created. 22 23 24 typedef void (* barrier_fptr_t)( ... ); // like C++, () => void and ... => C () 25 23 26 monitor barrier { 24 unsigned int group, arrivals; // group size, arrival counter 25 condition c; // wait for group to form 27 unsigned int group$, arrivals$; // group size, arrival counter (backward) 28 condition c$; // wait for group to form 29 barrier_fptr_t callback$; // global callback 30 void * arg$; // global callback argument 26 31 }; 27 32 28 static inline void ?{}( barrier & b, unsigned int group ) { 29 b.group = b.arrivals = group; // arrivals count backward 33 static inline void ?{}( barrier & b, unsigned int group, barrier_fptr_t callback, void * arg ) with ( b ) { 34 [group$, arrivals$] = group; 35 [callback$, arg$] = [callback, arg]; 30 36 } 31 37 32 // Returns a value indicating the reverse order the threads arrived, i.e. last thread returns 0 (and does not block) 33 // hook is an optional hook that is called by the Gth thread before unblocking the other threads. 34 static inline unsigned int block( barrier & mutex b, fptr_t hook = (fptr_t)0 ) with( b ) { 35 arrivals -= 1; // prefix decrement so last is 0 not 1 36 unsigned arrived = b.arrivals; // note arrival order 37 if ( arrivals != 0 ) { // wait for group to form 38 wait( b.c ); 38 static inline void ?{}( barrier & b, unsigned int group ) { (b){ group, 0p, 0p }; } // call base constructor 39 static inline unsigned int waiters( barrier & b ) with( b ) { return group$ - arrivals$; } 40 static inline unsigned int total( barrier & b ) with( b ) { return group$; } 41 42 // Returns a value indicating the reverse order the threads arrived, i.e., the Gth thread returns 0 (and does not 43 // block). olock is an optional mutex lock held by the called and atomically released and block. callback is an 44 // optional function that is called by the Gth thread before unblocking the other threads. arg is an optional (void *) 45 // argument passed to the callback. 46 47 // Barrier is a monitor => implicit mutual exclusion. 48 static inline unsigned int block( barrier & mutex b, owner_lock & olock, barrier_fptr_t callback, void * arg ) with( b ) { 49 arrivals$ -= 1; // prefix decrement so last is 0 not 1 50 typeof( arrivals$ ) arrived = arrivals$; // note arrival order 51 if ( arrivals$ != 0 ) { // wait for group to form 52 if ( &olock != 0p ) unlock( olock ); // if lock specified, release it 53 wait( c$ ); 54 // DO NOT REACQUIRE LOCK TO ALLOW BARGING PREVENTION 39 55 } else { // group formed 40 if ( hook ) hook(); // safe to call 41 signal_all( c ); // unblock group 42 arrivals = group; // reset 56 if ( callback ) callback( arg ); // if callback specified, safe to call with argument 57 else if ( callback$ ) callback$( arg$ ); // if callback specified, safe to call with argument 58 signal_all( c$ ); // unblock group 59 arrivals$ = group$; // reset 43 60 } // if 44 61 return arrived; // return arrival order 45 62 } 63 64 static inline unsigned int block( barrier & b ) { return block( b, *0p, 0p, 0p ); } 65 static inline unsigned int block( barrier & b, owner_lock & olock ) { return block( b, olock, 0p, 0p ); } 66 static inline unsigned int block( barrier & b, barrier_fptr_t callback ) { return block( b, *0p, callback, 0p ); } 67 static inline unsigned int block( barrier & b, barrier_fptr_t callback, void * arg ) { return block( b, *0p, callback, arg ); } 68 static inline unsigned int block( barrier & b, owner_lock & olock, barrier_fptr_t callback ) { return block( b, olock, callback, 0p ); }
Note:
See TracChangeset
for help on using the changeset viewer.