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 17288 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 17344 of file midas.cxx.

17365{
17366 int i;
17367
17368 for (i = 0; i < MAX_RING_BUFFER; i++)
17369 if (rb[i].buffer == NULL)
17370 break;
17371
17372 if (i == MAX_RING_BUFFER)
17373 return DB_NO_MEMORY;
17374
17375 if (size < max_event_size * 2)
17376 return DB_INVALID_PARAM;
17377
17378 memset(&rb[i], 0, sizeof(RING_BUFFER));
17379 rb[i].buffer = (unsigned char *) M_MALLOC(size);
17380 assert(rb[i].buffer);
17381 rb[i].size = size;
17383 rb[i].rp = rb[i].buffer;
17384 rb[i].wp = rb[i].buffer;
17385 rb[i].ep = rb[i].buffer;
17386
17387 *handle = i + 1;
17388
17389 return DB_SUCCESS;
17390}
#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:17288
static RING_BUFFER rb[MAX_RING_BUFFER]
Definition midas.cxx:17290
INT i
Definition mdump.cxx:32
INT max_event_size
Definition mfed.cxx:30
#define M_MALLOC(x)
Definition midas.h:1550
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:17284
unsigned char * buffer
Definition midas.cxx:17280
unsigned int max_event_size
Definition midas.cxx:17282
unsigned int size
Definition midas.cxx:17281
unsigned char * rp
Definition midas.cxx:17283
unsigned char * ep
Definition midas.cxx:17285
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 17398 of file midas.cxx.

17414{
17415 if (handle < 0 || handle >= MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17416 return DB_INVALID_HANDLE;
17417
17418 M_FREE(rb[handle - 1].buffer);
17419 rb[handle - 1].buffer = NULL;
17420 memset(&rb[handle - 1], 0, sizeof(RING_BUFFER));
17421
17422 return DB_SUCCESS;
17423}
#define DB_INVALID_HANDLE
Definition midas.h:635
#define M_FREE(x)
Definition midas.h:1552
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 17693 of file midas.cxx.

17711{
17712 int h;
17713
17714 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
17715 return DB_INVALID_HANDLE;
17716
17717 h = handle - 1;
17718
17719 if (rb[h].wp >= rb[h].rp)
17720 *n_bytes = (POINTER_T) rb[h].wp - (POINTER_T) rb[h].rp;
17721 else
17722 *n_bytes =
17723 (POINTER_T) rb[h].ep - (POINTER_T) rb[h].rp + (POINTER_T) rb[h].wp - (POINTER_T) rb[h].buffer;
17724
17725 return DB_SUCCESS;
17726}
#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 17576 of file midas.cxx.

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

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

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

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

17321{
17322 _rb_nonblocking = 1;
17323
17324 return DB_SUCCESS;
17325}
Here is the caller graph for this function:

Variable Documentation

◆ _rb_nonblocking

volatile int _rb_nonblocking = 0
static

Definition at line 17292 of file midas.cxx.

◆ rb

Definition at line 17290 of file midas.cxx.