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 18693 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 18749 of file midas.cxx.

18770{
18771 int i;
18772
18773 for (i = 0; i < MAX_RING_BUFFER; i++)
18774 if (rb[i].buffer == NULL)
18775 break;
18776
18777 if (i == MAX_RING_BUFFER)
18778 return DB_NO_MEMORY;
18779
18780 if (size < max_event_size * 2)
18781 return DB_INVALID_PARAM;
18782
18783 memset(&rb[i], 0, sizeof(RING_BUFFER));
18784 rb[i].buffer = (unsigned char *) M_MALLOC(size);
18785 assert(rb[i].buffer);
18786 rb[i].size = size;
18788 rb[i].rp = rb[i].buffer;
18789 rb[i].wp = rb[i].buffer;
18790 rb[i].ep = rb[i].buffer;
18791
18792 *handle = i + 1;
18793
18794 return DB_SUCCESS;
18795}
#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:18693
static RING_BUFFER rb[MAX_RING_BUFFER]
Definition midas.cxx:18695
INT i
Definition mdump.cxx:32
INT max_event_size
Definition mfed.cxx:30
#define M_MALLOC(x)
Definition midas.h:1535
unsigned char * wp
Definition midas.cxx:18689
unsigned char * buffer
Definition midas.cxx:18685
unsigned int max_event_size
Definition midas.cxx:18687
unsigned int size
Definition midas.cxx:18686
unsigned char * rp
Definition midas.cxx:18688
unsigned char * ep
Definition midas.cxx:18690
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 18803 of file midas.cxx.

18819{
18820 if (handle < 0 || handle >= MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
18821 return DB_INVALID_HANDLE;
18822
18823 M_FREE(rb[handle - 1].buffer);
18824 rb[handle - 1].buffer = NULL;
18825 memset(&rb[handle - 1], 0, sizeof(RING_BUFFER));
18826
18827 return DB_SUCCESS;
18828}
#define DB_INVALID_HANDLE
Definition midas.h:636
#define M_FREE(x)
Definition midas.h:1537

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

19116{
19117 int h;
19118
19119 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19120 return DB_INVALID_HANDLE;
19121
19122 h = handle - 1;
19123
19124 if (rb[h].wp >= rb[h].rp)
19125 *n_bytes = (POINTER_T) rb[h].wp - (POINTER_T) rb[h].rp;
19126 else
19127 *n_bytes =
19128 (POINTER_T) rb[h].ep - (POINTER_T) rb[h].rp + (POINTER_T) rb[h].wp - (POINTER_T) rb[h].buffer;
19129
19130 return DB_SUCCESS;
19131}
#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 18981 of file midas.cxx.

19004{
19005 int i, h;
19006
19007 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19008 return DB_INVALID_HANDLE;
19009
19010 h = handle - 1;
19011
19012 for (i = 0; i <= millisec / 10; i++) {
19013
19014 if (rb[h].wp != rb[h].rp) {
19015 if (p != NULL)
19016 *p = rb[handle - 1].rp;
19017 return DB_SUCCESS;
19018 }
19019
19020 if (millisec == 0)
19021 return DB_TIMEOUT;
19022
19023 if (_rb_nonblocking)
19024 return DB_TIMEOUT;
19025
19026 /* wait one time slice */
19027 ss_sleep(10);
19028 }
19029
19030 return DB_TIMEOUT;
19031}
#define DB_TIMEOUT
Definition midas.h:656
INT ss_sleep(INT millisec)
Definition system.cxx:3707
static volatile int _rb_nonblocking
Definition midas.cxx:18697
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 18840 of file midas.cxx.

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

19064{
19065 int h;
19066
19067 unsigned char *new_rp;
19068 unsigned char *ep;
19069
19070 if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
19071 return DB_INVALID_HANDLE;
19072
19073 h = handle - 1;
19074
19075 if ((DWORD) size > rb[h].max_event_size)
19076 return DB_INVALID_PARAM;
19077
19078 new_rp = rb[h].rp + size;
19079 ep = rb[h].ep; // keep local copy of end pointer, rb[h].ep might be changed by other thread
19080
19081 /* wrap around if end pointer reached */
19082 if (new_rp >= ep && rb[h].wp < ep)
19083 new_rp = rb[h].buffer;
19084
19085 rb[handle - 1].rp = new_rp;
19086
19087 return DB_SUCCESS;
19088}
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 18915 of file midas.cxx.

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

18726{
18727 _rb_nonblocking = 1;
18728
18729 return DB_SUCCESS;
18730}
Here is the caller graph for this function:

Variable Documentation

◆ _rb_nonblocking

volatile int _rb_nonblocking = 0
static

Definition at line 18697 of file midas.cxx.

◆ rb

Definition at line 18695 of file midas.cxx.