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
00036 template<typename T>
00037 class DoubleBuffer {
00038 public:
00039
00040 inline DoubleBuffer(T val)
00041 : _state(RAUL_DB_READ_WRITE)
00042 {
00043 _vals[0] = val;
00044 _read_val = &_vals[0];
00045 }
00046
00047 inline DoubleBuffer(const DoubleBuffer& copy)
00048 : _state(RAUL_DB_READ_WRITE)
00049 {
00050 T val = copy.get();
00051 _vals[0] = val;
00052 _read_val = &_vals[0];
00053 }
00054
00055 inline T& get() const {
00056 return *_read_val.get();
00057 }
00058
00059 inline bool set(T new_val) {
00060 if (_state.compare_and_exchange(RAUL_DB_READ_WRITE, RAUL_DB_READ_LOCK)) {
00061
00062
00063 _vals[1] = new_val;
00064 _read_val = &_vals[1];
00065 _state = RAUL_DB_WRITE_READ;
00066 return true;
00067
00068
00069
00070
00071 } else if (_state.compare_and_exchange(RAUL_DB_WRITE_READ, RAUL_DB_LOCK_READ)) {
00072
00073
00074 _vals[0] = new_val;
00075 _read_val = &_vals[0];
00076 _state = RAUL_DB_READ_WRITE;
00077 return true;
00078
00079 } else {
00080
00081 return false;
00082
00083 }
00084 }
00085
00086 private:
00087 enum States {
00088
00089 RAUL_DB_READ_WRITE = 0,
00090 RAUL_DB_READ_LOCK,
00091 RAUL_DB_WRITE_READ,
00092 RAUL_DB_LOCK_READ
00093 };
00094
00095 AtomicInt _state;
00096 AtomicPtr<T> _read_val;
00097 T _vals[2];
00098 };
00099
00100
00101 }
00102
00103 #endif // RAUL_DOUBLE_BUFFER_HPP