Atomic operations.
More...
|
|
using | SDL::AtomicIntRaw = SDL_AtomicInt |
| | Alias to raw representation for AtomicInt.
|
| |
|
using | SDL::AtomicU32Raw = SDL_AtomicU32 |
| | Alias to raw representation for AtomicU32.
|
| |
|
| void | SDL::MemoryBarrierRelease () |
| | Insert a memory release barrier (function version). More...
|
| |
| void | SDL::MemoryBarrierAcquire () |
| | Insert a memory acquire barrier (function version). More...
|
| |
| bool | SDL::CompareAndSwapAtomicInt (AtomicIntRaw *a, int oldval, int newval) |
| | Set an atomic variable to a new value if it is currently an old value. More...
|
| |
| int | SDL::SetAtomicInt (AtomicIntRaw *a, int v) |
| | Set an atomic variable to a value. More...
|
| |
| int | SDL::GetAtomicInt (AtomicIntRaw *a) |
| | Get the value of an atomic variable. More...
|
| |
| int | SDL::AddAtomicInt (AtomicIntRaw *a, int v) |
| | Add to an atomic variable. More...
|
| |
| bool | SDL::AtomicIncRef (AtomicIntRaw *a) |
| | Increment an atomic variable used as a reference count. More...
|
| |
| bool | SDL::AtomicDecRef (AtomicIntRaw *a) |
| | Decrement an atomic variable used as a reference count. More...
|
| |
| bool | SDL::CompareAndSwapAtomicU32 (AtomicU32Raw *a, Uint32 oldval, Uint32 newval) |
| | Set an atomic variable to a new value if it is currently an old value. More...
|
| |
| Uint32 | SDL::SetAtomicU32 (AtomicU32Raw *a, Uint32 v) |
| | Set an atomic variable to a value. More...
|
| |
| Uint32 | SDL::GetAtomicU32 (AtomicU32Raw *a) |
| | Get the value of an atomic variable. More...
|
| |
| bool | SDL::AtomicInt::CompareAndSwap (int oldval, int newval) |
| | Set an atomic variable to a new value if it is currently an old value. More...
|
| |
| int | SDL::AtomicInt::Set (int v) |
| | Set an atomic variable to a value. More...
|
| |
| int | SDL::AtomicInt::Get () |
| | Get the value of an atomic variable. More...
|
| |
| int | SDL::AtomicInt::Add (int v) |
| | Add to an atomic variable. More...
|
| |
| bool | SDL::AtomicInt::AtomicIncRef () |
| | Increment an atomic variable used as a reference count. More...
|
| |
| bool | SDL::AtomicInt::AtomicDecRef () |
| | Decrement an atomic variable used as a reference count. More...
|
| |
| bool | SDL::AtomicU32::CompareAndSwap (Uint32 oldval, Uint32 newval) |
| | Set an atomic variable to a new value if it is currently an old value. More...
|
| |
| Uint32 | SDL::AtomicU32::Set (Uint32 v) |
| | Set an atomic variable to a value. More...
|
| |
| Uint32 | SDL::AtomicU32::Get () |
| | Get the value of an atomic variable. More...
|
| |
| bool | SDL::AtomicPointer< T >::CompareAndSwap (T *oldval, T *newval) |
| | Set a pointer to a new value if it is currently an old value. More...
|
| |
| T * | SDL::AtomicPointer< T >::Set (T *v) |
| | Set a pointer to a value atomically. More...
|
| |
| T * | SDL::AtomicPointer< T >::Get () |
| | Get the value of a pointer atomically. More...
|
| |
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.
◆ SDL_CompilerBarrier
| #define SDL_CompilerBarrier |
( |
| ) |
DoCompilerSpecificReadWriteBarrier() |
A compiler barrier prevents the compiler from reordering reads and writes to globally visible variables across the call.
This macro only prevents the compiler from reordering reads and writes, it does not prevent the CPU from reordering reads and writes. However, all of the atomic operations that modify memory are full memory barriers.
- Thread safety:
- Obviously this macro 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!
- Since
- This macro is available since SDL 3.2.0.
◆ SDL_CPUPauseInstruction
| #define SDL_CPUPauseInstruction |
( |
| ) |
DoACPUPauseInACompilerAndArchitectureSpecificWay |
This can be useful in busy-wait loops, as it serves as a hint to the CPU as to the program's intent; some CPUs can use this to do more efficient processing. On some platforms, this doesn't do anything, so using this macro might just be a harmless no-op.
Note that if you are busy-waiting, there are often more-efficient approaches with other synchronization primitives: mutexes, semaphores, condition variables, etc.
- Thread safety:
- This macro is safe to use from any thread.
- Since
- This macro is available since SDL 3.2.0.
◆ SDL_MemoryBarrierAcquire
| #define SDL_MemoryBarrierAcquire |
( |
| ) |
SDL_MemoryBarrierAcquireFunction() |
Please see SDL_MemoryBarrierRelease for the details on what memory barriers are and when to use them.
This is the macro version of this functionality; if possible, SDL will use compiler intrinsics or inline assembly, but some platforms might need to call the function version of this, MemoryBarrierAcquire, to do the heavy lifting. Apps that can use the macro should favor it over the function.
- Thread safety:
- Obviously this macro 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!
- Since
- This macro is available since SDL 3.2.0.
- See also
- SDL_MemoryBarrierRelease
-
MemoryBarrierAcquire
◆ SDL_MemoryBarrierRelease
| #define SDL_MemoryBarrierRelease |
( |
| ) |
SDL_MemoryBarrierReleaseFunction() |
Memory barriers are designed to prevent reads and writes from being reordered by the compiler and being seen out of order on multi-core CPUs.
A typical pattern would be for thread A to write some data and a flag, and for thread B to read the flag and get the data. In this case you would insert a release barrier between writing the data and the flag, guaranteeing that the data write completes no later than the flag is written, and you would insert an acquire barrier between reading the flag and reading the data, to ensure that all the reads associated with the flag have completed.
In this pattern you should always see a release barrier paired with an acquire barrier and you should gate the data reads/writes with a single flag variable.
For more information on these semantics, take a look at the blog post: http://preshing.com/20120913/acquire-and-release-semantics
This is the macro version of this functionality; if possible, SDL will use compiler intrinsics or inline assembly, but some platforms might need to call the function version of this, MemoryBarrierRelease to do the heavy lifting. Apps that can use the macro should favor it over the function.
- Thread safety:
- Obviously this macro 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!
- Since
- This macro is available since SDL 3.2.0.
- See also
- SDL_MemoryBarrierAcquire
-
MemoryBarrierRelease
◆ Add()
| int SDL::AtomicInt::Add |
( |
int |
v | ) |
|
|
inline |
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!
- Parameters
-
| v | the desired value to add. |
- Returns
- the previous value of the atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.AtomicDecRef
-
AtomicInt.AtomicIncRef
◆ AddAtomicInt()
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!
- Parameters
-
| a | a pointer to an AtomicInt variable to be modified. |
| v | the desired value to add. |
- Returns
- the previous value of the atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.AtomicDecRef
-
AtomicInt.AtomicIncRef
◆ AtomicDecRef() [1/2]
| bool SDL::AtomicInt::AtomicDecRef |
( |
| ) |
|
|
inline |
Note: If you don't know what this macro is for, you shouldn't use it!
- Returns
- true if the variable reached zero after decrementing, false otherwise.
- Thread safety:
- It is safe to call this macro from any thread.
- Since
- This macro is available since SDL 3.2.0.
- See also
- AtomicInt.AtomicIncRef
◆ AtomicDecRef() [2/2]
Note: If you don't know what this macro is for, you shouldn't use it!
- Parameters
-
- Returns
- true if the variable reached zero after decrementing, false otherwise.
- Thread safety:
- It is safe to call this macro from any thread.
- Since
- This macro is available since SDL 3.2.0.
- See also
- AtomicInt.AtomicIncRef
◆ AtomicIncRef() [1/2]
| bool SDL::AtomicInt::AtomicIncRef |
( |
| ) |
|
|
inline |
Note: If you don't know what this macro is for, you shouldn't use it!
- Returns
- the previous value of the atomic variable.
- Thread safety:
- It is safe to call this macro from any thread.
- Since
- This macro is available since SDL 3.2.0.
- See also
- AtomicInt.AtomicDecRef
◆ AtomicIncRef() [2/2]
Note: If you don't know what this macro is for, you shouldn't use it!
- Parameters
-
- Returns
- the previous value of the atomic variable.
- Thread safety:
- It is safe to call this macro from any thread.
- Since
- This macro is available since SDL 3.2.0.
- See also
- AtomicInt.AtomicDecRef
◆ CompareAndSwap() [1/3]
| bool SDL::AtomicInt::CompareAndSwap |
( |
int |
oldval, |
|
|
int |
newval |
|
) |
| |
|
inline |
Note: If you don't know what this function is for, you shouldn't use it!
- Parameters
-
| oldval | the old value. |
| newval | the new value. |
- Returns
- true if the atomic variable was set, false otherwise.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.Get
-
AtomicInt.Set
◆ CompareAndSwap() [2/3]
Note: If you don't know what this function is for, you shouldn't use it!
- Parameters
-
| oldval | the old pointer value. |
| newval | the new pointer value. |
- Returns
- true if the pointer was set, false otherwise.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.CompareAndSwap
-
AtomicPointer.Get
-
AtomicPointer.Set
◆ CompareAndSwap() [3/3]
| bool SDL::AtomicU32::CompareAndSwap |
( |
Uint32 |
oldval, |
|
|
Uint32 |
newval |
|
) |
| |
|
inline |
Note: If you don't know what this function is for, you shouldn't use it!
- Parameters
-
| oldval | the old value. |
| newval | the new value. |
- Returns
- true if the atomic variable was set, false otherwise.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicU32.Get
-
AtomicU32.Set
◆ CompareAndSwapAtomicInt()
| bool SDL::CompareAndSwapAtomicInt |
( |
AtomicIntRaw * |
a, |
|
|
int |
oldval, |
|
|
int |
newval |
|
) |
| |
|
inline |
Note: If you don't know what this function is for, you shouldn't use it!
- Parameters
-
| a | a pointer to an AtomicInt variable to be modified. |
| oldval | the old value. |
| newval | the new value. |
- Returns
- true if the atomic variable was set, false otherwise.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.Get
-
AtomicInt.Set
◆ CompareAndSwapAtomicU32()
Note: If you don't know what this function is for, you shouldn't use it!
- Parameters
-
| a | a pointer to an AtomicU32 variable to be modified. |
| oldval | the old value. |
| newval | the new value. |
- Returns
- true if the atomic variable was set, false otherwise.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicU32.Get
-
AtomicU32.Set
◆ Get() [1/3]
| int SDL::AtomicInt::Get |
( |
| ) |
|
|
inline |
Note: If you don't know what this function is for, you shouldn't use it!
- Returns
- the current value of an atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.Set
◆ Get() [2/3]
| Uint32 SDL::AtomicU32::Get |
( |
| ) |
|
|
inline |
Note: If you don't know what this function is for, you shouldn't use it!
- Returns
- the current value of an atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicU32.Set
◆ Get() [3/3]
Note: If you don't know what this function is for, you shouldn't use it!
- Returns
- the current value of a pointer.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicPointer.CompareAndSwap
-
AtomicPointer.Set
◆ GetAtomicInt()
Note: If you don't know what this function is for, you shouldn't use it!
- Parameters
-
- Returns
- the current value of an atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.Set
◆ GetAtomicU32()
Note: If you don't know what this function is for, you shouldn't use it!
- Parameters
-
- Returns
- the current value of an atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicU32.Set
◆ MemoryBarrierAcquire()
| void SDL::MemoryBarrierAcquire |
( |
| ) |
|
|
inline |
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.
- Thread safety:
- 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!
- Since
- This function is available since SDL 3.2.0.
- See also
- SDL_MemoryBarrierAcquire
◆ MemoryBarrierRelease()
| void SDL::MemoryBarrierRelease |
( |
| ) |
|
|
inline |
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.
- Thread safety:
- 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!
- Since
- This function is available since SDL 3.2.0.
- See also
- SDL_MemoryBarrierRelease
◆ Set() [1/3]
| int SDL::AtomicInt::Set |
( |
int |
v | ) |
|
|
inline |
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!
- Parameters
-
- Returns
- the previous value of the atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.Get
◆ Set() [2/3]
Note: If you don't know what this function is for, you shouldn't use it!
- Parameters
-
| v | the desired pointer value. |
- Returns
- the previous value of the pointer.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicPointer.CompareAndSwap
-
AtomicPointer.Get
◆ Set() [3/3]
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!
- Parameters
-
- Returns
- the previous value of the atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicU32.Get
◆ SetAtomicInt()
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!
- Parameters
-
| a | a pointer to an AtomicInt variable to be modified. |
| v | the desired value. |
- Returns
- the previous value of the atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicInt.Get
◆ SetAtomicU32()
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!
- Parameters
-
| a | a pointer to an AtomicU32 variable to be modified. |
| v | the desired value. |
- Returns
- the previous value of the atomic variable.
- Thread safety:
- It is safe to call this function from any thread.
- Since
- This function is available since SDL 3.2.0.
- See also
- AtomicU32.Get