8 #ifndef INCL_evo_atomic_h     9 #define INCL_evo_atomic_h    14 #if defined(EVO_CPP11) || (defined(EVO_MSVC_YEAR) && EVO_MSVC_YEAR >= 2012) || defined(EVO_INTEL_VER)    16     #define EVO_INTRINSIC_ATOMICS 1     // 1 when compiler supports atomic operations    17     #define EVO_STD_ATOMIC 1            // 1 when compiler supports std::atomic and std::atomic_flag    18     #define EVO_ATOMIC_PTRMATH 1        // 1 when pointer math works correctly with AtomicPtr, i.e. increment uses sizeof()    21     #define EVO_ATOMIC_RELAXED std::memory_order_relaxed    24     #define EVO_ATOMIC_CONSUME std::memory_order_consume    27     #define EVO_ATOMIC_ACQUIRE std::memory_order_acquire    30     #define EVO_ATOMIC_RELEASE std::memory_order_release    33     #define EVO_ATOMIC_ACQ_REL std::memory_order_acq_rel    36     #define EVO_ATOMIC_SYNC    std::memory_order_seq_cst    52     #define EVO_ATOMIC_FENCE(MEM_ORDER) std::atomic_thread_fence(MEM_ORDER)    53 #elif defined(EVO_GCC_VER) && EVO_GCC_VER >= 407    55     #define EVO_INTRINSIC_ATOMICS 1    56     #define EVO_GCC_ATOMICS 1    58     #define EVO_ATOMIC_RELAXED __ATOMIC_RELAXED    59     #define EVO_ATOMIC_CONSUME __ATOMIC_CONSUME    60     #define EVO_ATOMIC_ACQUIRE __ATOMIC_ACQUIRE    61     #define EVO_ATOMIC_RELEASE __ATOMIC_RELEASE    62     #define EVO_ATOMIC_ACQ_REL __ATOMIC_ACQ_REL    63     #define EVO_ATOMIC_SYNC    __ATOMIC_SEQ_CST    65     #define EVO_ATOMIC_FENCE(MEM_ORDER) __atomic_thread_fence(MEM_ORDER)    67     #define EVO_ATOMIC_FETCH_OP(OP, PTR, VAL, MEM_ORDER) __atomic_fetch_ ## OP (PTR, VAL, MEM_ORDER)    68     #define EVO_ATOMIC_OP_FETCH(OP, PTR, VAL, MEM_ORDER) __atomic_ ## OP ## _fetch(PTR, VAL, MEM_ORDER)    71     #define EVO_ATOMIC_RELAXED 0    72     #define EVO_ATOMIC_CONSUME 0    73     #define EVO_ATOMIC_ACQUIRE 0    74     #define EVO_ATOMIC_RELEASE 0    75     #define EVO_ATOMIC_ACQ_REL 0    76     #define EVO_ATOMIC_SYNC    0    78     #if defined(EVO_MSVC_YEAR) || (defined(EVO_GCC_VER) && EVO_GCC_VER < 401)    81         #define EVO_INTRINSIC_ATOMICS 0    84         #define EVO_INTRINSIC_ATOMICS 1    85         #define EVO_ATOMIC_FENCE(MEM_ORDER) __sync_synchronize()    87         #define EVO_ATOMIC_FETCH_OP(OP, PTR, VAL, MEM_ORDER) __sync_fetch_and_ ## OP (PTR, VAL)    88         #define EVO_ATOMIC_OP_FETCH(OP, PTR, VAL, MEM_ORDER) __sync_ ## OP ## _and_fetch(PTR, VAL)    91 #if !EVO_INTRINSIC_ATOMICS    94     #define EVO_ATOMIC_PTRMATH 1    98 #if defined(EVO_ATOMIC_SAFE_STATICS)   101     #if defined(EVO_MSVC_YEAR)   102         #if EVO_MSVC_YEAR >= 2015            // No thread-safe static init until MSVC 2015   103             #define EVO_ATOMIC_SAFE_STATICS 1   105     #elif defined(EVO_CPP11)                // C++11 requires thread-safe static init   106         #define EVO_ATOMIC_SAFE_STATICS 1   107     #elif defined(EVO_CLANG_VER)            // clang 2.9+   108         #if EVO_CLANG_VER >= 209   109             #define EVO_ATOMIC_SAFE_STATICS 1   111     #elif defined(EVO_GCC_VER)              // gcc 4.3+   112         #if EVO_GCC_VER >= 403   113             #define EVO_ATOMIC_SAFE_STATICS 1   117     #if !defined(EVO_ATOMIC_SAFE_STATICS)   122         #define EVO_ATOMIC_SAFE_STATICS 0   127 #if defined(EVO_MSVC_YEAR) && !EVO_INTRINSIC_ATOMICS   128     #pragma warning(push)   129     #pragma warning(disable:4800 4100)   139 #if defined(EVO_STD_ATOMIC)   159 #if !EVO_INTRINSIC_ATOMICS   160     #define EVO_TMP_ATOMIC_OP(CODE) { T val; mutex_.lock(); CODE; mutex_.unlock(); return val; }   171 #if defined(EVO_STD_ATOMIC)   173     #if defined(EVO_CLANG_VER) || defined(EVO_MSVC_YEAR)   197         #if !EVO_INTRINSIC_ATOMICS   201         #elif defined(EVO_GCC_ATOMICS)   202             __atomic_clear(&val_, mem_order);
   210         #if !EVO_INTRINSIC_ATOMICS   212             EVO_TMP_ATOMIC_OP(val = val_; val_ = 1)
   213         #elif defined(EVO_GCC_ATOMICS)
   214             return __atomic_test_and_set(&val_, mem_order);
   216             return !__sync_bool_compare_and_swap(&val_, 0, 1);
   221     #if defined(EVO_GCC_ATOMICS)   260 #if !EVO_INTRINSIC_ATOMICS   309 #if defined(EVO_STD_ATOMIC)   333         { T oldval = cmpval; 
return this->compare_exchange_strong(oldval, newval, mem_order_success, mem_order_failure); }
   441         #if !EVO_INTRINSIC_ATOMICS   442             EVO_TMP_ATOMIC_OP(val = val_)
   443         #elif defined(EVO_GCC_ATOMICS)   444             return __atomic_load_n(&val_, mem_order);
   447             __sync_synchronize();
   449             __sync_synchronize();
   455         #if !EVO_INTRINSIC_ATOMICS   456             EVO_TMP_ATOMIC_OP(val = val_; val_ = num)
   457         #elif defined(EVO_GCC_ATOMICS)
   458             return __atomic_exchange_n(&val_, num, mem_order);
   462                 __sync_synchronize();
   464             } 
while (!__sync_bool_compare_and_swap(&val_, prev_val, num));
   470         #if !EVO_INTRINSIC_ATOMICS   474         #elif defined(EVO_GCC_ATOMICS)   475             __atomic_store_n(&val_, num, mem_order);
   478             __sync_synchronize();
   482     This& operator=(T num) {
   488         #if !EVO_INTRINSIC_ATOMICS   489             bool replaced = 
false;
   491             if (val_ == cmpval) {
   497         #elif defined(EVO_GCC_ATOMICS)   498             return __atomic_compare_exchange_n(&val_, &cmpval, newval, 
false, mem_order_success, mem_order_failure);
   500             return __sync_bool_compare_and_swap(&val_, cmpval, newval);
   504 #if EVO_INTRINSIC_ATOMICS   506         { 
return EVO_ATOMIC_FETCH_OP(add, &val_, num, mem_order); }
   509         { 
return EVO_ATOMIC_FETCH_OP(sub, &val_, num, mem_order); }
   512         { 
return EVO_ATOMIC_FETCH_OP(and, &val_, num, mem_order); }
   515         { 
return EVO_ATOMIC_FETCH_OP(or, &val_, num, mem_order); }
   518         { 
return EVO_ATOMIC_FETCH_OP(xor, &val_, num, mem_order); }
   552         { EVO_TMP_ATOMIC_OP(val = val_; val_ += (NumType)num) }
   555         { EVO_TMP_ATOMIC_OP(val = val_; val_ -= (NumType)num) }
   558         { EVO_TMP_ATOMIC_OP(val = val_; val_ &= (NumType)num) }
   561         { EVO_TMP_ATOMIC_OP(val = val_; val_ |= (NumType)num) }
   564         { EVO_TMP_ATOMIC_OP(val = val_; val_ ^= (NumType)num) }
   567         { EVO_TMP_ATOMIC_OP(val = ++val_) }
   570         { EVO_TMP_ATOMIC_OP(val = val_; ++val_) }
   573         { EVO_TMP_ATOMIC_OP(val = --val_) }
   576         { EVO_TMP_ATOMIC_OP(val = val_; --val_) }
   579         { EVO_TMP_ATOMIC_OP(val = val_ += (NumType)num) }
   582         { EVO_TMP_ATOMIC_OP(val = val_ -= (NumType)num) }
   585         { EVO_TMP_ATOMIC_OP(val = val_ &= (NumType)num) }
   588         { EVO_TMP_ATOMIC_OP(val = val_ |= (NumType)num) }
   591         { EVO_TMP_ATOMIC_OP(val = val_ ^= (NumType)num) }
   607         { this->store(num); }
   614         { 
return this->load(); }
   623         { 
return this->load(); }
   632         { 
return this->load(); }
   638         { 
return !this->load(); }
   645         { 
return (
this == &num || this->load() == num.
load()); }
   652         { 
return this->load() == num; }
   659         { 
return (
this != &num && this->load() != num.
load()); }
   666         { 
return this->load() != num; }
   673         { 
return this->load() < num; }
   680         { 
return this->load() <= num; }
   687         { 
return this->load() > num; }
   694         { 
return this->load() >= num; }
   697 #if !EVO_INTRINSIC_ATOMICS   703     This& operator=(
const This&);
   723 #if defined(EVO_TMP_ATOMIC_OP)   724     #undef EVO_TMP_ATOMIC_OP   727 #if defined(_MSC_VER) && !EVO_INTRINSIC_ATOMICS   766         { ptr_.store((T*)ptr); }
   778         { ptr_.store(src.
ptr_); }
   784         { ptr_.store(src.
ptr_); }
   791         { ptr_.store(src.
ptr_.
load()); 
return *
this; }
   798         { ptr_.store(src.
ptr_); 
return *
this; }
   805         { ptr_.store(src.
ptr_); 
return *
this; }
   812         { ptr_.store(ptr); 
return *
this; }
   819         { ptr_.store((T*)ptr); 
return *
this; }
   825         { ptr_.store(NULL); 
return *
this; }
   833         { 
return ptr_.exchange(NULL); }
   839     #if defined(EVO_ATOMIC_PTRMATH)   842         return ptr_ += (T*)
sizeof(T);
   850     #if defined(EVO_ATOMIC_PTRMATH)   853         return ptr_.fetch_add((T*)
sizeof(T));
   862     #if defined(EVO_STD_ATOMIC)   864     #elif defined(EVO_ATOMIC_PTRMATH)   867         ptr_ += (T*)(count * 
sizeof(T));
   876     #if defined(EVO_ATOMIC_PTRMATH)   879         return ptr_ -= (T*)
sizeof(T);
   887     #if defined(EVO_ATOMIC_PTRMATH)   890         return ptr_.fetch_sub((T*)
sizeof(T));
   899     #if defined(EVO_STD_ATOMIC)   901     #elif defined(EVO_ATOMIC_PTRMATH)   904         ptr_ -= (T*)(count * 
sizeof(T));
   909     using Base::operator==;
   910     using Base::operator!=;
   911     using Base::operator<;
   912     using Base::operator<=;
   913     using Base::operator>;
   914     using Base::operator>=;
   921         { 
return ptr_.load() == ptr.
ptr_; }
   928         { 
return ptr_.load() != ptr.
ptr_; }
   935         { 
return ptr_.load() < ptr.
ptr_; }
   942         { 
return ptr_.load() <= ptr.
ptr_; }
   949         { 
return ptr_.load() > ptr.
ptr_; }
   956         { 
return ptr_.load() >= ptr.
ptr_; }
   992         { ptr_.store((T*)ptr); }
  1004         { ptr_.store(src.
ptr_); }
  1010         { ptr_.store(src.
ptr_); }
  1017         { ptr_.store(src.
ptr_.
load()); 
return *
this; }
  1024         { ptr_.store(src.
ptr_); 
return *
this; }
  1031         { ptr_.store(src.
ptr_); 
return *
this; }
  1038         { ptr_.store(ptr); 
return *
this; }
  1045         { ptr_.store((T*)ptr); 
return *
this; }
  1051         { ptr_.store(NULL); 
return *
this; }
  1059         { 
return ptr_.exchange(NULL); }
  1065     #if defined(EVO_ATOMIC_PTRMATH)  1068         return ptr_ += (T*)
sizeof(T);
  1076     #if defined(EVO_ATOMIC_PTRMATH)  1079         return ptr_.fetch_add((T*)
sizeof(T));
  1088     #if defined(EVO_STD_ATOMIC)  1090     #elif defined(EVO_ATOMIC_PTRMATH)  1093         ptr_ += (T*)(count * 
sizeof(T));
  1102     #if defined(EVO_ATOMIC_PTRMATH)  1105         return ptr_ -= (T*)
sizeof(T);
  1113     #if defined(EVO_ATOMIC_PTRMATH)  1116         return ptr_.fetch_sub((T*)
sizeof(T));
  1125     #if defined(EVO_STD_ATOMIC)  1127     #elif defined(EVO_ATOMIC_PTRMATH)  1130         ptr_ -= (T*)(count * 
sizeof(T));
  1135     using Base::operator==;
  1136     using Base::operator!=;
  1137     using Base::operator<;
  1138     using Base::operator<=;
  1139     using Base::operator>;
  1140     using Base::operator>=;
  1147         { 
return ptr_.load() == ptr.
ptr_; }
  1154         { 
return ptr_.load() != ptr.
ptr_; }
  1161         { 
return ptr_.load() < ptr.
ptr_; }
  1168         { 
return ptr_.load() <= ptr.
ptr_; }
  1175         { 
return ptr_.load() > ptr.
ptr_; }
  1182         { 
return ptr_.load() >= ptr.
ptr_; }
  1194     { 
return ptr1.
ptr_ == ptr2.ptr_.load(); }
  1203     { 
return ptr1.
ptr_ != ptr2.ptr_.load(); }
  1212     { 
return ptr1.
ptr_ < ptr2.ptr_.load(); }
  1221     { 
return ptr1.
ptr_ <= ptr2.ptr_.load(); }
  1230     { 
return ptr1.
ptr_ > ptr2.ptr_.load(); }
  1239     { 
return ptr1.
ptr_ >= ptr2.ptr_.load(); }
 bool operator>=(T num) const
Compare whether current value is greater than or equal to number. 
Definition: atomic.h:693
 
bool operator<(T num) const
Compare whether current value is less than number. 
Definition: atomic.h:672
 
AtomicPtr(const Base &src)
Copy constructor to reference pointer. 
Definition: atomic.h:777
 
AtomicPtr(T *ptr)
Constructor. 
Definition: atomic.h:759
 
AtomicPtr< T > This
This type. 
Definition: atomic.h:748
 
Atomic< long > AtomicLong
Atomic signed long. 
Definition: atomic.h:710
 
T * operator--(int)
Postfix decrement operator. 
Definition: atomic.h:886
 
AtomicPtr(const T *ptr)
Constructor. 
Definition: atomic.h:765
 
Atomic()
Constructor, initializes with 0. 
Definition: atomic.h:600
 
This & operator=(T num)
Store new value. 
Definition: atomic.h:319
 
Atomic signalling flag. 
Definition: atomic.h:172
 
Atomic integer type. 
Definition: atomic.h:311
 
#define EVO_ATOMIC_SYNC
Full sync (sequentially consistent) memory barrier. 
Definition: atomic.h:36
 
This & operator=(const This &src)
Copy/Assignment operator. 
Definition: atomic.h:790
 
bool test_and_set(MemOrder mem_order=std::memory_order_seq_cst)
Atomically set flag (to true) and return the previous value. 
 
PtrBase< T, Atomic< T * > > Base
Base type. 
Definition: atomic.h:749
 
Static conditional type. 
Definition: meta.h:134
 
T * operator++(int)
Prefix increment operator. 
Definition: atomic.h:849
 
Atomic< ulongl > AtomicULongL
Atomic unsigned long long. 
Definition: atomic.h:713
 
This & operator=(const T *ptr)
Assignment operator for raw pointer. 
Definition: atomic.h:818
 
Definition: systhread.h:165
 
T * operator--()
Prefix decrement operator. 
Definition: atomic.h:875
 
Atomic< int32 > AtomicInt32
Atomic 32-bit signed int. 
Definition: atomic.h:715
 
This & operator-=(int count)
Decrement by count operator. 
Definition: atomic.h:898
 
Evo implementation detail for system portability – this is included by most Evo headers, include this via: include <evo/type.h>. 
 
bool operator!() const
Negation operator checks if NULL/false (0). 
Definition: atomic.h:637
 
Atomic dumb pointer to single object. 
Definition: atomic.h:743
 
PtrBase< T > PtrBaseT
Managed pointer base type. 
Definition: atomic.h:750
 
bool operator!=(T num) const
Compare whether current value is not equal to number. 
Definition: atomic.h:665
 
bool operator==(const PtrBaseT &ptr) const
Equality operator. 
Definition: atomic.h:920
 
bool operator>=(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Greater-than-or-equals operator for managed pointer base and atomic pointer base. ...
Definition: atomic.h:1238
 
AtomicFlag()
Definition: atomic.h:174
 
#define EVO_ATOMIC_FENCE(MEM_ORDER)
Sets a memory fence/barrier. 
Definition: atomic.h:52
 
Evo system threads implementation. 
 
const T operator->() const
Member access operator (const). 
Definition: atomic.h:622
 
Atomic< int64 > AtomicInt64
Atomic 64-bit signed int. 
Definition: atomic.h:717
 
bool operator>=(const PtrBaseT &ptr) const
Greater-than-or-equals operator. 
Definition: atomic.h:955
 
bool operator>(T num) const
Compare whether current value is greater than number. 
Definition: atomic.h:686
 
This & operator=(T *ptr)
Assignment operator for raw pointer. 
Definition: atomic.h:811
 
AtomicPtr< T[]> This
This type. 
Definition: atomic.h:974
 
void clear(MemOrder mem_order=std::memory_order_seq_cst)
Clear flag (set to false). 
 
bool operator!=(const This &num) const
Compare whether current value is not equal to number. 
Definition: atomic.h:658
 
bool compare_set(T cmpval, T newval, MemOrder mem_order_success=std::memory_order_seq_cst, MemOrder mem_order_failure=std::memory_order_acquire)
Compare and set, storing new value if comparison matches. 
Definition: atomic.h:332
 
Safe bool base class. 
Definition: type.h:73
 
bool operator==(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Equality operator for managed pointer base and atomic pointer base. 
Definition: atomic.h:1193
 
This & clear()
Clear pointer, setting as null. 
Definition: atomic.h:824
 
void sleeplock(ulong ms=1)
Spin-lock flag with a sleep. 
Definition: atomic.h:247
 
Atomic dumb pointer to array. 
Definition: atomic.h:969
 
AtomicPtr(const PtrBaseT &src)
Copy constructor to reference pointer. 
Definition: atomic.h:783
 
bool operator!=(const PtrBaseT &ptr) const
Inequality operator. 
Definition: atomic.h:927
 
#define EVO_ATOMIC_ACQUIRE
Start "acquire" memory ordering barrier, usually followed by a matching "release" barrier...
Definition: atomic.h:27
 
bool operator<=(const PtrBaseT &ptr) const
Less-than-or-equals operator. 
Definition: atomic.h:941
 
bool operator==(T num) const
Compare whether current value is equal to number. 
Definition: atomic.h:651
 
T * detach()
Detach and return pointer. 
Definition: atomic.h:832
 
bool operator!=(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Inequality operator for managed pointer base and atomic pointer base. 
Definition: atomic.h:1202
 
bool operator>(const PtrBaseT &ptr) const
Greater-than operator. 
Definition: atomic.h:948
 
Atomic< T > This
This type. 
Definition: atomic.h:313
 
Atomic< int > AtomicInt
Atomic signed int. 
Definition: atomic.h:708
 
AtomicPtr()
Default constructor sets as NULL. 
Definition: atomic.h:753
 
void lock()
Spin-lock flag. 
Definition: atomic.h:234
 
Evo C++ Library namespace. 
Definition: alg.h:11
 
#define EVO_ATOMIC_RELEASE
Release (end) memory ordering barrier started with "consume" or "acquire" barrier. 
Definition: atomic.h:30
 
std::memory_order MemOrder
Atomic memory order (fence) type. 
Definition: atomic.h:153
 
Atomic< ulong > AtomicULong
Atomic unsigned long. 
Definition: atomic.h:711
 
Atomic(T num)
Constructor. 
Definition: atomic.h:606
 
Atomic< uint32 > AtomicUInt32
Atomic 32-bit unsigned int. 
Definition: atomic.h:716
 
void unlock()
Spin-unlock flag. 
Definition: atomic.h:256
 
bool sleepms(ulong msec)
Sleep for number of milliseconds. 
Definition: sys.h:654
 
P ptr_
Pointer. 
Definition: type.h:1566
 
T operator->()
Member access operator. 
Definition: atomic.h:631
 
Atomic< longl > AtomicLongL
Atomic signed long long. 
Definition: atomic.h:712
 
This & operator=(const Base &src)
Assignment operator to reference pointer. 
Definition: atomic.h:797
 
T * operator++()
Prefix increment operator. 
Definition: atomic.h:838
 
bool operator>(const PtrBase< T > &ptr1, const PtrBase< T, Atomic< T *> > &ptr2)
Greater-than operator for managed pointer base and atomic pointer base. 
Definition: atomic.h:1229
 
Base managed pointer. 
Definition: type.h:1562
 
bool operator==(const This &num) const
Compare whether current value is equal to number. 
Definition: atomic.h:644
 
bool operator<(const PtrBaseT &ptr) const
Less-than operator. 
Definition: atomic.h:934
 
T load(MemOrder mem_order=std::memory_order_seq_cst) const
Load and return current value. 
 
Atomic< uint > AtomicUInt
Atomic unsigned int. 
Definition: atomic.h:709
 
This & operator+=(int count)
Increment by count operator. 
Definition: atomic.h:861
 
bool operator<=(T num) const
Compare whether current value is less than or equal to number. 
Definition: atomic.h:679
 
AtomicPtr(const This &src)
Copy constructor. 
Definition: atomic.h:771
 
Evo basic types and traits. 
 
This & operator=(const PtrBaseT &src)
Assignment operator to reference pointer. 
Definition: atomic.h:804
 
Atomic< uint64 > AtomicUInt64
Atomic 64-bit unsigned int. 
Definition: atomic.h:718