xrootd
Loading...
Searching...
No Matches
XrdSysRAtomic.hh
Go to the documentation of this file.
1#ifndef __XRDSYSRATOMIC__HH
2#define __XRDSYSRATOMIC__HH
3/******************************************************************************/
4/* */
5/* X r d S y s R A t o m i c . h h */
6/* */
7/******************************************************************************/
8
9/* The XrdSys::RAtomic class can be used to define an integral, pointer, or
10 boolean type atomic variable that use relaxed memory order by default. In
11 general all atomics should use relaxed memory order and when more than one
12 such variable needs to be synchronized these should be done using a lock.
13 The server/client architecture do not require nor should require multiple
14 variable ordering consistency in the presence of atomics. This is done to
15 make it clear which variable are co-dependent in terms of atomic access.
16*/
17
18#include <atomic>
19#include <cstddef>
20#include <cstdint>
21
22namespace XrdSys
23{
24template<typename T>
26{
27public:
28
29// Store and fetch defined here for immediate expansion
30//
31T operator=(T v) noexcept
32 {_m.store(v, std::memory_order_relaxed); return v;}
33
34T operator=(T v) volatile noexcept
35 {_m.store(v, std::memory_order_relaxed); return v;}
36
37 operator T() noexcept
38 {return _m.load(std::memory_order_relaxed);}
39
40 operator T() volatile noexcept
41 {return _m.load(std::memory_order_relaxed);}
42
43// Post-increment/decrement (i.e. x++)
44//
45T operator++(int) noexcept
46 {return _m.fetch_add(1, std::memory_order_relaxed);}
47
48T operator++(int) volatile noexcept
49 {return _m.fetch_add(1, std::memory_order_relaxed);}
50
51T operator--(int) noexcept
52 {return _m.fetch_sub(1, std::memory_order_relaxed);}
53
54T operator--(int) volatile noexcept
55 {return _m.fetch_sub(1, std::memory_order_relaxed);}
56
57// Pre-increment/decrement (i.e.++x)
58//
59T operator++() noexcept
60 {return _m.fetch_add(1, std::memory_order_relaxed)+1;}
61
62T operator++() volatile noexcept
63 {return _m.fetch_add(1, std::memory_order_relaxed)+1;}
64
65T operator--() noexcept
66 {return _m.fetch_sub(1, std::memory_order_relaxed)-1;}
67
68T operator--() volatile noexcept
69 {return _m.fetch_sub(1, std::memory_order_relaxed)-1;}
70
71T operator+=(T v) noexcept
72 {return _m.fetch_add(v, std::memory_order_relaxed)+v;}
73
74T operator+=(T v) volatile noexcept
75 {return _m.fetch_add(v, std::memory_order_relaxed)+v;}
76
77T operator-=(T v) noexcept
78 {return _m.fetch_sub(v, std::memory_order_relaxed)-v;}
79
80T operator-=(T v) volatile noexcept
81 {return _m.fetch_sub(v, std::memory_order_relaxed)-v;}
82
83T operator&=(T v) noexcept
84 {return _m.fetch_and(v, std::memory_order_relaxed) & v;}
85
86T operator&=(T v) volatile noexcept
87 {return _m.fetch_and(v, std::memory_order_relaxed) & v;}
88
89T operator|=(T v) noexcept
90 {return _m.fetch_or (v, std::memory_order_relaxed) | v;}
91
92T operator|=(T v) volatile noexcept
93 {return _m.fetch_or (v, std::memory_order_relaxed) | v;}
94
95T operator^=(T v) noexcept
96 {return _m.fetch_xor(v, std::memory_order_relaxed) ^ v;}
97
98T operator^=(T v) volatile noexcept
99 {return _m.fetch_xor(v, std::memory_order_relaxed) ^ v;}
100
101// Specialty functions that fetch and do a post operation
102//
103T fetch_and(T v) noexcept
104 {return _m.fetch_and(v, std::memory_order_relaxed);}
105
106T fetch_or(T v) noexcept
107 {return _m.fetch_or (v, std::memory_order_relaxed);}
108
109T fetch_xor(T v) noexcept
110 {return _m.fetch_xor(v, std::memory_order_relaxed);}
111
112// Member functions
113//
115 std::memory_order mo1=std::memory_order_relaxed,
116 std::memory_order mo2=std::memory_order_relaxed)
117 noexcept
118 {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
119
121 std::memory_order mo1=std::memory_order_relaxed,
122 std::memory_order mo2=std::memory_order_relaxed)
123 volatile noexcept
124 {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
125
127 std::memory_order mo1=std::memory_order_relaxed,
128 std::memory_order mo2=std::memory_order_relaxed)
129 noexcept
130 {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
131
133 std::memory_order mo1=std::memory_order_relaxed,
134 std::memory_order mo2=std::memory_order_relaxed)
135 volatile noexcept
136 {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
137
138T exchange(T v, std::memory_order mo=std::memory_order_relaxed) noexcept
139 {return _m.exchange(v, mo);}
140
141T exchange(T v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
142 {return _m.exchange(v, mo);}
143
145
146 RAtomic(T v) : _m(v) {}
147
148private:
149
150std::atomic<T> _m;
151};
152
153template<typename T>
154class RAtomic<T*>
155{
156public:
157
158// Store and fetch defined here for immediate expansion
159//
160T* operator=(T* v) noexcept
161 {_m.store(v, std::memory_order_relaxed); return v;}
162
163T* operator=(T* v) volatile noexcept
164 {_m.store(v, std::memory_order_relaxed); return v;}
165
166 operator T*() noexcept
167 {return _m.load(std::memory_order_relaxed);}
168
169 operator T*() volatile noexcept
170 {return _m.load(std::memory_order_relaxed);}
171
172 T* operator->() noexcept
173 {return _m.load(std::memory_order_relaxed);}
174
175// Post-increment/decrement (i.e. x++)
176//
177T* operator++(int) noexcept
178 {return _m.fetch_add(1, std::memory_order_relaxed);}
179
180T* operator++(int) volatile noexcept
181 {return _m.fetch_add(1, std::memory_order_relaxed);}
182
183T* operator--(int) noexcept
184 {return _m.fetch_sub(1, std::memory_order_relaxed);}
185
186T* operator--(int) volatile noexcept
187 {return _m.fetch_sub(1, std::memory_order_relaxed);}
188
189// Pre-increment/decrement (i.e.++x)
190//
191T* operator++() noexcept
192 {return _m.fetch_add(1, std::memory_order_relaxed)+1;}
193
194T* operator++() volatile noexcept
195 {return _m.fetch_add(1, std::memory_order_relaxed)+1;}
196
197T* operator--() noexcept
198 {return _m.fetch_sub(1, std::memory_order_relaxed)-1;}
199
200T* operator--() volatile noexcept
201 {return _m.fetch_sub(1, std::memory_order_relaxed)-1;}
202
203T* operator+=(ptrdiff_t v) noexcept
204 {return _m.fetch_add(v, std::memory_order_relaxed)+v;}
205
206T* operator+=(ptrdiff_t v) volatile noexcept
207 {return _m.fetch_add(v, std::memory_order_relaxed)+v;}
208
209T* operator-=(ptrdiff_t v) noexcept
210 {return _m.fetch_sub(v, std::memory_order_relaxed)-v;}
211
212T* operator-=(ptrdiff_t v) volatile noexcept
213 {return _m.fetch_sub(v, std::memory_order_relaxed)-v;}
214
215// Member functions
216//
218 std::memory_order mo1=std::memory_order_relaxed,
219 std::memory_order mo2=std::memory_order_relaxed)
220 noexcept
221 {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
222
224 std::memory_order mo1=std::memory_order_relaxed,
225 std::memory_order mo2=std::memory_order_relaxed)
226 volatile noexcept
227 {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
228
229T* compare_exchange_weak(T& v1, T* v2,
230 std::memory_order mo1=std::memory_order_relaxed,
231 std::memory_order mo2=std::memory_order_relaxed)
232 noexcept
233 {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
234
235T* compare_exchange_weak(T& v1, T* v2,
236 std::memory_order mo1=std::memory_order_relaxed,
237 std::memory_order mo2=std::memory_order_relaxed)
238 volatile noexcept
239 {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
240
241T* exchange(T* v, std::memory_order mo=std::memory_order_relaxed) noexcept
242 {return _m.exchange(v, mo);}
243
244T* exchange(T* v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
245 {return _m.exchange(v, mo);}
246
248
249 RAtomic(T* v) : _m(v) {}
250
251private:
252
253std::atomic<T*> _m;
254};
255
256template<>
257class RAtomic<bool>
258{
259public:
260
261// Store and fetch defined here for immediate expansion
262//
263bool operator=(bool v) noexcept
264 {_m.store(v, std::memory_order_relaxed); return v;}
265
266bool operator=(bool v) volatile noexcept
267 {_m.store(v, std::memory_order_relaxed); return v;}
268
269 operator bool() noexcept
270 {return _m.load(std::memory_order_relaxed);}
271
272 operator bool() volatile noexcept
273 {return _m.load(std::memory_order_relaxed);}
274
275// Member functions
276//
277bool compare_exchange_strong(bool& v1, bool v2,
278 std::memory_order mo1=std::memory_order_relaxed,
279 std::memory_order mo2=std::memory_order_relaxed)
280 noexcept
281 {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
282
283bool compare_exchange_strong(bool& v1, bool v2,
284 std::memory_order mo1=std::memory_order_relaxed,
285 std::memory_order mo2=std::memory_order_relaxed)
286 volatile noexcept
287 {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
288
289bool compare_exchange_weak(bool& v1, bool v2,
290 std::memory_order mo1=std::memory_order_relaxed,
291 std::memory_order mo2=std::memory_order_relaxed)
292 noexcept
293 {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
294
295bool compare_exchange_weak(bool& v1, bool v2,
296 std::memory_order mo1=std::memory_order_relaxed,
297 std::memory_order mo2=std::memory_order_relaxed)
298 volatile noexcept
299 {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
300
301bool exchange(bool v, std::memory_order mo=std::memory_order_relaxed) noexcept
302 {return _m.exchange(v, mo);}
303
304bool exchange(bool v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
305 {return _m.exchange(v, mo);}
306
308
309 RAtomic(bool v) : _m(v) {}
310
311private:
312
313std::atomic<bool> _m;
314};
315}
316
317// Common types
318//
340#endif
XrdSys::RAtomic< unsigned char > RAtomic_uchar
Definition XrdSysRAtomic.hh:322
XrdSys::RAtomic< uint64_t > RAtomic_uint64_t
Definition XrdSysRAtomic.hh:339
XrdSys::RAtomic< short > RAtomic_short
Definition XrdSysRAtomic.hh:323
XrdSys::RAtomic< bool > RAtomic_bool
Definition XrdSysRAtomic.hh:319
XrdSys::RAtomic< char > RAtomic_char
Definition XrdSysRAtomic.hh:320
XrdSys::RAtomic< wchar_t > RAtomic_wchar_t
Definition XrdSysRAtomic.hh:331
XrdSys::RAtomic< long long > RAtomic_llong
Definition XrdSysRAtomic.hh:329
XrdSys::RAtomic< uint32_t > RAtomic_uint32_t
Definition XrdSysRAtomic.hh:337
XrdSys::RAtomic< int16_t > RAtomic_int16_t
Definition XrdSysRAtomic.hh:334
XrdSys::RAtomic< uint8_t > RAtomic_uint8_t
Definition XrdSysRAtomic.hh:333
XrdSys::RAtomic< int32_t > RAtomic_int32_t
Definition XrdSysRAtomic.hh:336
XrdSys::RAtomic< uint16_t > RAtomic_uint16_t
Definition XrdSysRAtomic.hh:335
XrdSys::RAtomic< long > RAtomic_long
Definition XrdSysRAtomic.hh:327
XrdSys::RAtomic< unsigned long long > RAtomic_ullong
Definition XrdSysRAtomic.hh:330
XrdSys::RAtomic< unsigned short > RAtomic_ushort
Definition XrdSysRAtomic.hh:324
XrdSys::RAtomic< int64_t > RAtomic_int64_t
Definition XrdSysRAtomic.hh:338
XrdSys::RAtomic< unsigned int > RAtomic_uint
Definition XrdSysRAtomic.hh:326
XrdSys::RAtomic< unsigned long > RAtomic_ulong
Definition XrdSysRAtomic.hh:328
XrdSys::RAtomic< signed char > RAtomic_schar
Definition XrdSysRAtomic.hh:321
XrdSys::RAtomic< int > RAtomic_int
Definition XrdSysRAtomic.hh:325
XrdSys::RAtomic< int8_t > RAtomic_int8_t
Definition XrdSysRAtomic.hh:332
T * exchange(T *v, std::memory_order mo=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:241
RAtomic()
Definition XrdSysRAtomic.hh:247
T * operator++(int) volatile noexcept
Definition XrdSysRAtomic.hh:180
T * compare_exchange_strong(T &v1, T *v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:223
T * compare_exchange_strong(T &v1, T *v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:217
T * operator--() volatile noexcept
Definition XrdSysRAtomic.hh:200
RAtomic(T *v)
Definition XrdSysRAtomic.hh:249
T * compare_exchange_weak(T &v1, T *v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:229
std::atomic< T * > _m
Definition XrdSysRAtomic.hh:253
T * operator--() noexcept
Definition XrdSysRAtomic.hh:197
T * operator+=(ptrdiff_t v) noexcept
Definition XrdSysRAtomic.hh:203
T * operator-=(ptrdiff_t v) volatile noexcept
Definition XrdSysRAtomic.hh:212
T * operator--(int) noexcept
Definition XrdSysRAtomic.hh:183
T * operator-=(ptrdiff_t v) noexcept
Definition XrdSysRAtomic.hh:209
T * operator++() noexcept
Definition XrdSysRAtomic.hh:191
T * operator=(T *v) noexcept
Definition XrdSysRAtomic.hh:160
T * operator->() noexcept
Definition XrdSysRAtomic.hh:172
T * operator+=(ptrdiff_t v) volatile noexcept
Definition XrdSysRAtomic.hh:206
T * operator=(T *v) volatile noexcept
Definition XrdSysRAtomic.hh:163
T * operator++() volatile noexcept
Definition XrdSysRAtomic.hh:194
T * operator++(int) noexcept
Definition XrdSysRAtomic.hh:177
T * exchange(T *v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:244
T * operator--(int) volatile noexcept
Definition XrdSysRAtomic.hh:186
T * compare_exchange_weak(T &v1, T *v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:235
bool operator=(bool v) noexcept
Definition XrdSysRAtomic.hh:263
bool operator=(bool v) volatile noexcept
Definition XrdSysRAtomic.hh:266
bool exchange(bool v, std::memory_order mo=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:301
bool compare_exchange_weak(bool &v1, bool v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:295
bool compare_exchange_strong(bool &v1, bool v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:283
bool compare_exchange_weak(bool &v1, bool v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:289
RAtomic(bool v)
Definition XrdSysRAtomic.hh:309
bool exchange(bool v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:304
std::atomic< bool > _m
Definition XrdSysRAtomic.hh:313
bool compare_exchange_strong(bool &v1, bool v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:277
RAtomic()
Definition XrdSysRAtomic.hh:307
Definition XrdSysRAtomic.hh:26
T operator++(int) noexcept
Definition XrdSysRAtomic.hh:45
T operator^=(T v) noexcept
Definition XrdSysRAtomic.hh:95
T operator+=(T v) noexcept
Definition XrdSysRAtomic.hh:71
T operator&=(T v) volatile noexcept
Definition XrdSysRAtomic.hh:86
T fetch_or(T v) noexcept
Definition XrdSysRAtomic.hh:106
T operator=(T v) noexcept
Definition XrdSysRAtomic.hh:31
T operator--(int) noexcept
Definition XrdSysRAtomic.hh:51
T exchange(T v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:141
RAtomic(T v)
Definition XrdSysRAtomic.hh:146
T operator|=(T v) volatile noexcept
Definition XrdSysRAtomic.hh:92
T compare_exchange_weak(T &v1, T v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:132
T fetch_xor(T v) noexcept
Definition XrdSysRAtomic.hh:109
T operator=(T v) volatile noexcept
Definition XrdSysRAtomic.hh:34
T fetch_and(T v) noexcept
Definition XrdSysRAtomic.hh:103
T compare_exchange_weak(T &v1, T v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:126
T operator--(int) volatile noexcept
Definition XrdSysRAtomic.hh:54
T operator&=(T v) noexcept
Definition XrdSysRAtomic.hh:83
T operator++() volatile noexcept
Definition XrdSysRAtomic.hh:62
T operator--() volatile noexcept
Definition XrdSysRAtomic.hh:68
T exchange(T v, std::memory_order mo=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:138
std::atomic< T > _m
Definition XrdSysRAtomic.hh:150
T compare_exchange_strong(T &v1, T v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) noexcept
Definition XrdSysRAtomic.hh:114
T compare_exchange_strong(T &v1, T v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatile noexcept
Definition XrdSysRAtomic.hh:120
T operator--() noexcept
Definition XrdSysRAtomic.hh:65
T operator^=(T v) volatile noexcept
Definition XrdSysRAtomic.hh:98
T operator|=(T v) noexcept
Definition XrdSysRAtomic.hh:89
T operator-=(T v) noexcept
Definition XrdSysRAtomic.hh:77
T operator++() noexcept
Definition XrdSysRAtomic.hh:59
T operator-=(T v) volatile noexcept
Definition XrdSysRAtomic.hh:80
T operator+=(T v) volatile noexcept
Definition XrdSysRAtomic.hh:74
RAtomic()
Definition XrdSysRAtomic.hh:144
T operator++(int) volatile noexcept
Definition XrdSysRAtomic.hh:48
Definition XrdClPollerBuiltIn.hh:28