sipxportlib  Version 3.3
OsAtomics.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2008-2020 SIPez LLC. All rights reserved.
3 //
4 // Copyright (C) 2008 SIPfoundry Inc.
5 // Licensed by SIPfoundry under the LGPL license.
6 //
7 // $$
9 
10 // Author: Alexander Chemeris <Alexander DOT Chemeris AT SIPez DOT com>
11 
12 #ifndef _OsAtomics_H_ // [
13 #define _OsAtomics_H_
14 
15 #ifdef HAVE_C_ATOMICS // [
16 # include <cstdatomic>
17 
18 typedef atomic_int OsAtomicInt;
19 typedef atomic_uint OsAtomicUInt;
20 typedef atomic_long OsAtomicLong;
21 typedef atomic_ulong OsAtomicULong;
22 typedef atomic_address OsAtomicVoidPtr;
23 
24 #define OsAtomicLight OsAtomic
25 
26 #elif defined(ANDROID) // HAVE_C_ATOMICS ][ ANDROID
27 
28 #include <os/OsAtomicsAndroid.h>
29 
30 #else // ANDROID ][
31 
32 #ifdef __arm__
33 #warning ARM version of OsAtomics need to be fixed to support ARM features.
34 #endif
35 
36 # include <os/OsLock.h>
37 # include <os/OsMutex.h>
38 # include <stddef.h>
39 # include <os/OsIntTypes.h>
40 
41 typedef enum memory_order {
44 } memory_order;
45 
46 template<class T>
47 class OsAtomic
48 {
49 public:
50  bool is_lock_free() const
51  {return false;}
52 
54  {OsLock lock(mMutex); mVal = val;}
55 
57  {OsLock lock(mMutex); return mVal;}
58 
59  operator T() const
60  {return load();}
61 
62 // T exchange(T val, ::memory_order = memory_order_seq_cst);
63 // bool compare_exchange(T &, T , ::memory_order, ::memory_order);
64 // bool compare_exchange(T &, T , ::memory_order = memory_order_seq_cst);
65 
66  void fence(::memory_order) const
67  {};
68 
70  {OsLock lock(mMutex); T temp = mVal; mVal += val; return temp;}
71 
73  {OsLock lock(mMutex); T temp = mVal; mVal -= val; return temp;}
74 
76  {OsLock lock(mMutex); T temp = mVal; mVal &= val; return temp;}
77 
79  {OsLock lock(mMutex); T temp = mVal; mVal |= val; return temp;}
80 
82  {OsLock lock(mMutex); T temp = mVal; mVal ^= val; return temp;}
83 
84  OsAtomic<T>() : mMutex(0) {};
85 
86  explicit OsAtomic<T>(T val) : mVal(val), mMutex(0) {};
87 
88  T operator=(T val)
89  {store(val); return val;}
90 
91  T operator++(int)
92  {return fetch_add(1);}
93 
94  T operator--(int)
95  {return fetch_sub(1);}
96 
98  {return operator+=(1);}
99 
101  {return operator-=(1);}
102 
103  T operator+=(T val)
104  {OsLock lock(mMutex); mVal += val; return mVal;}
105 
106  T operator-=(T val)
107  {OsLock lock(mMutex); mVal -= val; return mVal;}
108 
109  T operator&=(T val)
110  {OsLock lock(mMutex); mVal &= val; return mVal;}
111 
112  T operator|=(T val)
113  {OsLock lock(mMutex); mVal |= val; return mVal;}
114 
115  T operator^=(T val)
116  {OsLock lock(mMutex); mVal ^= val; return mVal;}
117 
118 private:
119  T mVal;
120  mutable OsMutex mMutex;
121 
122  // Prohibit use of copy constructor and operator=
123  OsAtomic<T>(const OsAtomic<T>&);
125 };
126 
131 
133 public:
134  bool is_lock_free() const
135  {return false;}
136 
137  OsAtomicBool() : mMutex(0) {};
138 
139  explicit OsAtomicBool(bool val) : mVal(val), mMutex(0) {};
140 
142  {OsLock lock(mMutex); mVal = val;}
143 
145  {OsLock lock(mMutex); return mVal;}
146 
147  bool operator=(bool val)
148  {store(val); return val;}
149 
150  operator bool() const
151  {return load();}
152 
153 // bool exchange(bool, ::memory_order = ::memory_order_seq_cst);
154 // bool compare_exchange(bool&, bool, ::memory_order, ::memory_order);
155 // bool compare_exchange(bool&, bool, ::memory_order = ::memory_order_seq_cst);
156 
157  void fence(::memory_order) const
158  {}
159 
160 private:
161  bool mVal;
162  mutable OsMutex mMutex;
163 
164  // Prohibit use of copy constructor and operator=
165  OsAtomicBool(const OsAtomicBool&);
167 };
168 
170 {
171 public:
172  bool is_lock_free() const
173  {return false;}
174 
175  void store(void* val, ::memory_order = ::memory_order_seq_cst)
176  {OsLock lock(mMutex); mVal = val;}
177 
179  {OsLock lock(mMutex); return mVal;}
180 
181  operator void*() const
182  {return load();}
183 
184 // void* exchange(void* val, ::memory_order = ::memory_order_seq_cst);
185 // bool compare_exchange(void* &, void* , ::memory_order, ::memory_order);
186 // bool compare_exchange(void* &, void* , ::memory_order = ::memory_order_seq_cst);
187 
188  void fence(::memory_order) const
189  {};
190 
191  void* fetch_add(ptrdiff_t val, ::memory_order = ::memory_order_seq_cst)
192  {OsLock lock(mMutex); void* temp = mVal; mVal = (int8_t*)mVal + val; return temp;}
193 
194  void* fetch_sub(ptrdiff_t val, ::memory_order = ::memory_order_seq_cst)
195  {OsLock lock(mMutex); void* temp = mVal; mVal = (int8_t*)mVal - val; return temp;}
196 
197  OsAtomicVoidPtr() : mMutex(0) {};
198 
199  explicit OsAtomicVoidPtr(void* val) : mVal(val), mMutex(0) {};
200 
201  void* operator=(void* val)
202  {store(val); return val;}
203 
204  void* operator+=(ptrdiff_t val)
205  {OsLock lock(mMutex); mVal = (int8_t*)mVal + val; return mVal;}
206 
207  void* operator-=(ptrdiff_t val)
208  {OsLock lock(mMutex); mVal = (int8_t*)mVal - val; return mVal;}
209 
210 private:
211  void* mVal;
212  mutable OsMutex mMutex;
213 
214  // Prohibit use of copy constructor and operator=
217 };
218 
219 template<class T>
221 {
222 public:
223  bool is_lock_free() const
224  {return false;}
225 
226  void store(T* val, ::memory_order mo = ::memory_order_seq_cst)
227  {OsAtomicVoidPtr::store((void*)val, mo);}
228 
230  {return (T*)OsAtomicVoidPtr::load(mo);}
231 
232  operator T*() const
233  {return (T*)OsAtomicVoidPtr::operator void*();}
234 
235 // T* exchange(T* val, ::memory_order mo = ::memory_order_seq_cst);
236 // bool compare_exchange(T* &, T* , ::memory_order mo, ::memory_order mo);
237 // bool compare_exchange(T* &, T* , ::memory_order mo = ::memory_order_seq_cst);
238 
239  void fence(::memory_order mo) const
241 
242  T* fetch_add(ptrdiff_t val, ::memory_order mo = ::memory_order_seq_cst)
243  {return (T*)OsAtomicVoidPtr::fetch_add(val, mo);}
244 
245  T* fetch_sub(ptrdiff_t val, ::memory_order mo = ::memory_order_seq_cst)
246  {return (T*)OsAtomicVoidPtr::fetch_sub(val, mo);}
247 
249 
250  explicit OsAtomicPtr(T* val) : OsAtomicVoidPtr((void*)val) {};
251 
252  T* operator=(T* val)
253  {return (T*)OsAtomicVoidPtr::operator=((void*)val);}
254 
255  T* operator+=(ptrdiff_t val)
256  {return (T*)OsAtomicVoidPtr::operator+=(val);}
257 
258  T* operator-=(ptrdiff_t val)
259  {return (T*)OsAtomicVoidPtr::operator-=(val);}
260 
261 private:
262  // Prohibit use of copy constructor and operator=
263  OsAtomicPtr(const OsAtomicPtr&);
265 };
266 
267 
268 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__amd64__) || defined (__arm__)// [
269 template<class T>
270 class OsAtomicLight
271 {
272 public:
273  bool is_lock_free() const
274  {return true;}
275 
276  void store(T val, ::memory_order = ::memory_order_relaxed)
277  {mVal = val;}
278 
279  T load(::memory_order = ::memory_order_relaxed) const
280  {return mVal;}
281 
282  operator T() const
283  {return load();}
284 
285  void fence(::memory_order) const
286  {};
287 
288  OsAtomicLight<T>() {};
289 
290  explicit OsAtomicLight<T>(T val) : mVal(val) {};
291 
292  T operator=(T val)
293  {store(val); return val;}
294 
295 private:
296  volatile T mVal;
297 
298  // Prohibit use of copy constructor and operator=
299  OsAtomicLight<T>(const OsAtomicLight<T>&);
300  OsAtomicLight<T>& operator=(const OsAtomicLight<T>&);
301 };
302 
303 
304 template<class T>
305 class OsAtomicLightPtr
306 {
307 public:
308  bool is_lock_free() const
309  {return true;}
310 
311  void store(T* val, ::memory_order mo = ::memory_order_relaxed)
312  {mVal = val;}
313 
314  const T* load(::memory_order mo = ::memory_order_relaxed) const
315  {return mVal;}
316 
318  {return mVal;}
319 
320  operator const T*() const
321  {return load();}
322 
323  operator T*()
324  {return load();}
325 
326  void fence(::memory_order mo) const
327  {}
328 
329  OsAtomicLightPtr() {};
330 
331  explicit OsAtomicLightPtr(T* val) : mVal(val) {};
332 
333  T* operator=(T* val)
334  {store(val); return val;}
335 
336 private:
337  T * volatile mVal;
338 
339  // Prohibit use of copy constructor and operator=
342 };
343 
344 #else // X86/X86_64/ARM ][
345 
346 #define OsAtomicLight OsAtomic
347 #define OsAtomicLightPtr OsAtomicPtr
348 
349 #endif // !X86/X86_64/ARM
350 
351 #endif // HAVE_C_ATOMICS ]
352 
353 typedef OsAtomicLight<int> OsAtomicLightInt;
354 typedef OsAtomicLight<unsigned int> OsAtomicLightUInt;
355 typedef OsAtomicLight<long> OsAtomicLightLong;
356 typedef OsAtomicLight<unsigned long> OsAtomicLightULong;
357 typedef OsAtomicLight<bool> OsAtomicLightBool;
358 
359 #endif // _OsAtomics_H_ ]
void store(void *val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:175
T operator++()
Definition: OsAtomics.h:97
bool is_lock_free() const
Definition: OsAtomics.h:50
T load(::memory_order=::memory_order_seq_cst) const
Definition: OsAtomics.h:56
T fetch_xor(T val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:81
void * load(::memory_order=::memory_order_seq_cst) const
Definition: OsAtomics.h:178
bool load(::memory_order=::memory_order_seq_cst) const
Definition: OsAtomics.h:144
OsAtomicPtr(T *val)
Definition: OsAtomics.h:250
T fetch_or(T val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:78
Lock class for mutual exclusion in a critical section.
Definition: OsLock.h:52
T * fetch_sub(ptrdiff_t val,::memory_order mo=::memory_order_seq_cst)
Definition: OsAtomics.h:245
Include this file if you want use C99 integer types with specified width and corresponding set of mac...
OsAtomicLight< bool > OsAtomicLightBool
Definition: OsAtomics.h:357
OsAtomicBool()
Definition: OsAtomics.h:137
Definition: OsAtomics.h:42
T operator&=(T val)
Definition: OsAtomics.h:109
T * operator-=(ptrdiff_t val)
Definition: OsAtomics.h:258
T operator--(int)
Definition: OsAtomics.h:94
T * load(::memory_order mo=::memory_order_seq_cst) const
Definition: OsAtomics.h:229
OsAtomic< unsigned long > OsAtomicULong
Definition: OsAtomics.h:130
void * operator=(void *val)
Definition: OsAtomics.h:201
void fence(::memory_order) const
Definition: OsAtomics.h:157
memory_order
Definition: OsAtomics.h:41
#define OsAtomicLight
Definition: OsAtomics.h:346
T operator-=(T val)
Definition: OsAtomics.h:106
OsAtomic< long > OsAtomicLong
Definition: OsAtomics.h:129
Definition: OsAtomics.h:169
bool is_lock_free() const
Definition: OsAtomics.h:172
OsAtomicLight< long > OsAtomicLightLong
Definition: OsAtomics.h:355
void * fetch_sub(ptrdiff_t val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:194
OsAtomicPtr()
Definition: OsAtomics.h:248
Definition: OsAtomics.h:42
OsAtomicLight< int > OsAtomicLightInt
Definition: OsAtomics.h:353
void fence(::memory_order mo) const
Definition: OsAtomics.h:239
T operator^=(T val)
Definition: OsAtomics.h:115
OsAtomicLight< unsigned int > OsAtomicLightUInt
Definition: OsAtomics.h:354
OsAtomic< unsigned int > OsAtomicUInt
Definition: OsAtomics.h:128
Definition: OsAtomics.h:47
void * fetch_add(ptrdiff_t val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:191
OsAtomicVoidPtr(void *val)
Definition: OsAtomics.h:199
T fetch_sub(T val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:72
void store(bool val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:141
void * operator-=(ptrdiff_t val)
Definition: OsAtomics.h:207
signed char int8_t
Definition: stdint.h:75
Definition: OsAtomics.h:220
T operator|=(T val)
Definition: OsAtomics.h:112
#define OsAtomicLightPtr
Definition: OsAtomics.h:347
void store(T val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:53
OsAtomicBool(bool val)
Definition: OsAtomics.h:139
void store(T *val,::memory_order mo=::memory_order_seq_cst)
Definition: OsAtomics.h:226
OsAtomicLight< unsigned long > OsAtomicLightULong
Definition: OsAtomics.h:356
T operator=(T val)
Definition: OsAtomics.h:88
T * fetch_add(ptrdiff_t val,::memory_order mo=::memory_order_seq_cst)
Definition: OsAtomics.h:242
Definition: OsAtomics.h:43
T * operator=(T *val)
Definition: OsAtomics.h:252
Definition: OsAtomics.h:43
bool is_lock_free() const
Definition: OsAtomics.h:134
bool is_lock_free() const
Definition: OsAtomics.h:223
void * operator+=(ptrdiff_t val)
Definition: OsAtomics.h:204
T * operator+=(ptrdiff_t val)
Definition: OsAtomics.h:255
T operator--()
Definition: OsAtomics.h:100
Definition: OsAtomics.h:43
bool operator=(bool val)
Definition: OsAtomics.h:147
Definition: OsAtomics.h:132
void fence(::memory_order) const
Definition: OsAtomics.h:66
T operator+=(T val)
Definition: OsAtomics.h:103
T operator++(int)
Definition: OsAtomics.h:91
T fetch_add(T val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:69
T fetch_and(T val,::memory_order=::memory_order_seq_cst)
Definition: OsAtomics.h:75
OsAtomic< int > OsAtomicInt
Definition: OsAtomics.h:127
OsAtomicVoidPtr()
Definition: OsAtomics.h:197
Definition: OsAtomics.h:42
void fence(::memory_order) const
Definition: OsAtomics.h:188