v2.0.0
Loading...
Searching...
No Matches
circularbuffer.h
Go to the documentation of this file.
1//=============================================================================================================
30
31#ifndef CIRCULARBUFFER_H
32#define CIRCULARBUFFER_H
33
34//=============================================================================================================
35// INCLUDES
36//=============================================================================================================
37
38#include "../utils_global.h"
39
40//=============================================================================================================
41// QT INCLUDES
42//=============================================================================================================
43
44#include <QPair>
45#include <QSemaphore>
46#include <QSharedPointer>
47
48//=============================================================================================================
49// EIGEN INCLUDES
50//=============================================================================================================
51
52#include <Eigen/Core>
53
54//=============================================================================================================
55// DEFINE NAMESPACE UTILSLIB
56//=============================================================================================================
57
58namespace UTILSLIB
59{
60
61//=============================================================================================================
69template<typename T>
71{
72public:
73 typedef QSharedPointer<CircularBuffer> SPtr;
74 typedef QSharedPointer<const CircularBuffer> ConstSPtr;
75
76 //=========================================================================================================
82 explicit CircularBuffer(unsigned int uiMaxNumElements);
83
84 //=========================================================================================================
89
90 //=========================================================================================================
99 inline bool push(const T* pArray, unsigned int size);
100
101 //=========================================================================================================
109 inline bool push(const T& newElement);
110
111 //=========================================================================================================
119 inline bool pop(T& element);
120
121 //=========================================================================================================
125 void clear();
126
127 //=========================================================================================================
133 inline void pause(bool);
134
135 //=========================================================================================================
142
143 //=========================================================================================================
150
151private:
152 //=========================================================================================================
159 inline unsigned int mapIndex(int& index);
160 unsigned int m_uiMaxNumElements;
161 T* m_pBuffer;
162 int m_iCurrentReadIndex;
163 int m_iCurrentWriteIndex;
164 QSemaphore* m_pFreeElements;
165 QSemaphore* m_pUsedElements;
166 int m_iTimeout;
167
168 bool m_bPause;
169};
170
171//=============================================================================================================
172// DEFINE MEMBER METHODS
173//=============================================================================================================
174
175template<typename T>
176CircularBuffer<T>::CircularBuffer(unsigned int uiMaxNumElements)
177: m_uiMaxNumElements(uiMaxNumElements)
178, m_pBuffer(new T[m_uiMaxNumElements])
179, m_iCurrentReadIndex(-1)
180, m_iCurrentWriteIndex(-1)
181, m_pFreeElements(new QSemaphore(m_uiMaxNumElements))
182, m_pUsedElements(new QSemaphore(0))
183, m_iTimeout(1000)
184, m_bPause(false)
185{
186}
187
188//=============================================================================================================
189
190template<typename T>
192{
193 delete m_pFreeElements;
194 delete m_pUsedElements;
195 delete[] m_pBuffer;
196}
197
198//=============================================================================================================
199
200template<typename T>
201inline bool CircularBuffer<T>::push(const T* pArray, unsigned int size)
202{
203 if (m_bPause) {
204 return false;
205 }
206
207 if (m_pFreeElements->tryAcquire(size, m_iTimeout)) {
208 for (unsigned int i = 0; i < size; ++i) {
209 m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = pArray[i];
210 }
211 const QSemaphoreReleaser releaser(m_pUsedElements, size);
212 } else {
213 return false;
214 }
215
216 return true;
217}
218
219//=============================================================================================================
220
221template<typename T>
222inline bool CircularBuffer<T>::push(const T& newElement)
223{
224 if (m_bPause) {
225 return false;
226 }
227
228 if (m_pFreeElements->tryAcquire(1, m_iTimeout)) {
229 m_pBuffer[mapIndex(m_iCurrentWriteIndex)] = newElement;
230 const QSemaphoreReleaser releaser(m_pUsedElements, 1);
231 } else {
232 return false;
233 }
234
235 return true;
236}
237
238//=============================================================================================================
239
240template<typename T>
241inline bool CircularBuffer<T>::pop(T& element)
242{
243 if (m_bPause) {
244 return false;
245 }
246
247 if (m_pUsedElements->tryAcquire(1, m_iTimeout)) {
248 element = m_pBuffer[mapIndex(m_iCurrentReadIndex)];
249 const QSemaphoreReleaser releaser(m_pFreeElements, 1);
250 } else {
251 return false;
252 }
253
254 return true;
255}
256
257//=============================================================================================================
258
259template<typename T>
260inline unsigned int CircularBuffer<T>::mapIndex(int& index)
261{
262 int aux = index;
263 return index = ++aux % m_uiMaxNumElements;
264}
265
266//=============================================================================================================
267
268template<typename T>
270{
271 delete m_pFreeElements;
272 m_pFreeElements = new QSemaphore(m_uiMaxNumElements);
273 delete m_pUsedElements;
274 m_pUsedElements = new QSemaphore(0);
275
276 m_iCurrentReadIndex = -1;
277 m_iCurrentWriteIndex = -1;
278}
279
280//=============================================================================================================
281
282template<typename T>
283inline void CircularBuffer<T>::pause(bool bPause)
284{
285 m_bPause = bPause;
286}
287
288//=============================================================================================================
289
290template<typename T>
292{
293 return m_pUsedElements->available();
294}
295
296//=============================================================================================================
297
298template<typename T>
300{
301 return m_pFreeElements->available();
302}
303
304//=============================================================================================================
305// TYPEDEF
306//=============================================================================================================
307
316
317} // NAMESPACE
318
319#endif // CIRCULARBUFFER_H
Public umbrella header for UTILSLIB exposing the UTILSSHARED_EXPORT macro and build-info accessors.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
CircularBuffer< QPair< int, int > > CircularBuffer_pair_int_int
CircularBuffer< QPair< double, double > > CircularBuffer_pair_double_double
CircularBuffer< short > CircularBuffer_short
CircularBuffer< double > CircularBuffer_double
CircularBuffer< Eigen::MatrixXd > CircularBuffer_Matrix_double
CircularBuffer< char > CircularBuffer_char
CircularBuffer< Eigen::MatrixXf > CircularBuffer_Matrix_float
CircularBuffer< int > CircularBuffer_int
Thread-safe lock-free circular (ring) buffer for producer-consumer data exchange between threads.
CircularBuffer(unsigned int uiMaxNumElements)
QSharedPointer< const CircularBuffer > ConstSPtr
bool push(const T *pArray, unsigned int size)
QSharedPointer< CircularBuffer > SPtr
bool push(const T &newElement)