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

ADT ast-experimental
Last change on this file since ccf1d99 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
RevLine 
[93b8cf4]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
[31ef267]20// Simple barrier based on a monitor
[93b8cf4]21monitor barrier {
[31ef267]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;
[93b8cf4]25
[31ef267]26 // Current count (counting backwards)
27 unsigned count;
28
29 // Barrier uses internal scheduling
[93b8cf4]30 condition c;
31};
32
[31ef267]33// Constructor
34void ?{}( barrier & this, unsigned width ) {
35 this.width = width;
36 this.count = width; // Count backwards so initialize at width
[93b8cf4]37}
38
[31ef267]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.
[a18373a]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 ) {
[31ef267]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) {
[a18373a]50 if(last) last();
[31ef267]51 // If arrived last unblock everyone and reset
[93b8cf4]52 signal_all(this.c);
[31ef267]53 this.count = this.width;
54 } else {
55 // Otherwise block
56 wait(this.c);
[93b8cf4]57 }
[31ef267]58 return arrival; // return arrival order
[93b8cf4]59}
Note: See TracBrowser for help on using the repository browser.