--- a/include/SDL_atomic.h Wed Jun 17 04:26:19 2009 +0000
+++ b/include/SDL_atomic.h Wed Jun 24 20:04:08 2009 +0000
@@ -23,7 +23,7 @@
/**
* \file SDL_atomic.h
*
- * Atomic int and pointer magic
+ * Atomic operations.
*/
#ifndef _SDL_atomic_h_
@@ -42,628 +42,232 @@
/* *INDENT-ON* */
#endif
-/* indent is really bad at handling assembly */
/* *INDENT-OFF* */
-
-#if defined(__GNUC__) && (defined(i386) || defined(__i386__) || defined(__x86_64__))
-static __inline__ void
-SDL_atomic_int_add(volatile int* atomic, int value)
-{
- __asm__ __volatile__("lock;"
- "addl %1, %0"
- : "=m" (*atomic)
- : "ir" (value),
- "m" (*atomic));
-}
-
-static __inline__ int
-SDL_atomic_int_xchg_add(volatile int* atomic, int value)
-{
- int rv;
- __asm__ __volatile__("lock;"
- "xaddl %0, %1"
- : "=r" (rv),
- "=m" (*atomic)
- : "0" (value),
- "m" (*atomic));
- return rv;
-}
-
-static __inline__ SDL_bool
-SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
-{
- int rv;
- __asm__ __volatile__("lock;"
- "cmpxchgl %2, %1"
- : "=a" (rv),
- "=m" (*atomic)
- : "r" (newvalue),
- "m" (*atomic),
- "0" (oldvalue));
- return (SDL_bool)(rv == oldvalue);
-}
-
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- void* rv;
- __asm__ __volatile__("lock;"
-# if defined(__x86_64__)
- "cmpxchgq %q2, %1"
-# else
- "cmpxchgl %2, %1"
-# endif
- : "=a" (rv),
- "=m" (*atomic)
- : "r" (newvalue),
- "m" (*atomic),
- "0" (oldvalue));
- return (SDL_bool)(rv == oldvalue);
-}
-#elif defined(__GNUC__) && defined(__alpha__)
-# define ATOMIC_MEMORY_BARRIER (__asm__ __volatile__ ("mb" : : : "memory"))
-# define ATOMIC_INT_CMP_XCHG(atomic,value) \
- ({ \
- int rv,prev; \
- __asm__ __volatile__(" mb\n" \
- "1: ldl_l %0,%2\n" \
- " cmpeq %0,%3,%1\n" \
- " beq %1,2f\n" \
- " mov %4,%1\n" \
- " stl_c %1,%2\n" \
- " beq %1,1b\n" \
- " mb\n" \
- "2:" \
- : "=&r" (prev), \
- "=&r" (rv) \
- : "m" (*(atomic)), \
- "Ir" (oldvalue), \
- "Ir" (newvalue) \
- : "memory"); \
- (rv != 0); \
- })
-
-# if (SIZEOF_VOIDP == 4)
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- int rv;
- void* prev;
- __asm__ __volatile__(" mb\n"
- "1: ldl_l %0,%2\n"
- " cmpeq %0,%3,%1\n"
- " beq $1,2f\n"
- " mov %4,%1\n"
- " stl_c %1,%2\n"
- " beq %1,1b\n"
- " mb\n"
- "2:"
- : "=&r" (prev),
- "=&r" (rv)
- : "m" (*atomic),
- "Ir" (oldvalue),
- "Ir" (newvalue)
- : "memory");
- return (SDL_bool)(rv != 0);
-}
-# elif (SIZEOF_VOIDP == 8)
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- int rv;
- void* prev;
- __asm__ __volatile__(" mb\n"
- "1: ldq_l %0,%2\n"
- " cmpeq %0,%3,%1\n"
- " beq %1,2f\n"
- " mov %4,%1\n"
- " stq_c %1,%2\n"
- " beq %1,1b\n"
- " mb\n"
- "2:"
- : "=&r" (prev),
- "=&r" (rv)
- : "m" (*atomic),
- "Ir" (oldvalue),
- "Ir" (newvalue)
- : "memory");
- return (SDL_bool)(rv != 0);
-}
-# else
-# error "Your system has an unsupported pointer size"
-# endif /* SIZEOF_VOIDP */
-#elif defined(__GNUC__) && defined(__sparc__)
-# define ATOMIC_MEMORY_BARRIER \
- (__asm__ __volatile__("membar #LoadLoad | #LoadStore" \
- " | #StoreLoad | #StoreStore" : : : "memory"))
-# define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue) \
- ({ \
- int rv; \
- __asm__ __volatile__("cas [%4], %2, %0" \
- : "=r" (rv), "=m" (*(atomic)) \
- : "r" (oldvalue), "m" (*(atomic)), \
- "r" (atomic), "0" (newvalue)); \
- rv == oldvalue; \
- })
-
-# if (SIZEOF_VOIDP == 4)
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- void* rv;
- __asm__ __volatile__("cas [%4], %2, %0"
- : "=r" (rv),
- "=m" (*atomic)
- : "r" (oldvalue),
- "m" (*atomic),
- "r" (atomic),
- "0" (newvalue));
- return (SDL_bool)(rv == oldvalue);
-}
-# elif (SIZEOF_VOIDP == 8)
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- void* rv;
- void** a = atomic;
- __asm__ __volatile__("casx [%4], %2, %0"
- : "=r" (rv),
- "=m" (*a)
- : "r" (oldvalue),
- "m" (*a),
- "r" (a),
- "0" (newvalue));
- return (SDL_bool)(rv == oldvalue);
-}
-# else
-# error "Your system has an unsupported pointer size"
-# endif /* SIZEOF_VOIDP */
-#elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC))
-# define ATOMIC_MEMORY_BARRIER \
- (__asm__ __volatile__ ("sync" : : : "memory"))
-static __inline__ void
-SDL_atomic_int_add(volatile int* atomic, int value)
-{
- int rv,tmp;
- __asm__ __volatile__("1: lwarx %0, 0, %3\n"
- " add %1, %0, %4\n"
- " stwcx. %1, 0, %3\n"
- " bne- 1b"
- : "=&b" (rv),
- "=&r" (tmp),
- "=m" (*atomic)
- : "b" (atomic),
- "r" (value),
- "m" (*atomic)
- : "cr0",
- "memory");
-}
-
-static __inline__ int
-SDL_atomic_int_xchg_add(volatile int* atomic, int value)
-{
- int rv,tmp;
- __asm__ __volatile__("1: lwarx %0, 0, %3\n"
- " add %1, %0, %4\n"
- " stwcx. %1, 0, %3\n"
- " bne- 1b"
- : "=&b" (rv),
- "=&r" (tmp),
- "=m" (*atomic)
- : "b" (atomic),
- "r" (value),
- "m" (*atomic)
- : "cr0",
- "memory");
- return rv;
-}
-
-# if (SIZEOF_VOIDP == 4)
-static __inline__ SDL_bool
-SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
-{
- int rv;
- __asm__ __volatile__(" sync\n"
- "1: lwarx %0, 0, %1\n"
- " subf. %0, %2, %0\n"
- " bne 2f\n"
- " stwcx. %3, 0, %1\n"
- " bne- 1b\n"
- "2: isync"
- : "=&r" (rv)
- : "b" (atomic),
- "r" (oldvalue),
- "r"
- : "cr0",
- "memory");
- return (SDL_bool)(rv == 0);
-}
-
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- void* rv;
- __asm__ __volatile__("sync\n"
- "1: lwarx %0, 0, %1\n"
- " subf. %0, %2, %0\n"
- " bne 2f\n"
- " stwcx. %3, 0, %1\n"
- " bne- 1b\n"
- "2: isync"
- : "=&r" (rv)
- : "b" (atomic),
- "r" (oldvalue),
- "r" (newvalue)
- : "cr0",
- "memory");
- return (SDL_bool)(rv == 0);
-}
-# elif (SIZEOF_VOIDP == 8)
-static __inline__ SDL_bool
-SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
-{
- int rv;
- __asm__ __volatile__(" sync\n"
- "1: lwarx %0, 0, %1\n"
- " extsw %0, %0\n"
- " subf. %0, %2, %0\n"
- " bne 2f\n"
- " stwcx. %3, 0, %1\n"
- " bne- 1b\n"
- "2: isync"
- : "=&r" (rv)
- : "b" (atomic),
- "r" (oldvalue),
- "r"
- : "cr0",
- "memory");
- return (SDL_bool)(rv == 0);
-}
+/**
+ * \def SDL_AtomicBusyWait32 (ptr)
+ *
+ * \brief Implements a simple busy wait for use with
+ * SDL_AtomicTestThenSet and SDL_AtomicClear.
+ *
+ * Note: This can be an infinite loop.
+ *
+ */
+#define SDL_AtomicBusyWait32(ptr) \
+ { \
+ while (!SDL_AtomicTestThenSet32(ptr) \
+ { \
+ }; \
+ };
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- void* rv;
- __asm__ __volatile__("sync\n"
- "1: ldarx %0, 0, %1\n"
- " subf. %0, %2, %0\n"
- " bne 2f\n"
- " stdcx. %3, 0, %1\n"
- " bne- 1b\n"
- "2: isync"
- : "=&r" (rv)
- : "b" (atomic),
- "r" (oldvalue),
- "r" (newvalue)
- : "cr0",
- "memory");
- return (SDL_bool)(rv == 0);
-}
-# else
-# error "Your system has an unsupported pointer size"
-# endif /* SIZEOF_VOIDP */
-#elif defined(__GNUC__) && (defined(__IA64__) || defined(__ia64__))
-# define ATOMIC_MEMORY_BARRIER (__sync_synchronize())
-# define SDL_atomic_int_xchg_add(atomic, value) \
- (__sync_fetch_and_add((atomic),(value)))
-# define SDL_atomic_int_add(atomic, value) \
- ((void)__sync_fetch_and_add((atomic),(value)))
-# define SDL_atomic_int_cmp_xchg(atomic,oldvalue,newvalue) \
- (__sync_bool_compare_and_swap((atomic),(oldvalue),(newvalue)))
-# define SDL_atomic_ptr_cmp_xchg(atomic,oldvalue,newvalue) \
- (__sync_bool_compare_and_swap((long*)(atomic),(long)(oldvalue),(long)(newvalue)))
-#elif defined(__GNUC__) && defined(__LINUX__) && (defined(__mips__) || defined(__MIPS__))
-static __inline__ int
-SDL_atomic_int_xchg_add(volatile int* atomic, int value)
-{
- int rv,tmp;
- __asm__ __volatile__("1: \n"
- ".set push \n"
- ".set mips2 \n"
- "ll %0,%3 \n"
- "addu %1,%4,%0 \n"
- "sc %1,%2 \n"
- ".set pop \n"
- "beqz %1,1b \n"
- : "=&r" (rv),
- "=&r" (tmp),
- "=m" (*atomic)
- : "m" (*atomic),
- "r" (value)
- : "memory");
- return rv;
-}
-
-static __inline__ void
-SDL_atomic_int_add(volatile int* atomic, int value)
-{
- int rv;
- __asm__ __volatile__("1: \n"
- ".set push \n"
- ".set mips2 \n"
- "ll %0,%2 \n"
- "addu %0,%3,%0 \n"
- "sc %0,%1 \n"
- ".set pop \n"
- "beqz %0,1b \n"
- : "=&r" (rv),
- "=m" (*atomic)
- : "m" (*atomic),
- "r" (value)
- : "memory");
-}
-
-static __inline__ SDL_bool
-SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
-{
- int rv;
- __asm__ __volatile__(" .set push \n"
- " .set noat \n"
- " .set mips3 \n"
- "1: ll %0, %2 \n"
- " bne %0, %z3, 2f \n"
- " .set mips0 \n"
- " move $1, %z4 \n"
- " .set mips3 \n"
- " sc $1, %1 \n"
- " beqz $1, 1b \n"
- " sync \n"
- "2: \n"
- " .set pop \n"
- : "=&r" (rv),
- "=R" (*atomic)
- : "R" (*atomic),
- "Jr" (oldvalue),
- "Jr" (newvalue)
- : "memory");
- return (SDL_bool)rv;
-}
-
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- int rv;
- __asm__ __volatile__(" .set push \n"
- " .set noat \n"
- " .set mips3 \n"
-# if defined(__mips64)
- "1: lld %0, %2 \n"
-# else
- "1: ll %0, %2 \n"
-# endif
- " bne %0, %z3, 2f \n"
- " move $1, %z4 \n"
-# if defined(__mips64)
- " sc $1, %1 \n"
-# else
- " scd $1, %1 \n"
-# endif
- " beqz $1, 1b \n"
- " sync \n"
- "2: \n"
- " .set pop \n"
- : "=&r" (rv),
- "=R" (*atomic)
- : "R" (*atomic),
- "Jr" (oldvalue),
- "Jr" (newvalue)
- : "memory");
- return (SDL_bool)rv;
-}
-#elif defined(__GNUC__) && defined(__m68k__)
-static __inline__ int
-SDL_atomic_int_xchg_add(volatile int* atomic, int value)
-{
- int rv = *atomic;
- int tmp;
- __asm__ __volatile__("1: move%.l %0,%1 \n"
- " add%.l %2,%1 \n"
- " cas%.l %0,%1,%3 \n"
- " jbne 1b \n"
- : "=d" (rv),
- "=&d" (tmp)
- : "d" (value),
- "m" (*atomic),
- "0" (rv)
- : "memory");
- return (SDL_bool)rv;
-}
+/**
+ * \def SDL_AtomicWait32(ptr)
+ *
+ * \brief A safer way to wait for a test-then-set lock to be cleared.
+ *
+ * This assumes that the SDL_Sleep(0) call acts as a thread_yeild
+ * operation.
+ *
+ */
+#define SDL_AtomicWait32(ptr) \
+ { \
+ while (!SDL_AtomicTestThenSet32(ptr) \
+ { \
+ SDL_Sleep(0); \
+ }; \
+ };
-static __inline__ void
-SDL_atomic_int_add(volatile int* atomic, int value)
-{
- __asm__ __volatile__("add%.l %0,%1"
- :
- : "id" (value),
- "m" (*atomic)
- : "memory");
-}
-
-static __inline__ SDL_bool
-SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
-{
- char rv;
- int readvalue;
- __asm__ __volatile__("cas%.l %2,%3,%1\n"
- "seq %0"
- : "=dm" (rv),
- "=m" (*atomic),
- "=d" (readvalue)
- : "d" (newvalue),
- "m" (*atomic),
- "2" (oldvalue));
- return (SDL_bool)rv;
-}
+/**
+ * \def SDL_AtomicBusyWait64(ptr)
+ *
+ * \brief 64 bit version of busy wait
+ *
+ * \sa SDL_AtomicBusyWait32
+ */
+#define SDL_AtomicBusyWait64(ptr) \
+ { \
+ while (!SDL_AtomicTestThenSet64(ptr) \
+ { \
+ }; \
+ };
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- char rv;
- int readvalue;
- __asm__ __volatile__("cas%.l %2,%3,%1\n"
- "seq %0"
- : "=dm" (rv),
- "=m" (*atomic),
- "=d" (readvalue)
- : "d" (newvalue),
- "m" (*atomic),
- "2" (oldvalue));
- return (SDL_bool)rv;
-}
-#elif defined(__GNUC__) && defined(__s390__)
-# define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue) \
- ({ \
- int rv = oldvalue; \
- __asm__ __volatile__("cs %0, %2, %1" \
- : "+d" (rv), \
- "=Q" (*(atomic)) \
- : "d" (newvalue), \
- "m" (*(atomic)) \
- : "cc"); \
- rv == oldvalue; \
- })
-# if (SIZEOF_VOIDP == 4)
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- void* rv = oldvalue;
- __asm__ __volatile__("cs %0, %2, %1"
- : "+d" (rv),
- "=Q" (*atomic)
- : "d" (newvalue),
- "m" (*atomic)
- : "cc");
- return (SDL_bool)(rv == oldvalue);
-}
-# elif (SIZEOF_VOIDP == 8)
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- void* rv = oldvalue;
- void** a = atomic;
- __asm__ __volatile__("csg %0, %2, %1"
- : "+d" (rv),
- "=Q" (*a)
- : "d" ((long)(newvalue)),
- "m" (*a)
- : "cc");
- return (SDL_bool)(rv == oldvalue);
-}
-# else
-# error "Your system has an unsupported pointer size"
-# endif /* SIZEOF_VOIDP */
-#elif defined(__WIN32__)
-# include <windows.h>
-static __inline__ int
-SDL_atomic_int_xchg_add(volatile int* atomic, int value)
-{
- return InterlockedExchangeAdd(atomic, value);
-}
-
-static __inline__ void
-SDL_atomic_int_add(volatile int* atomic, int value)
-{
- InterlockedExchangeAdd(atomic, value);
-}
-
-# if (WINVER > 0X0400)
-static __inline__ SDL_bool
-SDL_atmoic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
-{
- return (SDL_bool)(InterlockedCompareExchangePointer((PVOID*)atomic,
- (PVOID)newvalue,
- (PVOID)oldvalue) == oldvalue);
-}
-
-
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- return (InterlockedCompareExchangePointer(atomic, newvalue, oldvalue) == oldvalue);
-}
-# else /* WINVER <= 0x0400 */
-# if (SIZEOF_VOIDP != 4)
-# error "InterlockedCompareExchangePointer needed"
-# endif
-
-static __inline__ SDL_bool
-SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
-{
- return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == oldvalue);
-}
-
-static __inline__ SDL_bool
-SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
-{
- return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == oldvalue);
-}
-# endif
-#else /* when all else fails */
-# define SDL_ATOMIC_OPS_NOT_SUPPORTED
-# warning "Atomic Ops for this platform not supported!"
-static __inline__ int
-SDL_atomic_int_xchg_add(volatile int* atomic, int value)
-{
- int rv = *atomic;
- *(atomic) += value;
- return rv;
-}
-
-static __inline__ SDL_bool
-SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
-{
- return (*atomic == oldvalue) ?
- ((*atomic = newvalue), SDL_TRUE) : SDL_FALSE;
-}
-
-static __inline__ void
-SDL_atomic_int_add(volatile int* atomic, int value)
-{
- *atomic += value;
-}
-#endif /* arch & platforms */
-
+/**
+ * \def SDL_AtomicWait64(ptr)
+ *
+ * \brief 64 bit version of SDL_AtomicWait32
+ *
+ * \sa SDL_AtomicWait32
+ */
+#define SDL_AtomicWait64(ptr) \
+ { \
+ while (!SDL_AtomicTestThenSet64(ptr) \
+ { \
+ SDL_Sleep(0); \
+ }; \
+ };
/* *INDENT-ON* */
-#ifdef ATOMIC_INT_CMP_XCHG
-static __inline__ SDL_bool
-SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue)
-{
- return (SDL_bool) ATOMIC_INT_CMP_XCHG(atomic, oldvalue, newvalue);
-}
-
-static __inline__ int
-SDL_atomic_int_xchg_add(volatile int *atomic, int value)
-{
- int rv;
- do
- rv = *atomic;
- while (!ATOMIC_INT_CMP_XCHG(atomic, rv, rv + value));
- return rv;
-}
+/* Function prototypes */
-static __inline__ void
-SDL_atomic_int_add(volatile int *atomic, int value)
-{
- int rv;
- do
- rv = *atomic;
- while (!ATOMIC_INT_CMP_XCHG(atomic, rv, rv + value));
-}
-#endif /* ATOMIC_CMP_XCHG */
+/**
+ * \fn int SDL_AtomicExchange32(Uint32 * ptr, Uint32 value)
+ *
+ * \brief Atomically exchange two 32 bit values.
+ *
+ * \return the value point to by ptr.
+ *
+ * \param ptr points to the value to be fetched from *ptr.
+ * \param value is value to be stored at *ptr.
+ *
+ * The current value stored at *ptr is returned and it is replaced
+ * with value. This function can be used to implement SDL_TestThenSet.
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicExchange32(Uint32 * ptr, Uint32 value);
+/**
+ * \fn int SDL_AtomicCompareThenSet32(Uint32 * ptr, Uint32 oldvalue, Uint32 newvalue)
+ *
+ * \brief If *ptr == oldvalue then replace the contents of *ptr by new value.
+ *
+ * \return true if the newvalue was stored.
+ *
+ * \param *ptr is the value to be compared and replaced.
+ * \param oldvalue is value to be compared to *ptr.
+ * \param newvalue is value to be stored at *ptr.
+ *
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCompareThenSet32(Uint32 * ptr,
+ Uint32 oldvalue, Uint32 newvalue);
+/**
+ * \fn SDL_bool SDL_AtomicTestThenSet32(Uint32 * ptr);
+ *
+ * \brief Check to see if *ptr == 0 and set it to non-zero.
+ *
+ * \return SDL_True if the value pointed to by ptr was zero and
+ * SDL_False if it was not zero
+ *
+ * \param ptr points to the value to be tested and set.
+ *
+ */
+extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTestThenSet32(Uint32 * ptr);
+/**
+ * \fn void SDL_AtomicClear32(Uint32 * ptr);
+ *
+ * \brief set the value pointed to by ptr to be zero.
+ *
+ * \param ptr address of the value to be set to zero
+ *
+ */
+extern DECLSPEC void SDLCALL SDL_AtomicClear32(Uint32 * ptr);
+/**
+ * \fn Uint32 SDL_AtomicFetchThenIncrement32(Uint32 * ptr);
+ *
+ * \brief fetch the current value of *ptr and then increment that
+ * value in place.
+ *
+ * \return the value before it was incremented.
+ *
+ * \param ptr address of the value to fetch and increment
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicFetchThenIncrement32(Uint32 * ptr);
+/**
+ * \fn Uint32 SDL_AtomicFetchThenDecrement32(Uint32 * ptr);
+ *
+ * \brief fetch *ptr and then decrement the value in place.
+ *
+ * \return the value before it was decremented.
+ *
+ * \param ptr address of the value to fetch and drement
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicFetchThenDecrement32(Uint32 * ptr);
+/**
+ * \fn Uint32 SDL_AtomicFetchThenAdd32(Uint32 * ptr, Uint32 value);
+ *
+ * \brief fetch the current value at ptr and then add value to *ptr.
+ *
+ * \return *ptr before the addition took place.
+ *
+ * \param ptr the address of data we are changing.
+ * \param value the value to add to *ptr.
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicFetchThenAdd32(Uint32 * ptr, Uint32 value);
+/**
+ * \fn Uint32 SDL_AtomicFetchThenSubtract32(Uint32 * ptr, Uint32 value);
+ *
+ * \brief Fetch *ptr and then subtract value from it.
+ *
+ * \return *ptr before the subtraction took place.
+ *
+ * \param ptr the address of the data being changed.
+ * \param value the value to subtract from *ptr.
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicFetchThenSubtract32(Uint32 * ptr, Uint32 value);
+/**
+ * \fn Uint32 SDL_AtomicIncrementThenFetch32(Uint32 * ptr);
+ *
+ * \brief Add one to the data pointed to by ptr and return that value.
+ *
+ * \return the incremented value.
+ *
+ * \param ptr address of the data to increment.
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicIncrementThenFetch32(Uint32 * ptr);
+/**
+ * \fn Uint32 SDL_AtomicDecrementThenFetch32(Uint32 * ptr);
+ *
+ * \brief Subtract one from data pointed to by ptr and return the new value.
+ *
+ * \return The decremented value.
+ *
+ * \param ptr The address of the data to decrement.
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicDecrementThenFetch32(Uint32 * ptr);
+/**
+ * \fn Uint32 SDL_AtomicAddThenFetch32(Uint32 * ptr, Uint32 value);
+ *
+ * \brief Add value to the data pointed to by ptr and return result.
+ *
+ * \return The sum of *ptr and value.
+ *
+ * \param ptr The address of the data to be modified.
+ * \param value The value to be added.
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicAddThenFetch32(Uint32 * ptr, Uint32 value);
+/**
+ * \fn Uint32 SDL_AtomicSubtractThenFetch32(Uint32 * ptr, Uint32 value);
+ *
+ * \brief Subtract value from the data pointed to by ptr and return the result.
+ *
+ * \return the difference between *ptr and value.
+ *
+ * \param ptr The address of the data to be modified.
+ * \param value The value to be subtracted.
+ *
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_AtomicSubtractThenFetch32(Uint32 * ptr, Uint32 value);
-#ifdef ATOMIC_MEMORY_BARRIER
-# define SDL_atomic_int_get(atomic) \
- (ATOMIC_MEMORY_BARRIER,*(atomic))
-# define SDL_atomic_int_set(atomic,value) \
- (*(atomic)=value,ATOMIC_MEMORY_BARRIER)
-#else
-# define SDL_atomic_int_get(atomic) (*(atomic))
-# define SDL_atomic_int_set(atomic, newvalue) ((void)(*(atomic) = (newvalue)))
-#endif /* MEMORY_BARRIER_NEEDED */
+#ifdef SDL_HAS_64BIT_TYPE
-#define SDL_atomic_int_inc(atomic) (SDL_atomic_int_add((atomic),1))
-#define SDL_atomic_int_dec_test(atomic) (SDL_atomic_int_xchg_add((atomic),-1) == 1)
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicExchange64(Uint64 * ptr, Uint64 value);
+extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCompareThenSet64(Uint64 * ptr,
+ Uint64 oldvalue, Uint64 newvalue);
+extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTestThenSet64(Uint64 * ptr);
+extern DECLSPEC void SDLCALL SDL_AtomicClear64(Uint64 * ptr);
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenIncrement64(Uint64 * ptr);
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenDecrement64(Uint64 * ptr);
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenAdd64(Uint64 * ptr, Uint64 value);
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicFetchThenSubtract64(Uint64 * ptr, Uint64 value);
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicIncrementThenFetch64(Uint64 * ptr);
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicDecrementThenFetch64(Uint64 * ptr);
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicAddThenFetch64(Uint64 * ptr, Uint64 value);
+extern DECLSPEC Uint64 SDLCALL SDL_AtomicSubtractThenFetch64(Uint64 * ptr, Uint64 value);
+#endif
/* Ends C function definitions when using C++ */
#ifdef __cplusplus