annotate SDL3/SDL_atomic.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 /*
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 Simple DirectMedia Layer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 This software is provided 'as-is', without any express or implied
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 warranty. In no event will the authors be held liable for any damages
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 arising from the use of this software.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 Permission is granted to anyone to use this software for any purpose,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 including commercial applications, and to alter it and redistribute it
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 freely, subject to the following restrictions:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 1. The origin of this software must not be misrepresented; you must not
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 claim that you wrote the original software. If you use this software
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 in a product, an acknowledgment in the product documentation would be
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 appreciated but is not required.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 2. Altered source versions must be plainly marked as such, and must not be
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 misrepresented as being the original software.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 3. This notice may not be removed or altered from any source distribution.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 * # CategoryAtomic
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 * Atomic operations.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 * IMPORTANT: If you are not an expert in concurrent lockless programming, you
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 * should not be using any functions in this file. You should be protecting
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 * your data structures with full mutexes instead.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 * ***Seriously, here be dragons!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 * You can find out a little more about lockless programming and the subtle
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 * issues that can arise here:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 * https://learn.microsoft.com/en-us/windows/win32/dxtecharts/lockless-programming
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 * There's also lots of good information here:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 * - https://www.1024cores.net/home/lock-free-algorithms
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 * - https://preshing.com/
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 * These operations may or may not actually be implemented using processor
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 * specific atomic operations. When possible they are implemented as true
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 * processor specific atomic operations. When that is not possible the are
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 * implemented using locks that *do* use the available atomic operations.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 * All of the atomic operations that modify memory are full memory barriers.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 #ifndef SDL_atomic_h_
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 #define SDL_atomic_h_
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 #include <SDL3/SDL_stdinc.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 #include <SDL3/SDL_platform_defines.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 #include <SDL3/SDL_begin_code.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 /* Set up for C function definitions, even when using C++ */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 #ifdef __cplusplus
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 extern "C" {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 * An atomic spinlock.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 * The atomic locks are efficient spinlocks using CPU instructions, but are
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 * vulnerable to starvation and can spin forever if a thread holding a lock
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 * has been terminated. For this reason you should minimize the code executed
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 * inside an atomic lock and never do expensive things like API or system
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 * calls while holding them.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 * They are also vulnerable to starvation if the thread holding the lock is
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 * lower priority than other threads and doesn't get scheduled. In general you
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 * should use mutexes instead, since they have better performance and
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 * contention behavior.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 * The atomic locks are not safe to lock recursively.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 * Porting Note: The spin lock functions and type are required and can not be
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 * emulated because they are used in the atomic emulation code.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 typedef int SDL_SpinLock;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 * Try to lock a spin lock by setting it to a non-zero value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 * ***Please note that spinlocks are dangerous if you don't know what you're
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 * doing. Please be careful using any sort of spinlock!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 * \param lock a pointer to a lock variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 * \returns true if the lock succeeded, false if the lock is already held.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 * \sa SDL_LockSpinlock
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 * \sa SDL_UnlockSpinlock
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 extern SDL_DECLSPEC bool SDLCALL SDL_TryLockSpinlock(SDL_SpinLock *lock);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 * Lock a spin lock by setting it to a non-zero value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 * ***Please note that spinlocks are dangerous if you don't know what you're
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 * doing. Please be careful using any sort of spinlock!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 * \param lock a pointer to a lock variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 * \sa SDL_TryLockSpinlock
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 * \sa SDL_UnlockSpinlock
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 extern SDL_DECLSPEC void SDLCALL SDL_LockSpinlock(SDL_SpinLock *lock);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 * Unlock a spin lock by setting it to 0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 * Always returns immediately.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 * ***Please note that spinlocks are dangerous if you don't know what you're
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 * doing. Please be careful using any sort of spinlock!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 * \param lock a pointer to a lock variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 * \sa SDL_LockSpinlock
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 * \sa SDL_TryLockSpinlock
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 extern SDL_DECLSPEC void SDLCALL SDL_UnlockSpinlock(SDL_SpinLock *lock);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 #ifdef SDL_WIKI_DOCUMENTATION_SECTION
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 * Mark a compiler barrier.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 * A compiler barrier prevents the compiler from reordering reads and writes
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 * to globally visible variables across the call.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 * This macro only prevents the compiler from reordering reads and writes, it
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 * does not prevent the CPU from reordering reads and writes. However, all of
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 * the atomic operations that modify memory are full memory barriers.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 * \threadsafety Obviously this macro is safe to use from any thread at any
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 * time, but if you find yourself needing this, you are probably
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 * dealing with some very sensitive code; be careful!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 * \since This macro is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 #define SDL_CompilerBarrier() DoCompilerSpecificReadWriteBarrier()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 #elif defined(_MSC_VER) && (_MSC_VER > 1200) && !defined(__clang__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 void _ReadWriteBarrier(void);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 #pragma intrinsic(_ReadWriteBarrier)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 #define SDL_CompilerBarrier() _ReadWriteBarrier()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 #elif (defined(__GNUC__) && !defined(SDL_PLATFORM_EMSCRIPTEN)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 /* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 #define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 #elif defined(__WATCOMC__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 extern __inline void SDL_CompilerBarrier(void);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 #pragma aux SDL_CompilerBarrier = "" parm [] modify exact [];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 #define SDL_CompilerBarrier() \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 { SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 * Insert a memory release barrier (function version).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 * Please refer to SDL_MemoryBarrierRelease for details. This is a function
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 * version, which might be useful if you need to use this functionality from a
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 * scripting language, etc. Also, some of the macro versions call this
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 * function behind the scenes, where more heavy lifting can happen inside of
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 * SDL. Generally, though, an app written in C/C++/etc should use the macro
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 * version, as it will be more efficient.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 * \threadsafety Obviously this function is safe to use from any thread at any
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 * time, but if you find yourself needing this, you are probably
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 * dealing with some very sensitive code; be careful!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 * \sa SDL_MemoryBarrierRelease
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierReleaseFunction(void);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 * Insert a memory acquire barrier (function version).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 * Please refer to SDL_MemoryBarrierRelease for details. This is a function
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 * version, which might be useful if you need to use this functionality from a
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 * scripting language, etc. Also, some of the macro versions call this
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 * function behind the scenes, where more heavy lifting can happen inside of
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 * SDL. Generally, though, an app written in C/C++/etc should use the macro
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 * version, as it will be more efficient.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 * \threadsafety Obviously this function is safe to use from any thread at any
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 * time, but if you find yourself needing this, you are probably
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 * dealing with some very sensitive code; be careful!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 * \sa SDL_MemoryBarrierAcquire
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 extern SDL_DECLSPEC void SDLCALL SDL_MemoryBarrierAcquireFunction(void);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 #ifdef SDL_WIKI_DOCUMENTATION_SECTION
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 * Insert a memory release barrier (macro version).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 * Memory barriers are designed to prevent reads and writes from being
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 * reordered by the compiler and being seen out of order on multi-core CPUs.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 * A typical pattern would be for thread A to write some data and a flag, and
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 * for thread B to read the flag and get the data. In this case you would
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 * insert a release barrier between writing the data and the flag,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 * guaranteeing that the data write completes no later than the flag is
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 * written, and you would insert an acquire barrier between reading the flag
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 * and reading the data, to ensure that all the reads associated with the flag
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 * have completed.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 * In this pattern you should always see a release barrier paired with an
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 * acquire barrier and you should gate the data reads/writes with a single
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 * flag variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 * For more information on these semantics, take a look at the blog post:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 * http://preshing.com/20120913/acquire-and-release-semantics
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 * This is the macro version of this functionality; if possible, SDL will use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 * compiler intrinsics or inline assembly, but some platforms might need to
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 * call the function version of this, SDL_MemoryBarrierReleaseFunction to do
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 * the heavy lifting. Apps that can use the macro should favor it over the
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 * function.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 * \threadsafety Obviously this macro is safe to use from any thread at any
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 * time, but if you find yourself needing this, you are probably
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 * dealing with some very sensitive code; be careful!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 * \since This macro is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 * \sa SDL_MemoryBarrierAcquire
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 * \sa SDL_MemoryBarrierReleaseFunction
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 #define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 * Insert a memory acquire barrier (macro version).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 * Please see SDL_MemoryBarrierRelease for the details on what memory barriers
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 * are and when to use them.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 * This is the macro version of this functionality; if possible, SDL will use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 * compiler intrinsics or inline assembly, but some platforms might need to
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 * call the function version of this, SDL_MemoryBarrierAcquireFunction, to do
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 * the heavy lifting. Apps that can use the macro should favor it over the
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 * function.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 * \threadsafety Obviously this macro is safe to use from any thread at any
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 * time, but if you find yourself needing this, you are probably
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 * dealing with some very sensitive code; be careful!
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 * \since This macro is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 * \sa SDL_MemoryBarrierRelease
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 * \sa SDL_MemoryBarrierAcquireFunction
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 #define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("lwsync" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("lwsync" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 #elif defined(__GNUC__) && defined(__aarch64__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 #elif defined(__GNUC__) && defined(__arm__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 #if 0 /* defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID) */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 /* Information from:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 https://chromium.googlesource.com/chromium/chromium/+/trunk/base/atomicops_internals_arm_gcc.h#19
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 The Linux kernel provides a helper function which provides the right code for a memory barrier,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 hard-coded at address 0xffff0fa0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 typedef void (*SDL_KernelMemoryBarrierFunc)();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 #define SDL_MemoryBarrierRelease() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 #define SDL_MemoryBarrierAcquire() ((SDL_KernelMemoryBarrierFunc)0xffff0fa0)()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 #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__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("dmb ish" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("dmb ish" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 #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__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 #ifdef __thumb__
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 /* The mcr instruction isn't available in thumb mode, use real functions */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 #define SDL_MEMORY_BARRIER_USES_FUNCTION
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 #define SDL_MemoryBarrierRelease() SDL_MemoryBarrierReleaseFunction()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 #define SDL_MemoryBarrierAcquire() SDL_MemoryBarrierAcquireFunction()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r"(0) : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 #endif /* __thumb__ */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 #define SDL_MemoryBarrierRelease() __asm__ __volatile__ ("" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 #define SDL_MemoryBarrierAcquire() __asm__ __volatile__ ("" : : : "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 #endif /* SDL_PLATFORM_LINUX || SDL_PLATFORM_ANDROID */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 #endif /* __GNUC__ && __arm__ */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 #if (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 /* This is correct for all CPUs on Solaris when using Solaris Studio 12.1+. */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 #include <mbarrier.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 #define SDL_MemoryBarrierRelease() __machine_rel_barrier()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 #define SDL_MemoryBarrierAcquire() __machine_acq_barrier()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 /* This is correct for the x86 and x64 CPUs, and we'll expand this over time. */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 #define SDL_MemoryBarrierRelease() SDL_CompilerBarrier()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 #define SDL_MemoryBarrierAcquire() SDL_CompilerBarrier()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 /* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 #ifdef SDL_WIKI_DOCUMENTATION_SECTION
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 * A macro to insert a CPU-specific "pause" instruction into the program.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 * This can be useful in busy-wait loops, as it serves as a hint to the CPU as
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 * to the program's intent; some CPUs can use this to do more efficient
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 * processing. On some platforms, this doesn't do anything, so using this
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 * macro might just be a harmless no-op.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 * Note that if you are busy-waiting, there are often more-efficient
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 * approaches with other synchronization primitives: mutexes, semaphores,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 * condition variables, etc.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 * \threadsafety This macro is safe to use from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 * \since This macro is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 #define SDL_CPUPauseInstruction() DoACPUPauseInACompilerAndArchitectureSpecificWay
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 #elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 #define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 #elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__aarch64__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 #define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory")
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 #elif (defined(__powerpc__) || defined(__powerpc64__))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 #define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 #elif (defined(__riscv) && __riscv_xlen == 64)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 #define SDL_CPUPauseInstruction() __asm__ __volatile__(".insn i 0x0F, 0, x0, x0, 0x010");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 #define SDL_CPUPauseInstruction() _mm_pause() /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 #elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 #define SDL_CPUPauseInstruction() __yield()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 #elif defined(__WATCOMC__) && defined(__386__)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 extern __inline void SDL_CPUPauseInstruction(void);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 #pragma aux SDL_CPUPauseInstruction = ".686p" ".xmm2" "pause"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 #define SDL_CPUPauseInstruction()
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 * A type representing an atomic integer value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 * This can be used to manage a value that is synchronized across multiple
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 * CPUs without a race condition; when an app sets a value with
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 * SDL_SetAtomicInt all other threads, regardless of the CPU it is running on,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 * will see that value when retrieved with SDL_GetAtomicInt, regardless of CPU
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 * caches, etc.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 * This is also useful for atomic compare-and-swap operations: a thread can
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 * change the value as long as its current value matches expectations. When
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 * done in a loop, one can guarantee data consistency across threads without a
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 * lock (but the usual warnings apply: if you don't know what you're doing, or
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 * you don't do it carefully, you can confidently cause any number of
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 * disasters with this, so in most cases, you _should_ use a mutex instead of
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 * this!).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 * This is a struct so people don't accidentally use numeric operations on it
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 * directly. You have to use SDL atomic functions.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 * \since This struct is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 * \sa SDL_CompareAndSwapAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 * \sa SDL_GetAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 * \sa SDL_SetAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 * \sa SDL_AddAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 typedef struct SDL_AtomicInt { int value; } SDL_AtomicInt;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 * Set an atomic variable to a new value if it is currently an old value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 * \param a a pointer to an SDL_AtomicInt variable to be modified.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 * \param oldval the old value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 * \param newval the new value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 * \returns true if the atomic variable was set, false otherwise.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 * \sa SDL_GetAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 * \sa SDL_SetAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicInt(SDL_AtomicInt *a, int oldval, int newval);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418 * Set an atomic variable to a value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 * This function also acts as a full memory barrier.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 * \param a a pointer to an SDL_AtomicInt variable to be modified.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426 * \param v the desired value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 * \returns the previous value of the atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 * \sa SDL_GetAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 extern SDL_DECLSPEC int SDLCALL SDL_SetAtomicInt(SDL_AtomicInt *a, int v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 * Get the value of an atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443 * \param a a pointer to an SDL_AtomicInt variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 * \returns the current value of an atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450 * \sa SDL_SetAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 extern SDL_DECLSPEC int SDLCALL SDL_GetAtomicInt(SDL_AtomicInt *a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 * Add to an atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 * This function also acts as a full memory barrier.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462 * \param a a pointer to an SDL_AtomicInt variable to be modified.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463 * \param v the desired value to add.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464 * \returns the previous value of the atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 * \sa SDL_AtomicDecRef
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471 * \sa SDL_AtomicIncRef
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 extern SDL_DECLSPEC int SDLCALL SDL_AddAtomicInt(SDL_AtomicInt *a, int v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 #ifndef SDL_AtomicIncRef
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 * Increment an atomic variable used as a reference count.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 * ***Note: If you don't know what this macro is for, you shouldn't use it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 * \param a a pointer to an SDL_AtomicInt to increment.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 * \returns the previous value of the atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 * \threadsafety It is safe to call this macro from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 * \since This macro is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489 * \sa SDL_AtomicDecRef
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 #define SDL_AtomicIncRef(a) SDL_AddAtomicInt(a, 1)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 #ifndef SDL_AtomicDecRef
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497 * Decrement an atomic variable used as a reference count.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
498 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
499 * ***Note: If you don't know what this macro is for, you shouldn't use it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501 * \param a a pointer to an SDL_AtomicInt to decrement.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502 * \returns true if the variable reached zero after decrementing, false
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 * otherwise.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505 * \threadsafety It is safe to call this macro from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507 * \since This macro is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
508 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
509 * \sa SDL_AtomicIncRef
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511 #define SDL_AtomicDecRef(a) (SDL_AddAtomicInt(a, -1) == 1)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
515 * A type representing an atomic unsigned 32-bit value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
516 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
517 * This can be used to manage a value that is synchronized across multiple
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
518 * CPUs without a race condition; when an app sets a value with
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
519 * SDL_SetAtomicU32 all other threads, regardless of the CPU it is running on,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
520 * will see that value when retrieved with SDL_GetAtomicU32, regardless of CPU
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
521 * caches, etc.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
522 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
523 * This is also useful for atomic compare-and-swap operations: a thread can
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
524 * change the value as long as its current value matches expectations. When
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
525 * done in a loop, one can guarantee data consistency across threads without a
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
526 * lock (but the usual warnings apply: if you don't know what you're doing, or
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
527 * you don't do it carefully, you can confidently cause any number of
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
528 * disasters with this, so in most cases, you _should_ use a mutex instead of
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
529 * this!).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
530 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
531 * This is a struct so people don't accidentally use numeric operations on it
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
532 * directly. You have to use SDL atomic functions.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
533 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
534 * \since This struct is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
535 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
536 * \sa SDL_CompareAndSwapAtomicU32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
537 * \sa SDL_GetAtomicU32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
538 * \sa SDL_SetAtomicU32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
539 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
540 typedef struct SDL_AtomicU32 { Uint32 value; } SDL_AtomicU32;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
541
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
542 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
543 * Set an atomic variable to a new value if it is currently an old value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
544 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
545 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
546 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
547 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
548 * \param a a pointer to an SDL_AtomicU32 variable to be modified.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
549 * \param oldval the old value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
550 * \param newval the new value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
551 * \returns true if the atomic variable was set, false otherwise.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
552 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
553 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
554 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
555 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
556 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
557 * \sa SDL_GetAtomicU32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
558 * \sa SDL_SetAtomicU32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
559 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
560 extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicU32(SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
561
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
562 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
563 * Set an atomic variable to a value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
564 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
565 * This function also acts as a full memory barrier.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
566 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
567 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
568 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
569 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
570 * \param a a pointer to an SDL_AtomicU32 variable to be modified.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
571 * \param v the desired value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
572 * \returns the previous value of the atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
573 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
574 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
575 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
576 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
577 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
578 * \sa SDL_GetAtomicU32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
579 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
580 extern SDL_DECLSPEC Uint32 SDLCALL SDL_SetAtomicU32(SDL_AtomicU32 *a, Uint32 v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
581
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
582 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
583 * Get the value of an atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
584 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
585 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
586 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
587 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
588 * \param a a pointer to an SDL_AtomicU32 variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
589 * \returns the current value of an atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
590 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
591 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
592 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
593 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
594 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
595 * \sa SDL_SetAtomicU32
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
596 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
597 extern SDL_DECLSPEC Uint32 SDLCALL SDL_GetAtomicU32(SDL_AtomicU32 *a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
598
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
599 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
600 * Add to an atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
601 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
602 * This function also acts as a full memory barrier.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
603 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
604 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
605 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
606 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
607 * \param a a pointer to an SDL_AtomicU32 variable to be modified.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
608 * \param v the desired value to add or subtract.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
609 * \returns the previous value of the atomic variable.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
610 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
611 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
612 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
613 * \since This function is available since SDL 3.4.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
614 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
615 extern SDL_DECLSPEC Uint32 SDLCALL SDL_AddAtomicU32(SDL_AtomicU32 *a, int v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
616
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
617 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
618 * Set a pointer to a new value if it is currently an old value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
619 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
620 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
621 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
622 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
623 * \param a a pointer to a pointer.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
624 * \param oldval the old pointer value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
625 * \param newval the new pointer value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
626 * \returns true if the pointer was set, false otherwise.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
627 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
628 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
629 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
630 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
631 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
632 * \sa SDL_CompareAndSwapAtomicInt
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
633 * \sa SDL_GetAtomicPointer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
634 * \sa SDL_SetAtomicPointer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
635 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
636 extern SDL_DECLSPEC bool SDLCALL SDL_CompareAndSwapAtomicPointer(void **a, void *oldval, void *newval);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
637
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
638 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
639 * Set a pointer to a value atomically.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
640 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
641 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
642 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
643 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
644 * \param a a pointer to a pointer.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
645 * \param v the desired pointer value.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
646 * \returns the previous value of the pointer.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
647 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
648 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
649 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
650 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
651 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
652 * \sa SDL_CompareAndSwapAtomicPointer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
653 * \sa SDL_GetAtomicPointer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
654 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
655 extern SDL_DECLSPEC void * SDLCALL SDL_SetAtomicPointer(void **a, void *v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
656
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
657 /**
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
658 * Get the value of a pointer atomically.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
659 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
660 * ***Note: If you don't know what this function is for, you shouldn't use
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
661 * it!***
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
662 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
663 * \param a a pointer to a pointer.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
664 * \returns the current value of a pointer.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
665 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
666 * \threadsafety It is safe to call this function from any thread.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
667 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
668 * \since This function is available since SDL 3.2.0.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
669 *
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
670 * \sa SDL_CompareAndSwapAtomicPointer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
671 * \sa SDL_SetAtomicPointer
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
672 */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
673 extern SDL_DECLSPEC void * SDLCALL SDL_GetAtomicPointer(void **a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
674
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
675 /* Ends C function definitions when using C++ */
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
676 #ifdef __cplusplus
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
677 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
678 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
679
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
680 #include <SDL3/SDL_close_code.h>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
681
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
682 #endif /* SDL_atomic_h_ */