1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // <atomic> 11 12 // template <class T> 13 // struct atomic 14 // { 15 // bool is_lock_free() const volatile; 16 // bool is_lock_free() const; 17 // void store(T desr, memory_order m = memory_order_seq_cst) volatile; 18 // void store(T desr, memory_order m = memory_order_seq_cst); 19 // T load(memory_order m = memory_order_seq_cst) const volatile; 20 // T load(memory_order m = memory_order_seq_cst) const; 21 // operator T() const volatile; 22 // operator T() const; 23 // T exchange(T desr, memory_order m = memory_order_seq_cst) volatile; 24 // T exchange(T desr, memory_order m = memory_order_seq_cst); 25 // bool compare_exchange_weak(T& expc, T desr, 26 // memory_order s, memory_order f) volatile; 27 // bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f); 28 // bool compare_exchange_strong(T& expc, T desr, 29 // memory_order s, memory_order f) volatile; 30 // bool compare_exchange_strong(T& expc, T desr, 31 // memory_order s, memory_order f); 32 // bool compare_exchange_weak(T& expc, T desr, 33 // memory_order m = memory_order_seq_cst) volatile; 34 // bool compare_exchange_weak(T& expc, T desr, 35 // memory_order m = memory_order_seq_cst); 36 // bool compare_exchange_strong(T& expc, T desr, 37 // memory_order m = memory_order_seq_cst) volatile; 38 // bool compare_exchange_strong(T& expc, T desr, 39 // memory_order m = memory_order_seq_cst); 40 // 41 // atomic() = default; 42 // constexpr atomic(T desr); 43 // atomic(const atomic&) = delete; 44 // atomic& operator=(const atomic&) = delete; 45 // atomic& operator=(const atomic&) volatile = delete; 46 // T operator=(T) volatile; 47 // T operator=(T); 48 // }; 49 // 50 // typedef atomic<bool> atomic_bool; 51 52 #include <atomic> 53 #include <new> 54 #include <cassert> 55 56 int main() 57 { 58 { 59 volatile std::atomic<bool> _; 60 volatile std::atomic<bool> obj(true); 61 assert(obj == true); 62 std::atomic_init(&obj, false); 63 assert(obj == false); 64 std::atomic_init(&obj, true); 65 assert(obj == true); 66 bool b0 = obj.is_lock_free(); 67 obj.store(false); 68 assert(obj == false); 69 obj.store(true, std::memory_order_release); 70 assert(obj == true); 71 assert(obj.load() == true); 72 assert(obj.load(std::memory_order_acquire) == true); 73 assert(obj.exchange(false) == true); 74 assert(obj == false); 75 assert(obj.exchange(true, std::memory_order_relaxed) == false); 76 assert(obj == true); 77 bool x = obj; 78 assert(obj.compare_exchange_weak(x, false) == true); 79 assert(obj == false); 80 assert(x == true); 81 assert(obj.compare_exchange_weak(x, true, 82 std::memory_order_seq_cst) == false); 83 assert(obj == false); 84 assert(x == false); 85 obj.store(true); 86 x = true; 87 assert(obj.compare_exchange_weak(x, false, 88 std::memory_order_seq_cst, 89 std::memory_order_seq_cst) == true); 90 assert(obj == false); 91 assert(x == true); 92 x = true; 93 obj.store(true); 94 assert(obj.compare_exchange_strong(x, false) == true); 95 assert(obj == false); 96 assert(x == true); 97 assert(obj.compare_exchange_strong(x, true, 98 std::memory_order_seq_cst) == false); 99 assert(obj == false); 100 assert(x == false); 101 x = true; 102 obj.store(true); 103 assert(obj.compare_exchange_strong(x, false, 104 std::memory_order_seq_cst, 105 std::memory_order_seq_cst) == true); 106 assert(obj == false); 107 assert(x == true); 108 assert((obj = false) == false); 109 assert(obj == false); 110 assert((obj = true) == true); 111 assert(obj == true); 112 } 113 { 114 std::atomic<bool> _; 115 std::atomic<bool> obj(true); 116 assert(obj == true); 117 std::atomic_init(&obj, false); 118 assert(obj == false); 119 std::atomic_init(&obj, true); 120 assert(obj == true); 121 bool b0 = obj.is_lock_free(); 122 obj.store(false); 123 assert(obj == false); 124 obj.store(true, std::memory_order_release); 125 assert(obj == true); 126 assert(obj.load() == true); 127 assert(obj.load(std::memory_order_acquire) == true); 128 assert(obj.exchange(false) == true); 129 assert(obj == false); 130 assert(obj.exchange(true, std::memory_order_relaxed) == false); 131 assert(obj == true); 132 bool x = obj; 133 assert(obj.compare_exchange_weak(x, false) == true); 134 assert(obj == false); 135 assert(x == true); 136 assert(obj.compare_exchange_weak(x, true, 137 std::memory_order_seq_cst) == false); 138 assert(obj == false); 139 assert(x == false); 140 obj.store(true); 141 x = true; 142 assert(obj.compare_exchange_weak(x, false, 143 std::memory_order_seq_cst, 144 std::memory_order_seq_cst) == true); 145 assert(obj == false); 146 assert(x == true); 147 x = true; 148 obj.store(true); 149 assert(obj.compare_exchange_strong(x, false) == true); 150 assert(obj == false); 151 assert(x == true); 152 assert(obj.compare_exchange_strong(x, true, 153 std::memory_order_seq_cst) == false); 154 assert(obj == false); 155 assert(x == false); 156 x = true; 157 obj.store(true); 158 assert(obj.compare_exchange_strong(x, false, 159 std::memory_order_seq_cst, 160 std::memory_order_seq_cst) == true); 161 assert(obj == false); 162 assert(x == true); 163 assert((obj = false) == false); 164 assert(obj == false); 165 assert((obj = true) == true); 166 assert(obj == true); 167 } 168 { 169 std::atomic_bool _; 170 std::atomic_bool obj(true); 171 assert(obj == true); 172 std::atomic_init(&obj, false); 173 assert(obj == false); 174 std::atomic_init(&obj, true); 175 assert(obj == true); 176 bool b0 = obj.is_lock_free(); 177 obj.store(false); 178 assert(obj == false); 179 obj.store(true, std::memory_order_release); 180 assert(obj == true); 181 assert(obj.load() == true); 182 assert(obj.load(std::memory_order_acquire) == true); 183 assert(obj.exchange(false) == true); 184 assert(obj == false); 185 assert(obj.exchange(true, std::memory_order_relaxed) == false); 186 assert(obj == true); 187 bool x = obj; 188 assert(obj.compare_exchange_weak(x, false) == true); 189 assert(obj == false); 190 assert(x == true); 191 assert(obj.compare_exchange_weak(x, true, 192 std::memory_order_seq_cst) == false); 193 assert(obj == false); 194 assert(x == false); 195 obj.store(true); 196 x = true; 197 assert(obj.compare_exchange_weak(x, false, 198 std::memory_order_seq_cst, 199 std::memory_order_seq_cst) == true); 200 assert(obj == false); 201 assert(x == true); 202 x = true; 203 obj.store(true); 204 assert(obj.compare_exchange_strong(x, false) == true); 205 assert(obj == false); 206 assert(x == true); 207 assert(obj.compare_exchange_strong(x, true, 208 std::memory_order_seq_cst) == false); 209 assert(obj == false); 210 assert(x == false); 211 x = true; 212 obj.store(true); 213 assert(obj.compare_exchange_strong(x, false, 214 std::memory_order_seq_cst, 215 std::memory_order_seq_cst) == true); 216 assert(obj == false); 217 assert(x == true); 218 assert((obj = false) == false); 219 assert(obj == false); 220 assert((obj = true) == true); 221 assert(obj == true); 222 } 223 { 224 typedef std::atomic<bool> A; 225 _ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1}; 226 A& zero = *new (storage) A(); 227 assert(zero == false); 228 zero.~A(); 229 } 230 } 231