diff options
Diffstat (limited to 'asl/synchronization')
-rw-r--r-- | asl/synchronization/BUILD.bazel | 10 | ||||
-rw-r--r-- | asl/synchronization/atomic.hpp | 51 |
2 files changed, 61 insertions, 0 deletions
diff --git a/asl/synchronization/BUILD.bazel b/asl/synchronization/BUILD.bazel new file mode 100644 index 0000000..29e0a62 --- /dev/null +++ b/asl/synchronization/BUILD.bazel @@ -0,0 +1,10 @@ +cc_library( + name = "atomic", + hdrs = [ + "atomic.hpp", + ], + deps = [ + "//asl/base", + ], + visibility = ["//visibility:public"], +) 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 + |