From 8fcbf4e5d5cc88d52f4e6e67ebead27fc856ff4a Mon Sep 17 00:00:00 2001 From: inmarket Date: Sun, 26 May 2013 02:06:55 +1000 Subject: More GOS module changes GQUEUE as a seperate module GOS changes including basic Win32 O/S support --- src/gos/chibios.c | 114 ++---------------------------------------------------- src/gos/win32.c | 81 +++++++++++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 112 deletions(-) (limited to 'src/gos') 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 + +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 */ /** @} */ -- cgit v1.2.3