diff --git a/CHANGES b/CHANGES index 6c3568d10..86da73c66 100644 --- a/CHANGES +++ b/CHANGES @@ -64,6 +64,7 @@ Misc: - Qt: Optimize logo drawing - Qt: Move frame upload back onto main thread - All: Enable link-time optimization + - GBA Thread: Make GBASyncWaitFrameStart time out 0.1.1: (2015-01-24) Bugfixes: diff --git a/src/gba/supervisor/thread.c b/src/gba/supervisor/thread.c index 14bb3a07c..df3c7989d 100644 --- a/src/gba/supervisor/thread.c +++ b/src/gba/supervisor/thread.c @@ -659,7 +659,9 @@ bool GBASyncWaitFrameStart(struct GBASync* sync, int frameskip) { return false; } if (sync->videoFrameOn) { - ConditionWait(&sync->videoFrameAvailableCond, &sync->videoFrameMutex); + if (ConditionWaitTimed(&sync->videoFrameAvailableCond, &sync->videoFrameMutex, 20)) { + return false; + } } sync->videoFramePending = 0; sync->videoFrameSkip = frameskip; diff --git a/src/util/threading.h b/src/util/threading.h index 6dc09fb50..8d0837bbb 100644 --- a/src/util/threading.h +++ b/src/util/threading.h @@ -10,6 +10,7 @@ #ifdef USE_PTHREADS #include +#include #define THREAD_ENTRY void* typedef THREAD_ENTRY (*ThreadEntry)(void*); @@ -46,6 +47,21 @@ static inline int ConditionWait(Condition* cond, Mutex* mutex) { return pthread_cond_wait(cond, mutex); } +static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) { + struct timespec ts; + struct timeval tv; + + gettimeofday(&tv, 0); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = (tv.tv_usec + timeoutMs * 1000L) * 1000L; + if (ts.tv_nsec >= 1000000000L) { + ts.tv_nsec -= 1000000000L; + ++ts.tv_sec; + } + + return pthread_cond_timedwait(cond, mutex, &ts); +} + static inline int ConditionWake(Condition* cond) { return pthread_cond_broadcast(cond); } @@ -104,6 +120,11 @@ static inline int ConditionWait(Condition* cond, Mutex* mutex) { return GetLastError(); } +static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) { + SleepConditionVariableCS(cond, mutex, timeoutMs); + return GetLastError(); +} + static inline int ConditionWake(Condition* cond) { WakeAllConditionVariable(cond); return GetLastError(); @@ -163,6 +184,13 @@ static inline int ConditionWait(Condition* cond, Mutex* mutex) { return 0; } +static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) { + UNUSED(cond); + UNUSED(mutex); + UNUSED(timeoutMs); + return 0; +} + static inline int ConditionWake(Condition* cond) { UNUSED(cond); return 0;