aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYotam Barnoy2010-06-15 06:30:49 +0000
committerYotam Barnoy2010-06-15 06:30:49 +0000
commitff66c67439ec501da5335e78e77b58943cea0972 (patch)
tree23b7050fc8d9614287ce1d06c3c2acd6fd36f311
parent25c7dc08b1ca6816ef3b99bb13819469bd45c710 (diff)
downloadscummvm-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.cpp41
-rw-r--r--backends/platform/psp/thread.h14
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(); }
};