raw elimination-backoff code from paper
[model-checker-benchmarks.git] / barrier / barrier.h
1 #include <atomic>
2
3 class spinning_barrier {
4  public:
5         spinning_barrier (unsigned int n) : n_ (n) {
6                 nwait_ = 0;
7                 step_ = 0;
8         }
9
10         bool wait() {
11                 unsigned int step = step_.load ();
12
13                 if (nwait_.fetch_add (1) == n_ - 1) {
14                         /* OK, last thread to come.  */
15                         nwait_.store (0); // XXX: maybe can use relaxed ordering here ??
16                         step_.fetch_add (1);
17                         return true;
18                 } else {
19                         /* Run in circles and scream like a little girl.  */
20                         while (step_.load () == step)
21                                 thrd_yield();
22                         return false;
23                 }
24         }
25
26  protected:
27         /* Number of synchronized threads. */
28         const unsigned int n_;
29
30         /* Number of threads currently spinning.  */
31         std::atomic<unsigned int> nwait_;
32
33         /* Number of barrier syncronizations completed so far, 
34          *      * it's OK to wrap.  */
35         std::atomic<unsigned int> step_;
36 };