blob: fa4be8a1417068a59c0e020beaee87578a27e869 (
plain) (
blame)
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#pragma once
#include <library/cpp/deprecated/atomic/atomic.h>
#include <util/system/condvar.h>
#include <util/system/mutex.h>
#include <util/system/platform.h>
class TFutexLike {
private:
#ifdef _linux_
int Value;
#else
TAtomic Value;
TMutex Mutex;
TCondVar CondVar;
#endif
public:
TFutexLike()
: Value(0)
{
}
int AddAndGet(int add) {
#ifdef _linux_
//return __atomic_add_fetch(&Value, add, __ATOMIC_SEQ_CST);
return __sync_add_and_fetch(&Value, add);
#else
return AtomicAdd(Value, add);
#endif
}
int GetAndAdd(int add) {
return AddAndGet(add) - add;
}
// until we have modern GCC
#if 0
int GetAndSet(int newValue) {
#ifdef _linux_
return __atomic_exchange_n(&Value, newValue, __ATOMIC_SEQ_CST);
#else
return AtomicSwap(&Value, newValue);
#endif
}
#endif
int Get() {
#ifdef _linux_
//return __atomic_load_n(&Value, __ATOMIC_SEQ_CST);
__sync_synchronize();
return Value;
#else
return AtomicGet(Value);
#endif
}
void Set(int newValue) {
#ifdef _linux_
//__atomic_store_n(&Value, newValue, __ATOMIC_SEQ_CST);
Value = newValue;
__sync_synchronize();
#else
AtomicSet(Value, newValue);
#endif
}
int GetAndIncrement() {
return AddAndGet(1) - 1;
}
int IncrementAndGet() {
return AddAndGet(1);
}
int GetAndDecrement() {
return AddAndGet(-1) + 1;
}
int DecrementAndGet() {
return AddAndGet(-1);
}
void Wake(size_t count = Max<size_t>());
void Wait(int expected);
};
|