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