28 #ifndef INCepicsRingPointerh
29 #define INCepicsRingPointerh
32 #include "epicsSpin.h"
33 #include "libComAPI.h"
104 int getUsedNoLock()
const;
108 volatile int nextPush;
109 volatile int nextPop;
112 T *
volatile * buffer;
120 typedef void const *epicsRingPointerIdConst;
208 #define epicsRingPointerSize epicsRingPointerGetSize
221 lock(0), nextPush(0), nextPop(0), size(sz+1), highWaterMark(0),
222 buffer(new T* [sz+1])
225 lock = epicsSpinCreate();
231 if (lock) epicsSpinDestroy(lock);
238 if (lock) epicsSpinLock(lock);
240 int newNext = next + 1;
241 if(newNext>=size) newNext=0;
242 if (newNext == nextPop) {
243 if (lock) epicsSpinUnlock(lock);
248 int used = getUsedNoLock();
249 if (used > highWaterMark) highWaterMark = used;
250 if (lock) epicsSpinUnlock(lock);
257 if (lock) epicsSpinLock(lock);
259 if (next == nextPush) {
260 if (lock) epicsSpinUnlock(lock);
265 if(next >=size) next = 0;
267 if (lock) epicsSpinUnlock(lock);
274 if (lock) epicsSpinLock(lock);
277 if (lock) epicsSpinUnlock(lock);
283 if (lock) epicsSpinLock(lock);
284 int n = nextPop - nextPush - 1;
285 if (n < 0) n += size;
286 if (lock) epicsSpinUnlock(lock);
293 int n = nextPush - nextPop;
294 if (n < 0) n += size;
301 if (lock) epicsSpinLock(lock);
302 int n = getUsedNoLock();
303 if (lock) epicsSpinUnlock(lock);
317 if (lock) epicsSpinLock(lock);
318 isEmpty = (nextPush == nextPop);
319 if (lock) epicsSpinUnlock(lock);
326 if (lock) epicsSpinLock(lock);
327 int count = nextPush - nextPop +1;
328 if (lock) epicsSpinUnlock(lock);
329 return((count == 0) || (count == size));
335 return highWaterMark;
341 if (lock) epicsSpinLock(lock);
342 highWaterMark = getUsedNoLock();
343 if (lock) epicsSpinUnlock(lock);
T * pop()
Take an element off the ring.
LIBCOM_API int epicsStdCall epicsRingPointerGetFree(epicsRingPointerId id)
Return the amount of empty space in the ring buffer.
LIBCOM_API void epicsStdCall epicsRingPointerFlush(epicsRingPointerId id)
Remove all elements from the ring.
LIBCOM_API epicsRingPointerId epicsStdCall epicsRingPointerLockedCreate(int size)
Create a new ring buffer, secured by a spinlock.
LIBCOM_API void epicsStdCall epicsRingPointerDelete(epicsRingPointerId id)
Delete the ring buffer and free any associated memory.
LIBCOM_API int epicsStdCall epicsRingPointerIsEmpty(epicsRingPointerId id)
Check if the ring buffer is currently empty.
LIBCOM_API int epicsStdCall epicsRingPointerGetUsed(epicsRingPointerId id)
Return the number of elements stored in the ring buffer.
int getFree() const
Get how much free space remains in the ring.
LIBCOM_API int epicsStdCall epicsRingPointerPush(epicsRingPointerId id, void *p)
Push pointer into the ring buffer.
bool push(T *p)
Push a new entry on the ring.
A C++ template class providing methods for creating and using a ring buffer (a first in...
LIBCOM_API int epicsStdCall epicsRingPointerIsFull(epicsRingPointerId id)
Check if the ring buffer is currently full.
LIBCOM_API void *epicsStdCall epicsRingPointerPop(epicsRingPointerId id)
Take an element off the ring.
LIBCOM_API void epicsStdCall epicsRingPointerResetHighWaterMark(epicsRingPointerId id)
Reset the Highwater mark of the ring buffer.
LIBCOM_API int epicsStdCall epicsRingPointerGetHighWaterMark(epicsRingPointerIdConst id)
Get the Highwater mark of the ring buffer.
LIBCOM_API int epicsStdCall epicsRingPointerGetSize(epicsRingPointerId id)
Return the size of the ring.
int getHighWaterMark() const
See how full the ring has got since it was last checked.
~epicsRingPointer()
Destructor.
void resetHighWaterMark()
Reset high water mark.
int getSize() const
Get the size of the ring.
LIBCOM_API epicsRingPointerId epicsStdCall epicsRingPointerCreate(int size)
Create a new ring buffer.
int getUsed() const
Get how many elements are stored on the ring.
bool isFull() const
Test if the ring is currently full.
void * epicsRingPointerId
An identifier for the C API to a ring buffer storing pointers.
bool isEmpty() const
Test if the ring is currently empty.
void flush()
Remove all elements from the ring.