85 lines
1.9 KiB
C++
85 lines
1.9 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Copyright (c) Electronic Arts Inc. All rights reserved.
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// Pseudo implementation of 64 bit primitives modelled after Android's internals.
|
|
/// Return values and semantics are intended to be the same as 32 bit versions.
|
|
///
|
|
/// Basically just does a mutex lock around the operation. Rather than just
|
|
/// one global lock, uses a fixed set of mutexes to lock based on incoming
|
|
/// address to reduce contention.
|
|
///
|
|
/// Abuses the fact that the initializer for a pthread_mutex_t in Android is
|
|
/// simply "{0}" on a volatile int to avoid requiring global initialization of
|
|
/// these mutexes.
|
|
|
|
|
|
#include <EABase/eabase.h>
|
|
|
|
#if defined(EA_PLATFORM_ANDROID)
|
|
|
|
#include <pthread.h>
|
|
|
|
namespace EA
|
|
{
|
|
namespace Thread
|
|
{
|
|
|
|
#define EAT_FAKE_ATOMIC_SWAP_LOCK_COUNT 32U
|
|
static pthread_mutex_t sFakeAtomic64SwapLocks[EAT_FAKE_ATOMIC_SWAP_LOCK_COUNT];
|
|
|
|
#define EAT_SWAP_LOCK(addr) &sFakeAtomic64SwapLocks[((unsigned)(void*)(addr) >> 3U) % EAT_FAKE_ATOMIC_SWAP_LOCK_COUNT]
|
|
|
|
|
|
int64_t android_fake_atomic_swap_64(int64_t value, volatile int64_t* addr)
|
|
{
|
|
int64_t oldValue;
|
|
pthread_mutex_t* lock = EAT_SWAP_LOCK(addr);
|
|
|
|
pthread_mutex_lock(lock);
|
|
|
|
oldValue = *addr;
|
|
*addr = value;
|
|
|
|
pthread_mutex_unlock(lock);
|
|
return oldValue;
|
|
}
|
|
|
|
|
|
int android_fake_atomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue, volatile int64_t* addr)
|
|
{
|
|
int ret;
|
|
pthread_mutex_t* lock = EAT_SWAP_LOCK(addr);
|
|
|
|
pthread_mutex_lock(lock);
|
|
|
|
if (*addr == oldvalue)
|
|
{
|
|
*addr = newvalue;
|
|
ret = 0;
|
|
}
|
|
else
|
|
{
|
|
ret = 1;
|
|
}
|
|
pthread_mutex_unlock(lock);
|
|
return ret;
|
|
}
|
|
|
|
|
|
int64_t android_fake_atomic_read_64(volatile int64_t* addr)
|
|
{
|
|
int64_t ret;
|
|
pthread_mutex_t* lock = EAT_SWAP_LOCK(addr);
|
|
|
|
pthread_mutex_lock(lock);
|
|
ret = *addr;
|
|
pthread_mutex_unlock(lock);
|
|
return ret;
|
|
}
|
|
|
|
} // namespace Thread
|
|
} // namespace EA
|
|
|
|
#endif // #if defined(EA_PLATFORM_ANDROID)
|