1 2 #ifndef __has_builtin 3 # define __has_builtin(x) 0 4 #endif 5 #ifndef __has_feature 6 # define __has_feature(x) 0 7 #endif 8 #ifndef __has_extension 9 # define __has_extension(x) 0 10 #endif 11 12 #if !__has_extension(c_atomic) 13 # define _Atomic(T) T 14 #endif 15 #if __has_builtin(__c11_atomic_exchange) 16 # define ATOMIC_BUILTIN(name) __c11_atomic_##name 17 #else 18 # define ATOMIC_BUILTIN(name) __atomic_##name##_n 19 #endif 20 21 namespace 22 { 23 /** 24 * C++11 memory orders. We only need a subset of them. 25 */ 26 enum memory_order 27 { 28 /** 29 * Acquire order. 30 */ 31 acquire = __ATOMIC_ACQUIRE, 32 33 /** 34 * Release order. 35 */ 36 release = __ATOMIC_RELEASE, 37 38 /** 39 * Sequentially consistent memory ordering. 40 */ 41 seqcst = __ATOMIC_SEQ_CST 42 }; 43 44 /** 45 * Atomic, implements a subset of `std::atomic`. 46 */ 47 template<typename T> 48 class atomic 49 { 50 /** 51 * The underlying value. Use C11 atomic qualification if available. 52 */ 53 _Atomic(T) val; 54 55 public: 56 /** 57 * Constructor, takes a value. 58 */ 59 constexpr atomic(T init) : val(init) {} 60 61 /** 62 * Atomically load with the specified memory order. 63 */ 64 T load(memory_order order = memory_order::seqcst) 65 { 66 return ATOMIC_BUILTIN(load)(&val, order); 67 } 68 69 /** 70 * Atomically store with the specified memory order. 71 */ 72 void store(T v, memory_order order = memory_order::seqcst) 73 { 74 return ATOMIC_BUILTIN(store)(&val, v, order); 75 } 76 77 /** 78 * Atomically exchange with the specified memory order. 79 */ 80 T exchange(T v, memory_order order = memory_order::seqcst) 81 { 82 return ATOMIC_BUILTIN(exchange)(&val, v, order); 83 } 84 85 /** 86 * Atomically exchange with the specified memory order. 87 */ 88 bool compare_exchange(T & expected, 89 T desired, 90 memory_order order = memory_order::seqcst) 91 { 92 #if __has_builtin(__c11_atomic_compare_exchange_strong) 93 return __c11_atomic_compare_exchange_strong( 94 &val, &expected, desired, order, order); 95 #else 96 return __atomic_compare_exchange_n( 97 &val, &expected, desired, true, order, order); 98 #endif 99 } 100 }; 101 } // namespace 102 #undef ATOMIC_BUILTIN 103