atomic.h 3.5 KB

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