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
main()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