include/SDL_atomic.h
changeset 5004 0c72ae7b7cb2
parent 5003 3a95a2b93eb3
child 5005 7f0265279b68
equal deleted inserted replaced
5003:3a95a2b93eb3 5004:0c72ae7b7cb2
   106 extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock);
   106 extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock);
   107 
   107 
   108 /*@}*//*SDL AtomicLock*/
   108 /*@}*//*SDL AtomicLock*/
   109 
   109 
   110 /* Platform specific optimized versions of the atomic functions */
   110 /* Platform specific optimized versions of the atomic functions */
   111 /* None yet... */
   111 #if defined(__WIN32__)
       
   112 #define WIN32_LEAN_AND_MEAN
       
   113 #include <windows.h>
       
   114 
       
   115 #define SDL_AtomicSet(a, v)     InterlockedExchange(&(a)->value, v)
       
   116 #define SDL_AtomicGet(a)        ((a)->value)
       
   117 #define SDL_AtomicAdd(a, v)     InterlockedAdd(&(a)->value, v)
       
   118 #define SDL_AtomicCAS(a, oldval, newval) (InterlockedCompareExchange(&(a)->value, newval, oldval) == (oldval))
       
   119 #define SDL_AtomicSetPtr(a, v)  InterlockedExchangePointer(a, v)
       
   120 #define SDL_AtomicGetPtr(a)     (*(a))
       
   121 #define SDL_AtomicCASPtr(a, oldval, newval) (InterlockedCompareExchangePointer(a, newval, oldval) == (oldval))
       
   122 
       
   123 #elif defined(__MACOSX__)
       
   124 #include <libkern/OSAtomic.h>
       
   125 
       
   126 #define SDL_AtomicSet(a, v) \
       
   127 ({                          \
       
   128     int oldvalue;           \
       
   129                             \
       
   130     do {                    \
       
   131         oldvalue = (a)->value; \
       
   132     } while (!OSAtomicCompareAndSwap32Barrier(oldvalue, v, &(a)->value)); \
       
   133                             \
       
   134     oldvalue;               \
       
   135 })
       
   136 #define SDL_AtomicGet(a)        ((a)->value)
       
   137 #define SDL_AtomicAdd(a, v) \
       
   138 ({                          \
       
   139     int oldvalue;           \
       
   140                             \
       
   141     do {                    \
       
   142         oldvalue = (a)->value; \
       
   143     } while (!OSAtomicCompareAndSwap32Barrier(oldvalue, oldvalue+v, &(a)->value)); \
       
   144                             \
       
   145     oldvalue;               \
       
   146 })
       
   147 #define SDL_AtomicCAS(a, oldval, newval) OSAtomicCompareAndSwap32Barrier(oldval, newval, &(a)->value)
       
   148 #define SDL_AtomicSetPtr(a, v)  (*(a) = v, OSMemoryBarrier())
       
   149 #define SDL_AtomicGetPtr(a)     (*(a))
       
   150 #if SIZEOF_VOIDP == 4
       
   151 #define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((int32_t)(oldval), (int32_t)(newval), (int32_t*)(a))
       
   152 #elif SIZEOF_VOIDP == 8
       
   153 #define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap64Barrier((int64_t)(oldval), (int64_t)(newval), (int64_t*)(a))
       
   154 #endif
       
   155 
       
   156 #elif defined(HAVE_GCC_ATOMICS)
       
   157 
       
   158 #define SDL_AtomicSet(a, v)     __sync_lock_test_and_set(&(a)->value, v)
       
   159 #define SDL_AtomicGet(a)        ((a)->value)
       
   160 #define SDL_AtomicAdd(a, v)     __sync_fetch_and_add(&(a)->value, v)
       
   161 #define SDL_AtomicCAS(a, oldval, newval) __sync_bool_compare_and_swap(&(a)->value, oldval, newval)
       
   162 #define SDL_AtomicSetPtr(a, v)  (*(a) = v, __sync_synchronize())
       
   163 #define SDL_AtomicGetPtr(a)     (*(a))
       
   164 #define SDL_AtomicCASPtr(a, oldval, newval) __sync_bool_compare_and_swap(a, oldval, newval)
       
   165 
       
   166 #endif
   112 
   167 
   113 /**
   168 /**
   114  * \brief A type representing an atomic integer value.  It is a struct
   169  * \brief A type representing an atomic integer value.  It is a struct
   115  *        so people don't accidentally use numeric operations on it.
   170  *        so people don't accidentally use numeric operations on it.
   116  */
   171  */
   161 #endif
   216 #endif
   162 
   217 
   163 /**
   218 /**
   164  * \brief Set an atomic variable to a new value if it is currently an old value.
   219  * \brief Set an atomic variable to a new value if it is currently an old value.
   165  *
   220  *
   166  * \return The previous value of the atomic variable
   221  * \return SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise.
   167  *
   222  *
   168  * \note If you don't know what this function is for, you shouldn't use it!
   223  * \note If you don't know what this function is for, you shouldn't use it!
   169 */
   224 */
   170 #ifndef SDL_AtomicCAS
   225 #ifndef SDL_AtomicCAS
   171 extern DECLSPEC int SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval);
   226 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval);
   172 #endif
   227 #endif
   173 
   228 
   174 /**
   229 /**
   175  * \brief Set a pointer to a value atomically.
   230  * \brief Set a pointer to a value atomically.
   176  */
   231  */
   186 #endif
   241 #endif
   187 
   242 
   188 /**
   243 /**
   189  * \brief Set a pointer to a new value if it is currently an old value.
   244  * \brief Set a pointer to a new value if it is currently an old value.
   190  *
   245  *
   191  * \return The previous value of the pointer
   246  * \return SDL_TRUE if the pointer was set, SDL_FALSE otherwise.
   192  *
   247  *
   193  * \note If you don't know what this function is for, you shouldn't use it!
   248  * \note If you don't know what this function is for, you shouldn't use it!
   194 */
   249 */
   195 #ifndef SDL_AtomicCASPtr
   250 #ifndef SDL_AtomicCASPtr
   196 extern DECLSPEC void* SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval);
   251 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *newval);
   197 #endif
   252 #endif
   198 
   253 
   199 /* Ends C function definitions when using C++ */
   254 /* Ends C function definitions when using C++ */
   200 #ifdef __cplusplus
   255 #ifdef __cplusplus
   201 /* *INDENT-OFF* */
   256 /* *INDENT-OFF* */