SDL_atomic.h File Reference
`#include <SDL3/SDL_stdinc.h>`
`#include <SDL3/SDL_platform_defines.h>`
`#include <SDL3/SDL_begin_code.h>`
`#include <SDL3/SDL_close_code.h>`
Include dependency graph for SDL_atomic.h:
This graph shows which files directly or indirectly include this file:

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)

## Macro Definition Documentation

## SDL_AtomicDecRef

#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!

Parameters

  a | a pointer to an SDL_AtomicInt to decrement.

Returns
  true if the variable reached zero after decrementing, false otherwise.

\threadsafety It is safe to call this macro from any thread.

Since
  This macro is available since SDL 3.2.0.

See also
  SDL_AtomicIncRef

Definition at line 511 of file SDL_atomic.h.

## SDL_AtomicIncRef

#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!

Parameters

  a | a pointer to an SDL_AtomicInt to increment.

Returns
  the previous value of the atomic variable.

\threadsafety It is safe to call this macro from any thread.

Since
  This macro is available since SDL 3.2.0.

See also
  SDL_AtomicDecRef

Definition at line 491 of file SDL_atomic.h.

## SDL_CompilerBarrier

#define SDL_CompilerBarrier | ( |  | ) | { SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); }

Definition at line 170 of file SDL_atomic.h.

{ SDL_SpinLock _tmp = 0; SDL_LockSpinlock(&_tmp); SDL_UnlockSpinlock(&_tmp); }
SDL_SpinLock
int SDL_SpinLock
Definition SDL_atomic.h:82
SDL_LockSpinlock
void SDL_LockSpinlock(SDL_SpinLock *lock)
SDL_UnlockSpinlock
void SDL_UnlockSpinlock(SDL_SpinLock *lock)

## SDL_CPUPauseInstruction

#define SDL_CPUPauseInstruction | ( |  | ) |

Definition at line 364 of file SDL_atomic.h.

## SDL_MemoryBarrierAcquire

#define SDL_MemoryBarrierAcquire | ( |  | ) | SDL_CompilerBarrier()

Definition at line 323 of file SDL_atomic.h.

## SDL_MemoryBarrierRelease

#define SDL_MemoryBarrierRelease | ( |  | ) | SDL_CompilerBarrier()

Definition at line 322 of file SDL_atomic.h.

## Typedef Documentation

## SDL_SpinLock

typedef int SDL_SpinLock

# CategoryAtomic

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:

- https://www.1024cores.net/home/lock-free-algorithms
- https://preshing.com/

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.

## Function Documentation

## SDL_AddAtomicInt()

int SDL_AddAtomicInt | ( | SDL_AtomicInt * | a,
|  | int | v
| ) |  |

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!

Parameters

  a | a pointer to an SDL_AtomicInt variable to be modified.
  v | the desired value to add.

Returns
  the previous value of the atomic variable.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_AtomicDecRef
  SDL_AtomicIncRef

## SDL_CompareAndSwapAtomicInt()

bool SDL_CompareAndSwapAtomicInt | ( | SDL_AtomicInt * | a,
|  | int | oldval,
|  | int | newval
| ) |  |

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!

Parameters

  a | a pointer to an SDL_AtomicInt variable to be modified.
  oldval | the old value.
  newval | the new value.

Returns
  true if the atomic variable was set, false otherwise.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_GetAtomicInt
  SDL_SetAtomicInt

## SDL_CompareAndSwapAtomicPointer()

bool SDL_CompareAndSwapAtomicPointer | ( | void ** | a,
|  | void * | oldval,
|  | void * | newval
| ) |  |

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!

Parameters

  a | a pointer to a pointer.
  oldval | the old pointer value.
  newval | the new pointer value.

Returns
  true if the pointer was set, false otherwise.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_CompareAndSwapAtomicInt
  SDL_GetAtomicPointer
  SDL_SetAtomicPointer

## SDL_CompareAndSwapAtomicU32()

bool SDL_CompareAndSwapAtomicU32 | ( | SDL_AtomicU32 * | a,
|  | Uint32 | oldval,
|  | Uint32 | newval
| ) |  |

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!

Parameters

  a | a pointer to an SDL_AtomicU32 variable to be modified.
  oldval | the old value.
  newval | the new value.

Returns
  true if the atomic variable was set, false otherwise.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_GetAtomicU32
  SDL_SetAtomicU32

## SDL_GetAtomicInt()

int SDL_GetAtomicInt | ( | SDL_AtomicInt * | a | ) |

extern

Get the value of an atomic variable.

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

Parameters

  a | a pointer to an SDL_AtomicInt variable.

Returns
  the current value of an atomic variable.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_SetAtomicInt

## SDL_GetAtomicPointer()

void * SDL_GetAtomicPointer | ( | void ** | a | ) |

extern

Get the value of a pointer atomically.

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

Parameters

  a | a pointer to a pointer.

Returns
  the current value of a pointer.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_CompareAndSwapAtomicPointer
  SDL_SetAtomicPointer

## SDL_GetAtomicU32()

Uint32 SDL_GetAtomicU32 | ( | SDL_AtomicU32 * | a | ) |

extern

Get the value of an atomic variable.

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

Parameters

  a | a pointer to an SDL_AtomicU32 variable.

Returns
  the current value of an atomic variable.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_SetAtomicU32

## SDL_LockSpinlock()

void SDL_LockSpinlock | ( | SDL_SpinLock * | lock | ) |

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!

Parameters

  lock | a pointer to a lock variable.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_TryLockSpinlock
  SDL_UnlockSpinlock

## SDL_MemoryBarrierAcquireFunction()

void SDL_MemoryBarrierAcquireFunction | ( | void |  | ) |

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!

Since
  This function is available since SDL 3.2.0.

See also
  SDL_MemoryBarrierAcquire

## SDL_MemoryBarrierReleaseFunction()

void SDL_MemoryBarrierReleaseFunction | ( | void |  | ) |

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!

Since
  This function is available since SDL 3.2.0.

See also
  SDL_MemoryBarrierRelease

## SDL_SetAtomicInt()

int SDL_SetAtomicInt | ( | SDL_AtomicInt * | a,
|  | int | v
| ) |  |

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!

Parameters

  a | a pointer to an SDL_AtomicInt variable to be modified.
  v | the desired value.

Returns
  the previous value of the atomic variable.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_GetAtomicInt

## SDL_SetAtomicPointer()

void * SDL_SetAtomicPointer | ( | void ** | a,
|  | void * | v
| ) |  |

extern

Set a pointer to a value atomically.

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

Parameters

  a | a pointer to a pointer.
  v | the desired pointer value.

Returns
  the previous value of the pointer.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_CompareAndSwapAtomicPointer
  SDL_GetAtomicPointer

## SDL_SetAtomicU32()

Uint32 SDL_SetAtomicU32 | ( | SDL_AtomicU32 * | a,
|  | Uint32 | v
| ) |  |

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!

Parameters

  a | a pointer to an SDL_AtomicU32 variable to be modified.
  v | the desired value.

Returns
  the previous value of the atomic variable.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_GetAtomicU32

## SDL_TryLockSpinlock()

bool SDL_TryLockSpinlock | ( | SDL_SpinLock * | lock | ) |

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!

Parameters

  lock | a pointer to a lock variable.

Returns
  true if the lock succeeded, false if the lock is already held.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_LockSpinlock
  SDL_UnlockSpinlock

## SDL_UnlockSpinlock()

void SDL_UnlockSpinlock | ( | SDL_SpinLock * | lock | ) |

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!

Parameters

  lock | a pointer to a lock variable.

\threadsafety It is safe to call this function from any thread.

Since
  This function is available since SDL 3.2.0.

See also
  SDL_LockSpinlock
  SDL_TryLockSpinlock