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

  lock | Points to the lock.

Definition at line 120 of file SDL_spinlock.c.

References SDL_AtomicTryLock(), and SDL_Delay.

{
/* FIXME: Should we have an eventual timeout? */
while (!SDL_AtomicTryLock(lock)) {
SDL_Delay(0);
}
}
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:486
lock
SDL_mutex * lock
Definition: SDL_events.c:78
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: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

  lock | Points 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().

{
#if SDL_ATOMIC_DISABLED
/* Terrible terrible damage */
static SDL_mutex *_spinlock_mutex;
if (!_spinlock_mutex) {
/* Race condition on first lock... */
_spinlock_mutex = SDL_CreateMutex();
}
SDL_LockMutex(_spinlock_mutex);
if (*lock == 0) {
*lock = 1;
SDL_UnlockMutex(_spinlock_mutex);
return SDL_TRUE;
} else {
SDL_UnlockMutex(_spinlock_mutex);
return SDL_FALSE;
}
#elif defined(_MSC_VER)
SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
return (InterlockedExchange((long*)lock, 1) == 0);
#elif defined(__WATCOMC__) && defined(__386__)
return _SDL_xchg_watcom(lock, 1) == 0;
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
return (__sync_lock_test_and_set(lock, 1) == 0);
#elif defined(__GNUC__) && defined(__arm__) && \
(defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \
defined(__ARM_ARCH_5TEJ__))
int result;
__asm__ __volatile__ (
"swp %0, %1, [%2]\n"
: "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory");
return (result == 0);
#elif defined(__GNUC__) && defined(__arm__)
int result;
__asm__ __volatile__ (
"ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
: "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
return (result == 0);
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
int result;
__asm__ __volatile__(
"lock ; xchgl %0, (%1)\n"
: "=r" (result) : "r" (lock), "0" (1) : "cc", "memory");
return (result == 0);
#elif defined(__MACOSX__) || defined(__IPHONEOS__)
/* Maybe used for PowerPC, but the Intel asm or gcc atomics are favored. */
return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
#elif defined(__SOLARIS__) && defined(_LP64)
/* Used for Solaris with non-gcc compilers. */
return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)lock, 0, 1) == 0);
#elif defined(__SOLARIS__) && !defined(_LP64)
/* Used for Solaris with non-gcc compilers. */
return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)lock, 0, 1) == 0);
#else
#error Please implement for your platform.
return SDL_FALSE;
#endif
}
SDL_LockMutex
#define SDL_LockMutex
Definition: SDL_dynapi_overrides.h:260
SDL_TRUE
Definition: SDL_stdinc.h:142
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9432
SDL_FALSE
Definition: SDL_stdinc.h:141
SDL_CreateMutex
#define SDL_CreateMutex
Definition: SDL_dynapi_overrides.h:259
uint64_t
unsigned long long uint64_t
Definition: SDL_config_windows.h:65
SDL_mutex
Definition: SDL_sysmutex.c:29
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:139
uint32_t
unsigned int uint32_t
Definition: SDL_config_windows.h:63
lock
SDL_mutex * lock
Definition: SDL_events.c:78
SDL_UnlockMutex
#define SDL_UnlockMutex
Definition: SDL_dynapi_overrides.h:262
SDL_COMPILE_TIME_ASSERT
#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

  lock | Points to the lock.

Definition at line 129 of file SDL_spinlock.c.

References SDL_CompilerBarrier.

{
#if defined(_MSC_VER)
_ReadWriteBarrier();
*lock = 0;
#elif defined(__WATCOMC__) && defined(__386__)
SDL_CompilerBarrier ();
*lock = 0;
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
__sync_lock_release(lock);
#elif defined(__SOLARIS__)
/* Used for Solaris when not using gcc. */
*lock = 0;
membar_producer();
#else
*lock = 0;
#endif
}
SDL_CompilerBarrier
#define SDL_CompilerBarrier()
Definition: SDL_atomic.h:132
lock
SDL_mutex * lock
Definition: SDL_events.c:78