MIDAS
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 17247 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 17303 of file midas.cxx.

17324 {
17325  int i;
17326 
17327  for (i = 0; i < MAX_RING_BUFFER; i++)
17328  if (rb[i].buffer == NULL)
17329  break;
17330 
17331  if (i == MAX_RING_BUFFER)
17332  return DB_NO_MEMORY;
17333 
17334  if (size < max_event_size * 2)
17335  return DB_INVALID_PARAM;
17336 
17337  memset(&rb[i], 0, sizeof(RING_BUFFER));
17338  rb[i].buffer = (unsigned char *) M_MALLOC(size);
17339  assert(rb[i].buffer);
17340  rb[i].size = size;
17342  rb[i].rp = rb[i].buffer;
17343  rb[i].wp = rb[i].buffer;
17344  rb[i].ep = rb[i].buffer;
17345 
17346  *handle = i + 1;
17347 
17348  return DB_SUCCESS;
17349 }
#define DB_INVALID_PARAM
Definition: midas.h:645
#define DB_SUCCESS
Definition: midas.h:637
#define DB_NO_MEMORY
Definition: midas.h:639
#define MAX_RING_BUFFER
Definition: midas.cxx:17247
static RING_BUFFER rb[MAX_RING_BUFFER]
Definition: midas.cxx:17249
INT i
Definition: mdump.cxx:35
INT max_event_size
Definition: mfed.cxx:29
#define M_MALLOC(x)
Definition: midas.h:1550
unsigned char * wp
Definition: midas.cxx:17243
unsigned char * buffer
Definition: midas.cxx:17239
unsigned int max_event_size
Definition: midas.cxx:17241
unsigned int size
Definition: midas.cxx:17240
unsigned char * rp
Definition: midas.cxx:17242
unsigned char * ep
Definition: midas.cxx:17244
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 17357 of file midas.cxx.

17373 {
17374  if (handle < 0 || handle >= MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17375  return DB_INVALID_HANDLE;
17376 
17377  M_FREE(rb[handle - 1].buffer);
17378  rb[handle - 1].buffer = NULL;
17379  memset(&rb[handle - 1], 0, sizeof(RING_BUFFER));
17380 
17381  return DB_SUCCESS;
17382 }
#define DB_INVALID_HANDLE
Definition: midas.h:641
#define M_FREE(x)
Definition: midas.h:1552

◆ 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 17652 of file midas.cxx.

17670 {
17671  int h;
17672 
17673  if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17674  return DB_INVALID_HANDLE;
17675 
17676  h = handle - 1;
17677 
17678  if (rb[h].wp >= rb[h].rp)
17679  *n_bytes = (POINTER_T) rb[h].wp - (POINTER_T) rb[h].rp;
17680  else
17681  *n_bytes =
17682  (POINTER_T) rb[h].ep - (POINTER_T) rb[h].rp + (POINTER_T) rb[h].wp - (POINTER_T) rb[h].buffer;
17683 
17684  return DB_SUCCESS;
17685 }
#define POINTER_T
Definition: midas.h:166
WP * wp
Definition: wdfe.cxx:109

◆ 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 17535 of file midas.cxx.

17558 {
17559  int i, h;
17560 
17561  if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17562  return DB_INVALID_HANDLE;
17563 
17564  h = handle - 1;
17565 
17566  for (i = 0; i <= millisec / 10; i++) {
17567 
17568  if (rb[h].wp != rb[h].rp) {
17569  if (p != NULL)
17570  *p = rb[handle - 1].rp;
17571  return DB_SUCCESS;
17572  }
17573 
17574  if (millisec == 0)
17575  return DB_TIMEOUT;
17576 
17577  if (_rb_nonblocking)
17578  return DB_TIMEOUT;
17579 
17580  /* wait one time slice */
17581  ss_sleep(10);
17582  }
17583 
17584  return DB_TIMEOUT;
17585 }
#define DB_TIMEOUT
Definition: midas.h:661
INT ss_sleep(INT millisec)
Definition: system.cxx:3567
static volatile int _rb_nonblocking
Definition: midas.cxx:17251
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 17394 of file midas.cxx.

17414 {
17415  int h, i;
17416  unsigned char *rp;
17417 
17418  if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17419  return DB_INVALID_HANDLE;
17420 
17421  h = handle - 1;
17422 
17423  for (i = 0; i <= millisec / 10; i++) {
17424 
17425  rp = rb[h].rp; // keep local copy for convenience
17426 
17427  /* check if enough size for wp >= rp without wrap-around */
17428  if (rb[h].wp >= rp
17429  && rb[h].wp + rb[h].max_event_size <= rb[h].buffer + rb[h].size - rb[h].max_event_size) {
17430  *p = rb[h].wp;
17431  return DB_SUCCESS;
17432  }
17433 
17434  /* check if enough size for wp >= rp with wrap-around */
17435  if (rb[h].wp >= rp && rb[h].wp + rb[h].max_event_size > rb[h].buffer + rb[h].size - rb[h].max_event_size &&
17436  rp > rb[h].buffer) { // next increment of wp wraps around, so need space at beginning
17437  *p = rb[h].wp;
17438  return DB_SUCCESS;
17439  }
17440 
17441  /* check if enough size for wp < rp */
17442  if (rb[h].wp < rp && rb[h].wp + rb[h].max_event_size < rp) {
17443  *p = rb[h].wp;
17444  return DB_SUCCESS;
17445  }
17446 
17447  if (millisec == 0)
17448  return DB_TIMEOUT;
17449 
17450  if (_rb_nonblocking)
17451  return DB_TIMEOUT;
17452 
17453  /* wait one time slice */
17454  ss_sleep(10);
17455  }
17456 
17457  return DB_TIMEOUT;
17458 }
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 17597 of file midas.cxx.

17618 {
17619  int h;
17620 
17621  unsigned char *new_rp;
17622  unsigned char *ep;
17623 
17624  if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17625  return DB_INVALID_HANDLE;
17626 
17627  h = handle - 1;
17628 
17629  if ((DWORD) size > rb[h].max_event_size)
17630  return DB_INVALID_PARAM;
17631 
17632  new_rp = rb[h].rp + size;
17633  ep = rb[h].ep; // keep local copy of end pointer, rb[h].ep might be changed by other thread
17634 
17635  /* wrap around if end pointer reached */
17636  if (new_rp >= ep && rb[h].wp < ep)
17637  new_rp = rb[h].buffer;
17638 
17639  rb[handle - 1].rp = new_rp;
17640 
17641  return DB_SUCCESS;
17642 }
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 17469 of file midas.cxx.

17488 {
17489  int h;
17490  unsigned char *new_wp;
17491 
17492  if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17493  return DB_INVALID_HANDLE;
17494 
17495  h = handle - 1;
17496 
17497  if ((DWORD) size > rb[h].max_event_size) {
17498  cm_msg(MERROR, "rb_increment_wp", "event size of %d MB larger than max_event_size of %d MB",
17499  size/1024/1024, rb[h].max_event_size/1024/1024);
17500  abort();
17501  }
17502 
17503  new_wp = rb[h].wp + size;
17504 
17505  /* wrap around wp if not enough space */
17506  if (new_wp > rb[h].buffer + rb[h].size - rb[h].max_event_size) {
17507  rb[h].ep = new_wp;
17508  new_wp = rb[h].buffer;
17509  assert(rb[h].rp != rb[h].buffer);
17510  } else
17511  if (new_wp > rb[h].ep)
17512  rb[h].ep = new_wp;
17513 
17514  rb[h].wp = new_wp;
17515 
17516  return DB_SUCCESS;
17517 }
#define MERROR
Definition: midas.h:565
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition: midas.cxx:917
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 17262 of file midas.cxx.

17280 {
17281  _rb_nonblocking = 1;
17282 
17283  return DB_SUCCESS;
17284 }
Here is the caller graph for this function:

Variable Documentation

◆ _rb_nonblocking

volatile int _rb_nonblocking = 0
static

Definition at line 17251 of file midas.cxx.

◆ rb

Definition at line 17249 of file midas.cxx.