ARGOBOTS  dce6e727ffc4ca5b3ffc04cb9517c6689be51ec5
abtd_atomic.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #ifndef ABTD_ATOMIC_H_INCLUDED
7 #define ABTD_ATOMIC_H_INCLUDED
8 
9 #include <stdint.h>
10 
11 typedef struct ABTD_atomic_bool {
12  uint8_t val;
13 } ABTD_atomic_bool;
14 
15 typedef struct ABTD_atomic_int {
16  int val;
17 } ABTD_atomic_int;
18 
19 typedef struct ABTD_atomic_size {
20  size_t val;
21 } ABTD_atomic_size;
22 
23 typedef struct ABTD_atomic_int32 {
24  int32_t val;
25 } ABTD_atomic_int32;
26 
27 typedef struct ABTD_atomic_uint32 {
28  uint32_t val;
29 } ABTD_atomic_uint32;
30 
31 typedef struct ABTD_atomic_int64 {
32  int64_t val;
33 } ABTD_atomic_int64;
34 
35 typedef struct ABTD_atomic_uint64 {
36  uint64_t val;
37 } ABTD_atomic_uint64;
38 
39 typedef struct ABTD_atomic_ptr {
40  void *val;
41 } ABTD_atomic_ptr;
42 
43 #define ABTD_ATOMIC_BOOL_STATIC_INITIALIZER(val) \
44  { \
45  (val) \
46  }
47 #define ABTD_ATOMIC_INT_STATIC_INITIALIZER(val) \
48  { \
49  (val) \
50  }
51 #define ABTD_ATOMIC_SIZE_STATIC_INITIALIZER(val) \
52  { \
53  (val) \
54  }
55 #define ABTD_ATOMIC_INT32_STATIC_INITIALIZER(val) \
56  { \
57  (val) \
58  }
59 #define ABTD_ATOMIC_UINT32_STATIC_INITIALIZER(val) \
60  { \
61  (val) \
62  }
63 #define ABTD_ATOMIC_INT64_STATIC_INITIALIZER(val) \
64  { \
65  (val) \
66  }
67 #define ABTD_ATOMIC_UINT64_STATIC_INITIALIZER(val) \
68  { \
69  (val) \
70  }
71 #define ABTD_ATOMIC_PTR_STATIC_INITIALIZER(val) \
72  { \
73  (val) \
74  }
75 
76 static inline int ABTDI_atomic_val_cas_int(ABTD_atomic_int *ptr, int oldv,
77  int newv, int weak)
78 {
79 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
80  int tmp_oldv = oldv;
81  int ret = __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
82  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
83  return ret ? tmp_oldv : oldv;
84 #else
85  return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
86 #endif
87 }
88 
89 static inline size_t ABTDI_atomic_val_cas_size(ABTD_atomic_size *ptr,
90  size_t oldv, size_t newv,
91  int weak)
92 {
93 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
94  size_t tmp_oldv = oldv;
95  int ret = __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
96  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
97  return ret ? tmp_oldv : oldv;
98 #else
99  return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
100 #endif
101 }
102 
103 static inline int32_t ABTDI_atomic_val_cas_int32(ABTD_atomic_int32 *ptr,
104  int32_t oldv, int32_t newv,
105  int weak)
106 {
107 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
108  int32_t tmp_oldv = oldv;
109  int ret = __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
110  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
111  return ret ? tmp_oldv : oldv;
112 #else
113  return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
114 #endif
115 }
116 
117 static inline uint32_t ABTDI_atomic_val_cas_uint32(ABTD_atomic_uint32 *ptr,
118  uint32_t oldv, uint32_t newv,
119  int weak)
120 {
121 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
122  uint32_t tmp_oldv = oldv;
123  int ret = __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
124  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
125  return ret ? tmp_oldv : oldv;
126 #else
127  return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
128 #endif
129 }
130 
131 static inline int64_t ABTDI_atomic_val_cas_int64(ABTD_atomic_int64 *ptr,
132  int64_t oldv, int64_t newv,
133  int weak)
134 {
135 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
136  int64_t tmp_oldv = oldv;
137  int ret = __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
138  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
139  return ret ? tmp_oldv : oldv;
140 #else
141  return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
142 #endif
143 }
144 
145 static inline uint64_t ABTDI_atomic_val_cas_uint64(ABTD_atomic_uint64 *ptr,
146  uint64_t oldv, uint64_t newv,
147  int weak)
148 {
149 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
150  uint64_t tmp_oldv = oldv;
151  int ret = __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
152  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
153  return ret ? tmp_oldv : oldv;
154 #else
155  return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
156 #endif
157 }
158 
159 static inline void *ABTDI_atomic_val_cas_ptr(ABTD_atomic_ptr *ptr, void *oldv,
160  void *newv, int weak)
161 {
162 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
163  void *tmp_oldv = oldv;
164  int ret = __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
165  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
166  return ret ? tmp_oldv : oldv;
167 #else
168  return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
169 #endif
170 }
171 
172 static inline int ABTDI_atomic_bool_cas_int(ABTD_atomic_int *ptr, int oldv,
173  int newv, int weak)
174 {
175 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
176  return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
177  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
178 #else
179  return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
180 #endif
181 }
182 
183 static inline int ABTDI_atomic_bool_cas_size(ABTD_atomic_size *ptr, size_t oldv,
184  size_t newv, int weak)
185 {
186 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
187  return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
188  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
189 #else
190  return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
191 #endif
192 }
193 
194 static inline int ABTDI_atomic_bool_cas_int32(ABTD_atomic_int32 *ptr,
195  int32_t oldv, int32_t newv,
196  int weak)
197 {
198 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
199  return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
200  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
201 #else
202  return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
203 #endif
204 }
205 
206 static inline int ABTDI_atomic_bool_cas_uint32(ABTD_atomic_uint32 *ptr,
207  uint32_t oldv, uint32_t newv,
208  int weak)
209 {
210 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
211  return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
212  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
213 #else
214  return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
215 #endif
216 }
217 
218 static inline int ABTDI_atomic_bool_cas_int64(ABTD_atomic_int64 *ptr,
219  int64_t oldv, int64_t newv,
220  int weak)
221 {
222 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
223  return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
224  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
225 #else
226  return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
227 #endif
228 }
229 
230 static inline int ABTDI_atomic_bool_cas_uint64(ABTD_atomic_uint64 *ptr,
231  uint64_t oldv, uint64_t newv,
232  int weak)
233 {
234 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
235  return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
236  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
237 #else
238  return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
239 #endif
240 }
241 
242 static inline int ABTDI_atomic_bool_cas_ptr(ABTD_atomic_ptr *ptr, void *oldv,
243  void *newv, int weak)
244 {
245 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
246  return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
247  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
248 #else
249  return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
250 #endif
251 }
252 
253 static inline int ABTD_atomic_val_cas_weak_int(ABTD_atomic_int *ptr, int oldv,
254  int newv)
255 {
256  return ABTDI_atomic_val_cas_int(ptr, oldv, newv, 1);
257 }
258 
259 static inline size_t ABTD_atomic_val_cas_weak_size(ABTD_atomic_size *ptr,
260  size_t oldv, size_t newv)
261 {
262  return ABTDI_atomic_val_cas_size(ptr, oldv, newv, 1);
263 }
264 
265 static inline int32_t ABTD_atomic_val_cas_weak_int32(ABTD_atomic_int32 *ptr,
266  int32_t oldv, int32_t newv)
267 {
268  return ABTDI_atomic_val_cas_int32(ptr, oldv, newv, 1);
269 }
270 
271 static inline uint32_t ABTD_atomic_val_cas_weak_uint32(ABTD_atomic_uint32 *ptr,
272  uint32_t oldv,
273  uint32_t newv)
274 {
275  return ABTDI_atomic_val_cas_uint32(ptr, oldv, newv, 1);
276 }
277 
278 static inline int64_t ABTD_atomic_val_cas_weak_int64(ABTD_atomic_int64 *ptr,
279  int64_t oldv, int64_t newv)
280 {
281  return ABTDI_atomic_val_cas_int64(ptr, oldv, newv, 1);
282 }
283 
284 static inline uint64_t ABTD_atomic_val_cas_weak_uint64(ABTD_atomic_uint64 *ptr,
285  uint64_t oldv,
286  uint64_t newv)
287 {
288  return ABTDI_atomic_val_cas_uint64(ptr, oldv, newv, 1);
289 }
290 
291 static inline void *ABTD_atomic_val_cas_weak_ptr(ABTD_atomic_ptr *ptr,
292  void *oldv, void *newv)
293 {
294  return ABTDI_atomic_val_cas_ptr(ptr, oldv, newv, 1);
295 }
296 
297 static inline int ABTD_atomic_val_cas_strong_int(ABTD_atomic_int *ptr, int oldv,
298  int newv)
299 {
300  return ABTDI_atomic_val_cas_int(ptr, oldv, newv, 0);
301 }
302 
303 static inline size_t ABTD_atomic_val_cas_strong_size(ABTD_atomic_size *ptr,
304  size_t oldv, size_t newv)
305 {
306  return ABTDI_atomic_val_cas_size(ptr, oldv, newv, 0);
307 }
308 
309 static inline int32_t ABTD_atomic_val_cas_strong_int32(ABTD_atomic_int32 *ptr,
310  int32_t oldv,
311  int32_t newv)
312 {
313  return ABTDI_atomic_val_cas_int32(ptr, oldv, newv, 0);
314 }
315 
316 static inline uint32_t
317 ABTD_atomic_val_cas_strong_uint32(ABTD_atomic_uint32 *ptr, uint32_t oldv,
318  uint32_t newv)
319 {
320  return ABTDI_atomic_val_cas_uint32(ptr, oldv, newv, 0);
321 }
322 
323 static inline int64_t ABTD_atomic_val_cas_strong_int64(ABTD_atomic_int64 *ptr,
324  int64_t oldv,
325  int64_t newv)
326 {
327  return ABTDI_atomic_val_cas_int64(ptr, oldv, newv, 0);
328 }
329 
330 static inline uint64_t
331 ABTD_atomic_val_cas_strong_uint64(ABTD_atomic_uint64 *ptr, uint64_t oldv,
332  uint64_t newv)
333 {
334  return ABTDI_atomic_val_cas_uint64(ptr, oldv, newv, 0);
335 }
336 
337 static inline void *ABTD_atomic_val_cas_strong_ptr(ABTD_atomic_ptr *ptr,
338  void *oldv, void *newv)
339 {
340  return ABTDI_atomic_val_cas_ptr(ptr, oldv, newv, 0);
341 }
342 
343 static inline int ABTD_atomic_bool_cas_weak_int(ABTD_atomic_int *ptr, int oldv,
344  int newv)
345 {
346  return ABTDI_atomic_bool_cas_int(ptr, oldv, newv, 1);
347 }
348 
349 static inline int ABTD_atomic_bool_cas_weak_size(ABTD_atomic_size *ptr,
350  size_t oldv, size_t newv)
351 {
352  return ABTDI_atomic_bool_cas_size(ptr, oldv, newv, 1);
353 }
354 
355 static inline int ABTD_atomic_bool_cas_weak_int32(ABTD_atomic_int32 *ptr,
356  int32_t oldv, int32_t newv)
357 {
358  return ABTDI_atomic_bool_cas_int32(ptr, oldv, newv, 1);
359 }
360 
361 static inline int ABTD_atomic_bool_cas_weak_uint32(ABTD_atomic_uint32 *ptr,
362  uint32_t oldv, uint32_t newv)
363 {
364  return ABTDI_atomic_bool_cas_uint32(ptr, oldv, newv, 1);
365 }
366 
367 static inline int ABTD_atomic_bool_cas_weak_int64(ABTD_atomic_int64 *ptr,
368  int64_t oldv, int64_t newv)
369 {
370  return ABTDI_atomic_bool_cas_int64(ptr, oldv, newv, 1);
371 }
372 
373 static inline int ABTD_atomic_bool_cas_weak_uint64(ABTD_atomic_uint64 *ptr,
374  uint64_t oldv, uint64_t newv)
375 {
376  return ABTDI_atomic_bool_cas_uint64(ptr, oldv, newv, 1);
377 }
378 
379 static inline int ABTD_atomic_bool_cas_weak_ptr(ABTD_atomic_ptr *ptr,
380  void *oldv, void *newv)
381 {
382  return ABTDI_atomic_bool_cas_ptr(ptr, oldv, newv, 1);
383 }
384 
385 static inline int ABTD_atomic_bool_cas_strong_int(ABTD_atomic_int *ptr,
386  int oldv, int newv)
387 {
388  return ABTDI_atomic_bool_cas_int(ptr, oldv, newv, 0);
389 }
390 
391 static inline int ABTD_atomic_bool_cas_strong_size(ABTD_atomic_size *ptr,
392  size_t oldv, size_t newv)
393 {
394  return ABTDI_atomic_bool_cas_size(ptr, oldv, newv, 0);
395 }
396 
397 static inline int ABTD_atomic_bool_cas_strong_int32(ABTD_atomic_int32 *ptr,
398  int32_t oldv, int32_t newv)
399 {
400  return ABTDI_atomic_bool_cas_int32(ptr, oldv, newv, 0);
401 }
402 
403 static inline int ABTD_atomic_bool_cas_strong_uint32(ABTD_atomic_uint32 *ptr,
404  uint32_t oldv,
405  uint32_t newv)
406 {
407  return ABTDI_atomic_bool_cas_uint32(ptr, oldv, newv, 0);
408 }
409 
410 static inline int ABTD_atomic_bool_cas_strong_int64(ABTD_atomic_int64 *ptr,
411  int64_t oldv, int64_t newv)
412 {
413  return ABTDI_atomic_bool_cas_int64(ptr, oldv, newv, 0);
414 }
415 
416 static inline int ABTD_atomic_bool_cas_strong_uint64(ABTD_atomic_uint64 *ptr,
417  uint64_t oldv,
418  uint64_t newv)
419 {
420  return ABTDI_atomic_bool_cas_uint64(ptr, oldv, newv, 0);
421 }
422 
423 static inline int ABTD_atomic_bool_cas_strong_ptr(ABTD_atomic_ptr *ptr,
424  void *oldv, void *newv)
425 {
426  return ABTDI_atomic_bool_cas_ptr(ptr, oldv, newv, 0);
427 }
428 
429 static inline int ABTD_atomic_fetch_add_int(ABTD_atomic_int *ptr, int v)
430 {
431 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
432  return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
433 #else
434  return __sync_fetch_and_add(&ptr->val, v);
435 #endif
436 }
437 
438 static inline size_t ABTD_atomic_fetch_add_size(ABTD_atomic_size *ptr, size_t v)
439 {
440 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
441  return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
442 #else
443  return __sync_fetch_and_add(&ptr->val, v);
444 #endif
445 }
446 
447 static inline int32_t ABTD_atomic_fetch_add_int32(ABTD_atomic_int32 *ptr,
448  int32_t v)
449 {
450 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
451  return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
452 #else
453  return __sync_fetch_and_add(&ptr->val, v);
454 #endif
455 }
456 
457 static inline uint32_t ABTD_atomic_fetch_add_uint32(ABTD_atomic_uint32 *ptr,
458  uint32_t v)
459 {
460 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
461  return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
462 #else
463  return __sync_fetch_and_add(&ptr->val, v);
464 #endif
465 }
466 
467 static inline int64_t ABTD_atomic_fetch_add_int64(ABTD_atomic_int64 *ptr,
468  int64_t v)
469 {
470 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
471  return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
472 #else
473  return __sync_fetch_and_add(&ptr->val, v);
474 #endif
475 }
476 
477 static inline uint64_t ABTD_atomic_fetch_add_uint64(ABTD_atomic_uint64 *ptr,
478  uint64_t v)
479 {
480 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
481  return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
482 #else
483  return __sync_fetch_and_add(&ptr->val, v);
484 #endif
485 }
486 
487 static inline int ABTD_atomic_fetch_sub_int(ABTD_atomic_int *ptr, int v)
488 {
489 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
490  return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
491 #else
492  return __sync_fetch_and_sub(&ptr->val, v);
493 #endif
494 }
495 
496 static inline size_t ABTD_atomic_fetch_sub_size(ABTD_atomic_size *ptr, size_t v)
497 {
498 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
499  return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
500 #else
501  return __sync_fetch_and_sub(&ptr->val, v);
502 #endif
503 }
504 
505 static inline int32_t ABTD_atomic_fetch_sub_int32(ABTD_atomic_int32 *ptr,
506  int32_t v)
507 {
508 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
509  return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
510 #else
511  return __sync_fetch_and_sub(&ptr->val, v);
512 #endif
513 }
514 
515 static inline uint32_t ABTD_atomic_fetch_sub_uint32(ABTD_atomic_uint32 *ptr,
516  uint32_t v)
517 {
518 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
519  return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
520 #else
521  return __sync_fetch_and_sub(&ptr->val, v);
522 #endif
523 }
524 
525 static inline int64_t ABTD_atomic_fetch_sub_int64(ABTD_atomic_int64 *ptr,
526  int64_t v)
527 {
528 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
529  return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
530 #else
531  return __sync_fetch_and_sub(&ptr->val, v);
532 #endif
533 }
534 
535 static inline uint64_t ABTD_atomic_fetch_sub_uint64(ABTD_atomic_uint64 *ptr,
536  uint64_t v)
537 {
538 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
539  return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
540 #else
541  return __sync_fetch_and_sub(&ptr->val, v);
542 #endif
543 }
544 
545 static inline int ABTD_atomic_fetch_and_int(ABTD_atomic_int *ptr, int v)
546 {
547 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
548  return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
549 #else
550  return __sync_fetch_and_and(&ptr->val, v);
551 #endif
552 }
553 
554 static inline size_t ABTD_atomic_fetch_and_size(ABTD_atomic_size *ptr, size_t v)
555 {
556 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
557  return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
558 #else
559  return __sync_fetch_and_and(&ptr->val, v);
560 #endif
561 }
562 
563 static inline int32_t ABTD_atomic_fetch_and_int32(ABTD_atomic_int32 *ptr,
564  int32_t v)
565 {
566 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
567  return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
568 #else
569  return __sync_fetch_and_and(&ptr->val, v);
570 #endif
571 }
572 
573 static inline uint32_t ABTD_atomic_fetch_and_uint32(ABTD_atomic_uint32 *ptr,
574  uint32_t v)
575 {
576 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
577  return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
578 #else
579  return __sync_fetch_and_and(&ptr->val, v);
580 #endif
581 }
582 
583 static inline int64_t ABTD_atomic_fetch_and_int64(ABTD_atomic_int64 *ptr,
584  int64_t v)
585 {
586 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
587  return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
588 #else
589  return __sync_fetch_and_and(&ptr->val, v);
590 #endif
591 }
592 
593 static inline uint64_t ABTD_atomic_fetch_and_uint64(ABTD_atomic_uint64 *ptr,
594  uint64_t v)
595 {
596 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
597  return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
598 #else
599  return __sync_fetch_and_and(&ptr->val, v);
600 #endif
601 }
602 
603 static inline int ABTD_atomic_fetch_or_int(ABTD_atomic_int *ptr, int v)
604 {
605 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
606  return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
607 #else
608  return __sync_fetch_and_or(&ptr->val, v);
609 #endif
610 }
611 
612 static inline size_t ABTD_atomic_fetch_or_size(ABTD_atomic_size *ptr, size_t v)
613 {
614 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
615  return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
616 #else
617  return __sync_fetch_and_or(&ptr->val, v);
618 #endif
619 }
620 
621 static inline int32_t ABTD_atomic_fetch_or_int32(ABTD_atomic_int32 *ptr,
622  int32_t v)
623 {
624 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
625  return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
626 #else
627  return __sync_fetch_and_or(&ptr->val, v);
628 #endif
629 }
630 
631 static inline uint32_t ABTD_atomic_fetch_or_uint32(ABTD_atomic_uint32 *ptr,
632  uint32_t v)
633 {
634 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
635  return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
636 #else
637  return __sync_fetch_and_or(&ptr->val, v);
638 #endif
639 }
640 
641 static inline int64_t ABTD_atomic_fetch_or_int64(ABTD_atomic_int64 *ptr,
642  int64_t v)
643 {
644 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
645  return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
646 #else
647  return __sync_fetch_and_or(&ptr->val, v);
648 #endif
649 }
650 
651 static inline uint64_t ABTD_atomic_fetch_or_uint64(ABTD_atomic_uint64 *ptr,
652  uint64_t v)
653 {
654 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
655  return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
656 #else
657  return __sync_fetch_and_or(&ptr->val, v);
658 #endif
659 }
660 
661 static inline int ABTD_atomic_fetch_xor_int(ABTD_atomic_int *ptr, int v)
662 {
663 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
664  return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
665 #else
666  return __sync_fetch_and_xor(&ptr->val, v);
667 #endif
668 }
669 
670 static inline size_t ABTD_atomic_fetch_xor_size(ABTD_atomic_size *ptr, size_t v)
671 {
672 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
673  return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
674 #else
675  return __sync_fetch_and_xor(&ptr->val, v);
676 #endif
677 }
678 
679 static inline int32_t ABTD_atomic_fetch_xor_int32(ABTD_atomic_int32 *ptr,
680  int32_t v)
681 {
682 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
683  return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
684 #else
685  return __sync_fetch_and_xor(&ptr->val, v);
686 #endif
687 }
688 
689 static inline uint32_t ABTD_atomic_fetch_xor_uint32(ABTD_atomic_uint32 *ptr,
690  uint32_t v)
691 {
692 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
693  return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
694 #else
695  return __sync_fetch_and_xor(&ptr->val, v);
696 #endif
697 }
698 
699 static inline int64_t ABTD_atomic_fetch_xor_int64(ABTD_atomic_int64 *ptr,
700  int64_t v)
701 {
702 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
703  return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
704 #else
705  return __sync_fetch_and_xor(&ptr->val, v);
706 #endif
707 }
708 
709 static inline uint64_t ABTD_atomic_fetch_xor_uint64(ABTD_atomic_uint64 *ptr,
710  uint64_t v)
711 {
712 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
713  return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
714 #else
715  return __sync_fetch_and_xor(&ptr->val, v);
716 #endif
717 }
718 
719 static inline uint16_t ABTD_atomic_test_and_set_bool(ABTD_atomic_bool *ptr)
720 {
721  /* return 0 if this test_and_set succeeds to set a value. */
722 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
723  return __atomic_test_and_set(&ptr->val, __ATOMIC_ACQUIRE);
724 #else
725  return __sync_lock_test_and_set(&ptr->val, 1);
726 #endif
727 }
728 
729 static inline void ABTD_atomic_relaxed_clear_bool(ABTD_atomic_bool *ptr)
730 {
731 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
732  __atomic_clear(&ptr->val, __ATOMIC_RELAXED);
733 #else
734  *(volatile uint8_t *)&ptr->val = 0;
735 #endif
736 }
737 
738 static inline void ABTD_atomic_release_clear_bool(ABTD_atomic_bool *ptr)
739 {
740 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
741  __atomic_clear(&ptr->val, __ATOMIC_RELEASE);
742 #else
743  __sync_lock_release(&ptr->val);
744 #endif
745 }
746 
747 static inline ABT_bool
748 ABTD_atomic_relaxed_load_bool(const ABTD_atomic_bool *ptr)
749 {
750 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
751 #ifndef __SUNPRO_C
752  return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED) ? ABT_TRUE : ABT_FALSE;
753 #else
754  /* __atomic_load_n() takes a non-const pointer. */
755  return __atomic_load_n((uint8_t *)&ptr->val, __ATOMIC_RELAXED) ? ABT_TRUE
756  : ABT_FALSE;
757 #endif
758 #else
759  return (*(volatile uint8_t *)&ptr->val) ? ABT_TRUE : ABT_FALSE;
760 #endif
761 }
762 
763 static inline int ABTD_atomic_relaxed_load_int(const ABTD_atomic_int *ptr)
764 {
765 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
766 #ifndef __SUNPRO_C
767  return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
768 #else
769  return __atomic_load_n((int *)&ptr->val, __ATOMIC_RELAXED);
770 #endif
771 #else
772  return *(volatile int *)&ptr->val;
773 #endif
774 }
775 
776 static inline size_t ABTD_atomic_relaxed_load_size(const ABTD_atomic_size *ptr)
777 {
778 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
779 #ifndef __SUNPRO_C
780  return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
781 #else
782  return __atomic_load_n((size_t *)&ptr->val, __ATOMIC_RELAXED);
783 #endif
784 #else
785  return *(volatile size_t *)&ptr->val;
786 #endif
787 }
788 
789 static inline int32_t
790 ABTD_atomic_relaxed_load_int32(const ABTD_atomic_int32 *ptr)
791 {
792 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
793 #ifndef __SUNPRO_C
794  return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
795 #else
796  return __atomic_load_n((int32_t *)&ptr->val, __ATOMIC_RELAXED);
797 #endif
798 #else
799  return *(volatile int32_t *)&ptr->val;
800 #endif
801 }
802 
803 static inline uint32_t
804 ABTD_atomic_relaxed_load_uint32(const ABTD_atomic_uint32 *ptr)
805 {
806 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
807 #ifndef __SUNPRO_C
808  return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
809 #else
810  return __atomic_load_n((uint32_t *)&ptr->val, __ATOMIC_RELAXED);
811 #endif
812 #else
813  return *(volatile uint32_t *)&ptr->val;
814 #endif
815 }
816 
817 static inline int64_t
818 ABTD_atomic_relaxed_load_int64(const ABTD_atomic_int64 *ptr)
819 {
820 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
821 #ifndef __SUNPRO_C
822  return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
823 #else
824  return __atomic_load_n((int64_t *)&ptr->val, __ATOMIC_RELAXED);
825 #endif
826 #else
827  return *(volatile int64_t *)&ptr->val;
828 #endif
829 }
830 
831 static inline uint64_t
832 ABTD_atomic_relaxed_load_uint64(const ABTD_atomic_uint64 *ptr)
833 {
834  /* return 0 if this test_and_set succeeds to set a value. */
835 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
836 #ifndef __SUNPRO_C
837  return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
838 #else
839  return __atomic_load_n((uint64_t *)&ptr->val, __ATOMIC_RELAXED);
840 #endif
841 #else
842  return *(volatile uint64_t *)&ptr->val;
843 #endif
844 }
845 
846 static inline void *ABTD_atomic_relaxed_load_ptr(const ABTD_atomic_ptr *ptr)
847 {
848  /* return 0 if this test_and_set succeeds to set a value. */
849 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
850 #ifndef __SUNPRO_C
851  return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
852 #else
853  return __atomic_load_n((void **)&ptr->val, __ATOMIC_RELAXED);
854 #endif
855 #else
856  return *(void *volatile *)&ptr->val;
857 #endif
858 }
859 
860 static inline ABT_bool
861 ABTD_atomic_acquire_load_bool(const ABTD_atomic_bool *ptr)
862 {
863 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
864 #ifndef __SUNPRO_C
865  return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE) ? ABT_TRUE : ABT_FALSE;
866 #else
867  return __atomic_load_n((uint8_t *)&ptr->val, __ATOMIC_ACQUIRE) ? ABT_TRUE
868  : ABT_FALSE;
869 #endif
870 #else
871  __sync_synchronize();
872  ABT_bool val = *(volatile uint8_t *)&ptr->val ? ABT_TRUE : ABT_FALSE;
873  __sync_synchronize();
874  return val;
875 #endif
876 }
877 
878 static inline int ABTD_atomic_acquire_load_int(const ABTD_atomic_int *ptr)
879 {
880 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
881 #ifndef __SUNPRO_C
882  return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
883 #else
884  return __atomic_load_n((int *)&ptr->val, __ATOMIC_ACQUIRE);
885 #endif
886 #else
887  __sync_synchronize();
888  int val = *(volatile int *)&ptr->val;
889  __sync_synchronize();
890  return val;
891 #endif
892 }
893 
894 static inline size_t ABTD_atomic_acquire_load_size(const ABTD_atomic_size *ptr)
895 {
896 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
897 #ifndef __SUNPRO_C
898  return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
899 #else
900  return __atomic_load_n((size_t *)&ptr->val, __ATOMIC_ACQUIRE);
901 #endif
902 #else
903  __sync_synchronize();
904  size_t val = *(volatile size_t *)&ptr->val;
905  __sync_synchronize();
906  return val;
907 #endif
908 }
909 
910 static inline int32_t
911 ABTD_atomic_acquire_load_int32(const ABTD_atomic_int32 *ptr)
912 {
913 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
914 #ifndef __SUNPRO_C
915  return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
916 #else
917  return __atomic_load_n((int32_t *)&ptr->val, __ATOMIC_ACQUIRE);
918 #endif
919 #else
920  __sync_synchronize();
921  int32_t val = *(volatile int32_t *)&ptr->val;
922  __sync_synchronize();
923  return val;
924 #endif
925 }
926 
927 static inline uint32_t
928 ABTD_atomic_acquire_load_uint32(const ABTD_atomic_uint32 *ptr)
929 {
930 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
931 #ifndef __SUNPRO_C
932  return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
933 #else
934  return __atomic_load_n((uint32_t *)&ptr->val, __ATOMIC_ACQUIRE);
935 #endif
936 #else
937  __sync_synchronize();
938  uint32_t val = *(volatile uint32_t *)&ptr->val;
939  __sync_synchronize();
940  return val;
941 #endif
942 }
943 
944 static inline int64_t
945 ABTD_atomic_acquire_load_int64(const ABTD_atomic_int64 *ptr)
946 {
947 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
948 #ifndef __SUNPRO_C
949  return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
950 #else
951  return __atomic_load_n((int64_t *)&ptr->val, __ATOMIC_ACQUIRE);
952 #endif
953 #else
954  __sync_synchronize();
955  int64_t val = *(volatile int64_t *)&ptr->val;
956  __sync_synchronize();
957  return val;
958 #endif
959 }
960 
961 static inline uint64_t
962 ABTD_atomic_acquire_load_uint64(const ABTD_atomic_uint64 *ptr)
963 {
964  /* return 0 if this test_and_set succeeds to set a value. */
965 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
966 #ifndef __SUNPRO_C
967  return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
968 #else
969  return __atomic_load_n((uint64_t *)&ptr->val, __ATOMIC_ACQUIRE);
970 #endif
971 #else
972  __sync_synchronize();
973  uint64_t val = *(volatile uint64_t *)&ptr->val;
974  __sync_synchronize();
975  return val;
976 #endif
977 }
978 
979 static inline void *ABTD_atomic_acquire_load_ptr(const ABTD_atomic_ptr *ptr)
980 {
981  /* return 0 if this test_and_set succeeds to set a value. */
982 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
983 #ifndef __SUNPRO_C
984  return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
985 #else
986  return __atomic_load_n((void **)&ptr->val, __ATOMIC_ACQUIRE);
987 #endif
988 #else
989  __sync_synchronize();
990  void *val = *(void *volatile *)&ptr->val;
991  __sync_synchronize();
992  return val;
993 #endif
994 }
995 
996 static inline void ABTD_atomic_relaxed_store_int(ABTD_atomic_int *ptr, int val)
997 {
998 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
999  __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1000 #else
1001  *(volatile int *)&ptr->val = val;
1002 #endif
1003 }
1004 
1005 static inline void ABTD_atomic_relaxed_store_size(ABTD_atomic_size *ptr,
1006  size_t val)
1007 {
1008 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1009  __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1010 #else
1011  *(volatile size_t *)&ptr->val = val;
1012 #endif
1013 }
1014 
1015 static inline void ABTD_atomic_relaxed_store_int32(ABTD_atomic_int32 *ptr,
1016  int32_t val)
1017 {
1018 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1019  __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1020 #else
1021  *(volatile int32_t *)&ptr->val = val;
1022 #endif
1023 }
1024 
1025 static inline void ABTD_atomic_relaxed_store_uint32(ABTD_atomic_uint32 *ptr,
1026  uint32_t val)
1027 {
1028 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1029  __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1030 #else
1031  *(volatile uint32_t *)&ptr->val = val;
1032 #endif
1033 }
1034 
1035 static inline void ABTD_atomic_relaxed_store_int64(ABTD_atomic_int64 *ptr,
1036  int64_t val)
1037 {
1038 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1039  __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1040 #else
1041  *(volatile int64_t *)&ptr->val = val;
1042 #endif
1043 }
1044 
1045 static inline void ABTD_atomic_relaxed_store_uint64(ABTD_atomic_uint64 *ptr,
1046  uint64_t val)
1047 {
1048 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1049  __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1050 #else
1051  *(volatile uint64_t *)&ptr->val = val;
1052 #endif
1053 }
1054 
1055 static inline void ABTD_atomic_relaxed_store_ptr(ABTD_atomic_ptr *ptr,
1056  void *val)
1057 {
1058 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1059  __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1060 #else
1061  *(void *volatile *)&ptr->val = val;
1062 #endif
1063 }
1064 
1065 static inline void ABTD_atomic_release_store_int(ABTD_atomic_int *ptr, int val)
1066 {
1067 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1068  __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1069 #else
1070  __sync_synchronize();
1071  *(volatile int *)&ptr->val = val;
1072  __sync_synchronize();
1073 #endif
1074 }
1075 
1076 static inline void ABTD_atomic_release_store_size(ABTD_atomic_size *ptr,
1077  size_t val)
1078 {
1079 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1080  __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1081 #else
1082  __sync_synchronize();
1083  *(volatile size_t *)&ptr->val = val;
1084  __sync_synchronize();
1085 #endif
1086 }
1087 
1088 static inline void ABTD_atomic_release_store_int32(ABTD_atomic_int32 *ptr,
1089  int32_t val)
1090 {
1091 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1092  __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1093 #else
1094  __sync_synchronize();
1095  *(volatile int32_t *)&ptr->val = val;
1096  __sync_synchronize();
1097 #endif
1098 }
1099 
1100 static inline void ABTD_atomic_release_store_uint32(ABTD_atomic_uint32 *ptr,
1101  uint32_t val)
1102 {
1103 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1104  __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1105 #else
1106  __sync_synchronize();
1107  *(volatile uint32_t *)&ptr->val = val;
1108  __sync_synchronize();
1109 #endif
1110 }
1111 
1112 static inline void ABTD_atomic_release_store_int64(ABTD_atomic_int64 *ptr,
1113  int64_t val)
1114 {
1115 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1116  __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1117 #else
1118  __sync_synchronize();
1119  *(volatile int64_t *)&ptr->val = val;
1120  __sync_synchronize();
1121 #endif
1122 }
1123 
1124 static inline void ABTD_atomic_release_store_uint64(ABTD_atomic_uint64 *ptr,
1125  uint64_t val)
1126 {
1127 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1128  __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1129 #else
1130  __sync_synchronize();
1131  *(volatile uint64_t *)&ptr->val = val;
1132  __sync_synchronize();
1133 #endif
1134 }
1135 
1136 static inline void ABTD_atomic_release_store_ptr(ABTD_atomic_ptr *ptr,
1137  void *val)
1138 {
1139 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1140  __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1141 #else
1142  __sync_synchronize();
1143  *(void *volatile *)&ptr->val = val;
1144  __sync_synchronize();
1145 #endif
1146 }
1147 
1148 static inline int ABTD_atomic_exchange_int(ABTD_atomic_int *ptr, int v)
1149 {
1150 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1151  return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1152 #else
1153  int val;
1154  do {
1155  val = ABTD_atomic_acquire_load_int(ptr);
1156  } while (!ABTD_atomic_bool_cas_weak_int(ptr, val, v));
1157  return val;
1158 #endif
1159 }
1160 
1161 static inline size_t ABTD_atomic_exchange_size(ABTD_atomic_size *ptr, size_t v)
1162 {
1163 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1164  return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1165 #else
1166  size_t val;
1167  do {
1168  val = ABTD_atomic_acquire_load_size(ptr);
1169  } while (!ABTD_atomic_bool_cas_weak_size(ptr, val, v));
1170  return val;
1171 #endif
1172 }
1173 
1174 static inline int32_t ABTD_atomic_exchange_int32(ABTD_atomic_int32 *ptr,
1175  int32_t v)
1176 {
1177 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1178  return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1179 #else
1180  int32_t val;
1181  do {
1182  val = ABTD_atomic_acquire_load_int32(ptr);
1183  } while (!ABTD_atomic_bool_cas_weak_int32(ptr, val, v));
1184  return val;
1185 #endif
1186 }
1187 
1188 static inline uint32_t ABTD_atomic_exchange_uint32(ABTD_atomic_uint32 *ptr,
1189  uint32_t v)
1190 {
1191 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1192  return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1193 #else
1194  uint32_t val;
1195  do {
1196  val = ABTD_atomic_acquire_load_uint32(ptr);
1197  } while (!ABTD_atomic_bool_cas_weak_uint32(ptr, val, v));
1198  return val;
1199 #endif
1200 }
1201 
1202 static inline int64_t ABTD_atomic_exchange_int64(ABTD_atomic_int64 *ptr,
1203  int64_t v)
1204 {
1205 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1206  return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1207 #else
1208  int64_t val;
1209  do {
1210  val = ABTD_atomic_acquire_load_int64(ptr);
1211  } while (!ABTD_atomic_bool_cas_weak_int64(ptr, val, v));
1212  return val;
1213 #endif
1214 }
1215 
1216 static inline uint64_t ABTD_atomic_exchange_uint64(ABTD_atomic_uint64 *ptr,
1217  uint64_t v)
1218 {
1219 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1220  return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1221 #else
1222  uint64_t val;
1223  do {
1224  val = ABTD_atomic_acquire_load_uint64(ptr);
1225  } while (!ABTD_atomic_bool_cas_weak_uint64(ptr, val, v));
1226  return val;
1227 #endif
1228 }
1229 
1230 static inline void *ABTD_atomic_exchange_ptr(ABTD_atomic_ptr *ptr, void *v)
1231 {
1232 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1233  return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1234 #else
1235  void *val;
1236  do {
1237  val = ABTD_atomic_acquire_load_ptr(ptr);
1238  } while (!ABTD_atomic_bool_cas_weak_ptr(ptr, val, v));
1239  return val;
1240 #endif
1241 }
1242 
1243 static inline void ABTD_atomic_mem_barrier(void)
1244 {
1245 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1246  __atomic_thread_fence(__ATOMIC_ACQ_REL);
1247 #else
1248  __sync_synchronize();
1249 #endif
1250 }
1251 
1252 static inline void ABTD_compiler_barrier(void)
1253 {
1254  __asm__ __volatile__("" ::: "memory");
1255 }
1256 
1257 static inline void ABTD_atomic_pause(void)
1258 {
1259 #ifdef __x86_64__
1260  __asm__ __volatile__("pause" ::: "memory");
1261 #endif
1262 }
1263 
1264 /*
1265  * Declare an atomic tagged pointer here. This atomic type supports very few
1266  * functions, which are basically for the lock-free LIFO implementation.
1267  *
1268  * If ABTD_ATOMIC_SUPPORT_TAGGED_PTR is not defined, this atomic type is
1269  * disabled.
1270  */
1271 #undef ABTD_ATOMIC_SUPPORT_TAGGED_PTR
1272 
1273 #if SIZEOF_VOID_P == 4 || (SIZEOF_VOID_P == 8 && ABT_CONFIG_HAVE_ATOMIC_INT128)
1274 
1275 #define ABTD_ATOMIC_SUPPORT_TAGGED_PTR 1
1276 
1277 typedef struct ABTD_atomic_tagged_ptr {
1278  void *ptr;
1279  size_t tag;
1280 } ABTD_atomic_tagged_ptr;
1281 
1282 #define ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(ptr, tag) \
1283  { \
1284  (ptr), (tag) \
1285  }
1286 
1287 #if SIZEOF_VOID_P == 8
1288 #include "asm/abtd_asm_int128_cas.h"
1289 #endif
1290 
1291 static inline int
1292 ABTD_atomic_bool_cas_weak_tagged_ptr(ABTD_atomic_tagged_ptr *tagged_ptr,
1293  void *old_ptr, size_t old_tag,
1294  void *new_ptr, size_t new_tag)
1295 {
1296 #if SIZEOF_VOID_P == 4
1297 
1298  ABTI_STATIC_ASSERT(sizeof(ABTD_atomic_tagged_ptr) == 8);
1299  /* Use uint64_t for this. */
1300  typedef union {
1301  ABTD_atomic_tagged_ptr tagged_ptr;
1302  uint64_t val;
1303  } atomic_tagged_ptr_t;
1304  atomic_tagged_ptr_t oldv = {
1305  ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(old_ptr, old_tag)
1306  };
1307  atomic_tagged_ptr_t newv = {
1308  ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(new_ptr, new_tag)
1309  };
1310  uint64_t *p_val = (uint64_t *)tagged_ptr;
1311 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1312  return __atomic_compare_exchange_n(p_val, &oldv.val, newv.val, 1,
1313  __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
1314 #else
1315  return __sync_bool_compare_and_swap(&p_ptr, oldv, newv);
1316 #endif
1317 
1318 #elif SIZEOF_VOID_P == 8
1319 
1320  ABTI_STATIC_ASSERT(sizeof(ABTD_atomic_tagged_ptr) == 16);
1321  typedef union {
1322  ABTD_atomic_tagged_ptr tagged_ptr;
1323  __int128 val;
1324  } atomic_tagged_ptr_t;
1325  __int128 *p_val = (__int128 *)tagged_ptr;
1326  atomic_tagged_ptr_t oldv = {
1327  ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(old_ptr, old_tag)
1328  };
1329  atomic_tagged_ptr_t newv = {
1330  ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(new_ptr, new_tag)
1331  };
1332 
1333  return ABTD_asm_bool_cas_weak_int128(p_val, oldv.val, newv.val);
1334 
1335 #else /* SIZEOF_VOID_P */
1336 
1337 #error "Unsupported pointer size."
1338 
1339 #endif
1340 }
1341 
1342 /* The following loads and stores follow relaxed/acquire/release semantics, but
1343  * these operations are not "atomic" as a pair of a pointer and a tag (i.e.,
1344  * ptr and tag are accessed in a non-atomic manner). */
1345 static inline void ABTD_atomic_relaxed_load_non_atomic_tagged_ptr(
1346  const ABTD_atomic_tagged_ptr *tagged_ptr, void **p_ptr, size_t *p_tag)
1347 {
1348 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1349 #ifndef __SUNPRO_C
1350  *p_ptr = __atomic_load_n(&tagged_ptr->ptr, __ATOMIC_RELAXED);
1351  *p_tag = __atomic_load_n(&tagged_ptr->tag, __ATOMIC_RELAXED);
1352 #else
1353  *p_ptr = __atomic_load_n((void **)&tagged_ptr->ptr, __ATOMIC_RELAXED);
1354  *p_tag = __atomic_load_n((size_t *)&tagged_ptr->tag, __ATOMIC_RELAXED);
1355 #endif
1356 #else
1357  *p_ptr = *(void *volatile *)&tagged_ptr->ptr;
1358  *p_tag = *(volatile size_t *)&tagged_ptr->tag;
1359 #endif
1360 }
1361 
1362 static inline void ABTD_atomic_relaxed_store_non_atomic_tagged_ptr(
1363  ABTD_atomic_tagged_ptr *tagged_ptr, void *ptr, size_t tag)
1364 {
1365 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1366  __atomic_store_n(&tagged_ptr->ptr, ptr, __ATOMIC_RELAXED);
1367  __atomic_store_n(&tagged_ptr->tag, tag, __ATOMIC_RELAXED);
1368 #else
1369  *(void *volatile *)&tagged_ptr->ptr = ptr;
1370  *(volatile size_t *)&tagged_ptr->tag = tag;
1371 #endif
1372 }
1373 
1374 static inline void ABTD_atomic_acquire_load_non_atomic_tagged_ptr(
1375  const ABTD_atomic_tagged_ptr *tagged_ptr, void **p_ptr, size_t *p_tag)
1376 {
1377 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1378 #ifndef __SUNPRO_C
1379  *p_ptr = __atomic_load_n(&tagged_ptr->ptr, __ATOMIC_ACQUIRE);
1380  *p_tag = __atomic_load_n(&tagged_ptr->tag, __ATOMIC_ACQUIRE);
1381 #else
1382  *p_ptr = __atomic_load_n((void **)&tagged_ptr->ptr, __ATOMIC_ACQUIRE);
1383  *p_tag = __atomic_load_n((size_t *)&tagged_ptr->tag, __ATOMIC_ACQUIRE);
1384 #endif
1385 #else
1386  __sync_synchronize();
1387  *p_ptr = *(void *volatile *)&tagged_ptr->ptr;
1388  *p_tag = *(volatile size_t *)&tagged_ptr->tag;
1389  __sync_synchronize();
1390 #endif
1391 }
1392 
1393 static inline void ABTD_atomic_release_store_non_atomic_tagged_ptr(
1394  ABTD_atomic_tagged_ptr *tagged_ptr, void *ptr, size_t tag)
1395 {
1396 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1397  __atomic_store_n(&tagged_ptr->ptr, ptr, __ATOMIC_RELEASE);
1398  __atomic_store_n(&tagged_ptr->tag, tag, __ATOMIC_RELEASE);
1399 #else
1400  __sync_synchronize();
1401  *(void *volatile *)&tagged_ptr->ptr = ptr;
1402  *(volatile size_t *)&tagged_ptr->tag = tag;
1403  __sync_synchronize();
1404 #endif
1405 }
1406 
1407 #endif /* ABTD_ATOMIC_SUPPORT_TAGGED_PTR */
1408 
1409 #endif /* ABTD_ATOMIC_H_INCLUDED */
ABTDI_atomic_val_cas_ptr
static void * ABTDI_atomic_val_cas_ptr(ABTD_atomic_ptr *ptr, void *oldv, void *newv, int weak)
Definition: abtd_atomic.h:159
ABTDI_atomic_bool_cas_size
static int ABTDI_atomic_bool_cas_size(ABTD_atomic_size *ptr, size_t oldv, size_t newv, int weak)
Definition: abtd_atomic.h:183
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1043
ABTDI_atomic_val_cas_int32
static int32_t ABTDI_atomic_val_cas_int32(ABTD_atomic_int32 *ptr, int32_t oldv, int32_t newv, int weak)
Definition: abtd_atomic.h:103
ABTDI_atomic_bool_cas_uint64
static int ABTDI_atomic_bool_cas_uint64(ABTD_atomic_uint64 *ptr, uint64_t oldv, uint64_t newv, int weak)
Definition: abtd_atomic.h:230
ABTDI_atomic_bool_cas_ptr
static int ABTDI_atomic_bool_cas_ptr(ABTD_atomic_ptr *ptr, void *oldv, void *newv, int weak)
Definition: abtd_atomic.h:242
ABTDI_atomic_val_cas_int
static int ABTDI_atomic_val_cas_int(ABTD_atomic_int *ptr, int oldv, int newv, int weak)
Definition: abtd_atomic.h:76
ABTDI_atomic_val_cas_uint32
static uint32_t ABTDI_atomic_val_cas_uint32(ABTD_atomic_uint32 *ptr, uint32_t oldv, uint32_t newv, int weak)
Definition: abtd_atomic.h:117
ABTDI_atomic_bool_cas_int
static int ABTDI_atomic_bool_cas_int(ABTD_atomic_int *ptr, int oldv, int newv, int weak)
Definition: abtd_atomic.h:172
ABTDI_atomic_val_cas_size
static size_t ABTDI_atomic_val_cas_size(ABTD_atomic_size *ptr, size_t oldv, size_t newv, int weak)
Definition: abtd_atomic.h:89
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:784
ABTDI_atomic_bool_cas_int64
static int ABTDI_atomic_bool_cas_int64(ABTD_atomic_int64 *ptr, int64_t oldv, int64_t newv, int weak)
Definition: abtd_atomic.h:218
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:786
ABTDI_atomic_val_cas_int64
static int64_t ABTDI_atomic_val_cas_int64(ABTD_atomic_int64 *ptr, int64_t oldv, int64_t newv, int weak)
Definition: abtd_atomic.h:131
ABTDI_atomic_bool_cas_int32
static int ABTDI_atomic_bool_cas_int32(ABTD_atomic_int32 *ptr, int32_t oldv, int32_t newv, int weak)
Definition: abtd_atomic.h:194
ABTDI_atomic_val_cas_uint64
static uint64_t ABTDI_atomic_val_cas_uint64(ABTD_atomic_uint64 *ptr, uint64_t oldv, uint64_t newv, int weak)
Definition: abtd_atomic.h:145
abtd_asm_int128_cas.h
ABTDI_atomic_bool_cas_uint32
static int ABTDI_atomic_bool_cas_uint32(ABTD_atomic_uint32 *ptr, uint32_t oldv, uint32_t newv, int weak)
Definition: abtd_atomic.h:206