1 /* Tests for atomic.h macros.
2    Copyright (C) 2003-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <stdio.h>
20 #include <atomic.h>
21 
22 #ifndef atomic_t
23 # define atomic_t int
24 #endif
25 
26 /* Test various atomic.h macros.  */
27 static int
do_test(void)28 do_test (void)
29 {
30   atomic_t mem, expected;
31   int ret = 0;
32 
33 #ifdef atomic_compare_and_exchange_val_acq
34   mem = 24;
35   if (atomic_compare_and_exchange_val_acq (&mem, 35, 24) != 24
36       || mem != 35)
37     {
38       puts ("atomic_compare_and_exchange_val_acq test 1 failed");
39       ret = 1;
40     }
41 
42   mem = 12;
43   if (atomic_compare_and_exchange_val_acq (&mem, 10, 15) != 12
44       || mem != 12)
45     {
46       puts ("atomic_compare_and_exchange_val_acq test 2 failed");
47       ret = 1;
48     }
49 
50   mem = -15;
51   if (atomic_compare_and_exchange_val_acq (&mem, -56, -15) != -15
52       || mem != -56)
53     {
54       puts ("atomic_compare_and_exchange_val_acq test 3 failed");
55       ret = 1;
56     }
57 
58   mem = -1;
59   if (atomic_compare_and_exchange_val_acq (&mem, 17, 0) != -1
60       || mem != -1)
61     {
62       puts ("atomic_compare_and_exchange_val_acq test 4 failed");
63       ret = 1;
64     }
65 #endif
66 
67   mem = 24;
68   if (atomic_compare_and_exchange_bool_acq (&mem, 35, 24)
69       || mem != 35)
70     {
71       puts ("atomic_compare_and_exchange_bool_acq test 1 failed");
72       ret = 1;
73     }
74 
75   mem = 12;
76   if (! atomic_compare_and_exchange_bool_acq (&mem, 10, 15)
77       || mem != 12)
78     {
79       puts ("atomic_compare_and_exchange_bool_acq test 2 failed");
80       ret = 1;
81     }
82 
83   mem = -15;
84   if (atomic_compare_and_exchange_bool_acq (&mem, -56, -15)
85       || mem != -56)
86     {
87       puts ("atomic_compare_and_exchange_bool_acq test 3 failed");
88       ret = 1;
89     }
90 
91   mem = -1;
92   if (! atomic_compare_and_exchange_bool_acq (&mem, 17, 0)
93       || mem != -1)
94     {
95       puts ("atomic_compare_and_exchange_bool_acq test 4 failed");
96       ret = 1;
97     }
98 
99   mem = 64;
100   if (atomic_exchange_acq (&mem, 31) != 64
101       || mem != 31)
102     {
103       puts ("atomic_exchange_acq test failed");
104       ret = 1;
105     }
106 
107   mem = 2;
108   if (atomic_exchange_and_add (&mem, 11) != 2
109       || mem != 13)
110     {
111       puts ("atomic_exchange_and_add test failed");
112       ret = 1;
113     }
114 
115   mem = 2;
116   if (atomic_exchange_and_add_acq (&mem, 11) != 2
117       || mem != 13)
118     {
119       puts ("atomic_exchange_and_add test failed");
120       ret = 1;
121     }
122 
123   mem = 2;
124   if (atomic_exchange_and_add_rel (&mem, 11) != 2
125       || mem != 13)
126     {
127       puts ("atomic_exchange_and_add test failed");
128       ret = 1;
129     }
130 
131   mem = -21;
132   atomic_add (&mem, 22);
133   if (mem != 1)
134     {
135       puts ("atomic_add test failed");
136       ret = 1;
137     }
138 
139   mem = -1;
140   atomic_increment (&mem);
141   if (mem != 0)
142     {
143       puts ("atomic_increment test failed");
144       ret = 1;
145     }
146 
147   mem = 2;
148   if (atomic_increment_val (&mem) != 3)
149     {
150       puts ("atomic_increment_val test failed");
151       ret = 1;
152     }
153 
154   mem = 0;
155   if (atomic_increment_and_test (&mem)
156       || mem != 1)
157     {
158       puts ("atomic_increment_and_test test 1 failed");
159       ret = 1;
160     }
161 
162   mem = 35;
163   if (atomic_increment_and_test (&mem)
164       || mem != 36)
165     {
166       puts ("atomic_increment_and_test test 2 failed");
167       ret = 1;
168     }
169 
170   mem = -1;
171   if (! atomic_increment_and_test (&mem)
172       || mem != 0)
173     {
174       puts ("atomic_increment_and_test test 3 failed");
175       ret = 1;
176     }
177 
178   mem = 17;
179   atomic_decrement (&mem);
180   if (mem != 16)
181     {
182       puts ("atomic_decrement test failed");
183       ret = 1;
184     }
185 
186   if (atomic_decrement_val (&mem) != 15)
187     {
188       puts ("atomic_decrement_val test failed");
189       ret = 1;
190     }
191 
192   mem = 0;
193   if (atomic_decrement_and_test (&mem)
194       || mem != -1)
195     {
196       puts ("atomic_decrement_and_test test 1 failed");
197       ret = 1;
198     }
199 
200   mem = 15;
201   if (atomic_decrement_and_test (&mem)
202       || mem != 14)
203     {
204       puts ("atomic_decrement_and_test test 2 failed");
205       ret = 1;
206     }
207 
208   mem = 1;
209   if (! atomic_decrement_and_test (&mem)
210       || mem != 0)
211     {
212       puts ("atomic_decrement_and_test test 3 failed");
213       ret = 1;
214     }
215 
216   mem = 1;
217   if (atomic_decrement_if_positive (&mem) != 1
218       || mem != 0)
219     {
220       puts ("atomic_decrement_if_positive test 1 failed");
221       ret = 1;
222     }
223 
224   mem = 0;
225   if (atomic_decrement_if_positive (&mem) != 0
226       || mem != 0)
227     {
228       puts ("atomic_decrement_if_positive test 2 failed");
229       ret = 1;
230     }
231 
232   mem = -1;
233   if (atomic_decrement_if_positive (&mem) != -1
234       || mem != -1)
235     {
236       puts ("atomic_decrement_if_positive test 3 failed");
237       ret = 1;
238     }
239 
240   mem = -12;
241   if (! atomic_add_negative (&mem, 10)
242       || mem != -2)
243     {
244       puts ("atomic_add_negative test 1 failed");
245       ret = 1;
246     }
247 
248   mem = 0;
249   if (atomic_add_negative (&mem, 100)
250       || mem != 100)
251     {
252       puts ("atomic_add_negative test 2 failed");
253       ret = 1;
254     }
255 
256   mem = 15;
257   if (atomic_add_negative (&mem, -10)
258       || mem != 5)
259     {
260       puts ("atomic_add_negative test 3 failed");
261       ret = 1;
262     }
263 
264   mem = -12;
265   if (atomic_add_negative (&mem, 14)
266       || mem != 2)
267     {
268       puts ("atomic_add_negative test 4 failed");
269       ret = 1;
270     }
271 
272   mem = 0;
273   if (! atomic_add_negative (&mem, -1)
274       || mem != -1)
275     {
276       puts ("atomic_add_negative test 5 failed");
277       ret = 1;
278     }
279 
280   mem = -31;
281   if (atomic_add_negative (&mem, 31)
282       || mem != 0)
283     {
284       puts ("atomic_add_negative test 6 failed");
285       ret = 1;
286     }
287 
288   mem = -34;
289   if (atomic_add_zero (&mem, 31)
290       || mem != -3)
291     {
292       puts ("atomic_add_zero test 1 failed");
293       ret = 1;
294     }
295 
296   mem = -36;
297   if (! atomic_add_zero (&mem, 36)
298       || mem != 0)
299     {
300       puts ("atomic_add_zero test 2 failed");
301       ret = 1;
302     }
303 
304   mem = 113;
305   if (atomic_add_zero (&mem, -13)
306       || mem != 100)
307     {
308       puts ("atomic_add_zero test 3 failed");
309       ret = 1;
310     }
311 
312   mem = -18;
313   if (atomic_add_zero (&mem, 20)
314       || mem != 2)
315     {
316       puts ("atomic_add_zero test 4 failed");
317       ret = 1;
318     }
319 
320   mem = 10;
321   if (atomic_add_zero (&mem, -20)
322       || mem != -10)
323     {
324       puts ("atomic_add_zero test 5 failed");
325       ret = 1;
326     }
327 
328   mem = 10;
329   if (! atomic_add_zero (&mem, -10)
330       || mem != 0)
331     {
332       puts ("atomic_add_zero test 6 failed");
333       ret = 1;
334     }
335 
336   mem = 0;
337   atomic_bit_set (&mem, 1);
338   if (mem != 2)
339     {
340       puts ("atomic_bit_set test 1 failed");
341       ret = 1;
342     }
343 
344   mem = 8;
345   atomic_bit_set (&mem, 3);
346   if (mem != 8)
347     {
348       puts ("atomic_bit_set test 2 failed");
349       ret = 1;
350     }
351 
352 #ifdef TEST_ATOMIC64
353   mem = 16;
354   atomic_bit_set (&mem, 35);
355   if (mem != 0x800000010LL)
356     {
357       puts ("atomic_bit_set test 3 failed");
358       ret = 1;
359     }
360 #endif
361 
362   mem = 0;
363   if (atomic_bit_test_set (&mem, 1)
364       || mem != 2)
365     {
366       puts ("atomic_bit_test_set test 1 failed");
367       ret = 1;
368     }
369 
370   mem = 8;
371   if (! atomic_bit_test_set (&mem, 3)
372       || mem != 8)
373     {
374       puts ("atomic_bit_test_set test 2 failed");
375       ret = 1;
376     }
377 
378 #ifdef TEST_ATOMIC64
379   mem = 16;
380   if (atomic_bit_test_set (&mem, 35)
381       || mem != 0x800000010LL)
382     {
383       puts ("atomic_bit_test_set test 3 failed");
384       ret = 1;
385     }
386 
387   mem = 0x100000000LL;
388   if (! atomic_bit_test_set (&mem, 32)
389       || mem != 0x100000000LL)
390     {
391       puts ("atomic_bit_test_set test 4 failed");
392       ret = 1;
393     }
394 #endif
395 
396 #ifdef catomic_compare_and_exchange_val_acq
397   mem = 24;
398   if (catomic_compare_and_exchange_val_acq (&mem, 35, 24) != 24
399       || mem != 35)
400     {
401       puts ("catomic_compare_and_exchange_val_acq test 1 failed");
402       ret = 1;
403     }
404 
405   mem = 12;
406   if (catomic_compare_and_exchange_val_acq (&mem, 10, 15) != 12
407       || mem != 12)
408     {
409       puts ("catomic_compare_and_exchange_val_acq test 2 failed");
410       ret = 1;
411     }
412 
413   mem = -15;
414   if (catomic_compare_and_exchange_val_acq (&mem, -56, -15) != -15
415       || mem != -56)
416     {
417       puts ("catomic_compare_and_exchange_val_acq test 3 failed");
418       ret = 1;
419     }
420 
421   mem = -1;
422   if (catomic_compare_and_exchange_val_acq (&mem, 17, 0) != -1
423       || mem != -1)
424     {
425       puts ("catomic_compare_and_exchange_val_acq test 4 failed");
426       ret = 1;
427     }
428 #endif
429 
430   mem = 24;
431   if (catomic_compare_and_exchange_bool_acq (&mem, 35, 24)
432       || mem != 35)
433     {
434       puts ("catomic_compare_and_exchange_bool_acq test 1 failed");
435       ret = 1;
436     }
437 
438   mem = 12;
439   if (! catomic_compare_and_exchange_bool_acq (&mem, 10, 15)
440       || mem != 12)
441     {
442       puts ("catomic_compare_and_exchange_bool_acq test 2 failed");
443       ret = 1;
444     }
445 
446   mem = -15;
447   if (catomic_compare_and_exchange_bool_acq (&mem, -56, -15)
448       || mem != -56)
449     {
450       puts ("catomic_compare_and_exchange_bool_acq test 3 failed");
451       ret = 1;
452     }
453 
454   mem = -1;
455   if (! catomic_compare_and_exchange_bool_acq (&mem, 17, 0)
456       || mem != -1)
457     {
458       puts ("catomic_compare_and_exchange_bool_acq test 4 failed");
459       ret = 1;
460     }
461 
462   mem = 2;
463   if (catomic_exchange_and_add (&mem, 11) != 2
464       || mem != 13)
465     {
466       puts ("catomic_exchange_and_add test failed");
467       ret = 1;
468     }
469 
470   mem = -21;
471   catomic_add (&mem, 22);
472   if (mem != 1)
473     {
474       puts ("catomic_add test failed");
475       ret = 1;
476     }
477 
478   mem = -1;
479   catomic_increment (&mem);
480   if (mem != 0)
481     {
482       puts ("catomic_increment test failed");
483       ret = 1;
484     }
485 
486   mem = 2;
487   if (catomic_increment_val (&mem) != 3)
488     {
489       puts ("catomic_increment_val test failed");
490       ret = 1;
491     }
492 
493   mem = 17;
494   catomic_decrement (&mem);
495   if (mem != 16)
496     {
497       puts ("catomic_decrement test failed");
498       ret = 1;
499     }
500 
501   if (catomic_decrement_val (&mem) != 15)
502     {
503       puts ("catomic_decrement_val test failed");
504       ret = 1;
505     }
506 
507   /* Tests for C11-like atomics.  */
508   mem = 11;
509   if (atomic_load_relaxed (&mem) != 11 || atomic_load_acquire (&mem) != 11)
510     {
511       puts ("atomic_load_{relaxed,acquire} test failed");
512       ret = 1;
513     }
514 
515   atomic_store_relaxed (&mem, 12);
516   if (mem != 12)
517     {
518       puts ("atomic_store_relaxed test failed");
519       ret = 1;
520     }
521   atomic_store_release (&mem, 13);
522   if (mem != 13)
523     {
524       puts ("atomic_store_release test failed");
525       ret = 1;
526     }
527 
528   mem = 14;
529   expected = 14;
530   if (!atomic_compare_exchange_weak_relaxed (&mem, &expected, 25)
531       || mem != 25 || expected != 14)
532     {
533       puts ("atomic_compare_exchange_weak_relaxed test 1 failed");
534       ret = 1;
535     }
536   if (atomic_compare_exchange_weak_relaxed (&mem, &expected, 14)
537       || mem != 25 || expected != 25)
538     {
539       puts ("atomic_compare_exchange_weak_relaxed test 2 failed");
540       ret = 1;
541     }
542   mem = 14;
543   expected = 14;
544   if (!atomic_compare_exchange_weak_acquire (&mem, &expected, 25)
545       || mem != 25 || expected != 14)
546     {
547       puts ("atomic_compare_exchange_weak_acquire test 1 failed");
548       ret = 1;
549     }
550   if (atomic_compare_exchange_weak_acquire (&mem, &expected, 14)
551       || mem != 25 || expected != 25)
552     {
553       puts ("atomic_compare_exchange_weak_acquire test 2 failed");
554       ret = 1;
555     }
556   mem = 14;
557   expected = 14;
558   if (!atomic_compare_exchange_weak_release (&mem, &expected, 25)
559       || mem != 25 || expected != 14)
560     {
561       puts ("atomic_compare_exchange_weak_release test 1 failed");
562       ret = 1;
563     }
564   if (atomic_compare_exchange_weak_release (&mem, &expected, 14)
565       || mem != 25 || expected != 25)
566     {
567       puts ("atomic_compare_exchange_weak_release test 2 failed");
568       ret = 1;
569     }
570 
571   mem = 23;
572   if (atomic_exchange_acquire (&mem, 42) != 23 || mem != 42)
573     {
574       puts ("atomic_exchange_acquire test failed");
575       ret = 1;
576     }
577   mem = 23;
578   if (atomic_exchange_release (&mem, 42) != 23 || mem != 42)
579     {
580       puts ("atomic_exchange_release test failed");
581       ret = 1;
582     }
583 
584   mem = 23;
585   if (atomic_fetch_add_relaxed (&mem, 1) != 23 || mem != 24)
586     {
587       puts ("atomic_fetch_add_relaxed test failed");
588       ret = 1;
589     }
590   mem = 23;
591   if (atomic_fetch_add_acquire (&mem, 1) != 23 || mem != 24)
592     {
593       puts ("atomic_fetch_add_acquire test failed");
594       ret = 1;
595     }
596   mem = 23;
597   if (atomic_fetch_add_release (&mem, 1) != 23 || mem != 24)
598     {
599       puts ("atomic_fetch_add_release test failed");
600       ret = 1;
601     }
602   mem = 23;
603   if (atomic_fetch_add_acq_rel (&mem, 1) != 23 || mem != 24)
604     {
605       puts ("atomic_fetch_add_acq_rel test failed");
606       ret = 1;
607     }
608 
609   mem = 3;
610   if (atomic_fetch_and_acquire (&mem, 2) != 3 || mem != 2)
611     {
612       puts ("atomic_fetch_and_acquire test failed");
613       ret = 1;
614     }
615 
616   mem = 4;
617   if (atomic_fetch_or_relaxed (&mem, 2) != 4 || mem != 6)
618     {
619       puts ("atomic_fetch_or_relaxed test failed");
620       ret = 1;
621     }
622   mem = 4;
623   if (atomic_fetch_or_acquire (&mem, 2) != 4 || mem != 6)
624     {
625       puts ("atomic_fetch_or_acquire test failed");
626       ret = 1;
627     }
628 
629   /* This is a single-threaded test, so we can't test the effects of the
630      fences.  */
631   atomic_thread_fence_acquire ();
632   atomic_thread_fence_release ();
633   atomic_thread_fence_seq_cst ();
634 
635   return ret;
636 }
637 
638 #include <support/test-driver.c>
639