-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathatomic_64.h
142 lines (125 loc) · 3.07 KB
/
atomic_64.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef MY_ATOMIC_64_H
#define MY_ATOMIC_64_H
#include <stdint.h>
/* public domain, from http://golubenco.org/2007/06/14/atomic-operations/ */
/**
* Atomic 64-bit type.
*/
typedef struct {
volatile int64_t counter;
} atomic64_t;
#define ATOMIC64_INIT(i) { (i) }
/**
* Read atomic variable
* @param v pointer of type atomic64_t
*
* Atomically reads the value of @v.
*/
#define atomic64_read(v) ((v)->counter)
/**
* Set atomic variable
* @param v pointer of type atomic64_t
* @param i required value
*/
#define atomic64_set(v, i) (((v)->counter) = (i))
/**
* Add to the atomic variable
* @param i integer value to add
* @param v pointer of type atomic64_t
*/
static inline void
atomic64_add(int i, atomic64_t *v) {
(void)__sync_add_and_fetch(&v->counter, i);
}
/**
* Subtract the atomic variable
* @param i integer value to subtract
* @param v pointer of type atomic64_t
*
* Atomically subtracts @i from @v.
*/
static inline void
atomic64_sub(int i, atomic64_t *v) {
(void)__sync_sub_and_fetch(&v->counter, i);
}
/**
* Read atomic variable and reset to zero.
*
* @param v pointer of type atomic64_t
*/
static inline int
atomic64_zero(atomic64_t *v) {
return (__sync_fetch_and_and(&v->counter, 0));
}
/**
* Subtract value from variable and test result
* @param i integer value to subtract
* @param v pointer of type atomic64_t
*
* Atomically subtracts @i from @v and returns
* true if the result is zero, or false for all
* other cases.
*/
static inline int
atomic64_sub_and_test(int i, atomic64_t *v) {
return !(__sync_sub_and_fetch(&v->counter, i));
}
/**
* Increment atomic variable
* @param v pointer of type atomic64_t
*
* Atomically increments @v by 1.
*/
static inline void
atomic64_inc(atomic64_t *v) {
(void)__sync_fetch_and_add(&v->counter, 1);
}
/**
* @brief decrement atomic variable
* @param v: pointer of type atomic64_t
*
* Atomically decrements @v by 1. Note that the guaranteed
* useful range of an atomic64_t is only 24 bits.
*/
static inline void
atomic64_dec(atomic64_t *v) {
(void)__sync_fetch_and_sub(&v->counter, 1);
}
/**
* @brief Decrement and test
* @param v pointer of type atomic64_t
*
* Atomically decrements @v by 1 and
* returns true if the result is 0, or false for all other
* cases.
*/
static inline int
atomic64_dec_and_test(atomic64_t *v) {
return !(__sync_sub_and_fetch(&v->counter, 1));
}
/**
* @brief Increment and test
* @param v pointer of type atomic64_t
*
* Atomically increments @v by 1
* and returns true if the result is zero, or false for all
* other cases.
*/
static inline int
atomic64_inc_and_test(atomic64_t *v) {
return !(__sync_add_and_fetch(&v->counter, 1));
}
/**
* @brief add and test if negative
* @param v pointer of type atomic64_t
* @param i integer value to add
*
* Atomically adds @i to @v and returns true
* if the result is negative, or false when
* result is greater than or equal to zero.
*/
static inline int
atomic64_add_negative(int i, atomic64_t *v) {
return (__sync_add_and_fetch(&v->counter, i) < 0);
}
#endif /* MY_ATOMIC_H */