1*8e33eff8Schristos #ifndef JEMALLOC_INTERNAL_ATOMIC_GCC_ATOMIC_H 2*8e33eff8Schristos #define JEMALLOC_INTERNAL_ATOMIC_GCC_ATOMIC_H 3*8e33eff8Schristos 4*8e33eff8Schristos #include "jemalloc/internal/assert.h" 5*8e33eff8Schristos 6*8e33eff8Schristos #define ATOMIC_INIT(...) {__VA_ARGS__} 7*8e33eff8Schristos 8*8e33eff8Schristos typedef enum { 9*8e33eff8Schristos atomic_memory_order_relaxed, 10*8e33eff8Schristos atomic_memory_order_acquire, 11*8e33eff8Schristos atomic_memory_order_release, 12*8e33eff8Schristos atomic_memory_order_acq_rel, 13*8e33eff8Schristos atomic_memory_order_seq_cst 14*8e33eff8Schristos } atomic_memory_order_t; 15*8e33eff8Schristos 16*8e33eff8Schristos ATOMIC_INLINE int 17*8e33eff8Schristos atomic_enum_to_builtin(atomic_memory_order_t mo) { 18*8e33eff8Schristos switch (mo) { 19*8e33eff8Schristos case atomic_memory_order_relaxed: 20*8e33eff8Schristos return __ATOMIC_RELAXED; 21*8e33eff8Schristos case atomic_memory_order_acquire: 22*8e33eff8Schristos return __ATOMIC_ACQUIRE; 23*8e33eff8Schristos case atomic_memory_order_release: 24*8e33eff8Schristos return __ATOMIC_RELEASE; 25*8e33eff8Schristos case atomic_memory_order_acq_rel: 26*8e33eff8Schristos return __ATOMIC_ACQ_REL; 27*8e33eff8Schristos case atomic_memory_order_seq_cst: 28*8e33eff8Schristos return __ATOMIC_SEQ_CST; 29*8e33eff8Schristos } 30*8e33eff8Schristos /* Can't happen; the switch is exhaustive. */ 31*8e33eff8Schristos not_reached(); 32*8e33eff8Schristos } 33*8e33eff8Schristos 34*8e33eff8Schristos ATOMIC_INLINE void 35*8e33eff8Schristos atomic_fence(atomic_memory_order_t mo) { 36*8e33eff8Schristos __atomic_thread_fence(atomic_enum_to_builtin(mo)); 37*8e33eff8Schristos } 38*8e33eff8Schristos 39*8e33eff8Schristos #define JEMALLOC_GENERATE_ATOMICS(type, short_type, lg_size) \ 40*8e33eff8Schristos typedef struct { \ 41*8e33eff8Schristos type repr; \ 42*8e33eff8Schristos } atomic_##short_type##_t; \ 43*8e33eff8Schristos \ 44*8e33eff8Schristos ATOMIC_INLINE type \ 45*8e33eff8Schristos atomic_load_##short_type(const atomic_##short_type##_t *a, \ 46*8e33eff8Schristos atomic_memory_order_t mo) { \ 47*8e33eff8Schristos type result; \ 48*8e33eff8Schristos __atomic_load(&a->repr, &result, atomic_enum_to_builtin(mo)); \ 49*8e33eff8Schristos return result; \ 50*8e33eff8Schristos } \ 51*8e33eff8Schristos \ 52*8e33eff8Schristos ATOMIC_INLINE void \ 53*8e33eff8Schristos atomic_store_##short_type(atomic_##short_type##_t *a, type val, \ 54*8e33eff8Schristos atomic_memory_order_t mo) { \ 55*8e33eff8Schristos __atomic_store(&a->repr, &val, atomic_enum_to_builtin(mo)); \ 56*8e33eff8Schristos } \ 57*8e33eff8Schristos \ 58*8e33eff8Schristos ATOMIC_INLINE type \ 59*8e33eff8Schristos atomic_exchange_##short_type(atomic_##short_type##_t *a, type val, \ 60*8e33eff8Schristos atomic_memory_order_t mo) { \ 61*8e33eff8Schristos type result; \ 62*8e33eff8Schristos __atomic_exchange(&a->repr, &val, &result, \ 63*8e33eff8Schristos atomic_enum_to_builtin(mo)); \ 64*8e33eff8Schristos return result; \ 65*8e33eff8Schristos } \ 66*8e33eff8Schristos \ 67*8e33eff8Schristos ATOMIC_INLINE bool \ 68*8e33eff8Schristos atomic_compare_exchange_weak_##short_type(atomic_##short_type##_t *a, \ 69*8e33eff8Schristos type *expected, type desired, atomic_memory_order_t success_mo, \ 70*8e33eff8Schristos atomic_memory_order_t failure_mo) { \ 71*8e33eff8Schristos return __atomic_compare_exchange(&a->repr, expected, &desired, \ 72*8e33eff8Schristos true, atomic_enum_to_builtin(success_mo), \ 73*8e33eff8Schristos atomic_enum_to_builtin(failure_mo)); \ 74*8e33eff8Schristos } \ 75*8e33eff8Schristos \ 76*8e33eff8Schristos ATOMIC_INLINE bool \ 77*8e33eff8Schristos atomic_compare_exchange_strong_##short_type(atomic_##short_type##_t *a, \ 78*8e33eff8Schristos type *expected, type desired, atomic_memory_order_t success_mo, \ 79*8e33eff8Schristos atomic_memory_order_t failure_mo) { \ 80*8e33eff8Schristos return __atomic_compare_exchange(&a->repr, expected, &desired, \ 81*8e33eff8Schristos false, \ 82*8e33eff8Schristos atomic_enum_to_builtin(success_mo), \ 83*8e33eff8Schristos atomic_enum_to_builtin(failure_mo)); \ 84*8e33eff8Schristos } 85*8e33eff8Schristos 86*8e33eff8Schristos 87*8e33eff8Schristos #define JEMALLOC_GENERATE_INT_ATOMICS(type, short_type, lg_size) \ 88*8e33eff8Schristos JEMALLOC_GENERATE_ATOMICS(type, short_type, /* unused */ lg_size) \ 89*8e33eff8Schristos \ 90*8e33eff8Schristos ATOMIC_INLINE type \ 91*8e33eff8Schristos atomic_fetch_add_##short_type(atomic_##short_type##_t *a, type val, \ 92*8e33eff8Schristos atomic_memory_order_t mo) { \ 93*8e33eff8Schristos return __atomic_fetch_add(&a->repr, val, \ 94*8e33eff8Schristos atomic_enum_to_builtin(mo)); \ 95*8e33eff8Schristos } \ 96*8e33eff8Schristos \ 97*8e33eff8Schristos ATOMIC_INLINE type \ 98*8e33eff8Schristos atomic_fetch_sub_##short_type(atomic_##short_type##_t *a, type val, \ 99*8e33eff8Schristos atomic_memory_order_t mo) { \ 100*8e33eff8Schristos return __atomic_fetch_sub(&a->repr, val, \ 101*8e33eff8Schristos atomic_enum_to_builtin(mo)); \ 102*8e33eff8Schristos } \ 103*8e33eff8Schristos \ 104*8e33eff8Schristos ATOMIC_INLINE type \ 105*8e33eff8Schristos atomic_fetch_and_##short_type(atomic_##short_type##_t *a, type val, \ 106*8e33eff8Schristos atomic_memory_order_t mo) { \ 107*8e33eff8Schristos return __atomic_fetch_and(&a->repr, val, \ 108*8e33eff8Schristos atomic_enum_to_builtin(mo)); \ 109*8e33eff8Schristos } \ 110*8e33eff8Schristos \ 111*8e33eff8Schristos ATOMIC_INLINE type \ 112*8e33eff8Schristos atomic_fetch_or_##short_type(atomic_##short_type##_t *a, type val, \ 113*8e33eff8Schristos atomic_memory_order_t mo) { \ 114*8e33eff8Schristos return __atomic_fetch_or(&a->repr, val, \ 115*8e33eff8Schristos atomic_enum_to_builtin(mo)); \ 116*8e33eff8Schristos } \ 117*8e33eff8Schristos \ 118*8e33eff8Schristos ATOMIC_INLINE type \ 119*8e33eff8Schristos atomic_fetch_xor_##short_type(atomic_##short_type##_t *a, type val, \ 120*8e33eff8Schristos atomic_memory_order_t mo) { \ 121*8e33eff8Schristos return __atomic_fetch_xor(&a->repr, val, \ 122*8e33eff8Schristos atomic_enum_to_builtin(mo)); \ 123*8e33eff8Schristos } 124*8e33eff8Schristos 125*8e33eff8Schristos #endif /* JEMALLOC_INTERNAL_ATOMIC_GCC_ATOMIC_H */ 126