4 class spinning_barrier {
6 spinning_barrier (unsigned int n) : n_ (n) {
11 // The purpose of wait() is that threads that enter it synchronize with
12 // threads when they get out of it.
13 /** wildcard(2) is acq_rel, ensuring that all threads hb before other
14 * threads in the rmw chain order, then the wildcard (4) and (5) are
15 * release/acquire to make sure the last thread synchronize with all other
16 * earlier threads. Plus, the (4) and (5) synchronization can make sure the
17 * reset of nwait_ in wildcard(3) happens-before any other threads in the
18 * later usage of the barrier.
21 // All orderings are SC originally!!!
24 unsigned int step = step_.load (wildcard(1));
27 if (nwait_.fetch_add (1, wildcard(2)) == n_ - 1) {
28 /* OK, last thread to come. */
30 nwait_.store (0, wildcard(3)); // XXX: maybe can use relaxed ordering here ??
32 step_.fetch_add (1, wildcard(4));
35 /* Run in circles and scream like a little girl. */
37 while (step_.load (wildcard(5)) == step)
44 /* Number of synchronized threads. */
45 const unsigned int n_;
47 /* Number of threads currently spinning. */
48 std::atomic<unsigned int> nwait_;
50 /* Number of barrier syncronizations completed so far,
51 * * it's OK to wrap. */
52 std::atomic<unsigned int> step_;