22#define AO_GCC_ATOMIC_TEST_AND_SET
23#include "../test_and_set_t_is_char.h"
25#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1) \
26 || defined(AO_GCC_FORCE_HAVE_CAS)
27# define AO_GCC_HAVE_char_SYNC_CAS
30#if (__SIZEOF_SHORT__ == 2 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)) \
31 || defined(AO_GCC_FORCE_HAVE_CAS)
32# define AO_GCC_HAVE_short_SYNC_CAS
35#if (__SIZEOF_INT__ == 4 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) \
36 || (__SIZEOF_INT__ == 8 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) \
37 || defined(AO_GCC_FORCE_HAVE_CAS)
38# define AO_GCC_HAVE_int_SYNC_CAS
41#if (__SIZEOF_SIZE_T__ == 4 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) \
42 || (__SIZEOF_SIZE_T__ == 8 \
43 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) \
44 || defined(AO_GCC_FORCE_HAVE_CAS)
45# define AO_GCC_HAVE_SYNC_CAS
48#undef AO_compiler_barrier
49#define AO_compiler_barrier() __atomic_signal_fence(__ATOMIC_SEQ_CST)
59# define AO_HAVE_nop_full
65 __atomic_thread_fence(__ATOMIC_ACQUIRE);
67# define AO_HAVE_nop_read
69# ifndef AO_HAVE_nop_write
73 __atomic_thread_fence(__ATOMIC_RELEASE);
75# define AO_HAVE_nop_write
82 __atomic_thread_fence(__ATOMIC_SEQ_CST);
84# define AO_HAVE_nop_full
89#ifndef AO_PREFER_GENERALIZED
92# define AO_CLEAR(addr) __atomic_clear(addr, __ATOMIC_RELEASE)
98 return (
AO_TS_VAL_t)__atomic_test_and_set(addr, __ATOMIC_RELAXED);
100# define AO_HAVE_test_and_set
105 return (
AO_TS_VAL_t)__atomic_test_and_set(addr, __ATOMIC_ACQUIRE);
107# define AO_HAVE_test_and_set_acquire
112 return (
AO_TS_VAL_t)__atomic_test_and_set(addr, __ATOMIC_RELEASE);
114# define AO_HAVE_test_and_set_release
119 return (
AO_TS_VAL_t)__atomic_test_and_set(addr, __ATOMIC_SEQ_CST);
121# define AO_HAVE_test_and_set_full
124#ifdef AO_HAVE_DOUBLE_PTR_STORAGE
126# if ((__SIZEOF_SIZE_T__ == 4 \
127 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)) \
128 || (__SIZEOF_SIZE_T__ == 8 \
129 && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16))) \
130 && !defined(AO_SKIPATOMIC_double_compare_and_swap_ANY)
131# define AO_GCC_HAVE_double_SYNC_CAS
134# if !defined(AO_GCC_HAVE_double_SYNC_CAS) || !defined(AO_PREFER_GENERALIZED)
136# if !defined(AO_HAVE_double_load) && !defined(AO_SKIPATOMIC_double_load)
142 result.AO_whole = __atomic_load_n(&addr->
AO_whole, __ATOMIC_RELAXED);
145# define AO_HAVE_double_load
148# if !defined(AO_HAVE_double_load_acquire) \
149 && !defined(AO_SKIPATOMIC_double_load_acquire)
155 result.AO_whole = __atomic_load_n(&addr->
AO_whole, __ATOMIC_ACQUIRE);
158# define AO_HAVE_double_load_acquire
161# if !defined(AO_HAVE_double_store) && !defined(AO_SKIPATOMIC_double_store)
167# define AO_HAVE_double_store
170# if !defined(AO_HAVE_double_store_release) \
171 && !defined(AO_SKIPATOMIC_double_store_release)
177# define AO_HAVE_double_store_release
184#ifdef AO_GCC_HAVE_double_SYNC_CAS
185# ifndef AO_HAVE_double_compare_and_swap
190 return (
int)__atomic_compare_exchange_n(&addr->
AO_whole,
197# define AO_HAVE_double_compare_and_swap
200# ifndef AO_HAVE_double_compare_and_swap_acquire
206 return (
int)__atomic_compare_exchange_n(&addr->
AO_whole,
208 __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE);
210# define AO_HAVE_double_compare_and_swap_acquire
213# ifndef AO_HAVE_double_compare_and_swap_release
219 return (
int)__atomic_compare_exchange_n(&addr->
AO_whole,
224# define AO_HAVE_double_compare_and_swap_release
227# ifndef AO_HAVE_double_compare_and_swap_full
232 return (
int)__atomic_compare_exchange_n(&addr->
AO_whole,
237# define AO_HAVE_double_compare_and_swap_full
AO_INLINE int AO_double_compare_and_swap(volatile AO_double_t *addr, AO_double_t old_val, AO_double_t new_val)
AO_INLINE int AO_double_compare_and_swap_release(volatile AO_double_t *addr, AO_double_t old_val, AO_double_t new_val)
AO_INLINE void AO_double_store_release(volatile AO_double_t *addr, AO_double_t value)
AO_INLINE int AO_double_compare_and_swap_acquire(volatile AO_double_t *addr, AO_double_t old_val, AO_double_t new_val)
AO_INLINE AO_double_t AO_double_load_acquire(const volatile AO_double_t *addr)
AO_INLINE int AO_double_compare_and_swap_full(volatile AO_double_t *addr, AO_double_t old_val, AO_double_t new_val)
AO_INLINE AO_double_t AO_double_load(const volatile AO_double_t *addr)
AO_INLINE void AO_double_store(volatile AO_double_t *addr, AO_double_t value)
AO_INLINE AO_TS_VAL_t AO_test_and_set_acquire(volatile AO_TS_t *addr)
#define AO_compiler_barrier()
AO_INLINE AO_TS_VAL_t AO_test_and_set(volatile AO_TS_t *addr)
AO_INLINE AO_TS_VAL_t AO_test_and_set_full(volatile AO_TS_t *addr)
AO_INLINE void AO_nop_read(void)
AO_INLINE AO_TS_VAL_t AO_test_and_set_release(volatile AO_TS_t *addr)
AO_INLINE void AO_nop_full(void)
double_ptr_storage AO_whole