source: libcfa/src/concurrency/barrier.hfa @ 7a1b7e6

ADTast-experimentalenumpthread-emulationqualifiedEnum
Last change on this file since 7a1b7e6 was a18373a, checked in by Thierry Delisle <tdelisle@…>, 2 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.