SDL3pp
A slim C++ wrapper for SDL3
Loading...
Searching...
No Matches
Classes | Macros | Typedefs | Functions
Atomic Operations

Atomic operations. More...

Collaboration diagram for Atomic Operations:

Classes

struct  SDL::AtomicInt
 A type representing an atomic integer value. More...
 
struct  SDL::AtomicU32
 A type representing an atomic unsigned 32-bit value. More...
 
class  SDL::AtomicPointer< T >
 

Macros

#define SDL_CompilerBarrier()   DoCompilerSpecificReadWriteBarrier()
 Mark a compiler barrier. More...
 
#define SDL_MemoryBarrierRelease()   SDL_MemoryBarrierReleaseFunction()
 Insert a memory release barrier (macro version). More...
 
#define SDL_MemoryBarrierAcquire()   SDL_MemoryBarrierAcquireFunction()
 Insert a memory acquire barrier (macro version). More...
 
#define SDL_CPUPauseInstruction()    DoACPUPauseInACompilerAndArchitectureSpecificWay
 A macro to insert a CPU-specific "pause" instruction into the program. More...
 

Typedefs

using SDL::AtomicIntRaw = SDL_AtomicInt
 Alias to raw representation for AtomicInt.
 
using SDL::AtomicU32Raw = SDL_AtomicU32
 Alias to raw representation for AtomicU32.
 

Functions

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...
 

Detailed Description

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.

Macro Definition Documentation

◆ 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

Function Documentation

◆ 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
vthe 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()

int SDL::AddAtomicInt ( AtomicIntRaw a,
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
aa pointer to an AtomicInt variable to be modified.
vthe 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]

bool SDL::AtomicDecRef ( AtomicIntRaw a)
inline

Note: If you don't know what this macro is for, you shouldn't use it!

Parameters
aa pointer to an AtomicInt to decrement.
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]

bool SDL::AtomicIncRef ( AtomicIntRaw a)
inline

Note: If you don't know what this macro is for, you shouldn't use it!

Parameters
aa pointer to an AtomicInt to increment.
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
oldvalthe old value.
newvalthe 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]

template<class T >
bool SDL::AtomicPointer< T >::CompareAndSwap ( T *  oldval,
T *  newval 
)
inline

Note: If you don't know what this function is for, you shouldn't use it!

Parameters
oldvalthe old pointer value.
newvalthe 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
oldvalthe old value.
newvalthe 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
aa pointer to an AtomicInt variable to be modified.
oldvalthe old value.
newvalthe 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()

bool SDL::CompareAndSwapAtomicU32 ( AtomicU32Raw a,
Uint32  oldval,
Uint32  newval 
)
inline

Note: If you don't know what this function is for, you shouldn't use it!

Parameters
aa pointer to an AtomicU32 variable to be modified.
oldvalthe old value.
newvalthe 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]

template<class T >
T * SDL::AtomicPointer< T >::Get
inline

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()

int SDL::GetAtomicInt ( AtomicIntRaw a)
inline

Note: If you don't know what this function is for, you shouldn't use it!

Parameters
aa pointer to an AtomicInt variable.
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()

Uint32 SDL::GetAtomicU32 ( AtomicU32Raw a)
inline

Note: If you don't know what this function is for, you shouldn't use it!

Parameters
aa pointer to an AtomicU32 variable.
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
vthe 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

◆ Set() [2/3]

template<class T >
T * SDL::AtomicPointer< T >::Set ( T *  v)
inline

Note: If you don't know what this function is for, you shouldn't use it!

Parameters
vthe 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]

Uint32 SDL::AtomicU32::Set ( Uint32  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
vthe 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

◆ SetAtomicInt()

int SDL::SetAtomicInt ( AtomicIntRaw a,
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
aa pointer to an AtomicInt variable to be modified.
vthe 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()

Uint32 SDL::SetAtomicU32 ( AtomicU32Raw a,
Uint32  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
aa pointer to an AtomicU32 variable to be modified.
vthe 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