From fa8167b94d13e94a6cb953e7f549a89f155f77c6 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 21 Jan 2015 17:26:24 +1000 Subject: Big file rename to reduce problems with brain-dead IDE's that don't handle project file hierarchies well. Naming is more consistent with the new scheme. May affect some third party drivers (header file renames). --- src/gqueue/gqueue.c | 464 +++++++++++++++++++++++++++++++++++++++++++ src/gqueue/gqueue.h | 412 ++++++++++++++++++++++++++++++++++++++ src/gqueue/gqueue.mk | 1 + src/gqueue/gqueue_gqueue.c | 469 -------------------------------------------- src/gqueue/gqueue_options.h | 59 ++++++ src/gqueue/gqueue_rules.h | 30 +++ src/gqueue/sys_defs.h | 412 -------------------------------------- src/gqueue/sys_make.mk | 1 - src/gqueue/sys_options.h | 59 ------ src/gqueue/sys_rules.h | 30 --- 10 files changed, 966 insertions(+), 971 deletions(-) create mode 100644 src/gqueue/gqueue.c create mode 100644 src/gqueue/gqueue.h create mode 100644 src/gqueue/gqueue.mk delete mode 100644 src/gqueue/gqueue_gqueue.c create mode 100644 src/gqueue/gqueue_options.h create mode 100644 src/gqueue/gqueue_rules.h delete mode 100644 src/gqueue/sys_defs.h delete mode 100644 src/gqueue/sys_make.mk delete mode 100644 src/gqueue/sys_options.h delete mode 100644 src/gqueue/sys_rules.h (limited to 'src/gqueue') diff --git a/src/gqueue/gqueue.c b/src/gqueue/gqueue.c new file mode 100644 index 00000000..1205143f --- /dev/null +++ b/src/gqueue/gqueue.c @@ -0,0 +1,464 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +#include "gfx.h" + +#if GFX_USE_GQUEUE + +#if GQUEUE_NEED_BUFFERS + static gfxQueueGSync bufferFreeList; +#endif + +void _gqueueInit(void) +{ + #if GQUEUE_NEED_BUFFERS + gfxQueueGSyncInit(&bufferFreeList); + #endif +} + +void _gqueueDeinit(void) +{ +} + +#if GQUEUE_NEED_ASYNC + void gfxQueueASyncInit(gfxQueueASync *pqueue) { + pqueue->head = pqueue->tail = 0; + } + + gfxQueueASyncItem *gfxQueueASyncGet(gfxQueueASync *pqueue) { + gfxQueueASyncItem *pi; + + // This is just a shortcut to speed execution + if (!pqueue->head) + return 0; + + gfxSystemLock(); + pi = gfxQueueASyncGetI(pqueue); + gfxSystemUnlock(); + + return pi; + } + gfxQueueASyncItem *gfxQueueASyncGetI(gfxQueueASync *pqueue) { + gfxQueueASyncItem *pi; + + if ((pi = pqueue->head)) { + pqueue->head = pi->next; + pi->next = 0; + } + + return pi; + } + + void gfxQueueASyncPut(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { + gfxSystemLock(); + gfxQueueASyncPutI(pqueue, pitem); + gfxSystemUnlock(); + } + void gfxQueueASyncPutI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { + if (!pitem) return; // Safety + pitem->next = 0; + if (!pqueue->head) { + pqueue->head = pqueue->tail = pitem; + } else { + pqueue->tail->next = pitem; + pqueue->tail = pitem; + } + } + + void gfxQueueASyncPush(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { + gfxSystemLock(); + gfxQueueASyncPushI(pqueue, pitem); + gfxSystemUnlock(); + } + void gfxQueueASyncPushI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { + if (!pitem) return; // Safety + pitem->next = pqueue->head; + pqueue->head = pitem; + if (!pitem->next) + pqueue->tail = pitem; + } + + void gfxQueueASyncInsert(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter) { + gfxSystemLock(); + gfxQueueASyncInsertI(pqueue, pitem, pafter); + gfxSystemUnlock(); + } + void gfxQueueASyncInsertI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter) { + if (!pitem) return; // Safety + + if (pafter && gfxQueueASyncIsInI(pqueue, pafter)) { + pitem->next = pafter->next; + pafter->next = pitem; + if (pqueue->tail == pafter) + pqueue->tail = pitem; + } else { + pitem->next = 0; + if (!pqueue->head) { + pqueue->head = pqueue->tail = pitem; + } else { + pqueue->tail->next = pitem; + pqueue->tail = pitem; + } + } + } + + void gfxQueueASyncRemove(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { + gfxSystemLock(); + gfxQueueASyncRemoveI(pqueue, pitem); + gfxSystemUnlock(); + } + void gfxQueueASyncRemoveI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { + gfxQueueASyncItem *pi; + + if (!pitem) return; // Safety + if (pqueue->head) { + if (pqueue->head == pitem) { + pqueue->head = pitem->next; + pitem->next = 0; + } else { + for(pi = pqueue->head; pi->next; pi = pi->next) { + if (pi->next == pitem) { + pi->next = pitem->next; + if (pqueue->tail == pitem) + pqueue->tail = pi; + pitem->next = 0; + break; + } + } + } + } + } + + bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem) { + bool_t res; + + gfxSystemLock(); + res = gfxQueueASyncIsInI(pqueue, pitem); + gfxSystemUnlock(); + + return res; + } + bool_t gfxQueueASyncIsInI(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem) { + gfxQueueASyncItem *pi; + + for(pi = pqueue->head; pi; pi = pi->next) { + if (pi == pitem) + return TRUE; + } + return FALSE; + } +#endif + +#if GQUEUE_NEED_GSYNC + void gfxQueueGSyncInit(gfxQueueGSync *pqueue) { + pqueue->head = pqueue->tail = 0; + gfxSemInit(&pqueue->sem, 0, MAX_SEMAPHORE_COUNT); + } + void gfxQueueGSyncDeinit(gfxQueueGSync *pqueue) { + pqueue->head = pqueue->tail = 0; + gfxSemDestroy(&pqueue->sem); + } + + gfxQueueGSyncItem *gfxQueueGSyncGet(gfxQueueGSync *pqueue, delaytime_t ms) { + gfxQueueGSyncItem *pi; + + if (!gfxSemWait(&pqueue->sem, ms)) + return 0; + + gfxSystemLock(); + pi = pqueue->head; + pqueue->head = pi->next; + pi->next = 0; + gfxSystemUnlock(); + + return pi; + } + gfxQueueGSyncItem *gfxQueueGSyncGetI(gfxQueueGSync *pqueue) { + gfxQueueGSyncItem *pi; + + if (!gfxSemWaitI(&pqueue->sem)) + return 0; + + pi = pqueue->head; + pqueue->head = pi->next; + pi->next = 0; + return pi; + } + + void gfxQueueGSyncPut(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { + gfxSystemLock(); + gfxQueueGSyncPutI(pqueue, pitem); + gfxSystemUnlock(); + } + void gfxQueueGSyncPutI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { + if (!pitem) return; // Safety + pitem->next = 0; + if (!pqueue->head) { + pqueue->head = pqueue->tail = pitem; + } else { + pqueue->tail->next = pitem; + pqueue->tail = pitem; + } + gfxSemSignalI(&pqueue->sem); + } + + void gfxQueueGSyncPush(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { + gfxSystemLock(); + gfxQueueGSyncPushI(pqueue, pitem); + gfxSystemUnlock(); + } + void gfxQueueGSyncPushI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { + if (!pitem) return; // Safety + pitem->next = pqueue->head; + pqueue->head = pitem; + if (!pitem->next) + pqueue->tail = pitem; + gfxSemSignalI(&pqueue->sem); + } + + void gfxQueueGSyncInsert(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter) { + gfxSystemLock(); + gfxQueueGSyncInsertI(pqueue, pitem, pafter); + gfxSystemUnlock(); + } + void gfxQueueGSyncInsertI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter) { + if (!pitem) return; // Safety + + if (pafter && gfxQueueGSyncIsInI(pqueue, pafter)) { + pitem->next = pafter->next; + pafter->next = pitem; + if (pqueue->tail == pafter) + pqueue->tail = pitem; + } else { + pitem->next = 0; + if (!pqueue->head) { + pqueue->head = pqueue->tail = pitem; + } else { + pqueue->tail->next = pitem; + pqueue->tail = pitem; + } + } + } + + void gfxQueueGSyncRemove(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { + gfxSystemLock(); + gfxQueueGSyncRemoveI(pqueue, pitem); + gfxSystemUnlock(); + } + void gfxQueueGSyncRemoveI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { + gfxQueueGSyncItem *pi; + + if (!pitem) return; // Safety + if (pqueue->head) { + if (pqueue->head == pitem) { + pqueue->head = pitem->next; + pitem->next = 0; + } else { + for(pi = pqueue->head; pi->next; pi = pi->next) { + if (pi->next == pitem) { + pi->next = pitem->next; + if (pqueue->tail == pitem) + pqueue->tail = pi; + pitem->next = 0; + break; + } + } + } + } + } + + bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem) { + bool_t res; + + gfxSystemLock(); + res = gfxQueueGSyncIsInI(pqueue, pitem); + gfxSystemUnlock(); + + return res; + } + bool_t gfxQueueGSyncIsInI(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem) { + gfxQueueGSyncItem *pi; + + for(pi = pqueue->head; pi; pi = pi->next) { + if (pi == pitem) + return TRUE; + } + return FALSE; + } +#endif + +#if GQUEUE_NEED_FSYNC + void gfxQueueFSyncInit(gfxQueueFSync *pqueue) { + pqueue->head = pqueue->tail = 0; + gfxSemInit(&pqueue->sem, 0, MAX_SEMAPHORE_COUNT); + } + void gfxQueueFSyncDeinit(gfxQueueGSync *pqueue) { + while(gfxQueueFSyncGet(pqueue, TIME_IMMEDIATE)); + pqueue->head = pqueue->tail = 0; + gfxSemDestroy(&pqueue->sem); + } + + gfxQueueFSyncItem *gfxQueueFSyncGet(gfxQueueFSync *pqueue, delaytime_t ms) { + gfxQueueFSyncItem *pi; + + if (!gfxSemWait(&pqueue->sem, ms)) + return 0; + + gfxSystemLock(); + pi = pqueue->head; + pqueue->head = pi->next; + pi->next = 0; + gfxSystemUnlock(); + + gfxSemSignal(&pi->sem); + gfxSemDestroy(&pi->sem); + + return pi; + } + + bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms) { + if (!pitem) return; // Safety + gfxSemInit(&pitem->sem, 0, 1); + pitem->next = 0; + + gfxSystemLock(); + if (!pqueue->head) { + pqueue->head = pqueue->tail = pitem; + } else { + pqueue->tail->next = pitem; + pqueue->tail = pitem; + } + gfxSystemUnlock(); + + gfxSemSignal(&pqueue->sem); + + return gfxSemWait(&pitem->sem, ms); + } + + bool_t gfxQueueFSyncPush(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms) { + if (!pitem) return; // Safety + gfxSemInit(&pitem->sem, 0, 1); + + gfxSystemLock(); + pitem->next = pqueue->head; + pqueue->head = pitem; + if (!pitem->next) + pqueue->tail = pitem; + gfxSystemUnlock(); + + gfxSemSignal(&pqueue->sem); + + return gfxSemWait(&pitem->sem, ms); + } + + bool_t gfxQueueFSyncInsert(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, gfxQueueASyncItem *pafter, delaytime_t ms) { + if (!pitem) return; // Safety + gfxSemInit(&pitem->sem, 0, 1); + + gfxSystemLock(); + if (pafter && gfxQueueGSyncIsInI(pqueue, pafter)) { + pitem->next = pafter->next; + pafter->next = pitem; + if (pqueue->tail == pafter) + pqueue->tail = pitem; + } else { + pitem->next = 0; + if (!pqueue->head) { + pqueue->head = pqueue->tail = pitem; + } else { + pqueue->tail->next = pitem; + pqueue->tail = pitem; + } + } + gfxSystemUnlock(); + + gfxSemSignal(&pqueue->sem); + + return gfxSemWait(&pitem->sem, ms); + + } + + void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem) { + gfxQueueFSyncItem *pi; + + if (!pitem) return; // Safety + gfxSystemLock(); + if (pqueue->head) { + if (pqueue->head == pitem) { + pqueue->head = pitem->next; + found: + pitem->next = 0; + gfxSystemUnlock(); + gfxSemSignal(&pitem->sem); + gfxSemDestroy(&pitem->sem); + return; + } + for(pi = pqueue->head; pi->next; pi = pi->next) { + if (pi->next == pitem) { + pi->next = pitem->next; + if (pqueue->tail == pitem) + pqueue->tail = pi; + goto found; + } + } + } + gfxSystemUnlock(); + } + + bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem) { + bool_t res; + + gfxSystemLock(); + res = gfxQueueFSyncIsInI(pqueue, pitem); + gfxSystemUnlock(); + + return res; + } + bool_t gfxQueueFSyncIsInI(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem) { + gfxQueueASyncItem *pi; + + for(pi = pqueue->head; pi; pi = pi->next) { + if (pi == pitem) + return TRUE; + } + return FALSE; + } +#endif + +#if GQUEUE_NEED_BUFFERS + bool_t gfxBufferAlloc(unsigned num, size_t size) { + GDataBuffer *pd; + + if (num < 1) + return FALSE; + + // Round up to a multiple of 4 to prevent problems with structure alignment + size = (size + 3) & ~0x03; + + // Allocate the memory + if (!(pd = gfxAlloc((size+sizeof(GDataBuffer)) * num))) + return FALSE; + + // Add each of them to our free list + for(;num--; pd = (GDataBuffer *)((char *)(pd+1)+size)) { + pd->size = size; + gfxBufferRelease(pd); + } + + return TRUE; + } + + void gfxBufferRelease(GDataBuffer *pd) { gfxQueueGSyncPut(&bufferFreeList, (gfxQueueGSyncItem *)pd); } + void gfxBufferReleaseI(GDataBuffer *pd) { gfxQueueGSyncPutI(&bufferFreeList, (gfxQueueGSyncItem *)pd); } + GDataBuffer *gfxBufferGet(delaytime_t ms) { return (GDataBuffer *)gfxQueueGSyncGet(&bufferFreeList, ms); } + GDataBuffer *gfxBufferGetI(void) { return (GDataBuffer *)gfxQueueGSyncGetI(&bufferFreeList); } + bool_t gfxBufferIsAvailable(void) { return bufferFreeList.head != 0; } + +#endif + + +#endif /* GFX_USE_GQUEUE */ diff --git a/src/gqueue/gqueue.h b/src/gqueue/gqueue.h new file mode 100644 index 00000000..924024b7 --- /dev/null +++ b/src/gqueue/gqueue.h @@ -0,0 +1,412 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gqueue/gqueue.h + * @brief GQUEUE header file. + * + * @addtogroup GQUEUE + * + * @brief Module which provides queue management (only internally used) + * + * @details There are 3 types of queues: + * + * We need 4 types of queues even though fully synchronous queues support all operations including asynchronous + * operations because fully synchronous queues have the highest storage requirements. The other queue types are + * optimizations. Efficiency IS important to use (particularly RAM efficiency). + * In practice we only implement ASync, GSync and FSync queues as PSync queues are of dubious value. + *
+ * We also define GDataBuffer which is a data buffer that supports being queued. + * @{ + */ + +#ifndef _GQUEUE_H +#define _GQUEUE_H + +#if GFX_USE_GQUEUE || defined(__DOXYGEN__) + +/** + * @brief A queue item + * @{ + */ +typedef struct gfxQueueASyncItem { + struct gfxQueueASyncItem *next; +} gfxQueueASyncItem, gfxQueueGSyncItem; + +typedef struct gfxQueueFSyncItem { + struct gfxQueueFSyncItem *next; + gfxSem sem; +} gfxQueueFSyncItem; +/** @} */ + +/** + * @brief A queue + * @{ + */ +typedef struct gfxQueueASync { + gfxQueueASyncItem *head; + gfxQueueASyncItem *tail; +} gfxQueueASync; + +typedef struct gfxQueueGSync { + gfxQueueGSyncItem *head; + gfxQueueGSyncItem *tail; + gfxSem sem; +} gfxQueueGSync; + +typedef struct gfxQueueFSync { + gfxQueueFSyncItem *head; + gfxQueueFSyncItem *tail; + gfxSem sem; +} gfxQueueFSync; +/** @} */ + +/** + * @brief A Data Buffer Queue + * @note This structure is followed immediately by the data itself. + * When allocating the buffers for the data put this structure + * at the beginning of the buffer. + */ +typedef struct GDataBuffer { + gfxQueueGSyncItem next; // @< Used for queueing the buffers + size_t size; // @< The size of the buffer area following this structure (in bytes) + size_t len; // @< The length of the data in the buffer area (in bytes) +} GDataBuffer; + +/*===========================================================================*/ +/* Function declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Initialisation functions + * @brief Initialise a queue. + * + * @param[in] pqueue A pointer to the queue + * + * @note Whilst queues are normally FIFO, a GFX queue also supports push and pop operations. + * A pop operation is the same as normal get from the queue but a push places the item + * at the head of the queue instead of the tail (as a put would). + * + * @api + * @{ + */ +void gfxQueueASyncInit(gfxQueueASync *pqueue); +void gfxQueueGSyncInit(gfxQueueGSync *pqueue); +void gfxQueueFSyncInit(gfxQueueFSync *pqueue); +/** @} */ + +/** + * @name Deinitialisation functions + * @brief De-Initialise a queue. + * + * @param[in] pqueue A pointer to the queue + * + * @api + * @{ + */ +#define gfxQueueASyncDeinit(pqueue) +void gfxQueueGSyncDeinit(gfxQueueGSync *pqueue); +void gfxQueueFSyncDeinit(gfxQueueFSync *pqueue); +/** @} */ + +/** + * @name Get() Functions + * @brief Get an item from the head of the queue (and remove it from the queue). + * @return NULL if the timeout expires before an item is available + * + * @param[in] pqueue A pointer to the queue + * @param[in] ms The maxmimum time to wait for an item. For ASync queues this parameter is + * not specified as TIME_IMMEDIATE is assumed. + * + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +gfxQueueASyncItem *gfxQueueASyncGet(gfxQueueASync *pqueue); +gfxQueueASyncItem *gfxQueueASyncGetI(gfxQueueASync *pqueue); +gfxQueueGSyncItem *gfxQueueGSyncGet(gfxQueueGSync *pqueue, delaytime_t ms); +gfxQueueGSyncItem *gfxQueueGSyncGetI(gfxQueueGSync *pqueue); +gfxQueueFSyncItem *gfxQueueFSyncGet(gfxQueueFSync *pqueue, delaytime_t ms); +/** @} */ + +/** + * @name Put() Functions + * @brief Put an item on the end of the queue. + * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE + * + * @param[in] pqueue A pointer to the queue + * @param[in] pitem A pointer to the queue item + * @param[in] ms The maxmimum time to wait for an item to be removed from the queue (only for FSync queues) + * + * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the + * item is removed from the queue. Note that even if the timeout occurs - the item + * remains in the queue. + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +void gfxQueueASyncPut(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); +void gfxQueueASyncPutI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); +void gfxQueueGSyncPut(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); +void gfxQueueGSyncPutI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); +bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms); +/** @} */ + +/** + * @name Pop() Functions + * @brief Pop an item from the head of the queue (and remove it from the queue). + * @details This is exactly the same as the Get operation above. + * + * @api + * @{ + */ +#define gfxQueueASyncPop(pqueue) gfxQueueASyncGet(pqueue) +#define gfxQueueASyncPopI(pqueue) gfxQueueASyncGetI(pqueue) +#define gfxQueueGSyncPop(pqueue, ms) gfxQueueGSyncGet(pqueue, ms) +#define gfxQueueFSyncPop(pqueue, ms) gfxQueueFSyncGet(pqueue, ms) +/** @} */ + +/** + * @name Push() Functions + * @brief Push an item into the start of the queue. + * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE + * + * @param[in] pqueue A pointer to the queue + * @param[in] pitem A pointer to the queue item + * @param[in] ms The maxmimum time to wait for an item to be popped (only for FSync queues) + * + * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the + * item is removed from the queue. Note that even if the timeout occurs - the item + * remains in the queue. + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +void gfxQueueASyncPush(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); +void gfxQueueASyncPushI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); +void gfxQueueGSyncPush(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); +void gfxQueueGSyncPushI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); +bool_t gfxQueueFSyncPush(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms); +/** @} */ + +/** + * @name Insert() Functions + * @brief Insert an item on the queue after the specified item. + * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE + * + * @param[in] pqueue A pointer to the queue + * @param[in] pitem A pointer to the queue item + * @param[in] pafter A pointer to the queue item this new item must be inserted after. If NULL or + * pafter can't be found in the queue, it puts the new item at the end of the queue. + * @param[in] ms The maxmimum time to wait for an item to be removed from the queue (only for FSync queues) + * + * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the + * item is removed from the queue. Note that even if the timeout occurs - the item + * remains in the queue. + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +void gfxQueueASyncInsert(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter); +void gfxQueueASyncInsertI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter); +void gfxQueueGSyncInsert(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter); +void gfxQueueGSyncInsertI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter); +bool_t gfxQueueFSyncInsert(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, gfxQueueASyncItem *pafter, delaytime_t ms); +/** @} */ + +/** + * @name Remove() Functions + * @brief Remove an item from the queue. + * @note Removes the specified item from the queue where-ever it is in the queue + * + * @param[in] pqueue A pointer to the queue + * @param[in] pitem A pointer to the queue item + * + * @note If the item isn't in the queue the routine just returns. + * @note If a process is waiting on the Put/Push operation for the item, that process + * will be signaled. + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +void gfxQueueASyncRemove(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); +void gfxQueueASyncRemoveI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); +void gfxQueueGSyncRemove(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); +void gfxQueueGSyncRemoveI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); +void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem); +/** @} */ + +/** + * @name isEmpty() Functions + * @brief Is the queue empty? + * @return TRUE if the queue is empty + * + * @param[in] pqueue A pointer to the queue + * + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +#define gfxQueueASyncIsEmpty(pqueue) ((pqueue)->head == 0) +#define gfxQueueASyncIsEmptyI(pqueue) ((pqueue)->head == 0) +#define gfxQueueGSyncIsEmpty(pqueue) ((pqueue)->head == 0) +#define gfxQueueGSyncIsEmptyI(pqueue) ((pqueue)->head == 0) +#define gfxQueueFSyncIsEmpty(pqueue) ((pqueue)->head == 0) +#define gfxQueueFSyncIsEmptyI(pqueue) ((pqueue)->head == 0) +/** @} */ + +/** + * @name IsInQueue() Functions + * @brief Is an item in the queue? + * @return TRUE if the item is in the queue? + * + * @param[in] pqueue A pointer to the queue + * @param[in] pitem A pointer to the queue item + * + * @note This operation may be expensive. + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem); +bool_t gfxQueueASyncIsInI(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem); +bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem); +bool_t gfxQueueGSyncIsInI(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem); +bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem); +bool_t gfxQueueFSyncIsInI(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem); +/** @} */ + +/** + * @name Peek() Functions + * @brief Get the first item from the head of the queue but do not remove it from the queue. + * @return NULL if no item is available. + * + * @param[in] pqueue A pointer to the queue + * + * @note This call does not block. + * @note This can be used as the first call to iterate all the elements in the queue. + * @note As that item is still on the queue, it should be treated as read-only. It could + * also be removed from the queue at any time by another thread (thereby altering the + * queue item). + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +#define gfxQueueASyncPeek(pqueue) ((const gfxQueueASyncItem *)((pqueue)->head)) +#define gfxQueueASyncPeekI(pqueue) ((const gfxQueueASyncItem *)((pqueue)->head)) +#define gfxQueueGSyncPeek(pqueue) ((const gfxQueueGSyncItem *)((pqueue)->head)) +#define gfxQueueGSyncPeekI(pqueue) ((const gfxQueueGSyncItem *)((pqueue)->head)) +#define gfxQueueFSyncPeek(pqueue) ((const gfxQueueFSyncItem *)((pqueue)->head)) +#define gfxQueueFSyncPeekI(pqueue) ((const gfxQueueFSyncItem *)((pqueue)->head)) +/** @} */ + +/** + * @name Next() Functions + * @brief Get the next item in the queue (but do not remove it from the queue). + * @return NULL if no item is available. + * + * @param[in] pitem The previous item in the queue + * + * @note This call does not block. + * @note This can be used as subsequent calls to iterate all the elements in the queue. + * @note As that item is still on the queue, it should be treated as read-only. It could + * also be removed from the queue at any time by another thread (thereby altering the + * queue item). + * @note The routines ending in "I" are interrupt/system/iclass level routines. + * + * @api + * @{ + */ +#define gfxQueueASyncNext(pitem) ((const gfxQueueASyncItem *)((pitem)->next)) +#define gfxQueueASyncNextI(pitem) ((const gfxQueueASyncItem *)((pitem)->next)) +#define gfxQueueGSyncNext(pitem) ((const gfxQueueGSyncItem *)((pitem)->next)) +#define gfxQueueGSyncNextI(pitem) ((const gfxQueueGSyncItem *)((pitem)->next)) +#define gfxQueueFSyncNext(pitem) ((const gfxQueueFSyncItem *)((pitem)->next)) +#define gfxQueueFSyncNextI(pitem) ((const gfxQueueFSyncItem *)((pitem)->next)) +/** @} */ + +/** + * @name BufferAlloc() Functions + * @brief Allocate some buffers and put them on the free list + * @return TRUE is it succeeded. FALSE on allocation failure. + * + * @param[in] num The number of buffers to allocate + * @param[in] size The size (in bytes) of each buffer + * + * @api + * @{ + */ +bool_t gfxBufferAlloc(unsigned num, size_t size); +/** @} */ + +/** + * @name BufferIsAvailable() Functions + * @brief Is there one or more buffers currently available on the free list + * @return TRUE if there are buffers in the free list + * + * @api + * @{ + */ +bool_t gfxBufferIsAvailable(void); +/** @} */ + +/** + * @name BufferGet() Functions + * @brief Get a buffer from the free list + * @return A GDataBuffer pointer or NULL if the timeout is exceeded + * + * @param[in] ms The maximum amount of time in milliseconds to wait for a buffer if one is not available. + * + * @api + * @{ + */ +GDataBuffer *gfxBufferGet(delaytime_t ms); +GDataBuffer *gfxBufferGetI(void); +/** @} */ + +/** + * @name BufferRelease) Functions + * @brief Release a buffer back to the free list + * + * @param[in] pd The buffer to put (back) on the free-list. + * + * @note This call should be used to return any buffers that were taken from + * the free-list once they have been finished with. It can also be used + * to put new buffers onto the free-list. Just make sure the "size" field + * of the GDataBuffer structure has been filled in first. + * + * @api + * @{ + */ +void gfxBufferRelease(GDataBuffer *pd); +void gfxBufferReleaseI(GDataBuffer *pd); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_USE_GQUEUE */ +#endif /* _GQUEUE_H */ +/** @} */ diff --git a/src/gqueue/gqueue.mk b/src/gqueue/gqueue.mk new file mode 100644 index 00000000..ab8a0423 --- /dev/null +++ b/src/gqueue/gqueue.mk @@ -0,0 +1 @@ +GFXSRC += $(GFXLIB)/src/gqueue/gqueue.c diff --git a/src/gqueue/gqueue_gqueue.c b/src/gqueue/gqueue_gqueue.c deleted file mode 100644 index 5a50c64b..00000000 --- a/src/gqueue/gqueue_gqueue.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gqueue/gqueue_gqueue.c - * @brief GQUEUE source file. - */ - -#include "gfx.h" - -#if GFX_USE_GQUEUE - -#if GQUEUE_NEED_BUFFERS - static gfxQueueGSync bufferFreeList; -#endif - -void _gqueueInit(void) -{ - #if GQUEUE_NEED_BUFFERS - gfxQueueGSyncInit(&bufferFreeList); - #endif -} - -void _gqueueDeinit(void) -{ -} - -#if GQUEUE_NEED_ASYNC - void gfxQueueASyncInit(gfxQueueASync *pqueue) { - pqueue->head = pqueue->tail = 0; - } - - gfxQueueASyncItem *gfxQueueASyncGet(gfxQueueASync *pqueue) { - gfxQueueASyncItem *pi; - - // This is just a shortcut to speed execution - if (!pqueue->head) - return 0; - - gfxSystemLock(); - pi = gfxQueueASyncGetI(pqueue); - gfxSystemUnlock(); - - return pi; - } - gfxQueueASyncItem *gfxQueueASyncGetI(gfxQueueASync *pqueue) { - gfxQueueASyncItem *pi; - - if ((pi = pqueue->head)) { - pqueue->head = pi->next; - pi->next = 0; - } - - return pi; - } - - void gfxQueueASyncPut(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { - gfxSystemLock(); - gfxQueueASyncPutI(pqueue, pitem); - gfxSystemUnlock(); - } - void gfxQueueASyncPutI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { - if (!pitem) return; // Safety - pitem->next = 0; - if (!pqueue->head) { - pqueue->head = pqueue->tail = pitem; - } else { - pqueue->tail->next = pitem; - pqueue->tail = pitem; - } - } - - void gfxQueueASyncPush(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { - gfxSystemLock(); - gfxQueueASyncPushI(pqueue, pitem); - gfxSystemUnlock(); - } - void gfxQueueASyncPushI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { - if (!pitem) return; // Safety - pitem->next = pqueue->head; - pqueue->head = pitem; - if (!pitem->next) - pqueue->tail = pitem; - } - - void gfxQueueASyncInsert(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter) { - gfxSystemLock(); - gfxQueueASyncInsertI(pqueue, pitem, pafter); - gfxSystemUnlock(); - } - void gfxQueueASyncInsertI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter) { - if (!pitem) return; // Safety - - if (pafter && gfxQueueASyncIsInI(pqueue, pafter)) { - pitem->next = pafter->next; - pafter->next = pitem; - if (pqueue->tail == pafter) - pqueue->tail = pitem; - } else { - pitem->next = 0; - if (!pqueue->head) { - pqueue->head = pqueue->tail = pitem; - } else { - pqueue->tail->next = pitem; - pqueue->tail = pitem; - } - } - } - - void gfxQueueASyncRemove(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { - gfxSystemLock(); - gfxQueueASyncRemoveI(pqueue, pitem); - gfxSystemUnlock(); - } - void gfxQueueASyncRemoveI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) { - gfxQueueASyncItem *pi; - - if (!pitem) return; // Safety - if (pqueue->head) { - if (pqueue->head == pitem) { - pqueue->head = pitem->next; - pitem->next = 0; - } else { - for(pi = pqueue->head; pi->next; pi = pi->next) { - if (pi->next == pitem) { - pi->next = pitem->next; - if (pqueue->tail == pitem) - pqueue->tail = pi; - pitem->next = 0; - break; - } - } - } - } - } - - bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem) { - bool_t res; - - gfxSystemLock(); - res = gfxQueueASyncIsInI(pqueue, pitem); - gfxSystemUnlock(); - - return res; - } - bool_t gfxQueueASyncIsInI(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem) { - gfxQueueASyncItem *pi; - - for(pi = pqueue->head; pi; pi = pi->next) { - if (pi == pitem) - return TRUE; - } - return FALSE; - } -#endif - -#if GQUEUE_NEED_GSYNC - void gfxQueueGSyncInit(gfxQueueGSync *pqueue) { - pqueue->head = pqueue->tail = 0; - gfxSemInit(&pqueue->sem, 0, MAX_SEMAPHORE_COUNT); - } - void gfxQueueGSyncDeinit(gfxQueueGSync *pqueue) { - pqueue->head = pqueue->tail = 0; - gfxSemDestroy(&pqueue->sem); - } - - gfxQueueGSyncItem *gfxQueueGSyncGet(gfxQueueGSync *pqueue, delaytime_t ms) { - gfxQueueGSyncItem *pi; - - if (!gfxSemWait(&pqueue->sem, ms)) - return 0; - - gfxSystemLock(); - pi = pqueue->head; - pqueue->head = pi->next; - pi->next = 0; - gfxSystemUnlock(); - - return pi; - } - gfxQueueGSyncItem *gfxQueueGSyncGetI(gfxQueueGSync *pqueue) { - gfxQueueGSyncItem *pi; - - if (!gfxSemWaitI(&pqueue->sem)) - return 0; - - pi = pqueue->head; - pqueue->head = pi->next; - pi->next = 0; - return pi; - } - - void gfxQueueGSyncPut(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { - gfxSystemLock(); - gfxQueueGSyncPutI(pqueue, pitem); - gfxSystemUnlock(); - } - void gfxQueueGSyncPutI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { - if (!pitem) return; // Safety - pitem->next = 0; - if (!pqueue->head) { - pqueue->head = pqueue->tail = pitem; - } else { - pqueue->tail->next = pitem; - pqueue->tail = pitem; - } - gfxSemSignalI(&pqueue->sem); - } - - void gfxQueueGSyncPush(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { - gfxSystemLock(); - gfxQueueGSyncPushI(pqueue, pitem); - gfxSystemUnlock(); - } - void gfxQueueGSyncPushI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { - if (!pitem) return; // Safety - pitem->next = pqueue->head; - pqueue->head = pitem; - if (!pitem->next) - pqueue->tail = pitem; - gfxSemSignalI(&pqueue->sem); - } - - void gfxQueueGSyncInsert(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter) { - gfxSystemLock(); - gfxQueueGSyncInsertI(pqueue, pitem, pafter); - gfxSystemUnlock(); - } - void gfxQueueGSyncInsertI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter) { - if (!pitem) return; // Safety - - if (pafter && gfxQueueGSyncIsInI(pqueue, pafter)) { - pitem->next = pafter->next; - pafter->next = pitem; - if (pqueue->tail == pafter) - pqueue->tail = pitem; - } else { - pitem->next = 0; - if (!pqueue->head) { - pqueue->head = pqueue->tail = pitem; - } else { - pqueue->tail->next = pitem; - pqueue->tail = pitem; - } - } - } - - void gfxQueueGSyncRemove(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { - gfxSystemLock(); - gfxQueueGSyncRemoveI(pqueue, pitem); - gfxSystemUnlock(); - } - void gfxQueueGSyncRemoveI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) { - gfxQueueGSyncItem *pi; - - if (!pitem) return; // Safety - if (pqueue->head) { - if (pqueue->head == pitem) { - pqueue->head = pitem->next; - pitem->next = 0; - } else { - for(pi = pqueue->head; pi->next; pi = pi->next) { - if (pi->next == pitem) { - pi->next = pitem->next; - if (pqueue->tail == pitem) - pqueue->tail = pi; - pitem->next = 0; - break; - } - } - } - } - } - - bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem) { - bool_t res; - - gfxSystemLock(); - res = gfxQueueGSyncIsInI(pqueue, pitem); - gfxSystemUnlock(); - - return res; - } - bool_t gfxQueueGSyncIsInI(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem) { - gfxQueueGSyncItem *pi; - - for(pi = pqueue->head; pi; pi = pi->next) { - if (pi == pitem) - return TRUE; - } - return FALSE; - } -#endif - -#if GQUEUE_NEED_FSYNC - void gfxQueueFSyncInit(gfxQueueFSync *pqueue) { - pqueue->head = pqueue->tail = 0; - gfxSemInit(&pqueue->sem, 0, MAX_SEMAPHORE_COUNT); - } - void gfxQueueFSyncDeinit(gfxQueueGSync *pqueue) { - while(gfxQueueFSyncGet(pqueue, TIME_IMMEDIATE)); - pqueue->head = pqueue->tail = 0; - gfxSemDestroy(&pqueue->sem); - } - - gfxQueueFSyncItem *gfxQueueFSyncGet(gfxQueueFSync *pqueue, delaytime_t ms) { - gfxQueueFSyncItem *pi; - - if (!gfxSemWait(&pqueue->sem, ms)) - return 0; - - gfxSystemLock(); - pi = pqueue->head; - pqueue->head = pi->next; - pi->next = 0; - gfxSystemUnlock(); - - gfxSemSignal(&pi->sem); - gfxSemDestroy(&pi->sem); - - return pi; - } - - bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms) { - if (!pitem) return; // Safety - gfxSemInit(&pitem->sem, 0, 1); - pitem->next = 0; - - gfxSystemLock(); - if (!pqueue->head) { - pqueue->head = pqueue->tail = pitem; - } else { - pqueue->tail->next = pitem; - pqueue->tail = pitem; - } - gfxSystemUnlock(); - - gfxSemSignal(&pqueue->sem); - - return gfxSemWait(&pitem->sem, ms); - } - - bool_t gfxQueueFSyncPush(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms) { - if (!pitem) return; // Safety - gfxSemInit(&pitem->sem, 0, 1); - - gfxSystemLock(); - pitem->next = pqueue->head; - pqueue->head = pitem; - if (!pitem->next) - pqueue->tail = pitem; - gfxSystemUnlock(); - - gfxSemSignal(&pqueue->sem); - - return gfxSemWait(&pitem->sem, ms); - } - - bool_t gfxQueueFSyncInsert(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, gfxQueueASyncItem *pafter, delaytime_t ms) { - if (!pitem) return; // Safety - gfxSemInit(&pitem->sem, 0, 1); - - gfxSystemLock(); - if (pafter && gfxQueueGSyncIsInI(pqueue, pafter)) { - pitem->next = pafter->next; - pafter->next = pitem; - if (pqueue->tail == pafter) - pqueue->tail = pitem; - } else { - pitem->next = 0; - if (!pqueue->head) { - pqueue->head = pqueue->tail = pitem; - } else { - pqueue->tail->next = pitem; - pqueue->tail = pitem; - } - } - gfxSystemUnlock(); - - gfxSemSignal(&pqueue->sem); - - return gfxSemWait(&pitem->sem, ms); - - } - - void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem) { - gfxQueueFSyncItem *pi; - - if (!pitem) return; // Safety - gfxSystemLock(); - if (pqueue->head) { - if (pqueue->head == pitem) { - pqueue->head = pitem->next; - found: - pitem->next = 0; - gfxSystemUnlock(); - gfxSemSignal(&pitem->sem); - gfxSemDestroy(&pitem->sem); - return; - } - for(pi = pqueue->head; pi->next; pi = pi->next) { - if (pi->next == pitem) { - pi->next = pitem->next; - if (pqueue->tail == pitem) - pqueue->tail = pi; - goto found; - } - } - } - gfxSystemUnlock(); - } - - bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem) { - bool_t res; - - gfxSystemLock(); - res = gfxQueueFSyncIsInI(pqueue, pitem); - gfxSystemUnlock(); - - return res; - } - bool_t gfxQueueFSyncIsInI(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem) { - gfxQueueASyncItem *pi; - - for(pi = pqueue->head; pi; pi = pi->next) { - if (pi == pitem) - return TRUE; - } - return FALSE; - } -#endif - -#if GQUEUE_NEED_BUFFERS - bool_t gfxBufferAlloc(unsigned num, size_t size) { - GDataBuffer *pd; - - if (num < 1) - return FALSE; - - // Round up to a multiple of 4 to prevent problems with structure alignment - size = (size + 3) & ~0x03; - - // Allocate the memory - if (!(pd = gfxAlloc((size+sizeof(GDataBuffer)) * num))) - return FALSE; - - // Add each of them to our free list - for(;num--; pd = (GDataBuffer *)((char *)(pd+1)+size)) { - pd->size = size; - gfxBufferRelease(pd); - } - - return TRUE; - } - - void gfxBufferRelease(GDataBuffer *pd) { gfxQueueGSyncPut(&bufferFreeList, (gfxQueueGSyncItem *)pd); } - void gfxBufferReleaseI(GDataBuffer *pd) { gfxQueueGSyncPutI(&bufferFreeList, (gfxQueueGSyncItem *)pd); } - GDataBuffer *gfxBufferGet(delaytime_t ms) { return (GDataBuffer *)gfxQueueGSyncGet(&bufferFreeList, ms); } - GDataBuffer *gfxBufferGetI(void) { return (GDataBuffer *)gfxQueueGSyncGetI(&bufferFreeList); } - bool_t gfxBufferIsAvailable(void) { return bufferFreeList.head != 0; } - -#endif - - -#endif /* GFX_USE_GQUEUE */ diff --git a/src/gqueue/gqueue_options.h b/src/gqueue/gqueue_options.h new file mode 100644 index 00000000..a9f7302f --- /dev/null +++ b/src/gqueue/gqueue_options.h @@ -0,0 +1,59 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gqueue/gqueue_options.h + * @brief GQUEUE - Queue options header file. + * + * @addtogroup GQUEUE + * @{ + */ + +#ifndef _GQUEUE_OPTIONS_H +#define _GQUEUE_OPTIONS_H + +/** + * @name GQUEUE Functions to include. + * @{ + */ + /** + * @brief Enable Asynchronous Queues + * @details Defaults to FALSE + */ + #ifndef GQUEUE_NEED_ASYNC + #define GQUEUE_NEED_ASYNC FALSE + #endif + /** + * @brief Enable Get-Synchronous Queues + * @details Defaults to FALSE + */ + #ifndef GQUEUE_NEED_GSYNC + #define GQUEUE_NEED_GSYNC FALSE + #endif + /** + * @brief Enable Fully Synchronous Queues + * @details Defaults to FALSE + */ + #ifndef GQUEUE_NEED_FSYNC + #define GQUEUE_NEED_FSYNC FALSE + #endif + /** + * @brief Enable Queue-able Data Buffers + */ + #ifndef GQUEUE_NEED_BUFFERS + #define GQUEUE_NEED_BUFFERS FALSE + #endif +/** + * @} + * + * @name GQUEUE Optional Sizing Parameters + * @{ + */ +/** @} */ + +#endif /* _GQUEUE_OPTIONS_H */ +/** @} */ diff --git a/src/gqueue/gqueue_rules.h b/src/gqueue/gqueue_rules.h new file mode 100644 index 00000000..0bccb196 --- /dev/null +++ b/src/gqueue/gqueue_rules.h @@ -0,0 +1,30 @@ +/* + * This file is subject to the terms of the GFX License. If a copy of + * the license was not distributed with this file, you can obtain one at: + * + * http://ugfx.org/license.html + */ + +/** + * @file src/gqueue/gqueue_rules.h + * @brief GQUEUE safety rules header file. + * + * @addtogroup GQUEUE + * @{ + */ + +#ifndef _GQUEUE_RULES_H +#define _GQUEUE_RULES_H + +#if GFX_USE_GQUEUE + #if GQUEUE_NEED_BUFFERS && !GQUEUE_NEED_GSYNC + #if GFX_DISPLAY_RULE_WARNINGS + #warning "GQUEUE: GQUEUE_NEED_GSYNC is required if GQUEUE_NEED_BUFFERS is TRUE. It has been turned on for you." + #endif + #undef GQUEUE_NEED_GSYNC + #define GQUEUE_NEED_GSYNC TRUE + #endif +#endif + +#endif /* _GQUEUE_RULES_H */ +/** @} */ diff --git a/src/gqueue/sys_defs.h b/src/gqueue/sys_defs.h deleted file mode 100644 index cba22588..00000000 --- a/src/gqueue/sys_defs.h +++ /dev/null @@ -1,412 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gqueue/sys_defs.h - * @brief GQUEUE header file. - * - * @addtogroup GQUEUE - * - * @brief Module which provides queue management (only internally used) - * - * @details There are 3 types of queues: - * - * We need 4 types of queues even though fully synchronous queues support all operations including asynchronous - * operations because fully synchronous queues have the highest storage requirements. The other queue types are - * optimizations. Efficiency IS important to use (particularly RAM efficiency). - * In practice we only implement ASync, GSync and FSync queues as PSync queues are of dubious value. - *
- * We also define GDataBuffer which is a data buffer that supports being queued. - * @{ - */ - -#ifndef _GQUEUE_H -#define _GQUEUE_H - -#if GFX_USE_GQUEUE || defined(__DOXYGEN__) - -/** - * @brief A queue item - * @{ - */ -typedef struct gfxQueueASyncItem { - struct gfxQueueASyncItem *next; -} gfxQueueASyncItem, gfxQueueGSyncItem; - -typedef struct gfxQueueFSyncItem { - struct gfxQueueFSyncItem *next; - gfxSem sem; -} gfxQueueFSyncItem; -/** @} */ - -/** - * @brief A queue - * @{ - */ -typedef struct gfxQueueASync { - gfxQueueASyncItem *head; - gfxQueueASyncItem *tail; -} gfxQueueASync; - -typedef struct gfxQueueGSync { - gfxQueueGSyncItem *head; - gfxQueueGSyncItem *tail; - gfxSem sem; -} gfxQueueGSync; - -typedef struct gfxQueueFSync { - gfxQueueFSyncItem *head; - gfxQueueFSyncItem *tail; - gfxSem sem; -} gfxQueueFSync; -/** @} */ - -/** - * @brief A Data Buffer Queue - * @note This structure is followed immediately by the data itself. - * When allocating the buffers for the data put this structure - * at the beginning of the buffer. - */ -typedef struct GDataBuffer { - gfxQueueGSyncItem next; // @< Used for queueing the buffers - size_t size; // @< The size of the buffer area following this structure (in bytes) - size_t len; // @< The length of the data in the buffer area (in bytes) -} GDataBuffer; - -/*===========================================================================*/ -/* Function declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @name Initialisation functions - * @brief Initialise a queue. - * - * @param[in] pqueue A pointer to the queue - * - * @note Whilst queues are normally FIFO, a GFX queue also supports push and pop operations. - * A pop operation is the same as normal get from the queue but a push places the item - * at the head of the queue instead of the tail (as a put would). - * - * @api - * @{ - */ -void gfxQueueASyncInit(gfxQueueASync *pqueue); -void gfxQueueGSyncInit(gfxQueueGSync *pqueue); -void gfxQueueFSyncInit(gfxQueueFSync *pqueue); -/** @} */ - -/** - * @name Deinitialisation functions - * @brief De-Initialise a queue. - * - * @param[in] pqueue A pointer to the queue - * - * @api - * @{ - */ -#define gfxQueueASyncDeinit(pqueue) -void gfxQueueGSyncDeinit(gfxQueueGSync *pqueue); -void gfxQueueFSyncDeinit(gfxQueueFSync *pqueue); -/** @} */ - -/** - * @name Get() Functions - * @brief Get an item from the head of the queue (and remove it from the queue). - * @return NULL if the timeout expires before an item is available - * - * @param[in] pqueue A pointer to the queue - * @param[in] ms The maxmimum time to wait for an item. For ASync queues this parameter is - * not specified as TIME_IMMEDIATE is assumed. - * - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -gfxQueueASyncItem *gfxQueueASyncGet(gfxQueueASync *pqueue); -gfxQueueASyncItem *gfxQueueASyncGetI(gfxQueueASync *pqueue); -gfxQueueGSyncItem *gfxQueueGSyncGet(gfxQueueGSync *pqueue, delaytime_t ms); -gfxQueueGSyncItem *gfxQueueGSyncGetI(gfxQueueGSync *pqueue); -gfxQueueFSyncItem *gfxQueueFSyncGet(gfxQueueFSync *pqueue, delaytime_t ms); -/** @} */ - -/** - * @name Put() Functions - * @brief Put an item on the end of the queue. - * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE - * - * @param[in] pqueue A pointer to the queue - * @param[in] pitem A pointer to the queue item - * @param[in] ms The maxmimum time to wait for an item to be removed from the queue (only for FSync queues) - * - * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the - * item is removed from the queue. Note that even if the timeout occurs - the item - * remains in the queue. - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -void gfxQueueASyncPut(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); -void gfxQueueASyncPutI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); -void gfxQueueGSyncPut(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); -void gfxQueueGSyncPutI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); -bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms); -/** @} */ - -/** - * @name Pop() Functions - * @brief Pop an item from the head of the queue (and remove it from the queue). - * @details This is exactly the same as the Get operation above. - * - * @api - * @{ - */ -#define gfxQueueASyncPop(pqueue) gfxQueueASyncGet(pqueue) -#define gfxQueueASyncPopI(pqueue) gfxQueueASyncGetI(pqueue) -#define gfxQueueGSyncPop(pqueue, ms) gfxQueueGSyncGet(pqueue, ms) -#define gfxQueueFSyncPop(pqueue, ms) gfxQueueFSyncGet(pqueue, ms) -/** @} */ - -/** - * @name Push() Functions - * @brief Push an item into the start of the queue. - * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE - * - * @param[in] pqueue A pointer to the queue - * @param[in] pitem A pointer to the queue item - * @param[in] ms The maxmimum time to wait for an item to be popped (only for FSync queues) - * - * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the - * item is removed from the queue. Note that even if the timeout occurs - the item - * remains in the queue. - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -void gfxQueueASyncPush(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); -void gfxQueueASyncPushI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); -void gfxQueueGSyncPush(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); -void gfxQueueGSyncPushI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); -bool_t gfxQueueFSyncPush(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms); -/** @} */ - -/** - * @name Insert() Functions - * @brief Insert an item on the queue after the specified item. - * @return none for ASync and GSync queues; For FSync queues - FALSE on timeout, otherwise TRUE - * - * @param[in] pqueue A pointer to the queue - * @param[in] pitem A pointer to the queue item - * @param[in] pafter A pointer to the queue item this new item must be inserted after. If NULL or - * pafter can't be found in the queue, it puts the new item at the end of the queue. - * @param[in] ms The maxmimum time to wait for an item to be removed from the queue (only for FSync queues) - * - * @note FSync: Use a delay time of TIME_IMMEDIATE if you don't want to wait until the - * item is removed from the queue. Note that even if the timeout occurs - the item - * remains in the queue. - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -void gfxQueueASyncInsert(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter); -void gfxQueueASyncInsertI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem, gfxQueueASyncItem *pafter); -void gfxQueueGSyncInsert(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter); -void gfxQueueGSyncInsertI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem, gfxQueueASyncItem *pafter); -bool_t gfxQueueFSyncInsert(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, gfxQueueASyncItem *pafter, delaytime_t ms); -/** @} */ - -/** - * @name Remove() Functions - * @brief Remove an item from the queue. - * @note Removes the specified item from the queue where-ever it is in the queue - * - * @param[in] pqueue A pointer to the queue - * @param[in] pitem A pointer to the queue item - * - * @note If the item isn't in the queue the routine just returns. - * @note If a process is waiting on the Put/Push operation for the item, that process - * will be signaled. - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -void gfxQueueASyncRemove(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); -void gfxQueueASyncRemoveI(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem); -void gfxQueueGSyncRemove(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); -void gfxQueueGSyncRemoveI(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem); -void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem); -/** @} */ - -/** - * @name isEmpty() Functions - * @brief Is the queue empty? - * @return TRUE if the queue is empty - * - * @param[in] pqueue A pointer to the queue - * - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -#define gfxQueueASyncIsEmpty(pqueue) ((pqueue)->head == 0) -#define gfxQueueASyncIsEmptyI(pqueue) ((pqueue)->head == 0) -#define gfxQueueGSyncIsEmpty(pqueue) ((pqueue)->head == 0) -#define gfxQueueGSyncIsEmptyI(pqueue) ((pqueue)->head == 0) -#define gfxQueueFSyncIsEmpty(pqueue) ((pqueue)->head == 0) -#define gfxQueueFSyncIsEmptyI(pqueue) ((pqueue)->head == 0) -/** @} */ - -/** - * @name IsInQueue() Functions - * @brief Is an item in the queue? - * @return TRUE if the item is in the queue? - * - * @param[in] pqueue A pointer to the queue - * @param[in] pitem A pointer to the queue item - * - * @note This operation may be expensive. - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem); -bool_t gfxQueueASyncIsInI(gfxQueueASync *pqueue, const gfxQueueASyncItem *pitem); -bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem); -bool_t gfxQueueGSyncIsInI(gfxQueueGSync *pqueue, const gfxQueueGSyncItem *pitem); -bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem); -bool_t gfxQueueFSyncIsInI(gfxQueueFSync *pqueue, const gfxQueueFSyncItem *pitem); -/** @} */ - -/** - * @name Peek() Functions - * @brief Get the first item from the head of the queue but do not remove it from the queue. - * @return NULL if no item is available. - * - * @param[in] pqueue A pointer to the queue - * - * @note This call does not block. - * @note This can be used as the first call to iterate all the elements in the queue. - * @note As that item is still on the queue, it should be treated as read-only. It could - * also be removed from the queue at any time by another thread (thereby altering the - * queue item). - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -#define gfxQueueASyncPeek(pqueue) ((const gfxQueueASyncItem *)((pqueue)->head)) -#define gfxQueueASyncPeekI(pqueue) ((const gfxQueueASyncItem *)((pqueue)->head)) -#define gfxQueueGSyncPeek(pqueue) ((const gfxQueueGSyncItem *)((pqueue)->head)) -#define gfxQueueGSyncPeekI(pqueue) ((const gfxQueueGSyncItem *)((pqueue)->head)) -#define gfxQueueFSyncPeek(pqueue) ((const gfxQueueFSyncItem *)((pqueue)->head)) -#define gfxQueueFSyncPeekI(pqueue) ((const gfxQueueFSyncItem *)((pqueue)->head)) -/** @} */ - -/** - * @name Next() Functions - * @brief Get the next item in the queue (but do not remove it from the queue). - * @return NULL if no item is available. - * - * @param[in] pitem The previous item in the queue - * - * @note This call does not block. - * @note This can be used as subsequent calls to iterate all the elements in the queue. - * @note As that item is still on the queue, it should be treated as read-only. It could - * also be removed from the queue at any time by another thread (thereby altering the - * queue item). - * @note The routines ending in "I" are interrupt/system/iclass level routines. - * - * @api - * @{ - */ -#define gfxQueueASyncNext(pitem) ((const gfxQueueASyncItem *)((pitem)->next)) -#define gfxQueueASyncNextI(pitem) ((const gfxQueueASyncItem *)((pitem)->next)) -#define gfxQueueGSyncNext(pitem) ((const gfxQueueGSyncItem *)((pitem)->next)) -#define gfxQueueGSyncNextI(pitem) ((const gfxQueueGSyncItem *)((pitem)->next)) -#define gfxQueueFSyncNext(pitem) ((const gfxQueueFSyncItem *)((pitem)->next)) -#define gfxQueueFSyncNextI(pitem) ((const gfxQueueFSyncItem *)((pitem)->next)) -/** @} */ - -/** - * @name BufferAlloc() Functions - * @brief Allocate some buffers and put them on the free list - * @return TRUE is it succeeded. FALSE on allocation failure. - * - * @param[in] num The number of buffers to allocate - * @param[in] size The size (in bytes) of each buffer - * - * @api - * @{ - */ -bool_t gfxBufferAlloc(unsigned num, size_t size); -/** @} */ - -/** - * @name BufferIsAvailable() Functions - * @brief Is there one or more buffers currently available on the free list - * @return TRUE if there are buffers in the free list - * - * @api - * @{ - */ -bool_t gfxBufferIsAvailable(void); -/** @} */ - -/** - * @name BufferGet() Functions - * @brief Get a buffer from the free list - * @return A GDataBuffer pointer or NULL if the timeout is exceeded - * - * @param[in] ms The maximum amount of time in milliseconds to wait for a buffer if one is not available. - * - * @api - * @{ - */ -GDataBuffer *gfxBufferGet(delaytime_t ms); -GDataBuffer *gfxBufferGetI(void); -/** @} */ - -/** - * @name BufferRelease) Functions - * @brief Release a buffer back to the free list - * - * @param[in] pd The buffer to put (back) on the free-list. - * - * @note This call should be used to return any buffers that were taken from - * the free-list once they have been finished with. It can also be used - * to put new buffers onto the free-list. Just make sure the "size" field - * of the GDataBuffer structure has been filled in first. - * - * @api - * @{ - */ -void gfxBufferRelease(GDataBuffer *pd); -void gfxBufferReleaseI(GDataBuffer *pd); -/** @} */ - - -#ifdef __cplusplus -} -#endif - -#endif /* GFX_USE_GQUEUE */ -#endif /* _GQUEUE_H */ -/** @} */ diff --git a/src/gqueue/sys_make.mk b/src/gqueue/sys_make.mk deleted file mode 100644 index f8a542c3..00000000 --- a/src/gqueue/sys_make.mk +++ /dev/null @@ -1 +0,0 @@ -GFXSRC += $(GFXLIB)/src/gqueue/gqueue_gqueue.c diff --git a/src/gqueue/sys_options.h b/src/gqueue/sys_options.h deleted file mode 100644 index 169cf116..00000000 --- a/src/gqueue/sys_options.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gqueue/sys_options.h - * @brief GQUEUE - Queue options header file. - * - * @addtogroup GQUEUE - * @{ - */ - -#ifndef _GQUEUE_OPTIONS_H -#define _GQUEUE_OPTIONS_H - -/** - * @name GQUEUE Functions to include. - * @{ - */ - /** - * @brief Enable Asynchronous Queues - * @details Defaults to FALSE - */ - #ifndef GQUEUE_NEED_ASYNC - #define GQUEUE_NEED_ASYNC FALSE - #endif - /** - * @brief Enable Get-Synchronous Queues - * @details Defaults to FALSE - */ - #ifndef GQUEUE_NEED_GSYNC - #define GQUEUE_NEED_GSYNC FALSE - #endif - /** - * @brief Enable Fully Synchronous Queues - * @details Defaults to FALSE - */ - #ifndef GQUEUE_NEED_FSYNC - #define GQUEUE_NEED_FSYNC FALSE - #endif - /** - * @brief Enable Queue-able Data Buffers - */ - #ifndef GQUEUE_NEED_BUFFERS - #define GQUEUE_NEED_BUFFERS FALSE - #endif -/** - * @} - * - * @name GQUEUE Optional Sizing Parameters - * @{ - */ -/** @} */ - -#endif /* _GQUEUE_OPTIONS_H */ -/** @} */ diff --git a/src/gqueue/sys_rules.h b/src/gqueue/sys_rules.h deleted file mode 100644 index 831952d8..00000000 --- a/src/gqueue/sys_rules.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is subject to the terms of the GFX License. If a copy of - * the license was not distributed with this file, you can obtain one at: - * - * http://ugfx.org/license.html - */ - -/** - * @file src/gqueue/sys_rules.h - * @brief GQUEUE safety rules header file. - * - * @addtogroup GQUEUE - * @{ - */ - -#ifndef _GQUEUE_RULES_H -#define _GQUEUE_RULES_H - -#if GFX_USE_GQUEUE - #if GQUEUE_NEED_BUFFERS && !GQUEUE_NEED_GSYNC - #if GFX_DISPLAY_RULE_WARNINGS - #warning "GQUEUE: GQUEUE_NEED_GSYNC is required if GQUEUE_NEED_BUFFERS is TRUE. It has been turned on for you." - #endif - #undef GQUEUE_NEED_GSYNC - #define GQUEUE_NEED_GSYNC TRUE - #endif -#endif - -#endif /* _GQUEUE_RULES_H */ -/** @} */ -- cgit v1.2.3