diff --git a/include/SDL3/SDL_atomic.h b/include/SDL3/SDL_atomic.h index bfcf81ee067ba..09c92b7f66f86 100644 --- a/include/SDL3/SDL_atomic.h +++ b/include/SDL3/SDL_atomic.h @@ -365,6 +365,17 @@ typedef void (*SDL_KernelMemoryBarrierFunc)(); #endif +/** + * Memory ordering. TODO: document this + */ +typedef enum SDL_MemoryOrder { + SDL_MEMORY_ORDER_RELAXED, + SDL_MEMORY_ORDER_ACQUIRE, + SDL_MEMORY_ORDER_RELEASE, + SDL_MEMORY_ORDER_ACQ_REL, + SDL_MEMORY_ORDER_SEQ_CST, +} SDL_MemoryOrder; + /** * A type representing an atomic integer value. * @@ -395,7 +406,8 @@ typedef void (*SDL_KernelMemoryBarrierFunc)(); typedef struct SDL_AtomicInt { int value; } SDL_AtomicInt; /** - * Set an atomic variable to a new value if it is currently an old value. + * Set an atomic variable to a new value if it is currently an old value, + * using SEQ_CST memory ordering. * * ***Note: If you don't know what this function is for, you shouldn't use * it!*** @@ -409,11 +421,67 @@ typedef struct SDL_AtomicInt { int value; } SDL_AtomicInt; * * \since This function is available since SDL 3.2.0. * + * \sa SDL_CompareAndSwapAtomicIntStrongWithOrder + * \sa SDL_CompareAndSwapAtomicIntWeakWithOrder * \sa SDL_GetAtomicInt * \sa SDL_SetAtomicInt */ extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, int oldval, int newval); +/** + * Set an atomic variable to a new value if it is currently an old value, + * using the provided memory ordering. If you use this is a loop, consider + * using SDL_CompareAndSwapAtomicIntWeakWithOrder instead. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicInt variable to be modified. + * \param oldval the old value. + * \param newval the new value. + * \param successord memory order to use on a successful compare and swap. + * \param failord memory order to use on a failed compare. May not be RELEASE, ACQ_REL, or stronger than successord. + * \returns true if the atomic variable was set, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CompareAndSwapAtomicInt + * \sa SDL_CompareAndSwapAtomicIntWeakWithOrder + * \sa SDL_GetAtomicIntWithOrder + * \sa SDL_SetAtomicIntWithOrder + */ +extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicIntStrongWithOrder(SDL_AtomicInt *a, int oldval, int newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord); + +/** + * Set an atomic variable to a new value if it is currently an old value, + * using the provided memory ordering. This version can spuriously fail, + * but may be faster than SDL_CompareAndSwapAtomicIntStrongWithOrder in a loop. + * If SDL_CompareAndSwapAtomicIntStrongWithOrder wouldn't need a loop you should + * use that instead. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicInt variable to be modified. + * \param oldval the old value. + * \param newval the new value. + * \param successord memory order to use on a successful compare and swap. + * \param failord memory order to use on a failed compare. May not be RELEASE, ACQ_REL, or stronger than successord. + * \returns true if the atomic variable was set, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CompareAndSwapAtomicInt + * \sa SDL_CompareAndSwapAtomicIntStrongWithOrder + * \sa SDL_GetAtomicIntWithOrder + * \sa SDL_SetAtomicIntWithOrder + */ +extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicIntWeakWithOrder(SDL_AtomicInt *a, int oldval, int newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord); + /** * Set an atomic variable to a value. * @@ -434,6 +502,25 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, i */ extern SDL_DECLSPEC int SDLCALL SDL_SetAtomicInt(SDL_AtomicInt *a, int v); +/** + * Set an atomic variable to a value using the provided memory ordering. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicInt variable to be modified. + * \param v the desired value. + * \param order memory order to use for the atomic exchange. + * \returns the previous value of the atomic variable. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_GetAtomicIntWithOrder + */ +extern SDL_DECLSPEC int SDLCALL SDL_SetAtomicIntWithOrder(SDL_AtomicInt *a, int v, SDL_MemoryOrder order); + /** * Get the value of an atomic variable. * @@ -451,6 +538,24 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetAtomicInt(SDL_AtomicInt *a, int v); */ extern SDL_DECLSPEC int SDLCALL SDL_GetAtomicInt(SDL_AtomicInt *a); +/** + * Get the value of an atomic variable using the provided memory ordering. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicInt variable. + * \param order memory order to use for the atomic load. Must be one of RELAXED, ACQUIRE or SEQ_CST. + * \returns the current value of an atomic variable. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_SetAtomicIntWithOrder + */ +extern SDL_DECLSPEC int SDLCALL SDL_GetAtomicIntWithOrder(SDL_AtomicInt *a, SDL_MemoryOrder order); + /** * Add to an atomic variable. * @@ -472,6 +577,26 @@ extern SDL_DECLSPEC int SDLCALL SDL_GetAtomicInt(SDL_AtomicInt *a); */ extern SDL_DECLSPEC int SDLCALL SDL_AddAtomicInt(SDL_AtomicInt *a, int v); +/** + * Add to an atomic variable using the provided memory ordering. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicInt variable to be modified. + * \param v the desired value to add. + * \param order memory order to use for the atomic add. + * \returns the previous value of the atomic variable. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_AtomicDecRefWithOrder + * \sa SDL_AtomicIncRefWithOrder + */ +extern SDL_DECLSPEC int SDLCALL SDL_AddAtomicIntWithOrder(SDL_AtomicInt *a, int v, SDL_MemoryOrder order); + #ifndef SDL_AtomicIncRef /** @@ -491,6 +616,26 @@ extern SDL_DECLSPEC int SDLCALL SDL_AddAtomicInt(SDL_AtomicInt *a, int v); #define SDL_AtomicIncRef(a) SDL_AddAtomicInt(a, 1) #endif +#ifndef SDL_AtomicIncRefWithOrder + +/** + * Increment an atomic variable used as a reference count, using the provided memory ordering. + * + * ***Note: If you don't know what this macro is for, you shouldn't use it!*** + * + * \param a a pointer to an SDL_AtomicInt to increment. + * \param o memory order to use for the atomic increment. + * \returns the previous value of the atomic variable. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.4.0. + * + * \sa SDL_AtomicDecRefWithOrder + */ +#define SDL_AtomicIncRefWithOrder(a, o) SDL_AddAtomicIntWithOrder(a, 1, o) +#endif + #ifndef SDL_AtomicDecRef /** @@ -511,6 +656,27 @@ extern SDL_DECLSPEC int SDLCALL SDL_AddAtomicInt(SDL_AtomicInt *a, int v); #define SDL_AtomicDecRef(a) (SDL_AddAtomicInt(a, -1) == 1) #endif +#ifndef SDL_AtomicDecRefWithOrder + +/** + * Decrement an atomic variable used as a reference count, using the provided memory ordering. + * + * ***Note: If you don't know what this macro is for, you shouldn't use it!*** + * + * \param a a pointer to an SDL_AtomicInt to decrement. + * \param o memory order to use for the atomic decrement. + * \returns true if the variable reached zero after decrementing, false + * otherwise. + * + * \threadsafety It is safe to call this macro from any thread. + * + * \since This macro is available since SDL 3.4.0. + * + * \sa SDL_AtomicIncRef + */ +#define SDL_AtomicDecRefWithOrder(a, o) (SDL_AddAtomicIntWithOrder(a, -1, o) == 1) +#endif + /** * A type representing an atomic unsigned 32-bit value. * @@ -554,11 +720,67 @@ typedef struct SDL_AtomicU32 { Uint32 value; } SDL_AtomicU32; * * \since This function is available since SDL 3.2.0. * + * \sa SDL_CompareAndSwapAtomicU32StrongWithOrder + * \sa SDL_CompareAndSwapAtomicU32WeakWithOrder * \sa SDL_GetAtomicU32 * \sa SDL_SetAtomicU32 */ extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval); +/** + * Set an atomic variable to a new value if it is currently an old value, + * using the provided memory ordering. If you use this is a loop, consider + * using SDL_CompareAndSwapAtomicU32WeakWithOrder instead. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicU32 variable to be modified. + * \param oldval the old value. + * \param newval the new value. + * \param successord memory order to use on a successful compare and swap. + * \param failord memory order to use on a failed compare. May not be RELEASE, ACQ_REL, or stronger than successord. + * \returns true if the atomic variable was set, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CompareAndSwapAtomicU32 + * \sa SDL_CompareAndSwapAtomicU32WeakWithOrder + * \sa SDL_GetAtomicU32WithOrder + * \sa SDL_SetAtomicU32WithOrder + */ +extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicU32StrongWithOrder(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord); + +/** + * Set an atomic variable to a new value if it is currently an old value, + * using the provided memory ordering. This version can spuriously fail, + * but may be faster than SDL_CompareAndSwapAtomicU32StrongWithOrder in a loop. + * If SDL_CompareAndSwapAtomicU32StrongWithOrder wouldn't need a loop you should + * use that instead. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicU32 variable to be modified. + * \param oldval the old value. + * \param newval the new value. + * \param successord memory order to use on a successful compare and swap. + * \param failord memory order to use on a failed compare. May not be RELEASE, ACQ_REL, or stronger than successord. + * \returns true if the atomic variable was set, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CompareAndSwapAtomicU32 + * \sa SDL_CompareAndSwapAtomicU32StrongWithOrder + * \sa SDL_GetAtomicU32WithOrder + * \sa SDL_SetAtomicU32WithOrder + */ +extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicU32WeakWithOrder(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord); + /** * Set an atomic variable to a value. * @@ -579,6 +801,25 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, U */ extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v); +/** + * Set an atomic variable to a value using the provided memory ordering. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicU32 variable to be modified. + * \param v the desired value. + * \param order memory order to use for the atomic exchange. + * \returns the previous value of the atomic variable. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_GetAtomicU32WithOrder + */ +extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32WithOrder(SDL_AtomicU32 *a, Uint32 v, SDL_MemoryOrder order); + /** * Get the value of an atomic variable. * @@ -596,6 +837,24 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v); */ extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAtomicU32(SDL_AtomicU32 *a); +/** + * Get the value of an atomic variable using the provided memory ordering. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicU32 variable. + * \param order memory order to use for the atomic load. Must be one of RELAXED, ACQUIRE or SEQ_CST. + * \returns the current value of an atomic variable. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_SetAtomicU32WithOrder + */ +extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAtomicU32WithOrder(SDL_AtomicU32 *a, SDL_MemoryOrder order); + /** * Add to an atomic variable. * @@ -614,6 +873,23 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAtomicU32(SDL_AtomicU32 *a); */ extern SDL_DECLSPEC Uint32 SDLCALL SDL_AddAtomicU32(SDL_AtomicU32 *a, int v); +/** + * Add to an atomic variable using the provided memory ordering. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to an SDL_AtomicU32 variable to be modified. + * \param v the desired value to add or subtract. + * \param order memory order to use for the atomic add. + * \returns the previous value of the atomic variable. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + */ +extern SDL_DECLSPEC Uint32 SDLCALL SDL_AddAtomicU32WithOrder(SDL_AtomicU32 *a, int v, SDL_MemoryOrder order); + /** * Set a pointer to a new value if it is currently an old value. * @@ -629,12 +905,68 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_AddAtomicU32(SDL_AtomicU32 *a, int v); * * \since This function is available since SDL 3.2.0. * + * \sa SDL_CompareAndSwapAtomicPointerStrongWithOrder + * \sa SDL_CompareAndSwapAtomicPointerWeakWithOrder * \sa SDL_CompareAndSwapAtomicInt * \sa SDL_GetAtomicPointer * \sa SDL_SetAtomicPointer */ extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicPointer(void **a, void *oldval, void *newval); +/** + * Set a pointer to a new value if it is currently an old value, + * using the provided memory ordering. If you use this is a loop, consider + * using SDL_CompareAndSwapAtomicIntWeakWithOrder instead. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer. + * \param oldval the old pointer value. + * \param newval the new pointer value. + * \param successord memory order to use on a successful compare and swap. + * \param failord memory order to use on a failed compare. May not be RELEASE, ACQ_REL, or stronger than successord. + * \returns true if the pointer was set, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CompareAndSwapAtomicPointer + * \sa SDL_CompareAndSwapAtomicPointerWeakWithOrder + * \sa SDL_GetAtomicPointerWithOrder + * \sa SDL_SetAtomicPointerWithOrder + */ +extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicPointerStrongWithOrder(void **a, void *oldval, void *newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord); + +/** + * Set a pointer to a new value if it is currently an old value, + * using the provided memory ordering. This version can spuriously fail, + * but may be faster than SDL_CompareAndSwapAtomicPointerStrongWithOrder in a loop. + * If SDL_CompareAndSwapAtomicPointerStrongWithOrder wouldn't need a loop you should + * use that instead. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer. + * \param oldval the old pointer value. + * \param newval the new pointer value. + * \param successord memory order to use on a successful compare and swap. + * \param failord memory order to use on a failed compare. May not be RELEASE, ACQ_REL, or stronger than successord. + * \returns true if the pointer was set, false otherwise. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CompareAndSwapAtomicPointer + * \sa SDL_CompareAndSwapAtomicPointerStrongWithOrder + * \sa SDL_GetAtomicPointerWithOrder + * \sa SDL_SetAtomicPointerWithOrder + */ +extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicPointerWeakWithOrder(void **a, void *oldval, void *newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord); + /** * Set a pointer to a value atomically. * @@ -654,6 +986,26 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicPointer(void **a, void */ extern SDL_DECLSPEC void * SDLCALL SDL_SetAtomicPointer(void **a, void *v); +/** + * Set a pointer to a value atomically using the provided memory ordering. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer. + * \param v the desired pointer value. + * \param order memory order to use for the atomic exchange. + * \returns the previous value of the pointer. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CompareAndSwapAtomicPointerWithOrder + * \sa SDL_GetAtomicPointerWithOrder + */ +extern SDL_DECLSPEC void * SDLCALL SDL_SetAtomicPointerWithOrder(void **a, void *v, SDL_MemoryOrder order); + /** * Get the value of a pointer atomically. * @@ -672,6 +1024,25 @@ extern SDL_DECLSPEC void * SDLCALL SDL_SetAtomicPointer(void **a, void *v); */ extern SDL_DECLSPEC void * SDLCALL SDL_GetAtomicPointer(void **a); +/** + * Get the value of a pointer atomically using the provided memory ordering. + * + * ***Note: If you don't know what this function is for, you shouldn't use + * it!*** + * + * \param a a pointer to a pointer. + * \param order memory order to use for the atomic load. Must be one of RELAXED, ACQUIRE or SEQ_CST. + * \returns the current value of a pointer. + * + * \threadsafety It is safe to call this function from any thread. + * + * \since This function is available since SDL 3.4.0. + * + * \sa SDL_CompareAndSwapAtomicPointerWithOrder + * \sa SDL_SetAtomicPointerWithOrder + */ +extern SDL_DECLSPEC void * SDLCALL SDL_GetAtomicPointerWithOrder(void **a, SDL_MemoryOrder order); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/src/atomic/SDL_atomic.c b/src/atomic/SDL_atomic.c index c51ba710a563a..b2708842a1274 100644 --- a/src/atomic/SDL_atomic.c +++ b/src/atomic/SDL_atomic.c @@ -23,6 +23,9 @@ #if defined(_MSC_VER) && (_MSC_VER >= 1900) #include #define HAVE_MSC_ATOMICS 1 +#if defined(_M_ARM) || defined(_M_ARM64) +#define HAVE_MSC_ORDERED_ATOMICS 1 +#endif #endif #ifdef SDL_PLATFORM_MACOS // !!! FIXME: should we favor gcc atomics? @@ -42,9 +45,32 @@ #define HAVE_ATOMIC_LOAD_N 1 #endif #endif +#if __has_builtin(__atomic_compare_exchange_n) || defined(HAVE_GCC_ATOMICS) +/* !!! FIXME: see above */ +#ifndef SDL_PLATFORM_ANDROID +#define HAVE_ATOMIC_COMPARE_EXCHANGE_N 1 +#endif +#endif +#if __has_builtin(__atomic_exchange_n) || defined(HAVE_GCC_ATOMICS) +/* !!! FIXME: see above */ +#ifndef SDL_PLATFORM_ANDROID +#define HAVE_ATOMIC_EXCHANGE_N 1 +#endif +#endif +#if __has_builtin(__atomic_fetch_add) || defined(HAVE_GCC_ATOMICS) +/* !!! FIXME: see above */ +#ifndef SDL_PLATFORM_ANDROID +#define HAVE_ATOMIC_FETCH_ADD 1 +#endif +#endif #elif defined(__GNUC__) #if (__GNUC__ >= 5) #define HAVE_ATOMIC_LOAD_N 1 +#if !defined(SDL_PLATFORM_PS2) +#define HAVE_ATOMIC_COMPARE_EXCHANGE_N 1 +#define HAVE_ATOMIC_EXCHANGE_N 1 +#define HAVE_ATOMIC_FETCH_ADD 1 +#endif #endif #endif @@ -122,9 +148,85 @@ static SDL_INLINE void leaveLock(void *a) } #endif +#ifdef HAVE_ATOMIC_COMPARE_EXCHANGE_N +// __atomic ordering arguments should be compile time constants +#define COMPARE_AND_SWAP_INT_WITH_ORDER(value, oldval, newval, weak, successord, failord) \ + switch (successord) { \ + case SDL_MEMORY_ORDER_RELAXED: \ + switch (failord) { \ + case SDL_MEMORY_ORDER_RELAXED: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_RELAXED, __ATOMIC_RELAXED); \ + default: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ + } \ + case SDL_MEMORY_ORDER_ACQUIRE: \ + switch (failord) { \ + case SDL_MEMORY_ORDER_RELAXED: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); \ + case SDL_MEMORY_ORDER_ACQUIRE: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE); \ + default: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ + } \ + case SDL_MEMORY_ORDER_RELEASE: \ + switch (failord) { \ + case SDL_MEMORY_ORDER_RELAXED: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_RELEASE, __ATOMIC_RELAXED); \ + default: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ + } \ + case SDL_MEMORY_ORDER_ACQ_REL: \ + switch (failord) { \ + case SDL_MEMORY_ORDER_RELAXED: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); \ + case SDL_MEMORY_ORDER_ACQUIRE: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE); \ + default: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ + } \ + default: \ + switch (failord) { \ + case SDL_MEMORY_ORDER_RELAXED: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); \ + case SDL_MEMORY_ORDER_ACQUIRE: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_SEQ_CST, __ATOMIC_ACQUIRE); \ + default: \ + return __atomic_compare_exchange_n(value, &oldval, newval, weak, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); \ + } \ + } +#define COMPARE_AND_SWAP_POINTER_WITH_ORDER(value, oldval, newval, weak, successord, failord) \ + COMPARE_AND_SWAP_INT_WITH_ORDER(value, oldval, newval, weak, successord, failord) +#elif defined(HAVE_MSC_ORDERED_ATOMICS) +#define COMPARE_AND_SWAP_INT_WITH_ORDER(value, oldval, newval, weak, successord, failord) \ + SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(long) == sizeof(*value)); \ + switch (successord) { \ + case SDL_MEMORY_ORDER_RELAXED: \ + return _InterlockedCompareExchange_nf((long *)(value), (long)(newval), (long)(oldval)) == (long)(oldval); \ + case SDL_MEMORY_ORDER_ACQUIRE: \ + return _InterlockedCompareExchange_acq((long *)(value), (long)(newval), (long)(oldval)) == (long)(oldval); \ + case SDL_MEMORY_ORDER_RELEASE: \ + return _InterlockedCompareExchange_rel((long *)(value), (long)(newval), (long)(oldval)) == (long)(oldval); \ + default: \ + return _InterlockedCompareExchange((long *)(value), (long)(newval), (long)(oldval)) == (long)(oldval); \ + } +#define COMPARE_AND_SWAP_POINTER_WITH_ORDER(value, oldval, newval, weak, successord, failord) \ + switch (successord) { \ + case SDL_MEMORY_ORDER_RELAXED: \ + return _InterlockedCompareExchangePointer_nf(value, newval, oldval) == oldval; \ + case SDL_MEMORY_ORDER_ACQUIRE: \ + return _InterlockedCompareExchangePointer_acq(value, newval, oldval) == oldval; \ + case SDL_MEMORY_ORDER_RELEASE: \ + return _InterlockedCompareExchangePointer_rel(value, newval, oldval) == oldval; \ + default: \ + return _InterlockedCompareExchangePointer(value, newval, oldval) == oldval; \ + } +#endif + bool SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, int oldval, int newval) { -#ifdef HAVE_MSC_ATOMICS +#ifdef HAVE_ATOMIC_COMPARE_EXCHANGE_N + return __atomic_compare_exchange_n(&a->value, &oldval, newval, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(long) == sizeof(a->value)); return _InterlockedCompareExchange((long *)&a->value, (long)newval, (long)oldval) == (long)oldval; #elif defined(HAVE_WATCOM_ATOMICS) @@ -152,9 +254,29 @@ bool SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, int oldval, int newval) #endif } +bool SDL_CompareAndSwapAtomicIntStrongWithOrder(SDL_AtomicInt *a, int oldval, int newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord) +{ +#ifdef COMPARE_AND_SWAP_INT_WITH_ORDER + COMPARE_AND_SWAP_INT_WITH_ORDER(&a->value, oldval, newval, false, successord, failord) +#else + return SDL_CompareAndSwapAtomicInt(a, oldval, newval); +#endif +} + +bool SDL_CompareAndSwapAtomicIntWeakWithOrder(SDL_AtomicInt *a, int oldval, int newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord) +{ +#ifdef COMPARE_AND_SWAP_INT_WITH_ORDER + COMPARE_AND_SWAP_INT_WITH_ORDER(&a->value, oldval, newval, true, successord, failord) +#else + return SDL_CompareAndSwapAtomicInt(a, oldval, newval); +#endif +} + bool SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval) { -#ifdef HAVE_MSC_ATOMICS +#ifdef HAVE_ATOMIC_COMPARE_EXCHANGE_N + return __atomic_compare_exchange_n(&a->value, &oldval, newval, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(long) == sizeof(a->value)); return _InterlockedCompareExchange((long *)&a->value, (long)newval, (long)oldval) == (long)oldval; #elif defined(HAVE_WATCOM_ATOMICS) @@ -183,9 +305,29 @@ bool SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval) #endif } +bool SDL_CompareAndSwapAtomicU32StrongWithOrder(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord) +{ +#ifdef COMPARE_AND_SWAP_INT_WITH_ORDER + COMPARE_AND_SWAP_INT_WITH_ORDER(&a->value, oldval, newval, false, successord, failord) +#else + return SDL_CompareAndSwapAtomicU32(a, oldval, newval); +#endif +} + +bool SDL_CompareAndSwapAtomicU32WeakWithOrder(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord) +{ +#ifdef COMPARE_AND_SWAP_INT_WITH_ORDER + COMPARE_AND_SWAP_INT_WITH_ORDER(&a->value, oldval, newval, true, successord, failord) +#else + return SDL_CompareAndSwapAtomicU32(a, oldval, newval); +#endif +} + bool SDL_CompareAndSwapAtomicPointer(void **a, void *oldval, void *newval) { -#ifdef HAVE_MSC_ATOMICS +#ifdef HAVE_ATOMIC_COMPARE_EXCHANGE_N + return __atomic_compare_exchange_n(a, &oldval, newval, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) return _InterlockedCompareExchangePointer(a, newval, oldval) == oldval; #elif defined(HAVE_WATCOM_ATOMICS) return _SDL_cmpxchg_watcom((int *)a, (long)newval, (long)oldval); @@ -213,9 +355,29 @@ bool SDL_CompareAndSwapAtomicPointer(void **a, void *oldval, void *newval) #endif } +bool SDL_CompareAndSwapAtomicPointerStrongWithOrder(void **a, void *oldval, void *newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord) +{ +#ifdef COMPARE_AND_SWAP_POINTER_WITH_ORDER + COMPARE_AND_SWAP_POINTER_WITH_ORDER(a, oldval, newval, false, successord, failord) +#else + return SDL_CompareAndSwapAtomicPointer(a, oldval, newval); +#endif +} + +bool SDL_CompareAndSwapAtomicPointerWeakWithOrder(void **a, void *oldval, void *newval, SDL_MemoryOrder successord, SDL_MemoryOrder failord) +{ +#ifdef COMPARE_AND_SWAP_POINTER_WITH_ORDER + COMPARE_AND_SWAP_POINTER_WITH_ORDER(a, oldval, newval, true, successord, failord) +#else + return SDL_CompareAndSwapAtomicPointer(a, oldval, newval); +#endif +} + int SDL_SetAtomicInt(SDL_AtomicInt *a, int v) { -#ifdef HAVE_MSC_ATOMICS +#ifdef HAVE_ATOMIC_EXCHANGE_N + return __atomic_exchange_n(&a->value, v, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); return _InterlockedExchange((long *)&a->value, v); #elif defined(HAVE_WATCOM_ATOMICS) @@ -234,9 +396,34 @@ int SDL_SetAtomicInt(SDL_AtomicInt *a, int v) #endif } +int SDL_SetAtomicIntWithOrder(SDL_AtomicInt *a, int v, SDL_MemoryOrder order) +{ +#ifdef HAVE_ATOMIC_EXCHANGE_N + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return __atomic_exchange_n(&a->value, v, __ATOMIC_RELAXED); + case SDL_MEMORY_ORDER_ACQUIRE: return __atomic_exchange_n(&a->value, v, __ATOMIC_ACQUIRE); + case SDL_MEMORY_ORDER_RELEASE: return __atomic_exchange_n(&a->value, v, __ATOMIC_RELEASE); + case SDL_MEMORY_ORDER_ACQ_REL: return __atomic_exchange_n(&a->value, v, __ATOMIC_ACQ_REL); + default: return __atomic_exchange_n(&a->value, v, __ATOMIC_SEQ_CST); + } +#elif defined(HAVE_MSC_ORDERED_ATOMICS) + SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return _InterlockedExchange_nf((long *)&a->value, v); + case SDL_MEMORY_ORDER_ACQUIRE: return _InterlockedExchange_acq((long *)&a->value, v); + case SDL_MEMORY_ORDER_RELEASE: return _InterlockedExchange_rel((long *)&a->value, v); + default: return _InterlockedExchange((long *)&a->value, v); + } +#else + return SDL_SetAtomicInt(a, v); +#endif +} + Uint32 SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v) { -#ifdef HAVE_MSC_ATOMICS +#ifdef HAVE_ATOMIC_EXCHANGE_N + return __atomic_exchange_n(&a->value, v, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); return _InterlockedExchange((long *)&a->value, v); #elif defined(HAVE_WATCOM_ATOMICS) @@ -255,9 +442,34 @@ Uint32 SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v) #endif } +Uint32 SDL_SetAtomicU32WithOrder(SDL_AtomicU32 *a, Uint32 v, SDL_MemoryOrder order) +{ +#ifdef HAVE_ATOMIC_EXCHANGE_N + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return __atomic_exchange_n(&a->value, v, __ATOMIC_RELAXED); + case SDL_MEMORY_ORDER_ACQUIRE: return __atomic_exchange_n(&a->value, v, __ATOMIC_ACQUIRE); + case SDL_MEMORY_ORDER_RELEASE: return __atomic_exchange_n(&a->value, v, __ATOMIC_RELEASE); + case SDL_MEMORY_ORDER_ACQ_REL: return __atomic_exchange_n(&a->value, v, __ATOMIC_ACQ_REL); + default: return __atomic_exchange_n(&a->value, v, __ATOMIC_SEQ_CST); + } +#elif defined(HAVE_MSC_ORDERED_ATOMICS) + SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return _InterlockedExchange_nf((long *)&a->value, v); + case SDL_MEMORY_ORDER_ACQUIRE: return _InterlockedExchange_acq((long *)&a->value, v); + case SDL_MEMORY_ORDER_RELEASE: return _InterlockedExchange_rel((long *)&a->value, v); + default: return _InterlockedExchange((long *)&a->value, v); + } +#else + return SDL_SetAtomicU32(a, v); +#endif +} + void *SDL_SetAtomicPointer(void **a, void *v) { -#ifdef HAVE_MSC_ATOMICS +#ifdef HAVE_ATOMIC_EXCHANGE_N + return __atomic_exchange_n(a, v, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) return _InterlockedExchangePointer(a, v); #elif defined(HAVE_WATCOM_ATOMICS) return (void *)_SDL_xchg_watcom((int *)a, (long)v); @@ -274,9 +486,33 @@ void *SDL_SetAtomicPointer(void **a, void *v) #endif } +void *SDL_SetAtomicPointerWithOrder(void **a, void *v, SDL_MemoryOrder order) +{ +#ifdef HAVE_ATOMIC_EXCHANGE_N + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return __atomic_exchange_n(a, v, __ATOMIC_RELAXED); + case SDL_MEMORY_ORDER_ACQUIRE: return __atomic_exchange_n(a, v, __ATOMIC_ACQUIRE); + case SDL_MEMORY_ORDER_RELEASE: return __atomic_exchange_n(a, v, __ATOMIC_RELEASE); + case SDL_MEMORY_ORDER_ACQ_REL: return __atomic_exchange_n(a, v, __ATOMIC_ACQ_REL); + default: return __atomic_exchange_n(a, v, __ATOMIC_SEQ_CST); + } +#elif defined(HAVE_MSC_ORDERED_ATOMICS) + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return _InterlockedExchangePointer_nf(a, v); + case SDL_MEMORY_ORDER_ACQUIRE: return _InterlockedExchangePointer_acq(a, v); + case SDL_MEMORY_ORDER_RELEASE: return _InterlockedExchangePointer_rel(a, v); + default: return _InterlockedExchangePointer(a, v); + } +#else + return SDL_SetAtomicPointer(a, v); +#endif +} + int SDL_AddAtomicInt(SDL_AtomicInt *a, int v) { -#ifdef HAVE_MSC_ATOMICS +#ifdef HAVE_ATOMIC_FETCH_ADD + return __atomic_fetch_add(&a->value, v, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(long) == sizeof(a->value)); return _InterlockedExchangeAdd((long *)&a->value, v); #elif defined(HAVE_WATCOM_ATOMICS) @@ -298,9 +534,34 @@ int SDL_AddAtomicInt(SDL_AtomicInt *a, int v) #endif } +int SDL_AddAtomicIntWithOrder(SDL_AtomicInt *a, int v, SDL_MemoryOrder order) +{ +#ifdef HAVE_ATOMIC_FETCH_ADD + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return __atomic_fetch_add(&a->value, v, __ATOMIC_RELAXED); + case SDL_MEMORY_ORDER_ACQUIRE: return __atomic_fetch_add(&a->value, v, __ATOMIC_ACQUIRE); + case SDL_MEMORY_ORDER_RELEASE: return __atomic_fetch_add(&a->value, v, __ATOMIC_RELEASE); + case SDL_MEMORY_ORDER_ACQ_REL: return __atomic_fetch_add(&a->value, v, __ATOMIC_ACQ_REL); + default: return __atomic_fetch_add(&a->value, v, __ATOMIC_SEQ_CST); + } +#elif defined(HAVE_MSC_ORDERED_ATOMICS) + SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return _InterlockedExchangeAdd_nf((long *)&a->value, v); + case SDL_MEMORY_ORDER_ACQUIRE: return _InterlockedExchangeAdd_acq((long *)&a->value, v); + case SDL_MEMORY_ORDER_RELEASE: return _InterlockedExchangeAdd_rel((long *)&a->value, v); + default: return _InterlockedExchangeAdd((long *)&a->value, v); + } +#else + return SDL_AddAtomicInt(a, v); +#endif +} + Uint32 SDL_AddAtomicU32(SDL_AtomicU32 *a, int v) { -#ifdef HAVE_MSC_ATOMICS +#ifdef HAVE_ATOMIC_FETCH_ADD + return __atomic_fetch_add(&a->value, v, __ATOMIC_SEQ_CST); +#elif defined(HAVE_MSC_ATOMICS) SDL_COMPILE_TIME_ASSERT(atomic_add, sizeof(long) == sizeof(a->value)); return (Uint32)_InterlockedExchangeAdd((long *)&a->value, v); #elif defined(HAVE_WATCOM_ATOMICS) @@ -322,6 +583,29 @@ Uint32 SDL_AddAtomicU32(SDL_AtomicU32 *a, int v) #endif } +Uint32 SDL_AddAtomicU32WithOrder(SDL_AtomicU32 *a, int v, SDL_MemoryOrder order) +{ +#ifdef HAVE_ATOMIC_FETCH_ADD + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return __atomic_fetch_add(&a->value, v, __ATOMIC_RELAXED); + case SDL_MEMORY_ORDER_ACQUIRE: return __atomic_fetch_add(&a->value, v, __ATOMIC_ACQUIRE); + case SDL_MEMORY_ORDER_RELEASE: return __atomic_fetch_add(&a->value, v, __ATOMIC_RELEASE); + case SDL_MEMORY_ORDER_ACQ_REL: return __atomic_fetch_add(&a->value, v, __ATOMIC_ACQ_REL); + default: return __atomic_fetch_add(&a->value, v, __ATOMIC_SEQ_CST); + } +#elif defined(HAVE_MSC_ORDERED_ATOMICS) + SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return _InterlockedExchangeAdd_nf((long *)&a->value, v); + case SDL_MEMORY_ORDER_ACQUIRE: return _InterlockedExchangeAdd_acq((long *)&a->value, v); + case SDL_MEMORY_ORDER_RELEASE: return _InterlockedExchangeAdd_rel((long *)&a->value, v); + default: return _InterlockedExchangeAdd((long *)&a->value, v); + } +#else + return SDL_AddAtomicU32(a, v); +#endif +} + int SDL_GetAtomicInt(SDL_AtomicInt *a) { #ifdef HAVE_ATOMIC_LOAD_N @@ -346,6 +630,26 @@ int SDL_GetAtomicInt(SDL_AtomicInt *a) #endif } +int SDL_GetAtomicIntWithOrder(SDL_AtomicInt *a, SDL_MemoryOrder order) +{ +#ifdef HAVE_ATOMIC_LOAD_N + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return __atomic_load_n(&a->value, __ATOMIC_RELAXED); + case SDL_MEMORY_ORDER_ACQUIRE: return __atomic_load_n(&a->value, __ATOMIC_ACQUIRE); + default: return __atomic_load_n(&a->value, __ATOMIC_SEQ_CST); + } +#elif defined(HAVE_MSC_ORDERED_ATOMICS) + SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return _InterlockedOr_nf((long *)&a->value, 0); + case SDL_MEMORY_ORDER_ACQUIRE: return _InterlockedOr_acq((long *)&a->value, 0); + default: return _InterlockedOr((long *)&a->value, 0); + } +#else + return SDL_GetAtomicInt(a); +#endif +} + Uint32 SDL_GetAtomicU32(SDL_AtomicU32 *a) { #ifdef HAVE_ATOMIC_LOAD_N @@ -372,6 +676,26 @@ Uint32 SDL_GetAtomicU32(SDL_AtomicU32 *a) #endif } +Uint32 SDL_GetAtomicU32WithOrder(SDL_AtomicU32 *a, SDL_MemoryOrder order) +{ +#ifdef HAVE_ATOMIC_LOAD_N + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return __atomic_load_n(&a->value, __ATOMIC_RELAXED); + case SDL_MEMORY_ORDER_ACQUIRE: return __atomic_load_n(&a->value, __ATOMIC_ACQUIRE); + default: return __atomic_load_n(&a->value, __ATOMIC_SEQ_CST); + } +#elif defined(HAVE_MSC_ORDERED_ATOMICS) + SDL_COMPILE_TIME_ASSERT(atomic_set, sizeof(long) == sizeof(a->value)); + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return _InterlockedOr_nf((long *)&a->value, 0); + case SDL_MEMORY_ORDER_ACQUIRE: return _InterlockedOr_acq((long *)&a->value, 0); + default: return _InterlockedOr((long *)&a->value, 0); + } +#else + return SDL_GetAtomicU32(a); +#endif +} + void *SDL_GetAtomicPointer(void **a) { #ifdef HAVE_ATOMIC_LOAD_N @@ -391,6 +715,25 @@ void *SDL_GetAtomicPointer(void **a) #endif } +void *SDL_GetAtomicPointerWithOrder(void **a, SDL_MemoryOrder order) +{ +#ifdef HAVE_ATOMIC_LOAD_N + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return __atomic_load_n(a, __ATOMIC_RELAXED); + case SDL_MEMORY_ORDER_ACQUIRE: return __atomic_load_n(a, __ATOMIC_ACQUIRE); + default: return __atomic_load_n(a, __ATOMIC_SEQ_CST); + } +#elif defined(HAVE_MSC_ORDERED_ATOMICS) + switch (order) { + case SDL_MEMORY_ORDER_RELAXED: return _InterlockedCompareExchangePointer_nf(a, NULL, NULL); + case SDL_MEMORY_ORDER_ACQUIRE: return _InterlockedCompareExchangePointer_acq(a, NULL, NULL); + default: return _InterlockedCompareExchangePointer(a, NULL, NULL); + } +#else + return SDL_GetAtomicPointer(a); +#endif +} + #ifdef SDL_MEMORY_BARRIER_USES_FUNCTION #error This file should be built in arm mode so the mcr instruction is available for memory barriers #endif diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 0e4b0aa6d89a3..5ef677ec4e43b 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1257,6 +1257,20 @@ SDL3_0.0.0 { SDL_hid_get_properties; SDL_GetPixelFormatFromGPUTextureFormat; SDL_GetGPUTextureFormatFromPixelFormat; + SDL_CompareAndSwapAtomicIntStrongWithOrder; + SDL_CompareAndSwapAtomicIntWeakWithOrder; + SDL_SetAtomicIntWithOrder; + SDL_GetAtomicIntWithOrder; + SDL_AddAtomicIntWithOrder; + SDL_CompareAndSwapAtomicU32StrongWithOrder; + SDL_CompareAndSwapAtomicU32WeakWithOrder; + SDL_SetAtomicU32WithOrder; + SDL_GetAtomicU32WithOrder; + SDL_AddAtomicU32WithOrder; + SDL_CompareAndSwapAtomicPointerStrongWithOrder; + SDL_CompareAndSwapAtomicPointerWeakWithOrder; + SDL_SetAtomicPointerWithOrder; + SDL_GetAtomicPointerWithOrder; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 686e5472ed930..4b493c87d8c73 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1282,3 +1282,17 @@ #define SDL_hid_get_properties SDL_hid_get_properties_REAL #define SDL_GetPixelFormatFromGPUTextureFormat SDL_GetPixelFormatFromGPUTextureFormat_REAL #define SDL_GetGPUTextureFormatFromPixelFormat SDL_GetGPUTextureFormatFromPixelFormat_REAL +#define SDL_CompareAndSwapAtomicIntStrongWithOrder SDL_CompareAndSwapAtomicIntStrongWithOrder_REAL +#define SDL_CompareAndSwapAtomicIntWeakWithOrder SDL_CompareAndSwapAtomicIntWeakWithOrder_REAL +#define SDL_SetAtomicIntWithOrder SDL_SetAtomicIntWithOrder_REAL +#define SDL_GetAtomicIntWithOrder SDL_GetAtomicIntWithOrder_REAL +#define SDL_AddAtomicIntWithOrder SDL_AddAtomicIntWithOrder_REAL +#define SDL_CompareAndSwapAtomicU32StrongWithOrder SDL_CompareAndSwapAtomicU32StrongWithOrder_REAL +#define SDL_CompareAndSwapAtomicU32WeakWithOrder SDL_CompareAndSwapAtomicU32WeakWithOrder_REAL +#define SDL_SetAtomicU32WithOrder SDL_SetAtomicU32WithOrder_REAL +#define SDL_GetAtomicU32WithOrder SDL_GetAtomicU32WithOrder_REAL +#define SDL_AddAtomicU32WithOrder SDL_AddAtomicU32WithOrder_REAL +#define SDL_CompareAndSwapAtomicPointerStrongWithOrder SDL_CompareAndSwapAtomicPointerStrongWithOrder_REAL +#define SDL_CompareAndSwapAtomicPointerWeakWithOrder SDL_CompareAndSwapAtomicPointerWeakWithOrder_REAL +#define SDL_SetAtomicPointerWithOrder SDL_SetAtomicPointerWithOrder_REAL +#define SDL_GetAtomicPointerWithOrder SDL_GetAtomicPointerWithOrder_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 8516bfe26a0b7..3d158e29b80f5 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1290,3 +1290,17 @@ SDL_DYNAPI_PROC(Uint32,SDL_AddAtomicU32,(SDL_AtomicU32 *a,int b),(a,b),return) SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_hid_get_properties,(SDL_hid_device *a),(a),return) SDL_DYNAPI_PROC(SDL_PixelFormat,SDL_GetPixelFormatFromGPUTextureFormat,(SDL_GPUTextureFormat a),(a),return) SDL_DYNAPI_PROC(SDL_GPUTextureFormat,SDL_GetGPUTextureFormatFromPixelFormat,(SDL_PixelFormat a),(a),return) +SDL_DYNAPI_PROC(bool,SDL_CompareAndSwapAtomicIntStrongWithOrder,(SDL_AtomicInt *a,int b,int c,SDL_MemoryOrder d,SDL_MemoryOrder e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(bool,SDL_CompareAndSwapAtomicIntWeakWithOrder,(SDL_AtomicInt *a,int b,int c,SDL_MemoryOrder d,SDL_MemoryOrder e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(int,SDL_SetAtomicIntWithOrder,(SDL_AtomicInt *a,int b,SDL_MemoryOrder c),(a,b,c),return) +SDL_DYNAPI_PROC(int,SDL_GetAtomicIntWithOrder,(SDL_AtomicInt *a,SDL_MemoryOrder b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_AddAtomicIntWithOrder,(SDL_AtomicInt *a,int b,SDL_MemoryOrder c),(a,b,c),return) +SDL_DYNAPI_PROC(bool,SDL_CompareAndSwapAtomicU32StrongWithOrder,(SDL_AtomicU32 *a,Uint32 b,Uint32 c,SDL_MemoryOrder d,SDL_MemoryOrder e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(bool,SDL_CompareAndSwapAtomicU32WeakWithOrder,(SDL_AtomicU32 *a,Uint32 b,Uint32 c,SDL_MemoryOrder d,SDL_MemoryOrder e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(Uint32,SDL_SetAtomicU32WithOrder,(SDL_AtomicU32 *a,Uint32 b,SDL_MemoryOrder c),(a,b,c),return) +SDL_DYNAPI_PROC(Uint32,SDL_GetAtomicU32WithOrder,(SDL_AtomicU32 *a,SDL_MemoryOrder b),(a,b),return) +SDL_DYNAPI_PROC(Uint32,SDL_AddAtomicU32WithOrder,(SDL_AtomicU32 *a,int b,SDL_MemoryOrder c),(a,b,c),return) +SDL_DYNAPI_PROC(bool,SDL_CompareAndSwapAtomicPointerStrongWithOrder,(void **a,void *b,void *c,SDL_MemoryOrder d,SDL_MemoryOrder e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(bool,SDL_CompareAndSwapAtomicPointerWeakWithOrder,(void **a,void *b,void *c,SDL_MemoryOrder d,SDL_MemoryOrder e),(a,b,c,d,e),return) +SDL_DYNAPI_PROC(void*,SDL_SetAtomicPointerWithOrder,(void **a,void *b,SDL_MemoryOrder c),(a,b,c),return) +SDL_DYNAPI_PROC(void*,SDL_GetAtomicPointerWithOrder,(void **a,SDL_MemoryOrder b),(a,b),return)