SDL  2.0
SDL_atomic.c File Reference
#include "../SDL_internal.h"
#include "SDL_atomic.h"
+ Include dependency graph for SDL_atomic.c:

Go to the source code of this file.

Macros

#define EMULATE_CAS   1
 

Functions

static SDL_INLINE void enterLock (void *a)
 
static SDL_INLINE void leaveLock (void *a)
 
SDL_bool 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...
 
SDL_bool SDL_AtomicCASPtr (void **a, void *oldval, void *newval)
 Set a pointer to a new value if it is currently an old value. More...
 
int SDL_AtomicSet (SDL_atomic_t *a, int v)
 Set an atomic variable to a value. More...
 
voidSDL_AtomicSetPtr (void **a, void *v)
 Set a pointer to a value atomically. More...
 
int SDL_AtomicAdd (SDL_atomic_t *a, int v)
 Add to an atomic variable. More...
 
int SDL_AtomicGet (SDL_atomic_t *a)
 Get the value of an atomic variable. More...
 
voidSDL_AtomicGetPtr (void **a)
 Get the value of a pointer atomically. More...
 

Variables

static SDL_SpinLock locks [32]
 

Macro Definition Documentation

#define EMULATE_CAS   1

Definition at line 62 of file SDL_atomic.c.

Function Documentation

static SDL_INLINE void enterLock ( void a)
static

Definition at line 69 of file SDL_atomic.c.

References locks, SDL_AtomicLock, and SDL_INLINE.

Referenced by SDL_AtomicCAS(), and SDL_AtomicCASPtr().

70 {
71  uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
72 
73  SDL_AtomicLock(&locks[index]);
74 }
#define SDL_AtomicLock
unsigned int uintptr_t
GLuint index
static SDL_SpinLock locks[32]
Definition: SDL_atomic.c:66
GLboolean GLboolean GLboolean GLboolean a
static SDL_INLINE void leaveLock ( void a)
static

Definition at line 77 of file SDL_atomic.c.

References locks, and SDL_AtomicUnlock.

Referenced by SDL_AtomicCAS(), and SDL_AtomicCASPtr().

78 {
79  uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
80 
81  SDL_AtomicUnlock(&locks[index]);
82 }
#define SDL_AtomicUnlock
unsigned int uintptr_t
GLuint index
static SDL_SpinLock locks[32]
Definition: SDL_atomic.c:66
GLboolean GLboolean GLboolean GLboolean a
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 187 of file SDL_atomic.c.

References SDL_AtomicCAS(), and SDL_atomic_t::value.

188 {
189 #ifdef HAVE_MSC_ATOMICS
190  return _InterlockedExchangeAdd((long*)&a->value, v);
191 #elif defined(HAVE_GCC_ATOMICS)
192  return __sync_fetch_and_add(&a->value, v);
193 #elif defined(__SOLARIS__)
194  int pv = a->value;
195  membar_consumer();
196 #if defined(_LP64)
197  atomic_add_64((volatile uint64_t*)&a->value, v);
198 #elif !defined(_LP64)
199  atomic_add_32((volatile uint32_t*)&a->value, v);
200 #endif
201  return pv;
202 #else
203  int value;
204  do {
205  value = a->value;
206  } while (!SDL_AtomicCAS(a, value, (value + v)));
207  return value;
208 #endif
209 }
unsigned long long uint64_t
const GLdouble * v
Definition: SDL_opengl.h:2057
GLsizei const GLfloat * value
unsigned int uint32_t
SDL_bool 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.
Definition: SDL_atomic.c:87
SDL_bool 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 87 of file SDL_atomic.c.

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

Referenced by SDL_AtomicAdd(), SDL_AtomicGet(), and SDL_AtomicSet().

88 {
89 #ifdef HAVE_MSC_ATOMICS
90  return (_InterlockedCompareExchange((long*)&a->value, (long)newval, (long)oldval) == (long)oldval);
91 #elif defined(__MACOSX__) /* !!! FIXME: should we favor gcc atomics? */
92  return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value);
93 #elif defined(HAVE_GCC_ATOMICS)
94  return (SDL_bool) __sync_bool_compare_and_swap(&a->value, oldval, newval);
95 #elif defined(__SOLARIS__) && defined(_LP64)
96  return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)&a->value, (uint64_t)oldval, (uint64_t)newval) == oldval);
97 #elif defined(__SOLARIS__) && !defined(_LP64)
98  return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)&a->value, (uint32_t)oldval, (uint32_t)newval) == oldval);
99 #elif EMULATE_CAS
101 
102  enterLock(a);
103  if (a->value == oldval) {
104  a->value = newval;
105  retval = SDL_TRUE;
106  }
107  leaveLock(a);
108 
109  return retval;
110 #else
111  #error Please define your platform.
112 #endif
113 }
unsigned long long uint64_t
SDL_bool
Definition: SDL_stdinc.h:126
SDL_bool retval
static SDL_INLINE void leaveLock(void *a)
Definition: SDL_atomic.c:77
static SDL_INLINE void enterLock(void *a)
Definition: SDL_atomic.c:69
unsigned int uint32_t
SDL_bool 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 116 of file SDL_atomic.c.

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

Referenced by SDL_AtomicGetPtr(), and SDL_AtomicSetPtr().

117 {
118 #if defined(HAVE_MSC_ATOMICS) && (_M_IX86)
119  return (_InterlockedCompareExchange((long*)a, (long)newval, (long)oldval) == (long)oldval);
120 #elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86)
121  return (_InterlockedCompareExchangePointer(a, newval, oldval) == oldval);
122 #elif defined(__MACOSX__) && defined(__LP64__) /* !!! FIXME: should we favor gcc atomics? */
123  return (SDL_bool) OSAtomicCompareAndSwap64Barrier((int64_t)oldval, (int64_t)newval, (int64_t*) a);
124 #elif defined(__MACOSX__) && !defined(__LP64__) /* !!! FIXME: should we favor gcc atomics? */
125  return (SDL_bool) OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t*) a);
126 #elif defined(HAVE_GCC_ATOMICS)
127  return __sync_bool_compare_and_swap(a, oldval, newval);
128 #elif defined(__SOLARIS__)
129  return (SDL_bool) (atomic_cas_ptr(a, oldval, newval) == oldval);
130 #elif EMULATE_CAS
132 
133  enterLock(a);
134  if (*a == oldval) {
135  *a = newval;
136  retval = SDL_TRUE;
137  }
138  leaveLock(a);
139 
140  return retval;
141 #else
142  #error Please define your platform.
143 #endif
144 }
signed int int32_t
SDL_bool
Definition: SDL_stdinc.h:126
SDL_bool retval
static SDL_INLINE void leaveLock(void *a)
Definition: SDL_atomic.c:77
static SDL_INLINE void enterLock(void *a)
Definition: SDL_atomic.c:69
GLboolean GLboolean GLboolean GLboolean a
signed long long int64_t
int SDL_AtomicGet ( SDL_atomic_t a)

Get the value of an atomic variable.

Definition at line 212 of file SDL_atomic.c.

References SDL_AtomicCAS(), and SDL_atomic_t::value.

213 {
214  int value;
215  do {
216  value = a->value;
217  } while (!SDL_AtomicCAS(a, value, value));
218  return value;
219 }
GLsizei const GLfloat * value
SDL_bool 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.
Definition: SDL_atomic.c:87
void* SDL_AtomicGetPtr ( void **  a)

Get the value of a pointer atomically.

Definition at line 222 of file SDL_atomic.c.

References SDL_AtomicCASPtr().

223 {
224  void *value;
225  do {
226  value = *a;
227  } while (!SDL_AtomicCASPtr(a, value, value));
228  return value;
229 }
SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
Set a pointer to a new value if it is currently an old value.
Definition: SDL_atomic.c:116
GLsizei const GLfloat * value
GLboolean GLboolean GLboolean GLboolean a
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 147 of file SDL_atomic.c.

References SDL_AtomicCAS(), and SDL_atomic_t::value.

148 {
149 #ifdef HAVE_MSC_ATOMICS
150  return _InterlockedExchange((long*)&a->value, v);
151 #elif defined(HAVE_GCC_ATOMICS)
152  return __sync_lock_test_and_set(&a->value, v);
153 #elif defined(__SOLARIS__) && defined(_LP64)
154  return (int) atomic_swap_64((volatile uint64_t*)&a->value, (uint64_t)v);
155 #elif defined(__SOLARIS__) && !defined(_LP64)
156  return (int) atomic_swap_32((volatile uint32_t*)&a->value, (uint32_t)v);
157 #else
158  int value;
159  do {
160  value = a->value;
161  } while (!SDL_AtomicCAS(a, value, v));
162  return value;
163 #endif
164 }
unsigned long long uint64_t
const GLdouble * v
Definition: SDL_opengl.h:2057
GLsizei const GLfloat * value
unsigned int uint32_t
SDL_bool 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.
Definition: SDL_atomic.c:87
void* SDL_AtomicSetPtr ( void **  a,
void v 
)

Set a pointer to a value atomically.

Returns
The previous value of the pointer.

Definition at line 167 of file SDL_atomic.c.

References SDL_AtomicCASPtr().

168 {
169 #if defined(HAVE_MSC_ATOMICS) && (_M_IX86)
170  return (void *) _InterlockedExchange((long *)a, (long) v);
171 #elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86)
172  return _InterlockedExchangePointer(a, v);
173 #elif defined(HAVE_GCC_ATOMICS)
174  return __sync_lock_test_and_set(a, v);
175 #elif defined(__SOLARIS__)
176  return atomic_swap_ptr(a, v);
177 #else
178  void *value;
179  do {
180  value = *a;
181  } while (!SDL_AtomicCASPtr(a, value, v));
182  return value;
183 #endif
184 }
SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
Set a pointer to a new value if it is currently an old value.
Definition: SDL_atomic.c:116
const GLdouble * v
Definition: SDL_opengl.h:2057
GLsizei const GLfloat * value
GLboolean GLboolean GLboolean GLboolean a

Variable Documentation

SDL_SpinLock locks[32]
static

Definition at line 66 of file SDL_atomic.c.

Referenced by enterLock(), and leaveLock().