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