aboutsummaryrefslogtreecommitdiffstats
path: root/src/gos
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/gos
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/gos')
-rw-r--r--src/gos/chibios.c114
-rw-r--r--src/gos/win32.c81
2 files changed, 83 insertions, 112 deletions
diff --git a/src/gos/chibios.c b/src/gos/chibios.c
index 6e63a2a4..7e369824 100644
--- a/src/gos/chibios.c
+++ b/src/gos/chibios.c
@@ -57,13 +57,14 @@ void gfxSleepMicroseconds(delaytime_t ms) {
default: chThdSleepMicroseconds(ms); return;
}
}
-
void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit) {
if (val > limit) val = limit;
psem->limit = limit;
chSemInit(&psem->sem, val);
}
-
+void gfxSemDestroy(gfxSem *psem) {
+ chSemReset(&psem->sem, 1);
+}
bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) {
if (ms == TIME_INFINITE) {
chSemWait(&psem->sem);
@@ -85,115 +86,6 @@ void gfxSemSignalI(gfxSem *psem) {
chSemSignalI(&psem->sem);
}
-void gfxQueueInit(gfxQueue *pqueue) {
- pqueue->head = pqueue->tail = 0;
- chSemInit(&pqueue->sem, 0);
-}
-
-gfxQueueItem * gfxQueueGet(gfxQueue *pqueue, delaytime_t ms) {
- gfxQueueItem *pi;
-
- chSysLock();
- /* If someone else is waiting or if the queue is empty - wait ourselves */
- if (pqueue->sem.s_cnt < 0 || !pqueue->head) {
- if (chSemWaitTimeoutS(&pqueue->sem, ms == TIME_INFINITE ? TIME_INFINITE : MS2ST(ms)) == RDY_TIMEOUT) {
- chSysUnlock();
- return NULL;
- }
- }
- /* We can now get the head element */
- pi = pqueue->head;
- pqueue->head = pi;
- chSemSignalI(&pi->sem);
- chSysUnlock();
- return pi;
-}
-
-bool_t gfxQueuePut(gfxQueue *pqueue, gfxQueueItem *pitem, delaytime_t ms) {
- chSemInit(&pitem->sem, 0);
- chSysLock();
- pitem->next = 0;
- if (!pqueue->head) {
- pqueue->head = pqueue->tail = pitem;
- } else {
- pqueue->tail->next = pitem;
- pqueue->tail = pitem;
- }
- /* Wake up someone who is waiting */
- if (chSemGetCounterI(&pqueue->sem) < 0)
- chSemSignalI(&pqueue->sem);
- chSysUnlock();
- return chSemWaitTimeout(&pitem->sem, ms == TIME_INFINITE ? TIME_INFINITE : MS2ST(ms)) != RDY_TIMEOUT;
-}
-
-bool_t gfxQueuePush(gfxQueue *pqueue, gfxQueueItem *pitem, delaytime_t ms) {
- chSemInit(&pitem->sem, 0);
- chSysLock();
- pitem->next = pqueue->head;
- pqueue->head = pitem;
- if (!pitem->next)
- pqueue->tail = pitem;
- /* Wake up someone who is waiting */
- if (chSemGetCounterI(&pqueue->sem) < 0)
- chSemSignalI(&pqueue->sem);
- chSysUnlock();
- return chSemWaitTimeout(&pitem->sem, ms == TIME_INFINITE ? TIME_INFINITE : MS2ST(ms)) != RDY_TIMEOUT;
-}
-
-void gfxQueueRemove(gfxQueue *pqueue, gfxQueueItem *pitem) {
- gfxQueueItem *pi;
-
- chSysLock();
- if (pqueue->head) {
- if (pqueue->head == pitem) {
- pqueue->head = pitem->next;
- chSemSignalI(&pitem->sem);
- } 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;
- chSemSignalI(&pitem->sem);
- break;
- }
- }
- }
- }
- chSysUnlock();
-}
-
-bool_t gfxQueueIsEmpty(gfxQueue *pqueue) {
- return pqueue->head == NULL;
-}
-
-bool_t gfxQueueIsIn(gfxQueue *pqueue, gfxQueueItem *pitem) {
- gfxQueueItem *pi;
-
- chSysLock();
- for(pi = pqueue->head; pi; pi = pi->next) {
- if (pi == pitem) {
- chSysUnlock();
- return TRUE;
- }
- }
- chSysUnlock();
- return FALSE;
-}
-
-/**
- * @brief Start a new thread.
- * @return Return TRUE if the thread was started, FALSE on an error
- *
- * @param[in] stackarea A pointer to the area for the new threads stack or NULL to dynamically allocate it
- * @param[in] stacksz The size of the thread stack. 0 means the default operating system size although this
- * is only valid when stackarea is dynamically allocated.
- * @param[in] prio The priority of the new thread
- * @param[in] fn The function the new thread will run
- * @param[in] param A parameter to pass the thread function.
- *
- * @api
- */
bool_t gfxCreateThread(void *stackarea, size_t stacksz, threadpriority_t prio, gfxThreadFunction fn, void *param) {
if (!stackarea) {
if (!stacksz) stacksz = 256;
diff --git a/src/gos/win32.c b/src/gos/win32.c
index 6cf803a2..bda57f6f 100644
--- a/src/gos/win32.c
+++ b/src/gos/win32.c
@@ -26,7 +26,86 @@
#if GFX_USE_OS_WIN32
-#error "GOS: WIN32 not supported yet"
+#include <stdio.h>
+
+static HANDLE SystemMutex;
+
+void _gosInit(void) {
+}
+
+void gfxHalt(const char *msg) {
+ fprintf(stderr, "%s\n", msg);
+ ExitProcess(1);
+}
+
+void gfxSleepMicroseconds(delaytime_t ms) {
+ static LARGE_INTEGER pcfreq;
+ static int initflag;
+ LARGE_INTEGER t1, t2, tdiff;
+
+ switch(ms) {
+ case TIME_IMMEDIATE: return;
+ case TIME_INFINITE: while(1) Sleep(1000); return;
+ }
+
+ if (!initflag) {
+ QueryPerformanceFrequency(&pcfreq);
+ initflag++;
+ }
+ tdiff.QuadPart = pcfreq.QuadPart * ms / 1000000;
+
+ QueryPerformanceCounter(&t1);
+ do {
+ QueryPerformanceCounter(&t2);
+ } while (t2.QuadPart - t1.QuadPart < tdiff.QuadPart);
+}
+
+void gfxSystemLock(void) {
+ if (!SystemMutex)
+ SystemMutex = CreateMutex(NULL, FALSE, NULL);
+ WaitForSingleObject(SystemMutex, INFINITE);
+}
+
+void gfxSystemUnlock(void) {
+ ReleaseMutex(SystemMutex);
+}
+
+bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) {
+ return WaitForSingleObject(*psem, ms) == WAIT_OBJECT_0;
+}
+
+typedef LONG __stdcall (*_NtQuerySemaphore)(
+ HANDLE SemaphoreHandle,
+ DWORD SemaphoreInformationClass, /* Would be SEMAPHORE_INFORMATION_CLASS */
+ PVOID SemaphoreInformation, /* but this is to much to dump here */
+ ULONG SemaphoreInformationLength,
+ PULONG ReturnLength OPTIONAL
+);
+
+semcount_t gfxSemCounter(gfxSem *pSem) {
+ static _NtQuerySemaphore NtQuerySemaphore;
+ struct _SEMAPHORE_BASIC_INFORMATION {
+ ULONG CurrentCount;
+ ULONG MaximumCount;
+ } BasicInfo;
+
+ if (!NtQuerySemaphore)
+ NtQuerySemaphore = (_NtQuerySemaphore)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySemaphore");
+
+ NtQuerySemaphore(*pSem, 0, &BasicInfo, sizeof(BasicInfo), NULL);
+ return BasicInfo.CurrentCount;
+}
+
+bool_t gfxCreateThread(void *stackarea, size_t stacksz, threadpriority_t prio, gfxThreadFunction fn, void *param) {
+ (void) stackarea;
+ HANDLE thd;
+
+ if (!(thd = CreateThread(NULL, stacksz, fn, param, CREATE_SUSPENDED, NULL)))
+ return FALSE;
+ SetThreadPriority(thd, prio);
+ ResumeThread(thd);
+ return TRUE;
+}
#endif /* GFX_USE_OS_WIN32 */
/** @} */