aboutsummaryrefslogtreecommitdiff
path: root/build2/types.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'build2/types.hxx')
-rw-r--r--build2/types.hxx35
1 files changed, 35 insertions, 0 deletions
diff --git a/build2/types.hxx b/build2/types.hxx
index cf95a9d..2f07029 100644
--- a/build2/types.hxx
+++ b/build2/types.hxx
@@ -98,6 +98,41 @@ namespace build2
using atomic_count = atomic<size_t>; // Matches scheduler::atomic_count.
+ // Like std::atomic except implicit conversion and assignment use relaxed
+ // memory ordering.
+ //
+ template <typename T>
+ struct relaxed_atomic: atomic<T>
+ {
+ using atomic<T>::atomic; // Delegate.
+ relaxed_atomic (const relaxed_atomic& a) noexcept
+ : atomic<T> (a.load (memory_order_relaxed)) {}
+
+ operator T () const noexcept {return this->load (memory_order_relaxed);}
+
+ T operator= (T v) noexcept {
+ this->store (v, memory_order_relaxed); return v;}
+ T operator= (const relaxed_atomic& a) noexcept {
+ return *this = a.load (memory_order_relaxed);}
+ };
+
+ template <typename T>
+ struct relaxed_atomic<T*>: atomic<T*>
+ {
+ using atomic<T*>::atomic; // Delegate.
+ relaxed_atomic (const relaxed_atomic& a) noexcept
+ : atomic<T*> (a.load (memory_order_relaxed)) {}
+
+ operator T* () const noexcept {return this->load (memory_order_relaxed);}
+ T& operator* () const noexcept {return *this->load (memory_order_relaxed);}
+ T* operator-> () const noexcept {return this->load (memory_order_relaxed);}
+
+ T* operator= (T* v) noexcept {
+ this->store (v, memory_order_relaxed); return v;}
+ T* operator= (const relaxed_atomic& a) noexcept {
+ return *this = a.load (memory_order_relaxed);}
+ };
+
using std::mutex;
using mlock = std::unique_lock<mutex>;