51#if !defined(__has_feature)
52#define __has_feature(x) 0
54#if !defined(__has_builtin)
55#define __has_builtin(x) 0
57#if !defined(__GNUC_PREREQ__)
58#if defined(__GNUC__) && defined(__GNUC_MINOR__)
59#define __GNUC_PREREQ__(maj, min) \
60 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
62#define __GNUC_PREREQ__(maj, min) 0
66#if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS)
67#if __has_feature(c_atomic)
68#define __CLANG_ATOMICS
69#elif __GNUC_PREREQ__(4, 7)
71#elif !defined(__GNUC__)
72#error "stdatomic.h does not support your compiler"
76#if !defined(__CLANG_ATOMICS)
77#define _Atomic(T) struct { volatile __typeof__(T) __val; }
84#if defined(__CLANG_ATOMICS)
85#define ATOMIC_VAR_INIT(value) (value)
86#define atomic_init(obj, value) __c11_atomic_init(obj, value)
88#define ATOMIC_VAR_INIT(value) { .__val = (value) }
89#define atomic_init(obj, value) do { \
90 (obj)->__val = (value); \
100#ifndef __ATOMIC_RELAXED
101#define __ATOMIC_RELAXED 0
103#ifndef __ATOMIC_CONSUME
104#define __ATOMIC_CONSUME 1
106#ifndef __ATOMIC_ACQUIRE
107#define __ATOMIC_ACQUIRE 2
109#ifndef __ATOMIC_RELEASE
110#define __ATOMIC_RELEASE 3
112#ifndef __ATOMIC_ACQ_REL
113#define __ATOMIC_ACQ_REL 4
115#ifndef __ATOMIC_SEQ_CST
116#define __ATOMIC_SEQ_CST 5
141#ifdef __CLANG_ATOMICS
142#define atomic_thread_fence(order) __c11_atomic_thread_fence(order)
143#define atomic_signal_fence(order) __c11_atomic_signal_fence(order)
144#elif defined(__GNUC_ATOMICS)
145#define atomic_thread_fence(order) __atomic_thread_fence(order)
146#define atomic_signal_fence(order) __atomic_signal_fence(order)
148#define atomic_thread_fence(order) __sync_synchronize()
149#define atomic_signal_fence(order) __asm volatile ("" : : : "memory")
156#if defined(__CLANG_ATOMICS)
157#define atomic_is_lock_free(obj) \
158 __c11_atomic_is_lock_free(sizeof(obj))
159#elif defined(__GNUC_ATOMICS)
160#define atomic_is_lock_free(obj) \
161 __atomic_is_lock_free(sizeof((obj)->__val))
163#define atomic_is_lock_free(obj) \
164 (sizeof((obj)->__val) <= sizeof(void *))
182typedef _Atomic(
unsigned long long) atomic_ullong;
184typedef _Atomic(
char16_t) atomic_char16_t;
185typedef _Atomic(
char32_t) atomic_char32_t;
188typedef _Atomic(int_least8_t) atomic_int_least8_t;
189typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
190typedef _Atomic(int_least16_t) atomic_int_least16_t;
191typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
192typedef _Atomic(int_least32_t) atomic_int_least32_t;
193typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
194typedef _Atomic(int_least64_t) atomic_int_least64_t;
195typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
196typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
197typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
198typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
199typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
200typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
201typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
202typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
203typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
219#if defined(__CLANG_ATOMICS)
220#define atomic_compare_exchange_strong_explicit(object, expected, \
221 desired, success, failure) \
222 __c11_atomic_compare_exchange_strong(object, expected, desired, \
224#define atomic_compare_exchange_weak_explicit(object, expected, \
225 desired, success, failure) \
226 __c11_atomic_compare_exchange_weak(object, expected, desired, \
228#define atomic_exchange_explicit(object, desired, order) \
229 __c11_atomic_exchange(object, desired, order)
230#define atomic_fetch_add_explicit(object, operand, order) \
231 __c11_atomic_fetch_add(object, operand, order)
232#define atomic_fetch_and_explicit(object, operand, order) \
233 __c11_atomic_fetch_and(object, operand, order)
234#define atomic_fetch_or_explicit(object, operand, order) \
235 __c11_atomic_fetch_or(object, operand, order)
236#define atomic_fetch_sub_explicit(object, operand, order) \
237 __c11_atomic_fetch_sub(object, operand, order)
238#define atomic_fetch_xor_explicit(object, operand, order) \
239 __c11_atomic_fetch_xor(object, operand, order)
240#define atomic_load_explicit(object, order) \
241 __c11_atomic_load(object, order)
242#define atomic_store_explicit(object, desired, order) \
243 __c11_atomic_store(object, desired, order)
244#elif defined(__GNUC_ATOMICS)
245#define atomic_compare_exchange_strong_explicit(object, expected, \
246 desired, success, failure) \
247 __atomic_compare_exchange_n(&(object)->__val, expected, \
248 desired, 0, success, failure)
249#define atomic_compare_exchange_weak_explicit(object, expected, \
250 desired, success, failure) \
251 __atomic_compare_exchange_n(&(object)->__val, expected, \
252 desired, 1, success, failure)
253#define atomic_exchange_explicit(object, desired, order) \
254 __atomic_exchange_n(&(object)->__val, desired, order)
255#define atomic_fetch_add_explicit(object, operand, order) \
256 __atomic_fetch_add(&(object)->__val, operand, order)
257#define atomic_fetch_and_explicit(object, operand, order) \
258 __atomic_fetch_and(&(object)->__val, operand, order)
259#define atomic_fetch_or_explicit(object, operand, order) \
260 __atomic_fetch_or(&(object)->__val, operand, order)
261#define atomic_fetch_sub_explicit(object, operand, order) \
262 __atomic_fetch_sub(&(object)->__val, operand, order)
263#define atomic_fetch_xor_explicit(object, operand, order) \
264 __atomic_fetch_xor(&(object)->__val, operand, order)
265#define atomic_load_explicit(object, order) \
266 __atomic_load_n(&(object)->__val, order)
267#define atomic_store_explicit(object, desired, order) \
268 __atomic_store_n(&(object)->__val, desired, order)
270#define atomic_compare_exchange_strong_explicit(object, expected, \
271 desired, success, failure) ({ \
272 __typeof__((object)->__val) __v; \
274 __v = __sync_val_compare_and_swap(&(object)->__val, \
275 *(expected), desired); \
276 __r = *(expected) == __v; \
281#define atomic_compare_exchange_weak_explicit(object, expected, \
282 desired, success, failure) \
283 atomic_compare_exchange_strong_explicit(object, expected, \
284 desired, success, failure)
285#if __has_builtin(__sync_swap)
287#define atomic_exchange_explicit(object, desired, order) \
288 __sync_swap(&(object)->__val, desired)
295#define atomic_exchange_explicit(object, desired, order) ({ \
296 __typeof__((object)->__val) __v; \
297 __v = __sync_lock_test_and_set(&(object)->__val, desired); \
298 __sync_synchronize(); \
302#define atomic_fetch_add_explicit(object, operand, order) \
303 __sync_fetch_and_add(&(object)->__val, operand)
304#define atomic_fetch_and_explicit(object, operand, order) \
305 __sync_fetch_and_and(&(object)->__val, operand)
306#define atomic_fetch_or_explicit(object, operand, order) \
307 __sync_fetch_and_or(&(object)->__val, operand)
308#define atomic_fetch_sub_explicit(object, operand, order) \
309 __sync_fetch_and_sub(&(object)->__val, operand)
310#define atomic_fetch_xor_explicit(object, operand, order) \
311 __sync_fetch_and_xor(&(object)->__val, operand)
312#define atomic_load_explicit(object, order) \
313 __sync_fetch_and_add(&(object)->__val, 0)
314#define atomic_store_explicit(object, desired, order) do { \
315 __sync_synchronize(); \
316 (object)->__val = (desired); \
317 __sync_synchronize(); \
325#define atomic_compare_exchange_strong(object, expected, desired) \
326 atomic_compare_exchange_strong_explicit(object, expected, \
327 desired, memory_order_seq_cst, memory_order_seq_cst)
328#define atomic_compare_exchange_weak(object, expected, desired) \
329 atomic_compare_exchange_weak_explicit(object, expected, \
330 desired, memory_order_seq_cst, memory_order_seq_cst)
331#define atomic_exchange(object, desired) \
332 atomic_exchange_explicit(object, desired, memory_order_seq_cst)
333#define atomic_fetch_add(object, operand) \
334 atomic_fetch_add_explicit(object, operand, memory_order_seq_cst)
335#define atomic_fetch_and(object, operand) \
336 atomic_fetch_and_explicit(object, operand, memory_order_seq_cst)
337#define atomic_fetch_or(object, operand) \
338 atomic_fetch_or_explicit(object, operand, memory_order_seq_cst)
339#define atomic_fetch_sub(object, operand) \
340 atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst)
341#define atomic_fetch_xor(object, operand) \
342 atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst)
343#define atomic_load(object) \
344 atomic_load_explicit(object, memory_order_seq_cst)
345#define atomic_store(object, desired) \
346 atomic_store_explicit(object, desired, memory_order_seq_cst)
354#define ATOMIC_FLAG_INIT ATOMIC_VAR_INIT(0)
356#define atomic_flag_clear_explicit(object, order) \
357 atomic_store_explicit(object, 0, order)
358#define atomic_flag_test_and_set_explicit(object, order) \
359 atomic_compare_exchange_strong_explicit(object, 0, 1, order, order)
361#define atomic_flag_clear(object) \
362 atomic_flag_clear_explicit(object, memory_order_seq_cst)
363#define atomic_flag_test_and_set(object) \
364 atomic_flag_test_and_set_explicit(object, memory_order_seq_cst)