SpinlocksLoadStoreEx.c [plain text]
typedef int32_t OSSpinLock;
#import <mach/mach_traps.h>
static inline void _OSSpinLockSlow(volatile OSSpinLock * lock) _OSATOMIC_VARIANT(_OSSpinLockSlow);
static inline void _OSSpinLockSlow(volatile OSSpinLock * lock)
{
int32_t r;
uint32_t t;
_spin: ;
#if (defined(_ARM_ARCH_7) && !defined(_OSATOMIC_NO_BARRIERS))
uint32_t tries = MP_SPIN_TRIES;
do {
if (*lock == 0) goto _try_store;
_osatomic_pause();
} while (--tries);
#endif
__asm__ ("mov r0, %[_a] ;"
"mov r1, %[_b] ;"
"mov r2, %[_c] ;"
"bl _syscall_thread_switch ;"
: : [_a] "i" (0), [_b] "i" (1), [_c] "i" (1)
: "r0", "r1", "r2", "r9", "r12", "lr" );
_try_store:
do {
_osatomic_load_exclusive(lock, r);
if (slowpath(r)) goto _spin;
_osatomic_store_exclusive(lock, 1, t);
} while (slowpath(t));
_osatomic_barrier();
}
void OSSpinLockLock(volatile OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockLock);
void OSSpinLockLock(volatile OSSpinLock * lock)
{
_OSATOMIC_ALIAS(spin_lock, OSSpinLockLock);
_OSATOMIC_ALIAS(_spin_lock, OSSpinLockLock);
int32_t r;
uint32_t t;
do {
_osatomic_load_exclusive(lock, r);
if (slowpath(r)) return _OSSpinLockSlow(lock);
_osatomic_store_exclusive(lock, 1, t);
} while (slowpath(t));
_osatomic_barrier();
}
#ifndef _OSATOMIC_WFE
bool OSSpinLockTry(OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockTry);
bool OSSpinLockTry(OSSpinLock * lock)
{
_OSATOMIC_ALIAS(spin_lock_try, OSSpinLockTry);
_OSATOMIC_ALIAS(_spin_lock_try, OSSpinLockTry);
int32_t r;
uint32_t t;
do {
_osatomic_load_exclusive(lock, r);
if (slowpath(r)) return false;
_osatomic_store_exclusive(lock, 1, t);
} while (slowpath(t));
_osatomic_barrier();
return (r == 0);
}
void OSSpinLockUnlock(OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockUnlock);
void OSSpinLockUnlock(OSSpinLock * lock)
{
_OSATOMIC_ALIAS(spin_unlock, OSSpinLockUnlock);
_OSATOMIC_ALIAS(_spin_unlock, OSSpinLockUnlock);
_osatomic_barrier();
*lock = 0;
}
#endif // _OSATOMIC_WFE