diff options
author | Yotam Barnoy | 2010-06-15 06:30:49 +0000 |
---|---|---|
committer | Yotam Barnoy | 2010-06-15 06:30:49 +0000 |
commit | ff66c67439ec501da5335e78e77b58943cea0972 (patch) | |
tree | 23b7050fc8d9614287ce1d06c3c2acd6fd36f311 | |
parent | 25c7dc08b1ca6816ef3b99bb13819469bd45c710 (diff) | |
download | scummvm-rg350-ff66c67439ec501da5335e78e77b58943cea0972.tar.gz scummvm-rg350-ff66c67439ec501da5335e78e77b58943cea0972.tar.bz2 scummvm-rg350-ff66c67439ec501da5335e78e77b58943cea0972.zip |
PSP: fixed SCI freeze issue by using recursive mutexes
svn-id: r49682
-rw-r--r-- | backends/platform/psp/thread.cpp | 41 | ||||
-rw-r--r-- | backends/platform/psp/thread.h | 14 |
2 files changed, 47 insertions, 8 deletions
diff --git a/backends/platform/psp/thread.cpp b/backends/platform/psp/thread.cpp index 684a985fed..d20df45215 100644 --- a/backends/platform/psp/thread.cpp +++ b/backends/platform/psp/thread.cpp @@ -95,14 +95,14 @@ bool PspSemaphore::pollForValue(int value) { } // false: timeout or error -bool PspSemaphore::takeWithTimeOut(int num, uint32 timeOut) { +bool PspSemaphore::takeWithTimeOut(uint32 timeOut) { DEBUG_ENTER_FUNC(); uint32 *pTimeOut = 0; if (timeOut) pTimeOut = &timeOut; - if (sceKernelWaitSema(_handle, num, pTimeOut) < 0) + if (sceKernelWaitSema(_handle, 1, pTimeOut) < 0) // we always wait for 1 return false; return true; } @@ -115,6 +115,43 @@ bool PspSemaphore::give(int num) { return true; } +// Class PspMutex ------------------------------------------------------------ + +bool PspMutex::lock() { + DEBUG_ENTER_FUNC(); + int threadId = sceKernelGetThreadId(); + bool ret = true; + + if (_ownerId == threadId) { + _recursiveCount++; + } else { + ret = _semaphore.take(); + _ownerId = threadId; + _recursiveCount = 0; + } + return ret; +} + +bool PspMutex::unlock() { + DEBUG_ENTER_FUNC(); + int threadId = sceKernelGetThreadId(); + bool ret = true; + + if (_ownerId != threadId) { + PSP_ERROR("attempt to unlock mutex by thread[%x] as opposed to owner[%x]\n", + threadId, _ownerId); + return false; + } + + if (_recursiveCount) { + _recursiveCount--; + } else { + _ownerId = 0; + ret = _semaphore.give(1); + } + return ret; +} + //#define __PSP_DEBUG_FUNCS__ /* For debugging function calls */ //#define __PSP_DEBUG_PRINT__ /* For debug printouts */ diff --git a/backends/platform/psp/thread.h b/backends/platform/psp/thread.h index 23db8594dc..33b3f6ce53 100644 --- a/backends/platform/psp/thread.h +++ b/backends/platform/psp/thread.h @@ -40,8 +40,8 @@ private: public: PspSemaphore(int initialValue, int maxValue); ~PspSemaphore(); - bool take(int num) { return takeWithTimeOut(num, 0); } - bool takeWithTimeOut(int num, uint32 timeOut); + bool take() { return takeWithTimeOut(0); } + bool takeWithTimeOut(uint32 timeOut); bool give(int num); bool pollForValue(int value); // check for a certain value int numOfWaitingThreads(); @@ -51,12 +51,14 @@ public: class PspMutex { private: PspSemaphore _semaphore; + int _recursiveCount; + int _ownerId; public: - PspMutex(bool initialValue) : _semaphore(initialValue ? 1 : 0, 255) {} // initial, max value - bool lock() { return _semaphore.take(1); } - bool unlock() { return _semaphore.give(1); } + PspMutex(bool initialValue) : _semaphore(initialValue ? 1 : 0, 255), _recursiveCount(0), _ownerId(0) {} // initial, max value + bool lock(); + bool unlock(); bool poll() { return _semaphore.pollForValue(1); } - int getNumWaitingThreads() { return _semaphore.numOfWaitingThreads(); } + int numOfWaitingThreads() { return _semaphore.numOfWaitingThreads(); } bool getValue() { return (bool)_semaphore.getValue(); } }; |