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