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