epicsRingPointer.h

A circular buffer to store pointers.

epicsRingPointer.h provides both C and C++ APIs for creating and using ring buffers (first in first out circular buffers) that store pointers. The unlocked kind is designed so that one writer thread and one reader thread can access the ring simultaneously without requiring mutual exclusion. The locked variant uses an epicsSpinLock, and works with any numbers of writer and reader threads.

Author

Marty Kraimer, Ralph Lange

Note

If there is only one writer it is not necessary to lock pushes. If there is a single reader it is not necessary to lock pops. epicsRingPointerLocked uses a spinlock.

Defines

epicsRingPointerSize

Typedefs

typedef void *epicsRingPointerId

An identifier for the C API to a ring buffer storing pointers.

typedef void const *epicsRingPointerIdConst

Functions

epicsRingPointerId epicsRingPointerCreate(int size)

Create a new ring buffer.

Parameters:

size – Size of ring buffer to create

Returns:

Ring buffer identifier or NULL on failure

epicsRingPointerId epicsRingPointerLockedCreate(int size)

Create a new ring buffer, secured by a spinlock.

Parameters:

size – Size of ring buffer to create

Returns:

Ring buffer identifier or NULL on failure

void epicsRingPointerDelete(epicsRingPointerId id)

Delete the ring buffer and free any associated memory.

Parameters:

id – Ring buffer identifier

int epicsRingPointerPush(epicsRingPointerId id, void *p)

Push pointer into the ring buffer.

Parameters:
  • id – Ring buffer identifier

  • p – Pointer to be pushed to the ring

Returns:

1 if the pointer was successfully pushed, 0 if the buffer was full

void *epicsRingPointerPop(epicsRingPointerId id)

Take an element off the ring.

Parameters:

id – Ring buffer identifier

Returns:

The pointer from the buffer, or NULL if the ring was empty

void epicsRingPointerFlush(epicsRingPointerId id)

Remove all elements from the ring.

Note

If this operation is performed on a ring buffer of the unsecured kind, all access to the ring should be locked.

Parameters:

id – Ring buffer identifier

int epicsRingPointerGetFree(epicsRingPointerId id)

Return the amount of empty space in the ring buffer.

Parameters:

id – Ring buffer identifier

Returns:

The number of additional elements it could hold.

int epicsRingPointerGetUsed(epicsRingPointerId id)

Return the number of elements stored in the ring buffer.

Parameters:

id – Ring buffer identifier

Returns:

The number of elements stored in the ring buffer

int epicsRingPointerGetSize(epicsRingPointerId id)

Return the size of the ring.

Parameters:

id – Ring buffer identifier

Returns:

The size of the ring buffer, i.e. the value of size given when the ring was created.

int epicsRingPointerIsEmpty(epicsRingPointerId id)

Check if the ring buffer is currently empty.

Parameters:

id – Ring buffer identifier

Returns:

1 if the ring is empty, otherwise 0

int epicsRingPointerIsFull(epicsRingPointerId id)

Check if the ring buffer is currently full.

Parameters:

id – Ring buffer identifier

Returns:

1 if the ring buffer is full, otherwise 0

int epicsRingPointerGetHighWaterMark(epicsRingPointerIdConst id)

Get the Highwater mark of the ring buffer.

Returns the largest number of elements the ring buffer has held since the water mark was last reset. A new ring buffer starts with a water mark of 0.

Parameters:

id – Ring buffer identifier

Returns:

Actual Highwater mark

void epicsRingPointerResetHighWaterMark(epicsRingPointerId id)

Reset the Highwater mark of the ring buffer.

The Highwater mark will be set to the current usage

Parameters:

id – Ring buffer identifier

template<class T>
class epicsRingPointer
#include <epicsRingPointer.h>

A C++ template class providing methods for creating and using a ring buffer (a first in, first out circular buffer) that stores pointers to objects of the template type.

Public Functions

inline epicsRingPointer(int size, bool locked)

Constructor.

Parameters:
  • size – Maximum number of elements (pointers) that can be stored

  • locked – If true, the spin lock secured variant is created

inline ~epicsRingPointer()

Destructor.

inline bool push(T *p)

Push a new entry on the ring.

Returns:

True on success, False if the buffer was full

inline T *pop()

Take an element off the ring.

Returns:

The element, or NULL if the ring was empty

inline void flush()

Remove all elements from the ring.

Note

If this operation is performed on a ring buffer of the unsecured kind, all access to the ring should be locked.

inline int getFree() const

Get how much free space remains in the ring.

Returns:

The number of additional elements the ring could hold.

inline int getUsed() const

Get how many elements are stored on the ring.

Returns:

The number of elements currently stored.

inline int getSize() const

Get the size of the ring.

Returns:

The size specified when the ring was created.

inline bool isEmpty() const

Test if the ring is currently empty.

Returns:

True if the ring is empty, otherwise false.

inline bool isFull() const

Test if the ring is currently full.

Returns:

True if the ring is full, otherwise false.

inline int getHighWaterMark() const

See how full the ring has got since it was last checked.

Returns the maximum number of elements the ring buffer has held since the water mark was last reset. A new ring buffer starts with a water mark of 0.

Returns:

Actual highwater mark

inline void resetHighWaterMark()

Reset high water mark.

High water mark will be set to the current usage

Private Functions

epicsRingPointer()
epicsRingPointer(const epicsRingPointer&)
epicsRingPointer &operator=(const epicsRingPointer&)
inline int getUsedNoLock() const

Private Members

epicsSpinId lock
int nextPush
int nextPop
int size
int highWaterMark
T *volatile *buffer