source: libcfa/src/concurrency/barrier.hfa@ b14d0d97

Last change on this file since b14d0d97 was c4e3b507, checked in by Peter A. Buhr <pabuhr@…>, 12 days ago

new version of barrier lock

  • Property mode set to 100644
File size: 3.2 KB
Line 
1// -*- Mode: C -*-
2//
3// Cforall Version 1.0.0 Copyright (C) 2022 University of Waterloo
4//
5// The contents of this file are covered under the licence agreement in the
6// file "LICENCE" distributed with Cforall.
7//
8// barrier.hfa -- simple barrier implemented using a monitor
9//
10// Author : Peter A. Buhr
11// Created On : Sun Nov 10 08:07:35 2024
12// Last Modified By : Peter A. Buhr
13// Last Modified On : Thu Oct 30 21:20:18 2025
14// Update Count : 67
15//
16
17#pragma once
18
19#include <locks.hfa>
20#include <monitor.hfa>
21
22// Plan 9 inheritance does not work with monitors. Two monitor locks are created.
23
24typedef void (* barrier_fptr_t)( ... ); // like C++, () => void and ... => C ()
25
26monitor barrier {
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
31};
32
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];
36}
37
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
55 } else { // group formed
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
60 } // if
61 return arrived; // return arrival order
62}
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 TracBrowser for help on using the repository browser.