diff --git a/CHANGES b/CHANGES index ec2eac205..f1e68eec8 100644 --- a/CHANGES +++ b/CHANGES @@ -44,6 +44,7 @@ Misc: - GBA Memory: Implement several unimplemented memory access types - GBA: Implement bad I/O register loading - GBA Memory: Add GBAView* functions for viewing memory directly without bus issues + - Util: Add MutexTryLock 0.3.1: (2015-10-24) Bugfixes: diff --git a/src/gba/supervisor/thread.c b/src/gba/supervisor/thread.c index d53e53d98..b39d75d23 100644 --- a/src/gba/supervisor/thread.c +++ b/src/gba/supervisor/thread.c @@ -71,13 +71,15 @@ static void _waitUntilNotState(struct GBAThread* threadContext, enum ThreadState while (threadContext->state == oldState) { MutexUnlock(&threadContext->stateMutex); - MutexLock(&threadContext->sync.videoFrameMutex); - ConditionWake(&threadContext->sync.videoFrameRequiredCond); - MutexUnlock(&threadContext->sync.videoFrameMutex); + if (!MutexTryLock(&threadContext->sync.videoFrameMutex)) { + ConditionWake(&threadContext->sync.videoFrameRequiredCond); + MutexUnlock(&threadContext->sync.videoFrameMutex); + } - MutexLock(&threadContext->sync.audioBufferMutex); - ConditionWake(&threadContext->sync.audioRequiredCond); - MutexUnlock(&threadContext->sync.audioBufferMutex); + if (!MutexLock(&threadContext->sync.audioBufferMutex)) { + ConditionWake(&threadContext->sync.audioRequiredCond); + MutexUnlock(&threadContext->sync.audioBufferMutex); + } MutexLock(&threadContext->stateMutex); ConditionWake(&threadContext->stateCond); diff --git a/src/platform/3ds/threading.h b/src/platform/3ds/threading.h index 3df85aa88..36943a505 100644 --- a/src/platform/3ds/threading.h +++ b/src/platform/3ds/threading.h @@ -37,6 +37,10 @@ static inline int MutexLock(Mutex* mutex) { return svcWaitSynchronization(*mutex, U64_MAX); } +static inline int MutexTryLock(Mutex* mutex) { + return svcWaitSynchronization(*mutex, 10); +} + static inline int MutexUnlock(Mutex* mutex) { return svcReleaseMutex(*mutex); } diff --git a/src/platform/posix/threading.h b/src/platform/posix/threading.h index 9a49779b2..e13240f3e 100644 --- a/src/platform/posix/threading.h +++ b/src/platform/posix/threading.h @@ -33,6 +33,10 @@ static inline int MutexLock(Mutex* mutex) { return pthread_mutex_lock(mutex); } +static inline int MutexTryLock(Mutex* mutex) { + return pthread_mutex_trylock(mutex); +} + static inline int MutexUnlock(Mutex* mutex) { return pthread_mutex_unlock(mutex); } diff --git a/src/platform/psp2/threading.h b/src/platform/psp2/threading.h index 4ca74af13..9babe0aae 100644 --- a/src/platform/psp2/threading.h +++ b/src/platform/psp2/threading.h @@ -35,6 +35,10 @@ static inline int MutexLock(Mutex* mutex) { return sceKernelLockMutex(*mutex, 1, 0); } +static inline int MutexTryLock(Mutex* mutex) { + return sceKernelTryLockMutex(*mutex, 1); +} + static inline int MutexUnlock(Mutex* mutex) { return sceKernelUnlockMutex(*mutex, 1); } diff --git a/src/platform/windows/threading.h b/src/platform/windows/threading.h index 21d5c1971..37427bf23 100644 --- a/src/platform/windows/threading.h +++ b/src/platform/windows/threading.h @@ -32,6 +32,13 @@ static inline int MutexLock(Mutex* mutex) { return GetLastError(); } +static inline int MutexTryLock(Mutex* mutex) { + if (TryEnterCriticalSection(mutex)) { + return GetLastError(); + } + return 1; +} + static inline int MutexUnlock(Mutex* mutex) { LeaveCriticalSection(mutex); return GetLastError(); diff --git a/src/util/threading.h b/src/util/threading.h index d18ca91c8..643417818 100644 --- a/src/util/threading.h +++ b/src/util/threading.h @@ -41,6 +41,11 @@ static inline int MutexLock(Mutex* mutex) { return 0; } +static inline int MutexTryLock(Mutex* mutex) { + UNUSED(mutex); + return 0; +} + static inline int MutexUnlock(Mutex* mutex) { UNUSED(mutex); return 0;