Public Attributes | |
txc_buffermgr_t * | manager |
char * | buf |
unsigned int | size_max |
unsigned int | primary_head |
unsigned int | primary_tail |
unsigned int | secondary_head |
unsigned int | secondary_tail |
unsigned int | speculative_primary_head |
unsigned int | speculative_primary_tail |
unsigned int | speculative_secondary_head |
unsigned int | speculative_secondary_tail |
txc_buffer_state_t | state |
The circular buffer is implemented using two queues: a primary queue <primary_head, primary_tail> and a secondary queue <secondary_head, secondary_tail>. The two queues use a contiguous region of the same buffer (buf) and they never overlap. Data are copied to the primary queue, and when there is no space, data are copied to the secondary queue. There is no space in a queue if the tail would have to extend beyond the end of the buffer or extend into the buffer region of the other queue.
When a primary queue is emptied, the secondary queue becomes the new primary queue and the old primary the new secondary.
We chose to implement a circular buffer this way instead of simply using a single pair <head, tail> to avoid wrapping the head and tail pointers around to the beginning of the buffer region. The wrap around would result in a non-contiguous queue region. When reading data from the kernel (using a system call) would require either to bring the data into the two separate regions by doing two system calls or bring the data into an intermediate contiguous buffer to avoid crossing the kernel-user interface two times. The downside of using two queues is internal fragmentation.
Definition at line 35 of file buffer.h.