21#include "../SDL_internal.h"
25#if defined(_MSC_VER) && (_MSC_VER >= 1500)
27#define HAVE_MSC_ATOMICS 1
30#if defined(__MACOSX__)
31#include <libkern/OSAtomic.h>
34#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__)
39#if defined(HAVE_GCC_ATOMICS)
40# if defined(__clang__)
41# if __has_builtin(__atomic_load_n)
44# if !defined(__ANDROID__)
45# define HAVE_ATOMIC_LOAD_N 1
48# elif defined(__GNUC__)
50# define HAVE_ATOMIC_LOAD_N 1
55#if defined(__WATCOMC__) && defined(__386__)
57#define HAVE_WATCOM_ATOMICS
58extern _inline
int _SDL_xchg_watcom(
volatile int *
a,
int v);
59#pragma aux _SDL_xchg_watcom = \
60 "lock xchg [ecx], eax" \
65extern _inline
unsigned char _SDL_cmpxchg_watcom(
volatile int *
a,
int newval,
int oldval);
66#pragma aux _SDL_cmpxchg_watcom = \
67 "lock cmpxchg [edx], ecx" \
69 parm [edx] [ecx] [eax] \
73extern _inline
int _SDL_xadd_watcom(
volatile int *
a,
int v);
74#pragma aux _SDL_xadd_watcom = \
75 "lock xadd [ecx], eax" \
104#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__) && !defined(HAVE_WATCOM_ATOMICS)
132#ifdef HAVE_MSC_ATOMICS
133 return (_InterlockedCompareExchange((
long*)&
a->value, (
long)newval, (
long)oldval) == (
long)oldval);
134#elif defined(HAVE_WATCOM_ATOMICS)
135 return (
SDL_bool) _SDL_cmpxchg_watcom(&
a->value, newval, oldval);
136#elif defined(HAVE_GCC_ATOMICS)
137 return (
SDL_bool) __sync_bool_compare_and_swap(&
a->value, oldval, newval);
138#elif defined(__MACOSX__)
139 return (
SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &
a->value);
140#elif defined(__SOLARIS__) && defined(_LP64)
142#elif defined(__SOLARIS__) && !defined(_LP64)
148 if (
a->value == oldval) {
156 #error Please define your platform.
163#if defined(HAVE_MSC_ATOMICS) && (_M_IX86)
164 return (_InterlockedCompareExchange((
long*)
a, (
long)newval, (
long)oldval) == (
long)oldval);
165#elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86)
166 return (_InterlockedCompareExchangePointer(
a, newval, oldval) == oldval);
167#elif defined(HAVE_WATCOM_ATOMICS)
168 return (
SDL_bool) _SDL_cmpxchg_watcom((
int *)
a, (
long)newval, (
long)oldval);
169#elif defined(HAVE_GCC_ATOMICS)
170 return __sync_bool_compare_and_swap(
a, oldval, newval);
171#elif defined(__MACOSX__) && defined(__LP64__)
173#elif defined(__MACOSX__) && !defined(__LP64__)
175#elif defined(__SOLARIS__)
176 return (
SDL_bool) (atomic_cas_ptr(
a, oldval, newval) == oldval);
189 #error Please define your platform.
196#ifdef HAVE_MSC_ATOMICS
197 return _InterlockedExchange((
long*)&
a->value,
v);
198#elif defined(HAVE_WATCOM_ATOMICS)
199 return _SDL_xchg_watcom(&
a->value,
v);
200#elif defined(HAVE_GCC_ATOMICS)
201 return __sync_lock_test_and_set(&
a->value,
v);
202#elif defined(__SOLARIS__) && defined(_LP64)
204#elif defined(__SOLARIS__) && !defined(_LP64)
218#if defined(HAVE_MSC_ATOMICS) && (_M_IX86)
219 return (
void *) _InterlockedExchange((
long *)
a, (
long)
v);
220#elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86)
221 return _InterlockedExchangePointer(
a,
v);
222#elif defined(HAVE_WATCOM_ATOMICS)
223 return (
void *) _SDL_xchg_watcom((
int *)
a, (
long)
v);
224#elif defined(HAVE_GCC_ATOMICS)
225 return __sync_lock_test_and_set(
a,
v);
226#elif defined(__SOLARIS__)
227 return atomic_swap_ptr(
a,
v);
240#ifdef HAVE_MSC_ATOMICS
241 return _InterlockedExchangeAdd((
long*)&
a->value,
v);
242#elif defined(HAVE_WATCOM_ATOMICS)
243 return _SDL_xadd_watcom(&
a->value,
v);
244#elif defined(HAVE_GCC_ATOMICS)
245 return __sync_fetch_and_add(&
a->value,
v);
246#elif defined(__SOLARIS__)
250 atomic_add_64((
volatile uint64_t*)&
a->value,
v);
252 atomic_add_32((
volatile uint32_t*)&
a->value,
v);
267#ifdef HAVE_ATOMIC_LOAD_N
268 return __atomic_load_n(&
a->value, __ATOMIC_SEQ_CST);
281#ifdef HAVE_ATOMIC_LOAD_N
282 return __atomic_load_n(
a, __ATOMIC_SEQ_CST);
292#ifdef SDL_MEMORY_BARRIER_USES_FUNCTION
293#error This file should be built in arm mode so the mcr instruction is available for memory barriers
SDL_bool SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval)
Set an atomic variable to a new value if it is currently an old value.
void SDL_MemoryBarrierAcquireFunction(void)
SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
Set a pointer to a new value if it is currently an old value.
void * SDL_AtomicGetPtr(void **a)
Get the value of a pointer atomically.
static SDL_INLINE void leaveLock(void *a)
void SDL_MemoryBarrierReleaseFunction(void)
int SDL_AtomicGet(SDL_atomic_t *a)
Get the value of an atomic variable.
int SDL_AtomicAdd(SDL_atomic_t *a, int v)
Add to an atomic variable.
void * SDL_AtomicSetPtr(void **a, void *v)
Set a pointer to a value atomically.
static SDL_INLINE void enterLock(void *a)
int SDL_AtomicSet(SDL_atomic_t *a, int v)
Set an atomic variable to a value.
static SDL_SpinLock locks[32]
#define SDL_MemoryBarrierRelease()
#define SDL_MemoryBarrierAcquire()
unsigned long long uint64_t
GLboolean GLboolean GLboolean GLboolean a
GLsizei const GLfloat * value
#define SDL_COMPILE_TIME_ASSERT(name, x)
A type representing an atomic integer value. It is a struct so people don't accidentally use numeric ...