ring_buffer: expose the zero-copy interface

This commit is contained in:
Martin Piatka
2021-08-30 14:52:49 +02:00
parent 59f547a261
commit 250eafdb48
2 changed files with 59 additions and 6 deletions

View File

@@ -93,7 +93,7 @@ static int calculate_avail_write(int start, int end, int buf_len) {
}
static int ring_get_read_regions(struct ring_buffer *ring, int max_len,
int ring_get_read_regions(struct ring_buffer *ring, int max_len,
void **ptr1, int *size1,
void **ptr2, int *size2)
{
@@ -124,7 +124,7 @@ static int ring_get_read_regions(struct ring_buffer *ring, int max_len,
return read_len;
}
static void ring_advance_read_idx(struct ring_buffer *ring, int amount) {
void ring_advance_read_idx(struct ring_buffer *ring, int amount) {
// start index is modified only by this (reader) thread, so relaxed is enough
int start = std::atomic_load_explicit(&ring->start, std::memory_order_relaxed);
@@ -161,7 +161,7 @@ void ring_buffer_flush(struct ring_buffer * buf) {
buf->end = 0;
}
static bool ring_get_write_regions(struct ring_buffer *ring, int requested_len,
int ring_get_write_regions(struct ring_buffer *ring, int requested_len,
void **ptr1, int *size1,
void **ptr2, int *size2)
{
@@ -174,7 +174,7 @@ static bool ring_get_write_regions(struct ring_buffer *ring, int requested_len,
int end = std::atomic_load_explicit(&ring->end, std::memory_order_relaxed);
if(requested_len > ring->len) {
return false;
return 0;
}
int end_idx = end % ring->len;
@@ -186,10 +186,10 @@ static bool ring_get_write_regions(struct ring_buffer *ring, int requested_len,
*size2 = requested_len - *size1;
}
return true;
return *size1 + *size2;
}
static bool ring_advance_write_idx(struct ring_buffer *ring, int amount) {
bool ring_advance_write_idx(struct ring_buffer *ring, int amount) {
const int start = std::atomic_load_explicit(&ring->start, std::memory_order_acquire);
// end index is modified only by this (writer) thread, so relaxed is enough
const int end = std::atomic_load_explicit(&ring->end, std::memory_order_relaxed);

View File

@@ -84,6 +84,59 @@ int ring_get_current_size(struct ring_buffer * ring);
*/
int ring_get_available_write_size(struct ring_buffer * ring);
/**
* Returns pointers to memory available for reading. After reading use
* ring_advance_read_idx() to mark the memory as free for writing.
*
* @param max_len cap returned size to this value
* @param ptr1 pointer to the first region
* @param size1 size of available data in the first region
* @param ptr2 pointer to the second region
* @param size2 size of available data in the second region
* @return size1 + size2
*/
int ring_get_read_regions(struct ring_buffer *ring, int max_len,
void **ptr1, int *size1,
void **ptr2, int *size2);
/**
* Marks memory as already read and free for writing. Use after reading using
* ring_get_read_regions(), or simply for discarding unwanted unread data.
*
* @param amount amount in bytes to discard
*/
void ring_advance_read_idx(struct ring_buffer *ring, int amount);
/**
* Returns pointers to memory available for writing. After writing use
* ring_advance_write_idx() to mark the memory as available for reading.
*
* Does not check for overflow, returns regions of requested size even if
* buffer is full.
*
* If the requested_len is longer than the whole buffer, returns 0.
*
* @param requested_len amount you want to write
* @param ptr1 pointer to the first region
* @param size1 size of the first region
* @param ptr2 pointer to the second region
* @param size2 size of the second region
* @return size1 + size2
*/
int ring_get_write_regions(struct ring_buffer *ring, int requested_len,
void **ptr1, int *size1,
void **ptr2, int *size2);
/**
* Marks written memory as ready for reading. Use after writing using
* ring_get_write_regions().
*
* @param amount amount in bytes to discard
* @return true if an overflow occured
*/
bool ring_advance_write_idx(struct ring_buffer *ring, int amount);
extern struct audio_buffer_api ring_buffer_fns;
#ifdef __cplusplus