mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 03:25:16 +00:00
Atomic intrinsics refactoring
This commit is contained in:
parent
b0da8319b7
commit
09fbda603c
3 changed files with 137 additions and 18 deletions
|
@ -303,6 +303,29 @@ union u128
|
|||
}
|
||||
};
|
||||
|
||||
#ifndef InterlockedCompareExchange
|
||||
static __forceinline u128 InterlockedCompareExchange(volatile u128* dest, u128 exch, u128 comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
auto res = __sync_val_compare_and_swap((volatile __int128_t*)dest, (__int128_t&)comp, (__int128_t&)exch);
|
||||
return (u128&)res;
|
||||
#else
|
||||
u128 cmp = comp;
|
||||
_InterlockedCompareExchange128((volatile long long*)dest, exch._u64[1], exch._u64[0], (long long*)&cmp);
|
||||
return cmp;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static __forceinline bool InterlockedCompareExchangeTest(volatile u128* dest, u128 exch, u128 comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_bool_compare_and_swap((volatile __int128_t*)dest, (__int128_t&)comp, (__int128_t&)exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange128((volatile long long*)dest, exch._u64[1], exch._u64[0], (long long*)&comp) != 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define re16(val) _byteswap_ushort(val)
|
||||
#define re32(val) _byteswap_ulong(val)
|
||||
#define re64(val) _byteswap_uint64(val)
|
||||
|
|
130
Utilities/GNU.h
130
Utilities/GNU.h
|
@ -46,23 +46,6 @@ void strcpy_trunc(char(&dst)[size], const char(&src)[rsize])
|
|||
#define _byteswap_uint64(x) __builtin_bswap64(x)
|
||||
#define INFINITE 0xFFFFFFFF
|
||||
#define _CRT_ALIGN(x) __attribute__((aligned(x)))
|
||||
#define InterlockedCompareExchange(ptr,new_val,old_val) __sync_val_compare_and_swap(ptr,old_val,new_val)
|
||||
#define InterlockedExchange(ptr, value) __sync_lock_test_and_set(ptr, value)
|
||||
#define InterlockedOr(ptr, value) __sync_fetch_and_or(ptr, value)
|
||||
#define InterlockedAnd(ptr, value) __sync_fetch_and_and(ptr, value)
|
||||
#define InterlockedXor(ptr, value) __sync_fetch_and_xor(ptr, value)
|
||||
|
||||
//inline int64_t InterlockedOr64(volatile int64_t *dest, int64_t val)
|
||||
//{
|
||||
// int64_t olderval;
|
||||
// int64_t oldval = *dest;
|
||||
// do
|
||||
// {
|
||||
// olderval = oldval;
|
||||
// oldval = __sync_val_compare_and_swap(dest, olderval | val, olderval);
|
||||
// } while (olderval != oldval);
|
||||
// return oldval;
|
||||
//}
|
||||
|
||||
inline uint64_t __umulh(uint64_t a, uint64_t b)
|
||||
{
|
||||
|
@ -99,95 +82,208 @@ int clock_gettime(int foo, struct timespec *ts);
|
|||
#ifndef InterlockedCompareExchange
|
||||
static __forceinline uint8_t InterlockedCompareExchange(volatile uint8_t* dest, uint8_t exch, uint8_t comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_val_compare_and_swap(dest, comp, exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange8((volatile char*)dest, exch, comp);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint16_t InterlockedCompareExchange(volatile uint16_t* dest, uint16_t exch, uint16_t comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_val_compare_and_swap(dest, comp, exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange16((volatile short*)dest, exch, comp);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint32_t InterlockedCompareExchange(volatile uint32_t* dest, uint32_t exch, uint32_t comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_val_compare_and_swap(dest, comp, exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange((volatile long*)dest, exch, comp);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint64_t InterlockedCompareExchange(volatile uint64_t* dest, uint64_t exch, uint64_t comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_val_compare_and_swap(dest, comp, exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange64((volatile long long*)dest, exch, comp);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static __forceinline bool InterlockedCompareExchangeTest(volatile uint8_t* dest, uint8_t exch, uint8_t comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_bool_compare_and_swap(dest, comp, exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange8((volatile char*)dest, exch, comp) == comp;
|
||||
#endif
|
||||
}
|
||||
static __forceinline bool InterlockedCompareExchangeTest(volatile uint16_t* dest, uint16_t exch, uint16_t comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_bool_compare_and_swap(dest, comp, exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange16((volatile short*)dest, exch, comp) == comp;
|
||||
#endif
|
||||
}
|
||||
static __forceinline bool InterlockedCompareExchangeTest(volatile uint32_t* dest, uint32_t exch, uint32_t comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_bool_compare_and_swap(dest, comp, exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange((volatile long*)dest, exch, comp) == comp;
|
||||
#endif
|
||||
}
|
||||
static __forceinline bool InterlockedCompareExchangeTest(volatile uint64_t* dest, uint64_t exch, uint64_t comp)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_bool_compare_and_swap(dest, comp, exch);
|
||||
#else
|
||||
return _InterlockedCompareExchange64((volatile long long*)dest, exch, comp) == comp;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef InterlockedExchange
|
||||
static __forceinline uint8_t InterlockedExchange(volatile uint8_t* dest, uint8_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_lock_test_and_set(dest, value);
|
||||
#else
|
||||
return _InterlockedExchange8((volatile char*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint16_t InterlockedExchange(volatile uint16_t* dest, uint16_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_lock_test_and_set(dest, value);
|
||||
#else
|
||||
return _InterlockedExchange16((volatile short*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint32_t InterlockedExchange(volatile uint32_t* dest, uint32_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_lock_test_and_set(dest, value);
|
||||
#else
|
||||
return _InterlockedExchange((volatile long*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint64_t InterlockedExchange(volatile uint64_t* dest, uint64_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_lock_test_and_set(dest, value);
|
||||
#else
|
||||
return _InterlockedExchange64((volatile long long*)dest, value);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef InterlockedOr
|
||||
static __forceinline uint8_t InterlockedOr(volatile uint8_t* dest, uint8_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_or(dest, value);
|
||||
#else
|
||||
return _InterlockedOr8((volatile char*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint16_t InterlockedOr(volatile uint16_t* dest, uint16_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_or(dest, value);
|
||||
#else
|
||||
return _InterlockedOr16((volatile short*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint32_t InterlockedOr(volatile uint32_t* dest, uint32_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_or(dest, value);
|
||||
#else
|
||||
return _InterlockedOr((volatile long*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint64_t InterlockedOr(volatile uint64_t* dest, uint64_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_or(dest, value);
|
||||
#else
|
||||
return _InterlockedOr64((volatile long long*)dest, value);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef InterlockedAnd
|
||||
static __forceinline uint8_t InterlockedAnd(volatile uint8_t* dest, uint8_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_and(dest, value);
|
||||
#else
|
||||
return _InterlockedAnd8((volatile char*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint16_t InterlockedAnd(volatile uint16_t* dest, uint16_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_and(dest, value);
|
||||
#else
|
||||
return _InterlockedAnd16((volatile short*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint32_t InterlockedAnd(volatile uint32_t* dest, uint32_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_and(dest, value);
|
||||
#else
|
||||
return _InterlockedAnd((volatile long*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint64_t InterlockedAnd(volatile uint64_t* dest, uint64_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_and(dest, value);
|
||||
#else
|
||||
return _InterlockedAnd64((volatile long long*)dest, value);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef InterlockedXor
|
||||
static __forceinline uint8_t InterlockedXor(volatile uint8_t* dest, uint8_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_xor(dest, value);
|
||||
#else
|
||||
return _InterlockedXor8((volatile char*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint16_t InterlockedXor(volatile uint16_t* dest, uint16_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_xor(dest, value);
|
||||
#else
|
||||
return _InterlockedXor16((volatile short*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint32_t InterlockedXor(volatile uint32_t* dest, uint32_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_xor(dest, value);
|
||||
#else
|
||||
return _InterlockedXor((volatile long*)dest, value);
|
||||
#endif
|
||||
}
|
||||
static __forceinline uint64_t InterlockedXor(volatile uint64_t* dest, uint64_t value)
|
||||
{
|
||||
#if defined(__GNUG__)
|
||||
return __sync_fetch_and_xor(dest, value);
|
||||
#else
|
||||
return _InterlockedXor64((volatile long long*)dest, value);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
// atomically compare data with cmp, replace with exch if equal, return true if data was replaced
|
||||
__forceinline bool compare_and_swap_test(const T& cmp, const T& exch) volatile
|
||||
{
|
||||
return InterlockedCompareExchange(&data, (atomic_type&)(exch), (atomic_type&)(cmp)) == (atomic_type&)(cmp);
|
||||
return InterlockedCompareExchangeTest(&data, (atomic_type&)(exch), (atomic_type&)(cmp));
|
||||
}
|
||||
|
||||
// read data with memory barrier
|
||||
|
|
Loading…
Add table
Reference in a new issue