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

138{
139 int iterations = 0;
140 /* FIXME: Should we have an eventual timeout? */
141 while (!SDL_AtomicTryLock(lock)) {
142 if (iterations < 32) {
143 iterations++;
145 } else {
146 /* !!! FIXME: this doesn't definitely give up the current timeslice, it does different things on various platforms. */
147 SDL_Delay(0);
148 }
149 }
150}
#define SDL_Delay
SDL_mutex * lock
Definition: SDL_events.c:76
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:51
#define PAUSE_INSTRUCTION()
Definition: SDL_spinlock.c:133
static int iterations
Definition: testsprite2.c:45

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

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

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

154{
155#if defined(_MSC_VER)
156 _ReadWriteBarrier();
157 *lock = 0;
158
159#elif defined(__WATCOMC__) && defined(__386__)
161 *lock = 0;
162
163#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
164 __sync_lock_release(lock);
165
166#elif defined(__SOLARIS__)
167 /* Used for Solaris when not using gcc. */
168 *lock = 0;
169 membar_producer();
170
171#else
172 *lock = 0;
173#endif
174}
#define SDL_CompilerBarrier()
Definition: SDL_atomic.h:132

References lock, and SDL_CompilerBarrier.