summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2017-12-16 13:22:52 +0100
committerDavid Robillard <d@drobilla.net>2017-12-16 13:59:16 +0100
commit035c6f0650d590482a42e51263f5a898c40454a3 (patch)
tree2df08850555c77fa97c4cb18e3e3f23a9fd48353
parent4a994d87467531cd19f4c9fe2eb35e5405bb6934 (diff)
downloadraul-035c6f0650d590482a42e51263f5a898c40454a3.tar.gz
raul-035c6f0650d590482a42e51263f5a898c40454a3.tar.bz2
raul-035c6f0650d590482a42e51263f5a898c40454a3.zip
Clean up DoubleBuffer
-rw-r--r--raul/DoubleBuffer.hpp48
-rw-r--r--test/double_buffer_test.cpp7
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 <atomic>
+#include <utility>
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<T*> _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> _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<int> 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;