1 /* Test atomic_fetch routines for existence and proper execution on
2    4-byte values with each valid memory model.  */
3 /* { dg-do run } */
4 /* { dg-options "-std=c11 -pedantic-errors" } */
5 
6 #include <stdatomic.h>
7 
8 extern void abort (void);
9 
10 _Atomic int v;
11 int count, res;
12 const int init = ~0;
13 
14 void
test_fetch_add()15 test_fetch_add ()
16 {
17   v = 0;
18   count = 1;
19 
20   if (atomic_fetch_add_explicit (&v, count, memory_order_relaxed) != 0)
21     abort ();
22 
23   if (atomic_fetch_add_explicit (&v, 1, memory_order_consume) != 1)
24     abort ();
25 
26   if (atomic_fetch_add_explicit (&v, count, memory_order_acquire) != 2)
27     abort ();
28 
29   if (atomic_fetch_add_explicit (&v, 1, memory_order_release) != 3)
30     abort ();
31 
32   if (atomic_fetch_add_explicit (&v, count, memory_order_acq_rel) != 4)
33     abort ();
34 
35   if (atomic_fetch_add_explicit (&v, 1, memory_order_seq_cst) != 5)
36     abort ();
37 
38   if (atomic_fetch_add (&v, 1) != 6)
39     abort ();
40 }
41 
42 void
test_fetch_sub()43 test_fetch_sub ()
44 {
45   v = res = 20;
46   count = 0;
47 
48   if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_relaxed) != res--)
49     abort ();
50 
51   if (atomic_fetch_sub_explicit (&v, 1, memory_order_consume) != res--)
52     abort ();
53 
54   if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acquire) != res--)
55     abort ();
56 
57   if (atomic_fetch_sub_explicit (&v, 1, memory_order_release) != res--)
58     abort ();
59 
60   if (atomic_fetch_sub_explicit (&v, count + 1, memory_order_acq_rel) != res--)
61     abort ();
62 
63   if (atomic_fetch_sub_explicit (&v, 1, memory_order_seq_cst) != res--)
64     abort ();
65 
66   if (atomic_fetch_sub (&v, 1) != res--)
67     abort ();
68 }
69 
70 void
test_fetch_and()71 test_fetch_and ()
72 {
73   v = init;
74 
75   if (atomic_fetch_and_explicit (&v, 0, memory_order_relaxed) != init)
76     abort ();
77 
78   if (atomic_fetch_and_explicit (&v, init, memory_order_consume) != 0)
79     abort ();
80 
81   if (atomic_fetch_and_explicit (&v, 0, memory_order_acquire) != 0)
82     abort ();
83 
84   v = ~v;
85   if (atomic_fetch_and_explicit (&v, init, memory_order_release) != init)
86     abort ();
87 
88   if (atomic_fetch_and_explicit (&v, 0, memory_order_acq_rel) != init)
89     abort ();
90 
91   if (atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst) != 0)
92     abort ();
93 
94   if (atomic_fetch_and (&v, 0) != 0)
95     abort ();
96 }
97 
98 void
test_fetch_xor()99 test_fetch_xor ()
100 {
101   v = init;
102   count = 0;
103 
104   if (atomic_fetch_xor_explicit (&v, count, memory_order_relaxed) != init)
105     abort ();
106 
107   if (atomic_fetch_xor_explicit (&v, ~count, memory_order_consume) != init)
108     abort ();
109 
110   if (atomic_fetch_xor_explicit (&v, 0, memory_order_acquire) != 0)
111     abort ();
112 
113   if (atomic_fetch_xor_explicit (&v, ~count, memory_order_release) != 0)
114     abort ();
115 
116   if (atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel) != init)
117     abort ();
118 
119   if (atomic_fetch_xor_explicit (&v, ~count, memory_order_seq_cst) != init)
120     abort ();
121 
122   if (atomic_fetch_xor (&v, ~count) != 0)
123     abort ();
124 }
125 
126 void
test_fetch_or()127 test_fetch_or ()
128 {
129   v = 0;
130   count = 1;
131 
132   if (atomic_fetch_or_explicit (&v, count, memory_order_relaxed) != 0)
133     abort ();
134 
135   count *= 2;
136   if (atomic_fetch_or_explicit (&v, 2, memory_order_consume) != 1)
137     abort ();
138 
139   count *= 2;
140   if (atomic_fetch_or_explicit (&v, count, memory_order_acquire) != 3)
141     abort ();
142 
143   count *= 2;
144   if (atomic_fetch_or_explicit (&v, 8, memory_order_release) != 7)
145     abort ();
146 
147   count *= 2;
148   if (atomic_fetch_or_explicit (&v, count, memory_order_acq_rel) != 15)
149     abort ();
150 
151   count *= 2;
152   if (atomic_fetch_or_explicit (&v, count, memory_order_seq_cst) != 31)
153     abort ();
154 
155   count *= 2;
156   if (atomic_fetch_or (&v, count) != 63)
157     abort ();
158 }
159 
160 
161 /* Test the OP routines with a result which isn't used.  */
162 
163 void
test_add()164 test_add ()
165 {
166   v = 0;
167   count = 1;
168 
169   atomic_fetch_add (&v, count);
170   if (v != 1)
171     abort ();
172 
173   atomic_fetch_add_explicit (&v, count, memory_order_consume);
174   if (v != 2)
175     abort ();
176 
177   atomic_fetch_add (&v, 1);
178   if (v != 3)
179     abort ();
180 
181   atomic_fetch_add_explicit (&v, 1, memory_order_release);
182   if (v != 4)
183     abort ();
184 
185   atomic_fetch_add (&v, 1);
186   if (v != 5)
187     abort ();
188 
189   atomic_fetch_add_explicit (&v, count, memory_order_seq_cst);
190   if (v != 6)
191     abort ();
192 }
193 
194 void
test_sub()195 test_sub ()
196 {
197   v = res = 20;
198   count = 0;
199 
200   atomic_fetch_sub (&v, count + 1);
201   if (v != --res)
202     abort ();
203 
204   atomic_fetch_sub_explicit (&v, count + 1, memory_order_consume);
205   if (v != --res)
206     abort ();
207 
208   atomic_fetch_sub (&v, 1);
209   if (v != --res)
210     abort ();
211 
212   atomic_fetch_sub_explicit (&v, 1, memory_order_release);
213   if (v != --res)
214     abort ();
215 
216   atomic_fetch_sub (&v, count + 1);
217   if (v != --res)
218     abort ();
219 
220   atomic_fetch_sub_explicit (&v, count + 1, memory_order_seq_cst);
221   if (v != --res)
222     abort ();
223 }
224 
225 void
test_and()226 test_and ()
227 {
228   v = init;
229 
230   atomic_fetch_and (&v, 0);
231   if (v != 0)
232     abort ();
233 
234   v = init;
235   atomic_fetch_and_explicit (&v, init, memory_order_consume);
236   if (v != init)
237     abort ();
238 
239   atomic_fetch_and (&v, 0);
240   if (v != 0)
241     abort ();
242 
243   v = ~v;
244   atomic_fetch_and_explicit (&v, init, memory_order_release);
245   if (v != init)
246     abort ();
247 
248   atomic_fetch_and (&v, 0);
249   if (v != 0)
250     abort ();
251 
252   v = ~v;
253   atomic_fetch_and_explicit (&v, 0, memory_order_seq_cst);
254   if (v != 0)
255     abort ();
256 }
257 
258 void
test_xor()259 test_xor ()
260 {
261   v = init;
262   count = 0;
263 
264   atomic_fetch_xor (&v, count);
265   if (v != init)
266     abort ();
267 
268   atomic_fetch_xor_explicit (&v, ~count, memory_order_consume);
269   if (v != 0)
270     abort ();
271 
272   atomic_fetch_xor (&v, 0);
273   if (v != 0)
274     abort ();
275 
276   atomic_fetch_xor_explicit (&v, ~count, memory_order_release);
277   if (v != init)
278     abort ();
279 
280   atomic_fetch_xor_explicit (&v, 0, memory_order_acq_rel);
281   if (v != init)
282     abort ();
283 
284   atomic_fetch_xor (&v, ~count);
285   if (v != 0)
286     abort ();
287 }
288 
289 void
test_or()290 test_or ()
291 {
292   v = 0;
293   count = 1;
294 
295   atomic_fetch_or (&v, count);
296   if (v != 1)
297     abort ();
298 
299   count *= 2;
300   atomic_fetch_or_explicit (&v, count, memory_order_consume);
301   if (v != 3)
302     abort ();
303 
304   count *= 2;
305   atomic_fetch_or (&v, 4);
306   if (v != 7)
307     abort ();
308 
309   count *= 2;
310   atomic_fetch_or_explicit (&v, 8, memory_order_release);
311   if (v != 15)
312     abort ();
313 
314   count *= 2;
315   atomic_fetch_or (&v, count);
316   if (v != 31)
317     abort ();
318 
319   count *= 2;
320   atomic_fetch_or_explicit (&v, count, memory_order_seq_cst);
321   if (v != 63)
322     abort ();
323 }
324 
325 int
main()326 main ()
327 {
328   test_fetch_add ();
329   test_fetch_sub ();
330   test_fetch_and ();
331   test_fetch_xor ();
332   test_fetch_or ();
333 
334   test_add ();
335   test_sub ();
336   test_and ();
337   test_xor ();
338   test_or ();
339 
340   return 0;
341 }
342