]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/29_atomics/atomic_ref/float.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / 29_atomics / atomic_ref / float.cc
1 // Copyright (C) 2019-2024 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // { dg-do run { target c++20 } }
19
20 #include <atomic>
21 #include <testsuite_hooks.h>
22
23 void
24 test01()
25 {
26 float value;
27 if constexpr (std::atomic_ref<float>::is_always_lock_free)
28 {
29 const auto mo = std::memory_order_relaxed;
30 std::atomic_ref<float> a(value);
31 bool ok = a.is_lock_free();
32 if constexpr (std::atomic_ref<float>::is_always_lock_free)
33 VERIFY( ok );
34 a = 1.6f;
35 VERIFY( a.load() == 1.6f );
36 a.store(0.8f);
37 VERIFY( a.load(mo) == 0.8f );
38 a.store(3.2f, mo);
39 VERIFY( a.load() == 3.2f );
40 auto v = a.exchange(6.4f);
41 VERIFY( a == 6.4f );
42 VERIFY( v == 3.2f );
43 v = a.exchange(1.28f, mo);
44 VERIFY( a == 1.28f );
45 VERIFY( v == 6.4f );
46
47 auto expected = a.load();
48 while (!a.compare_exchange_weak(expected, 25.6f, mo, mo))
49 { /* weak form can fail spuriously */ }
50 VERIFY( a.load() == 25.6f );
51 VERIFY( expected == 1.28f );
52 expected = 3.2f;
53 ok = a.compare_exchange_weak(expected, 51.2f, mo, mo);
54 VERIFY( !ok && a.load() == 25.6f && expected == 25.6f );
55 ok = a.compare_exchange_strong(expected, 51.2f, mo, mo);
56 VERIFY( ok && a.load() == 51.2f && expected == 25.6f );
57 expected = 0.0f;
58 ok = a.compare_exchange_strong(expected, 1.28f, mo, mo);
59 VERIFY( !ok && a.load() == 51.2f && expected == 51.2f );
60
61 while (!a.compare_exchange_weak(expected, 25.6f))
62 { /* weak form can fail spuriously */ }
63 VERIFY( a.load() == 25.6f && expected == 51.2f );
64 expected = a.load();
65 while (!a.compare_exchange_weak(expected, 10.24f, mo))
66 { /* weak form can fail spuriously */ }
67 VERIFY( a.load() == 10.24f && expected == 25.6f );
68 expected = a.load() + 1;
69 ok = a.compare_exchange_weak(expected, 40.96f);
70 VERIFY( !ok && a.load() == 10.24f && expected == 10.24f );
71 expected = a.load() + 1;
72 ok = a.compare_exchange_weak(expected, 40.96f, mo);
73 VERIFY( !ok && a.load() == 10.24f && expected == 10.24f );
74
75 ok = a.compare_exchange_strong(expected, 1.024f);
76 VERIFY( ok && a.load() == 1.024f && expected == 10.24f );
77 expected = a.load();
78 ok = a.compare_exchange_strong(expected, 204.8f, mo);
79 VERIFY( ok && a.load() == 204.8f && expected == 1.024f );
80 expected = a.load() + 1;
81 ok = a.compare_exchange_strong(expected, 6.4f);
82 VERIFY( !ok && a.load() == 204.8f && expected == 204.8f );
83 expected = a.load() + 1;
84 ok = a.compare_exchange_strong(expected, 6.4f, mo);
85 VERIFY( !ok && a.load() == 204.8f && expected == 204.8f );
86
87 v = a.fetch_add(3.2f);
88 VERIFY( v == 204.8f );
89 VERIFY( a == 208.0f );
90 v = a.fetch_add(-8.5f, mo);
91 VERIFY( v == 208.0f );
92 VERIFY( a == 199.5f );
93
94 v = a.fetch_sub(109.5f);
95 VERIFY( v == 199.5f );
96 VERIFY( a == 90.0f );
97 v = a.fetch_sub(2, mo);
98 VERIFY( v == 90.0f );
99 VERIFY( a == 88.0f );
100
101 v = a += 5.0f;
102 VERIFY( v == 93.0f );
103 VERIFY( a == 93.0f );
104
105 v = a -= 6.5f;
106 VERIFY( v == 86.5f );
107 VERIFY( a == 86.5f );
108 }
109
110 if constexpr (std::atomic_ref<float>::is_always_lock_free)
111 VERIFY( value == 86.5f );
112 }
113
114 void
115 test02()
116 {
117 double value;
118 if constexpr (std::atomic_ref<double>::is_always_lock_free)
119 {
120 const auto mo = std::memory_order_relaxed;
121 std::atomic_ref<double> a(value);
122 bool ok = a.is_lock_free();
123 if constexpr (std::atomic_ref<double>::is_always_lock_free)
124 VERIFY( ok );
125 a = 1.6;
126 VERIFY( a.load() == 1.6 );
127 a.store(0.8);
128 VERIFY( a.load(mo) == 0.8 );
129 a.store(3.2, mo);
130 VERIFY( a.load() == 3.2 );
131 auto v = a.exchange(6.4);
132 VERIFY( a == 6.4 );
133 VERIFY( v == 3.2 );
134 v = a.exchange(1.28, mo);
135 VERIFY( a == 1.28 );
136 VERIFY( v == 6.4 );
137
138 auto expected = a.load();
139 while (!a.compare_exchange_weak(expected, 25.6, mo, mo))
140 { /* weak form can fail spuriously */ }
141 VERIFY( a.load() == 25.6 );
142 VERIFY( expected == 1.28 );
143 expected = 3.2;
144 ok = a.compare_exchange_weak(expected, 51.2, mo, mo);
145 VERIFY( !ok && a.load() == 25.6 && expected == 25.6 );
146 ok = a.compare_exchange_strong(expected, 51.2, mo, mo);
147 VERIFY( ok && a.load() == 51.2 && expected == 25.6 );
148 expected = 0.0;
149 ok = a.compare_exchange_strong(expected, 1.28, mo, mo);
150 VERIFY( !ok && a.load() == 51.2 && expected == 51.2 );
151
152 while (!a.compare_exchange_weak(expected, 25.6))
153 { /* weak form can fail spuriously */ }
154 VERIFY( a.load() == 25.6 && expected == 51.2 );
155 expected = a.load();
156 while (!a.compare_exchange_weak(expected, 10.24, mo))
157 { /* weak form can fail spuriously */ }
158 VERIFY( a.load() == 10.24 && expected == 25.6 );
159 expected = a.load() + 1;
160 ok = a.compare_exchange_weak(expected, 40.96);
161 VERIFY( !ok && a.load() == 10.24 && expected == 10.24 );
162 expected = a.load() + 1;
163 ok = a.compare_exchange_weak(expected, 40.96, mo);
164 VERIFY( !ok && a.load() == 10.24 && expected == 10.24 );
165
166 ok = a.compare_exchange_strong(expected, 1.024);
167 VERIFY( ok && a.load() == 1.024 && expected == 10.24 );
168 expected = a.load();
169 ok = a.compare_exchange_strong(expected, 204.8, mo);
170 VERIFY( ok && a.load() == 204.8 && expected == 1.024 );
171 expected = a.load() + 1;
172 ok = a.compare_exchange_strong(expected, 6.4);
173 VERIFY( !ok && a.load() == 204.8 && expected == 204.8 );
174 expected = a.load() + 1;
175 ok = a.compare_exchange_strong(expected, 6.4, mo);
176 VERIFY( !ok && a.load() == 204.8 && expected == 204.8 );
177
178 v = a.fetch_add(3.2);
179 VERIFY( v == 204.8 );
180 VERIFY( a == 208.0 );
181 v = a.fetch_add(-8.5, mo);
182 VERIFY( v == 208.0 );
183 VERIFY( a == 199.5 );
184
185 v = a.fetch_sub(109.5);
186 VERIFY( v == 199.5 );
187 VERIFY( a == 90.0 );
188 v = a.fetch_sub(2, mo);
189 VERIFY( v == 90.0 );
190 VERIFY( a == 88.0 );
191
192 v = a += 5.0;
193 VERIFY( v == 93.0 );
194 VERIFY( a == 93.0 );
195
196 v = a -= 6.5;
197 VERIFY( v == 86.5 );
198 VERIFY( a == 86.5 );
199 }
200
201 if constexpr (std::atomic_ref<double>::is_always_lock_free)
202 VERIFY( value == 86.5 );
203 }
204
205 void
206 test03()
207 {
208 long double value;
209 if constexpr (std::atomic_ref<long double>::is_always_lock_free)
210 {
211 const auto mo = std::memory_order_relaxed;
212 std::atomic_ref<long double> a(value);
213 bool ok = a.is_lock_free();
214 if constexpr (std::atomic_ref<long double>::is_always_lock_free)
215 VERIFY( ok );
216 a = 1.6l;
217 VERIFY( a.load() == 1.6l );
218 a.store(0.8l);
219 VERIFY( a.load(mo) == 0.8l );
220 a.store(3.2l, mo);
221 VERIFY( a.load() == 3.2l );
222 auto v = a.exchange(6.4l);
223 VERIFY( a == 6.4l );
224 VERIFY( v == 3.2l );
225 v = a.exchange(1.28l, mo);
226 VERIFY( a == 1.28l );
227 VERIFY( v == 6.4l );
228
229 auto expected = a.load();
230 while (!a.compare_exchange_weak(expected, 25.6l, mo, mo))
231 { /* weak form can fail spuriously */ }
232 VERIFY( a.load() == 25.6l );
233 VERIFY( expected == 1.28l );
234 expected = 3.2l;
235 ok = a.compare_exchange_weak(expected, 51.2l, mo, mo);
236 VERIFY( !ok && a.load() == 25.6l && expected == 25.6l );
237 ok = a.compare_exchange_strong(expected, 51.2l, mo, mo);
238 VERIFY( ok && a.load() == 51.2l && expected == 25.6l );
239 expected = 0.0l;
240 ok = a.compare_exchange_strong(expected, 1.28l, mo, mo);
241 VERIFY( !ok && a.load() == 51.2l && expected == 51.2l );
242
243 while (!a.compare_exchange_weak(expected, 25.6l))
244 { /* weak form can fail spuriously */ }
245 VERIFY( a.load() == 25.6l && expected == 51.2l );
246 expected = a.load();
247 while (!a.compare_exchange_weak(expected, 10.24l, mo))
248 { /* weak form can fail spuriously */ }
249 VERIFY( a.load() == 10.24l && expected == 25.6l );
250 expected = a.load() + 1;
251 ok = a.compare_exchange_weak(expected, 40.96l);
252 VERIFY( !ok && a.load() == 10.24l && expected == 10.24l );
253 expected = a.load() + 1;
254 ok = a.compare_exchange_weak(expected, 40.96l, mo);
255 VERIFY( !ok && a.load() == 10.24l && expected == 10.24l );
256
257 ok = a.compare_exchange_strong(expected, 1.024l);
258 VERIFY( ok && a.load() == 1.024l && expected == 10.24l );
259 expected = a.load();
260 ok = a.compare_exchange_strong(expected, 204.8l, mo);
261 VERIFY( ok && a.load() == 204.8l && expected == 1.024l );
262 expected = a.load() + 1;
263 ok = a.compare_exchange_strong(expected, 6.4l);
264 VERIFY( !ok && a.load() == 204.8l && expected == 204.8l );
265 expected = a.load() + 1;
266 ok = a.compare_exchange_strong(expected, 6.4l, mo);
267 VERIFY( !ok && a.load() == 204.8l && expected == 204.8l );
268
269 a = 0.5l;
270 v = a.fetch_add(0.5l);
271 VERIFY( v == 0.5l );
272 VERIFY( a == 1.0l );
273 v = a.fetch_add(-0.2l, mo);
274 VERIFY( v == 1.0l );
275 VERIFY( a == 0.8l );
276
277 v = a.fetch_sub(0.4l);
278 VERIFY( v == 0.8l );
279 VERIFY( a == 0.4l );
280 v = a.fetch_sub(-0.4l, mo);
281 VERIFY( v == 0.4l );
282 VERIFY( a == 0.8l );
283
284 v = a += .8l;
285 VERIFY( v == 1.6l );
286 VERIFY( a == 1.6l );
287
288 v = a -= 0.6l;
289 VERIFY( v == 1.0l );
290 VERIFY( a == 1.0l );
291 }
292
293 if constexpr (std::atomic_ref<long double>::is_always_lock_free)
294 VERIFY( value == 1.0l );
295 }
296
297 void
298 test04()
299 {
300 if constexpr (std::atomic_ref<float>::is_always_lock_free)
301 {
302 float i = 0;
303 float* ptr = 0;
304 std::atomic_ref<float*> a0(ptr);
305 std::atomic_ref<float*> a1(ptr);
306 std::atomic_ref<float*> a2(a0);
307 a0 = &i;
308 VERIFY( a1 == &i );
309 VERIFY( a2 == &i );
310 }
311 }
312
313 int
314 main()
315 {
316 test01();
317 test02();
318 test03();
319 test04();
320 }