cisst-saw
Loading...
Searching...
No Matches
osaTripleBuffer.h
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3
4/*
5
6 Author(s): Martin Kelly, Anton Deguet
7 Created on: 2011-03-15
8
9 (C) Copyright 2011 Johns Hopkins University (JHU), All Rights
10 Reserved.
11
12--- begin cisst license - do not edit ---
13
14This software is provided "as is" under an open source license, with
15no warranty. The complete license can be found in license.txt and
16http://www.cisst.org/cisst/license.txt.
17
18--- end cisst license ---
19
20*/
21
22#include <cisstConfig.h> // to define CISST_OS and CISST_COMPILER
23
26
48template <class _elementType>
50{
51 friend class osaTripleBufferTest;
52
53 typedef _elementType value_type;
54
55 typedef osaTripleBuffer<value_type> ThisType;
56
57 typedef value_type * pointer;
58 typedef const value_type * const_pointer;
59 typedef value_type & reference;
60 typedef const value_type & const_reference;
61
62 // did the buffer allocate memory or used existing pointers
63 bool OwnMemory;
64 pointer Memory;
65
66 // circular buffer node
67 class Node {
68 public:
69 Node(const pointer data):
70 Pointer(data) {}
71 pointer Pointer;
72 Node * Next;
73 };
74
75 typedef Node * NodePointer;
76
77 // last write node (behaves like a head in our lifo circular buffer
78 volatile NodePointer LastWriteNode;
79 volatile NodePointer WriteNode;
80 volatile NodePointer ReadNode;
81
82 // bool for debug
83 bool LastCompare;
84
85 // to make sure the ReadNode is thread safe
86 osaMutex Mutex;
87
88
89public:
92 inline osaTripleBuffer(void):
93 OwnMemory(true)
94 {
95 this->Memory = new value_type[3];
96 SetupNodes(this->Memory,
97 this->Memory + 1,
98 this->Memory + 2);
99 }
100
104 inline osaTripleBuffer(const_reference initialValue):
105 OwnMemory(true),
106 Memory(0)
107 {
108 SetupNodes(new value_type(initialValue),
109 new value_type(initialValue),
110 new value_type(initialValue));
111 }
112
117 inline osaTripleBuffer(pointer pointer1, pointer pointer2, pointer pointer3):
118 OwnMemory(false),
119 Memory(0)
120 {
121 SetupNodes(pointer1, pointer2, pointer3);
122 }
123
126 inline void SetupNodes(pointer pointer1, pointer pointer2, pointer pointer3) {
127 CMN_ASSERT(pointer1);
128 CMN_ASSERT(pointer2);
129 CMN_ASSERT(pointer3);
130 this->ReadNode = 0;
131 this->WriteNode = 0;
132 this->LastWriteNode = new Node(pointer1);
133 this->LastWriteNode->Next = new Node(pointer2);
134 this->LastWriteNode->Next->Next = new Node(pointer3);
135 this->LastWriteNode->Next->Next->Next = this->LastWriteNode;
136 }
137
141 // free memory if we own it
142 if (this->OwnMemory) {
143 // can be an array or three different pointers
144 if (this->Memory) {
145 delete[] this->Memory;
146 } else {
147 delete this->LastWriteNode->Next->Next->Pointer;
148 delete this->LastWriteNode->Next->Pointer;
149 delete this->LastWriteNode->Pointer;
150 }
151 }
152 // free nodes
153 delete this->LastWriteNode->Next->Next;
154 delete this->LastWriteNode->Next;
155 delete this->LastWriteNode;
156 }
157
160 inline void Read(reference placeHolder) {
161 this->BeginRead();
162 placeHolder = *(ReadNode->Pointer);
163 this->EndRead();
164 }
165
168 inline void Write(const_reference newValue) {
169 this->BeginWrite();
170 *(WriteNode->Pointer) = newValue;
171 this->EndWrite();
172 }
173
178 inline const_pointer GetReadPointer(void) const {
179 return this->ReadNode->Pointer;
180 }
181
186 inline pointer GetWritePointer(void) const {
187 return this->WriteNode->Pointer;
188 }
189
192 inline void BeginRead(void) {
193 Mutex.Lock(); {
194 this->ReadNode = this->LastWriteNode;
195 } Mutex.Unlock();
196 }
197
199 inline void EndRead(void) {
200 Mutex.Lock(); {
201 this->ReadNode = 0;
202 } Mutex.Unlock();
203 }
204
205
208 inline void BeginWrite(void) {
209 this->WriteNode = this->LastWriteNode->Next;
210 Mutex.Lock(); {
211 LastCompare = (this->WriteNode == this->ReadNode);
212 if (LastCompare) {
213 this->WriteNode = this->WriteNode->Next;
214 }
215 } Mutex.Unlock();
216 }
217
218
220 inline void EndWrite(void) {
221 this->LastWriteNode = this->WriteNode;
222 }
223
224
226 void ToStream(std::ostream & outputStream) const {
227 outputStream << "Node addresses from LastWriteNode: "
228 << this->LastWriteNode << "[" << this->LastWriteNode->Pointer << "] "
229 << this->LastWriteNode->Next << "[" << this->LastWriteNode->Next->Pointer << "] "
230 << this->LastWriteNode->Next->Next << "[" << this->LastWriteNode->Next->Next->Pointer << "]" << std::endl
231 << "LastCompare of read/write: " << ((this->LastCompare) ? "equal" : "different") << std::endl
232 << "ReadNode address: " << this->ReadNode << std::endl
233 << "WriteNode address: " << this->WriteNode << std::endl;
234 }
235};
_elementType value_type
Definition mtsGenericObjectProxy.h:329
void EndWrite(void)
Definition osaTripleBuffer.h:220
void Read(reference placeHolder)
Definition osaTripleBuffer.h:160
pointer GetWritePointer(void) const
Definition osaTripleBuffer.h:186
void BeginWrite(void)
Definition osaTripleBuffer.h:208
void BeginRead(void)
Definition osaTripleBuffer.h:192
~osaTripleBuffer()
Definition osaTripleBuffer.h:140
const_pointer GetReadPointer(void) const
Definition osaTripleBuffer.h:178
osaTripleBuffer(pointer pointer1, pointer pointer2, pointer pointer3)
Definition osaTripleBuffer.h:117
void Write(const_reference newValue)
Definition osaTripleBuffer.h:168
friend class osaTripleBufferTest
Definition osaTripleBuffer.h:51
void ToStream(std::ostream &outputStream) const
Definition osaTripleBuffer.h:226
void SetupNodes(pointer pointer1, pointer pointer2, pointer pointer3)
Definition osaTripleBuffer.h:126
osaTripleBuffer(const_reference initialValue)
Definition osaTripleBuffer.h:104
void EndRead(void)
Definition osaTripleBuffer.h:199
osaTripleBuffer(void)
Definition osaTripleBuffer.h:92
Assert macros definitions.
#define CMN_ASSERT(expr)
Definition cmnAssert.h:97
Declaration of osaMutex.
const_pointer Pointer(index_type rowIndex, index_type colIndex) const
Definition vctDynamicConstMatrixBase.h:306