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