diff options
Diffstat (limited to 'asl/synchronization/atomic.hpp')
-rw-r--r-- | asl/synchronization/atomic.hpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/asl/synchronization/atomic.hpp b/asl/synchronization/atomic.hpp new file mode 100644 index 0000000..528a6fa --- /dev/null +++ b/asl/synchronization/atomic.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "asl/base/meta.hpp" + +namespace asl +{ + +enum class memory_order : int // NOLINT(*-enum-size) +{ + relaxed = __ATOMIC_RELAXED, + acquire = __ATOMIC_ACQUIRE, + release = __ATOMIC_RELEASE, + acq_rel = __ATOMIC_ACQ_REL, + seq_cst = __ATOMIC_SEQ_CST, +}; + +template<typename T> struct atomic { T m_value{}; }; + +inline void atomic_fence(memory_order order) +{ + __atomic_thread_fence(static_cast<int>(order)); +} + +template<is_integer T> +inline void atomic_store(atomic<T>* a, T value, memory_order order = memory_order::relaxed) +{ + __atomic_store(&a->m_value, &value, static_cast<int>(order)); +} + +template<is_integer T> +inline T atomic_load(atomic<T>* a, memory_order order = memory_order::relaxed) +{ + T value; + __atomic_load(&a->m_value, &value, static_cast<int>(order)); + return value; +} + +template<typename T> +inline T atomic_fetch_increment(atomic<T>* a, memory_order order = memory_order::relaxed) +{ + return __atomic_fetch_add(&a->m_value, 1, static_cast<int>(order)); +} + +template<typename T> +inline T atomic_fetch_decrement(atomic<T>* a, memory_order order = memory_order::relaxed) +{ + return __atomic_fetch_sub(&a->m_value, 1, static_cast<int>(order)); +} + +} // namespace asl + |