// // Cforall Version 1.0.0 Copyright (C) 2022 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // barrier.hfa -- simple barrier implemented from monitors // // Author : Thierry Delisle // Created On : Thu Mar 31 16:51:35 2022 // Last Modified By : // Last Modified On : // Update Count : // #pragma once #include // Simple barrier based on a monitor monitor barrier { // Number of threads blocking needed to unblock the barrier // Unsigned should be enough, I don't expect use cases with 2^32 thread barriers. unsigned width; // Current count (counting backwards) unsigned count; // Barrier uses internal scheduling condition c; }; // Constructor void ?{}( barrier & this, unsigned width ) { this.width = width; this.count = width; // Count backwards so initialize at width } // block until the number of threads needed have blocked // returns an value indicating the reverse order the threads arrived in // i.e. last thread will return 0 (and not block) // second last thread returns 1 // etc. // last is an optional hook that will be called by the last thread // before unblocking the others static inline unsigned block(barrier & mutex this, fptr_t last = (fptr_t)0 ) { this.count -= 1; // prefix decrement so we the last is 0 and not 1 unsigned arrival = this.count; // Note arrival order if(arrival == 0) { if(last) last(); // If arrived last unblock everyone and reset signal_all(this.c); this.count = this.width; } else { // Otherwise block wait(this.c); } return arrival; // return arrival order }