aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/psp/powerman.cpp
diff options
context:
space:
mode:
authorYotam Barnoy2010-06-15 13:10:00 +0000
committerYotam Barnoy2010-06-15 13:10:00 +0000
commita21b9c7b96a29d3be9285b4217e91f835fed31ec (patch)
treebb58c2221ce5631d98bddd354cc2ba715493c159 /backends/platform/psp/powerman.cpp
parent891b568fde51c7f1732c86fd34cc40efcd4314ce (diff)
downloadscummvm-rg350-a21b9c7b96a29d3be9285b4217e91f835fed31ec.tar.gz
scummvm-rg350-a21b9c7b96a29d3be9285b4217e91f835fed31ec.tar.bz2
scummvm-rg350-a21b9c7b96a29d3be9285b4217e91f835fed31ec.zip
PSP: fixed up PowerManager and removed dependency on SDL
svn-id: r49852
Diffstat (limited to 'backends/platform/psp/powerman.cpp')
-rw-r--r--backends/platform/psp/powerman.cpp352
1 files changed, 123 insertions, 229 deletions
diff --git a/backends/platform/psp/powerman.cpp b/backends/platform/psp/powerman.cpp
index df8da12f6d..eaadad16c5 100644
--- a/backends/platform/psp/powerman.cpp
+++ b/backends/platform/psp/powerman.cpp
@@ -23,16 +23,16 @@
*
*/
-//#define __PSP_DEBUG_FUNCS__ /* can put this locally too */
-//#define __PSP_DEBUG_PRINT__
-#include "backends/platform/psp/trace.h"
-
#include <psppower.h>
#include <pspthreadman.h>
#include "backends/platform/psp/powerman.h"
#include "engine.h"
+//#define __PSP_DEBUG_FUNCS__ /* can put this locally too */
+//#define __PSP_DEBUG_PRINT__
+#include "backends/platform/psp/trace.h"
+
DECLARE_SINGLETON(PowerManager)
// Function to debug the Power Manager (we have no output to screen)
@@ -47,68 +47,30 @@ inline void PowerManager::debugPM() {
* Constructor
*
********************************************/
-PowerManager::PowerManager() {
- DEBUG_ENTER_FUNC();
-
- _flagMutex = NULL; /* Init mutex handle */
- _listMutex = NULL; /* Init mutex handle */
- _condSuspendable = NULL; /* Init condition variable */
- _condPM = NULL;
-
- _condSuspendable = SDL_CreateCond();
- if (_condSuspendable <= 0) {
- PSP_ERROR("Couldn't create Suspendable condition variable\n");
- }
-
- _condPM = SDL_CreateCond();
- if (_condPM <= 0) {
- PSP_ERROR("Couldn't create PM condition variable\n");
- }
-
- _flagMutex = SDL_CreateMutex();
- if (_flagMutex <= 0) {
- PSP_ERROR("Couldn't create flag Mutex\n");
- }
-
- _listMutex = SDL_CreateMutex();
- if (_listMutex <= 0) {
- PSP_ERROR("Couldn't create list Mutex\n");
- }
-
- _suspendFlag = false;
- _criticalCounter = 0; // How many are in the critical section
- _pauseFlag = 0;
- _pauseFlagOld = 0;
- _pauseClientState = 0;
- _listCounter = 0;
- PMStatusSet(kInitDone);
- _error = 0;
-}
+PowerManager::PowerManager() : _pauseFlag(false), _pauseFlagOld(false), _pauseClientState(UNPAUSED),
+ _suspendFlag(false), _flagMutex(true), _listMutex(true),
+ _criticalCounter(0), _listCounter(0), _error(0), _PMStatus(kInitDone) {}
/*******************************************
*
* Function to register to be notified when suspend/resume time comes
*
********************************************/
-int PowerManager::registerSuspend(Suspendable *item) {
+bool PowerManager::registerForSuspend(Suspendable *item) {
DEBUG_ENTER_FUNC();
// Register in list
debugPM();
- if (SDL_mutexP(_listMutex) != 0) {
- PSP_ERROR("Couldn't lock _listMutex[%p]\n", _listMutex);
- }
+ _listMutex.lock();
_suspendList.push_front(item);
_listCounter++;
- if (SDL_mutexV(_listMutex) != 0) {
- PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
- }
+ _listMutex.unlock();
debugPM();
- return 0;
+ return true;
}
/*******************************************
@@ -116,26 +78,20 @@ int PowerManager::registerSuspend(Suspendable *item) {
* Function to unregister to be notified when suspend/resume time comes
*
********************************************/
-int PowerManager::unregisterSuspend(Suspendable *item) {
+bool PowerManager::unregisterForSuspend(Suspendable *item) {
DEBUG_ENTER_FUNC();
debugPM();
// Unregister from stream list
- if (SDL_mutexP(_listMutex) != 0) {
- PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
- }
-
+ _listMutex.lock();
+
_suspendList.remove(item);
_listCounter--;
- if (SDL_mutexV(_listMutex) != 0) {
- PSP_ERROR("Couldn't unlock _listMutex[%p]\n", _listMutex);
- }
+ _listMutex.unlock();
- PSP_DEBUG_PRINT("Out of unregisterSuspend\n");
debugPM();
-
- return 0;
+ return true;
}
/*******************************************
@@ -144,21 +100,7 @@ int PowerManager::unregisterSuspend(Suspendable *item) {
*
********************************************/
PowerManager::~PowerManager() {
- DEBUG_ENTER_FUNC();
-
- PMStatusSet(kDestroyPM);
-
- SDL_DestroyCond(_condSuspendable);
- _condSuspendable = 0;
-
- SDL_DestroyCond(_condPM);
- _condPM = 0;
-
- SDL_DestroyMutex(_flagMutex);
- _flagMutex = 0;
-
- SDL_DestroyMutex(_listMutex);
- _listMutex = 0;
+ _PMStatus = kDestroyPM;
}
/*******************************************
@@ -171,114 +113,92 @@ PowerManager::~PowerManager() {
*
********************************************/
void PowerManager::pollPauseEngine() {
-
+ DEBUG_ENTER_FUNC();
+
+
bool pause = _pauseFlag; // We copy so as not to have multiple values
- if ((pause != _pauseFlagOld) && g_engine) { // Check to see if we have an engine
- if (pause && _pauseClientState == PowerManager::Unpaused) {
- _pauseClientState = PowerManager::Pausing; // Tell PM we're in the middle of pausing
- g_engine->pauseEngine(true);
- PSP_DEBUG_PRINT_FUNC("Pausing engine\n");
- _pauseClientState = PowerManager::Paused; // Tell PM we're done pausing
- } else if (!pause && _pauseClientState == PowerManager::Paused) {
- g_engine->pauseEngine(false);
- PSP_DEBUG_PRINT_FUNC("Unpausing for resume\n");
- _pauseClientState = PowerManager::Unpaused; // Tell PM we're in the middle of pausing
+ if (pause != _pauseFlagOld) {
+ if (g_engine) { // Check to see if we have an engine
+ if (pause && _pauseClientState == UNPAUSED) {
+ _pauseClientState = PAUSING; // Tell PM we're in the middle of pausing
+ g_engine->pauseEngine(true);
+ PSP_DEBUG_PRINT_FUNC("Pausing engine\n");
+ _pauseClientState = PAUSED; // Tell PM we're done pausing
+ } else if (!pause && _pauseClientState == PAUSED) {
+ g_engine->pauseEngine(false);
+ PSP_DEBUG_PRINT_FUNC("Unpausing for resume\n");
+ _pauseClientState = UNPAUSED; // Tell PM we're unpaused
+ }
}
-
_pauseFlagOld = pause;
}
}
/*******************************************
*
-* Function to be called by threads wanting to block on the PSP entering suspend
-* Use this for small critical sections where you can easily restore the previous state.
-*
-********************************************/
-int PowerManager::blockOnSuspend() {
- return beginCriticalSection(true);
-}
-
-/*******************************************
-*
* Function to block on a suspend, then start a non-suspendable critical section
* Use this for large or REALLY critical critical-sections.
* Make sure to call endCriticalSection or the PSP won't suspend.
+* returns true if blocked, false if not blocked
********************************************/
-int PowerManager::beginCriticalSection(bool justBlock) {
+bool PowerManager::beginCriticalSection() {
DEBUG_ENTER_FUNC();
- int ret = NotBlocked;
-
- if (SDL_mutexP(_flagMutex) != 0) {
- PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't lock flagMutex[%p]\n", _flagMutex);
- ret = Error;
- }
+ bool ret = false;
+
+ _flagMutex.lock();
// Check the access flag
- if (_suspendFlag == true) {
- PSP_DEBUG_PRINT("We're being blocked!\n");
- debugPM();
- ret = Blocked;
+ if (_suspendFlag) {
+ ret = true;
- // If it's true, we wait for a signal to continue
- if (SDL_CondWait(_condSuspendable, _flagMutex) != 0) {
- PSP_DEBUG_PRINT("PowerManager::blockOnSuspend(): Couldn't wait on cond[%p]\n", _condSuspendable);
- }
+ PSP_DEBUG_PRINT("I got blocked. ThreadId[%x]\n", sceKernelGetThreadId());
+ debugPM();
+
+ _threadSleep.wait(_flagMutex);
- PSP_DEBUG_PRINT("We got blocked!!\n");
+ PSP_DEBUG_PRINT_FUNC("I got released. ThreadId[%x]\n", sceKernelGetThreadId());
debugPM();
}
// Now prevent the PM from suspending until we're done
- if (justBlock == false)
- _criticalCounter++;
+ _criticalCounter++;
- if (SDL_mutexV(_flagMutex) != 0) {
- PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't unlock flagMutex[%p]\n", _flagMutex);
- ret = Error;
- }
+ _flagMutex.unlock();
return ret;
}
-int PowerManager::endCriticalSection() {
+// returns success = true
+void PowerManager::endCriticalSection() {
DEBUG_ENTER_FUNC();
- int ret = 0;
- if (SDL_mutexP(_flagMutex) != 0) {
- PSP_ERROR("PowerManager::endCriticalSection(): Couldn't lock flagMutex[%p]\n", _flagMutex);
- ret = Error;
- }
+ _flagMutex.lock();
// We're done with our critical section
_criticalCounter--;
if (_criticalCounter <= 0) {
- if (_suspendFlag == true) { // If the PM is sleeping, this flag must be set
- PSP_DEBUG_PRINT("Unblocked thread waking up the PM.\n");
- debugPM();
-
- SDL_CondBroadcast(_condPM);
-
- PSP_DEBUG_PRINT("Woke up the PM\n");
- debugPM();
+ if (_suspendFlag) { // If the PM is sleeping, this flag must be set
+ PSP_DEBUG_PRINT_FUNC("PM is asleep. Waking it up.\n");
+ debugPM();
+
+ _pmSleep.releaseAll();
+
+ PSP_DEBUG_PRINT_FUNC("Woke up the PM\n");
+
+ debugPM();
}
if (_criticalCounter < 0) { // Check for bad usage of critical sections
- PSP_ERROR("Critical counter[%d]\n", _criticalCounter);
+ PSP_ERROR("Critical counter[%d]!!!\n", _criticalCounter);
debugPM();
}
}
- if (SDL_mutexV(_flagMutex) != 0) {
- PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
- ret = Error;
- }
-
- return ret;
+ _flagMutex.unlock();
}
/*******************************************
@@ -286,90 +206,77 @@ int PowerManager::endCriticalSection() {
* Callback function to be called to put every Suspendable to suspend
*
********************************************/
-int PowerManager::suspend() {
+void PowerManager::suspend() {
DEBUG_ENTER_FUNC();
- int ret = 0;
- if (_pauseFlag) return ret; // Very important - make sure we only suspend once
+ if (_pauseFlag)
+ return; // Very important - make sure we only suspend once
- scePowerLock(0); // Critical to make sure PSP doesn't suspend before we're done
+ scePowerLock(0); // Also critical to make sure PSP doesn't suspend before we're done
// The first stage of suspend is pausing the engine if possible. We don't want to cause files
// to block, or we might not get the engine to pause. On the other hand, we might wait for polling
// and it'll never happen. We also want to do this w/o mutexes (for speed) which is ok in this case.
_pauseFlag = true;
- PMStatusSet(kWaitForClientPause);
+ _PMStatus = kWaitForClientPause;
// Now we wait, giving the engine thread some time to find our flag.
- for (int i = 0; i < 10 && _pauseClientState == Unpaused; i++)
- sceKernelDelayThread(50000); // We wait 50 msec x 10 times = 0.5 seconds
+ for (int i = 0; i < 10 && _pauseClientState == UNPAUSED; i++)
+ PspThread::delayMicros(50000); // We wait 50 msec x 10 times = 0.5 seconds
- if (_pauseClientState == Pausing) { // Our event has been acknowledged. Let's wait until the client is done.
- PMStatusSet(kWaitForClientToFinishPausing);
+ if (_pauseClientState == PAUSING) { // Our event has been acknowledged. Let's wait until the client is done.
+ _PMStatus = kWaitForClientToFinishPausing;
- while (_pauseClientState != Paused)
- sceKernelDelayThread(50000); // We wait 50 msec at a time
+ while (_pauseClientState != PAUSED)
+ PspThread::delayMicros(50000); // We wait 50 msec at a time
}
- // It's possible that the polling thread missed our pause event, but there's nothing we can do about that.
- // We can't know if there's polling going on or not. It's usually not a critical thing anyway.
+ // It's possible that the polling thread missed our pause event, but there's
+ // nothing we can do about that.
+ // We can't know if there's polling going on or not.
+ // It's usually not a critical thing anyway.
- PMStatusSet(kGettingFlagMutexSuspend);
+ _PMStatus = kGettingFlagMutexSuspend;
// Now we set the suspend flag to true to cause reading threads to block
+ _flagMutex.lock();
- if (SDL_mutexP(_flagMutex) != 0) {
- PSP_ERROR("Couldn't lock flagMutex[%p]\n", _flagMutex);
- _error = Error;
- ret = Error;
- }
-
- PMStatusSet(kGotFlagMutexSuspend);
+ _PMStatus = kGotFlagMutexSuspend;
_suspendFlag = true;
// Check if anyone is in a critical section. If so, we'll wait for them
if (_criticalCounter > 0) {
- PMStatusSet(kWaitCritSectionSuspend);
- SDL_CondWait(_condPM, _flagMutex);
- PMStatusSet(kDoneWaitingCritSectionSuspend);
- }
+ _PMStatus = kWaitCritSectionSuspend;
+
+ _pmSleep.wait(_flagMutex);
+
+ _PMStatus = kDoneWaitingCritSectionSuspend;
+ }
+
+ _flagMutex.unlock();
- if (SDL_mutexV(_flagMutex) != 0) {
- PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
- _error = Error;
- ret = Error;
- }
-
- PMStatusSet(kGettingListMutexSuspend);
+ _PMStatus = kGettingListMutexSuspend;
// Loop over list, calling suspend()
- if (SDL_mutexP(_listMutex) != 0) {
- PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
- _error = Error;
- ret = Error;
- }
- PMStatusSet(kIteratingListSuspend);
+ _listMutex.lock();
+
+ _PMStatus = kIteratingListSuspend;
// Iterate
Common::List<Suspendable *>::iterator i;
for (i = _suspendList.begin(); i != _suspendList.end(); ++i) {
(*i)->suspend();
}
+ _PMStatus = kDoneIteratingListSuspend;
- PMStatusSet(kDoneIteratingListSuspend);
-
- if (SDL_mutexV(_listMutex) != 0) {
- PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
- _error = Error;
- ret = Error;
- }
- PMStatusSet(kDoneSuspend);
+ _listMutex.unlock();
+ _PMStatus = kDoneSuspend;
scePowerUnlock(0); // Allow the PSP to go to sleep now
-
- return ret;
+
+ _PMStatus = kDonePowerUnlock;
}
/*******************************************
@@ -377,24 +284,26 @@ int PowerManager::suspend() {
* Callback function to resume every Suspendable
*
********************************************/
-int PowerManager::resume() {
+void PowerManager::resume() {
DEBUG_ENTER_FUNC();
- int ret = 0;
+
+ _PMStatus = kBeginResume;
// Make sure we can't get another suspend
scePowerLock(0);
- if (!_pauseFlag) return ret; // Make sure we can only resume once
+ _PMStatus = kCheckingPauseFlag;
+
+ if (!_pauseFlag)
+ return; // Make sure we can only resume once
- PMStatusSet(kGettingListMutexResume);
+ _PMStatus = kGettingListMutexResume;
// First we notify our Suspendables. Loop over list, calling resume()
- if (SDL_mutexP(_listMutex) != 0) {
- PSP_ERROR("Couldn't lock listMutex[%p]\n", _listMutex);
- _error = Error;
- ret = Error;
- }
- PMStatusSet(kIteratingListResume);
+ _listMutex.lock();
+
+ _PMStatus = kIteratingListResume;
+
// Iterate
Common::List<Suspendable *>::iterator i = _suspendList.begin();
@@ -402,46 +311,31 @@ int PowerManager::resume() {
(*i)->resume();
}
- PMStatusSet(kDoneIteratingListResume);
+ _PMStatus = kDoneIteratingListResume;
- if (SDL_mutexV(_listMutex) != 0) {
- PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
- _error = Error;
- ret = Error;
- }
-
- PMStatusSet(kGettingFlagMutexResume);
+ _listMutex.unlock();
+
+ _PMStatus = kGettingFlagMutexResume;
// Now we set the suspend flag to false
- if (SDL_mutexP(_flagMutex) != 0) {
- PSP_ERROR("Couldn't lock flagMutex %p\n", _flagMutex);
- _error = Error;
- ret = Error;
- }
- PMStatusSet(kGotFlagMutexResume);
+ _flagMutex.lock();
+
+ _PMStatus = kGotFlagMutexResume;
_suspendFlag = false;
- PMStatusSet(kSignalSuspendedThreadsResume);
+ _PMStatus = kSignalSuspendedThreadsResume;
- // Signal the other threads to wake up
- if (SDL_CondBroadcast(_condSuspendable) != 0) {
- PSP_ERROR("Couldn't broadcast condition[%p]\n", _condSuspendable);
- _error = Error;
- ret = Error;
- }
- PMStatusSet(kDoneSignallingSuspendedThreadsResume);
+ // Signal the threads to wake up
+ _threadSleep.releaseAll();
+
+ _PMStatus = kDoneSignallingSuspendedThreadsResume;
- if (SDL_mutexV(_flagMutex) != 0) {
- PSP_ERROR("Couldn't unlock flagMutex[%p]\n", _flagMutex);
- _error = Error;
- ret = Error;
- }
- PMStatusSet(kDoneResume);
+ _flagMutex.unlock();
+
+ _PMStatus = kDoneResume;
- _pauseFlag = false; // Signal engine to unpause
+ _pauseFlag = false; // Signal engine to unpause -- no mutex needed
scePowerUnlock(0); // Allow new suspends
-
- return ret;
}