00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef RAUL_DOUBLE_BUFFER_HPP
00019 #define RAUL_DOUBLE_BUFFER_HPP
00020
00021 #include <raul/AtomicInt.hpp>
00022 #include <raul/AtomicPtr.hpp>
00023
00024 namespace Raul {
00025
00035 template<typename T>
00036 class DoubleBuffer {
00037 public:
00038
00039 inline DoubleBuffer(T val)
00040 : _state(RAUL_DB_READ_WRITE)
00041 {
00042 _vals[0] = val;
00043 _read_val = &_vals[0];
00044 }
00045
00046 inline DoubleBuffer(const DoubleBuffer& copy)
00047 : _state(RAUL_DB_READ_WRITE)
00048 {
00049 T val = copy.get();
00050 _vals[0] = val;
00051 _read_val = &_vals[0];
00052 }
00053
00054 inline T& get() const {
00055 return *_read_val.get();
00056 }
00057
00058 inline bool set(T new_val) {
00059 if (_state.compare_and_exchange(RAUL_DB_READ_WRITE, RAUL_DB_READ_LOCK)) {
00060
00061
00062 _vals[1] = new_val;
00063 _read_val = &_vals[1];
00064 _state = RAUL_DB_WRITE_READ;
00065 return true;
00066
00067
00068
00069
00070 } else if (_state.compare_and_exchange(RAUL_DB_WRITE_READ, RAUL_DB_LOCK_READ)) {
00071
00072
00073 _vals[0] = new_val;
00074 _read_val = &_vals[0];
00075 _state = RAUL_DB_READ_WRITE;
00076 return true;
00077
00078 } else {
00079
00080 return false;
00081
00082 }
00083 }
00084
00085 private:
00086 enum States {
00087
00088 RAUL_DB_READ_WRITE = 0,
00089 RAUL_DB_READ_LOCK,
00090 RAUL_DB_WRITE_READ,
00091 RAUL_DB_LOCK_READ
00092 };
00093
00094 AtomicInt _state;
00095 AtomicPtr<T> _read_val;
00096 T _vals[2];
00097 };
00098
00099
00100 }
00101
00102 #endif // RAUL_DOUBLE_BUFFER_HPP