xref: /netbsd-src/external/bsd/jemalloc.old/include/jemalloc/internal/atomic_gcc_atomic.h (revision 8e33eff89e26cf71871ead62f0d5063e1313c33a)
1*8e33eff8Schristos #ifndef JEMALLOC_INTERNAL_ATOMIC_GCC_ATOMIC_H
2*8e33eff8Schristos #define JEMALLOC_INTERNAL_ATOMIC_GCC_ATOMIC_H
3*8e33eff8Schristos 
4*8e33eff8Schristos #include "jemalloc/internal/assert.h"
5*8e33eff8Schristos 
6*8e33eff8Schristos #define ATOMIC_INIT(...) {__VA_ARGS__}
7*8e33eff8Schristos 
8*8e33eff8Schristos typedef enum {
9*8e33eff8Schristos 	atomic_memory_order_relaxed,
10*8e33eff8Schristos 	atomic_memory_order_acquire,
11*8e33eff8Schristos 	atomic_memory_order_release,
12*8e33eff8Schristos 	atomic_memory_order_acq_rel,
13*8e33eff8Schristos 	atomic_memory_order_seq_cst
14*8e33eff8Schristos } atomic_memory_order_t;
15*8e33eff8Schristos 
16*8e33eff8Schristos ATOMIC_INLINE int
17*8e33eff8Schristos atomic_enum_to_builtin(atomic_memory_order_t mo) {
18*8e33eff8Schristos 	switch (mo) {
19*8e33eff8Schristos 	case atomic_memory_order_relaxed:
20*8e33eff8Schristos 		return __ATOMIC_RELAXED;
21*8e33eff8Schristos 	case atomic_memory_order_acquire:
22*8e33eff8Schristos 		return __ATOMIC_ACQUIRE;
23*8e33eff8Schristos 	case atomic_memory_order_release:
24*8e33eff8Schristos 		return __ATOMIC_RELEASE;
25*8e33eff8Schristos 	case atomic_memory_order_acq_rel:
26*8e33eff8Schristos 		return __ATOMIC_ACQ_REL;
27*8e33eff8Schristos 	case atomic_memory_order_seq_cst:
28*8e33eff8Schristos 		return __ATOMIC_SEQ_CST;
29*8e33eff8Schristos 	}
30*8e33eff8Schristos 	/* Can't happen; the switch is exhaustive. */
31*8e33eff8Schristos 	not_reached();
32*8e33eff8Schristos }
33*8e33eff8Schristos 
34*8e33eff8Schristos ATOMIC_INLINE void
35*8e33eff8Schristos atomic_fence(atomic_memory_order_t mo) {
36*8e33eff8Schristos 	__atomic_thread_fence(atomic_enum_to_builtin(mo));
37*8e33eff8Schristos }
38*8e33eff8Schristos 
39*8e33eff8Schristos #define JEMALLOC_GENERATE_ATOMICS(type, short_type, lg_size)		\
40*8e33eff8Schristos typedef struct {							\
41*8e33eff8Schristos 	type repr;							\
42*8e33eff8Schristos } atomic_##short_type##_t;						\
43*8e33eff8Schristos 									\
44*8e33eff8Schristos ATOMIC_INLINE type							\
45*8e33eff8Schristos atomic_load_##short_type(const atomic_##short_type##_t *a,		\
46*8e33eff8Schristos     atomic_memory_order_t mo) {						\
47*8e33eff8Schristos 	type result;							\
48*8e33eff8Schristos 	__atomic_load(&a->repr, &result, atomic_enum_to_builtin(mo));	\
49*8e33eff8Schristos 	return result;							\
50*8e33eff8Schristos }									\
51*8e33eff8Schristos 									\
52*8e33eff8Schristos ATOMIC_INLINE void							\
53*8e33eff8Schristos atomic_store_##short_type(atomic_##short_type##_t *a, type val,		\
54*8e33eff8Schristos     atomic_memory_order_t mo) {						\
55*8e33eff8Schristos 	__atomic_store(&a->repr, &val, atomic_enum_to_builtin(mo));	\
56*8e33eff8Schristos }									\
57*8e33eff8Schristos 									\
58*8e33eff8Schristos ATOMIC_INLINE type							\
59*8e33eff8Schristos atomic_exchange_##short_type(atomic_##short_type##_t *a, type val,	\
60*8e33eff8Schristos     atomic_memory_order_t mo) {						\
61*8e33eff8Schristos 	type result;							\
62*8e33eff8Schristos 	__atomic_exchange(&a->repr, &val, &result,			\
63*8e33eff8Schristos 	    atomic_enum_to_builtin(mo));				\
64*8e33eff8Schristos 	return result;							\
65*8e33eff8Schristos }									\
66*8e33eff8Schristos 									\
67*8e33eff8Schristos ATOMIC_INLINE bool							\
68*8e33eff8Schristos atomic_compare_exchange_weak_##short_type(atomic_##short_type##_t *a,	\
69*8e33eff8Schristos     type *expected, type desired, atomic_memory_order_t success_mo,	\
70*8e33eff8Schristos     atomic_memory_order_t failure_mo) {					\
71*8e33eff8Schristos 	return __atomic_compare_exchange(&a->repr, expected, &desired,	\
72*8e33eff8Schristos 	    true, atomic_enum_to_builtin(success_mo),			\
73*8e33eff8Schristos 	    atomic_enum_to_builtin(failure_mo));			\
74*8e33eff8Schristos }									\
75*8e33eff8Schristos 									\
76*8e33eff8Schristos ATOMIC_INLINE bool							\
77*8e33eff8Schristos atomic_compare_exchange_strong_##short_type(atomic_##short_type##_t *a,	\
78*8e33eff8Schristos     type *expected, type desired, atomic_memory_order_t success_mo,	\
79*8e33eff8Schristos     atomic_memory_order_t failure_mo) {					\
80*8e33eff8Schristos 	return __atomic_compare_exchange(&a->repr, expected, &desired,	\
81*8e33eff8Schristos 	    false,							\
82*8e33eff8Schristos 	    atomic_enum_to_builtin(success_mo),				\
83*8e33eff8Schristos 	    atomic_enum_to_builtin(failure_mo));			\
84*8e33eff8Schristos }
85*8e33eff8Schristos 
86*8e33eff8Schristos 
87*8e33eff8Schristos #define JEMALLOC_GENERATE_INT_ATOMICS(type, short_type,	lg_size)	\
88*8e33eff8Schristos JEMALLOC_GENERATE_ATOMICS(type, short_type, /* unused */ lg_size)	\
89*8e33eff8Schristos 									\
90*8e33eff8Schristos ATOMIC_INLINE type							\
91*8e33eff8Schristos atomic_fetch_add_##short_type(atomic_##short_type##_t *a, type val,	\
92*8e33eff8Schristos     atomic_memory_order_t mo) {						\
93*8e33eff8Schristos 	return __atomic_fetch_add(&a->repr, val,			\
94*8e33eff8Schristos 	    atomic_enum_to_builtin(mo));				\
95*8e33eff8Schristos }									\
96*8e33eff8Schristos 									\
97*8e33eff8Schristos ATOMIC_INLINE type							\
98*8e33eff8Schristos atomic_fetch_sub_##short_type(atomic_##short_type##_t *a, type val,	\
99*8e33eff8Schristos     atomic_memory_order_t mo) {						\
100*8e33eff8Schristos 	return __atomic_fetch_sub(&a->repr, val,			\
101*8e33eff8Schristos 	    atomic_enum_to_builtin(mo));				\
102*8e33eff8Schristos }									\
103*8e33eff8Schristos 									\
104*8e33eff8Schristos ATOMIC_INLINE type							\
105*8e33eff8Schristos atomic_fetch_and_##short_type(atomic_##short_type##_t *a, type val,	\
106*8e33eff8Schristos     atomic_memory_order_t mo) {						\
107*8e33eff8Schristos 	return __atomic_fetch_and(&a->repr, val,			\
108*8e33eff8Schristos 	    atomic_enum_to_builtin(mo));				\
109*8e33eff8Schristos }									\
110*8e33eff8Schristos 									\
111*8e33eff8Schristos ATOMIC_INLINE type							\
112*8e33eff8Schristos atomic_fetch_or_##short_type(atomic_##short_type##_t *a, type val,	\
113*8e33eff8Schristos     atomic_memory_order_t mo) {						\
114*8e33eff8Schristos 	return __atomic_fetch_or(&a->repr, val,				\
115*8e33eff8Schristos 	    atomic_enum_to_builtin(mo));				\
116*8e33eff8Schristos }									\
117*8e33eff8Schristos 									\
118*8e33eff8Schristos ATOMIC_INLINE type							\
119*8e33eff8Schristos atomic_fetch_xor_##short_type(atomic_##short_type##_t *a, type val,	\
120*8e33eff8Schristos     atomic_memory_order_t mo) {						\
121*8e33eff8Schristos 	return __atomic_fetch_xor(&a->repr, val,			\
122*8e33eff8Schristos 	    atomic_enum_to_builtin(mo));				\
123*8e33eff8Schristos }
124*8e33eff8Schristos 
125*8e33eff8Schristos #endif /* JEMALLOC_INTERNAL_ATOMIC_GCC_ATOMIC_H */
126