Midas Ring Buffer Functions (rb_xxx)
[The midas.h & midas.c]


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)


Function Documentation

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:
size Size of ring buffer, must be larger than 2*max_event_size
max_event_size Maximum event size to be placed into
*handle Handle to ring buffer
Returns:
DB_SUCCESS, DB_NO_MEMORY, DB_INVALID_PARAM

Definition at line 13514 of file midas.c.

Referenced by initialize_equipment().

13517          : rb_create
13518 
13519   Purpose: Create a ring buffer with a given size
13520 
13521   Input:
13522     int size             Size of ring buffer, must be larger than
13523                          2*max_event_size
13524     int max_event_size   Maximum event size to be placed into
13525                          ring buffer
13526   Output:
13527     int *handle          Handle to ring buffer
13528 
13529   Function value:
13530     DB_SUCCESS           Successful completion
13531     DB_NO_MEMORY         Maximum number of ring buffers exceeded
13532     DB_INVALID_PARAM     Invalid event size specified
13533 
13534 \********************************************************************/
13535 {
13536    int i;
13537 
13538    for (i = 0; i < MAX_RING_BUFFER; i++)
13539       if (rb[i].buffer == NULL)
13540          break;
13541 
13542    if (i == MAX_RING_BUFFER)
13543       return DB_NO_MEMORY;
13544 
13545    if (size < max_event_size * 2)
13546       return DB_INVALID_PARAM;
13547 
13548    memset(&rb[i], 0, sizeof(RING_BUFFER));
13549    rb[i].buffer = (unsigned char *) M_MALLOC(size);
13550    assert(rb[i].buffer);
13551    rb[i].size = size;
13552    rb[i].max_event_size = max_event_size;
13553    rb[i].rp = rb[i].buffer;
13554    rb[i].wp = rb[i].buffer;
13555    rb[i].ep = rb[i].buffer;
13556 
13557    *handle = i + 1;
13558 
13559    return DB_SUCCESS;
13560 }

int rb_delete ( int  handle  ) 

Delete a ring buffer

Parameters:
handle Handle of the ring buffer
Returns:
DB_SUCCESS

Definition at line 13568 of file midas.c.

13571          : rb_delete
13572 
13573   Purpose: Delete a ring buffer
13574 
13575   Input:
13576     none
13577   Output:
13578     int handle       Handle to ring buffer
13579 
13580   Function value:
13581     DB_SUCCESS       Successful completion
13582 
13583 \********************************************************************/
13584 {
13585    if (handle < 0 || handle >= MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
13586       return DB_INVALID_HANDLE;
13587 
13588    M_FREE(rb[handle - 1].buffer);
13589    memset(&rb[handle - 1], 0, sizeof(RING_BUFFER));
13590 
13591    return DB_SUCCESS;
13592 }

int rb_get_buffer_level ( int  handle,
int *  n_bytes 
)

Return number of bytes in a ring buffer

Parameters:
handle Handle of the buffer to get the info
*n_bytes Number of bytes in buffer
Returns:
DB_SUCCESS, DB_INVALID_HANDLE

Definition at line 13856 of file midas.c.

Referenced by receive_trigger_event().

13859          : rb_get_buffer_level
13860 
13861   Purpose: Return number of bytes in a ring buffer
13862 
13863   Input:
13864     int handle              Handle of the buffer to get the info
13865 
13866   Output:
13867     int *n_bytes            Number of bytes in buffer
13868 
13869   Function value:
13870     DB_SUCCESS              Successful completion
13871     DB_INVALID_HANDLE       Buffer handle is invalid
13872 
13873 \********************************************************************/
13874 {
13875    int h;
13876 
13877    if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
13878       return DB_INVALID_HANDLE;
13879 
13880    h = handle - 1;
13881 
13882    if (rb[h].wp >= rb[h].rp)
13883       *n_bytes = (POINTER_T) rb[h].wp - (POINTER_T) rb[h].rp;
13884    else
13885       *n_bytes =
13886           (POINTER_T) rb[h].ep - (POINTER_T) rb[h].rp + (POINTER_T) rb[h].wp - (POINTER_T) rb[h].buffer;
13887 
13888    return DB_SUCCESS;
13889 }

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:
handle Ring buffer handle
millisec Optional timeout in milliseconds if buffer is full. Zero to not wait at all (non-blocking)
**p Address of pointer pointing to newly available data. If p == NULL, only return status.
Returns:
DB_SUCCESS, DB_TIEMOUT, DB_INVALID_HANDLE

Definition at line 13740 of file midas.c.

Referenced by receive_trigger_event().

13743          : rb_get_rp
13744 
13745   Purpose: Obtain the current read pointer at which new data is
13746            available with optional timeout
13747 
13748   Input:
13749     int handle               Ring buffer handle
13750     int millisec             Optional timeout in milliseconds if
13751                              buffer is full. Zero to not wait at
13752                              all (non-blocking)
13753 
13754   Output:
13755     char **p                 Address of pointer pointing to newly
13756                              available data. If p == NULL, only
13757                              return status.
13758 
13759   Function value:
13760     DB_SUCCESS       Successful completion
13761 
13762 \********************************************************************/
13763 {
13764    int i, h;
13765 
13766    if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
13767       return DB_INVALID_HANDLE;
13768 
13769    h = handle - 1;
13770 
13771    for (i = 0; i <= millisec / 10; i++) {
13772 
13773       if (rb[h].wp != rb[h].rp) {
13774          if (p != NULL)
13775             *p = rb[handle - 1].rp;
13776          return DB_SUCCESS;
13777       }
13778 
13779       if (millisec == 0)
13780          return DB_TIMEOUT;
13781 
13782       if (_rb_nonblocking)
13783          return DB_TIMEOUT;
13784 
13785       /* wait one time slice */
13786       ss_sleep(10);
13787    }
13788 
13789    return DB_TIMEOUT;
13790 }

int rb_get_wp ( int  handle,
void **  p,
int  millisec 
)

Retrieve write pointer where new data can be written

Parameters:
handle Ring buffer handle
millisec Optional timeout in milliseconds if buffer is full. Zero to not wait at all (non-blocking)
**p Write pointer
Returns:
DB_SUCCESS, DB_TIMEOUT, DB_INVALID_HANDLE

Definition at line 13604 of file midas.c.

Referenced by interrupt_routine(), and readout_thread().

13607        : rb_get_wp
13608 
13609   Purpose: Retrieve write pointer where new data can be written
13610 
13611   Input:
13612      int handle               Ring buffer handle
13613      int millisec             Optional timeout in milliseconds if
13614                               buffer is full. Zero to not wait at
13615                               all (non-blocking)
13616 
13617   Output:
13618     char **p                  Write pointer
13619 
13620   Function value:
13621     DB_SUCCESS       Successful completion
13622 
13623 \********************************************************************/
13624 {
13625    int h, i;
13626    unsigned char *rp;
13627 
13628    if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
13629       return DB_INVALID_HANDLE;
13630 
13631    h = handle - 1;
13632 
13633    for (i = 0; i <= millisec / 10; i++) {
13634 
13635       rp = rb[h].rp;            // keep local copy, rb[h].rp might be changed by other thread
13636 
13637       /* check if enough size for wp >= rp without wrap-around */
13638       if (rb[h].wp >= rp
13639           && rb[h].wp + rb[h].max_event_size <= rb[h].buffer + rb[h].size - rb[h].max_event_size) {
13640          *p = rb[h].wp;
13641          return DB_SUCCESS;
13642       }
13643 
13644       /* check if enough size for wp >= rp with wrap-around */
13645       if (rb[h].wp >= rp && rb[h].wp + rb[h].max_event_size > rb[h].buffer + rb[h].size - rb[h].max_event_size && rb[h].rp > rb[h].buffer) {    // next increment of wp wraps around, so need space at beginning
13646          *p = rb[h].wp;
13647          return DB_SUCCESS;
13648       }
13649 
13650       /* check if enough size for wp < rp */
13651       if (rb[h].wp < rp && rb[h].wp + rb[h].max_event_size < rp) {
13652          *p = rb[h].wp;
13653          return DB_SUCCESS;
13654       }
13655 
13656       if (millisec == 0)
13657          return DB_TIMEOUT;
13658 
13659       if (_rb_nonblocking)
13660          return DB_TIMEOUT;
13661 
13662       /* wait one time slice */
13663       ss_sleep(10);
13664    }
13665 
13666    return DB_TIMEOUT;
13667 }

int rb_increment_rp ( int  handle,
int  size 
)

Increment current read pointer, freeing up space for the writing thread.

Parameters:
handle Ring buffer handle
size Number of bytes to free up at current read pointer
Returns:
DB_SUCCESS, DB_INVALID_PARAM

Definition at line 13802 of file midas.c.

Referenced by receive_trigger_event().

13805          : rb_increment_rp
13806 
13807   Purpose: Increment current read pointer, freeing up space for
13808            the writing thread.
13809 
13810   Input:
13811      int handle               Ring buffer handle
13812      int size                 Number of bytes to free up at current
13813                               read pointer
13814 
13815   Output:
13816     NONE
13817 
13818   Function value:
13819     DB_SUCCESS                Successful completion
13820     DB_INVALID_PARAM          Event size too large or invalid handle
13821 
13822 \********************************************************************/
13823 {
13824    int h;
13825 
13826    unsigned char *new_rp, *old_rp;
13827 
13828    if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
13829       return DB_INVALID_HANDLE;
13830 
13831    h = handle - 1;
13832 
13833    if ((DWORD) size > rb[h].max_event_size)
13834       return DB_INVALID_PARAM;
13835 
13836    old_rp = rb[h].rp;
13837    new_rp = rb[h].rp + size;
13838 
13839    /* wrap around if not enough space left */
13840    if (new_rp + rb[h].max_event_size > rb[h].buffer + rb[h].size)
13841       new_rp = rb[h].buffer;
13842 
13843    rb[handle - 1].rp = new_rp;
13844 
13845    return DB_SUCCESS;
13846 }

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:
handle Ring buffer handle
size Number of bytes placed at the WP
Returns:
DB_SUCCESS, DB_INVALID_PARAM, DB_INVALID_HANDLE

Definition at line 13678 of file midas.c.

Referenced by interrupt_routine(), and readout_thread().

13681          : rb_increment_wp
13682 
13683   Purpose: Increment current write pointer, making the data at
13684            the write pointer available to the receiving thread
13685 
13686   Input:
13687      int handle               Ring buffer handle
13688      int size                 Number of bytes placed at the WP
13689 
13690   Output:
13691     NONE
13692 
13693   Function value:
13694     DB_SUCCESS                Successful completion
13695     DB_INVALID_PARAM          Event size too large or invalid handle
13696 \********************************************************************/
13697 {
13698    int h;
13699    unsigned char *old_wp, *new_wp;
13700 
13701    if (handle < 1 || handle > MAX_RING_BUFFER || rb[handle - 1].buffer == NULL)
13702       return DB_INVALID_HANDLE;
13703 
13704    h = handle - 1;
13705 
13706    if ((DWORD) size > rb[h].max_event_size)
13707       return DB_INVALID_PARAM;
13708 
13709    old_wp = rb[h].wp;
13710    new_wp = rb[h].wp + size;
13711 
13712    /* wrap around wp if not enough space */
13713    if (new_wp > rb[h].buffer + rb[h].size - rb[h].max_event_size) {
13714       rb[h].ep = new_wp;
13715       new_wp = rb[h].buffer;
13716       assert(rb[h].rp != rb[h].buffer);
13717    }
13718 
13719    rb[h].wp = new_wp;
13720 
13721    return DB_SUCCESS;
13722 }

int rb_set_nonblocking (  ) 

Set all rb_get_xx to nonblocking. Needed in multi-thread environments for stopping all theads without deadlock

Returns:
DB_SUCCESS

Definition at line 13473 of file midas.c.

Referenced by main().

13476          : rb_set_nonblocking
13477 
13478   Purpose: Set all rb_get_xx to nonblocking. Needed in multi-thread
13479            environments for stopping all theads without deadlock
13480 
13481   Input:
13482     NONE
13483 
13484   Output:
13485     NONE
13486 
13487   Function value:
13488     DB_SUCCESS       Successful completion
13489 
13490 \********************************************************************/
13491 {
13492    _rb_nonblocking = 1;
13493 
13494    return DB_SUCCESS;
13495 }


Midas DOC Version 3.0.0 ---- PSI Stefan Ritt ----
Contributions: Pierre-Andre Amaudruz - Sergio Ballestrero - Suzannah Daviel - Doxygen - Peter Green - Qing Gu - Greg Hackman - Gertjan Hofman - Paul Knowles - Exaos Lee - Rudi Meier - Glenn Moloney - Dave Morris - John M O'Donnell - Konstantin Olchanski - Renee Poutissou - Tamsen Schurman - Andreas Suter - Jan M.Wouters - Piotr Adam Zolnierczuk