aboutsummaryrefslogtreecommitdiffstats
path: root/src/gqueue
diff options
context:
space:
mode:
authorinmarket <andrewh@inmarket.com.au>2013-05-26 02:06:55 +1000
committerinmarket <andrewh@inmarket.com.au>2013-05-26 02:06:55 +1000
commit8fcbf4e5d5cc88d52f4e6e67ebead27fc856ff4a (patch)
treec52d7733525727320d2de00acedb42bc18124471 /src/gqueue
parent7fbfde42aabbcd30cffba2fba35158236c0a6c6c (diff)
downloaduGFX-8fcbf4e5d5cc88d52f4e6e67ebead27fc856ff4a.tar.gz
uGFX-8fcbf4e5d5cc88d52f4e6e67ebead27fc856ff4a.tar.bz2
uGFX-8fcbf4e5d5cc88d52f4e6e67ebead27fc856ff4a.zip
More GOS module changes
GQUEUE as a seperate module GOS changes including basic Win32 O/S support
Diffstat (limited to 'src/gqueue')
-rw-r--r--src/gqueue/gqueue.c255
-rw-r--r--src/gqueue/gqueue.mk1
2 files changed, 256 insertions, 0 deletions
diff --git a/src/gqueue/gqueue.c b/src/gqueue/gqueue.c
new file mode 100644
index 00000000..d515a425
--- /dev/null
+++ b/src/gqueue/gqueue.c
@@ -0,0 +1,255 @@
+/*
+ ChibiOS/GFX - Copyright (C) 2012, 2013
+ Joel Bodenmann aka Tectu <joel@unormal.org>
+
+ This file is part of ChibiOS/GFX.
+
+ ChibiOS/GFX is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/GFX is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @file src/gqueue/gqueue.c
+ * @brief GQUEUE source file.
+ */
+#if GFX_USE_GQUEUE
+
+#if GQUEUE_NEED_ASYNC
+ void gfxQueueASyncInit(gfxQueueASync *pqueue) {
+ pqueue->head = pqueue->tail = 0;
+ }
+ gfxQueueASyncItem *gfxQueueASyncGet(gfxQueueASync *pqueue) {
+ gfxQueueASyncItem *pi;
+
+ if (!pqueue->head) return 0;
+ gfxSystemLock();
+ if ((pi = pqueue->head))
+ pqueue->head = pi->next;
+ gfxSytemUnlock();
+ return pi;
+ }
+ void gfxQueueASyncPut(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) {
+ pitem->next = 0;
+
+ gfxSystemLock();
+ if (!pqueue->head) {
+ pqueue->head = pqueue->tail = pitem;
+ } else {
+ pqueue->tail->next = pitem;
+ pqueue->tail = pitem;
+ }
+ gfxSystemUnlock();
+ }
+ void gfxQueueASyncPush(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) {
+ gfxSystemLock();
+ pitem->next = pqueue->head;
+ pqueue->head = pitem;
+ if (!pitem->next)
+ pqueue->tail = pitem;
+ gfxSystemUnlock();
+ }
+ void gfxQueueASyncRemove(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) {
+ if (!pitem) return;
+ gfxSystemLock();
+ if (pqueue->head) {
+ if (pqueue->head == pitem) {
+ pqueue->head = pitem->next;
+ } else {
+ for(gfxQueueASyncItem *pi = pqueue->head; pi->next; pi = pi->next) {
+ if (pi->next == pitem) {
+ pi->next = pitem->next;
+ if (pqueue->tail == pitem)
+ pqueue->tail = pi;
+ break;
+ }
+ }
+ }
+ }
+ gfxSystemUnlock();
+ }
+ bool_t gfxQueueASyncIsEmpty(gfxQueueASync *pqueue) {
+ return pqueue->head == NULL;
+ }
+ bool_t gfxQueueASyncIsIn(gfxQueueASync *pqueue, gfxQueueASyncItem *pitem) {
+ gfxSystemLock();
+ for(gfxQueueASyncItem *pi = pqueue->head; pi; pi = pi->next) {
+ if (pi == pitem) {
+ gfxSystemUnlock();
+ return TRUE;
+ }
+ }
+ gfxSystemUnlock();
+ return FALSE;
+ }
+#endif
+
+#if GQUEUE_NEED_GSYNC
+ void gfxQueueGSyncInit(gfxQueueGSync *pqueue) {
+ pqueue->head = pqueue->tail = 0;
+ gfxSemInit(&pqueue->sem, 0, MAX_SEMAPHORE_COUNT);
+ }
+ gfxQueueGSyncItem *gfxQueueGSyncGet(gfxQueueGSync *pqueue, delaytime_t ms) {
+ gfxQueueGSyncItem *pi;
+
+ if (!gfxSemWait(&pqueue->sem, ms)) return 0;
+ gfxSystemLock();
+ pi = pqueue->head;
+ pqueue->head = pi->next;
+ gfxSytemUnlock();
+ return pi;
+ }
+ void gfxQueueGSyncPut(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) {
+ pitem->next = 0;
+
+ gfxSystemLock();
+ if (!pqueue->head) {
+ pqueue->head = pqueue->tail = pitem;
+ } else {
+ pqueue->tail->next = pitem;
+ pqueue->tail = pitem;
+ }
+ gfxSystemUnlock();
+
+ gfxSemSignal(&pqueue->sem);
+ }
+ void gfxQueueGSyncPush(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) {
+ gfxSystemLock();
+ pitem->next = pqueue->head;
+ pqueue->head = pitem;
+ if (!pitem->next)
+ pqueue->tail = pitem;
+ gfxSystemUnlock();
+
+ gfxSemSignal(&pqueue->sem);
+ }
+ void gfxQueueGSyncRemove(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) {
+ if (!pitem) return;
+ gfxSystemLock();
+ if (pqueue->head) {
+ if (pqueue->head == pitem) {
+ pqueue->head = pitem->next;
+ } else {
+ for(gfxQueueGSyncItem *pi = pqueue->head; pi->next; pi = pi->next) {
+ if (pi->next == pitem) {
+ pi->next = pitem->next;
+ if (pqueue->tail == pitem)
+ pqueue->tail = pi;
+ break;
+ }
+ }
+ }
+ }
+ gfxSystemUnlock();
+ }
+ bool_t gfxQueueGSyncIsEmpty(gfxQueueGSync *pqueue) {
+ return pqueue->head == NULL;
+ }
+ bool_t gfxQueueGSyncIsIn(gfxQueueGSync *pqueue, gfxQueueGSyncItem *pitem) {
+ gfxSystemLock();
+ for(gfxQueueGSyncItem *pi = pqueue->head; pi; pi = pi->next) {
+ if (pi == pitem) {
+ gfxSystemUnlock();
+ return TRUE;
+ }
+ }
+ gfxSystemUnlock();
+ return FALSE;
+ }
+#endif
+
+#if GQUEUE_NEED_FSYNC
+ void gfxQueueFSyncInit(gfxQueueFSync *pqueue) {
+ pqueue->head = pqueue->tail = 0;
+ gfxSemInit(&pqueue->sem, 0, MAX_SEMAPHORE_COUNT);
+ }
+ gfxQueueFSyncItem *gfxQueueFSyncGet(gfxQueueFSync *pqueue, delaytime_t ms) {
+ gfxQueueFSyncItem *pi;
+
+ if (!gfxSemWait(&pqueue->sem, ms)) return 0;
+ gfxSystemLock();
+ pi = pqueue->head;
+ pqueue->head = pi->next;
+ gfxSytemUnlock();
+
+ gfxSemSignalI(&pi->sem);
+ gfxSemDestroy(&pi->sem);
+ return pi;
+ }
+ bool_t gfxQueueFSyncPut(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem, delaytime_t ms) {
+ 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) {
+ 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);
+ }
+ void gfxQueueFSyncRemove(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem) {
+ if (!pitem) return;
+ gfxSystemLock();
+ if (pqueue->head) {
+ if (pqueue->head == pitem) {
+ pqueue->head = pitem->next;
+ found:
+ gfxSystemUnlock();
+ gfxSemSignal(&pitem->sem);
+ gfxSemDestroy(&pitem->sem);
+ return;
+ }
+ for(gfxQueueFSyncItem *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 gfxQueueFSyncIsEmpty(gfxQueueFSync *pqueue) {
+ return pqueue->head == NULL;
+ }
+ bool_t gfxQueueFSyncIsIn(gfxQueueFSync *pqueue, gfxQueueFSyncItem *pitem) {
+ gfxSystemLock();
+ for(gfxQueueFSyncItem *pi = pqueue->head; pi; pi = pi->next) {
+ if (pi == pitem) {
+ gfxSystemUnlock();
+ return TRUE;
+ }
+ }
+ gfxSystemUnlock();
+ return FALSE;
+ }
+#endif
+
+#endif /* GFX_USE_GQUEUE */
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