diff --git a/esch_queue.c b/esch_queue.c index bf396e4..8499427 100644 --- a/esch_queue.c +++ b/esch_queue.c @@ -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; } } @@ -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; } @@ -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; diff --git a/include/esch_queue.h b/include/esch_queue.h index 5bdbcb8..49884bd 100644 --- a/include/esch_queue.h +++ b/include/esch_queue.h @@ -1,12 +1,12 @@ /** * @file esch_queue.h * @author Sergey Tkachenko (saergey.iray@yandex.ru) - * @brief + * @brief * @version 0.1 * @date 2021-07-18 - * + * * @copyright Copyright (c) 2021 - * + * */ #pragma once @@ -19,46 +19,47 @@ 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 @@ -66,11 +67,11 @@ esch_err esch_queue_create(esch_queue_t* queue); 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);