[+] AuAtomicStore
[+] AuAtomicLoad [+] AuAtomicClearU8Lock
This commit is contained in:
parent
d7d2a576b2
commit
2e93ca7e32
@ -7,6 +7,10 @@
|
||||
***/
|
||||
#pragma once
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct AuAtomicUtils
|
||||
{
|
||||
@ -64,6 +68,15 @@ struct AuAtomicUtils
|
||||
* @warning T is bound by platform and compiler constraints
|
||||
*/
|
||||
static bool TestAndSet(T *in, const AuUInt8 offset);
|
||||
|
||||
//
|
||||
static T Load(T *in);
|
||||
|
||||
//
|
||||
static void Store(T *in, T value);
|
||||
|
||||
//
|
||||
static void ClearU8Lock(T *in);
|
||||
};
|
||||
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
@ -327,6 +340,117 @@ inline auline T AuAtomicUtils<T>::And(T *in, T value)
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AURORA_COMPILER_CLANG)
|
||||
#define ATOMIC_PREFIX_HAX(name) __c11_ ## name
|
||||
#else
|
||||
#define ATOMIC_PREFIX_HAX(name) __ ## name ## _explicit
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline auline T AuAtomicUtils<T>::Load(T *in)
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC) && (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
|
||||
::_ReadWriteBarrier();
|
||||
return *in;
|
||||
#elif defined(AURORA_COMPILER_MSVC)
|
||||
return *in;
|
||||
#else
|
||||
if constexpr (AuIsSame_v<AuUInt8, T>)
|
||||
{
|
||||
return ATOMIC_PREFIX_HAX(atomic_load)((atomic_uint_fast8_t *)in, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuInt8, T>)
|
||||
{
|
||||
return ATOMIC_PREFIX_HAX(atomic_load)((atomic_int_fast8_t *)in, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuUInt16, T>)
|
||||
{
|
||||
return ATOMIC_PREFIX_HAX(atomic_load)((atomic_uint_fast16_t *)in, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuInt16, T>)
|
||||
{
|
||||
return ATOMIC_PREFIX_HAX(atomic_load)((atomic_int_fast16_t *)in, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuUInt32, T>)
|
||||
{
|
||||
return ATOMIC_PREFIX_HAX(atomic_load)((atomic_uint_fast32_t *)in, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuInt32, T>)
|
||||
{
|
||||
return ATOMIC_PREFIX_HAX(atomic_load)((atomic_int_fast32_t *)in, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(AuIsVoid_v<T>, "T");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline auline void AuAtomicUtils<T>::Store(T *in, T val)
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC) && (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
|
||||
*in = val;
|
||||
::_ReadWriteBarrier();
|
||||
#elif defined(AURORA_COMPILER_MSVC)
|
||||
*in = val;
|
||||
#else
|
||||
if constexpr (AuIsSame_v<AuUInt8, T>)
|
||||
{
|
||||
ATOMIC_PREFIX_HAX(atomic_store)((atomic_uint_fast8_t *)in, val, __ATOMIC_RELEASE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuInt8, T>)
|
||||
{
|
||||
ATOMIC_PREFIX_HAX(atomic_store)((atomic_int_fast8_t *)in, val, __ATOMIC_RELEASE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuUInt16, T>)
|
||||
{
|
||||
ATOMIC_PREFIX_HAX(atomic_store)((atomic_uint_fast16_t *)in, val, __ATOMIC_RELEASE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuInt16, T>)
|
||||
{
|
||||
ATOMIC_PREFIX_HAX(atomic_store)((atomic_int_fast16_t *)in, val, __ATOMIC_RELEASE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuUInt32, T>)
|
||||
{
|
||||
ATOMIC_PREFIX_HAX(atomic_store)((atomic_uint_fast32_t *)in, val, __ATOMIC_RELEASE);
|
||||
}
|
||||
else if constexpr (AuIsSame_v<AuInt32, T>)
|
||||
{
|
||||
ATOMIC_PREFIX_HAX(atomic_store)((atomic_int_fast32_t *)in, val, __ATOMIC_RELEASE);
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert(AuIsVoid_v<T>, "T");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
inline auline
|
||||
void AuAtomicUtils<AuUInt8>::ClearU8Lock(AuUInt8 *in)
|
||||
{
|
||||
#if defined(AURORA_COMPILER_MSVC) && (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
|
||||
*in = 0;
|
||||
::_ReadWriteBarrier();
|
||||
#elif defined(AURORA_COMPILER_MSVC)
|
||||
InterlockedAndRelease((volatile LONG *)in, ~0xFF);
|
||||
#else
|
||||
ATOMIC_PREFIX_HAX(atomic_store)((atomic_uint_fast8_t *)in, 0, __ATOMIC_RELEASE);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
inline auline
|
||||
void AuAtomicUtils<AuUInt32>::ClearU8Lock(AuUInt32 *in)
|
||||
{
|
||||
#if defined(AU_CPU_ENDIAN_LITTLE)
|
||||
AuAtomicUtils<AuUInt8>::ClearU8Lock((AuUInt8 *)in);
|
||||
#else
|
||||
AuAtomicUtils<AuUInt8>::ClearU8Lock(((AuUInt8 *)in) + 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline auline bool AuAtomicUtils<T>::TestAndSet(T *in, const AuUInt8 offset)
|
||||
{
|
||||
@ -375,6 +499,27 @@ inline auline bool AuAtomicUtils<AuInt64>::TestAndSet(AuInt64 *in, const AuUInt8
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
auline
|
||||
void AuAtomicStore(T *in, T value)
|
||||
{
|
||||
AuAtomicUtils<T>::Store(in, value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auline
|
||||
T AuAtomicLoad(T *in)
|
||||
{
|
||||
return AuAtomicUtils<T>::Load(in);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auline
|
||||
void AuAtomicClearU8Lock(T *in)
|
||||
{
|
||||
AuAtomicUtils<T>::ClearU8Lock(in);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auline
|
||||
T AuAtomicOrSetBit(T *in, AuUInt8 offset)
|
||||
@ -446,6 +591,27 @@ bool AuAtomicTestAndSet(T *in, AuUInt8 offset)
|
||||
return AuAtomicUtils<T>::TestAndSet(in, offset);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auline
|
||||
void AuAtomicStore(volatile T *in, T value)
|
||||
{
|
||||
AuAtomicUtils<T>::Store((T *)in, value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auline
|
||||
T AuAtomicLoad(volatile T *in)
|
||||
{
|
||||
return AuAtomicUtils<T>::Load((T *)in);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auline
|
||||
void AuAtomicClearU8Lock(volatile T *in)
|
||||
{
|
||||
AuAtomicUtils<T>::ClearU8Lock((T *)in);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auline
|
||||
T AuAtomicOrSetBit(volatile T *in, AuUInt8 offset)
|
||||
|
Loading…
Reference in New Issue
Block a user