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

ADTast-experimental
Last change on this file since b797d978 was a18373a, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Added a hook for the barrier's last block.
Added testing to go with it.

  • Property mode set to 100644
File size: 1.6 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2022 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// barrier.hfa -- simple barrier implemented from monitors
8//
9// Author           : Thierry Delisle
10// Created On       : Thu Mar 31 16:51:35 2022
11// Last Modified By :
12// Last Modified On :
13// Update Count     :
14//
15
16#pragma once
17
18#include <monitor.hfa>
19
20// Simple barrier based on a monitor
21monitor barrier {
22        // Number of threads blocking needed to unblock the barrier
23        // Unsigned should be enough, I don't expect use cases with 2^32 thread barriers.
24        unsigned width;
25
26        // Current count (counting backwards)
27        unsigned count;
28
29        // Barrier uses internal scheduling
30        condition c;
31};
32
33// Constructor
34void ?{}( barrier & this, unsigned width ) {
35        this.width = width;
36        this.count = width; // Count backwards so initialize at width
37}
38
39// block until the number of threads needed have blocked
40// returns an value indicating the reverse order the threads arrived in
41// i.e. last thread will return 0 (and not block)
42//      second last thread returns 1
43//      etc.
44// last is an optional hook that will be called by the last thread
45// before unblocking the others
46static inline unsigned block(barrier & mutex this, fptr_t last = (fptr_t)0 ) {
47        this.count -= 1; // prefix decrement so we the last is 0 and not 1
48        unsigned arrival = this.count; // Note arrival order
49        if(arrival == 0) {
50                if(last) last();
51                // If arrived last unblock everyone and reset
52                signal_all(this.c);
53                this.count = this.width;
54        } else {
55                // Otherwise block
56                wait(this.c);
57        }
58        return arrival; // return arrival order
59}
Note: See TracBrowser for help on using the repository browser.