[+] AuAtomicOr

[+] AuRemoveVolatile_t
This commit is contained in:
Reece Wilson 2022-09-27 16:37:42 +01:00
parent a046eafdd5
commit 4696123268
2 changed files with 64 additions and 22 deletions

View File

@ -17,6 +17,14 @@ struct AuAtomicUtils
*/
static T Set(T *in, AuUInt8 offset);
/**
* @brief
* @param in
* @param orValue
* @return original value
*/
static T Or(T *in, T orValue);
/**
* @brief Adds addend to in
* @return updated value
@ -150,54 +158,60 @@ inline auline AuUInt16 AuAtomicUtils<AuUInt16>::Sub(AuUInt16 *in, AuUInt16 minue
#if !defined(AURORA_IS_32BIT)
template <>
inline auline AuUInt64 AuAtomicUtils<AuUInt64>::Set(AuUInt64 *in, AuUInt8 offset)
inline auline AuUInt64 AuAtomicUtils<AuUInt64>::Or(AuUInt64 *in, AuUInt64 orValue)
{
return _InterlockedOr64(reinterpret_cast<long long volatile *>(in), AuUInt64(1) << offset);
return _InterlockedOr64(reinterpret_cast<long long volatile *>(in), orValue);
}
#endif
template <>
inline auline AuUInt32 AuAtomicUtils<AuUInt32>::Set(AuUInt32 *in, AuUInt8 offset)
inline auline AuUInt32 AuAtomicUtils<AuUInt32>::Or(AuUInt32 *in, AuUInt32 orValue)
{
return _InterlockedOr(reinterpret_cast<long volatile *>(in), 1 << offset);
return _InterlockedOr(reinterpret_cast<long volatile *>(in), orValue);
}
template <>
inline auline AuUInt16 AuAtomicUtils<AuUInt16>::Set(AuUInt16 *in, AuUInt8 offset)
inline auline AuUInt16 AuAtomicUtils<AuUInt16>::Or(AuUInt16 *in, AuUInt16 orValue)
{
return _InterlockedOr16(reinterpret_cast<short volatile *>(in), 1 << offset);
return _InterlockedOr16(reinterpret_cast<short volatile *>(in), orValue);
}
#if !defined(AURORA_IS_32BIT)
template <>
inline auline AuInt64 AuAtomicUtils<AuInt64>::Set(AuInt64 *in, AuUInt8 offset)
inline auline AuInt64 AuAtomicUtils<AuInt64>::Or(AuInt64 *in, AuInt64 orValue)
{
return _InterlockedOr64(reinterpret_cast<long long volatile *>(in), AuUInt64(1) << offset);
return _InterlockedOr64(reinterpret_cast<long long volatile *>(in), orValue);
}
#endif
template <>
inline auline AuInt32 AuAtomicUtils<AuInt32>::Set(AuInt32 *in, AuUInt8 offset)
inline auline AuInt32 AuAtomicUtils<AuInt32>::Or(AuInt32 *in, AuInt32 orValue)
{
return _InterlockedOr(reinterpret_cast<long volatile *>(in), 1 << offset);
return _InterlockedOr(reinterpret_cast<long volatile *>(in), orValue);
}
template <>
inline auline long AuAtomicUtils<long>::Set(long *in, AuUInt8 offset)
inline auline long AuAtomicUtils<long>::Or(long *in, long orValue)
{
return _InterlockedOr(reinterpret_cast<long volatile *>(in), 1 << offset);
return _InterlockedOr(reinterpret_cast<long volatile *>(in), orValue);
}
template <>
inline auline unsigned long AuAtomicUtils<unsigned long>::Set(unsigned long *in, AuUInt8 offset)
inline auline unsigned long AuAtomicUtils<unsigned long>::Or(unsigned long *in, unsigned long orValue)
{
return _InterlockedOr(reinterpret_cast<long volatile *>(in), 1 << offset);
return _InterlockedOr(reinterpret_cast<long volatile *>(in), orValue);
}
template <>
inline auline AuInt16 AuAtomicUtils<AuInt16>::Set(AuInt16 *in, AuUInt8 offset)
inline auline AuInt16 AuAtomicUtils<AuInt16>::Or(AuInt16 *in, AuInt16 orValue)
{
return _InterlockedOr16(reinterpret_cast<short volatile *>(in), 1 << offset);
return _InterlockedOr16(reinterpret_cast<short volatile *>(in), orValue);
}
template <class T>
inline auline T AuAtomicUtils<T>::Set(T *in, AuUInt8 offset)
{
return AuAtomicUtils<T>::Or(in, T(1) << offset);
}
#elif defined(AURORA_COMPILER_CLANG) || defined(AURORA_COMPILER_GCC)
@ -226,6 +240,12 @@ inline auline T AuAtomicUtils<T>::Set(T *in, AuUInt8 offset)
return __sync_fetch_and_or(in, T(1) << offset);
}
template <class T>
inline auline T AuAtomicUtils<T>::Or(T *in, T value)
{
return __sync_fetch_and_or(in, value);
}
#endif
template <class T>
@ -277,36 +297,43 @@ inline auline bool AuAtomicUtils<AuInt64>::TestAndSet(AuInt64 *in, const AuUInt8
#endif
template <class T>
auline
auline
T AuAtomicSet(T *in, AuUInt8 offset)
{
return AuAtomicUtils<T>::Set(in, offset);
return AuAtomicUtils<AuRemoveVolatile_t<T>>::Set(in, offset);
}
template <class T>
auline
T AuAtomicOr(T *in, T value)
{
return AuAtomicUtils<AuRemoveVolatile_t<T>>::Or(in, value);
}
template <class T>
auline
T AuAtomicAdd(T *in, T addend)
{
return AuAtomicUtils<T>::Add(in, addend);
return AuAtomicUtils<AuRemoveVolatile_t<T>>::Add(in, addend);
}
template <class T>
auline
T AuAtomicSub(T *in, T minuend)
{
return AuAtomicUtils<T>::Sub(in, minuend);
return AuAtomicUtils<AuRemoveVolatile_t<T>>::Sub(in, minuend);
}
template <class T>
auline
T AuAtomicCompareExchange(T *in, T replace, T compare)
{
return AuAtomicUtils<T>::CompareExchange(in, replace, compare);
return AuAtomicUtils<AuRemoveVolatile_t<T>>::CompareExchange(in, replace, compare);
}
template <class T>
auline
bool AuAtomicTestAndSet(T *in, AuUInt8 offset)
{
return AuAtomicUtils<T>::TestAndSet(in, offset);
return AuAtomicUtils<AuRemoveVolatile_t<T>>::TestAndSet(in, offset);
}

View File

@ -200,6 +200,21 @@ struct AuRemoveConst<const T>
template <class T>
using AuRemoveConst_t = typename AuRemoveConst<T>::type;
template <class T>
struct AuRemoveVolatile
{
typedef T type;
};
template <class T>
struct AuRemoveVolatile<volatile T>
{
typedef T type;
};
template <class T>
using AuRemoveVolatile_t = typename AuRemoveVolatile<T>::type;
template <bool Test, class T = void>
struct AuEnableIf
{};