1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: libcpp-has-no-threads
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);
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;
52 // typedef atomic<bool> atomic_bool;
58 #include <cmpxchg_loop.h>
60 #include "test_macros.h"
65 volatile std::atomic<bool> obj(true);
67 std::atomic_init(&obj, false);
69 std::atomic_init(&obj, true);
71 bool b0 = obj.is_lock_free();
72 (void)b0; // to placate scan-build
75 obj.store(true, std::memory_order_release);
77 assert(obj.load() == true);
78 assert(obj.load(std::memory_order_acquire) == true);
79 assert(obj.exchange(false) == true);
81 assert(obj.exchange(true, std::memory_order_relaxed) == false);
84 assert(cmpxchg_weak_loop(obj, x, false) == true);
87 assert(obj.compare_exchange_weak(x, true,
88 std::memory_order_seq_cst) == false);
93 assert(cmpxchg_weak_loop(obj, x, false,
94 std::memory_order_seq_cst,
95 std::memory_order_seq_cst) == true);
100 assert(obj.compare_exchange_strong(x, false) == true);
101 assert(obj == false);
103 assert(obj.compare_exchange_strong(x, true,
104 std::memory_order_seq_cst) == false);
105 assert(obj == false);
109 assert(obj.compare_exchange_strong(x, false,
110 std::memory_order_seq_cst,
111 std::memory_order_seq_cst) == true);
112 assert(obj == false);
114 assert((obj = false) == false);
115 assert(obj == false);
116 assert((obj = true) == true);
120 std::atomic<bool> obj(true);
122 std::atomic_init(&obj, false);
123 assert(obj == false);
124 std::atomic_init(&obj, true);
126 bool b0 = obj.is_lock_free();
127 (void)b0; // to placate scan-build
129 assert(obj == false);
130 obj.store(true, std::memory_order_release);
132 assert(obj.load() == true);
133 assert(obj.load(std::memory_order_acquire) == true);
134 assert(obj.exchange(false) == true);
135 assert(obj == false);
136 assert(obj.exchange(true, std::memory_order_relaxed) == false);
139 assert(cmpxchg_weak_loop(obj, x, false) == true);
140 assert(obj == false);
142 assert(obj.compare_exchange_weak(x, true,
143 std::memory_order_seq_cst) == false);
144 assert(obj == false);
148 assert(cmpxchg_weak_loop(obj, x, false,
149 std::memory_order_seq_cst,
150 std::memory_order_seq_cst) == true);
151 assert(obj == false);
155 assert(obj.compare_exchange_strong(x, false) == true);
156 assert(obj == false);
158 assert(obj.compare_exchange_strong(x, true,
159 std::memory_order_seq_cst) == false);
160 assert(obj == false);
164 assert(obj.compare_exchange_strong(x, false,
165 std::memory_order_seq_cst,
166 std::memory_order_seq_cst) == true);
167 assert(obj == false);
169 assert((obj = false) == false);
170 assert(obj == false);
171 assert((obj = true) == true);
175 std::atomic_bool obj(true);
177 std::atomic_init(&obj, false);
178 assert(obj == false);
179 std::atomic_init(&obj, true);
181 bool b0 = obj.is_lock_free();
182 (void)b0; // to placate scan-build
184 assert(obj == false);
185 obj.store(true, std::memory_order_release);
187 assert(obj.load() == true);
188 assert(obj.load(std::memory_order_acquire) == true);
189 assert(obj.exchange(false) == true);
190 assert(obj == false);
191 assert(obj.exchange(true, std::memory_order_relaxed) == false);
194 assert(cmpxchg_weak_loop(obj, x, false) == true);
195 assert(obj == false);
197 assert(obj.compare_exchange_weak(x, true,
198 std::memory_order_seq_cst) == false);
199 assert(obj == false);
203 assert(cmpxchg_weak_loop(obj, x, false,
204 std::memory_order_seq_cst,
205 std::memory_order_seq_cst) == true);
206 assert(obj == false);
210 assert(obj.compare_exchange_strong(x, false) == true);
211 assert(obj == false);
213 assert(obj.compare_exchange_strong(x, true,
214 std::memory_order_seq_cst) == false);
215 assert(obj == false);
219 assert(obj.compare_exchange_strong(x, false,
220 std::memory_order_seq_cst,
221 std::memory_order_seq_cst) == true);
222 assert(obj == false);
224 assert((obj = false) == false);
225 assert(obj == false);
226 assert((obj = true) == true);
230 typedef std::atomic<bool> A;
231 TEST_ALIGNAS_TYPE(A) char storage[sizeof(A)] = {1};
232 A& zero = *new (storage) A();
233 assert(zero == false);