aboutsummaryrefslogtreecommitdiff
path: root/build2/types.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-12-05 17:34:00 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-12-05 17:34:00 +0200
commitfebfafcf7f0e4d1cbe878e7dfffd9c9b78036aed (patch)
tree03d9fffbc37f7a9ecf213155bfdf9d9839dfb289 /build2/types.hxx
parente5e975934fd25811a79f3fc40ba7f94b7d1cb0b4 (diff)
Add support for first-access value typification during non-load phases
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>;