1*8e33eff8Schristos #ifndef JEMALLOC_INTERNAL_ATOMIC_H 2*8e33eff8Schristos #define JEMALLOC_INTERNAL_ATOMIC_H 3*8e33eff8Schristos 4*8e33eff8Schristos #define ATOMIC_INLINE static inline 5*8e33eff8Schristos 6*8e33eff8Schristos #if defined(JEMALLOC_GCC_ATOMIC_ATOMICS) 7*8e33eff8Schristos # include "jemalloc/internal/atomic_gcc_atomic.h" 8*8e33eff8Schristos #elif defined(JEMALLOC_GCC_SYNC_ATOMICS) 9*8e33eff8Schristos # include "jemalloc/internal/atomic_gcc_sync.h" 10*8e33eff8Schristos #elif defined(_MSC_VER) 11*8e33eff8Schristos # include "jemalloc/internal/atomic_msvc.h" 12*8e33eff8Schristos #elif defined(JEMALLOC_C11_ATOMICS) 13*8e33eff8Schristos # include "jemalloc/internal/atomic_c11.h" 14*8e33eff8Schristos #else 15*8e33eff8Schristos # error "Don't have atomics implemented on this platform." 16*8e33eff8Schristos #endif 17*8e33eff8Schristos 18*8e33eff8Schristos /* 19*8e33eff8Schristos * This header gives more or less a backport of C11 atomics. The user can write 20*8e33eff8Schristos * JEMALLOC_GENERATE_ATOMICS(type, short_type, lg_sizeof_type); to generate 21*8e33eff8Schristos * counterparts of the C11 atomic functions for type, as so: 22*8e33eff8Schristos * JEMALLOC_GENERATE_ATOMICS(int *, pi, 3); 23*8e33eff8Schristos * and then write things like: 24*8e33eff8Schristos * int *some_ptr; 25*8e33eff8Schristos * atomic_pi_t atomic_ptr_to_int; 26*8e33eff8Schristos * atomic_store_pi(&atomic_ptr_to_int, some_ptr, ATOMIC_RELAXED); 27*8e33eff8Schristos * int *prev_value = atomic_exchange_pi(&ptr_to_int, NULL, ATOMIC_ACQ_REL); 28*8e33eff8Schristos * assert(some_ptr == prev_value); 29*8e33eff8Schristos * and expect things to work in the obvious way. 30*8e33eff8Schristos * 31*8e33eff8Schristos * Also included (with naming differences to avoid conflicts with the standard 32*8e33eff8Schristos * library): 33*8e33eff8Schristos * atomic_fence(atomic_memory_order_t) (mimics C11's atomic_thread_fence). 34*8e33eff8Schristos * ATOMIC_INIT (mimics C11's ATOMIC_VAR_INIT). 35*8e33eff8Schristos */ 36*8e33eff8Schristos 37*8e33eff8Schristos /* 38*8e33eff8Schristos * Pure convenience, so that we don't have to type "atomic_memory_order_" 39*8e33eff8Schristos * quite so often. 40*8e33eff8Schristos */ 41*8e33eff8Schristos #define ATOMIC_RELAXED atomic_memory_order_relaxed 42*8e33eff8Schristos #define ATOMIC_ACQUIRE atomic_memory_order_acquire 43*8e33eff8Schristos #define ATOMIC_RELEASE atomic_memory_order_release 44*8e33eff8Schristos #define ATOMIC_ACQ_REL atomic_memory_order_acq_rel 45*8e33eff8Schristos #define ATOMIC_SEQ_CST atomic_memory_order_seq_cst 46*8e33eff8Schristos 47*8e33eff8Schristos /* 48*8e33eff8Schristos * Not all platforms have 64-bit atomics. If we do, this #define exposes that 49*8e33eff8Schristos * fact. 50*8e33eff8Schristos */ 51*8e33eff8Schristos #if (LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3) 52*8e33eff8Schristos # define JEMALLOC_ATOMIC_U64 53*8e33eff8Schristos #endif 54*8e33eff8Schristos 55*8e33eff8Schristos JEMALLOC_GENERATE_ATOMICS(void *, p, LG_SIZEOF_PTR) 56*8e33eff8Schristos 57*8e33eff8Schristos /* 58*8e33eff8Schristos * There's no actual guarantee that sizeof(bool) == 1, but it's true on the only 59*8e33eff8Schristos * platform that actually needs to know the size, MSVC. 60*8e33eff8Schristos */ 61*8e33eff8Schristos JEMALLOC_GENERATE_ATOMICS(bool, b, 0) 62*8e33eff8Schristos 63*8e33eff8Schristos JEMALLOC_GENERATE_INT_ATOMICS(unsigned, u, LG_SIZEOF_INT) 64*8e33eff8Schristos 65*8e33eff8Schristos JEMALLOC_GENERATE_INT_ATOMICS(size_t, zu, LG_SIZEOF_PTR) 66*8e33eff8Schristos 67*8e33eff8Schristos JEMALLOC_GENERATE_INT_ATOMICS(ssize_t, zd, LG_SIZEOF_PTR) 68*8e33eff8Schristos 69*8e33eff8Schristos JEMALLOC_GENERATE_INT_ATOMICS(uint32_t, u32, 2) 70*8e33eff8Schristos 71*8e33eff8Schristos #ifdef JEMALLOC_ATOMIC_U64 72*8e33eff8Schristos JEMALLOC_GENERATE_INT_ATOMICS(uint64_t, u64, 3) 73*8e33eff8Schristos #endif 74*8e33eff8Schristos 75*8e33eff8Schristos #undef ATOMIC_INLINE 76*8e33eff8Schristos 77*8e33eff8Schristos #endif /* JEMALLOC_INTERNAL_ATOMIC_H */ 78