MIDAS
Loading...
Searching...
No Matches
Ring Buffer Functions (rb_xxx)

Classes

struct  RING_BUFFER
 

Macros

#define MAX_RING_BUFFER   100
 

Functions

int rb_set_nonblocking ()
 
int rb_create (int size, int max_event_size, int *handle)
 
int rb_delete (int handle)
 
int rb_get_wp (int handle, void **p, int millisec)
 
int rb_increment_wp (int handle, int size)
 
int rb_get_rp (int handle, void **p, int millisec)
 
int rb_increment_rp (int handle, int size)
 
int rb_get_buffer_level (int handle, int *n_bytes)
 

Variables

static RING_BUFFER rb [MAX_RING_BUFFER]
 
static volatile int _rb_nonblocking = 0
 

Detailed Description

dox dox


Macro Definition Documentation

◆ MAX_RING_BUFFER

#define MAX_RING_BUFFER   100

Definition at line 18852 of file midas.cxx.

Function Documentation

◆ rb_create()

int rb_create ( int  size,
int  max_event_size,
int *  handle 
)

Create a ring buffer with a given size

Provide an inter-thread buffer scheme for handling front-end events. This code allows concurrent data acquisition, calibration and network transfer on a multi-CPU machine. One thread reads out the data, passes it via the ring buffer functions to another thread running on the other CPU, which can then calibrate and/or send the data over the network.

Parameters
sizeSize of ring buffer, must be larger than 2*max_event_size
max_event_sizeMaximum event size to be placed into
*handleHandle to ring buffer
Returns
DB_SUCCESS, DB_NO_MEMORY, DB_INVALID_PARAM

Definition at line 18908 of file midas.cxx.

18929{
18930 int i;
18931
18932 if (handle == NULL || size <= 0 || max_event_size <= 0 || max_event_size > size / 2)
18933 return DB_INVALID_PARAM;
18934
18935 for (i = 0; i < MAX_RING_BUFFER; i++)
18936 if (rb[i].buffer == NULL)
18937 break;
18938
18939 if (i == MAX_RING_BUFFER)
18940 return DB_NO_MEMORY;
18941
18942 memset(&rb[i], 0, sizeof(RING_BUFFER));
18943 rb[i].buffer = (unsigned char *) M_MALLOC(size);
18944 if (rb[i].buffer == NULL)
18945 return DB_NO_MEMORY;
18946 rb[i].size = size;
18948 rb[i].rp = rb[i].buffer;
18949 rb[i].wp = rb[i].buffer;
18950 rb[i].ep = rb[i].buffer;
18951
18952 *handle = i + 1;
18953
18954 return DB_SUCCESS;
18955}
#define DB_INVALID_PARAM
Definition midas.h:640
#define DB_SUCCESS
Definition midas.h:632
#define DB_NO_MEMORY
Definition midas.h:634
#define MAX_RING_BUFFER
Definition midas.cxx:18852
static RING_BUFFER rb[MAX_RING_BUFFER]
Definition midas.cxx:18854
INT i
Definition mdump.cxx:32
INT max_event_size
Definition mfed.cxx:30
#define M_MALLOC(x)
Definition midas.h:1487
unsigned char * wp
Definition midas.cxx:18848
unsigned char * buffer
Definition midas.cxx:18844
unsigned int max_event_size
Definition midas.cxx:18846
unsigned int size
Definition midas.cxx:18845
unsigned char * rp
Definition midas.cxx:18847
unsigned char * ep
Definition midas.cxx:18849
Here is the caller graph for this function:

◆ rb_delete()

int rb_delete ( int  handle)

Delete a ring buffer

Parameters
handleHandle of the ring buffer
Returns
DB_SUCCESS

Definition at line 18963 of file midas.cxx.

18979{
18980 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
18981 return DB_INVALID_HANDLE;
18982
18983 M_FREE(rb[handle - 1].buffer);
18984 rb[handle - 1].buffer = NULL;
18985 memset(&rb[handle - 1], 0, sizeof(RING_BUFFER));
18986
18987 return DB_SUCCESS;
18988}
#define DB_INVALID_HANDLE
Definition midas.h:636
#define M_FREE(x)
Definition midas.h:1489

◆ rb_get_buffer_level()

int rb_get_buffer_level ( int  handle,
int *  n_bytes 
)

Return number of bytes in a ring buffer

Parameters
handleHandle of the buffer to get the info
*n_bytesNumber of bytes in buffer
Returns
DB_SUCCESS, DB_INVALID_HANDLE

Definition at line 19258 of file midas.cxx.

19276{
19277 int h;
19278
19279 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19280 return DB_INVALID_HANDLE;
19281
19282 h = handle - 1;
19283
19284 if (rb[h].wp >= rb[h].rp)
19285 *n_bytes = (POINTER_T) rb[h].wp - (POINTER_T) rb[h].rp;
19286 else
19287 *n_bytes =
19288 (POINTER_T) rb[h].ep - (POINTER_T) rb[h].rp + (POINTER_T) rb[h].wp - (POINTER_T) rb[h].buffer;
19289
19290 return DB_SUCCESS;
19291}
#define POINTER_T
Definition midas.h:166

◆ rb_get_rp()

int rb_get_rp ( int  handle,
void **  p,
int  millisec 
)

Obtain the current read pointer at which new data is available with optional timeout

Parameters
handleRing buffer handle
millisecOptional timeout in milliseconds if buffer is full. Zero to not wait at all (non-blocking)
**pAddress of pointer pointing to newly available data. If p == NULL, only return status.
Returns
DB_SUCCESS, DB_TIEMOUT, DB_INVALID_HANDLE

Definition at line 19141 of file midas.cxx.

19164{
19165 int i, h;
19166
19167 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19168 return DB_INVALID_HANDLE;
19169
19170 h = handle - 1;
19171
19172 for (i = 0; i <= millisec / 10; i++) {
19173
19174 if (rb[h].wp != rb[h].rp) {
19175 if (p != NULL)
19176 *p = rb[handle - 1].rp;
19177 return DB_SUCCESS;
19178 }
19179
19180 if (millisec == 0)
19181 return DB_TIMEOUT;
19182
19183 if (_rb_nonblocking)
19184 return DB_TIMEOUT;
19185
19186 /* wait one time slice */
19187 ss_sleep(10);
19188 }
19189
19190 return DB_TIMEOUT;
19191}
#define DB_TIMEOUT
Definition midas.h:656
INT ss_sleep(INT millisec)
Definition system.cxx:3707
static volatile int _rb_nonblocking
Definition midas.cxx:18856
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rb_get_wp()

int rb_get_wp ( int  handle,
void **  p,
int  millisec 
)

Retrieve write pointer where new data can be written

Parameters
handleRing buffer handle
millisecOptional timeout in milliseconds if buffer is full. Zero to not wait at all (non-blocking)
**pWrite pointer
Returns
DB_SUCCESS, DB_TIMEOUT, DB_INVALID_HANDLE

Definition at line 19000 of file midas.cxx.

19020{
19021 int h, i;
19022 unsigned char *rp;
19023
19024 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19025 return DB_INVALID_HANDLE;
19026
19027 h = handle - 1;
19028
19029 for (i = 0; i <= millisec / 10; i++) {
19030
19031 rp = rb[h].rp; // keep local copy for convenience
19032
19033 /* check if enough size for wp >= rp without wrap-around */
19034 if (rb[h].wp >= rp
19035 && rb[h].wp + rb[h].max_event_size <= rb[h].buffer + rb[h].size - rb[h].max_event_size) {
19036 *p = rb[h].wp;
19037 return DB_SUCCESS;
19038 }
19039
19040 /* check if enough size for wp >= rp with wrap-around */
19041 if (rb[h].wp >= rp && rb[h].wp + rb[h].max_event_size > rb[h].buffer + rb[h].size - rb[h].max_event_size &&
19042 rp > rb[h].buffer) { // next increment of wp wraps around, so need space at beginning
19043 *p = rb[h].wp;
19044 return DB_SUCCESS;
19045 }
19046
19047 /* check if enough size for wp < rp */
19048 if (rb[h].wp < rp && rb[h].wp + rb[h].max_event_size < rp) {
19049 *p = rb[h].wp;
19050 return DB_SUCCESS;
19051 }
19052
19053 if (millisec == 0)
19054 return DB_TIMEOUT;
19055
19056 if (_rb_nonblocking)
19057 return DB_TIMEOUT;
19058
19059 /* wait one time slice */
19060 ss_sleep(10);
19061 }
19062
19063 return DB_TIMEOUT;
19064}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rb_increment_rp()

int rb_increment_rp ( int  handle,
int  size 
)

Increment current read pointer, freeing up space for the writing thread.

Parameters
handleRing buffer handle
sizeNumber of bytes to free up at current read pointer
Returns
DB_SUCCESS, DB_INVALID_PARAM

Definition at line 19203 of file midas.cxx.

19224{
19225 int h;
19226
19227 unsigned char *new_rp;
19228 unsigned char *ep;
19229
19230 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19231 return DB_INVALID_HANDLE;
19232
19233 h = handle - 1;
19234
19235 if ((DWORD) size > rb[h].max_event_size)
19236 return DB_INVALID_PARAM;
19237
19238 new_rp = rb[h].rp + size;
19239 ep = rb[h].ep; // keep local copy of end pointer, rb[h].ep might be changed by other thread
19240
19241 /* wrap around if end pointer reached */
19242 if (new_rp >= ep && rb[h].wp < ep)
19243 new_rp = rb[h].buffer;
19244
19245 rb[handle - 1].rp = new_rp;
19246
19247 return DB_SUCCESS;
19248}
unsigned int DWORD
Definition mcstd.h:51
Here is the caller graph for this function:

◆ rb_increment_wp()

int rb_increment_wp ( int  handle,
int  size 
)

rb_increment_wp

Increment current write pointer, making the data at the write pointer available to the receiving thread

Parameters
handleRing buffer handle
sizeNumber of bytes placed at the WP
Returns
DB_SUCCESS, DB_INVALID_PARAM, DB_INVALID_HANDLE

Definition at line 19075 of file midas.cxx.

19094{
19095 int h;
19096 unsigned char *new_wp;
19097
19098 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19099 return DB_INVALID_HANDLE;
19100
19101 h = handle - 1;
19102
19103 if (size < 0 || (DWORD) size > rb[h].max_event_size) {
19104 cm_msg(MERROR, "rb_increment_wp", "invalid event size of %d bytes, max_event_size is %u bytes",
19105 size, rb[h].max_event_size);
19106 return DB_INVALID_PARAM;
19107 }
19108
19109 new_wp = rb[h].wp + size;
19110
19111 /* wrap around wp if not enough space */
19112 if (new_wp > rb[h].buffer + rb[h].size - rb[h].max_event_size) {
19113 rb[h].ep = new_wp;
19114 new_wp = rb[h].buffer;
19115 assert(rb[h].rp != rb[h].buffer);
19116 } else
19117 if (new_wp > rb[h].ep)
19118 rb[h].ep = new_wp;
19119
19120 rb[h].wp = new_wp;
19121
19122 return DB_SUCCESS;
19123}
#define MERROR
Definition midas.h:559
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:939
Here is the call graph for this function:
Here is the caller graph for this function:

◆ rb_set_nonblocking()

int rb_set_nonblocking ( void  )

dox Set all rb_get_xx to nonblocking. Needed in multi-thread environments for stopping all theads without deadlock

Returns
DB_SUCCESS

Definition at line 18867 of file midas.cxx.

18885{
18886 _rb_nonblocking = 1;
18887
18888 return DB_SUCCESS;
18889}
Here is the caller graph for this function:

Variable Documentation

◆ _rb_nonblocking

volatile int _rb_nonblocking = 0
static

Definition at line 18856 of file midas.cxx.

◆ rb

Definition at line 18854 of file midas.cxx.