1 #ifndef JEMALLOC_INTERNAL_ATOMIC_C11_H 2 #define JEMALLOC_INTERNAL_ATOMIC_C11_H 3 4 #include <stdatomic.h> 5 6 #define ATOMIC_INIT(...) ATOMIC_VAR_INIT(__VA_ARGS__) 7 8 #define atomic_memory_order_t memory_order 9 #define atomic_memory_order_relaxed memory_order_relaxed 10 #define atomic_memory_order_acquire memory_order_acquire 11 #define atomic_memory_order_release memory_order_release 12 #define atomic_memory_order_acq_rel memory_order_acq_rel 13 #define atomic_memory_order_seq_cst memory_order_seq_cst 14 15 #define atomic_fence atomic_thread_fence 16 17 #define JEMALLOC_GENERATE_ATOMICS(type, short_type, \ 18 /* unused */ lg_size) \ 19 typedef _Atomic(type) atomic_##short_type##_t; \ 20 \ 21 ATOMIC_INLINE type \ 22 atomic_load_##short_type(const atomic_##short_type##_t *a, \ 23 atomic_memory_order_t mo) { \ 24 /* \ 25 * A strict interpretation of the C standard prevents \ 26 * atomic_load from taking a const argument, but it's \ 27 * convenient for our purposes. This cast is a workaround. \ 28 */ \ 29 atomic_##short_type##_t* a_nonconst = \ 30 (atomic_##short_type##_t*)a; \ 31 return atomic_load_explicit(a_nonconst, mo); \ 32 } \ 33 \ 34 ATOMIC_INLINE void \ 35 atomic_store_##short_type(atomic_##short_type##_t *a, \ 36 type val, atomic_memory_order_t mo) { \ 37 atomic_store_explicit(a, val, mo); \ 38 } \ 39 \ 40 ATOMIC_INLINE type \ 41 atomic_exchange_##short_type(atomic_##short_type##_t *a, type val, \ 42 atomic_memory_order_t mo) { \ 43 return atomic_exchange_explicit(a, val, mo); \ 44 } \ 45 \ 46 ATOMIC_INLINE bool \ 47 atomic_compare_exchange_weak_##short_type(atomic_##short_type##_t *a, \ 48 type *expected, type desired, atomic_memory_order_t success_mo, \ 49 atomic_memory_order_t failure_mo) { \ 50 return atomic_compare_exchange_weak_explicit(a, expected, \ 51 desired, success_mo, failure_mo); \ 52 } \ 53 \ 54 ATOMIC_INLINE bool \ 55 atomic_compare_exchange_strong_##short_type(atomic_##short_type##_t *a, \ 56 type *expected, type desired, atomic_memory_order_t success_mo, \ 57 atomic_memory_order_t failure_mo) { \ 58 return atomic_compare_exchange_strong_explicit(a, expected, \ 59 desired, success_mo, failure_mo); \ 60 } 61 62 /* 63 * Integral types have some special operations available that non-integral ones 64 * lack. 65 */ 66 #define JEMALLOC_GENERATE_INT_ATOMICS(type, short_type, \ 67 /* unused */ lg_size) \ 68 JEMALLOC_GENERATE_ATOMICS(type, short_type, /* unused */ lg_size) \ 69 \ 70 ATOMIC_INLINE type \ 71 atomic_fetch_add_##short_type(atomic_##short_type##_t *a, \ 72 type val, atomic_memory_order_t mo) { \ 73 return atomic_fetch_add_explicit(a, val, mo); \ 74 } \ 75 \ 76 ATOMIC_INLINE type \ 77 atomic_fetch_sub_##short_type(atomic_##short_type##_t *a, \ 78 type val, atomic_memory_order_t mo) { \ 79 return atomic_fetch_sub_explicit(a, val, mo); \ 80 } \ 81 ATOMIC_INLINE type \ 82 atomic_fetch_and_##short_type(atomic_##short_type##_t *a, \ 83 type val, atomic_memory_order_t mo) { \ 84 return atomic_fetch_and_explicit(a, val, mo); \ 85 } \ 86 ATOMIC_INLINE type \ 87 atomic_fetch_or_##short_type(atomic_##short_type##_t *a, \ 88 type val, atomic_memory_order_t mo) { \ 89 return atomic_fetch_or_explicit(a, val, mo); \ 90 } \ 91 ATOMIC_INLINE type \ 92 atomic_fetch_xor_##short_type(atomic_##short_type##_t *a, \ 93 type val, atomic_memory_order_t mo) { \ 94 return atomic_fetch_xor_explicit(a, val, mo); \ 95 } 96 97 #endif /* JEMALLOC_INTERNAL_ATOMIC_C11_H */ 98