|
@@ -13,14 +13,16 @@ namespace anki {
|
|
|
/// @addtogroup util_other
|
|
/// @addtogroup util_other
|
|
|
/// @{
|
|
/// @{
|
|
|
|
|
|
|
|
-enum class AtomicMemoryOrder
|
|
|
|
|
|
|
+using StdMemoryOrderEnumUnderlyingType = std::underlying_type_t<std::memory_order>;
|
|
|
|
|
+
|
|
|
|
|
+enum class AtomicMemoryOrder : StdMemoryOrderEnumUnderlyingType
|
|
|
{
|
|
{
|
|
|
- kRelaxed = std::memory_order_relaxed,
|
|
|
|
|
- kConsume = std::memory_order_consume,
|
|
|
|
|
- kAcquire = std::memory_order_acquire,
|
|
|
|
|
- kRelease = std::memory_order_release,
|
|
|
|
|
- kAcqRel = std::memory_order_acq_rel,
|
|
|
|
|
- kSeqCst = std::memory_order_seq_cst
|
|
|
|
|
|
|
+ kRelaxed = StdMemoryOrderEnumUnderlyingType(std::memory_order_relaxed),
|
|
|
|
|
+ kConsume = StdMemoryOrderEnumUnderlyingType(std::memory_order_consume),
|
|
|
|
|
+ kAcquire = StdMemoryOrderEnumUnderlyingType(std::memory_order_acquire),
|
|
|
|
|
+ kRelease = StdMemoryOrderEnumUnderlyingType(std::memory_order_release),
|
|
|
|
|
+ kAcqRel = StdMemoryOrderEnumUnderlyingType(std::memory_order_acq_rel),
|
|
|
|
|
+ kSeqCst = StdMemoryOrderEnumUnderlyingType(std::memory_order_seq_cst)
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
/// Atomic template. At the moment it doesn't work well with pointers.
|
|
/// Atomic template. At the moment it doesn't work well with pointers.
|
|
@@ -60,41 +62,41 @@ public:
|
|
|
/// Get the value of the atomic.
|
|
/// Get the value of the atomic.
|
|
|
Value load(AtomicMemoryOrder memOrd = kDefaultMemoryOrder) const
|
|
Value load(AtomicMemoryOrder memOrd = kDefaultMemoryOrder) const
|
|
|
{
|
|
{
|
|
|
- return m_att.load(static_cast<std::memory_order>(memOrd));
|
|
|
|
|
|
|
+ return m_att.load(std::memory_order(memOrd));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Store
|
|
/// Store
|
|
|
void store(Value a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
void store(Value a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
|
{
|
|
{
|
|
|
- m_att.store(a, static_cast<std::memory_order>(memOrd));
|
|
|
|
|
|
|
+ m_att.store(a, std::memory_order(memOrd));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Fetch and add.
|
|
/// Fetch and add.
|
|
|
template<typename Y>
|
|
template<typename Y>
|
|
|
Value fetchAdd(Y a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
Value fetchAdd(Y a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
|
{
|
|
{
|
|
|
- return m_att.fetch_add(a, static_cast<std::memory_order>(memOrd));
|
|
|
|
|
|
|
+ return m_att.fetch_add(a, std::memory_order(memOrd));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Fetch and subtract.
|
|
/// Fetch and subtract.
|
|
|
template<typename Y>
|
|
template<typename Y>
|
|
|
Value fetchSub(Y a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
Value fetchSub(Y a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
|
{
|
|
{
|
|
|
- return m_att.fetch_sub(a, static_cast<std::memory_order>(memOrd));
|
|
|
|
|
|
|
+ return m_att.fetch_sub(a, std::memory_order(memOrd));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Fetch and do bitwise or.
|
|
/// Fetch and do bitwise or.
|
|
|
template<typename Y>
|
|
template<typename Y>
|
|
|
Value fetchOr(Y a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
Value fetchOr(Y a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
|
{
|
|
{
|
|
|
- return m_att.fetch_or(a, static_cast<std::memory_order>(memOrd));
|
|
|
|
|
|
|
+ return m_att.fetch_or(a, std::memory_order(memOrd));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Fetch and do bitwise and.
|
|
/// Fetch and do bitwise and.
|
|
|
template<typename Y>
|
|
template<typename Y>
|
|
|
Value fetchAnd(Y a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
Value fetchAnd(Y a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
|
{
|
|
{
|
|
|
- return m_att.fetch_and(a, static_cast<std::memory_order>(memOrd));
|
|
|
|
|
|
|
+ return m_att.fetch_and(a, std::memory_order(memOrd));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// @code
|
|
/// @code
|
|
@@ -109,14 +111,14 @@ public:
|
|
|
Bool compareExchange(Value& expected, Value desired, AtomicMemoryOrder successMemOrd = kDefaultMemoryOrder,
|
|
Bool compareExchange(Value& expected, Value desired, AtomicMemoryOrder successMemOrd = kDefaultMemoryOrder,
|
|
|
AtomicMemoryOrder failMemOrd = kDefaultMemoryOrder)
|
|
AtomicMemoryOrder failMemOrd = kDefaultMemoryOrder)
|
|
|
{
|
|
{
|
|
|
- return m_att.compare_exchange_weak(expected, desired, static_cast<std::memory_order>(successMemOrd),
|
|
|
|
|
- static_cast<std::memory_order>(failMemOrd));
|
|
|
|
|
|
|
+ return m_att.compare_exchange_weak(expected, desired, std::memory_order(successMemOrd),
|
|
|
|
|
+ std::memory_order(failMemOrd));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Set @a a to the atomic and return the previous value.
|
|
/// Set @a a to the atomic and return the previous value.
|
|
|
Value exchange(Value a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
Value exchange(Value a, AtomicMemoryOrder memOrd = kDefaultMemoryOrder)
|
|
|
{
|
|
{
|
|
|
- return m_att.exchange(a, static_cast<std::memory_order>(memOrd));
|
|
|
|
|
|
|
+ return m_att.exchange(a, std::memory_order(memOrd));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Store the minimum using compare-and-swap.
|
|
/// Store the minimum using compare-and-swap.
|