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.

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...
 

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

References SDL_AtomicTryLock(), and SDL_Delay.

121 {
122  /* FIXME: Should we have an eventual timeout? */
123  while (!SDL_AtomicTryLock(lock)) {
124  SDL_Delay(0);
125  }
126 }
#define SDL_Delay
SDL_mutex * lock
Definition: SDL_events.c:78
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:47

◆ 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 47 of file SDL_spinlock.c.

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

Referenced by SDL_AtomicLock().

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

◆ 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 129 of file SDL_spinlock.c.

References SDL_CompilerBarrier.

130 {
131 #if defined(_MSC_VER)
132  _ReadWriteBarrier();
133  *lock = 0;
134 
135 #elif defined(__WATCOMC__) && defined(__386__)
137  *lock = 0;
138 
139 #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
140  __sync_lock_release(lock);
141 
142 #elif defined(__SOLARIS__)
143  /* Used for Solaris when not using gcc. */
144  *lock = 0;
145  membar_producer();
146 
147 #else
148  *lock = 0;
149 #endif
150 }
#define SDL_CompilerBarrier()
Definition: SDL_atomic.h:132
SDL_mutex * lock
Definition: SDL_events.c:78