diff --git a/src/gos/chibios.c b/src/gos/chibios.c index cf02b3e2..7d64fe1c 100644 --- a/src/gos/chibios.c +++ b/src/gos/chibios.c @@ -89,6 +89,13 @@ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) { return chSemWaitTimeout(&psem->sem, MS2ST(ms)) != RDY_TIMEOUT; } +bool_t gfxSemWaitI(gfxSem *psem) { + if (chSemGetCounterI(&psem->sem) <= 0) + return FALSE; + chSemFastWaitI(&psem->sem); + return TRUE; +} + void gfxSemSignal(gfxSem *psem) { chSysLock(); diff --git a/src/gos/chibios.h b/src/gos/chibios.h index 6373aa43..1db9482e 100644 --- a/src/gos/chibios.h +++ b/src/gos/chibios.h @@ -82,6 +82,7 @@ void gfxSleepMicroseconds(delaytime_t ms); void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit); void gfxSemDestroy(gfxSem *psem); bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); +bool_t gfxSemWaitI(gfxSem *psem); void gfxSemSignal(gfxSem *psem); void gfxSemSignalI(gfxSem *psem); #define gfxSemCounterI(psem) ((psem)->sem.s_cnt) diff --git a/src/gos/linux.h b/src/gos/linux.h index f8b049e9..f92fc4e9 100644 --- a/src/gos/linux.h +++ b/src/gos/linux.h @@ -46,6 +46,7 @@ typedef pthread_mutex_t gfxMutex; #define gfxMutexDestroy(pmtx) pthread_mutex_destroy(pmtx) #define gfxMutexEnter(pmtx) pthread_mutex_lock(pmtx) #define gfxMutexExit(pmtx) pthread_mutex_unlock(pmtx) +#define gfxSemWaitI(psem) gfxSemWait(psem, TIME_IMMEDIATE) #define gfxSemSignalI(psem) gfxSemSignal(psem) #define gfxSemCounterI(pSem) ((pSem)->cnt) diff --git a/src/gos/osx.h b/src/gos/osx.h index 56e0551e..80b07eec 100644 --- a/src/gos/osx.h +++ b/src/gos/osx.h @@ -45,6 +45,7 @@ typedef pthread_mutex_t gfxMutex; #define gfxMutexDestroy(pmtx) pthread_mutex_destroy(pmtx) #define gfxMutexEnter(pmtx) pthread_mutex_lock(pmtx) #define gfxMutexExit(pmtx) pthread_mutex_unlock(pmtx) +#define gfxSemWaitI(psem) gfxSemWait(psem, TIME_IMMEDIATE) #define gfxSemSignalI(psem) gfxSemSignal(psem) #define gfxSemCounterI(pSem) ((pSem)->cnt) diff --git a/src/gos/raw32.c b/src/gos/raw32.c index 61d09761..2fdfdf68 100644 --- a/src/gos/raw32.c +++ b/src/gos/raw32.c @@ -346,6 +346,13 @@ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms) { return TRUE; } +bool_t gfxSemWaitI(gfxSem *psem) { + if (psem->cnt <= 0) + return FALSE; + psem->cnt--; + return TRUE; +} + void gfxSemSignal(gfxSem *psem) { INTERRUPTS_OFF(); gfxSemSignalI(psem); diff --git a/src/gos/raw32.h b/src/gos/raw32.h index eb5b5e18..d4e8e548 100644 --- a/src/gos/raw32.h +++ b/src/gos/raw32.h @@ -110,6 +110,7 @@ extern "C" { void gfxMutexExit(gfxMutex *pmutex); void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit); bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); + bool_t gfxSemWaitI(gfxSem *psem); void gfxSemSignal(gfxSem *psem); void gfxSemSignalI(gfxSem *psem); gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param); diff --git a/src/gos/sys_defs.h b/src/gos/sys_defs.h index b913fb66..f10ddd62 100644 --- a/src/gos/sys_defs.h +++ b/src/gos/sys_defs.h @@ -327,6 +327,19 @@ */ bool_t gfxSemWait(gfxSem *psem, delaytime_t ms); + /** + * @brief Test if a wait on a semaphore can be satisfied immediately + * @details Equivalent to @p gfxSemWait(psem, TIME_IMMEDIATE) except it can be called at interrupt level + * @return FALSE if the wait would occur occurred otherwise TRUE + * + * @param[in] psem A pointer to the semaphore + * @param[in] ms The maximum time to wait for the semaphore + * + * @iclass + * @api + */ + bool_t gfxSemWaitI(gfxSem *psem); + /** * @brief Signal a semaphore * @details The semaphore counter is increased and if the result is non-positive then a waiting thread diff --git a/src/gos/win32.h b/src/gos/win32.h index c704a288..8a5d9025 100644 --- a/src/gos/win32.h +++ b/src/gos/win32.h @@ -74,6 +74,7 @@ typedef HANDLE gfxThreadHandle; #define gfxMutexExit(pmutex) ReleaseMutex(*(pmutex)) #define gfxSemInit(psem, val, limit) *(psem) = CreateSemaphore(0, val, limit, 0) #define gfxSemDestroy(psem) CloseHandle(*(psem)) +#define gfxSemWaitI(psem) gfxSemWait((psem), TIME_IMMEDIATE) #define gfxSemSignal(psem) ReleaseSemaphore(*(psem), 1, 0) #define gfxSemSignalI(psem) ReleaseSemaphore(*(psem), 1, 0) #define gfxSemCounterI(psem) gfxSemCounter(psem)