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

Go to the source code of this file.

Macros

#define PAUSE_INSTRUCTION()
 

Functions

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

Macro Definition Documentation

◆ PAUSE_INSTRUCTION

#define PAUSE_INSTRUCTION ( )

Definition at line 148 of file SDL_spinlock.c.

Function Documentation

◆ SDL_AtomicLock()

void 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 152 of file SDL_spinlock.c.

153 {
154  int iterations = 0;
155  /* FIXME: Should we have an eventual timeout? */
156  while (!SDL_AtomicTryLock(lock)) {
157  if (iterations < 32) {
158  iterations++;
160  } else {
161  /* !!! FIXME: this doesn't definitely give up the current timeslice, it does different things on various platforms. */
162  SDL_Delay(0);
163  }
164  }
165 }

References iterations, lock, PAUSE_INSTRUCTION, SDL_AtomicTryLock(), and SDL_Delay.

◆ SDL_AtomicTryLock()

SDL_bool 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 55 of file SDL_spinlock.c.

56 {
57 #if SDL_ATOMIC_DISABLED
58  /* Terrible terrible damage */
59  static SDL_mutex *_spinlock_mutex;
60 
61  if (!_spinlock_mutex) {
62  /* Race condition on first lock... */
63  _spinlock_mutex = SDL_CreateMutex();
64  }
65  SDL_LockMutex(_spinlock_mutex);
66  if (*lock == 0) {
67  *lock = 1;
68  SDL_UnlockMutex(_spinlock_mutex);
69  return SDL_TRUE;
70  } else {
71  SDL_UnlockMutex(_spinlock_mutex);
72  return SDL_FALSE;
73  }
74 
75 #elif defined(_MSC_VER)
76  SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
77  return (InterlockedExchange((long*)lock, 1) == 0);
78 
79 #elif defined(__WATCOMC__) && defined(__386__)
80  return _SDL_xchg_watcom(lock, 1) == 0;
81 
82 #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
83  return (__sync_lock_test_and_set(lock, 1) == 0);
84 
85 #elif defined(__GNUC__) && defined(__arm__) && \
86  (defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \
87  defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
88  defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \
89  defined(__ARM_ARCH_5TEJ__))
90  int result;
91 
92 #if defined(__RISCOS__)
93  if (__cpucap_have_rex()) {
94  __asm__ __volatile__ (
95  "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
96  : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
97  return (result == 0);
98  }
99 #endif
100 
101  __asm__ __volatile__ (
102  "swp %0, %1, [%2]\n"
103  : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory");
104  return (result == 0);
105 
106 #elif defined(__GNUC__) && defined(__arm__)
107  int result;
108  __asm__ __volatile__ (
109  "ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
110  : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
111  return (result == 0);
112 
113 #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
114  int result;
115  __asm__ __volatile__(
116  "lock ; xchgl %0, (%1)\n"
117  : "=r" (result) : "r" (lock), "0" (1) : "cc", "memory");
118  return (result == 0);
119 
120 #elif defined(__MACOSX__) || defined(__IPHONEOS__)
121  /* Maybe used for PowerPC, but the Intel asm or gcc atomics are favored. */
122  return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
123 
124 #elif defined(__SOLARIS__) && defined(_LP64)
125  /* Used for Solaris with non-gcc compilers. */
126  return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)lock, 0, 1) == 0);
127 
128 #elif defined(__SOLARIS__) && !defined(_LP64)
129  /* Used for Solaris with non-gcc compilers. */
130  return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)lock, 0, 1) == 0);
131 
132 #else
133 #error Please implement for your platform.
134  return SDL_FALSE;
135 #endif
136 }

References lock, SDL_COMPILE_TIME_ASSERT, SDL_CreateMutex, SDL_FALSE, SDL_LockMutex, SDL_TRUE, and SDL_UnlockMutex.

Referenced by SDL_AtomicLock().

◆ SDL_AtomicUnlock()

void 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 168 of file SDL_spinlock.c.

169 {
170 #if defined(_MSC_VER)
171  _ReadWriteBarrier();
172  *lock = 0;
173 
174 #elif defined(__WATCOMC__) && defined(__386__)
176  *lock = 0;
177 
178 #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
179  __sync_lock_release(lock);
180 
181 #elif defined(__SOLARIS__)
182  /* Used for Solaris when not using gcc. */
183  *lock = 0;
184  membar_producer();
185 
186 #else
187  *lock = 0;
188 #endif
189 }

References lock, and SDL_CompilerBarrier.

SDL_LockMutex
#define SDL_LockMutex
Definition: SDL_dynapi_overrides.h:260
SDL_mutex
Definition: SDL_sysmutex.c:29
iterations
static int iterations
Definition: testsprite2.c:45
SDL_CreateMutex
#define SDL_CreateMutex
Definition: SDL_dynapi_overrides.h:259
SDL_AtomicTryLock
SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock)
Try to lock a spin lock by setting it to a non-zero value.
Definition: SDL_spinlock.c:55
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9435
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_COMPILE_TIME_ASSERT
#define SDL_COMPILE_TIME_ASSERT(name, x)
Definition: SDL_stdinc.h:312
SDL_CompilerBarrier
#define SDL_CompilerBarrier()
Definition: SDL_atomic.h:132
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:486
uint32_t
unsigned int uint32_t
Definition: SDL_config_windows.h:63
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
PAUSE_INSTRUCTION
#define PAUSE_INSTRUCTION()
Definition: SDL_spinlock.c:148
SDL_UnlockMutex
#define SDL_UnlockMutex
Definition: SDL_dynapi_overrides.h:262
uint64_t
unsigned long long uint64_t
Definition: SDL_config_windows.h:65
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
lock
SDL_mutex * lock
Definition: SDL_events.c:83