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 17333 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 17389 of file midas.cxx.

17410{
17411 int i;
17412
17413 for (i = 0; i < MAX_RING_BUFFER; i++)
17414 if (rb[i].buffer == NULL)
17415 break;
17416
17417 if (i == MAX_RING_BUFFER)
17418 return DB_NO_MEMORY;
17419
17420 if (size < max_event_size * 2)
17421 return DB_INVALID_PARAM;
17422
17423 memset(&rb[i], 0, sizeof(RING_BUFFER));
17424 rb[i].buffer = (unsigned char *) M_MALLOC(size);
17425 assert(rb[i].buffer);
17426 rb[i].size = size;
17428 rb[i].rp = rb[i].buffer;
17429 rb[i].wp = rb[i].buffer;
17430 rb[i].ep = rb[i].buffer;
17431
17432 *handle = i + 1;
17433
17434 return DB_SUCCESS;
17435}
#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:17333
static RING_BUFFER rb[MAX_RING_BUFFER]
Definition midas.cxx:17335
INT i
Definition mdump.cxx:32
INT max_event_size
Definition mfed.cxx:30
#define M_MALLOC(x)
Definition midas.h:1551
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
unsigned char * wp
Definition midas.cxx:17329
unsigned char * buffer
Definition midas.cxx:17325
unsigned int max_event_size
Definition midas.cxx:17327
unsigned int size
Definition midas.cxx:17326
unsigned char * rp
Definition midas.cxx:17328
unsigned char * ep
Definition midas.cxx:17330
Here is the call graph for this function:
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 17443 of file midas.cxx.

17459{
17460 if (handle < 0 || handle >= MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17461 return DB_INVALID_HANDLE;
17462
17463 M_FREE(rb[handle - 1].buffer);
17464 rb[handle - 1].buffer = NULL;
17465 memset(&rb[handle - 1], 0, sizeof(RING_BUFFER));
17466
17467 return DB_SUCCESS;
17468}
#define DB_INVALID_HANDLE
Definition midas.h:636
#define M_FREE(x)
Definition midas.h:1553
Here is the call graph for this function:

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

17756{
17757 int h;
17758
17759 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17760 return DB_INVALID_HANDLE;
17761
17762 h = handle - 1;
17763
17764 if (rb[h].wp >= rb[h].rp)
17765 *n_bytes = (POINTER_T) rb[h].wp - (POINTER_T) rb[h].rp;
17766 else
17767 *n_bytes =
17768 (POINTER_T) rb[h].ep - (POINTER_T) rb[h].rp + (POINTER_T) rb[h].wp - (POINTER_T) rb[h].buffer;
17769
17770 return DB_SUCCESS;
17771}
#define POINTER_T
Definition midas.h:166
Here is the call graph for this function:

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

17644{
17645 int i, h;
17646
17647 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17648 return DB_INVALID_HANDLE;
17649
17650 h = handle - 1;
17651
17652 for (i = 0; i <= millisec / 10; i++) {
17653
17654 if (rb[h].wp != rb[h].rp) {
17655 if (p != NULL)
17656 *p = rb[handle - 1].rp;
17657 return DB_SUCCESS;
17658 }
17659
17660 if (millisec == 0)
17661 return DB_TIMEOUT;
17662
17663 if (_rb_nonblocking)
17664 return DB_TIMEOUT;
17665
17666 /* wait one time slice */
17667 ss_sleep(10);
17668 }
17669
17670 return DB_TIMEOUT;
17671}
#define DB_TIMEOUT
Definition midas.h:656
INT ss_sleep(INT millisec)
Definition system.cxx:3700
static volatile int _rb_nonblocking
Definition midas.cxx:17337
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 17480 of file midas.cxx.

17500{
17501 int h, i;
17502 unsigned char *rp;
17503
17504 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17505 return DB_INVALID_HANDLE;
17506
17507 h = handle - 1;
17508
17509 for (i = 0; i <= millisec / 10; i++) {
17510
17511 rp = rb[h].rp; // keep local copy for convenience
17512
17513 /* check if enough size for wp >= rp without wrap-around */
17514 if (rb[h].wp >= rp
17515 && rb[h].wp + rb[h].max_event_size <= rb[h].buffer + rb[h].size - rb[h].max_event_size) {
17516 *p = rb[h].wp;
17517 return DB_SUCCESS;
17518 }
17519
17520 /* check if enough size for wp >= rp with wrap-around */
17521 if (rb[h].wp >= rp && rb[h].wp + rb[h].max_event_size > rb[h].buffer + rb[h].size - rb[h].max_event_size &&
17522 rp > rb[h].buffer) { // next increment of wp wraps around, so need space at beginning
17523 *p = rb[h].wp;
17524 return DB_SUCCESS;
17525 }
17526
17527 /* check if enough size for wp < rp */
17528 if (rb[h].wp < rp && rb[h].wp + rb[h].max_event_size < rp) {
17529 *p = rb[h].wp;
17530 return DB_SUCCESS;
17531 }
17532
17533 if (millisec == 0)
17534 return DB_TIMEOUT;
17535
17536 if (_rb_nonblocking)
17537 return DB_TIMEOUT;
17538
17539 /* wait one time slice */
17540 ss_sleep(10);
17541 }
17542
17543 return DB_TIMEOUT;
17544}
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 17683 of file midas.cxx.

17704{
17705 int h;
17706
17707 unsigned char *new_rp;
17708 unsigned char *ep;
17709
17710 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17711 return DB_INVALID_HANDLE;
17712
17713 h = handle - 1;
17714
17715 if ((DWORD) size > rb[h].max_event_size)
17716 return DB_INVALID_PARAM;
17717
17718 new_rp = rb[h].rp + size;
17719 ep = rb[h].ep; // keep local copy of end pointer, rb[h].ep might be changed by other thread
17720
17721 /* wrap around if end pointer reached */
17722 if (new_rp >= ep && rb[h].wp < ep)
17723 new_rp = rb[h].buffer;
17724
17725 rb[handle - 1].rp = new_rp;
17726
17727 return DB_SUCCESS;
17728}
unsigned int DWORD
Definition mcstd.h:51
Here is the call graph for this function:
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 17555 of file midas.cxx.

17574{
17575 int h;
17576 unsigned char *new_wp;
17577
17578 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17579 return DB_INVALID_HANDLE;
17580
17581 h = handle - 1;
17582
17583 if ((DWORD) size > rb[h].max_event_size) {
17584 cm_msg(MERROR, "rb_increment_wp", "event size of %d MB larger than max_event_size of %d MB",
17585 size/1024/1024, rb[h].max_event_size/1024/1024);
17586 abort();
17587 }
17588
17589 new_wp = rb[h].wp + size;
17590
17591 /* wrap around wp if not enough space */
17592 if (new_wp > rb[h].buffer + rb[h].size - rb[h].max_event_size) {
17593 rb[h].ep = new_wp;
17594 new_wp = rb[h].buffer;
17595 assert(rb[h].rp != rb[h].buffer);
17596 } else
17597 if (new_wp > rb[h].ep)
17598 rb[h].ep = new_wp;
17599
17600 rb[h].wp = new_wp;
17601
17602 return DB_SUCCESS;
17603}
#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:930
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 17348 of file midas.cxx.

17366{
17367 _rb_nonblocking = 1;
17368
17369 return DB_SUCCESS;
17370}
Here is the caller graph for this function:

Variable Documentation

◆ _rb_nonblocking

volatile int _rb_nonblocking = 0
static

Definition at line 17337 of file midas.cxx.

◆ rb

Definition at line 17335 of file midas.cxx.