SDL 3.0
|
#include <SDL3/SDL_stdinc.h>
#include <SDL3/SDL_platform_defines.h>
#include <SDL3/SDL_begin_code.h>
#include <SDL3/SDL_close_code.h>
Go to the source code of this file.
Data Structures | |
struct | SDL_AtomicInt |
struct | SDL_AtomicU32 |
Macros | |
#define | SDL_CompilerBarrier() { SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); } |
#define | SDL_MemoryBarrierRelease() SDL_CompilerBarrier() |
#define | SDL_MemoryBarrierAcquire() SDL_CompilerBarrier() |
#define | SDL_CPUPauseInstruction() |
#define | SDL_AtomicIncRef(a) SDL_AddAtomicInt(a, 1) |
#define | SDL_AtomicDecRef(a) (SDL_AddAtomicInt(a, -1) == 1) |
Typedefs | |
typedef int | SDL_SpinLock |
Functions | |
bool | SDL_TryLockSpinlock (SDL_SpinLock *lock) |
void | SDL_LockSpinlock (SDL_SpinLock *lock) |
void | SDL_UnlockSpinlock (SDL_SpinLock *lock) |
void | SDL_MemoryBarrierReleaseFunction (void) |
void | SDL_MemoryBarrierAcquireFunction (void) |
bool | SDL_CompareAndSwapAtomicInt (SDL_AtomicInt *a, int oldval, int newval) |
int | SDL_SetAtomicInt (SDL_AtomicInt *a, int v) |
int | SDL_GetAtomicInt (SDL_AtomicInt *a) |
int | SDL_AddAtomicInt (SDL_AtomicInt *a, int v) |
bool | SDL_CompareAndSwapAtomicU32 (SDL_AtomicU32 *a, Uint32 oldval, Uint32 newval) |
Uint32 | SDL_SetAtomicU32 (SDL_AtomicU32 *a, Uint32 v) |
Uint32 | SDL_GetAtomicU32 (SDL_AtomicU32 *a) |
bool | SDL_CompareAndSwapAtomicPointer (void **a, void *oldval, void *newval) |
void * | SDL_SetAtomicPointer (void **a, void *v) |
void * | SDL_GetAtomicPointer (void **a) |
#define SDL_AtomicDecRef | ( | a | ) | (SDL_AddAtomicInt(a, -1) == 1) |
Decrement an atomic variable used as a reference count.
Note: If you don't know what this macro is for, you shouldn't use it!
a | a pointer to an SDL_AtomicInt to increment. |
\threadsafety It is safe to call this macro from any thread.
Definition at line 511 of file SDL_atomic.h.
#define SDL_AtomicIncRef | ( | a | ) | SDL_AddAtomicInt(a, 1) |
Increment an atomic variable used as a reference count.
Note: If you don't know what this macro is for, you shouldn't use it!
a | a pointer to an SDL_AtomicInt to increment. |
\threadsafety It is safe to call this macro from any thread.
Definition at line 491 of file SDL_atomic.h.
#define SDL_CompilerBarrier | ( | ) | { SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); } |
Definition at line 170 of file SDL_atomic.h.
#define SDL_CPUPauseInstruction | ( | ) |
Definition at line 364 of file SDL_atomic.h.
#define SDL_MemoryBarrierAcquire | ( | ) | SDL_CompilerBarrier() |
Definition at line 323 of file SDL_atomic.h.
#define SDL_MemoryBarrierRelease | ( | ) | SDL_CompilerBarrier() |
Definition at line 322 of file SDL_atomic.h.
typedef int SDL_SpinLock |
Atomic operations.
IMPORTANT: If you are not an expert in concurrent lockless programming, you should not be using any functions in this file. You should be protecting your data structures with full mutexes instead.
Seriously, here be dragons!
You can find out a little more about lockless programming and the subtle issues that can arise here: https://learn.microsoft.com/en-us/windows/win32/dxtecharts/lockless-programming
There's also lots of good information here:
These operations may or may not actually be implemented using processor specific atomic operations. When possible they are implemented as true processor specific atomic operations. When that is not possible the are implemented using locks that do use the available atomic operations.
All of the atomic operations that modify memory are full memory barriers. An atomic spinlock.
The atomic locks are efficient spinlocks using CPU instructions, but are vulnerable to starvation and can spin forever if a thread holding a lock has been terminated. For this reason you should minimize the code executed inside an atomic lock and never do expensive things like API or system calls while holding them.
They are also vulnerable to starvation if the thread holding the lock is lower priority than other threads and doesn't get scheduled. In general you should use mutexes instead, since they have better performance and contention behavior.
The atomic locks are not safe to lock recursively.
Porting Note: The spin lock functions and type are required and can not be emulated because they are used in the atomic emulation code.
Definition at line 82 of file SDL_atomic.h.
|
extern |
Add to an atomic variable.
This function also acts as a full memory barrier.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to an SDL_AtomicInt variable to be modified. |
v | the desired value to add. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Set an atomic variable to a new value if it is currently an old value.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to an SDL_AtomicInt variable to be modified. |
oldval | the old value. |
newval | the new value. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Set a pointer to a new value if it is currently an old value.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to a pointer. |
oldval | the old pointer value. |
newval | the new pointer value. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Set an atomic variable to a new value if it is currently an old value.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to an SDL_AtomicU32 variable to be modified. |
oldval | the old value. |
newval | the new value. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Get the value of an atomic variable.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to an SDL_AtomicInt variable. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Get the value of a pointer atomically.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to a pointer. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Get the value of an atomic variable.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to an SDL_AtomicU32 variable. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Lock a spin lock by setting it to a non-zero value.
Please note that spinlocks are dangerous if you don't know what you're doing. Please be careful using any sort of spinlock!
lock | a pointer to a lock variable. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Insert a memory acquire barrier (function version).
Please refer to SDL_MemoryBarrierRelease for details. This is a function version, which might be useful if you need to use this functionality from a scripting language, etc. Also, some of the macro versions call this function behind the scenes, where more heavy lifting can happen inside of SDL. Generally, though, an app written in C/C++/etc should use the macro version, as it will be more efficient.
\threadsafety Obviously this function is safe to use from any thread at any time, but if you find yourself needing this, you are probably dealing with some very sensitive code; be careful!
|
extern |
Insert a memory release barrier (function version).
Please refer to SDL_MemoryBarrierRelease for details. This is a function version, which might be useful if you need to use this functionality from a scripting language, etc. Also, some of the macro versions call this function behind the scenes, where more heavy lifting can happen inside of SDL. Generally, though, an app written in C/C++/etc should use the macro version, as it will be more efficient.
\threadsafety Obviously this function is safe to use from any thread at any time, but if you find yourself needing this, you are probably dealing with some very sensitive code; be careful!
|
extern |
Set an atomic variable to a value.
This function also acts as a full memory barrier.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to an SDL_AtomicInt variable to be modified. |
v | the desired value. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Set a pointer to a value atomically.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to a pointer. |
v | the desired pointer value. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Set an atomic variable to a value.
This function also acts as a full memory barrier.
Note: If you don't know what this function is for, you shouldn't use it!
a | a pointer to an SDL_AtomicU32 variable to be modified. |
v | the desired value. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Try to lock a spin lock by setting it to a non-zero value.
Please note that spinlocks are dangerous if you don't know what you're doing. Please be careful using any sort of spinlock!
lock | a pointer to a lock variable. |
\threadsafety It is safe to call this function from any thread.
|
extern |
Unlock a spin lock by setting it to 0.
Always returns immediately.
Please note that spinlocks are dangerous if you don't know what you're doing. Please be careful using any sort of spinlock!
lock | a pointer to a lock variable. |
\threadsafety It is safe to call this function from any thread.