11/*
22 Simple DirectMedia Layer
3- Copyright (C) 1997-2022 Sam Lantinga <[email protected] > 3+ Copyright (C) 1997-2025 Sam Lantinga <[email protected] > 44
55 This software is provided 'as-is', without any express or implied
66 warranty. In no event will the authors be held liable for any damages
2020*/
2121
2222/**
23- * \file SDL_atomic.h
23+ * # CategoryAtomic
2424 *
2525 * Atomic operations.
2626 *
27- * IMPORTANT:
28- * If you are not an expert in concurrent lockless programming, you should
29- * only be using the atomic lock and reference counting functions in this
30- * file. In all other cases you should be protecting your data structures
31- * with full mutexes.
27+ * IMPORTANT: If you are not an expert in concurrent lockless programming, you
28+ * should not be using any functions in this file. You should be protecting
29+ * your data structures with full mutexes instead.
3230 *
33- * The list of "safe" functions to use are:
34- * SDL_AtomicLock()
35- * SDL_AtomicUnlock()
36- * SDL_AtomicIncRef()
37- * SDL_AtomicDecRef()
31+ * ***Seriously, here be dragons!***
3832 *
39- * Seriously, here be dragons!
40- * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
41- *
42- * You can find out a little more about lockless programming and the
43- * subtle issues that can arise here:
44- * http://msdn.microsoft.com/en-us/library/ee418650%28v=vs.85%29.aspx
33+ * You can find out a little more about lockless programming and the subtle
34+ * issues that can arise here:
35+ * https://learn.microsoft.com/en-us/windows/win32/dxtecharts/lockless-programming
4536 *
4637 * There's also lots of good information here:
47- * http://www.1024cores.net/home/lock-free-algorithms
48- * http://preshing.com/
4938 *
50- * These operations may or may not actually be implemented using
51- * processor specific atomic operations. When possible they are
52- * implemented as true processor specific atomic operations. When that
53- * is not possible the are implemented using locks that *do* use the
54- * available atomic operations.
39+ * - https://www.1024cores.net/home/lock-free-algorithms
40+ * - https://preshing.com/
41+ *
42+ * These operations may or may not actually be implemented using processor
43+ * specific atomic operations. When possible they are implemented as true
44+ * processor specific atomic operations. When that is not possible the are
45+ * implemented using locks that *do* use the available atomic operations.
5546 *
5647 * All of the atomic operations that modify memory are full memory barriers.
5748 */
@@ -94,7 +85,7 @@ typedef int SDL_SpinLock;
9485 * ***Please note that spinlocks are dangerous if you don't know what you're
9586 * doing. Please be careful using any sort of spinlock!***
9687 *
97- * \param lock a pointer to a lock variable
88+ * \param lock a pointer to a lock variable.
9889 * \returns SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already
9990 * held.
10091 *
@@ -111,7 +102,7 @@ extern DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock(SDL_SpinLock *lock);
111102 * ***Please note that spinlocks are dangerous if you don't know what you're
112103 * doing. Please be careful using any sort of spinlock!***
113104 *
114- * \param lock a pointer to a lock variable
105+ * \param lock a pointer to a lock variable.
115106 *
116107 * \since This function is available since SDL 2.0.0.
117108 *
@@ -128,7 +119,7 @@ extern DECLSPEC void SDLCALL SDL_AtomicLock(SDL_SpinLock *lock);
128119 * ***Please note that spinlocks are dangerous if you don't know what you're
129120 * doing. Please be careful using any sort of spinlock!***
130121 *
131- * \param lock a pointer to a lock variable
122+ * \param lock a pointer to a lock variable.
132123 *
133124 * \since This function is available since SDL 2.0.0.
134125 *
@@ -209,7 +200,7 @@ typedef void (*SDL_KernelMemoryBarrierFunc)();
209200#if defined(__ARM_ARCH_7__ ) || defined(__ARM_ARCH_7A__ ) || defined(__ARM_ARCH_7EM__ ) || defined(__ARM_ARCH_7R__ ) || defined(__ARM_ARCH_7M__ ) || defined(__ARM_ARCH_7S__ ) || defined(__ARM_ARCH_8A__ )
210201#define SDL_MemoryBarrierRelease () __asm__ __volatile__ ("dmb ish" : : : "memory")
211202#define SDL_MemoryBarrierAcquire () __asm__ __volatile__ ("dmb ish" : : : "memory")
212- #elif defined(__ARM_ARCH_6__ ) || defined(__ARM_ARCH_6J__ ) || defined(__ARM_ARCH_6K__ ) || defined(__ARM_ARCH_6T2__ ) || defined(__ARM_ARCH_6Z__ ) || defined(__ARM_ARCH_6ZK__ ) || defined( __ARM_ARCH_5TE__ )
203+ #elif defined(__ARM_ARCH_6__ ) || defined(__ARM_ARCH_6J__ ) || defined(__ARM_ARCH_6K__ ) || defined(__ARM_ARCH_6T2__ ) || defined(__ARM_ARCH_6Z__ ) || defined(__ARM_ARCH_6ZK__ )
213204#ifdef __thumb__
214205/* The mcr instruction isn't available in thumb mode, use real functions */
215206#define SDL_MEMORY_BARRIER_USES_FUNCTION
@@ -240,7 +231,7 @@ typedef void (*SDL_KernelMemoryBarrierFunc)();
240231/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */
241232#if (defined(__GNUC__ ) || defined(__clang__ )) && (defined(__i386__ ) || defined(__x86_64__ ))
242233 #define SDL_CPUPauseInstruction () __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
243- #elif (defined(__arm__ ) && __ARM_ARCH >= 7 ) || defined(__aarch64__ )
234+ #elif (defined(__arm__ ) && defined( __ARM_ARCH ) && __ARM_ARCH >= 7 ) || defined(__aarch64__ )
244235 #define SDL_CPUPauseInstruction () __asm__ __volatile__("yield" ::: "memory")
245236#elif (defined(__powerpc__ ) || defined(__powerpc64__ ))
246237 #define SDL_CPUPauseInstruction () __asm__ __volatile__("or 27,27,27");
@@ -249,29 +240,31 @@ typedef void (*SDL_KernelMemoryBarrierFunc)();
249240#elif defined(_MSC_VER ) && (defined(_M_ARM ) || defined(_M_ARM64 ))
250241 #define SDL_CPUPauseInstruction () __yield()
251242#elif defined(__WATCOMC__ ) && defined(__386__ )
252- /* watcom assembler rejects PAUSE if CPU < i686, and it refuses REP NOP as an invalid combination. Hardcode the bytes. */
253243 extern __inline void SDL_CPUPauseInstruction (void );
254- #pragma aux SDL_CPUPauseInstruction = "db 0f3h,90h "
244+ #pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause "
255245#else
256246 #define SDL_CPUPauseInstruction ()
257247#endif
258248
259249
260250/**
261- * \brief A type representing an atomic integer value. It is a struct
262- * so people don't accidentally use numeric operations on it.
251+ * A type representing an atomic integer value.
252+ *
253+ * It is a struct so people don't accidentally use numeric operations on it.
263254 */
264- typedef struct { int value ; } SDL_atomic_t ;
255+ typedef struct SDL_atomic_t {
256+ int value ;
257+ } SDL_atomic_t ;
265258
266259/**
267260 * Set an atomic variable to a new value if it is currently an old value.
268261 *
269262 * ***Note: If you don't know what this function is for, you shouldn't use
270263 * it!***
271264 *
272- * \param a a pointer to an SDL_atomic_t variable to be modified
273- * \param oldval the old value
274- * \param newval the new value
265+ * \param a a pointer to an SDL_atomic_t variable to be modified.
266+ * \param oldval the old value.
267+ * \param newval the new value.
275268 * \returns SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise.
276269 *
277270 * \since This function is available since SDL 2.0.0.
@@ -290,8 +283,8 @@ extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int
290283 * ***Note: If you don't know what this function is for, you shouldn't use
291284 * it!***
292285 *
293- * \param a a pointer to an SDL_atomic_t variable to be modified
294- * \param v the desired value
286+ * \param a a pointer to an SDL_atomic_t variable to be modified.
287+ * \param v the desired value.
295288 * \returns the previous value of the atomic variable.
296289 *
297290 * \since This function is available since SDL 2.0.2.
@@ -306,7 +299,7 @@ extern DECLSPEC int SDLCALL SDL_AtomicSet(SDL_atomic_t *a, int v);
306299 * ***Note: If you don't know what this function is for, you shouldn't use
307300 * it!***
308301 *
309- * \param a a pointer to an SDL_atomic_t variable
302+ * \param a a pointer to an SDL_atomic_t variable.
310303 * \returns the current value of an atomic variable.
311304 *
312305 * \since This function is available since SDL 2.0.2.
@@ -323,8 +316,8 @@ extern DECLSPEC int SDLCALL SDL_AtomicGet(SDL_atomic_t *a);
323316 * ***Note: If you don't know what this function is for, you shouldn't use
324317 * it!***
325318 *
326- * \param a a pointer to an SDL_atomic_t variable to be modified
327- * \param v the desired value to add
319+ * \param a a pointer to an SDL_atomic_t variable to be modified.
320+ * \param v the desired value to add.
328321 * \returns the previous value of the atomic variable.
329322 *
330323 * \since This function is available since SDL 2.0.2.
@@ -357,9 +350,9 @@ extern DECLSPEC int SDLCALL SDL_AtomicAdd(SDL_atomic_t *a, int v);
357350 * ***Note: If you don't know what this function is for, you shouldn't use
358351 * it!***
359352 *
360- * \param a a pointer to a pointer
361- * \param oldval the old pointer value
362- * \param newval the new pointer value
353+ * \param a a pointer to a pointer.
354+ * \param oldval the old pointer value.
355+ * \param newval the new pointer value.
363356 * \returns SDL_TRUE if the pointer was set, SDL_FALSE otherwise.
364357 *
365358 * \since This function is available since SDL 2.0.0.
@@ -376,8 +369,8 @@ extern DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr(void **a, void *oldval, void *
376369 * ***Note: If you don't know what this function is for, you shouldn't use
377370 * it!***
378371 *
379- * \param a a pointer to a pointer
380- * \param v the desired pointer value
372+ * \param a a pointer to a pointer.
373+ * \param v the desired pointer value.
381374 * \returns the previous value of the pointer.
382375 *
383376 * \since This function is available since SDL 2.0.2.
@@ -393,7 +386,7 @@ extern DECLSPEC void* SDLCALL SDL_AtomicSetPtr(void **a, void* v);
393386 * ***Note: If you don't know what this function is for, you shouldn't use
394387 * it!***
395388 *
396- * \param a a pointer to a pointer
389+ * \param a a pointer to a pointer.
397390 * \returns the current value of a pointer.
398391 *
399392 * \since This function is available since SDL 2.0.2.
0 commit comments