Add an Atomic class
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2022-12-16 21:15:22 +01:00
parent b316e3b3b7
commit a16f357ab9
Signed by: apio
GPG Key ID: B8A7D06E42258954

108
luna/include/luna/Atomic.h Normal file
View File

@ -0,0 +1,108 @@
#pragma once
enum class MemoryOrder
{
Relaxed = __ATOMIC_RELAXED,
Consume = __ATOMIC_CONSUME,
Acquire = __ATOMIC_ACQUIRE,
Release = __ATOMIC_RELEASE,
AcqRel = __ATOMIC_ACQ_REL,
SeqCst = __ATOMIC_SEQ_CST,
};
template <typename T> class Atomic
{
public:
Atomic() : m_value()
{
}
Atomic(T value) : m_value(value)
{
}
T operator=(T other)
{
store(other);
return other;
}
T load(MemoryOrder order = MemoryOrder::SeqCst) const
{
return __atomic_load_n(&m_value, (int)order);
}
operator T() const
{
return load();
}
void store(T value, MemoryOrder order = MemoryOrder::SeqCst)
{
return __atomic_store_n(&m_value, value, (int)order);
}
T exchange(T value, MemoryOrder order = MemoryOrder::SeqCst)
{
return __atomic_exchange_n(&m_value, value, (int)order);
}
bool compare_exchange_strong(T& expected, T desired, MemoryOrder success, MemoryOrder failure)
{
return __atomic_compare_exchange_n(&m_value, &expected, desired, false, (int)success, (int)failure);
}
bool compare_exchange_strong(T& expected, T desired, MemoryOrder order = MemoryOrder::SeqCst)
{
MemoryOrder failure = (order == MemoryOrder::AcqRel) ? MemoryOrder::Acquire
: (order == MemoryOrder::Release) ? MemoryOrder::Relaxed
: order;
return __atomic_compare_exchange_n(&m_value, &expected, desired, false, (int)order, (int)failure);
}
bool compare_exchange_weak(T& expected, T desired, MemoryOrder success, MemoryOrder failure)
{
return __atomic_compare_exchange_n(&m_value, &expected, desired, true, (int)success, (int)failure);
}
bool compare_exchange_weak(T& expected, T desired, MemoryOrder order = MemoryOrder::SeqCst)
{
MemoryOrder failure = (order == MemoryOrder::AcqRel) ? MemoryOrder::Acquire
: (order == MemoryOrder::Release) ? MemoryOrder::Relaxed
: order;
return __atomic_compare_exchange_n(&m_value, &expected, desired, true, (int)order, (int)failure);
}
T fetch_add(T other, MemoryOrder order = MemoryOrder::SeqCst)
{
return __atomic_fetch_add(&m_value, other, (int)order);
}
T fetch_sub(T other, MemoryOrder order = MemoryOrder::SeqCst)
{
return __atomic_fetch_sub(&m_value, other, (int)order);
}
T operator++()
{
return fetch_add(1) + 1;
}
T operator++(int)
{
return fetch_add(1);
}
T operator--()
{
return fetch_sub(1) - 1;
}
T operator--(int)
{
return fetch_sub(1);
}
private:
T m_value;
};