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