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) |
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.
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 |
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
handle | Handle of the ring buffer |
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
handle | Handle of the buffer to get the info | |
*n_bytes | Number of bytes in buffer |
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
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. |
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
handle | Ring buffer handle | |
millisec | Optional timeout in milliseconds if buffer is full. Zero to not wait at all (non-blocking) | |
**p | Write pointer |
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.
handle | Ring buffer handle | |
size | Number of bytes to free up at current read pointer |
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
handle | Ring buffer handle | |
size | Number of bytes placed at the WP |
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
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 }