xrootd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 
22 namespace XrdSys
23 {
24 template<typename T>
25 class RAtomic
26 {
27 public:
28 
29 // Store and fetch defined here for immediate expansion
30 //
31 T operator=(T v) noexcept
32  {_m.store(v, std::memory_order_relaxed); return v;}
33 
34 T 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 //
45 T operator++(int) noexcept
46  {return _m.fetch_add(1, std::memory_order_relaxed);}
47 
48 T operator++(int) volatile noexcept
49  {return _m.fetch_add(1, std::memory_order_relaxed);}
50 
51 T operator--(int) noexcept
52  {return _m.fetch_sub(1, std::memory_order_relaxed);}
53 
54 T operator--(int) volatile noexcept
55  {return _m.fetch_sub(1, std::memory_order_relaxed);}
56 
57 // Pre-increment/decrement (i.e.++x)
58 //
59 T operator++() noexcept
60  {return _m.fetch_add(1, std::memory_order_relaxed)+1;}
61 
62 T operator++() volatile noexcept
63  {return _m.fetch_add(1, std::memory_order_relaxed)+1;}
64 
65 T operator--() noexcept
66  {return _m.fetch_sub(1, std::memory_order_relaxed)-1;}
67 
68 T operator--() volatile noexcept
69  {return _m.fetch_sub(1, std::memory_order_relaxed)-1;}
70 
71 T operator+=(T v) noexcept
72  {return _m.fetch_add(v, std::memory_order_relaxed)+v;}
73 
74 T operator+=(T v) volatile noexcept
75  {return _m.fetch_add(v, std::memory_order_relaxed)+v;}
76 
77 T operator-=(T v) noexcept
78  {return _m.fetch_sub(v, std::memory_order_relaxed)-v;}
79 
80 T operator-=(T v) volatile noexcept
81  {return _m.fetch_sub(v, std::memory_order_relaxed)-v;}
82 
83 T operator&=(T v) noexcept
84  {return _m.fetch_and(v, std::memory_order_relaxed) & v;}
85 
86 T operator&=(T v) volatile noexcept
87  {return _m.fetch_and(v, std::memory_order_relaxed) & v;}
88 
89 T operator|=(T v) noexcept
90  {return _m.fetch_or (v, std::memory_order_relaxed) | v;}
91 
92 T operator|=(T v) volatile noexcept
93  {return _m.fetch_or (v, std::memory_order_relaxed) | v;}
94 
95 T operator^=(T v) noexcept
96  {return _m.fetch_xor(v, std::memory_order_relaxed) ^ v;}
97 
98 T 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 //
103 T fetch_and(T v) noexcept
104  {return _m.fetch_and(v, std::memory_order_relaxed);}
105 
106 T fetch_or(T v) noexcept
107  {return _m.fetch_or (v, std::memory_order_relaxed);}
108 
109 T 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 
126 T compare_exchange_weak(T& v1, T v2,
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 
132 T compare_exchange_weak(T& v1, T v2,
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 
138 T exchange(T v, std::memory_order mo=std::memory_order_relaxed) noexcept
139  {return _m.exchange(v, mo);}
140 
141 T exchange(T v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
142  {return _m.exchange(v, mo);}
143 
144  RAtomic() {}
145 
146  RAtomic(T v) : _m(v) {}
147 
148 private:
149 
150 std::atomic<T> _m;
151 };
152 
153 template<typename T>
154 class RAtomic<T*>
155 {
156 public:
157 
158 // Store and fetch defined here for immediate expansion
159 //
160 T* operator=(T* v) noexcept
161  {_m.store(v, std::memory_order_relaxed); return v;}
162 
163 T* 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 // Post-increment/decrement (i.e. x++)
173 //
174 T* operator++(int) noexcept
175  {return _m.fetch_add(1, std::memory_order_relaxed);}
176 
177 T* operator++(int) volatile noexcept
178  {return _m.fetch_add(1, std::memory_order_relaxed);}
179 
180 T* operator--(int) noexcept
181  {return _m.fetch_sub(1, std::memory_order_relaxed);}
182 
183 T* operator--(int) volatile noexcept
184  {return _m.fetch_sub(1, std::memory_order_relaxed);}
185 
186 // Pre-increment/decrement (i.e.++x)
187 //
188 T* operator++() noexcept
189  {return _m.fetch_add(1, std::memory_order_relaxed)+1;}
190 
191 T* operator++() volatile noexcept
192  {return _m.fetch_add(1, std::memory_order_relaxed)+1;}
193 
194 T* operator--() noexcept
195  {return _m.fetch_sub(1, std::memory_order_relaxed)-1;}
196 
197 T* operator--() volatile noexcept
198  {return _m.fetch_sub(1, std::memory_order_relaxed)-1;}
199 
200 T* operator+=(ptrdiff_t v) noexcept
201  {return _m.fetch_add(v, std::memory_order_relaxed)+v;}
202 
203 T* operator+=(ptrdiff_t v) volatile noexcept
204  {return _m.fetch_add(v, std::memory_order_relaxed)+v;}
205 
206 T* operator-=(ptrdiff_t v) noexcept
207  {return _m.fetch_sub(v, std::memory_order_relaxed)-v;}
208 
209 T* operator-=(ptrdiff_t v) volatile noexcept
210  {return _m.fetch_sub(v, std::memory_order_relaxed)-v;}
211 
212 // Member functions
213 //
214 T* compare_exchange_strong(T& v1, T* v2,
215  std::memory_order mo1=std::memory_order_relaxed,
216  std::memory_order mo2=std::memory_order_relaxed)
217  noexcept
218  {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
219 
220 T* compare_exchange_strong(T& v1, T* v2,
221  std::memory_order mo1=std::memory_order_relaxed,
222  std::memory_order mo2=std::memory_order_relaxed)
223  volatile noexcept
224  {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
225 
226 T* compare_exchange_weak(T& v1, T* v2,
227  std::memory_order mo1=std::memory_order_relaxed,
228  std::memory_order mo2=std::memory_order_relaxed)
229  noexcept
230  {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
231 
232 T* compare_exchange_weak(T& v1, T* v2,
233  std::memory_order mo1=std::memory_order_relaxed,
234  std::memory_order mo2=std::memory_order_relaxed)
235  volatile noexcept
236  {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
237 
238 T* exchange(T* v, std::memory_order mo=std::memory_order_relaxed) noexcept
239  {return _m.exchange(v, mo);}
240 
241 T* exchange(T* v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
242  {return _m.exchange(v, mo);}
243 
244  RAtomic() {}
245 
246  RAtomic(T* v) : _m(v) {}
247 
248 private:
249 
250 std::atomic<T*> _m;
251 };
252 
253 template<>
254 class RAtomic<bool>
255 {
256 public:
257 
258 // Store and fetch defined here for immediate expansion
259 //
260 bool operator=(bool v) noexcept
261  {_m.store(v, std::memory_order_relaxed); return v;}
262 
263 bool operator=(bool v) volatile noexcept
264  {_m.store(v, std::memory_order_relaxed); return v;}
265 
266  operator bool() noexcept
267  {return _m.load(std::memory_order_relaxed);}
268 
269  operator bool() volatile noexcept
270  {return _m.load(std::memory_order_relaxed);}
271 
272 // Member functions
273 //
274 bool compare_exchange_strong(bool& v1, bool v2,
275  std::memory_order mo1=std::memory_order_relaxed,
276  std::memory_order mo2=std::memory_order_relaxed)
277  noexcept
278  {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
279 
280 bool compare_exchange_strong(bool& v1, bool v2,
281  std::memory_order mo1=std::memory_order_relaxed,
282  std::memory_order mo2=std::memory_order_relaxed)
283  volatile noexcept
284  {return _m.compare_exchange_strong(v1, v2, mo1, mo2);}
285 
286 bool compare_exchange_weak(bool& v1, bool v2,
287  std::memory_order mo1=std::memory_order_relaxed,
288  std::memory_order mo2=std::memory_order_relaxed)
289  noexcept
290  {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
291 
292 bool compare_exchange_weak(bool& v1, bool v2,
293  std::memory_order mo1=std::memory_order_relaxed,
294  std::memory_order mo2=std::memory_order_relaxed)
295  volatile noexcept
296  {return _m.compare_exchange_weak(v1, v2, mo1, mo2);}
297 
298 bool exchange(bool v, std::memory_order mo=std::memory_order_relaxed) noexcept
299  {return _m.exchange(v, mo);}
300 
301 bool exchange(bool v, std::memory_order mo=std::memory_order_relaxed) volatile noexcept
302  {return _m.exchange(v, mo);}
303 
304  RAtomic() {}
305 
306  RAtomic(bool v) : _m(v) {}
307 
308 private:
309 
310 std::atomic<bool> _m;
311 };
312 }
313 
314 // Common types
315 //
337 #endif
bool compare_exchange_strong(bool &v1, bool v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:280
T operator=(T v) volatilenoexcept
Definition: XrdSysRAtomic.hh:34
XrdSys::RAtomic< int32_t > RAtomic_int32_t
Definition: XrdSysRAtomic.hh:333
std::atomic< T > _m
Definition: XrdSysRAtomic.hh:150
T operator++(int) volatilenoexcept
Definition: XrdSysRAtomic.hh:48
T operator+=(T v) noexcept
Definition: XrdSysRAtomic.hh:71
T * compare_exchange_strong(T &v1, T *v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:220
T * operator++(int) noexcept
Definition: XrdSysRAtomic.hh:174
T operator&=(T v) volatilenoexcept
Definition: XrdSysRAtomic.hh:86
T * operator+=(ptrdiff_t v) noexcept
Definition: XrdSysRAtomic.hh:200
T fetch_or(T v) noexcept
Definition: XrdSysRAtomic.hh:106
XrdSys::RAtomic< bool > RAtomic_bool
Definition: XrdSysRAtomic.hh:316
XrdSys::RAtomic< int64_t > RAtomic_int64_t
Definition: XrdSysRAtomic.hh:335
T fetch_and(T v) noexcept
Definition: XrdSysRAtomic.hh:103
T * operator+=(ptrdiff_t v) volatilenoexcept
Definition: XrdSysRAtomic.hh:203
T operator--() noexcept
Definition: XrdSysRAtomic.hh:65
T operator&=(T v) noexcept
Definition: XrdSysRAtomic.hh:83
RAtomic()
Definition: XrdSysRAtomic.hh:244
XrdSys::RAtomic< uint16_t > RAtomic_uint16_t
Definition: XrdSysRAtomic.hh:332
XrdSys::RAtomic< uint64_t > RAtomic_uint64_t
Definition: XrdSysRAtomic.hh:336
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
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:274
T operator++(int) noexcept
Definition: XrdSysRAtomic.hh:45
T fetch_xor(T v) noexcept
Definition: XrdSysRAtomic.hh:109
T * exchange(T *v, std::memory_order mo=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:241
RAtomic()
Definition: XrdSysRAtomic.hh:144
XrdSys::RAtomic< int8_t > RAtomic_int8_t
Definition: XrdSysRAtomic.hh:329
T operator-=(T v) noexcept
Definition: XrdSysRAtomic.hh:77
RAtomic(T *v)
Definition: XrdSysRAtomic.hh:246
XrdSys::RAtomic< unsigned short > RAtomic_ushort
Definition: XrdSysRAtomic.hh:321
XrdSys::RAtomic< long long > RAtomic_llong
Definition: XrdSysRAtomic.hh:326
XrdSys::RAtomic< uint32_t > RAtomic_uint32_t
Definition: XrdSysRAtomic.hh:334
XrdSys::RAtomic< int > RAtomic_int
Definition: XrdSysRAtomic.hh:322
T * operator-=(ptrdiff_t v) noexcept
Definition: XrdSysRAtomic.hh:206
T operator=(T v) noexcept
Definition: XrdSysRAtomic.hh:31
bool compare_exchange_weak(bool &v1, bool v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:292
T * exchange(T *v, std::memory_order mo=std::memory_order_relaxed) noexcept
Definition: XrdSysRAtomic.hh:238
T operator-=(T v) volatilenoexcept
Definition: XrdSysRAtomic.hh:80
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:286
T operator^=(T v) volatilenoexcept
Definition: XrdSysRAtomic.hh:98
XrdSys::RAtomic< char > RAtomic_char
Definition: XrdSysRAtomic.hh:317
XrdSys::RAtomic< short > RAtomic_short
Definition: XrdSysRAtomic.hh:320
T operator++() noexcept
Definition: XrdSysRAtomic.hh:59
T operator++() volatilenoexcept
Definition: XrdSysRAtomic.hh:62
T exchange(T v, std::memory_order mo=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:141
T compare_exchange_weak(T &v1, T v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:132
XrdSys::RAtomic< unsigned int > RAtomic_uint
Definition: XrdSysRAtomic.hh:323
std::atomic< T * > _m
Definition: XrdSysRAtomic.hh:250
T compare_exchange_strong(T &v1, T v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:120
XrdSys::RAtomic< uint8_t > RAtomic_uint8_t
Definition: XrdSysRAtomic.hh:330
XrdSys::RAtomic< signed char > RAtomic_schar
Definition: XrdSysRAtomic.hh:318
T * operator++() noexcept
Definition: XrdSysRAtomic.hh:188
T exchange(T v, std::memory_order mo=std::memory_order_relaxed) noexcept
Definition: XrdSysRAtomic.hh:138
bool operator=(bool v) volatilenoexcept
Definition: XrdSysRAtomic.hh:263
bool exchange(bool v, std::memory_order mo=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:301
XrdSys::RAtomic< unsigned char > RAtomic_uchar
Definition: XrdSysRAtomic.hh:319
T * operator--() noexcept
Definition: XrdSysRAtomic.hh:194
Definition: XrdSysRAtomic.hh:25
XrdSys::RAtomic< unsigned long > RAtomic_ulong
Definition: XrdSysRAtomic.hh:325
T * operator--(int) noexcept
Definition: XrdSysRAtomic.hh:180
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:226
RAtomic(bool v)
Definition: XrdSysRAtomic.hh:306
XrdSys::RAtomic< long > RAtomic_long
Definition: XrdSysRAtomic.hh:324
Definition: XrdSysRAtomic.hh:254
RAtomic()
Definition: XrdSysRAtomic.hh:304
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--() volatilenoexcept
Definition: XrdSysRAtomic.hh:197
std::atomic< bool > _m
Definition: XrdSysRAtomic.hh:310
XrdSys::RAtomic< wchar_t > RAtomic_wchar_t
Definition: XrdSysRAtomic.hh:328
T operator+=(T v) volatilenoexcept
Definition: XrdSysRAtomic.hh:74
bool operator=(bool v) noexcept
Definition: XrdSysRAtomic.hh:260
T operator--() volatilenoexcept
Definition: XrdSysRAtomic.hh:68
T operator|=(T v) noexcept
Definition: XrdSysRAtomic.hh:89
T * operator++(int) volatilenoexcept
Definition: XrdSysRAtomic.hh:177
T * operator-=(ptrdiff_t v) volatilenoexcept
Definition: XrdSysRAtomic.hh:209
T * operator++() volatilenoexcept
Definition: XrdSysRAtomic.hh:191
T operator--(int) noexcept
Definition: XrdSysRAtomic.hh:51
T * operator=(T *v) noexcept
Definition: XrdSysRAtomic.hh:160
T * compare_exchange_weak(T &v1, T *v2, std::memory_order mo1=std::memory_order_relaxed, std::memory_order mo2=std::memory_order_relaxed) volatilenoexcept
Definition: XrdSysRAtomic.hh:232
T * operator=(T *v) volatilenoexcept
Definition: XrdSysRAtomic.hh:163
XrdSys::RAtomic< unsigned long long > RAtomic_ullong
Definition: XrdSysRAtomic.hh:327
T operator|=(T v) volatilenoexcept
Definition: XrdSysRAtomic.hh:92
T operator^=(T v) noexcept
Definition: XrdSysRAtomic.hh:95
bool exchange(bool v, std::memory_order mo=std::memory_order_relaxed) noexcept
Definition: XrdSysRAtomic.hh:298
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:214
T * operator--(int) volatilenoexcept
Definition: XrdSysRAtomic.hh:183
XrdSys::RAtomic< int16_t > RAtomic_int16_t
Definition: XrdSysRAtomic.hh:331
T operator--(int) volatilenoexcept
Definition: XrdSysRAtomic.hh:54
RAtomic(T v)
Definition: XrdSysRAtomic.hh:146