xref: /netbsd-src/external/bsd/jemalloc.old/include/jemalloc/internal/atomic_c11.h (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1*8e33eff8Schristos #ifndef JEMALLOC_INTERNAL_ATOMIC_C11_H
2*8e33eff8Schristos #define JEMALLOC_INTERNAL_ATOMIC_C11_H
3*8e33eff8Schristos 
4*8e33eff8Schristos #include <stdatomic.h>
5*8e33eff8Schristos 
6*8e33eff8Schristos #define ATOMIC_INIT(...) ATOMIC_VAR_INIT(__VA_ARGS__)
7*8e33eff8Schristos 
8*8e33eff8Schristos #define atomic_memory_order_t memory_order
9*8e33eff8Schristos #define atomic_memory_order_relaxed memory_order_relaxed
10*8e33eff8Schristos #define atomic_memory_order_acquire memory_order_acquire
11*8e33eff8Schristos #define atomic_memory_order_release memory_order_release
12*8e33eff8Schristos #define atomic_memory_order_acq_rel memory_order_acq_rel
13*8e33eff8Schristos #define atomic_memory_order_seq_cst memory_order_seq_cst
14*8e33eff8Schristos 
15*8e33eff8Schristos #define atomic_fence atomic_thread_fence
16*8e33eff8Schristos 
17*8e33eff8Schristos #define JEMALLOC_GENERATE_ATOMICS(type, short_type,			\
18*8e33eff8Schristos     /* unused */ lg_size)						\
19*8e33eff8Schristos typedef _Atomic(type) atomic_##short_type##_t;				\
20*8e33eff8Schristos 									\
21*8e33eff8Schristos ATOMIC_INLINE type							\
22*8e33eff8Schristos atomic_load_##short_type(const atomic_##short_type##_t *a,		\
23*8e33eff8Schristos     atomic_memory_order_t mo) {						\
24*8e33eff8Schristos 	/*								\
25*8e33eff8Schristos 	 * A strict interpretation of the C standard prevents		\
26*8e33eff8Schristos 	 * atomic_load from taking a const argument, but it's		\
27*8e33eff8Schristos 	 * convenient for our purposes. This cast is a workaround.	\
28*8e33eff8Schristos 	 */								\
29*8e33eff8Schristos 	atomic_##short_type##_t* a_nonconst =				\
30*8e33eff8Schristos 	    (atomic_##short_type##_t*)(_Atomic void *)(_Atomic uintptr_t)(a);			\
31*8e33eff8Schristos 	return atomic_load_explicit(a_nonconst, mo);			\
32*8e33eff8Schristos }									\
33*8e33eff8Schristos 									\
34*8e33eff8Schristos ATOMIC_INLINE void							\
35*8e33eff8Schristos atomic_store_##short_type(atomic_##short_type##_t *a,			\
36*8e33eff8Schristos     type val, atomic_memory_order_t mo) {				\
37*8e33eff8Schristos 	atomic_store_explicit(a, val, mo);				\
38*8e33eff8Schristos }									\
39*8e33eff8Schristos 									\
40*8e33eff8Schristos ATOMIC_INLINE type							\
41*8e33eff8Schristos atomic_exchange_##short_type(atomic_##short_type##_t *a, type val,	\
42*8e33eff8Schristos     atomic_memory_order_t mo) {						\
43*8e33eff8Schristos 	return atomic_exchange_explicit(a, val, mo);			\
44*8e33eff8Schristos }									\
45*8e33eff8Schristos 									\
46*8e33eff8Schristos ATOMIC_INLINE bool							\
47*8e33eff8Schristos atomic_compare_exchange_weak_##short_type(atomic_##short_type##_t *a,	\
48*8e33eff8Schristos     type *expected, type desired, atomic_memory_order_t success_mo,	\
49*8e33eff8Schristos     atomic_memory_order_t failure_mo) {					\
50*8e33eff8Schristos 	return atomic_compare_exchange_weak_explicit(a, expected,	\
51*8e33eff8Schristos 	    desired, success_mo, failure_mo);				\
52*8e33eff8Schristos }									\
53*8e33eff8Schristos 									\
54*8e33eff8Schristos ATOMIC_INLINE bool							\
55*8e33eff8Schristos atomic_compare_exchange_strong_##short_type(atomic_##short_type##_t *a,	\
56*8e33eff8Schristos     type *expected, type desired, atomic_memory_order_t success_mo,	\
57*8e33eff8Schristos     atomic_memory_order_t failure_mo) {					\
58*8e33eff8Schristos 	return atomic_compare_exchange_strong_explicit(a, expected,	\
59*8e33eff8Schristos 	    desired, success_mo, failure_mo);				\
60*8e33eff8Schristos }
61*8e33eff8Schristos 
62*8e33eff8Schristos /*
63*8e33eff8Schristos  * Integral types have some special operations available that non-integral ones
64*8e33eff8Schristos  * lack.
65*8e33eff8Schristos  */
66*8e33eff8Schristos #define JEMALLOC_GENERATE_INT_ATOMICS(type, short_type, 		\
67*8e33eff8Schristos     /* unused */ lg_size)						\
68*8e33eff8Schristos JEMALLOC_GENERATE_ATOMICS(type, short_type, /* unused */ lg_size)	\
69*8e33eff8Schristos 									\
70*8e33eff8Schristos ATOMIC_INLINE type							\
71*8e33eff8Schristos atomic_fetch_add_##short_type(atomic_##short_type##_t *a,		\
72*8e33eff8Schristos     type val, atomic_memory_order_t mo) {				\
73*8e33eff8Schristos 	return atomic_fetch_add_explicit(a, val, mo);			\
74*8e33eff8Schristos }									\
75*8e33eff8Schristos 									\
76*8e33eff8Schristos ATOMIC_INLINE type							\
77*8e33eff8Schristos atomic_fetch_sub_##short_type(atomic_##short_type##_t *a,		\
78*8e33eff8Schristos     type val, atomic_memory_order_t mo) {				\
79*8e33eff8Schristos 	return atomic_fetch_sub_explicit(a, val, mo);			\
80*8e33eff8Schristos }									\
81*8e33eff8Schristos ATOMIC_INLINE type							\
82*8e33eff8Schristos atomic_fetch_and_##short_type(atomic_##short_type##_t *a,		\
83*8e33eff8Schristos     type val, atomic_memory_order_t mo) {				\
84*8e33eff8Schristos 	return atomic_fetch_and_explicit(a, val, mo);			\
85*8e33eff8Schristos }									\
86*8e33eff8Schristos ATOMIC_INLINE type							\
87*8e33eff8Schristos atomic_fetch_or_##short_type(atomic_##short_type##_t *a,		\
88*8e33eff8Schristos     type val, atomic_memory_order_t mo) {				\
89*8e33eff8Schristos 	return atomic_fetch_or_explicit(a, val, mo);			\
90*8e33eff8Schristos }									\
91*8e33eff8Schristos ATOMIC_INLINE type							\
92*8e33eff8Schristos atomic_fetch_xor_##short_type(atomic_##short_type##_t *a,		\
93*8e33eff8Schristos     type val, atomic_memory_order_t mo) {				\
94*8e33eff8Schristos 	return atomic_fetch_xor_explicit(a, val, mo);			\
95*8e33eff8Schristos }
96*8e33eff8Schristos 
97*8e33eff8Schristos #endif /* JEMALLOC_INTERNAL_ATOMIC_C11_H */
98