Ignore:
Timestamp:
Oct 30, 2025, 9:31:39 PM (12 days ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
b14d0d97
Parents:
8920c6d
Message:

new version of barrier lock

File:
1 edited

Legend:

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

    r8920c6d rc4e3b507  
    1111// Created On       : Sun Nov 10 08:07:35 2024
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Thu Apr 24 22:41:11 2025
    14 // Update Count     : 12
     13// Last Modified On : Thu Oct 30 21:20:18 2025
     14// Update Count     : 67
    1515//
    1616
    1717#pragma once
    1818
     19#include <locks.hfa>
    1920#include <monitor.hfa>
    2021
    2122// Plan 9 inheritance does not work with monitors. Two monitor locks are created.
    2223
     24typedef void (* barrier_fptr_t)( ... );                                 // like C++, () => void and ... => C ()
     25
    2326monitor 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
    2631};
    2732
    28 static inline void ?{}( barrier & b, unsigned int group ) {
    29         b.group = b.arrivals = group;                                           // arrivals count backward
     33static inline void ?{}( barrier & b, unsigned int group, barrier_fptr_t callback, void * arg ) with ( b ) {
     34        [group$, arrivals$] = group;
     35        [callback$, arg$] = [callback, arg];
    3036}
    3137
    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 );
     38static inline void ?{}( barrier & b, unsigned int group ) { (b){ group, 0p, 0p }; }     // call base constructor
     39static inline unsigned int waiters( barrier & b ) with( b ) { return group$ - arrivals$; }
     40static 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.
     48static 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
    3955        } 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
    4360        } // if
    4461        return arrived;                                                                         // return arrival order
    4562}
     63
     64static inline unsigned int block( barrier & b ) { return block( b, *0p, 0p, 0p ); }
     65static inline unsigned int block( barrier & b, owner_lock & olock ) { return block( b, olock, 0p, 0p ); }
     66static inline unsigned int block( barrier & b, barrier_fptr_t callback ) { return block( b, *0p, callback, 0p ); }
     67static inline unsigned int block( barrier & b, barrier_fptr_t callback, void * arg ) { return block( b, *0p, callback, arg ); }
     68static 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.