aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-04-15 15:07:14 -0700
committerChris Robinson <[email protected]>2021-04-15 15:17:04 -0700
commit29cf7ebb752e00e116391a1df7a3ed0f49fdd193 (patch)
tree76b90d55cbcbae2bb3c04fc95aaef83161263ecc /common
parent92148a3a044389863601b8b907bcfc69ff77b869 (diff)
Make an inverted atomic flag type and use it
The inverted atomic flag replaces test_and_set+clear with test_and_clear+set, essentially inverting the flag status. This makes more logical sense for flagging dirty state, which is less confusing than flagging clean state. The one caveat is ATOMIC_FLAG_INIT (or default construction in C++20) initializes the state to true rather than false.
Diffstat (limited to 'common')
-rw-r--r--common/atomic.h21
1 files changed, 21 insertions, 0 deletions
diff --git a/common/atomic.h b/common/atomic.h
index 5e9b04c6..d70382ce 100644
--- a/common/atomic.h
+++ b/common/atomic.h
@@ -2,8 +2,29 @@
#define AL_ATOMIC_H
#include <atomic>
+#include <utility>
+namespace al {
+
+struct atomic_invflag : protected std::atomic_flag {
+ atomic_invflag() noexcept = default;
+ template<typename T>
+ atomic_invflag(T&& arg) noexcept : std::atomic_flag{std::forward<T>(arg)} { }
+
+ inline bool test_and_clear(std::memory_order m=std::memory_order_seq_cst) noexcept
+ { return !test_and_set(m); }
+ inline bool test_and_clear(std::memory_order m=std::memory_order_seq_cst) volatile noexcept
+ { return !test_and_set(m); }
+
+ inline void set(std::memory_order m=std::memory_order_seq_cst) noexcept
+ { clear(m); }
+ inline void set(std::memory_order m=std::memory_order_seq_cst) volatile noexcept
+ { clear(m); }
+};
+
+} // namespace al
+
using RefCount = std::atomic<unsigned int>;
inline void InitRef(RefCount &ref, unsigned int value)