Skip to content

Commit

Permalink
Major circular buffer fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergey Tkachenko committed Apr 13, 2022
1 parent 7894c1f commit c7d2975
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 42 deletions.
38 changes: 15 additions & 23 deletions esch_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ esch_err esch_queue_create(esch_queue_t* queue)

if (queue) {
if (queue->buffer) {
queue->item_top = queue->buffer;
queue->item_current = NULL;
queue->item_end = (uint32_t*)queue->item_top + (queue->item_count) * queue->item_size;
queue->private._head = 0;
queue->private._tail = 0;
queue->private._count = 0;

if (queue->item_count > 0) {
queue->count = 0;
memset(queue->buffer, 0, queue->item_size * queue->item_count);
if (queue->item_count > 0 && queue->item_size) {
memset(queue->buffer, 0, (queue->item_size * queue->item_count));
err = ESCH_OK;
}
}
Expand All @@ -28,23 +27,17 @@ esch_err esch_queue_add(esch_queue_t* queue, void* item)

if (queue) {
if (queue->buffer) {
if (queue->count <= queue->item_count - 1) {
if (queue->item_current) {
queue->item_current = (((uint32_t*)queue->item_current + queue->item_size) == queue->item_end)
? queue->buffer
: ((uint32_t*)queue->item_current + queue->item_size);
} else {
queue->item_current = queue->buffer;
}
memcpy(queue->item_current, item, queue->item_size);
queue->count++;
if (queue->private._head != ((queue->private._tail + 1) % queue->item_count)) {
uint32_t ptr = queue->private._tail * queue->item_size + (uint32_t)queue->buffer;
memcpy((void*)ptr, item, queue->item_size);
queue->private._tail = (queue->private._tail + 1) % queue->item_count;
queue->private._count++;
err = ESCH_OK;
} else {
err = ESCH_QUEUE_FULL;
}
}
}

return err;
}

Expand All @@ -53,12 +46,11 @@ esch_err esch_queue_get(esch_queue_t* queue, void* item)
esch_err err = ESCH_FAIL;
if (queue) {
if (queue->buffer) {
if (queue->count > 0) {
memcpy(item, queue->item_top, queue->item_size);
queue->item_top = (((uint32_t*)queue->item_top + queue->item_size) == queue->item_end)
? queue->buffer
: ((uint32_t*)queue->item_top + queue->item_size);
queue->count--;
if (queue->private._head != queue->private._tail) {
uint32_t ptr = queue->private._head * queue->item_size + (uint32_t)queue->buffer;
memcpy(item, (void*)ptr, queue->item_size);
queue->private._head = (queue->private._head + 1) % queue->item_count;
queue->private._count--;
err = ESCH_OK;
} else {
err = ESCH_QUEUE_EMPTY;
Expand Down
39 changes: 20 additions & 19 deletions include/esch_queue.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/**
* @file esch_queue.h
* @author Sergey Tkachenko ([email protected])
* @brief
* @brief
* @version 0.1
* @date 2021-07-18
*
*
* @copyright Copyright (c) 2021
*
*
*/
#pragma once

Expand All @@ -19,58 +19,59 @@ extern "C" {

/**
* @brief Queue handle/descriptor
*
*
*/
typedef struct {
const uint32_t item_size; /** User-defined item size */
const uint32_t item_count; /** User-defined item count / queue length */
void* buffer; /** User-defined pointer to queue memory. Should be (item_size * item_count) in size */
void* item_top; /** Top item pointer. Should not be accessed by user */
void* item_current; /** Current item pointer. Should not be accessed by user */
void* item_end; /** Address of last item. Should not be accessed by user */
uint32_t count; /** Quantity of items in queue. Should not be accessed by user */
struct {
uint32_t _head; /** Read item index. */
uint32_t _tail; /** Write item indexm. */
uint32_t _count; /** Quantity of items in queue. */
} private; /** Should not be accessed by user */
} esch_queue_t;

/**
* @brief Initializes the queue
*
*
* ```c
* #define BUFF_SIZE 5
* static uint32_t buff[BUFF_SIZE];
*
*
* esch_queue_t queue = {
* .item_size = sizeof(uint32_t),
* .item_count = BUFF_SIZE,
* .buffer = buff
* };
*
*
* esch_queue_create(&queue);
* ```
*
*
* @note Must be called before using esch_queue_add or esch_queue_get
*
*
* @param queue Pointer to queue object
* @return esch_err
* @return esch_err
*/
esch_err esch_queue_create(esch_queue_t* queue);

/**
* @brief Adds item to the queue
*
*
* @note item is copied into user-provided buffer
*
*
* @param queue Pointer to queue object
* @param item Item pointer
* @return esch_err
*/
esch_err esch_queue_add(esch_queue_t* queue, void* item);

/**
* @brief Copies item and removes it from queue
*
* @brief Copies item and removes it from queue
*
* @param queue Pointer to queue object
* @param item Item pointer
* @return esch_err
* @return esch_err
*/
esch_err esch_queue_get(esch_queue_t* queue, void* item);

Expand Down

0 comments on commit c7d2975

Please sign in to comment.