1b7eaed25SJason Evans #ifndef JEMALLOC_INTERNAL_ATOMIC_H 2b7eaed25SJason Evans #define JEMALLOC_INTERNAL_ATOMIC_H 3a4bd5210SJason Evans 4c5ad8142SEric van Gyzen #define ATOMIC_INLINE JEMALLOC_ALWAYS_INLINE 5a4bd5210SJason Evans 6c5ad8142SEric van Gyzen #define JEMALLOC_U8_ATOMICS 7b7eaed25SJason Evans #if defined(JEMALLOC_GCC_ATOMIC_ATOMICS) 8b7eaed25SJason Evans # include "jemalloc/internal/atomic_gcc_atomic.h" 9c5ad8142SEric van Gyzen # if !defined(JEMALLOC_GCC_U8_ATOMIC_ATOMICS) 10c5ad8142SEric van Gyzen # undef JEMALLOC_U8_ATOMICS 11c5ad8142SEric van Gyzen # endif 12b7eaed25SJason Evans #elif defined(JEMALLOC_GCC_SYNC_ATOMICS) 13b7eaed25SJason Evans # include "jemalloc/internal/atomic_gcc_sync.h" 14c5ad8142SEric van Gyzen # if !defined(JEMALLOC_GCC_U8_SYNC_ATOMICS) 15c5ad8142SEric van Gyzen # undef JEMALLOC_U8_ATOMICS 16c5ad8142SEric van Gyzen # endif 17b7eaed25SJason Evans #elif defined(_MSC_VER) 18b7eaed25SJason Evans # include "jemalloc/internal/atomic_msvc.h" 19b7eaed25SJason Evans #elif defined(JEMALLOC_C11_ATOMICS) 20b7eaed25SJason Evans # include "jemalloc/internal/atomic_c11.h" 21b7eaed25SJason Evans #else 22b7eaed25SJason Evans # error "Don't have atomics implemented on this platform." 23b7eaed25SJason Evans #endif 24a4bd5210SJason Evans 25d0e79aa3SJason Evans /* 26b7eaed25SJason Evans * This header gives more or less a backport of C11 atomics. The user can write 27b7eaed25SJason Evans * JEMALLOC_GENERATE_ATOMICS(type, short_type, lg_sizeof_type); to generate 28b7eaed25SJason Evans * counterparts of the C11 atomic functions for type, as so: 29b7eaed25SJason Evans * JEMALLOC_GENERATE_ATOMICS(int *, pi, 3); 30b7eaed25SJason Evans * and then write things like: 31b7eaed25SJason Evans * int *some_ptr; 32b7eaed25SJason Evans * atomic_pi_t atomic_ptr_to_int; 33b7eaed25SJason Evans * atomic_store_pi(&atomic_ptr_to_int, some_ptr, ATOMIC_RELAXED); 34b7eaed25SJason Evans * int *prev_value = atomic_exchange_pi(&ptr_to_int, NULL, ATOMIC_ACQ_REL); 35b7eaed25SJason Evans * assert(some_ptr == prev_value); 36b7eaed25SJason Evans * and expect things to work in the obvious way. 37d0e79aa3SJason Evans * 38b7eaed25SJason Evans * Also included (with naming differences to avoid conflicts with the standard 39b7eaed25SJason Evans * library): 40b7eaed25SJason Evans * atomic_fence(atomic_memory_order_t) (mimics C11's atomic_thread_fence). 41b7eaed25SJason Evans * ATOMIC_INIT (mimics C11's ATOMIC_VAR_INIT). 42d0e79aa3SJason Evans */ 43d0e79aa3SJason Evans 44c92c6224SJason Evans /* 45b7eaed25SJason Evans * Pure convenience, so that we don't have to type "atomic_memory_order_" 46b7eaed25SJason Evans * quite so often. 47c92c6224SJason Evans */ 48b7eaed25SJason Evans #define ATOMIC_RELAXED atomic_memory_order_relaxed 49b7eaed25SJason Evans #define ATOMIC_ACQUIRE atomic_memory_order_acquire 50b7eaed25SJason Evans #define ATOMIC_RELEASE atomic_memory_order_release 51b7eaed25SJason Evans #define ATOMIC_ACQ_REL atomic_memory_order_acq_rel 52b7eaed25SJason Evans #define ATOMIC_SEQ_CST atomic_memory_order_seq_cst 53c92c6224SJason Evans 54b7eaed25SJason Evans /* 55*c43cad87SWarner Losh * Another convenience -- simple atomic helper functions. 56*c43cad87SWarner Losh */ 57*c43cad87SWarner Losh #define JEMALLOC_GENERATE_EXPANDED_INT_ATOMICS(type, short_type, \ 58*c43cad87SWarner Losh lg_size) \ 59*c43cad87SWarner Losh JEMALLOC_GENERATE_INT_ATOMICS(type, short_type, lg_size) \ 60*c43cad87SWarner Losh ATOMIC_INLINE void \ 61*c43cad87SWarner Losh atomic_load_add_store_##short_type(atomic_##short_type##_t *a, \ 62*c43cad87SWarner Losh type inc) { \ 63*c43cad87SWarner Losh type oldval = atomic_load_##short_type(a, ATOMIC_RELAXED); \ 64*c43cad87SWarner Losh type newval = oldval + inc; \ 65*c43cad87SWarner Losh atomic_store_##short_type(a, newval, ATOMIC_RELAXED); \ 66*c43cad87SWarner Losh } \ 67*c43cad87SWarner Losh ATOMIC_INLINE void \ 68*c43cad87SWarner Losh atomic_load_sub_store_##short_type(atomic_##short_type##_t *a, \ 69*c43cad87SWarner Losh type inc) { \ 70*c43cad87SWarner Losh type oldval = atomic_load_##short_type(a, ATOMIC_RELAXED); \ 71*c43cad87SWarner Losh type newval = oldval - inc; \ 72*c43cad87SWarner Losh atomic_store_##short_type(a, newval, ATOMIC_RELAXED); \ 73*c43cad87SWarner Losh } 74*c43cad87SWarner Losh 75*c43cad87SWarner Losh /* 76b7eaed25SJason Evans * Not all platforms have 64-bit atomics. If we do, this #define exposes that 77b7eaed25SJason Evans * fact. 78b7eaed25SJason Evans */ 79b7eaed25SJason Evans #if (LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3) 80b7eaed25SJason Evans # define JEMALLOC_ATOMIC_U64 81a4bd5210SJason Evans #endif 82a4bd5210SJason Evans 83b7eaed25SJason Evans JEMALLOC_GENERATE_ATOMICS(void *, p, LG_SIZEOF_PTR) 84a4bd5210SJason Evans 85b7eaed25SJason Evans /* 86b7eaed25SJason Evans * There's no actual guarantee that sizeof(bool) == 1, but it's true on the only 87b7eaed25SJason Evans * platform that actually needs to know the size, MSVC. 88b7eaed25SJason Evans */ 89b7eaed25SJason Evans JEMALLOC_GENERATE_ATOMICS(bool, b, 0) 90a4bd5210SJason Evans 91*c43cad87SWarner Losh JEMALLOC_GENERATE_EXPANDED_INT_ATOMICS(unsigned, u, LG_SIZEOF_INT) 92a4bd5210SJason Evans 93*c43cad87SWarner Losh JEMALLOC_GENERATE_EXPANDED_INT_ATOMICS(size_t, zu, LG_SIZEOF_PTR) 94a4bd5210SJason Evans 95*c43cad87SWarner Losh JEMALLOC_GENERATE_EXPANDED_INT_ATOMICS(ssize_t, zd, LG_SIZEOF_PTR) 96a4bd5210SJason Evans 97*c43cad87SWarner Losh JEMALLOC_GENERATE_EXPANDED_INT_ATOMICS(uint8_t, u8, 0) 98c5ad8142SEric van Gyzen 99*c43cad87SWarner Losh JEMALLOC_GENERATE_EXPANDED_INT_ATOMICS(uint32_t, u32, 2) 100d0e79aa3SJason Evans 101b7eaed25SJason Evans #ifdef JEMALLOC_ATOMIC_U64 102*c43cad87SWarner Losh JEMALLOC_GENERATE_EXPANDED_INT_ATOMICS(uint64_t, u64, 3) 103a4bd5210SJason Evans #endif 104a4bd5210SJason Evans 105b7eaed25SJason Evans #undef ATOMIC_INLINE 106d0e79aa3SJason Evans 107b7eaed25SJason Evans #endif /* JEMALLOC_INTERNAL_ATOMIC_H */ 108