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) \ 19typedef _Atomic(type) atomic_##short_type##_t; \ 20 \ 21ATOMIC_INLINE type \ 22atomic_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*)(_Atomic void *)(_Atomic uintptr_t)(a); \ 31 return atomic_load_explicit(a_nonconst, mo); \ 32} \ 33 \ 34ATOMIC_INLINE void \ 35atomic_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 \ 40ATOMIC_INLINE type \ 41atomic_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 \ 46ATOMIC_INLINE bool \ 47atomic_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 \ 54ATOMIC_INLINE bool \ 55atomic_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) \ 68JEMALLOC_GENERATE_ATOMICS(type, short_type, /* unused */ lg_size) \ 69 \ 70ATOMIC_INLINE type \ 71atomic_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 \ 76ATOMIC_INLINE type \ 77atomic_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} \ 81ATOMIC_INLINE type \ 82atomic_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} \ 86ATOMIC_INLINE type \ 87atomic_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} \ 91ATOMIC_INLINE type \ 92atomic_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