Improvements based on feedback from Anthony Williams

This commit is contained in:
Sam Lantinga 2011-01-25 17:40:06 -08:00
parent c8cd5b9028
commit 29e0bf97e0
4 changed files with 93 additions and 126 deletions

View file

@ -70,61 +70,8 @@ leaveLock(void *a)
SDL_AtomicUnlock(&locks[index]);
}
#undef SDL_AtomicSet
int
SDL_AtomicSet(SDL_atomic_t *a, int value)
{
int oldvalue;
enterLock(a);
oldvalue = a->value;
a->value = value;
leaveLock(a);
return oldvalue;
}
#undef SDL_AtomicGet
int
SDL_AtomicGet(SDL_atomic_t *a)
{
/* Assuming integral reads on this platform, we're safe here since the
functions that set the variable have the necessary memory barriers.
*/
return a->value;
}
#undef SDL_AtomicAdd
int
SDL_AtomicAdd(SDL_atomic_t *a, int value)
{
int oldvalue;
enterLock(a);
oldvalue = a->value;
a->value += value;
leaveLock(a);
return oldvalue;
}
#undef SDL_AtomicIncRef
void
SDL_AtomicIncRef(SDL_atomic_t *a)
{
SDL_AtomicAdd(a, 1);
}
#undef SDL_AtomicDecRef
SDL_bool
SDL_AtomicDecRef(SDL_atomic_t *a)
{
return SDL_AtomicAdd(a, -1) == 1;
}
#undef SDL_AtomicCAS
SDL_bool
SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval)
SDL_AtomicCAS_(SDL_atomic_t *a, int oldval, int newval)
{
SDL_bool retval = SDL_FALSE;
@ -138,28 +85,8 @@ SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval)
return retval;
}
#undef SDL_AtomicSetPtr
void
SDL_AtomicSetPtr(void** a, void* value)
{
void *prevval;
do {
prevval = *a;
} while (!SDL_AtomicCASPtr(a, prevval, value));
}
#undef SDL_AtomicGetPtr
void*
SDL_AtomicGetPtr(void** a)
{
/* Assuming integral reads on this platform, we're safe here since the
functions that set the pointer have the necessary memory barriers.
*/
return *a;
}
#undef SDL_AtomicCASPtr
SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
SDL_bool
SDL_AtomicCASPtr_(void **a, void *oldval, void *newval)
{
SDL_bool retval = SDL_FALSE;

View file

@ -37,20 +37,20 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
return (InterlockedExchange((long*)lock, 1) == 0);
#elif defined(__MACOSX__)
#elif __MACOSX__
return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
#elif defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
#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_5__)
#elif __GNUC__ && __arm__ && __ARM_ARCH_5__
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__)
#elif __GNUC__ && __arm__
int result;
__asm__ __volatile__ (
"ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
@ -75,8 +75,16 @@ SDL_AtomicLock(SDL_SpinLock *lock)
void
SDL_AtomicUnlock(SDL_SpinLock *lock)
{
/* Assuming atomic assignment operation and full memory barrier in lock */
#if defined(_MSC_VER)
_ReadWriteBarrier();
*lock = 0;
#elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
__sync_lock_release(lock);
#else
*lock = 0;
#endif
}
/* vi: set ts=4 sw=4 expandtab: */