54 #if !defined(__has_feature) 55 #define __has_feature(x) 0 57 #if !defined(__has_builtin) 58 #define __has_builtin(x) 0 60 #if !defined(__GNUC_PREREQ__) 61 #if defined(__GNUC__) && defined(__GNUC_MINOR__) 62 #define __GNUC_PREREQ__(maj, min) \ 63 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) 65 #define __GNUC_PREREQ__(maj, min) 0 69 #if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS) 70 #if __has_feature(c_atomic) 71 #define __CLANG_ATOMICS 72 #elif __GNUC_PREREQ__(4, 7) 73 #define __GNUC_ATOMICS 74 #elif !defined(__GNUC__) 75 #error "stdatomic.h does not support your compiler" 89 #ifdef __GCC_ATOMIC_BOOL_LOCK_FREE 90 #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE 92 #ifdef __GCC_ATOMIC_CHAR_LOCK_FREE 93 #define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE 95 #ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE 96 #define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE 98 #ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE 99 #define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE 101 #ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE 102 #define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE 104 #ifdef __GCC_ATOMIC_SHORT_LOCK_FREE 105 #define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE 107 #ifdef __GCC_ATOMIC_INT_LOCK_FREE 108 #define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE 110 #ifdef __GCC_ATOMIC_LONG_LOCK_FREE 111 #define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE 113 #ifdef __GCC_ATOMIC_LLONG_LOCK_FREE 114 #define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE 116 #ifdef __GCC_ATOMIC_POINTER_LOCK_FREE 117 #define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE 120 #if !defined(__CLANG_ATOMICS) 121 #define _Atomic(T) struct { volatile __typeof__(T) __val; } 128 #if defined(__CLANG_ATOMICS) 129 #define ATOMIC_VAR_INIT(value) (value) 130 #define atomic_init(obj, value) __c11_atomic_init(obj, value) 132 #define ATOMIC_VAR_INIT(value) { .__val = (value) } 133 #define atomic_init(obj, value) ((void)((obj)->__val = (value))) 142 #ifndef __ATOMIC_RELAXED 143 #define __ATOMIC_RELAXED 0 145 #ifndef __ATOMIC_CONSUME 146 #define __ATOMIC_CONSUME 1 148 #ifndef __ATOMIC_ACQUIRE 149 #define __ATOMIC_ACQUIRE 2 151 #ifndef __ATOMIC_RELEASE 152 #define __ATOMIC_RELEASE 3 154 #ifndef __ATOMIC_ACQ_REL 155 #define __ATOMIC_ACQ_REL 4 157 #ifndef __ATOMIC_SEQ_CST 158 #define __ATOMIC_SEQ_CST 5 187 #ifdef __CLANG_ATOMICS 188 __c11_atomic_thread_fence(__order);
189 #elif defined(__GNUC_ATOMICS) 190 __atomic_thread_fence(__order);
192 __sync_synchronize();
200 #ifdef __CLANG_ATOMICS 201 __c11_atomic_signal_fence(__order);
202 #elif defined(__GNUC_ATOMICS) 203 __atomic_signal_fence(__order);
205 __asm
volatile (
"" :::
"memory");
217 #define atomic_is_lock_free(obj) \ 218 ((void)(obj), (__Bool)1) 219 #elif defined(__CLANG_ATOMICS) 220 #define atomic_is_lock_free(obj) \ 221 __atomic_is_lock_free(sizeof(*(obj)), obj) 222 #elif defined(__GNUC_ATOMICS) 223 #define atomic_is_lock_free(obj) \ 224 __atomic_is_lock_free(sizeof((obj)->__val), &(obj)->__val) 226 #define atomic_is_lock_free(obj) \ 227 ((void)(obj), sizeof((obj)->__val) <= sizeof(void *)) 235 typedef _Atomic(
char) atomic_char;
236 typedef _Atomic(
signed char) atomic_schar;
237 typedef _Atomic(
unsigned char) atomic_uchar;
238 typedef _Atomic(
short) atomic_short;
239 typedef _Atomic(
unsigned short) atomic_ushort;
240 typedef _Atomic(
int) atomic_int;
241 typedef _Atomic(
unsigned int) atomic_uint;
242 typedef _Atomic(
long) atomic_long;
243 typedef _Atomic(
unsigned long) atomic_ulong;
244 typedef _Atomic(
long long) atomic_llong;
245 typedef _Atomic(
unsigned long long) atomic_ullong;
247 typedef _Atomic(char16_t) atomic_char16_t;
248 typedef _Atomic(char32_t) atomic_char32_t;
250 typedef _Atomic(
wchar_t) atomic_wchar_t;
251 typedef _Atomic(int_least8_t) atomic_int_least8_t;
252 typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
253 typedef _Atomic(int_least16_t) atomic_int_least16_t;
254 typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
255 typedef _Atomic(int_least32_t) atomic_int_least32_t;
256 typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
257 typedef _Atomic(int_least64_t) atomic_int_least64_t;
258 typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
259 typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
260 typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
261 typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
262 typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
263 typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
264 typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
265 typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
266 typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
267 typedef _Atomic(intptr_t) atomic_intptr_t;
268 typedef _Atomic(uintptr_t) atomic_uintptr_t;
269 typedef _Atomic(
size_t) atomic_size_t;
270 typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
271 typedef _Atomic(intmax_t) atomic_intmax_t;
272 typedef _Atomic(uintmax_t) atomic_uintmax_t;
282 #if defined(__CLANG_ATOMICS) 283 #define atomic_compare_exchange_strong_explicit(object, expected, \ 284 desired, success, failure) \ 285 __c11_atomic_compare_exchange_strong(object, expected, desired, \ 287 #define atomic_compare_exchange_weak_explicit(object, expected, \ 288 desired, success, failure) \ 289 __c11_atomic_compare_exchange_weak(object, expected, desired, \ 291 #define atomic_exchange_explicit(object, desired, order) \ 292 __c11_atomic_exchange(object, desired, order) 293 #define atomic_fetch_add_explicit(object, operand, order) \ 294 __c11_atomic_fetch_add(object, operand, order) 295 #define atomic_fetch_and_explicit(object, operand, order) \ 296 __c11_atomic_fetch_and(object, operand, order) 297 #define atomic_fetch_or_explicit(object, operand, order) \ 298 __c11_atomic_fetch_or(object, operand, order) 299 #define atomic_fetch_sub_explicit(object, operand, order) \ 300 __c11_atomic_fetch_sub(object, operand, order) 301 #define atomic_fetch_xor_explicit(object, operand, order) \ 302 __c11_atomic_fetch_xor(object, operand, order) 303 #define atomic_load_explicit(object, order) \ 304 __c11_atomic_load(object, order) 305 #define atomic_store_explicit(object, desired, order) \ 306 __c11_atomic_store(object, desired, order) 307 #elif defined(__GNUC_ATOMICS) 308 #define atomic_compare_exchange_strong_explicit(object, expected, \ 309 desired, success, failure) \ 310 __atomic_compare_exchange_n(&(object)->__val, expected, \ 311 desired, 0, success, failure) 312 #define atomic_compare_exchange_weak_explicit(object, expected, \ 313 desired, success, failure) \ 314 __atomic_compare_exchange_n(&(object)->__val, expected, \ 315 desired, 1, success, failure) 316 #define atomic_exchange_explicit(object, desired, order) \ 317 __atomic_exchange_n(&(object)->__val, desired, order) 318 #define atomic_fetch_add_explicit(object, operand, order) \ 319 __atomic_fetch_add(&(object)->__val, operand, order) 320 #define atomic_fetch_and_explicit(object, operand, order) \ 321 __atomic_fetch_and(&(object)->__val, operand, order) 322 #define atomic_fetch_or_explicit(object, operand, order) \ 323 __atomic_fetch_or(&(object)->__val, operand, order) 324 #define atomic_fetch_sub_explicit(object, operand, order) \ 325 __atomic_fetch_sub(&(object)->__val, operand, order) 326 #define atomic_fetch_xor_explicit(object, operand, order) \ 327 __atomic_fetch_xor(&(object)->__val, operand, order) 328 #define atomic_load_explicit(object, order) \ 329 __atomic_load_n(&(object)->__val, order) 330 #define atomic_store_explicit(object, desired, order) \ 331 __atomic_store_n(&(object)->__val, desired, order) 333 #define __atomic_apply_stride(object, operand) \ 334 (((__typeof__((object)->__val))0) + (operand)) 335 #define atomic_compare_exchange_strong_explicit(object, expected, \ 336 desired, success, failure) __extension__ ({ \ 337 __typeof__(expected) __ep = (expected); \ 338 __typeof__(*__ep) __e = *__ep; \ 339 (void)(success); (void)(failure); \ 340 (__Bool)((*__ep = __sync_val_compare_and_swap(&(object)->__val, \ 341 __e, desired)) == __e); \ 343 #define atomic_compare_exchange_weak_explicit(object, expected, \ 344 desired, success, failure) \ 345 atomic_compare_exchange_strong_explicit(object, expected, \ 346 desired, success, failure) 347 #if __has_builtin(__sync_swap) 349 #define atomic_exchange_explicit(object, desired, order) \ 350 ((void)(order), __sync_swap(&(object)->__val, desired)) 357 #define atomic_exchange_explicit(object, desired, order) \ 359 __typeof__(object) __o = (object); \ 360 __typeof__(desired) __d = (desired); \ 362 __sync_synchronize(); \ 363 __sync_lock_test_and_set(&(__o)->__val, __d); \ 366 #define atomic_fetch_add_explicit(object, operand, order) \ 367 ((void)(order), __sync_fetch_and_add(&(object)->__val, \ 368 __atomic_apply_stride(object, operand))) 369 #define atomic_fetch_and_explicit(object, operand, order) \ 370 ((void)(order), __sync_fetch_and_and(&(object)->__val, operand)) 371 #define atomic_fetch_or_explicit(object, operand, order) \ 372 ((void)(order), __sync_fetch_and_or(&(object)->__val, operand)) 373 #define atomic_fetch_sub_explicit(object, operand, order) \ 374 ((void)(order), __sync_fetch_and_sub(&(object)->__val, \ 375 __atomic_apply_stride(object, operand))) 376 #define atomic_fetch_xor_explicit(object, operand, order) \ 377 ((void)(order), __sync_fetch_and_xor(&(object)->__val, operand)) 378 #define atomic_load_explicit(object, order) \ 379 ((void)(order), __sync_fetch_and_add(&(object)->__val, 0)) 380 #define atomic_store_explicit(object, desired, order) \ 381 ((void)atomic_exchange_explicit(object, desired, order)) 392 #define atomic_compare_exchange_strong(object, expected, desired) \ 393 atomic_compare_exchange_strong_explicit(object, expected, \ 394 desired, memory_order_seq_cst, memory_order_seq_cst) 395 #define atomic_compare_exchange_weak(object, expected, desired) \ 396 atomic_compare_exchange_weak_explicit(object, expected, \ 397 desired, memory_order_seq_cst, memory_order_seq_cst) 398 #define atomic_exchange(object, desired) \ 399 atomic_exchange_explicit(object, desired, memory_order_seq_cst) 400 #define atomic_fetch_add(object, operand) \ 401 atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) 402 #define atomic_fetch_and(object, operand) \ 403 atomic_fetch_and_explicit(object, operand, memory_order_seq_cst) 404 #define atomic_fetch_or(object, operand) \ 405 atomic_fetch_or_explicit(object, operand, memory_order_seq_cst) 406 #define atomic_fetch_sub(object, operand) \ 407 atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst) 408 #define atomic_fetch_xor(object, operand) \ 409 atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst) 410 #define atomic_load(object) \ 411 atomic_load_explicit(object, memory_order_seq_cst) 412 #define atomic_store(object, desired) \ 413 atomic_store_explicit(object, desired, memory_order_seq_cst) 427 #define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(0) }
#define atomic_exchange_explicit(object, desired, order)
static __inline __Bool atomic_flag_test_and_set(volatile atomic_flag *__object)
#define atomic_store_explicit(object, desired, order)
static __inline void atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order)
static __inline __Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *__object, memory_order __order)
static __inline void atomic_flag_clear(volatile atomic_flag *__object)
static __inline void atomic_signal_fence(memory_order __order __unused)
static __inline void atomic_thread_fence(memory_order __order __unused)