1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef POWERMAN_H 24 #define POWERMAN_H 25 26 #include "backends/platform/psp/thread.h" 27 #include "common/singleton.h" 28 #include "common/list.h" 29 30 #include "engines/engine.h" // for PauseToken 31 32 /* 33 * Implement this class (interface) if you want to use PowerManager's suspend callback functionality 34 * 35 */ 36 class Suspendable { 37 public: ~Suspendable()38 virtual ~Suspendable() {} 39 virtual int suspend() = 0; 40 virtual int resume() = 0; 41 }; 42 43 /****************************************************************************************************** 44 * 45 * This class will call a Suspendable when the PSP goes to suspend/resumes. It also provides the ability to block 46 * a thread when the PSP is going to suspend/suspending, and to wake it up when the PSP is resumed. 47 * This ability is very useful for managing the PSPIoStream class, but may be found useful by other classes as well. 48 * 49 *******************************************************************************************************/ 50 class PowerManager: public Common::Singleton<PowerManager> { 51 52 public: 53 int blockOnSuspend(); /* block if suspending */ 54 bool beginCriticalSection(); /* Use a critical section to block (if suspend was already pressed) */ 55 void endCriticalSection(); /* and to prevent the PSP from suspending in a particular section */ 56 bool registerForSuspend(Suspendable *item); /* register to be called to suspend/resume */ 57 bool unregisterForSuspend(Suspendable *item); /* remove from suspend/resume list */ 58 void suspend(); /* callback to have all items in list suspend */ 59 void resume(); /* callback to have all items in list resume */ 60 // Functions for pausing the engine 61 void pollPauseEngine(); /* Poll whether the engine should be paused */ 62 63 enum { 64 Error = -1, 65 NotBlocked = 0, 66 Blocked = 1 67 }; 68 69 enum PauseState { 70 UNPAUSED = 0, 71 PAUSING, 72 PAUSED 73 }; 74 75 private: 76 friend class Common::Singleton<PowerManager>; 77 PowerManager(); 78 ~PowerManager(); 79 80 Common::List<Suspendable *> _suspendList; // list to register in 81 82 volatile bool _pauseFlag; // For pausing, which is before suspending 83 volatile bool _pauseFlagOld; // Save the last state of the flag while polling 84 volatile PauseState _pauseClientState; // Pause state of the target 85 PauseToken _pauseToken; 86 87 volatile bool _suspendFlag; // protected variable 88 PspMutex _flagMutex; // mutex to access access flag 89 PspMutex _listMutex; // mutex to access Suspendable list 90 PspCondition _threadSleep; // signal to synchronize accessing threads 91 PspCondition _pmSleep; // signal to wake up the PM from a critical section 92 volatile int _criticalCounter; // Counter of how many threads are in a critical section 93 int _error; // error code - PM can't talk to us. For debugging 94 volatile int _PMStatus; // What the PM is doing. for debugging 95 96 // States for PM to be in (used for debugging) 97 enum PMState { 98 kInitDone = 1, 99 kDestroyPM = 2, 100 kWaitForClientPause = 3, 101 kWaitForClientToFinishPausing = 4, 102 kGettingFlagMutexSuspend = 5, 103 kGotFlagMutexSuspend = 6, 104 kWaitCritSectionSuspend = 7, 105 kDoneWaitingCritSectionSuspend = 8, 106 kGettingListMutexSuspend = 9, 107 kIteratingListSuspend = 10, 108 kDoneIteratingListSuspend = 11, 109 kDoneSuspend = 12, 110 kDonePowerUnlock, 111 kBeginResume, 112 kCheckingPauseFlag, 113 kGettingListMutexResume, 114 kIteratingListResume, 115 kDoneIteratingListResume, 116 kGettingFlagMutexResume, 117 kGotFlagMutexResume, 118 kSignalSuspendedThreadsResume, 119 kDoneSignallingSuspendedThreadsResume, 120 kDoneResume 121 }; 122 123 volatile int _listCounter; /* How many people are in the list - just for debugging */ 124 125 void debugPM(); /* print info about the PM */ 126 127 public: getPMStatus()128 int getPMStatus() const { return _PMStatus; } 129 130 }; 131 132 // For easy access 133 #define PowerMan PowerManager::instance() 134 135 #endif /* POWERMAN_H */ 136