// SPDX-License-Identifier: ISC #pragma once #include #include typedef enum memory_order { memory_order_relaxed = __ATOMIC_RELAXED, memory_order_consume = __ATOMIC_CONSUME, memory_order_acquire = __ATOMIC_ACQUIRE, memory_order_release = __ATOMIC_RELEASE, memory_order_acq_rel = __ATOMIC_ACQ_REL, memory_order_seq_cst = __ATOMIC_SEQ_CST, } memory_order; #define atomic_thread_fence(order) __atomic_thread_fence(order) #define atomic_signal_fence(order) __atomic_signal_fence(order) #ifdef __clang__ #define atomic_init(obj, value) __c11_atomic_init(obj, value) #define atomic_store_explicit(obj, val, order) __c11_atomic_store(obj, val, order) #define atomic_load_explicit(obj, order) __c11_atomic_load(obj, order) #define atomic_exchange_explicit(obj, val, order) __c11_atomic_exchange(obj, val, order) #define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \ __c11_atomic_compare_exchange_strong(obj, expected, desired, succ, fail) #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ __c11_atomic_compare_exchange_weak(obj, expected, desired, succ, fail) #define atomic_fetch_add_explicit(obj, arg, order) __c11_atomic_fetch_add(obj, arg, order) #define atomic_fetch_sub_explicit(obj, arg, order) __c11_atomic_fetch_sub(obj, arg, order) #define atomic_fetch_or_explicit(obj, arg, order) __c11_atomic_fetch_or(obj, arg, order) #define atomic_fetch_xor_explicit(obj, arg, order) __c11_atomic_fetch_xor(obj, arg, order) #define atomic_fetch_and_explicit(obj, arg, order) __c11_atomic_fetch_and(obj, arg, order) #define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj))) #else /* GCC */ #define atomic_init(obj, value) \ do { \ *(obj) = (value); \ } while (0) #define atomic_store_explicit(obj, val, order) \ ({ \ auto __ao = (obj); \ typeof(*__ao) __av = (val); \ __atomic_store(__ao, &__av, order); \ }) #define atomic_load_explicit(obj, order) \ ({ \ auto __ao = (obj); \ typeof(*__ao) __ar; \ __atomic_load(__ao, &__ar, order); \ __ar; \ }) #define atomic_exchange_explicit(obj, val, order) \ ({ \ auto __ao = (obj); \ typeof(*__ao) __av = (val); \ typeof(*__ao) __ar; \ __atomic_exchange(__ao, &__av, &__ar, order); \ __ar; \ }) #define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, fail) \ ({ \ auto __ao = (obj); \ auto __ae = (expected); \ typeof(*__ao) __ad = (desired); \ __atomic_compare_exchange(__ao, __ae, &__ad, 0, succ, fail); \ }) #define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, fail) \ ({ \ auto __ao = (obj); \ auto __ae = (expected); \ typeof(*__ao) __ad = (desired); \ __atomic_compare_exchange(__ao, __ae, &__ad, 1, succ, fail); \ }) #define atomic_fetch_add_explicit(obj, arg, order) __atomic_fetch_add(obj, arg, order) #define atomic_fetch_sub_explicit(obj, arg, order) __atomic_fetch_sub(obj, arg, order) #define atomic_fetch_or_explicit(obj, arg, order) __atomic_fetch_or(obj, arg, order) #define atomic_fetch_xor_explicit(obj, arg, order) __atomic_fetch_xor(obj, arg, order) #define atomic_fetch_and_explicit(obj, arg, order) __atomic_fetch_and(obj, arg, order) #define atomic_is_lock_free(obj) __atomic_is_lock_free(sizeof(*(obj)), (obj)) #endif #define atomic_store(obj, val) atomic_store_explicit(obj, val, memory_order_seq_cst) #define atomic_load(obj) atomic_load_explicit(obj, memory_order_seq_cst) #define atomic_exchange(obj, val) atomic_exchange_explicit(obj, val, memory_order_seq_cst) #define atomic_compare_exchange_strong(obj, expected, desired) \ atomic_compare_exchange_strong_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst) #define atomic_compare_exchange_weak(obj, expected, desired) \ atomic_compare_exchange_weak_explicit(obj, expected, desired, memory_order_seq_cst, memory_order_seq_cst) #define atomic_fetch_add(obj, arg) atomic_fetch_add_explicit(obj, arg, memory_order_seq_cst) #define atomic_fetch_sub(obj, arg) atomic_fetch_sub_explicit(obj, arg, memory_order_seq_cst) #define atomic_fetch_or(obj, arg) atomic_fetch_or_explicit(obj, arg, memory_order_seq_cst) #define atomic_fetch_xor(obj, arg) atomic_fetch_xor_explicit(obj, arg, memory_order_seq_cst) #define atomic_fetch_and(obj, arg) atomic_fetch_and_explicit(obj, arg, memory_order_seq_cst) // atomic_flag typedef struct atomic_flag { _Atomic(bool) __val; } atomic_flag; #define ATOMIC_FLAG_INIT {0} #define atomic_flag_test_and_set_explicit(obj, order) atomic_exchange_explicit(&(obj)->__val, 1, order) #define atomic_flag_test_and_set(obj) atomic_flag_test_and_set_explicit(obj, memory_order_seq_cst) #define atomic_flag_clear_explicit(obj, order) atomic_store_explicit(&(obj)->__val, 0, order) #define atomic_flag_clear(obj) atomic_flag_clear_explicit(obj, memory_order_seq_cst) typedef _Atomic(bool) atomic_bool; typedef _Atomic(char) atomic_char; typedef _Atomic(signed char) atomic_schar; typedef _Atomic(unsigned char) atomic_uchar; typedef _Atomic(short) atomic_short; typedef _Atomic(unsigned short) atomic_ushort; typedef _Atomic(int) atomic_int; typedef _Atomic(unsigned int) atomic_uint; typedef _Atomic(long) atomic_long; typedef _Atomic(unsigned long) atomic_ulong; typedef _Atomic(long long) atomic_llong; typedef _Atomic(unsigned long long) atomic_ullong; typedef _Atomic(__CHAR16_TYPE__) atomic_char16_t; typedef _Atomic(__CHAR32_TYPE__) atomic_char32_t; typedef _Atomic(__WCHAR_TYPE__) atomic_wchar_t; typedef _Atomic(int_least8_t) atomic_int_least8_t; typedef _Atomic(uint_least8_t) atomic_uint_least8_t; typedef _Atomic(int_least16_t) atomic_int_least16_t; typedef _Atomic(uint_least16_t) atomic_uint_least16_t; typedef _Atomic(int_least32_t) atomic_int_least32_t; typedef _Atomic(uint_least32_t) atomic_uint_least32_t; typedef _Atomic(int_least64_t) atomic_int_least64_t; typedef _Atomic(uint_least64_t) atomic_uint_least64_t; typedef _Atomic(int_fast8_t) atomic_int_fast8_t; typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; typedef _Atomic(int_fast16_t) atomic_int_fast16_t; typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; typedef _Atomic(int_fast32_t) atomic_int_fast32_t; typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; typedef _Atomic(int_fast64_t) atomic_int_fast64_t; typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; typedef _Atomic(intptr_t) atomic_intptr_t; typedef _Atomic(uintptr_t) atomic_uintptr_t; typedef _Atomic(size_t) atomic_size_t; typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; typedef _Atomic(intmax_t) atomic_intmax_t; typedef _Atomic(uintmax_t) atomic_uintmax_t;