-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatomic.h
67 lines (57 loc) · 1.65 KB
/
atomic.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
* Copyright (C) dirlt
*/
#ifndef __CC_COMMON_ATOMIC_H__
#define __CC_COMMON_ATOMIC_H__
#include <stdint.h>
#ifdef __x86_64__
#include "common/atomic_x86_64.h"
#else
#include "common/atomic_i386.h"
#endif
#include "common/log.h"
template< typename T >
T CompareAndSwap(volatile T& x, T n, T o) {
if(sizeof(x) == 1) {
return __arch_compare_and_exchange_val_8_acq(&x, n, o);
} else if(sizeof(x) == 2) {
return __arch_compare_and_exchange_val_16_acq(&x, n, o);
} else if(sizeof(x) == 4) {
return __arch_compare_and_exchange_val_32_acq(&x, n, o);
} else if(sizeof(x) == 8) {
return __arch_compare_and_exchange_val_64_acq(&x, n, o);
}
FATAL("unknown size=%zu", sizeof(T));
return 0;
}
#ifdef __x86_64__
#define CompareAndSwapPointer(x,n,o) __arch_compare_and_exchange_val_64_acq(&x,n,o)
#else
#define CompareAndSwapPointer(x,n,o) __arch_compare_and_exchange_val_32_acq(&x,n,o)
#endif
template< typename T >
T AtomicGetValue(T& x) {
return CompareAndSwap(x, static_cast<T>(0), static_cast<T>(0));
}
#define AtomicSetValue(x,v) (atomic_exchange_acq(&(x),v))
#define AtomicInc(x) (atomic_exchange_and_add(&(x),1)+1)
#define AtomicDec(x) (atomic_exchange_and_add(&(x),-1)-1)
namespace common {
class RefCount {
public:
RefCount(): ref_count_(1) {}
~RefCount() {}
int32_t acquire() {
return AtomicInc(ref_count_);
}
int32_t release() {
return AtomicDec(ref_count_);
}
int32_t getRefCount() const {
return AtomicGetValue(ref_count_);
}
private:
mutable volatile int32_t ref_count_;
}; // class RefCount
} // namespace common
#endif // __CC_COMMON_ATOMIC_H__