23 #ifndef INSIDE_ATOMICS_H
24 #error "should be included via atomics.h"
30 #define pg_compiler_barrier_impl() __asm__ __volatile__("" ::: "memory")
37 #if !defined(pg_memory_barrier_impl)
38 # if defined(HAVE_GCC__ATOMIC_INT32_CAS)
39 # define pg_memory_barrier_impl() __atomic_thread_fence(__ATOMIC_SEQ_CST)
40 # elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
41 # define pg_memory_barrier_impl() __sync_synchronize()
45 #if !defined(pg_read_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT32_CAS)
47 # define pg_read_barrier_impl() __atomic_thread_fence(__ATOMIC_ACQUIRE)
50 #if !defined(pg_write_barrier_impl) && defined(HAVE_GCC__ATOMIC_INT32_CAS)
52 # define pg_write_barrier_impl() __atomic_thread_fence(__ATOMIC_RELEASE)
59 #if !defined(PG_HAVE_ATOMIC_FLAG_SUPPORT) \
60 && (defined(HAVE_GCC__SYNC_INT32_TAS) || defined(HAVE_GCC__SYNC_CHAR_TAS))
62 #define PG_HAVE_ATOMIC_FLAG_SUPPORT
70 #ifdef HAVE_GCC__SYNC_INT32_TAS
80 #if !defined(PG_HAVE_ATOMIC_U32_SUPPORT) \
81 && (defined(HAVE_GCC__ATOMIC_INT32_CAS) || defined(HAVE_GCC__SYNC_INT32_CAS))
83 #define PG_HAVE_ATOMIC_U32_SUPPORT
92 #if !defined(PG_HAVE_ATOMIC_U64_SUPPORT) \
93 && !defined(PG_DISABLE_64_BIT_ATOMICS) \
94 && (defined(HAVE_GCC__ATOMIC_INT64_CAS) || defined(HAVE_GCC__SYNC_INT64_CAS))
96 #define PG_HAVE_ATOMIC_U64_SUPPORT
100 volatile uint64
value pg_attribute_aligned(8);
105 #ifdef PG_HAVE_ATOMIC_FLAG_SUPPORT
107 #if defined(HAVE_GCC__SYNC_CHAR_TAS) || defined(HAVE_GCC__SYNC_INT32_TAS)
109 #ifndef PG_HAVE_ATOMIC_TEST_SET_FLAG
110 #define PG_HAVE_ATOMIC_TEST_SET_FLAG
116 return __sync_lock_test_and_set(&ptr->
value, 1) == 0;
122 #ifndef PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG
123 #define PG_HAVE_ATOMIC_UNLOCKED_TEST_FLAG
127 return ptr->
value == 0;
131 #ifndef PG_HAVE_ATOMIC_CLEAR_FLAG
132 #define PG_HAVE_ATOMIC_CLEAR_FLAG
136 __sync_lock_release(&ptr->
value);
140 #ifndef PG_HAVE_ATOMIC_INIT_FLAG
141 #define PG_HAVE_ATOMIC_INIT_FLAG
152 #if !defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) && defined(HAVE_GCC__ATOMIC_INT32_CAS)
153 #define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
159 return __atomic_compare_exchange_n(&ptr->
value, expected,
newval,
false,
160 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
164 #if !defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
165 #define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U32
172 current = __sync_val_compare_and_swap(&ptr->
value, *expected,
newval);
173 ret = current == *expected;
187 #if !defined(PG_HAVE_ATOMIC_EXCHANGE_U32) && defined(HAVE_GCC__ATOMIC_INT32_CAS)
188 #define PG_HAVE_ATOMIC_EXCHANGE_U32
192 return __atomic_exchange_n(&ptr->
value,
newval, __ATOMIC_SEQ_CST);
198 #if !defined(PG_HAVE_ATOMIC_FETCH_ADD_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
199 #define PG_HAVE_ATOMIC_FETCH_ADD_U32
203 return __sync_fetch_and_add(&ptr->
value, add_);
207 #if !defined(PG_HAVE_ATOMIC_FETCH_SUB_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
208 #define PG_HAVE_ATOMIC_FETCH_SUB_U32
212 return __sync_fetch_and_sub(&ptr->
value, sub_);
216 #if !defined(PG_HAVE_ATOMIC_FETCH_AND_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
217 #define PG_HAVE_ATOMIC_FETCH_AND_U32
221 return __sync_fetch_and_and(&ptr->
value, and_);
225 #if !defined(PG_HAVE_ATOMIC_FETCH_OR_U32) && defined(HAVE_GCC__SYNC_INT32_CAS)
226 #define PG_HAVE_ATOMIC_FETCH_OR_U32
230 return __sync_fetch_and_or(&ptr->
value, or_);
235 #if !defined(PG_DISABLE_64_BIT_ATOMICS)
237 #if !defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) && defined(HAVE_GCC__ATOMIC_INT64_CAS)
238 #define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64
241 uint64 *expected, uint64
newval)
243 return __atomic_compare_exchange_n(&ptr->
value, expected,
newval,
false,
244 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
248 #if !defined(PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
249 #define PG_HAVE_ATOMIC_COMPARE_EXCHANGE_U64
252 uint64 *expected, uint64
newval)
256 current = __sync_val_compare_and_swap(&ptr->
value, *expected,
newval);
257 ret = current == *expected;
271 #if !defined(PG_HAVE_ATOMIC_EXCHANGE_U64) && defined(HAVE_GCC__ATOMIC_INT64_CAS)
272 #define PG_HAVE_ATOMIC_EXCHANGE_U64
276 return __atomic_exchange_n(&ptr->
value,
newval, __ATOMIC_SEQ_CST);
282 #if !defined(PG_HAVE_ATOMIC_FETCH_ADD_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
283 #define PG_HAVE_ATOMIC_FETCH_ADD_U64
287 return __sync_fetch_and_add(&ptr->
value, add_);
291 #if !defined(PG_HAVE_ATOMIC_FETCH_SUB_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
292 #define PG_HAVE_ATOMIC_FETCH_SUB_U64
296 return __sync_fetch_and_sub(&ptr->
value, sub_);
300 #if !defined(PG_HAVE_ATOMIC_FETCH_AND_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
301 #define PG_HAVE_ATOMIC_FETCH_AND_U64
305 return __sync_fetch_and_and(&ptr->
value, and_);
309 #if !defined(PG_HAVE_ATOMIC_FETCH_OR_U64) && defined(HAVE_GCC__SYNC_INT64_CAS)
310 #define PG_HAVE_ATOMIC_FETCH_OR_U64
314 return __sync_fetch_and_or(&ptr->
value, or_);
struct pg_atomic_uint32 pg_atomic_uint32
bool pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval)
void pg_atomic_clear_flag_impl(volatile pg_atomic_flag *ptr)
uint64 pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_)
uint32 pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_)
bool pg_atomic_unlocked_test_flag_impl(volatile pg_atomic_flag *ptr)
bool pg_atomic_test_set_flag_impl(volatile pg_atomic_flag *ptr)
bool pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, uint64 *expected, uint64 newval)
void pg_atomic_init_flag_impl(volatile pg_atomic_flag *ptr)
struct pg_atomic_flag pg_atomic_flag
struct pg_atomic_uint64 pg_atomic_uint64