[+] AuAtomicTestAndSet
This commit is contained in:
parent
b29be7b2d5
commit
2c55b722d6
@ -11,7 +11,7 @@ template<typename T>
|
||||
struct AuAtomicUtils
|
||||
{
|
||||
/**
|
||||
* @brief Sets bit offset in in
|
||||
* @brief Generic bitwise (1 << offset)
|
||||
* @return original value
|
||||
*/
|
||||
static T Set(T *in, AuUInt8 offset);
|
||||
@ -29,12 +29,20 @@ struct AuAtomicUtils
|
||||
static T Sub(T *in, T minuend);
|
||||
|
||||
/**
|
||||
* @brief Generic bitwise compare exchange
|
||||
* @brief Generic compare exchange
|
||||
* @param replace replacement value for in if in matches compare
|
||||
* @param compare required reference value
|
||||
* @return original value
|
||||
*/
|
||||
static T CompareExchange(T *in, T replace, T compare);
|
||||
|
||||
/**
|
||||
* @brief { return *in & (1 << offset); in |= (1 << offset) }
|
||||
* @param in
|
||||
* @param offset Bit index
|
||||
* @return *in & (1 << offset)
|
||||
*/
|
||||
static bool TestAndSet(T *in, const AuUInt8 offset);
|
||||
};
|
||||
|
||||
#if defined(AURORA_COMPILER_MSVC)
|
||||
@ -208,6 +216,52 @@ inline auline T AuAtomicUtils<T>::Set(T *in, AuUInt8 offset)
|
||||
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
inline auline bool AuAtomicUtils<T>::TestAndSet(T *in, const AuUInt8 offset)
|
||||
{
|
||||
return AuAtomicSet<T>::Set(in, offset) & (1 << offset);
|
||||
}
|
||||
|
||||
#if defined(AURORA_COMPILER_MSVC) && (defined(AURORA_ARCH_X64) || defined(AURORA_ARCH_X86))
|
||||
|
||||
template<>
|
||||
inline auline bool AuAtomicUtils<unsigned long>::TestAndSet(unsigned long *in, const AuUInt8 offset)
|
||||
{
|
||||
return _interlockedbittestandset(reinterpret_cast<volatile long *>(in), offset);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline auline bool AuAtomicUtils<long>::TestAndSet(long *in, const AuUInt8 offset)
|
||||
{
|
||||
return _interlockedbittestandset(reinterpret_cast<volatile long *>(in), offset);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline auline bool AuAtomicUtils<AuUInt32>::TestAndSet(AuUInt32 *in, const AuUInt8 offset)
|
||||
{
|
||||
return _interlockedbittestandset(reinterpret_cast<volatile long *>(in), offset);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline auline bool AuAtomicUtils<AuInt32>::TestAndSet(AuInt32 *in, const AuUInt8 offset)
|
||||
{
|
||||
return _interlockedbittestandset(reinterpret_cast<volatile long *>(in), offset);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline auline bool AuAtomicUtils<AuUInt64>::TestAndSet(AuUInt64 *in, const AuUInt8 offset)
|
||||
{
|
||||
return _interlockedbittestandset64(reinterpret_cast<volatile long long *>(in), offset);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline auline bool AuAtomicUtils<AuInt64>::TestAndSet(AuInt64 *in, const AuUInt8 offset)
|
||||
{
|
||||
return _interlockedbittestandset64(reinterpret_cast<volatile long long *>(in), offset);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
auline
|
||||
T AuAtomicSet(T *in, AuUInt8 offset)
|
||||
@ -235,3 +289,10 @@ T AuAtomicCompareExchange(T *in, T replace, T compare)
|
||||
{
|
||||
return AuAtomicUtils<T>::CompareExchange(in, replace, compare);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auline
|
||||
bool AuAtomicTestAndSet(T *in, AuUInt8 offset)
|
||||
{
|
||||
return AuAtomicUtils<T>::TestAndSet(in, offset);
|
||||
}
|
@ -33,6 +33,6 @@ namespace Aurora::Threading::Primitives
|
||||
const bool permitMultipleTriggers_{};
|
||||
ConditionMutexUnique_t mutex_;
|
||||
ConditionVariableUnique_t condition_;
|
||||
std::atomic<bool> triggered_;
|
||||
bool triggered_;
|
||||
};
|
||||
}
|
@ -36,11 +36,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool SpinLock::TryLock()
|
||||
{
|
||||
#if defined(_AU_HAS_ATOMIC_INTRINS)
|
||||
return _interlockedbittestandset(&value_, 0) == 0;
|
||||
#else
|
||||
return value_.fetch_or(1);
|
||||
#endif
|
||||
return AuAtomicTestAndSet(&this->value_, 0) == 0;
|
||||
}
|
||||
|
||||
bool SpinLock::HasLockImplementation()
|
||||
@ -58,7 +54,7 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
if (timeout == 0)
|
||||
{
|
||||
while (AuAtomicSet(&this->value_, 0))
|
||||
while (AuAtomicTestAndSet(&this->value_, 0))
|
||||
{
|
||||
long count = 0;
|
||||
while (value_)
|
||||
@ -72,7 +68,7 @@ namespace Aurora::Threading::Primitives
|
||||
AuUInt64 startTime = AuTime::CurrentInternalClockMS();
|
||||
AuUInt64 endTime = startTime + timeout;
|
||||
|
||||
while (AuAtomicSet(&this->value_, 0))
|
||||
while (AuAtomicTestAndSet(&this->value_, 0))
|
||||
{
|
||||
long count = 0;
|
||||
while (value_)
|
||||
|
Loading…
Reference in New Issue
Block a user