[Scummvm-cvs-logs] SF.net SVN: scummvm:[49852] scummvm/trunk/backends

Bluddy at users.sourceforge.net Bluddy at users.sourceforge.net
Tue Jun 15 15:10:01 CEST 2010


Revision: 49852
          http://scummvm.svn.sourceforge.net/scummvm/?rev=49852&view=rev
Author:   Bluddy
Date:     2010-06-15 13:10:00 +0000 (Tue, 15 Jun 2010)

Log Message:
-----------
PSP: fixed up PowerManager and removed dependency on SDL

Modified Paths:
--------------
    scummvm/trunk/backends/fs/psp/psp-stream.cpp
    scummvm/trunk/backends/platform/psp/powerman.cpp
    scummvm/trunk/backends/platform/psp/powerman.h
    scummvm/trunk/backends/platform/psp/thread.cpp
    scummvm/trunk/backends/platform/psp/thread.h

Modified: scummvm/trunk/backends/fs/psp/psp-stream.cpp
===================================================================
--- scummvm/trunk/backends/fs/psp/psp-stream.cpp	2010-06-15 13:01:07 UTC (rev 49851)
+++ scummvm/trunk/backends/fs/psp/psp-stream.cpp	2010-06-15 13:10:00 UTC (rev 49852)
@@ -81,10 +81,10 @@
 PSPIoStream::~PSPIoStream() {
 	DEBUG_ENTER_FUNC();
 
-	if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+	if (PowerMan.beginCriticalSection())
 		PSP_DEBUG_PRINT_FUNC("Suspended\n");
 
-	PowerMan.unregisterSuspend(this); // Unregister with powermanager to be suspended
+	PowerMan.unregisterForSuspend(this); // Unregister with powermanager to be suspended
 									  // Must do this before fclose() or resume() will reopen.
 
 	fclose((FILE *)_handle);		  // We don't need a critical section. Worst case, the handle gets closed on its own
@@ -100,7 +100,7 @@
  */
 void *PSPIoStream::open() {
 	DEBUG_ENTER_FUNC();
-	if (PowerMan.beginCriticalSection() == PowerManager::Blocked) {
+	if (PowerMan.beginCriticalSection()) {
 		// No need to open. Just return the _handle resume() already opened.
 		PSP_DEBUG_PRINT_FUNC("Suspended\n");
 	}
@@ -118,7 +118,7 @@
 		_cache = (char *)memalign(64, CACHE_SIZE);
 	}
 
-	PowerMan.registerSuspend(this);	 // Register with the powermanager to be suspended
+	PowerMan.registerForSuspend(this);	 // Register with the powermanager to be suspended
 
 	PowerMan.endCriticalSection();
 
@@ -233,7 +233,7 @@
 		}		
 	}
 
-	if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+	if (PowerMan.beginCriticalSection())
 		PSP_DEBUG_PRINT_FUNC("Suspended\n");
 	
 	
@@ -309,7 +309,7 @@
 uint32 PSPIoStream::write(const void *ptr, uint32 len) {
 	DEBUG_ENTER_FUNC();
 	// Check if we can access the file
-	if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+	if (PowerMan.beginCriticalSection())
 		PSP_DEBUG_PRINT_FUNC("Suspended\n");
 
 	PSP_DEBUG_PRINT_FUNC("filename[%s], len[0x%x]\n", _path.c_str(), len);
@@ -346,7 +346,7 @@
 bool PSPIoStream::flush() {
 	DEBUG_ENTER_FUNC();
 	// Enter critical section
-	if (PowerMan.beginCriticalSection() == PowerManager::Blocked)
+	if (PowerMan.beginCriticalSection())
 		PSP_DEBUG_PRINT_FUNC("Suspended\n");
 
 	int ret = fflush((FILE *)_handle);

Modified: scummvm/trunk/backends/platform/psp/powerman.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/powerman.cpp	2010-06-15 13:01:07 UTC (rev 49851)
+++ scummvm/trunk/backends/platform/psp/powerman.cpp	2010-06-15 13:10:00 UTC (rev 49852)
@@ -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 @@
 *	Constructor
 *
 ********************************************/
-PowerManager::PowerManager() {
-	DEBUG_ENTER_FUNC();
+PowerManager::PowerManager() : _pauseFlag(false), _pauseFlagOld(false), _pauseClientState(UNPAUSED),
+								_suspendFlag(false), _flagMutex(true), _listMutex(true),
+								_criticalCounter(0), _listCounter(0), _error(0), _PMStatus(kInitDone) {}
 
-	_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;
-}
-
 /*******************************************
 *
 *	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 @@
 *	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 @@
 *
 ********************************************/
 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 @@
 *
 ********************************************/
 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;
+	bool ret = false;
+	
+	_flagMutex.lock();
 
-	if (SDL_mutexP(_flagMutex) != 0) {
-		PSP_ERROR("PowerManager::blockOnSuspend(): Couldn't lock flagMutex[%p]\n", _flagMutex);
-		ret = Error;
-	}
-
 	// Check the access flag
-	if (_suspendFlag == true) {
-		PSP_DEBUG_PRINT("We're being blocked!\n");
+	if (_suspendFlag) {
+		ret = true;
+
+		PSP_DEBUG_PRINT("I got blocked. ThreadId[%x]\n", sceKernelGetThreadId());
 		debugPM();
-		ret = Blocked;
+		
+		_threadSleep.wait(_flagMutex);
 
-		// 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("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 @@
 *	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;
-	}
+	_PMStatus = kGotFlagMutexSuspend;
 
-	PMStatusSet(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;
-	}
+	_PMStatus = kGettingListMutexSuspend;
 
-	PMStatusSet(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);
+	_listMutex.unlock();
+	_PMStatus = kDoneSuspend;
 
-	if (SDL_mutexV(_listMutex) != 0) {
-		PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
-		_error = Error;
-		ret = Error;
-	}
-	PMStatusSet(kDoneSuspend);
-
 	scePowerUnlock(0);				// Allow the PSP to go to sleep now
-
-	return ret;
+	
+	_PMStatus = kDonePowerUnlock;
 }
 
 /*******************************************
@@ -377,24 +284,26 @@
 *	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 @@
 		(*i)->resume();
 	}
 
-	PMStatusSet(kDoneIteratingListResume);
+	_PMStatus = kDoneIteratingListResume;
 
-	if (SDL_mutexV(_listMutex) != 0) {
-		PSP_ERROR("Couldn't unlock listMutex[%p]\n", _listMutex);
-		_error = Error;
-		ret = Error;
-	}
+	_listMutex.unlock();
+	
+	_PMStatus = kGettingFlagMutexResume;
 
-	PMStatusSet(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;
 }

Modified: scummvm/trunk/backends/platform/psp/powerman.h
===================================================================
--- scummvm/trunk/backends/platform/psp/powerman.h	2010-06-15 13:01:07 UTC (rev 49851)
+++ scummvm/trunk/backends/platform/psp/powerman.h	2010-06-15 13:10:00 UTC (rev 49852)
@@ -26,8 +26,7 @@
 #ifndef POWERMAN_H
 #define POWERMAN_H
 
-#include <SDL/SDL_thread.h>
-#include <SDL/SDL_mutex.h>
+#include "backends/platform/psp/thread.h"
 #include "common/singleton.h"
 #include "common/list.h"
 
@@ -53,12 +52,12 @@
 
 public:
 	int blockOnSuspend();								/* block if suspending */
-	int beginCriticalSection(bool justBlock = false);	/* Use a critical section to block (if suspend was already pressed) */
-	int endCriticalSection();							/* and to prevent the PSP from suspending in a particular section */
-	int registerSuspend(Suspendable *item);			/* register to be called to suspend/resume */
-	int unregisterSuspend(Suspendable *item);		/* remove from suspend/resume list */
-	int suspend();									/* callback to have all items in list suspend */
-	int resume();									/* callback to have all items in list resume */
+	bool beginCriticalSection();	/* Use a critical section to block (if suspend was already pressed) */
+	void endCriticalSection();							/* and to prevent the PSP from suspending in a particular section */
+	bool registerForSuspend(Suspendable *item);			/* register to be called to suspend/resume */
+	bool unregisterForSuspend(Suspendable *item);		/* remove from suspend/resume list */
+	void suspend();									/* callback to have all items in list suspend */
+	void resume();									/* callback to have all items in list resume */
 	// Functions for pausing the engine
 	void pollPauseEngine();							/* Poll whether the engine should be paused */
 
@@ -69,11 +68,9 @@
 	};
 
 	enum PauseState {
-		Unpaused = 0,
-		PauseEvent,
-		UnpauseEvent,
-		Pausing,
-		Paused
+		UNPAUSED = 0,
+		PAUSING,
+		PAUSED
 	};
 
 private:
@@ -81,34 +78,38 @@
 	PowerManager();
 	~PowerManager();
 
-	Common::List<Suspendable *> _suspendList;		/* list to register in */
+	Common::List<Suspendable *> _suspendList;		// list to register in
 
-	volatile bool _pauseFlag;						/* For pausing, which is before suspending */
-	volatile bool _pauseFlagOld;					/* Save the last state of the flag while polling */
-	volatile int _pauseClientState;					/* Pause state of the target */
+	volatile bool _pauseFlag;						// For pausing, which is before suspending
+	volatile bool _pauseFlagOld;					// Save the last state of the flag while polling
+	volatile PauseState _pauseClientState;			// Pause state of the target
 
-	volatile bool _suspendFlag;						/* protected variable */
-	SDL_mutex *_flagMutex;							/* mutex to access access flag */
-	SDL_mutex *_listMutex;							/* mutex to access Suspendable list */
-	SDL_cond *_condSuspendable;						/* signal to synchronize accessing threads */
-	SDL_cond *_condPM;								/* signal to wake up the PM from a critical section */
-	volatile int _criticalCounter;					/* Counter of how many threads are in a critical section */
-	int _error;										/* error code - PM can't talk to us. For debugging */
+	volatile bool _suspendFlag;						// protected variable
+	PspMutex _flagMutex;							// mutex to access access flag
+	PspMutex _listMutex;							// mutex to access Suspendable list
+	PspCondition _threadSleep;						// signal to synchronize accessing threads
+	PspCondition _pmSleep;							// signal to wake up the PM from a critical section
+	volatile int _criticalCounter;					// Counter of how many threads are in a critical section
+	int _error;										// error code - PM can't talk to us. For debugging
+	volatile int _PMStatus;							// What the PM is doing. for debugging
 
 	// States for PM to be in (used for debugging)
 	enum PMState {
-		kInitDone = 1 ,
-		kDestroyPM,
-		kWaitForClientPause,
-		kWaitForClientToFinishPausing,
-		kGettingFlagMutexSuspend,
-		kGotFlagMutexSuspend,
-		kWaitCritSectionSuspend,
-		kDoneWaitingCritSectionSuspend,
-		kGettingListMutexSuspend,
-		kIteratingListSuspend,
-		kDoneIteratingListSuspend,
-		kDoneSuspend,
+		kInitDone = 1,
+		kDestroyPM = 2,
+		kWaitForClientPause = 3,
+		kWaitForClientToFinishPausing = 4,
+		kGettingFlagMutexSuspend = 5,
+		kGotFlagMutexSuspend = 6,
+		kWaitCritSectionSuspend = 7,
+		kDoneWaitingCritSectionSuspend = 8,
+		kGettingListMutexSuspend = 9,
+		kIteratingListSuspend = 10,
+		kDoneIteratingListSuspend = 11,
+		kDoneSuspend = 12,
+		kDonePowerUnlock,
+		kBeginResume,
+		kCheckingPauseFlag,
 		kGettingListMutexResume,
 		kIteratingListResume,
 		kDoneIteratingListResume,
@@ -122,8 +123,6 @@
 	volatile int _listCounter;						/* How many people are in the list - just for debugging */
 
 	void debugPM();									/* print info about the PM */
-	void PMStatusSet(PMState s) { _PMStatus = s; }
-	volatile int _PMStatus;							/* What the PM is doing */
 
 public:
 	int getPMStatus() const { return _PMStatus; }

Modified: scummvm/trunk/backends/platform/psp/thread.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/thread.cpp	2010-06-15 13:01:07 UTC (rev 49851)
+++ scummvm/trunk/backends/platform/psp/thread.cpp	2010-06-15 13:10:00 UTC (rev 49852)
@@ -47,10 +47,10 @@
 
 #include "backends/platform/psp/trace.h"
 
-PspSemaphore::PspSemaphore(int initialValue, int maxValue) {
+PspSemaphore::PspSemaphore(int initialValue, int maxValue/*=255*/) {
 	DEBUG_ENTER_FUNC();
 	_handle = 0;
-	_handle = sceKernelCreateSema("ScummVM Sema", 0 /* attr */, 
+	_handle = (uint32)sceKernelCreateSema("ScummVM Sema", 0 /* attr */, 
 								  initialValue, maxValue, 
 								  0 /*option*/);
 	if (!_handle)
@@ -60,7 +60,7 @@
 PspSemaphore::~PspSemaphore() {
 	DEBUG_ENTER_FUNC();
 	if (_handle)
-		if (sceKernelDeleteSema(_handle) < 0)
+		if (sceKernelDeleteSema((SceUID)_handle) < 0)
 			PSP_ERROR("failed to delete semaphore.\n");
 }
 
@@ -69,7 +69,7 @@
 	SceKernelSemaInfo info;
 	info.numWaitThreads = 0;
 	
-	if (sceKernelReferSemaStatus(_handle, &info) < 0)
+	if (sceKernelReferSemaStatus((SceUID)_handle, &info) < 0)
 		PSP_ERROR("failed to retrieve semaphore info for handle %d\n", _handle);
 		
 	return info.numWaitThreads;
@@ -80,7 +80,7 @@
 	SceKernelSemaInfo info;
 	info.currentCount = 0;
 	
-	if (sceKernelReferSemaStatus(_handle, &info) < 0)
+	if (sceKernelReferSemaStatus((SceUID)_handle, &info) < 0)
 		PSP_ERROR("failed to retrieve semaphore info for handle %d\n", _handle);
 		
 	return info.currentCount;
@@ -88,7 +88,7 @@
 
 bool PspSemaphore::pollForValue(int value) {
 	DEBUG_ENTER_FUNC();
-	if (sceKernelPollSema(_handle, value) < 0)
+	if (sceKernelPollSema((SceUID)_handle, value) < 0)
 		return false;
 	
 	return true;
@@ -107,10 +107,10 @@
 	return true;
 }
 
-bool PspSemaphore::give(int num) {
+bool PspSemaphore::give(int num /*=1*/) {
 	DEBUG_ENTER_FUNC();
 	
-	if (sceKernelSignalSema(_handle, num) < 0)
+	if (sceKernelSignalSema((SceUID)_handle, num) < 0)
 		return false;	
 	return true;
 }
@@ -152,6 +152,46 @@
 	return ret;
 }
 
+// Class PspCondition -------------------------------------------------
+
+// Release all threads waiting on the condition
+void PspCondition::releaseAll() {
+        _mutex.lock();
+        if (_waitingThreads > _signaledThreads) {	// we have signals to issue
+                int numWaiting = _waitingThreads - _signaledThreads;	// threads we haven't signaled
+                _signaledThreads = _waitingThreads;
+                
+				_waitSem.give(numWaiting);
+                _mutex.unlock();
+                for (int i=0; i<numWaiting; i++)	// wait for threads to tell us they're awake
+					_doneSem.take();
+        } else {
+                _mutex.unlock();
+        }
+}
+
+// Mutex must be taken before entering wait
+void PspCondition::wait(PspMutex &externalMutex) {
+        _mutex.lock();
+        _waitingThreads++;
+        _mutex.unlock();
+
+        externalMutex.unlock();	// must unlock external mutex
+
+		_waitSem.take();	// sleep on the wait semaphore
+
+		// let the signaling thread know we're done
+		_mutex.lock();
+        if (_signaledThreads > 0 ) {
+                _doneSem.give();	// let the thread know
+                _signaledThreads--;
+        }
+        _waitingThreads--;
+        _mutex.unlock();
+
+        externalMutex.lock();		// must lock external mutex here for continuation
+}
+
 //#define __PSP_DEBUG_FUNCS__	/* For debugging function calls */
 //#define __PSP_DEBUG_PRINT__	/* For debug printouts */
 

Modified: scummvm/trunk/backends/platform/psp/thread.h
===================================================================
--- scummvm/trunk/backends/platform/psp/thread.h	2010-06-15 13:01:07 UTC (rev 49851)
+++ scummvm/trunk/backends/platform/psp/thread.h	2010-06-15 13:10:00 UTC (rev 49852)
@@ -36,13 +36,13 @@
 
 class PspSemaphore {
 private:
-	SceUID _handle;
+	uint32 _handle;
 public:
-	PspSemaphore(int initialValue, int maxValue);
+	PspSemaphore(int initialValue, int maxValue=255);
 	~PspSemaphore();
 	bool take() { return takeWithTimeOut(0); }
 	bool takeWithTimeOut(uint32 timeOut);
-	bool give(int num);
+	bool give(int num=1);
 	bool pollForValue(int value);	// check for a certain value
 	int numOfWaitingThreads();
 	int getValue();
@@ -62,7 +62,21 @@
 	bool getValue() { return (bool)_semaphore.getValue(); }
 };
 
+class PspCondition {
+private:
+	PspMutex _mutex;
+	int _waitingThreads;
+	int _signaledThreads;
+	PspSemaphore _waitSem;
+	PspSemaphore _doneSem;
+public:
+	PspCondition() : _mutex(true), _waitingThreads(0), _signaledThreads(0),
+								_waitSem(0), _doneSem(0) {}
+	void wait(PspMutex &externalMutex);
+	void releaseAll();	
+};
 
+
 class PspRtc {
 private:
 	uint32 _startMillis;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list