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 17280 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 17336 of file midas.cxx.

17357{
17358 int i;
17359
17360 for (i = 0; i < MAX_RING_BUFFER; i++)
17361 if (rb[i].buffer == NULL)
17362 break;
17363
17364 if (i == MAX_RING_BUFFER)
17365 return DB_NO_MEMORY;
17366
17367 if (size < max_event_size * 2)
17368 return DB_INVALID_PARAM;
17369
17370 memset(&rb[i], 0, sizeof(RING_BUFFER));
17371 rb[i].buffer = (unsigned char *) M_MALLOC(size);
17372 assert(rb[i].buffer);
17373 rb[i].size = size;
17375 rb[i].rp = rb[i].buffer;
17376 rb[i].wp = rb[i].buffer;
17377 rb[i].ep = rb[i].buffer;
17378
17379 *handle = i + 1;
17380
17381 return DB_SUCCESS;
17382}
#define DB_INVALID_PARAM
Definition midas.h:639
#define DB_SUCCESS
Definition midas.h:631
#define DB_NO_MEMORY
Definition midas.h:633
#define MAX_RING_BUFFER
Definition midas.cxx:17280
static RING_BUFFER rb[MAX_RING_BUFFER]
Definition midas.cxx:17282
INT i
Definition mdump.cxx:32
INT max_event_size
Definition mfed.cxx:30
#define M_MALLOC(x)
Definition midas.h:1552
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:17276
unsigned char * buffer
Definition midas.cxx:17272
unsigned int max_event_size
Definition midas.cxx:17274
unsigned int size
Definition midas.cxx:17273
unsigned char * rp
Definition midas.cxx:17275
unsigned char * ep
Definition midas.cxx:17277
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 17390 of file midas.cxx.

17406{
17407 if (handle < 0 || handle >= MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17408 return DB_INVALID_HANDLE;
17409
17410 M_FREE(rb[handle - 1].buffer);
17411 rb[handle - 1].buffer = NULL;
17412 memset(&rb[handle - 1], 0, sizeof(RING_BUFFER));
17413
17414 return DB_SUCCESS;
17415}
#define DB_INVALID_HANDLE
Definition midas.h:635
#define M_FREE(x)
Definition midas.h:1554
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 17685 of file midas.cxx.

17703{
17704 int h;
17705
17706 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17707 return DB_INVALID_HANDLE;
17708
17709 h = handle - 1;
17710
17711 if (rb[h].wp >= rb[h].rp)
17712 *n_bytes = (POINTER_T) rb[h].wp - (POINTER_T) rb[h].rp;
17713 else
17714 *n_bytes =
17715 (POINTER_T) rb[h].ep - (POINTER_T) rb[h].rp + (POINTER_T) rb[h].wp - (POINTER_T) rb[h].buffer;
17716
17717 return DB_SUCCESS;
17718}
#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 17568 of file midas.cxx.

17591{
17592 int i, h;
17593
17594 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17595 return DB_INVALID_HANDLE;
17596
17597 h = handle - 1;
17598
17599 for (i = 0; i <= millisec / 10; i++) {
17600
17601 if (rb[h].wp != rb[h].rp) {
17602 if (p != NULL)
17603 *p = rb[handle - 1].rp;
17604 return DB_SUCCESS;
17605 }
17606
17607 if (millisec == 0)
17608 return DB_TIMEOUT;
17609
17610 if (_rb_nonblocking)
17611 return DB_TIMEOUT;
17612
17613 /* wait one time slice */
17614 ss_sleep(10);
17615 }
17616
17617 return DB_TIMEOUT;
17618}
#define DB_TIMEOUT
Definition midas.h:655
INT ss_sleep(INT millisec)
Definition system.cxx:3628
static volatile int _rb_nonblocking
Definition midas.cxx:17284
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 17427 of file midas.cxx.

17447{
17448 int h, i;
17449 unsigned char *rp;
17450
17451 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17452 return DB_INVALID_HANDLE;
17453
17454 h = handle - 1;
17455
17456 for (i = 0; i <= millisec / 10; i++) {
17457
17458 rp = rb[h].rp; // keep local copy for convenience
17459
17460 /* check if enough size for wp >= rp without wrap-around */
17461 if (rb[h].wp >= rp
17462 && rb[h].wp + rb[h].max_event_size <= rb[h].buffer + rb[h].size - rb[h].max_event_size) {
17463 *p = rb[h].wp;
17464 return DB_SUCCESS;
17465 }
17466
17467 /* check if enough size for wp >= rp with wrap-around */
17468 if (rb[h].wp >= rp && rb[h].wp + rb[h].max_event_size > rb[h].buffer + rb[h].size - rb[h].max_event_size &&
17469 rp > rb[h].buffer) { // next increment of wp wraps around, so need space at beginning
17470 *p = rb[h].wp;
17471 return DB_SUCCESS;
17472 }
17473
17474 /* check if enough size for wp < rp */
17475 if (rb[h].wp < rp && rb[h].wp + rb[h].max_event_size < rp) {
17476 *p = rb[h].wp;
17477 return DB_SUCCESS;
17478 }
17479
17480 if (millisec == 0)
17481 return DB_TIMEOUT;
17482
17483 if (_rb_nonblocking)
17484 return DB_TIMEOUT;
17485
17486 /* wait one time slice */
17487 ss_sleep(10);
17488 }
17489
17490 return DB_TIMEOUT;
17491}
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 17630 of file midas.cxx.

17651{
17652 int h;
17653
17654 unsigned char *new_rp;
17655 unsigned char *ep;
17656
17657 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17658 return DB_INVALID_HANDLE;
17659
17660 h = handle - 1;
17661
17662 if ((DWORD) size > rb[h].max_event_size)
17663 return DB_INVALID_PARAM;
17664
17665 new_rp = rb[h].rp + size;
17666 ep = rb[h].ep; // keep local copy of end pointer, rb[h].ep might be changed by other thread
17667
17668 /* wrap around if end pointer reached */
17669 if (new_rp >= ep && rb[h].wp < ep)
17670 new_rp = rb[h].buffer;
17671
17672 rb[handle - 1].rp = new_rp;
17673
17674 return DB_SUCCESS;
17675}
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 17502 of file midas.cxx.

17521{
17522 int h;
17523 unsigned char *new_wp;
17524
17525 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17526 return DB_INVALID_HANDLE;
17527
17528 h = handle - 1;
17529
17530 if ((DWORD) size > rb[h].max_event_size) {
17531 cm_msg(MERROR, "rb_increment_wp", "event size of %d MB larger than max_event_size of %d MB",
17532 size/1024/1024, rb[h].max_event_size/1024/1024);
17533 abort();
17534 }
17535
17536 new_wp = rb[h].wp + size;
17537
17538 /* wrap around wp if not enough space */
17539 if (new_wp > rb[h].buffer + rb[h].size - rb[h].max_event_size) {
17540 rb[h].ep = new_wp;
17541 new_wp = rb[h].buffer;
17542 assert(rb[h].rp != rb[h].buffer);
17543 } else
17544 if (new_wp > rb[h].ep)
17545 rb[h].ep = new_wp;
17546
17547 rb[h].wp = new_wp;
17548
17549 return DB_SUCCESS;
17550}
#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:915
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 17295 of file midas.cxx.

17313{
17314 _rb_nonblocking = 1;
17315
17316 return DB_SUCCESS;
17317}
Here is the caller graph for this function:

Variable Documentation

◆ _rb_nonblocking

volatile int _rb_nonblocking = 0
static

Definition at line 17284 of file midas.cxx.

◆ rb

Definition at line 17282 of file midas.cxx.