11 SpinBarrier(unsigned int n) : n_(n) {
16 // The purpose of wait() is that threads that enter it synchronize with
17 // threads when they get out of it.
18 /** wildcard(2) is acq_rel, ensuring that all threads hb before other
19 * threads in the rmw chain order, then the wildcard (4) and (5) are
20 * release/acquire to make sure the last thread synchronize with all other
21 * earlier threads. Plus, the (4) and (5) synchronization can make sure the
22 * reset of nwait_ in wildcard(3) happens-before any other threads in the
23 * later usage of the barrier.
27 unsigned int step = step_.load(std::memory_order_relaxed);
29 if (nwait_.fetch_add(1, std::memory_order_acq_rel) == n_ - 1) {
30 /* OK, last thread to come. */
31 nwait_.store(0, std::memory_order_relaxed);
32 step_.fetch_add(1, std::memory_order_release);
36 /* Run in circles and scream like a little girl. */
37 while (step_.load(std::memory_order_acquire) == step) {
45 /* Number of synchronized threads. */
46 const unsigned int n_;
48 /* Number of threads currently spinning. */
49 std::atomic<unsigned int> nwait_;
51 /* Number of barrier syncronizations completed so far,
52 * * it's OK to wrap. */
53 std::atomic<unsigned int> step_;
56 } // namespace cds_others