19#ifndef COMPAT_ATOMICS_STDATOMIC_H
20#define COMPAT_ATOMICS_STDATOMIC_H
55#include "stdatomic_impl.h"
119#define atomic_init(obj, value) ((void)(*(obj) = (value)))
121#define kill_dependency(y) (y)
123#define ATOMIC_BOOL_LOCK_FREE FF_ATOMIC_LOCK_FREE
124#define ATOMIC_CHAR_LOCK_FREE FF_ATOMIC_LOCK_FREE
125#define ATOMIC_CHAR8_T_LOCK_FREE FF_ATOMIC_LOCK_FREE
126#define ATOMIC_CHAR16_T_LOCK_FREE FF_ATOMIC_LOCK_FREE
127#define ATOMIC_CHAR32_T_LOCK_FREE FF_ATOMIC_LOCK_FREE
128#define ATOMIC_WCHAR_T_LOCK_FREE FF_ATOMIC_LOCK_FREE
129#define ATOMIC_SHORT_LOCK_FREE FF_ATOMIC_LOCK_FREE
130#define ATOMIC_INT_LOCK_FREE FF_ATOMIC_LOCK_FREE
131#define ATOMIC_LONG_LOCK_FREE FF_ATOMIC_LOCK_FREE
132#define ATOMIC_LLONG_LOCK_FREE FF_ATOMIC_LOCK_FREE
133#define ATOMIC_POINTER_LOCK_FREE FF_ATOMIC_LOCK_FREE
135#define atomic_is_lock_free(obj) ((void)(obj), (bool)(FF_ATOMIC_LOCK_FREE == 2))
137#define atomic_thread_fence(order) ff_atomic_thread_fence(order)
138#define atomic_signal_fence(order) ff_atomic_signal_fence(order)
140#define FF_ATOMIC_SIZE(op, size) \
141 _Generic((char (*)[size])0, \
142 char (*)[1]: ff_atomic_##op##_8, \
143 char (*)[2]: ff_atomic_##op##_16, \
144 char (*)[4]: ff_atomic_##op##_32, \
145 char (*)[8]: ff_atomic_##op##_64)
154 const volatile void *desired,
162#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1944 && \
163 (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC))
166 FF_ATOMIC_SIZE(store,
sizeof(
void *))(object, (uintptr_t)desired, order);
180 const volatile void *desired,
184 (uintptr_t)desired, order);
190#define FF_ATOMIC_PTR(op, object) \
191 _Generic((char (*)[sizeof(*(object))])0, \
192 char (*)[sizeof(void *)]: ff_atomic_##op##_ptr, \
193 default: ff_atomic_unsupported)
199#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1944
200#define FF_ATOMIC_CHAR(x)
202#define FF_ATOMIC_CHAR(x) char: x,
205#define FF_ATOMIC_INT(op, object) \
206 FF_ATOMIC_CHAR(FF_ATOMIC_SIZE(op, sizeof(*(object)))) \
207 signed char: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
208 unsigned char: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
209 short: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
210 unsigned short: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
211 int: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
212 unsigned int: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
213 long: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
214 unsigned long: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
215 long long: FF_ATOMIC_SIZE(op, sizeof(*(object))), \
216 unsigned long long: FF_ATOMIC_SIZE(op, sizeof(*(object)))
219#define FF_ATOMIC_FN(op, object) \
220 _Generic(*(object), \
221 bool: ff_atomic_##op##_bool, \
222 FF_ATOMIC_INT(op, object), \
223 default: FF_ATOMIC_PTR(op, object))
227#define FF_ATOMIC_FETCH_FN(op, object) \
228 _Generic(*(object), FF_ATOMIC_INT(op, object))
231#define ff_atomic_c(object, x) \
232 _Generic(*(object), \
234 FF_ATOMIC_CHAR((char)(x)) \
235 signed char: (signed char)(x), \
236 unsigned char: (unsigned char)(x), \
238 unsigned short: (unsigned short)(x), \
240 unsigned int: (unsigned int)(x), \
242 unsigned long: (unsigned long)(x), \
243 long long: (long long)(x), \
244 unsigned long long: (unsigned long long)(x), \
245 default: (void *)(uintptr_t)(x))
247#define atomic_load_explicit(object, order) \
248 ff_atomic_c(object, FF_ATOMIC_FN(load, object)(object, order))
250#define atomic_load(object) \
251 atomic_load_explicit(object, memory_order_seq_cst)
253#define atomic_store_explicit(object, desired, order) \
254 FF_ATOMIC_FN(store, object)(object, desired, order)
256#define atomic_store(object, desired) \
257 atomic_store_explicit(object, desired, memory_order_seq_cst)
259#define atomic_exchange_explicit(object, desired, order) \
260 ff_atomic_c(object, FF_ATOMIC_FN(exchange, object)(object, desired, order))
262#define atomic_exchange(object, desired) \
263 atomic_exchange_explicit(object, desired, memory_order_seq_cst)
274#define atomic_compare_exchange_strong_explicit(object, expected, desired, \
276 ((void)_Generic((char (*)[sizeof(*(expected))])0, \
277 char (*)[sizeof(*(object))]: 0), \
278 FF_ATOMIC_FN(cas, object)(object, expected, desired, \
279 ff_atomic_cas_order(success, failure)))
281#define atomic_compare_exchange_strong(object, expected, desired) \
282 atomic_compare_exchange_strong_explicit(object, expected, desired, \
283 memory_order_seq_cst, \
284 memory_order_seq_cst)
286#define atomic_compare_exchange_weak_explicit(object, expected, desired, \
288 atomic_compare_exchange_strong_explicit(object, expected, desired, \
291#define atomic_compare_exchange_weak(object, expected, desired) \
292 atomic_compare_exchange_strong(object, expected, desired)
294#define ff_atomic_fetch(object, operand, op, order) \
295 ff_atomic_c(object, FF_ATOMIC_FETCH_FN(op, object)(object, operand, order))
297#define atomic_fetch_add_explicit(object, operand, order) \
298 ff_atomic_fetch(object, operand, fetch_add, order)
300#define atomic_fetch_sub_explicit(object, operand, order) \
301 ff_atomic_fetch(object, operand, fetch_sub, order)
303#define atomic_fetch_or_explicit(object, operand, order) \
304 ff_atomic_fetch(object, operand, fetch_or, order)
306#define atomic_fetch_xor_explicit(object, operand, order) \
307 ff_atomic_fetch(object, operand, fetch_xor, order)
309#define atomic_fetch_and_explicit(object, operand, order) \
310 ff_atomic_fetch(object, operand, fetch_and, order)
312#define atomic_fetch_add(object, operand) \
313 atomic_fetch_add_explicit(object, operand, memory_order_seq_cst)
315#define atomic_fetch_sub(object, operand) \
316 atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst)
318#define atomic_fetch_or(object, operand) \
319 atomic_fetch_or_explicit(object, operand, memory_order_seq_cst)
321#define atomic_fetch_xor(object, operand) \
322 atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst)
324#define atomic_fetch_and(object, operand) \
325 atomic_fetch_and_explicit(object, operand, memory_order_seq_cst)
331#define ATOMIC_FLAG_INIT { 0 }
333#define atomic_flag_test_and_set_explicit(object, order) \
334 atomic_exchange_explicit(&(object)->value, 1, order)
336#define atomic_flag_test_and_set(object) \
337 atomic_flag_test_and_set_explicit(object, memory_order_seq_cst)
339#define atomic_flag_clear_explicit(object, order) \
340 atomic_store_explicit(&(object)->value, 0, order)
342#define atomic_flag_clear(object) \
343 atomic_flag_clear_explicit(object, memory_order_seq_cst)
#define FF_ATOMIC_ALIGN64
Macro definitions for various function/variable attributes.
static int exchange(MqcState *mqc, uint8_t *cxstate, int lps)
FF_ATOMIC_ALIGN64 int_least64_t atomic_int_least64_t
int_fast8_t atomic_int_fast8_t
uint_least8_t atomic_uint_least8_t
static av_always_inline uintptr_t ff_atomic_exchange_ptr(volatile void *object, const volatile void *desired, memory_order order)
#define FF_ATOMIC_SIZE(op, size)
unsigned char atomic_uchar
uint_fast16_t atomic_uint_fast16_t
uint_least16_t atomic_char16_t
FF_ATOMIC_ALIGN64 unsigned long long atomic_ullong
static av_always_inline memory_order ff_atomic_cas_order(memory_order success, memory_order failure)
FF_ATOMIC_ALIGN64 uint_least64_t atomic_uint_least64_t
FF_ATOMIC_ALIGN64 long long atomic_llong
static av_always_inline bool ff_atomic_cas_ptr(volatile void *object, void *expected, const volatile void *desired, memory_order order)
static av_always_inline void ff_atomic_store_ptr(volatile void *object, const volatile void *desired, memory_order order)
uint_fast8_t atomic_uint_fast8_t
uint_least32_t atomic_char32_t
unsigned char atomic_char8_t
FF_ATOMIC_ALIGN64 int_fast64_t atomic_int_fast64_t
unsigned short atomic_ushort
ptrdiff_t atomic_ptrdiff_t
int_least32_t atomic_int_least32_t
unsigned long atomic_ulong
FF_ATOMIC_ALIGN64 uint_fast64_t atomic_uint_fast64_t
uintptr_t atomic_uintptr_t
void ff_atomic_unsupported(void)
static av_always_inline uintptr_t ff_atomic_load_ptr(const volatile void *object, memory_order order)
int_fast32_t atomic_int_fast32_t
int_fast16_t atomic_int_fast16_t
uint_fast32_t atomic_uint_fast32_t
int_least16_t atomic_int_least16_t
FF_ATOMIC_ALIGN64 intmax_t atomic_intmax_t
uint_least16_t atomic_uint_least16_t
FF_ATOMIC_ALIGN64 uintmax_t atomic_uintmax_t
int_least8_t atomic_int_least8_t
uint_least32_t atomic_uint_least32_t