edit
[c11concurrency-benchmarks.git] / silo / spinbarrier.h
1 #ifndef _SPINBARRIER_H_
2 #define _SPINBARRIER_H_
3
4 #include "amd64.h"
5 #include "macros.h"
6 #include "util.h"
7
8 /**
9  * Barrier implemented by spinning
10  */
11
12 class spin_barrier {
13 public:
14   spin_barrier(size_t n)
15     : n(n)
16   {
17     ALWAYS_ASSERT(n > 0);
18   }
19
20   spin_barrier(const spin_barrier &) = delete;
21   spin_barrier(spin_barrier &&) = delete;
22   spin_barrier &operator=(const spin_barrier &) = delete;
23
24   ~spin_barrier()
25   {
26     ALWAYS_ASSERT(n == 0);
27   }
28
29   void
30   count_down()
31   {
32     // written like this (instead of using __sync_fetch_and_add())
33     // so we can have assertions
34     for (;;) {
35       size_t copy = n;
36       ALWAYS_ASSERT(copy > 0);
37       if (__sync_bool_compare_and_swap(&n, copy, copy - 1))
38         return;
39     }
40   }
41
42   void
43   wait_for()
44   {
45     while (n > 0)
46       nop_pause();
47   }
48
49 private:
50   volatile size_t n;
51 };
52
53 #endif /* _SPINBARRIER_H_ */