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