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 18684 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 18740 of file midas.cxx.

18761{
18762 int i;
18763
18764 for (i = 0; i < MAX_RING_BUFFER; i++)
18765 if (rb[i].buffer == NULL)
18766 break;
18767
18768 if (i == MAX_RING_BUFFER)
18769 return DB_NO_MEMORY;
18770
18771 if (size < max_event_size * 2)
18772 return DB_INVALID_PARAM;
18773
18774 memset(&rb[i], 0, sizeof(RING_BUFFER));
18775 rb[i].buffer = (unsigned char *) M_MALLOC(size);
18776 assert(rb[i].buffer);
18777 rb[i].size = size;
18779 rb[i].rp = rb[i].buffer;
18780 rb[i].wp = rb[i].buffer;
18781 rb[i].ep = rb[i].buffer;
18782
18783 *handle = i + 1;
18784
18785 return DB_SUCCESS;
18786}
#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:18684
static RING_BUFFER rb[MAX_RING_BUFFER]
Definition midas.cxx:18686
INT i
Definition mdump.cxx:32
INT max_event_size
Definition mfed.cxx:30
#define M_MALLOC(x)
Definition midas.h:1551
unsigned char * wp
Definition midas.cxx:18680
unsigned char * buffer
Definition midas.cxx:18676
unsigned int max_event_size
Definition midas.cxx:18678
unsigned int size
Definition midas.cxx:18677
unsigned char * rp
Definition midas.cxx:18679
unsigned char * ep
Definition midas.cxx:18681
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 18794 of file midas.cxx.

18810{
18811 if (handle < 0 || handle >= MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
18812 return DB_INVALID_HANDLE;
18813
18814 M_FREE(rb[handle - 1].buffer);
18815 rb[handle - 1].buffer = NULL;
18816 memset(&rb[handle - 1], 0, sizeof(RING_BUFFER));
18817
18818 return DB_SUCCESS;
18819}
#define DB_INVALID_HANDLE
Definition midas.h:636
#define M_FREE(x)
Definition midas.h:1553

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

19107{
19108 int h;
19109
19110 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19111 return DB_INVALID_HANDLE;
19112
19113 h = handle - 1;
19114
19115 if (rb[h].wp >= rb[h].rp)
19116 *n_bytes = (POINTER_T) rb[h].wp - (POINTER_T) rb[h].rp;
19117 else
19118 *n_bytes =
19119 (POINTER_T) rb[h].ep - (POINTER_T) rb[h].rp + (POINTER_T) rb[h].wp - (POINTER_T) rb[h].buffer;
19120
19121 return DB_SUCCESS;
19122}
#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 18972 of file midas.cxx.

18995{
18996 int i, h;
18997
18998 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
18999 return DB_INVALID_HANDLE;
19000
19001 h = handle - 1;
19002
19003 for (i = 0; i <= millisec / 10; i++) {
19004
19005 if (rb[h].wp != rb[h].rp) {
19006 if (p != NULL)
19007 *p = rb[handle - 1].rp;
19008 return DB_SUCCESS;
19009 }
19010
19011 if (millisec == 0)
19012 return DB_TIMEOUT;
19013
19014 if (_rb_nonblocking)
19015 return DB_TIMEOUT;
19016
19017 /* wait one time slice */
19018 ss_sleep(10);
19019 }
19020
19021 return DB_TIMEOUT;
19022}
#define DB_TIMEOUT
Definition midas.h:656
INT ss_sleep(INT millisec)
Definition system.cxx:3700
static volatile int _rb_nonblocking
Definition midas.cxx:18688
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 18831 of file midas.cxx.

18851{
18852 int h, i;
18853 unsigned char *rp;
18854
18855 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
18856 return DB_INVALID_HANDLE;
18857
18858 h = handle - 1;
18859
18860 for (i = 0; i <= millisec / 10; i++) {
18861
18862 rp = rb[h].rp; // keep local copy for convenience
18863
18864 /* check if enough size for wp >= rp without wrap-around */
18865 if (rb[h].wp >= rp
18866 && rb[h].wp + rb[h].max_event_size <= rb[h].buffer + rb[h].size - rb[h].max_event_size) {
18867 *p = rb[h].wp;
18868 return DB_SUCCESS;
18869 }
18870
18871 /* check if enough size for wp >= rp with wrap-around */
18872 if (rb[h].wp >= rp && rb[h].wp + rb[h].max_event_size > rb[h].buffer + rb[h].size - rb[h].max_event_size &&
18873 rp > rb[h].buffer) { // next increment of wp wraps around, so need space at beginning
18874 *p = rb[h].wp;
18875 return DB_SUCCESS;
18876 }
18877
18878 /* check if enough size for wp < rp */
18879 if (rb[h].wp < rp && rb[h].wp + rb[h].max_event_size < rp) {
18880 *p = rb[h].wp;
18881 return DB_SUCCESS;
18882 }
18883
18884 if (millisec == 0)
18885 return DB_TIMEOUT;
18886
18887 if (_rb_nonblocking)
18888 return DB_TIMEOUT;
18889
18890 /* wait one time slice */
18891 ss_sleep(10);
18892 }
18893
18894 return DB_TIMEOUT;
18895}
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 19034 of file midas.cxx.

19055{
19056 int h;
19057
19058 unsigned char *new_rp;
19059 unsigned char *ep;
19060
19061 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19062 return DB_INVALID_HANDLE;
19063
19064 h = handle - 1;
19065
19066 if ((DWORD) size > rb[h].max_event_size)
19067 return DB_INVALID_PARAM;
19068
19069 new_rp = rb[h].rp + size;
19070 ep = rb[h].ep; // keep local copy of end pointer, rb[h].ep might be changed by other thread
19071
19072 /* wrap around if end pointer reached */
19073 if (new_rp >= ep && rb[h].wp < ep)
19074 new_rp = rb[h].buffer;
19075
19076 rb[handle - 1].rp = new_rp;
19077
19078 return DB_SUCCESS;
19079}
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 18906 of file midas.cxx.

18925{
18926 int h;
18927 unsigned char *new_wp;
18928
18929 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
18930 return DB_INVALID_HANDLE;
18931
18932 h = handle - 1;
18933
18934 if ((DWORD) size > rb[h].max_event_size) {
18935 cm_msg(MERROR, "rb_increment_wp", "event size of %d MB larger than max_event_size of %d MB",
18936 size/1024/1024, rb[h].max_event_size/1024/1024);
18937 abort();
18938 }
18939
18940 new_wp = rb[h].wp + size;
18941
18942 /* wrap around wp if not enough space */
18943 if (new_wp > rb[h].buffer + rb[h].size - rb[h].max_event_size) {
18944 rb[h].ep = new_wp;
18945 new_wp = rb[h].buffer;
18946 assert(rb[h].rp != rb[h].buffer);
18947 } else
18948 if (new_wp > rb[h].ep)
18949 rb[h].ep = new_wp;
18950
18951 rb[h].wp = new_wp;
18952
18953 return DB_SUCCESS;
18954}
#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:931
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 18699 of file midas.cxx.

18717{
18718 _rb_nonblocking = 1;
18719
18720 return DB_SUCCESS;
18721}
Here is the caller graph for this function:

Variable Documentation

◆ _rb_nonblocking

volatile int _rb_nonblocking = 0
static

Definition at line 18688 of file midas.cxx.

◆ rb

Definition at line 18686 of file midas.cxx.