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