diff --git a/examples/c/circular_buffer/circular_buffer.c b/examples/c/circular_buffer/circular_buffer.c index 19b3027..9e78cd9 100644 --- a/examples/c/circular_buffer/circular_buffer.c +++ b/examples/c/circular_buffer/circular_buffer.c @@ -20,7 +20,7 @@ static void advance_pointer(cbuf_handle_t cbuf) { assert(cbuf); - if(cbuf->full) + if(circular_buf_full(cbuf)) { cbuf->tail = (cbuf->tail + 1) % cbuf->max; } @@ -78,7 +78,7 @@ size_t circular_buf_size(cbuf_handle_t cbuf) size_t size = cbuf->max; - if(!cbuf->full) + if(!circular_buf_full(cbuf)) { if(cbuf->head >= cbuf->tail) { @@ -147,7 +147,7 @@ bool circular_buf_empty(cbuf_handle_t cbuf) { assert(cbuf); - return (!cbuf->full && (cbuf->head == cbuf->tail)); + return (!circular_buf_full(cbuf) && (cbuf->head == cbuf->tail)); } bool circular_buf_full(cbuf_handle_t cbuf) diff --git a/examples/c/circular_buffer/circular_buffer_no_modulo.c b/examples/c/circular_buffer/circular_buffer_no_modulo.c new file mode 100644 index 0000000..e9e2c96 --- /dev/null +++ b/examples/c/circular_buffer/circular_buffer_no_modulo.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include + +#include "circular_buffer.h" + +// The definition of our circular buffer structure is hidden from the user +struct circular_buf_t { + uint8_t * buffer; + size_t head; + size_t tail; + size_t max; //of the buffer + bool full; +}; + +#pragma mark - Private Functions - + +static void advance_pointer(cbuf_handle_t cbuf) +{ + assert(cbuf); + + if(circular_buf_full(cbuf)) + { + if(++(cbuf->tail) == cbuf->max) + { + cbuf->tail = 0; + } + } + + if(++(cbuf->head) == cbuf->max) + { + cbuf->head = 0; + } + + // We mark full because we will advance tail on the next time around + cbuf->full = (cbuf->head == cbuf->tail); +} + +static void retreat_pointer(cbuf_handle_t cbuf) +{ + assert(cbuf); + + cbuf->full = false; + if(++(cbuf->tail) == cbuf->max) + { + cbuf->tail = 0; + } +} + +#pragma mark - APIs - + +cbuf_handle_t circular_buf_init(uint8_t* buffer, size_t size) +{ + assert(buffer && size); + + cbuf_handle_t cbuf = malloc(sizeof(circular_buf_t)); + assert(cbuf); + + cbuf->buffer = buffer; + cbuf->max = size; + circular_buf_reset(cbuf); + + assert(circular_buf_empty(cbuf)); + + return cbuf; +} + +void circular_buf_free(cbuf_handle_t cbuf) +{ + assert(cbuf); + free(cbuf); +} + +void circular_buf_reset(cbuf_handle_t cbuf) +{ + assert(cbuf); + + cbuf->head = 0; + cbuf->tail = 0; + cbuf->full = false; +} + +size_t circular_buf_size(cbuf_handle_t cbuf) +{ + assert(cbuf); + + size_t size = cbuf->max; + + if(!circular_buf_full(cbuf)) + { + if(cbuf->head >= cbuf->tail) + { + size = (cbuf->head - cbuf->tail); + } + else + { + size = (cbuf->max + cbuf->head - cbuf->tail); + } + + } + + return size; +} + +size_t circular_buf_capacity(cbuf_handle_t cbuf) +{ + assert(cbuf); + + return cbuf->max; +} + +void circular_buf_put(cbuf_handle_t cbuf, uint8_t data) +{ + assert(cbuf && cbuf->buffer); + + cbuf->buffer[cbuf->head] = data; + + advance_pointer(cbuf); +} + +int circular_buf_put2(cbuf_handle_t cbuf, uint8_t data) +{ + int r = -1; + + assert(cbuf && cbuf->buffer); + + if(!circular_buf_full(cbuf)) + { + cbuf->buffer[cbuf->head] = data; + advance_pointer(cbuf); + r = 0; + } + + return r; +} + +int circular_buf_get(cbuf_handle_t cbuf, uint8_t * data) +{ + assert(cbuf && data && cbuf->buffer); + + int r = -1; + + if(!circular_buf_empty(cbuf)) + { + *data = cbuf->buffer[cbuf->tail]; + retreat_pointer(cbuf); + + r = 0; + } + + return r; +} + +bool circular_buf_empty(cbuf_handle_t cbuf) +{ + assert(cbuf); + + return (!circular_buf_full(cbuf) && (cbuf->head == cbuf->tail)); +} + +bool circular_buf_full(cbuf_handle_t cbuf) +{ + assert(cbuf); + + return cbuf->full; +} diff --git a/examples/c/circular_buffer/circular_buffer_no_modulo_threadsafe.c b/examples/c/circular_buffer/circular_buffer_no_modulo_threadsafe.c new file mode 100644 index 0000000..484662a --- /dev/null +++ b/examples/c/circular_buffer/circular_buffer_no_modulo_threadsafe.c @@ -0,0 +1,166 @@ +#include +#include +#include +#include + +#include "circular_buffer.h" + +// The definition of our circular buffer structure is hidden from the user +struct circular_buf_t { + uint8_t * buffer; + size_t head; + size_t tail; + size_t max; //of the buffer +}; + +#pragma mark - Private Functions - + +static void advance_pointer(cbuf_handle_t cbuf) +{ + assert(cbuf); + + if(circular_buf_full(cbuf)) + { + if(++(cbuf->tail) == cbuf->max) + { + cbuf->tail = 0; + } + } + + if(++(cbuf->head) == cbuf->max) + { + cbuf->head = 0; + } +} + +static void retreat_pointer(cbuf_handle_t cbuf) +{ + assert(cbuf); + + if(++(cbuf->tail) == cbuf->max) + { + cbuf->tail = 0; + } +} + +#pragma mark - APIs - + +cbuf_handle_t circular_buf_init(uint8_t* buffer, size_t size) +{ + assert(buffer && size); + + cbuf_handle_t cbuf = malloc(sizeof(circular_buf_t)); + assert(cbuf); + + cbuf->buffer = buffer; + cbuf->max = size; + circular_buf_reset(cbuf); + + assert(circular_buf_empty(cbuf)); + + return cbuf; +} + +void circular_buf_free(cbuf_handle_t cbuf) +{ + assert(cbuf); + free(cbuf); +} + +void circular_buf_reset(cbuf_handle_t cbuf) +{ + assert(cbuf); + + cbuf->head = 0; + cbuf->tail = 0; +} + +size_t circular_buf_size(cbuf_handle_t cbuf) +{ + assert(cbuf); + + size_t size = cbuf->max; + + if(!circular_buf_full(cbuf)) + { + if(cbuf->head >= cbuf->tail) + { + size = (cbuf->head - cbuf->tail); + } + else + { + size = (cbuf->max + cbuf->head - cbuf->tail); + } + + } + + return size; +} + +size_t circular_buf_capacity(cbuf_handle_t cbuf) +{ + assert(cbuf); + + return cbuf->max; +} + +void circular_buf_put(cbuf_handle_t cbuf, uint8_t data) +{ + assert(cbuf && cbuf->buffer); + + cbuf->buffer[cbuf->head] = data; + + advance_pointer(cbuf); +} + +int circular_buf_put2(cbuf_handle_t cbuf, uint8_t data) +{ + int r = -1; + + assert(cbuf && cbuf->buffer); + + if(!circular_buf_full(cbuf)) + { + cbuf->buffer[cbuf->head] = data; + advance_pointer(cbuf); + r = 0; + } + + return r; +} + +int circular_buf_get(cbuf_handle_t cbuf, uint8_t * data) +{ + assert(cbuf && data && cbuf->buffer); + + int r = -1; + + if(!circular_buf_empty(cbuf)) + { + *data = cbuf->buffer[cbuf->tail]; + retreat_pointer(cbuf); + + r = 0; + } + + return r; +} + +bool circular_buf_empty(cbuf_handle_t cbuf) +{ + assert(cbuf); + + return (!circular_buf_full(cbuf) && (cbuf->head == cbuf->tail)); +} + +bool circular_buf_full(circular_buf_t* cbuf) +{ + // We need to handle the wraparound case + size_t head = cbuf->head + 1; + if(head == cbuf->max) + { + head = 0; + } + + return head == cbuf->tail; +} diff --git a/examples/c/meson.build b/examples/c/meson.build index 9cb6800..8dc3f46 100644 --- a/examples/c/meson.build +++ b/examples/c/meson.build @@ -17,6 +17,24 @@ executable('circular_buffer', c_args: '-DCOMPILE_AS_EXAMPLE' ) +executable('circular_buffer_no_modulo', + [ + 'circular_buffer_test.c', + 'circular_buffer/circular_buffer_no_modulo.c' + ], + include_directories: include_directories('circular_buffer'), + c_args: '-DCOMPILE_AS_EXAMPLE' +) + +executable('circular_buffer_no_modulo_threadsafe', + [ + 'circular_buffer_test.c', + 'circular_buffer/circular_buffer_no_modulo_threadsafe.c' + ], + include_directories: include_directories('circular_buffer'), + c_args: '-DCOMPILE_AS_EXAMPLE' +) + executable('malloc_aligned', 'malloc_aligned.c', c_args: '-DCOMPILE_AS_EXAMPLE',