Tidy up ringbuf and make tests
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
#ifndef UC_RINGBUG_H_
|
||||
#define UC_RINGBUG_H_
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct UCRingBuf UCRingBuf;
|
||||
struct UCRingBuf {
|
||||
char *base;
|
||||
uint32_t sz;
|
||||
uint32_t read_idx;
|
||||
uint32_t write_idx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new ringbuffer of at least @sz length.
|
||||
* The length will be rounded up to the neares page size
|
||||
*
|
||||
* The ringbuffer is implementd by mapping the same physical memory
|
||||
* twice into virtual memory adjacent to eachother, avoiding
|
||||
* a splitting up read/writes when the ringbuffer wraps around.
|
||||
*
|
||||
* This means accessing rb.base[rb.len] up to rb.base[rb.len * 2 - 1]
|
||||
* is accessing the same memory as rb.base[0] up to rb.base[rb.len -1]
|
||||
*
|
||||
* @param rb UCRingBuf to initialize
|
||||
* @param sz minimum length of the ring buffer
|
||||
* @returns 0 on success
|
||||
*/
|
||||
int uc_ringbuf_init(UCRingBuf *rb, uint32_t sz);
|
||||
|
||||
/** Free resources used by the ring buffer.
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int uc_ringbuf_destroy(UCRingBuf *rb);
|
||||
|
||||
/**
|
||||
* Write data to the ringbuffer. The number of bytes to write must fit
|
||||
* in the free space of the ringbuffer
|
||||
*
|
||||
* @param rb UCRingBuf to write to.
|
||||
* @param data data to write
|
||||
* @param sz number of bytes to write from data
|
||||
* @return 0 on success
|
||||
*/
|
||||
int uc_ringbuf_write(UCRingBuf *rb, const void *restrict data, uint32_t sz);
|
||||
|
||||
/** Read data from the ringbuffer
|
||||
*
|
||||
* @param rb UCRingBuf to write to.
|
||||
* @param data buffer to copy data into
|
||||
* @param sz number of bytes to read, must not exceed available data
|
||||
* in the buffer
|
||||
* @return 0 on success
|
||||
*/
|
||||
int uc_ringbuf_read(UCRingBuf *rb, void *restrict data, uint32_t sz);
|
||||
|
||||
|
||||
/** Inspect how much free space is available for writing to the ring buffer
|
||||
*
|
||||
* @param rb UCRingBuf to inspect
|
||||
* @returns number of free bytes
|
||||
*/
|
||||
uint32_t uc_ringbuf_available(const UCRingBuf *rb);
|
||||
|
||||
/**
|
||||
* Length of available data in the ringbuffer
|
||||
*
|
||||
* @param rb UCRingBuf get length of
|
||||
*
|
||||
* @return length of data available to read
|
||||
*/
|
||||
static inline uint32_t uc_ringbuf_len(const UCRingBuf *rb)
|
||||
{
|
||||
return rb->write_idx - rb->read_idx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the first unread byte
|
||||
* Caller is responsible for reading no more than the available
|
||||
* data
|
||||
*
|
||||
* @param rb UCRingBuf to peek into
|
||||
*
|
||||
* @returns pointer to first unread byte
|
||||
*/
|
||||
static inline void *uc_ringbuf_peek(const UCRingBuf *rb)
|
||||
{
|
||||
return &rb->base[rb->read_idx];
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user