Mercurial > sdl-ios-xcode
comparison include/SDL_atomic.h @ 5099:b938ad843e52
More fixes for compilation on Visual Studio
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 25 Jan 2011 18:02:41 -0800 |
parents | e4301cde4de1 |
children | 470ede30189c |
comparison
equal
deleted
inserted
replaced
5098:e4301cde4de1 | 5099:b938ad843e52 |
---|---|
125 */ | 125 */ |
126 #ifdef _MSC_VER | 126 #ifdef _MSC_VER |
127 void _ReadWriteBarrier(void); | 127 void _ReadWriteBarrier(void); |
128 #pragma intrinsic(_ReadWriteBarrier) | 128 #pragma intrinsic(_ReadWriteBarrier) |
129 #define SDL_CompilerBarrier() _ReadWriteBarrier() | 129 #define SDL_CompilerBarrier() _ReadWriteBarrier() |
130 #elif __GNUC__ | 130 #elif defined(__GNUC__) |
131 #define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") | 131 #define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") |
132 #else | 132 #else |
133 #define SDL_CompilerBarrier() \ | 133 #define SDL_CompilerBarrier() \ |
134 ({ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }) | 134 ({ SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }) |
135 #endif | 135 #endif |
137 /* Platform specific optimized versions of the atomic functions, | 137 /* Platform specific optimized versions of the atomic functions, |
138 * you can disable these by defining SDL_DISABLE_ATOMIC_INLINE | 138 * you can disable these by defining SDL_DISABLE_ATOMIC_INLINE |
139 */ | 139 */ |
140 #ifndef SDL_DISABLE_ATOMIC_INLINE | 140 #ifndef SDL_DISABLE_ATOMIC_INLINE |
141 | 141 |
142 #if HAVE_MSC_ATOMICS | 142 #ifdef HAVE_MSC_ATOMICS |
143 | 143 |
144 #define SDL_AtomicSet(a, v) _InterlockedExchange((long*)&(a)->value, (v)) | 144 #define SDL_AtomicSet(a, v) _InterlockedExchange((long*)&(a)->value, (v)) |
145 #define SDL_AtomicAdd(a, v) _InterlockedExchangeAdd((long*)&(a)->value, (v)) | 145 #define SDL_AtomicAdd(a, v) _InterlockedExchangeAdd((long*)&(a)->value, (v)) |
146 #define SDL_AtomicCAS(a, oldval, newval) (_InterlockedCompareExchange((long*)&(a)->value, (newval), (oldval)) == (oldval)) | 146 #define SDL_AtomicCAS(a, oldval, newval) (_InterlockedCompareExchange((long*)&(a)->value, (newval), (oldval)) == (oldval)) |
147 #define SDL_AtomicSetPtr(a, v) _InterlockedExchangePointer((a), (v)) | 147 #define SDL_AtomicSetPtr(a, v) _InterlockedExchangePointer((a), (v)) |
149 #define SDL_AtomicCASPtr(a, oldval, newval) (_InterlockedCompareExchange((long*)(a), (long)(newval), (long)(oldval)) == (long)(oldval)) | 149 #define SDL_AtomicCASPtr(a, oldval, newval) (_InterlockedCompareExchange((long*)(a), (long)(newval), (long)(oldval)) == (long)(oldval)) |
150 #else | 150 #else |
151 #define SDL_AtomicCASPtr(a, oldval, newval) (_InterlockedCompareExchangePointer((a), (newval), (oldval)) == (oldval)) | 151 #define SDL_AtomicCASPtr(a, oldval, newval) (_InterlockedCompareExchangePointer((a), (newval), (oldval)) == (oldval)) |
152 #endif | 152 #endif |
153 | 153 |
154 #elif __MACOSX__ | 154 #elif defined(__MACOSX__) |
155 #include <libkern/OSAtomic.h> | 155 #include <libkern/OSAtomic.h> |
156 | 156 |
157 #define SDL_AtomicCAS(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((oldval), (newval), &(a)->value) | 157 #define SDL_AtomicCAS(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((oldval), (newval), &(a)->value) |
158 #if SIZEOF_VOIDP == 4 | 158 #if SIZEOF_VOIDP == 4 |
159 #define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((int32_t)(oldval), (int32_t)(newval), (int32_t*)(a)) | 159 #define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap32Barrier((int32_t)(oldval), (int32_t)(newval), (int32_t*)(a)) |
160 #elif SIZEOF_VOIDP == 8 | 160 #elif SIZEOF_VOIDP == 8 |
161 #define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap64Barrier((int64_t)(oldval), (int64_t)(newval), (int64_t*)(a)) | 161 #define SDL_AtomicCASPtr(a, oldval, newval) OSAtomicCompareAndSwap64Barrier((int64_t)(oldval), (int64_t)(newval), (int64_t*)(a)) |
162 #endif | 162 #endif |
163 | 163 |
164 #elif HAVE_GCC_ATOMICS | 164 #elif defined(HAVE_GCC_ATOMICS) |
165 | 165 |
166 #define SDL_AtomicSet(a, v) __sync_lock_test_and_set(&(a)->value, v) | 166 #define SDL_AtomicSet(a, v) __sync_lock_test_and_set(&(a)->value, v) |
167 #define SDL_AtomicAdd(a, v) __sync_fetch_and_add(&(a)->value, v) | 167 #define SDL_AtomicAdd(a, v) __sync_fetch_and_add(&(a)->value, v) |
168 #define SDL_AtomicSetPtr(a, v) __sync_lock_test_and_set(a, v) | 168 #define SDL_AtomicSetPtr(a, v) __sync_lock_test_and_set(a, v) |
169 #define SDL_AtomicCAS(a, oldval, newval) __sync_bool_compare_and_swap(&(a)->value, oldval, newval) | 169 #define SDL_AtomicCAS(a, oldval, newval) __sync_bool_compare_and_swap(&(a)->value, oldval, newval) |
181 #ifndef SDL_atomic_t_defined | 181 #ifndef SDL_atomic_t_defined |
182 typedef struct { int value; } SDL_atomic_t; | 182 typedef struct { int value; } SDL_atomic_t; |
183 #endif | 183 #endif |
184 | 184 |
185 /** | 185 /** |
186 * \brief Set an atomic variable to a value. | |
187 * | |
188 * \return The previous value of the atomic variable. | |
189 */ | |
190 #ifndef SDL_AtomicSet | |
191 #define SDL_AtomicSet(a, v) \ | |
192 ({ \ | |
193 int _value; \ | |
194 do { \ | |
195 _value = (a)->value; \ | |
196 } while (!SDL_AtomicCAS(a, _value, (v))); \ | |
197 _value; \ | |
198 }) | |
199 #endif | |
200 | |
201 /** | |
202 * \brief Get the value of an atomic variable | |
203 */ | |
204 #ifndef SDL_AtomicGet | |
205 #define SDL_AtomicGet(a) \ | |
206 ({ \ | |
207 int _value = (a)->value; \ | |
208 SDL_CompilerBarrier(); \ | |
209 _value; \ | |
210 }) | |
211 #endif | |
212 | |
213 /** | |
214 * \brief Add to an atomic variable. | |
215 * | |
216 * \return The previous value of the atomic variable. | |
217 * | |
218 * \note This same style can be used for any number operation | |
219 */ | |
220 #ifndef SDL_AtomicAdd | |
221 #define SDL_AtomicAdd(a, v) \ | |
222 ({ \ | |
223 int _value; \ | |
224 do { \ | |
225 _value = (a)->value; \ | |
226 } while (!SDL_AtomicCAS(a, _value, (_value + (v)))); \ | |
227 _value; \ | |
228 }) | |
229 #endif | |
230 | |
231 /** | |
232 * \brief Increment an atomic variable used as a reference count. | |
233 */ | |
234 #ifndef SDL_AtomicIncRef | |
235 #define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1) | |
236 #endif | |
237 | |
238 /** | |
239 * \brief Decrement an atomic variable used as a reference count. | |
240 * | |
241 * \return SDL_TRUE if the variable reached zero after decrementing, | |
242 * SDL_FALSE otherwise | |
243 */ | |
244 #ifndef SDL_AtomicDecRef | |
245 #define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1) | |
246 #endif | |
247 | |
248 /** | |
249 * \brief Set an atomic variable to a new value if it is currently an old value. | 186 * \brief Set an atomic variable to a new value if it is currently an old value. |
250 * | 187 * |
251 * \return SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. | 188 * \return SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise. |
252 * | 189 * |
253 * \note If you don't know what this function is for, you shouldn't use it! | 190 * \note If you don't know what this function is for, you shouldn't use it! |
256 #define SDL_AtomicCAS SDL_AtomicCAS_ | 193 #define SDL_AtomicCAS SDL_AtomicCAS_ |
257 #endif | 194 #endif |
258 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS_(SDL_atomic_t *a, int oldval, int newval); | 195 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS_(SDL_atomic_t *a, int oldval, int newval); |
259 | 196 |
260 /** | 197 /** |
261 * \brief Set a pointer to a value atomically. | 198 * \brief Set an atomic variable to a value. |
262 * | 199 * |
263 * \return The previous value of the pointer. | 200 * \return The previous value of the atomic variable. |
264 */ | 201 */ |
265 #ifndef SDL_AtomicSetPtr | 202 #ifndef SDL_AtomicSet |
266 #define SDL_AtomicSetPtr(a, v) \ | 203 static __inline__ int SDL_AtomicSet(SDL_atomic_t *a, int v) |
267 ({ \ | 204 { |
268 void* _value; \ | 205 int value; |
269 do { \ | 206 do { |
270 _value = *(a); \ | 207 value = a->value; |
271 } while (!SDL_AtomicCASPtr(a, _value, (v))); \ | 208 } while (!SDL_AtomicCAS(a, value, v)); |
272 _value; \ | 209 return value; |
273 }) | 210 } |
274 #endif | 211 #endif |
275 | 212 |
276 /** | 213 /** |
277 * \brief Get the value of a pointer atomically. | 214 * \brief Get the value of an atomic variable |
278 */ | 215 */ |
279 #ifndef SDL_AtomicGetPtr | 216 #ifndef SDL_AtomicGet |
280 #define SDL_AtomicGetPtr(a) \ | 217 static __inline__ int SDL_AtomicGet(SDL_atomic_t *a) |
281 ({ \ | 218 { |
282 void* _value = *(a); \ | 219 int value = a->value; |
283 SDL_CompilerBarrier(); \ | 220 SDL_CompilerBarrier(); |
284 _value; \ | 221 return value; |
285 }) | 222 } |
223 #endif | |
224 | |
225 /** | |
226 * \brief Add to an atomic variable. | |
227 * | |
228 * \return The previous value of the atomic variable. | |
229 * | |
230 * \note This same style can be used for any number operation | |
231 */ | |
232 #ifndef SDL_AtomicAdd | |
233 static __inline__ int SDL_AtomicAdd(SDL_atomic_t *a, int v) | |
234 { | |
235 int value; | |
236 do { | |
237 value = a->value; | |
238 } while (!SDL_AtomicCAS(a, value, (value + v))); | |
239 return value; | |
240 } | |
241 #endif | |
242 | |
243 /** | |
244 * \brief Increment an atomic variable used as a reference count. | |
245 */ | |
246 #ifndef SDL_AtomicIncRef | |
247 #define SDL_AtomicIncRef(a) SDL_AtomicAdd(a, 1) | |
248 #endif | |
249 | |
250 /** | |
251 * \brief Decrement an atomic variable used as a reference count. | |
252 * | |
253 * \return SDL_TRUE if the variable reached zero after decrementing, | |
254 * SDL_FALSE otherwise | |
255 */ | |
256 #ifndef SDL_AtomicDecRef | |
257 #define SDL_AtomicDecRef(a) (SDL_AtomicAdd(a, -1) == 1) | |
286 #endif | 258 #endif |
287 | 259 |
288 /** | 260 /** |
289 * \brief Set a pointer to a new value if it is currently an old value. | 261 * \brief Set a pointer to a new value if it is currently an old value. |
290 * | 262 * |
295 #ifndef SDL_AtomicCASPtr | 267 #ifndef SDL_AtomicCASPtr |
296 #define SDL_AtomicCASPtr SDL_AtomicCASPtr_ | 268 #define SDL_AtomicCASPtr SDL_AtomicCASPtr_ |
297 #endif | 269 #endif |
298 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr_(void **a, void *oldval, void *newval); | 270 extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr_(void **a, void *oldval, void *newval); |
299 | 271 |
272 /** | |
273 * \brief Set a pointer to a value atomically. | |
274 * | |
275 * \return The previous value of the pointer. | |
276 */ | |
277 #ifndef SDL_AtomicSetPtr | |
278 static __inline__ void* SDL_AtomicSetPtr(void* *a, void* v) | |
279 { | |
280 void* value; | |
281 do { | |
282 value = *a; | |
283 } while (!SDL_AtomicCASPtr(a, value, v)); | |
284 return value; | |
285 } | |
286 #endif | |
287 | |
288 /** | |
289 * \brief Get the value of a pointer atomically. | |
290 */ | |
291 #ifndef SDL_AtomicGetPtr | |
292 static __inline__ void* SDL_AtomicGetPtr(void* *a) | |
293 { | |
294 void* value = *a; | |
295 SDL_CompilerBarrier(); | |
296 return value; | |
297 } | |
298 #endif | |
299 | |
300 | |
300 /* Ends C function definitions when using C++ */ | 301 /* Ends C function definitions when using C++ */ |
301 #ifdef __cplusplus | 302 #ifdef __cplusplus |
302 /* *INDENT-OFF* */ | 303 /* *INDENT-OFF* */ |
303 } | 304 } |
304 /* *INDENT-ON* */ | 305 /* *INDENT-ON* */ |