diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-12-05 17:34:00 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-12-05 17:34:00 +0200 |
commit | febfafcf7f0e4d1cbe878e7dfffd9c9b78036aed (patch) | |
tree | 03d9fffbc37f7a9ecf213155bfdf9d9839dfb289 /build2/types.hxx | |
parent | e5e975934fd25811a79f3fc40ba7f94b7d1cb0b4 (diff) |
Add support for first-access value typification during non-load phases
Diffstat (limited to 'build2/types.hxx')
-rw-r--r-- | build2/types.hxx | 35 |
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>; |