From 035c6f0650d590482a42e51263f5a898c40454a3 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 16 Dec 2017 13:22:52 +0100 Subject: Clean up DoubleBuffer --- raul/DoubleBuffer.hpp | 48 ++++++++++++++++++++++----------------------- test/double_buffer_test.cpp | 7 ------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/raul/DoubleBuffer.hpp b/raul/DoubleBuffer.hpp index 6a1bbd0..31bc8bf 100644 --- a/raul/DoubleBuffer.hpp +++ b/raul/DoubleBuffer.hpp @@ -18,6 +18,7 @@ #define RAUL_DOUBLE_BUFFER_HPP #include +#include namespace Raul { @@ -37,37 +38,32 @@ public: inline DoubleBuffer(T val) : _state(State::READ_WRITE) { - _vals[0] = val; - _read_val = &_vals[0]; + _vals[0] = std::move(val); } - inline DoubleBuffer(const DoubleBuffer& copy) - : _state(State::READ_WRITE) - { - _vals[0] = copy.get(); - _read_val = &_vals[0]; - } + DoubleBuffer(const DoubleBuffer&) = delete; + DoubleBuffer& operator=(const DoubleBuffer&) = delete; - inline T& get() const { - return *_read_val.load(); + inline const T& get() const { + switch (_state.load(std::memory_order_acquire)) { + case State::READ_WRITE: + case State::READ_LOCK: + return _vals[0]; + default: + return _vals[1]; + } } inline bool set(T new_val) { - State expected = State::READ_WRITE; - if (_state.compare_exchange_strong(expected, State::READ_LOCK)) { + if (transition(State::READ_WRITE, State::READ_LOCK)) { // Locked _vals[1] for writing - _vals[1] = new_val; - _read_val = &_vals[1]; - _state = State::WRITE_READ; + _vals[1] = std::move(new_val); + _state.store(State::WRITE_READ, std::memory_order_release); return true; - } - - expected = State::WRITE_READ; - if (_state.compare_exchange_strong(expected, State::LOCK_READ)) { + } else if (transition(State::WRITE_READ, State::LOCK_READ)) { // Locked _vals[0] for writing - _vals[0] = new_val; - _read_val = &_vals[0]; - _state = State::READ_WRITE; + _vals[0] = std::move(new_val); + _state.store(State::READ_WRITE, std::memory_order_release); return true; } @@ -78,11 +74,15 @@ private: enum class State { READ_WRITE, ///< Read vals[0], Write vals[1] READ_LOCK, ///< Read vals[0], Lock vals[1] - WRITE_READ, ///< Write vals[0], Write vals[1] + WRITE_READ, ///< Write vals[0], Read vals[1] LOCK_READ ///< Lock vals[0], Read vals[1] }; - std::atomic _read_val; + bool transition(State from, const State to) { + return _state.compare_exchange_strong( + from, to, std::memory_order_release, std::memory_order_relaxed); + } + std::atomic _state; T _vals[2]; }; diff --git a/test/double_buffer_test.cpp b/test/double_buffer_test.cpp index f5f7286..d4d0554 100644 --- a/test/double_buffer_test.cpp +++ b/test/double_buffer_test.cpp @@ -33,16 +33,9 @@ main(int argc, char** argv) return 1; } - DoubleBuffer db2(db); - if (db2.get() != 42) { - return 1; - } - db.set(43); if (db.get() != 43) { return 1; - } else if (db2.get() != 42) { - return 1; } return 0; -- cgit v1.2.1