zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_atomic.h File Reference
#include "SDL_stdinc.h"
#include "SDL_platform.h"
#include "begin_code.h"
#include "close_code.h"

Go to the source code of this file.

Classes

struct  SDL_atomic_t
 A type representing an atomic integer value. It is a struct so people don't accidentally use numeric operations on it. More...
 

Macros

#define SDL_AtomicDecRef(a)   (SDL_AtomicAdd(a, -1) == 1)
 Decrement an atomic variable used as a reference count. More...
 
#define SDL_AtomicIncRef(a)   SDL_AtomicAdd(a, 1)
 Increment an atomic variable used as a reference count. More...
 
#define SDL_CompilerBarrier()   { SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }
 
#define SDL_MemoryBarrierAcquire()   SDL_CompilerBarrier()
 
#define SDL_MemoryBarrierRelease()   SDL_CompilerBarrier()
 

Functions

SDL_FORCE_INLINE int SDL_AtomicAdd (SDL_atomic_t *a, int v)
 Add to an atomic variable. More...
 
DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS (SDL_atomic_t *a, int oldval, int newval)
 Set an atomic variable to a new value if it is currently an old value. More...
 
DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr (void **a, void *oldval, void *newval)
 Set a pointer to a new value if it is currently an old value. More...
 
SDL_FORCE_INLINE int SDL_AtomicGet (SDL_atomic_t *a)
 Get the value of an atomic variable. More...
 
SDL_FORCE_INLINE voidSDL_AtomicGetPtr (void **a)
 Get the value of a pointer atomically. More...
 
SDL_FORCE_INLINE int SDL_AtomicSet (SDL_atomic_t *a, int v)
 Set an atomic variable to a value. More...
 
SDL_FORCE_INLINE voidSDL_AtomicSetPtr (void **a, void *v)
 Set a pointer to a value atomically. More...
 

SDL AtomicLock

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.

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.

typedef int SDL_SpinLock
 
DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock (SDL_SpinLock *lock)
 Try to lock a spin lock by setting it to a non-zero value. More...
 
DECLSPEC void SDLCALL SDL_AtomicLock (SDL_SpinLock *lock)
 Lock a spin lock by setting it to a non-zero value. More...
 
DECLSPEC void SDLCALL SDL_AtomicUnlock (SDL_SpinLock *lock)
 Unlock a spin lock by setting it to 0. Always returns immediately. More...
 

Detailed Description

Atomic operations.

IMPORTANT: If you are not an expert in concurrent lockless programming, you should only be using the atomic lock and reference counting functions in this file. In all other cases you should be protecting your data structures with full mutexes.

The list of "safe" functions to use are: SDL_AtomicLock() SDL_AtomicUnlock() SDL_AtomicIncRef() SDL_AtomicDecRef()

Seriously, here be dragons! ^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can find out a little more about lockless programming and the subtle issues that can arise here: http://msdn.microsoft.com/en-us/library/ee418650%28v=vs.85%29.aspx

There's also lots of good information here: http://www.1024cores.net/home/lock-free-algorithms http://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.

Definition in file SDL_atomic.h.

Macro Definition Documentation

#define SDL_AtomicDecRef (   a)    (SDL_AtomicAdd(a, -1) == 1)

Decrement an atomic variable used as a reference count.

Returns
SDL_TRUE if the variable reached zero after decrementing, SDL_FALSE otherwise

Definition at line 307 of file SDL_atomic.h.

#define SDL_AtomicIncRef (   a)    SDL_AtomicAdd(a, 1)

Increment an atomic variable used as a reference count.

Definition at line 297 of file SDL_atomic.h.

Referenced by SDL_AddTimer(), and SDL_TLSCreate().

#define SDL_CompilerBarrier ( )    { SDL_SpinLock _tmp = 0; SDL_AtomicLock(&_tmp); SDL_AtomicUnlock(&_tmp); }

The compiler barrier prevents the compiler from reordering reads and writes to globally visible variables across the call.

Definition at line 135 of file SDL_atomic.h.

Referenced by SDL_AtomicGet(), and SDL_AtomicGetPtr().

#define SDL_MemoryBarrierAcquire ( )    SDL_CompilerBarrier()

Definition at line 181 of file SDL_atomic.h.

Referenced by SDL_Generic_GetTLSData(), SDL_GetErrBuf(), and SDL_SYS_GetTLSData().

#define SDL_MemoryBarrierRelease ( )    SDL_CompilerBarrier()

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

Definition at line 180 of file SDL_atomic.h.

Referenced by SDL_Generic_GetTLSData(), SDL_GetErrBuf(), and SDL_SYS_GetTLSData().

Typedef Documentation

typedef int SDL_SpinLock

Definition at line 96 of file SDL_atomic.h.

Function Documentation

SDL_FORCE_INLINE int SDL_AtomicAdd ( SDL_atomic_t a,
int  v 
)

Add to an atomic variable.

Returns
The previous value of the atomic variable.
Note
This same style can be used for any number operation

Definition at line 283 of file SDL_atomic.h.

References SDL_AtomicCAS(), and SDL_atomic_t::value.

DECLSPEC SDL_bool SDLCALL SDL_AtomicCAS ( SDL_atomic_t a,
int  oldval,
int  newval 
)

Set an atomic variable to a new value if it is currently an old value.

Returns
SDL_TRUE if the atomic variable was set, SDL_FALSE otherwise.
Note
If you don't know what this function is for, you shouldn't use it!

Definition at line 75 of file SDL_atomic.c.

References enterLock(), leaveLock(), SDL_FALSE, SDL_TRUE, and SDL_atomic_t::value.

Referenced by SDL_AtomicAdd(), and SDL_AtomicSet().

DECLSPEC SDL_bool SDLCALL SDL_AtomicCASPtr ( void **  a,
void oldval,
void newval 
)

Set a pointer to a new value if it is currently an old value.

Returns
SDL_TRUE if the pointer was set, SDL_FALSE otherwise.
Note
If you don't know what this function is for, you shouldn't use it!

Definition at line 90 of file SDL_atomic.c.

References enterLock(), leaveLock(), SDL_FALSE, and SDL_TRUE.

Referenced by SDL_AtomicSetPtr().

SDL_FORCE_INLINE int SDL_AtomicGet ( SDL_atomic_t a)

Get the value of an atomic variable.

Definition at line 267 of file SDL_atomic.h.

References SDL_CompilerBarrier, and SDL_atomic_t::value.

SDL_FORCE_INLINE void* SDL_AtomicGetPtr ( void **  a)

Get the value of a pointer atomically.

Definition at line 341 of file SDL_atomic.h.

References SDL_CompilerBarrier.

DECLSPEC void SDLCALL SDL_AtomicLock ( SDL_SpinLock lock)

Lock a spin lock by setting it to a non-zero value.

Parameters
lockPoints to the lock.

Definition at line 100 of file SDL_spinlock.c.

References SDL_AtomicTryLock(), and SDL_Delay().

Referenced by enterLock(), SDL_AddTimer(), SDL_Generic_GetTLSData(), SDL_GetErrBuf(), SDL_ReportAssertion(), SDL_SYS_GetTLSData(), and SDL_TimerThread().

SDL_FORCE_INLINE int SDL_AtomicSet ( SDL_atomic_t a,
int  v 
)

Set an atomic variable to a value.

Returns
The previous value of the atomic variable.

Definition at line 253 of file SDL_atomic.h.

References SDL_AtomicCAS(), and SDL_atomic_t::value.

Referenced by SDL_TimerInit().

SDL_FORCE_INLINE void* SDL_AtomicSetPtr ( void **  a,
void v 
)

Set a pointer to a value atomically.

Returns
The previous value of the pointer.

Definition at line 327 of file SDL_atomic.h.

References SDL_AtomicCASPtr().

DECLSPEC SDL_bool SDLCALL SDL_AtomicTryLock ( SDL_SpinLock lock)

Try to lock a spin lock by setting it to a non-zero value.

Parameters
lockPoints to the lock.
Returns
SDL_TRUE if the lock succeeded, SDL_FALSE if the lock is already held.

Definition at line 34 of file SDL_spinlock.c.

References SDL_COMPILE_TIME_ASSERT, SDL_CreateMutex(), SDL_FALSE, SDL_LockMutex(), SDL_TRUE, and SDL_UnlockMutex().

Referenced by SDL_AtomicLock().

DECLSPEC void SDLCALL SDL_AtomicUnlock ( SDL_SpinLock lock)

Unlock a spin lock by setting it to 0. Always returns immediately.

Parameters
lockPoints to the lock.

Definition at line 109 of file SDL_spinlock.c.

Referenced by leaveLock(), SDL_AddTimer(), SDL_Generic_GetTLSData(), SDL_GetErrBuf(), SDL_ReportAssertion(), SDL_SYS_GetTLSData(), and SDL_TimerThread().