6 #ifndef ABTD_ATOMIC_H_INCLUDED
7 #define ABTD_ATOMIC_H_INCLUDED
11 typedef struct ABTD_atomic_bool {
15 typedef struct ABTD_atomic_int {
19 typedef struct ABTD_atomic_size {
23 typedef struct ABTD_atomic_int32 {
27 typedef struct ABTD_atomic_uint32 {
31 typedef struct ABTD_atomic_int64 {
35 typedef struct ABTD_atomic_uint64 {
39 typedef struct ABTD_atomic_ptr {
43 #define ABTD_ATOMIC_BOOL_STATIC_INITIALIZER(val) \
47 #define ABTD_ATOMIC_INT_STATIC_INITIALIZER(val) \
51 #define ABTD_ATOMIC_SIZE_STATIC_INITIALIZER(val) \
55 #define ABTD_ATOMIC_INT32_STATIC_INITIALIZER(val) \
59 #define ABTD_ATOMIC_UINT32_STATIC_INITIALIZER(val) \
63 #define ABTD_ATOMIC_INT64_STATIC_INITIALIZER(val) \
67 #define ABTD_ATOMIC_UINT64_STATIC_INITIALIZER(val) \
71 #define ABTD_ATOMIC_PTR_STATIC_INITIALIZER(val) \
79 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
81 int ret = __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
82 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
83 return ret ? tmp_oldv : oldv;
85 return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
90 size_t oldv,
size_t newv,
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;
99 return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
104 int32_t oldv, int32_t newv,
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;
113 return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
118 uint32_t oldv, uint32_t newv,
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;
127 return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
132 int64_t oldv, int64_t newv,
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;
141 return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
146 uint64_t oldv, uint64_t newv,
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;
155 return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
160 void *newv,
int weak)
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;
168 return __sync_val_compare_and_swap(&ptr->val, oldv, newv);
175 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
176 return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
177 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
179 return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
184 size_t newv,
int weak)
186 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
187 return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
188 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
190 return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
195 int32_t oldv, int32_t newv,
198 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
199 return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
200 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
202 return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
207 uint32_t oldv, uint32_t newv,
210 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
211 return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
212 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
214 return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
219 int64_t oldv, int64_t newv,
222 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
223 return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
224 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
226 return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
231 uint64_t oldv, uint64_t newv,
234 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
235 return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
236 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
238 return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
243 void *newv,
int weak)
245 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
246 return __atomic_compare_exchange_n(&ptr->val, &oldv, newv, weak,
247 __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
249 return __sync_bool_compare_and_swap(&ptr->val, oldv, newv);
253 static inline int ABTD_atomic_val_cas_weak_int(ABTD_atomic_int *ptr,
int oldv,
259 static inline size_t ABTD_atomic_val_cas_weak_size(ABTD_atomic_size *ptr,
260 size_t oldv,
size_t newv)
265 static inline int32_t ABTD_atomic_val_cas_weak_int32(ABTD_atomic_int32 *ptr,
266 int32_t oldv, int32_t newv)
271 static inline uint32_t ABTD_atomic_val_cas_weak_uint32(ABTD_atomic_uint32 *ptr,
278 static inline int64_t ABTD_atomic_val_cas_weak_int64(ABTD_atomic_int64 *ptr,
279 int64_t oldv, int64_t newv)
284 static inline uint64_t ABTD_atomic_val_cas_weak_uint64(ABTD_atomic_uint64 *ptr,
291 static inline void *ABTD_atomic_val_cas_weak_ptr(ABTD_atomic_ptr *ptr,
292 void *oldv,
void *newv)
297 static inline int ABTD_atomic_val_cas_strong_int(ABTD_atomic_int *ptr,
int oldv,
303 static inline size_t ABTD_atomic_val_cas_strong_size(ABTD_atomic_size *ptr,
304 size_t oldv,
size_t newv)
309 static inline int32_t ABTD_atomic_val_cas_strong_int32(ABTD_atomic_int32 *ptr,
316 static inline uint32_t
317 ABTD_atomic_val_cas_strong_uint32(ABTD_atomic_uint32 *ptr, uint32_t oldv,
323 static inline int64_t ABTD_atomic_val_cas_strong_int64(ABTD_atomic_int64 *ptr,
330 static inline uint64_t
331 ABTD_atomic_val_cas_strong_uint64(ABTD_atomic_uint64 *ptr, uint64_t oldv,
337 static inline void *ABTD_atomic_val_cas_strong_ptr(ABTD_atomic_ptr *ptr,
338 void *oldv,
void *newv)
343 static inline int ABTD_atomic_bool_cas_weak_int(ABTD_atomic_int *ptr,
int oldv,
349 static inline int ABTD_atomic_bool_cas_weak_size(ABTD_atomic_size *ptr,
350 size_t oldv,
size_t newv)
355 static inline int ABTD_atomic_bool_cas_weak_int32(ABTD_atomic_int32 *ptr,
356 int32_t oldv, int32_t newv)
361 static inline int ABTD_atomic_bool_cas_weak_uint32(ABTD_atomic_uint32 *ptr,
362 uint32_t oldv, uint32_t newv)
367 static inline int ABTD_atomic_bool_cas_weak_int64(ABTD_atomic_int64 *ptr,
368 int64_t oldv, int64_t newv)
373 static inline int ABTD_atomic_bool_cas_weak_uint64(ABTD_atomic_uint64 *ptr,
374 uint64_t oldv, uint64_t newv)
379 static inline int ABTD_atomic_bool_cas_weak_ptr(ABTD_atomic_ptr *ptr,
380 void *oldv,
void *newv)
385 static inline int ABTD_atomic_bool_cas_strong_int(ABTD_atomic_int *ptr,
391 static inline int ABTD_atomic_bool_cas_strong_size(ABTD_atomic_size *ptr,
392 size_t oldv,
size_t newv)
397 static inline int ABTD_atomic_bool_cas_strong_int32(ABTD_atomic_int32 *ptr,
398 int32_t oldv, int32_t newv)
403 static inline int ABTD_atomic_bool_cas_strong_uint32(ABTD_atomic_uint32 *ptr,
410 static inline int ABTD_atomic_bool_cas_strong_int64(ABTD_atomic_int64 *ptr,
411 int64_t oldv, int64_t newv)
416 static inline int ABTD_atomic_bool_cas_strong_uint64(ABTD_atomic_uint64 *ptr,
423 static inline int ABTD_atomic_bool_cas_strong_ptr(ABTD_atomic_ptr *ptr,
424 void *oldv,
void *newv)
429 static inline int ABTD_atomic_fetch_add_int(ABTD_atomic_int *ptr,
int v)
431 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
432 return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
434 return __sync_fetch_and_add(&ptr->val, v);
438 static inline size_t ABTD_atomic_fetch_add_size(ABTD_atomic_size *ptr,
size_t v)
440 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
441 return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
443 return __sync_fetch_and_add(&ptr->val, v);
447 static inline int32_t ABTD_atomic_fetch_add_int32(ABTD_atomic_int32 *ptr,
450 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
451 return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
453 return __sync_fetch_and_add(&ptr->val, v);
457 static inline uint32_t ABTD_atomic_fetch_add_uint32(ABTD_atomic_uint32 *ptr,
460 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
461 return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
463 return __sync_fetch_and_add(&ptr->val, v);
467 static inline int64_t ABTD_atomic_fetch_add_int64(ABTD_atomic_int64 *ptr,
470 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
471 return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
473 return __sync_fetch_and_add(&ptr->val, v);
477 static inline uint64_t ABTD_atomic_fetch_add_uint64(ABTD_atomic_uint64 *ptr,
480 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
481 return __atomic_fetch_add(&ptr->val, v, __ATOMIC_ACQ_REL);
483 return __sync_fetch_and_add(&ptr->val, v);
487 static inline int ABTD_atomic_fetch_sub_int(ABTD_atomic_int *ptr,
int v)
489 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
490 return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
492 return __sync_fetch_and_sub(&ptr->val, v);
496 static inline size_t ABTD_atomic_fetch_sub_size(ABTD_atomic_size *ptr,
size_t v)
498 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
499 return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
501 return __sync_fetch_and_sub(&ptr->val, v);
505 static inline int32_t ABTD_atomic_fetch_sub_int32(ABTD_atomic_int32 *ptr,
508 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
509 return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
511 return __sync_fetch_and_sub(&ptr->val, v);
515 static inline uint32_t ABTD_atomic_fetch_sub_uint32(ABTD_atomic_uint32 *ptr,
518 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
519 return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
521 return __sync_fetch_and_sub(&ptr->val, v);
525 static inline int64_t ABTD_atomic_fetch_sub_int64(ABTD_atomic_int64 *ptr,
528 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
529 return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
531 return __sync_fetch_and_sub(&ptr->val, v);
535 static inline uint64_t ABTD_atomic_fetch_sub_uint64(ABTD_atomic_uint64 *ptr,
538 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
539 return __atomic_fetch_sub(&ptr->val, v, __ATOMIC_ACQ_REL);
541 return __sync_fetch_and_sub(&ptr->val, v);
545 static inline int ABTD_atomic_fetch_and_int(ABTD_atomic_int *ptr,
int v)
547 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
548 return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
550 return __sync_fetch_and_and(&ptr->val, v);
554 static inline size_t ABTD_atomic_fetch_and_size(ABTD_atomic_size *ptr,
size_t v)
556 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
557 return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
559 return __sync_fetch_and_and(&ptr->val, v);
563 static inline int32_t ABTD_atomic_fetch_and_int32(ABTD_atomic_int32 *ptr,
566 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
567 return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
569 return __sync_fetch_and_and(&ptr->val, v);
573 static inline uint32_t ABTD_atomic_fetch_and_uint32(ABTD_atomic_uint32 *ptr,
576 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
577 return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
579 return __sync_fetch_and_and(&ptr->val, v);
583 static inline int64_t ABTD_atomic_fetch_and_int64(ABTD_atomic_int64 *ptr,
586 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
587 return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
589 return __sync_fetch_and_and(&ptr->val, v);
593 static inline uint64_t ABTD_atomic_fetch_and_uint64(ABTD_atomic_uint64 *ptr,
596 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
597 return __atomic_fetch_and(&ptr->val, v, __ATOMIC_ACQ_REL);
599 return __sync_fetch_and_and(&ptr->val, v);
603 static inline int ABTD_atomic_fetch_or_int(ABTD_atomic_int *ptr,
int v)
605 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
606 return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
608 return __sync_fetch_and_or(&ptr->val, v);
612 static inline size_t ABTD_atomic_fetch_or_size(ABTD_atomic_size *ptr,
size_t v)
614 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
615 return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
617 return __sync_fetch_and_or(&ptr->val, v);
621 static inline int32_t ABTD_atomic_fetch_or_int32(ABTD_atomic_int32 *ptr,
624 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
625 return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
627 return __sync_fetch_and_or(&ptr->val, v);
631 static inline uint32_t ABTD_atomic_fetch_or_uint32(ABTD_atomic_uint32 *ptr,
634 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
635 return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
637 return __sync_fetch_and_or(&ptr->val, v);
641 static inline int64_t ABTD_atomic_fetch_or_int64(ABTD_atomic_int64 *ptr,
644 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
645 return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
647 return __sync_fetch_and_or(&ptr->val, v);
651 static inline uint64_t ABTD_atomic_fetch_or_uint64(ABTD_atomic_uint64 *ptr,
654 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
655 return __atomic_fetch_or(&ptr->val, v, __ATOMIC_ACQ_REL);
657 return __sync_fetch_and_or(&ptr->val, v);
661 static inline int ABTD_atomic_fetch_xor_int(ABTD_atomic_int *ptr,
int v)
663 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
664 return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
666 return __sync_fetch_and_xor(&ptr->val, v);
670 static inline size_t ABTD_atomic_fetch_xor_size(ABTD_atomic_size *ptr,
size_t v)
672 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
673 return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
675 return __sync_fetch_and_xor(&ptr->val, v);
679 static inline int32_t ABTD_atomic_fetch_xor_int32(ABTD_atomic_int32 *ptr,
682 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
683 return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
685 return __sync_fetch_and_xor(&ptr->val, v);
689 static inline uint32_t ABTD_atomic_fetch_xor_uint32(ABTD_atomic_uint32 *ptr,
692 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
693 return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
695 return __sync_fetch_and_xor(&ptr->val, v);
699 static inline int64_t ABTD_atomic_fetch_xor_int64(ABTD_atomic_int64 *ptr,
702 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
703 return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
705 return __sync_fetch_and_xor(&ptr->val, v);
709 static inline uint64_t ABTD_atomic_fetch_xor_uint64(ABTD_atomic_uint64 *ptr,
712 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
713 return __atomic_fetch_xor(&ptr->val, v, __ATOMIC_ACQ_REL);
715 return __sync_fetch_and_xor(&ptr->val, v);
719 static inline uint16_t ABTD_atomic_test_and_set_bool(ABTD_atomic_bool *ptr)
722 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
723 return __atomic_test_and_set(&ptr->val, __ATOMIC_ACQUIRE);
725 return __sync_lock_test_and_set(&ptr->val, 1);
729 static inline void ABTD_atomic_relaxed_clear_bool(ABTD_atomic_bool *ptr)
731 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
732 __atomic_clear(&ptr->val, __ATOMIC_RELAXED);
734 *(
volatile uint8_t *)&ptr->val = 0;
738 static inline void ABTD_atomic_release_clear_bool(ABTD_atomic_bool *ptr)
740 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
741 __atomic_clear(&ptr->val, __ATOMIC_RELEASE);
743 __sync_lock_release(&ptr->val);
748 ABTD_atomic_relaxed_load_bool(
const ABTD_atomic_bool *ptr)
750 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
755 return __atomic_load_n((uint8_t *)&ptr->val, __ATOMIC_RELAXED) ?
ABT_TRUE
763 static inline int ABTD_atomic_relaxed_load_int(
const ABTD_atomic_int *ptr)
765 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
767 return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
769 return __atomic_load_n((
int *)&ptr->val, __ATOMIC_RELAXED);
772 return *(
volatile int *)&ptr->val;
776 static inline size_t ABTD_atomic_relaxed_load_size(
const ABTD_atomic_size *ptr)
778 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
780 return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
782 return __atomic_load_n((
size_t *)&ptr->val, __ATOMIC_RELAXED);
785 return *(
volatile size_t *)&ptr->val;
789 static inline int32_t
790 ABTD_atomic_relaxed_load_int32(
const ABTD_atomic_int32 *ptr)
792 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
794 return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
796 return __atomic_load_n((int32_t *)&ptr->val, __ATOMIC_RELAXED);
799 return *(
volatile int32_t *)&ptr->val;
803 static inline uint32_t
804 ABTD_atomic_relaxed_load_uint32(
const ABTD_atomic_uint32 *ptr)
806 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
808 return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
810 return __atomic_load_n((uint32_t *)&ptr->val, __ATOMIC_RELAXED);
813 return *(
volatile uint32_t *)&ptr->val;
817 static inline int64_t
818 ABTD_atomic_relaxed_load_int64(
const ABTD_atomic_int64 *ptr)
820 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
822 return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
824 return __atomic_load_n((int64_t *)&ptr->val, __ATOMIC_RELAXED);
827 return *(
volatile int64_t *)&ptr->val;
831 static inline uint64_t
832 ABTD_atomic_relaxed_load_uint64(
const ABTD_atomic_uint64 *ptr)
835 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
837 return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
839 return __atomic_load_n((uint64_t *)&ptr->val, __ATOMIC_RELAXED);
842 return *(
volatile uint64_t *)&ptr->val;
846 static inline void *ABTD_atomic_relaxed_load_ptr(
const ABTD_atomic_ptr *ptr)
849 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
851 return __atomic_load_n(&ptr->val, __ATOMIC_RELAXED);
853 return __atomic_load_n((
void **)&ptr->val, __ATOMIC_RELAXED);
856 return *(
void *
volatile *)&ptr->val;
861 ABTD_atomic_acquire_load_bool(
const ABTD_atomic_bool *ptr)
863 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
867 return __atomic_load_n((uint8_t *)&ptr->val, __ATOMIC_ACQUIRE) ?
ABT_TRUE
871 __sync_synchronize();
873 __sync_synchronize();
878 static inline int ABTD_atomic_acquire_load_int(
const ABTD_atomic_int *ptr)
880 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
882 return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
884 return __atomic_load_n((
int *)&ptr->val, __ATOMIC_ACQUIRE);
887 __sync_synchronize();
888 int val = *(
volatile int *)&ptr->val;
889 __sync_synchronize();
894 static inline size_t ABTD_atomic_acquire_load_size(
const ABTD_atomic_size *ptr)
896 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
898 return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
900 return __atomic_load_n((
size_t *)&ptr->val, __ATOMIC_ACQUIRE);
903 __sync_synchronize();
904 size_t val = *(
volatile size_t *)&ptr->val;
905 __sync_synchronize();
910 static inline int32_t
911 ABTD_atomic_acquire_load_int32(
const ABTD_atomic_int32 *ptr)
913 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
915 return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
917 return __atomic_load_n((int32_t *)&ptr->val, __ATOMIC_ACQUIRE);
920 __sync_synchronize();
921 int32_t val = *(
volatile int32_t *)&ptr->val;
922 __sync_synchronize();
927 static inline uint32_t
928 ABTD_atomic_acquire_load_uint32(
const ABTD_atomic_uint32 *ptr)
930 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
932 return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
934 return __atomic_load_n((uint32_t *)&ptr->val, __ATOMIC_ACQUIRE);
937 __sync_synchronize();
938 uint32_t val = *(
volatile uint32_t *)&ptr->val;
939 __sync_synchronize();
944 static inline int64_t
945 ABTD_atomic_acquire_load_int64(
const ABTD_atomic_int64 *ptr)
947 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
949 return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
951 return __atomic_load_n((int64_t *)&ptr->val, __ATOMIC_ACQUIRE);
954 __sync_synchronize();
955 int64_t val = *(
volatile int64_t *)&ptr->val;
956 __sync_synchronize();
961 static inline uint64_t
962 ABTD_atomic_acquire_load_uint64(
const ABTD_atomic_uint64 *ptr)
965 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
967 return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
969 return __atomic_load_n((uint64_t *)&ptr->val, __ATOMIC_ACQUIRE);
972 __sync_synchronize();
973 uint64_t val = *(
volatile uint64_t *)&ptr->val;
974 __sync_synchronize();
979 static inline void *ABTD_atomic_acquire_load_ptr(
const ABTD_atomic_ptr *ptr)
982 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
984 return __atomic_load_n(&ptr->val, __ATOMIC_ACQUIRE);
986 return __atomic_load_n((
void **)&ptr->val, __ATOMIC_ACQUIRE);
989 __sync_synchronize();
990 void *val = *(
void *
volatile *)&ptr->val;
991 __sync_synchronize();
996 static inline void ABTD_atomic_relaxed_store_int(ABTD_atomic_int *ptr,
int val)
998 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
999 __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1001 *(
volatile int *)&ptr->val = val;
1005 static inline void ABTD_atomic_relaxed_store_size(ABTD_atomic_size *ptr,
1008 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1009 __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1011 *(
volatile size_t *)&ptr->val = val;
1015 static inline void ABTD_atomic_relaxed_store_int32(ABTD_atomic_int32 *ptr,
1018 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1019 __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1021 *(
volatile int32_t *)&ptr->val = val;
1025 static inline void ABTD_atomic_relaxed_store_uint32(ABTD_atomic_uint32 *ptr,
1028 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1029 __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1031 *(
volatile uint32_t *)&ptr->val = val;
1035 static inline void ABTD_atomic_relaxed_store_int64(ABTD_atomic_int64 *ptr,
1038 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1039 __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1041 *(
volatile int64_t *)&ptr->val = val;
1045 static inline void ABTD_atomic_relaxed_store_uint64(ABTD_atomic_uint64 *ptr,
1048 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1049 __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1051 *(
volatile uint64_t *)&ptr->val = val;
1055 static inline void ABTD_atomic_relaxed_store_ptr(ABTD_atomic_ptr *ptr,
1058 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1059 __atomic_store_n(&ptr->val, val, __ATOMIC_RELAXED);
1061 *(
void *
volatile *)&ptr->val = val;
1065 static inline void ABTD_atomic_release_store_int(ABTD_atomic_int *ptr,
int val)
1067 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1068 __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1070 __sync_synchronize();
1071 *(
volatile int *)&ptr->val = val;
1072 __sync_synchronize();
1076 static inline void ABTD_atomic_release_store_size(ABTD_atomic_size *ptr,
1079 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1080 __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1082 __sync_synchronize();
1083 *(
volatile size_t *)&ptr->val = val;
1084 __sync_synchronize();
1088 static inline void ABTD_atomic_release_store_int32(ABTD_atomic_int32 *ptr,
1091 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1092 __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1094 __sync_synchronize();
1095 *(
volatile int32_t *)&ptr->val = val;
1096 __sync_synchronize();
1100 static inline void ABTD_atomic_release_store_uint32(ABTD_atomic_uint32 *ptr,
1103 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1104 __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1106 __sync_synchronize();
1107 *(
volatile uint32_t *)&ptr->val = val;
1108 __sync_synchronize();
1112 static inline void ABTD_atomic_release_store_int64(ABTD_atomic_int64 *ptr,
1115 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1116 __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1118 __sync_synchronize();
1119 *(
volatile int64_t *)&ptr->val = val;
1120 __sync_synchronize();
1124 static inline void ABTD_atomic_release_store_uint64(ABTD_atomic_uint64 *ptr,
1127 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1128 __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1130 __sync_synchronize();
1131 *(
volatile uint64_t *)&ptr->val = val;
1132 __sync_synchronize();
1136 static inline void ABTD_atomic_release_store_ptr(ABTD_atomic_ptr *ptr,
1139 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1140 __atomic_store_n(&ptr->val, val, __ATOMIC_RELEASE);
1142 __sync_synchronize();
1143 *(
void *
volatile *)&ptr->val = val;
1144 __sync_synchronize();
1148 static inline int ABTD_atomic_exchange_int(ABTD_atomic_int *ptr,
int v)
1150 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1151 return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1155 val = ABTD_atomic_acquire_load_int(ptr);
1156 }
while (!ABTD_atomic_bool_cas_weak_int(ptr, val, v));
1161 static inline size_t ABTD_atomic_exchange_size(ABTD_atomic_size *ptr,
size_t v)
1163 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1164 return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1168 val = ABTD_atomic_acquire_load_size(ptr);
1169 }
while (!ABTD_atomic_bool_cas_weak_size(ptr, val, v));
1174 static inline int32_t ABTD_atomic_exchange_int32(ABTD_atomic_int32 *ptr,
1177 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1178 return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1182 val = ABTD_atomic_acquire_load_int32(ptr);
1183 }
while (!ABTD_atomic_bool_cas_weak_int32(ptr, val, v));
1188 static inline uint32_t ABTD_atomic_exchange_uint32(ABTD_atomic_uint32 *ptr,
1191 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1192 return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1196 val = ABTD_atomic_acquire_load_uint32(ptr);
1197 }
while (!ABTD_atomic_bool_cas_weak_uint32(ptr, val, v));
1202 static inline int64_t ABTD_atomic_exchange_int64(ABTD_atomic_int64 *ptr,
1205 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1206 return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1210 val = ABTD_atomic_acquire_load_int64(ptr);
1211 }
while (!ABTD_atomic_bool_cas_weak_int64(ptr, val, v));
1216 static inline uint64_t ABTD_atomic_exchange_uint64(ABTD_atomic_uint64 *ptr,
1219 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1220 return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1224 val = ABTD_atomic_acquire_load_uint64(ptr);
1225 }
while (!ABTD_atomic_bool_cas_weak_uint64(ptr, val, v));
1230 static inline void *ABTD_atomic_exchange_ptr(ABTD_atomic_ptr *ptr,
void *v)
1232 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1233 return __atomic_exchange_n(&ptr->val, v, __ATOMIC_ACQ_REL);
1237 val = ABTD_atomic_acquire_load_ptr(ptr);
1238 }
while (!ABTD_atomic_bool_cas_weak_ptr(ptr, val, v));
1243 static inline void ABTD_atomic_mem_barrier(
void)
1245 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1246 __atomic_thread_fence(__ATOMIC_ACQ_REL);
1248 __sync_synchronize();
1252 static inline void ABTD_compiler_barrier(
void)
1254 __asm__ __volatile__(
"" :::
"memory");
1257 static inline void ABTD_atomic_pause(
void)
1260 __asm__ __volatile__(
"pause" :::
"memory");
1271 #undef ABTD_ATOMIC_SUPPORT_TAGGED_PTR
1273 #if SIZEOF_VOID_P == 4 || (SIZEOF_VOID_P == 8 && ABT_CONFIG_HAVE_ATOMIC_INT128)
1275 #define ABTD_ATOMIC_SUPPORT_TAGGED_PTR 1
1277 typedef struct ABTD_atomic_tagged_ptr {
1280 } ABTD_atomic_tagged_ptr;
1282 #define ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(ptr, tag) \
1287 #if SIZEOF_VOID_P == 8
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)
1296 #if SIZEOF_VOID_P == 4
1298 ABTI_STATIC_ASSERT(
sizeof(ABTD_atomic_tagged_ptr) == 8);
1301 ABTD_atomic_tagged_ptr tagged_ptr;
1303 } atomic_tagged_ptr_t;
1304 atomic_tagged_ptr_t oldv = {
1305 ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(old_ptr, old_tag)
1307 atomic_tagged_ptr_t newv = {
1308 ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(new_ptr, new_tag)
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);
1315 return __sync_bool_compare_and_swap(&p_ptr, oldv, newv);
1318 #elif SIZEOF_VOID_P == 8
1320 ABTI_STATIC_ASSERT(
sizeof(ABTD_atomic_tagged_ptr) == 16);
1322 ABTD_atomic_tagged_ptr tagged_ptr;
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)
1329 atomic_tagged_ptr_t newv = {
1330 ABTD_ATOMIC_TAGGED_PTR_STATIC_INITIALIZER(new_ptr, new_tag)
1333 return ABTD_asm_bool_cas_weak_int128(p_val, oldv.val, newv.val);
1337 #error "Unsupported pointer size."
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)
1348 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1350 *p_ptr = __atomic_load_n(&tagged_ptr->ptr, __ATOMIC_RELAXED);
1351 *p_tag = __atomic_load_n(&tagged_ptr->tag, __ATOMIC_RELAXED);
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);
1357 *p_ptr = *(
void *
volatile *)&tagged_ptr->ptr;
1358 *p_tag = *(
volatile size_t *)&tagged_ptr->tag;
1362 static inline void ABTD_atomic_relaxed_store_non_atomic_tagged_ptr(
1363 ABTD_atomic_tagged_ptr *tagged_ptr,
void *ptr,
size_t tag)
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);
1369 *(
void *
volatile *)&tagged_ptr->ptr = ptr;
1370 *(
volatile size_t *)&tagged_ptr->tag = tag;
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)
1377 #ifdef ABT_CONFIG_HAVE_ATOMIC_BUILTIN
1379 *p_ptr = __atomic_load_n(&tagged_ptr->ptr, __ATOMIC_ACQUIRE);
1380 *p_tag = __atomic_load_n(&tagged_ptr->tag, __ATOMIC_ACQUIRE);
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);
1386 __sync_synchronize();
1387 *p_ptr = *(
void *
volatile *)&tagged_ptr->ptr;
1388 *p_tag = *(
volatile size_t *)&tagged_ptr->tag;
1389 __sync_synchronize();
1393 static inline void ABTD_atomic_release_store_non_atomic_tagged_ptr(
1394 ABTD_atomic_tagged_ptr *tagged_ptr,
void *ptr,
size_t tag)
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);
1400 __sync_synchronize();
1401 *(
void *
volatile *)&tagged_ptr->ptr = ptr;
1402 *(
volatile size_t *)&tagged_ptr->tag = tag;
1403 __sync_synchronize();