31#define _STDATOMIC_H_ 1
38#if defined __GNUC__ && defined __GNUC_MINOR__
39#define __GNUC_PREREQ(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
41#define __GNUC_PREREQ(maj, min) 0
44#define __GNUC_PREREQ__(ma, mi) __GNUC_PREREQ(ma, mi)
47#define __has_feature(x) 0
50#if __has_feature(cxx_atomic)
51#define __CLANG_ATOMICS
52#elif __GNUC_PREREQ__(4, 7)
54#elif !defined(__GNUC__)
55#error "stdatomic.h does not support your compiler"
58#if !defined(__CLANG_ATOMICS)
70#if defined(__CLANG_ATOMICS)
71#define ATOMIC_VAR_INIT(value) (value)
72#define atomic_init(obj, value) __c11_atomic_init(obj, value)
74#define ATOMIC_VAR_INIT(value) {.__val = (value)}
75#define atomic_init(obj, value) \
78 (obj)->__val = (value); \
88#ifndef __ATOMIC_RELAXED
89#define __ATOMIC_RELAXED 0
91#ifndef __ATOMIC_CONSUME
92#define __ATOMIC_CONSUME 1
94#ifndef __ATOMIC_ACQUIRE
95#define __ATOMIC_ACQUIRE 2
97#ifndef __ATOMIC_RELEASE
98#define __ATOMIC_RELEASE 3
100#ifndef __ATOMIC_ACQ_REL
101#define __ATOMIC_ACQ_REL 4
103#ifndef __ATOMIC_SEQ_CST
104#define __ATOMIC_SEQ_CST 5
128#ifdef __CLANG_ATOMICS
129#define atomic_thread_fence(order) __c11_atomic_thread_fence(order)
130#define atomic_signal_fence(order) __c11_atomic_signal_fence(order)
131#elif defined(__GNUC_ATOMICS)
132#define atomic_thread_fence(order) __atomic_thread_fence(order)
133#define atomic_signal_fence(order) __atomic_signal_fence(order)
135#define atomic_thread_fence(order) __sync_synchronize()
136#define atomic_signal_fence(order) __asm volatile("" : : : "memory")
143#if defined(__CLANG_ATOMICS)
144#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(obj))
145#elif defined(__GNUC_ATOMICS)
146#define atomic_is_lock_free(obj) __atomic_is_lock_free(sizeof((obj)->__val))
148#define atomic_is_lock_free(obj) (sizeof((obj)->__val) <= sizeof(void*))
166typedef _Atomic(
unsigned long long) atomic_ullong;
168 typedef _Atomic(__char16_t) atomic_char16_t;
169 typedef _Atomic(__char32_t) atomic_char32_t;
203#if defined(__CLANG_ATOMICS)
204#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
205 __c11_atomic_compare_exchange_strong(object, expected, desired, success, failure)
206#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
207 __c11_atomic_compare_exchange_weak(object, expected, desired, success, failure)
208#define atomic_exchange_explicit(object, desired, order) __c11_atomic_exchange(object, desired, order)
209#define atomic_fetch_add_explicit(object, operand, order) __c11_atomic_fetch_add(object, operand, order)
210#define atomic_fetch_and_explicit(object, operand, order) __c11_atomic_fetch_and(object, operand, order)
211#define atomic_fetch_or_explicit(object, operand, order) __c11_atomic_fetch_or(object, operand, order)
212#define atomic_fetch_sub_explicit(object, operand, order) __c11_atomic_fetch_sub(object, operand, order)
213#define atomic_fetch_xor_explicit(object, operand, order) __c11_atomic_fetch_xor(object, operand, order)
214#define atomic_load_explicit(object, order) __c11_atomic_load(object, order)
215#define atomic_store_explicit(object, desired, order) __c11_atomic_store(object, desired, order)
216#elif defined(__GNUC_ATOMICS)
217#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
218 __atomic_compare_exchange_n(&(object)->__val, expected, desired, 0, success, failure)
219#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
220 __atomic_compare_exchange_n(&(object)->__val, expected, desired, 1, success, failure)
221#define atomic_exchange_explicit(object, desired, order) __atomic_exchange_n(&(object)->__val, desired, order)
222#define atomic_fetch_add_explicit(object, operand, order) __atomic_fetch_add(&(object)->__val, operand, order)
223#define atomic_fetch_and_explicit(object, operand, order) __atomic_fetch_and(&(object)->__val, operand, order)
224#define atomic_fetch_or_explicit(object, operand, order) __atomic_fetch_or(&(object)->__val, operand, order)
225#define atomic_fetch_sub_explicit(object, operand, order) __atomic_fetch_sub(&(object)->__val, operand, order)
226#define atomic_fetch_xor_explicit(object, operand, order) __atomic_fetch_xor(&(object)->__val, operand, order)
227#define atomic_load_explicit(object, order) __atomic_load_n(&(object)->__val, order)
228#define atomic_store_explicit(object, desired, order) __atomic_store_n(&(object)->__val, desired, order)
230#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
232 __typeof__((object)->__val) __v; \
234 __v = __sync_val_compare_and_swap(&(object)->__val, *(expected), desired); \
235 __r = *(expected) == __v; \
240#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
241 atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure)
242#if __has_builtin(__sync_swap)
244#define atomic_exchange_explicit(object, desired, order) __sync_swap(&(object)->__val, desired)
251#define atomic_exchange_explicit(object, desired, order) \
253 __typeof__((object)->__val) __v; \
254 __v = __sync_lock_test_and_set(&(object)->__val, desired); \
255 __sync_synchronize(); \
259#define atomic_fetch_add_explicit(object, operand, order) __sync_fetch_and_add(&(object)->__val, operand)
260#define atomic_fetch_and_explicit(object, operand, order) __sync_fetch_and_and(&(object)->__val, operand)
261#define atomic_fetch_or_explicit(object, operand, order) __sync_fetch_and_or(&(object)->__val, operand)
262#define atomic_fetch_sub_explicit(object, operand, order) __sync_fetch_and_sub(&(object)->__val, operand)
263#define atomic_fetch_xor_explicit(object, operand, order) __sync_fetch_and_xor(&(object)->__val, operand)
264#define atomic_load_explicit(object, order) __sync_fetch_and_add(&(object)->__val, 0)
265#define atomic_store_explicit(object, desired, order) \
268 __sync_synchronize(); \
269 (object)->__val = (desired); \
270 __sync_synchronize(); \
278#define atomic_compare_exchange_strong(object, expected, desired) \
279 atomic_compare_exchange_strong_explicit(object, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
280#define atomic_compare_exchange_weak(object, expected, desired) \
281 atomic_compare_exchange_weak_explicit(object, expected, desired, memory_order_seq_cst, memory_order_seq_cst)
282#define atomic_exchange(object, desired) atomic_exchange_explicit(object, desired, memory_order_seq_cst)
283#define atomic_fetch_add(object, operand) atomic_fetch_add_explicit(object, operand, memory_order_seq_cst)
284#define atomic_fetch_and(object, operand) atomic_fetch_and_explicit(object, operand, memory_order_seq_cst)
285#define atomic_fetch_or(object, operand) atomic_fetch_or_explicit(object, operand, memory_order_seq_cst)
286#define atomic_fetch_sub(object, operand) atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst)
287#define atomic_fetch_xor(object, operand) atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst)
288#define atomic_load(object) atomic_load_explicit(object, memory_order_seq_cst)
289#define atomic_store(object, desired) atomic_store_explicit(object, desired, memory_order_seq_cst)
297#define ATOMIC_FLAG_INIT ATOMIC_VAR_INIT(0)
299#define atomic_flag_clear_explicit(object, order) atomic_store_explicit(object, 0, order)
300#define atomic_flag_test_and_set_explicit(object, order) \
301 atomic_compare_exchange_strong_explicit(object, 0, 1, order, order)
303#define atomic_flag_clear(object) atomic_flag_clear_explicit(object, memory_order_seq_cst)
304#define atomic_flag_test_and_set(object) atomic_flag_test_and_set_explicit(object, memory_order_seq_cst)
__UINTMAX_TYPE__ uintmax_t
__PTRDIFF_TYPE__ ptrdiff_t
__UINT_LEAST16_TYPE__ uint_least16_t
__UINT_FAST8_TYPE__ uint_fast8_t
__INT_LEAST16_TYPE__ int_least16_t
__INT_LEAST32_TYPE__ int_least32_t
__UINTPTR_TYPE__ uintptr_t
__INT_FAST32_TYPE__ int_fast32_t
__UINT_LEAST8_TYPE__ uint_least8_t
__UINT_FAST64_TYPE__ uint_fast64_t
__UINT_LEAST32_TYPE__ uint_least32_t
__INT_FAST16_TYPE__ int_fast16_t
__INT_LEAST64_TYPE__ int_least64_t
__INT_FAST8_TYPE__ int_fast8_t
__UINT_FAST32_TYPE__ uint_fast32_t
__UINT_FAST16_TYPE__ uint_fast16_t
__UINT_LEAST64_TYPE__ uint_least64_t
__INT_FAST64_TYPE__ int_fast64_t
__INT_LEAST8_TYPE__ int_least8_t