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

Atomic operations. More...

Classes

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

Macros

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

Functions

void SDL::MemoryBarrierRelease ()
 Insert a memory release barrier (function version).
 
void SDL::MemoryBarrierAcquire ()
 Insert a memory acquire barrier (function version).
 

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

◆ 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