/[pcsx2_0.9.7]/trunk/pcsx2/System/SysThreads.h
ViewVC logotype

Contents of /trunk/pcsx2/System/SysThreads.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years ago) by william
File MIME type: text/plain
File size: 8603 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #pragma once
17
18 #include "System.h"
19
20 #include "Utilities/PersistentThread.h"
21 #include "x86emitter/tools.h"
22
23
24 using namespace Threading;
25
26 typedef SafeArray<u8> VmStateBuffer;
27
28 // --------------------------------------------------------------------------------------
29 // SysThreadBase
30 // --------------------------------------------------------------------------------------
31
32 class SysThreadBase : public pxThread
33 {
34 typedef pxThread _parent;
35
36 public:
37 // Important: The order of these enumerations matters! Optimized tests are used for both
38 // Closed and Paused states.
39 enum ExecutionMode
40 {
41 // Thread has not been created yet. Typically this is the same as IsRunning()
42 // returning FALSE.
43 ExecMode_NoThreadYet,
44
45 // Thread is safely paused, with plugins in a "closed" state, and waiting for a
46 // resume/open signal.
47 ExecMode_Closed,
48
49 // Thread is safely paused, with plugins in an "open" state, and waiting for a
50 // resume/open signal.
51 ExecMode_Paused,
52
53 // Thread is active and running, with pluigns in an "open" state.
54 ExecMode_Opened,
55
56 // Close signal has been sent to the thread, but the thread's response is still
57 // pending (thread is busy/running).
58 ExecMode_Closing,
59
60 // Pause signal has been sent to the thread, but the thread's response is still
61 // pending (thread is busy/running).
62 ExecMode_Pausing,
63 };
64
65 protected:
66 volatile ExecutionMode m_ExecMode;
67
68 // This lock is used to avoid simultaneous requests to Suspend/Resume/Pause from
69 // contending threads.
70 MutexRecursive m_ExecModeMutex;
71
72 // Used to wake up the thread from sleeping when it's in a suspended state.
73 Semaphore m_sem_Resume;
74
75 // Used to synchronize inline changes from paused to suspended status.
76 Semaphore m_sem_ChangingExecMode;
77
78 // Locked whenever the thread is not in a suspended state (either closed or paused).
79 // Issue a Wait against this mutex for performing actions that require the thread
80 // to be suspended.
81 Mutex m_RunningLock;
82
83 public:
84 explicit SysThreadBase();
85 virtual ~SysThreadBase() throw();
86
87 // Thread safety for IsOpen / IsClosed: The execution mode can change at any time on
88 // any thread, so the actual status may have already changed by the time this function
89 // returns its result. Typically this isn't of major concern. However if you need
90 // more assured execution mode status, issue a lock against the ExecutionModeMutex()
91 // first.
92 bool IsOpen() const
93 {
94 return IsRunning() && (m_ExecMode > ExecMode_Closed);
95 }
96
97 bool IsClosed() const { return !IsOpen(); }
98 bool IsPaused() const { return !IsRunning() || (m_ExecMode <= ExecMode_Paused); }
99
100 bool IsClosing() const
101 {
102 return !IsRunning() || (m_ExecMode <= ExecMode_Closed) || (m_ExecMode == ExecMode_Closing);
103 }
104
105 bool HasPendingStateChangeRequest() const
106 {
107 return m_ExecMode >= ExecMode_Closing;
108 }
109
110 ExecutionMode GetExecutionMode() const { return m_ExecMode; }
111 Mutex& ExecutionModeMutex() { return m_ExecModeMutex; }
112
113 virtual void Suspend( bool isBlocking = true );
114 virtual void Resume();
115 virtual void Pause();
116
117 protected:
118 virtual void OnStart();
119
120 // This function is called by Resume immediately prior to releasing the suspension of
121 // the core emulation thread. You should overload this rather than Resume(), since
122 // Resume() has a lot of checks and balances to prevent re-entrance and race conditions.
123 virtual void OnResumeReady() {}
124
125 virtual bool StateCheckInThread();
126 virtual void OnCleanupInThread();
127 virtual void OnStartInThread();
128
129 // Used internally from Resume(), so let's make it private here.
130 virtual void Start();
131
132 // Extending classes should implement this, but should not call it. The parent class
133 // handles invocation by the following guidelines: Called *in thread* from StateCheckInThread()
134 // prior to suspending the thread (ie, when Suspend() has been called on a separate
135 // thread, requesting this thread suspend itself temporarily). After this is called,
136 // the thread enters a waiting state on the m_sem_Resume semaphore.
137 virtual void OnSuspendInThread()=0;
138
139 // Extending classes should implement this, but should not call it. The parent class
140 // handles invocation by the following guidelines: Called *in thread* from StateCheckInThread()
141 // prior to pausing the thread (ie, when Pause() has been called on a separate thread,
142 // requesting this thread pause itself temporarily). After this is called, the thread
143 // enters a waiting state on the m_sem_Resume semaphore.
144 virtual void OnPauseInThread()=0;
145
146 // Extending classes should implement this, but should not call it. The parent class
147 // handles invocation by the following guidelines: Called from StateCheckInThread() after the
148 // thread has been suspended and then subsequently resumed.
149 // Parameter:
150 // isSuspended - set to TRUE if the thread is returning from a suspended state, or
151 // FALSE if it's returning from a paused state.
152 virtual void OnResumeInThread( bool isSuspended )=0;
153 };
154
155
156 // --------------------------------------------------------------------------------------
157 // SysCoreThread class
158 // --------------------------------------------------------------------------------------
159 class SysCoreThread : public SysThreadBase
160 {
161 typedef SysThreadBase _parent;
162
163 protected:
164 bool m_resetRecompilers;
165 bool m_resetProfilers;
166 bool m_resetVsyncTimers;
167 bool m_resetVirtualMachine;
168
169 // Indicates if the system has an active virtual machine state. Pretty much always
170 // true anytime between plugins being initialized and plugins being shutdown. Gets
171 // set false when plugins are shutdown, the corethread is canceled, or when an error
172 // occurs while trying to upload a new state into the VM.
173 volatile bool m_hasActiveMachine;
174
175 wxString m_elf_override;
176
177 SSE_MXCSR m_mxcsr_saved;
178
179 public:
180 explicit SysCoreThread();
181 virtual ~SysCoreThread() throw();
182
183 bool HasPendingStateChangeRequest() const;
184
185 virtual void OnResumeReady();
186 virtual void Reset();
187 virtual void ResetQuick();
188 virtual void Cancel( bool isBlocking=true );
189 virtual bool Cancel( const wxTimeSpan& timeout );
190
191 virtual bool StateCheckInThread();
192 virtual void VsyncInThread();
193 virtual void GameStartingInThread();
194
195 virtual void ApplySettings( const Pcsx2Config& src );
196 virtual void UploadStateCopy( const VmStateBuffer& copy );
197
198 virtual bool HasActiveMachine() const { return m_hasActiveMachine; }
199
200 virtual const wxString& GetElfOverride() const { return m_elf_override; }
201 virtual void SetElfOverride( const wxString& elf );
202
203 protected:
204 void _reset_stuff_as_needed();
205
206 virtual void Start();
207 virtual void OnStart();
208 virtual void OnSuspendInThread();
209 virtual void OnPauseInThread() {}
210 virtual void OnResumeInThread( bool IsSuspended );
211 virtual void OnCleanupInThread();
212 virtual void ExecuteTaskInThread();
213 virtual void DoCpuReset();
214 virtual void DoCpuExecute();
215
216 void _StateCheckThrows();
217 };
218
219
220 struct SysStateUnlockedParams
221 {
222 SysStateUnlockedParams() {}
223 };
224
225 // --------------------------------------------------------------------------------------
226 // IEventListener_SaveStateThread
227 // --------------------------------------------------------------------------------------
228 class IEventListener_SysState : public IEventDispatcher<SysStateUnlockedParams>
229 {
230 public:
231 typedef SysStateUnlockedParams EvtParams;
232
233 public:
234 IEventListener_SysState() {}
235 virtual ~IEventListener_SysState() throw() {}
236
237 virtual void DispatchEvent( const SysStateUnlockedParams& status )
238 {
239 SysStateAction_OnUnlocked();
240 }
241
242 protected:
243 virtual void SysStateAction_OnUnlocked();
244 };
245
246 // GetCoreThread() is a required external implementation. This function is *NOT*
247 // provided by the PCSX2 core library. It provides an interface for the linking User
248 // Interface apps or DLLs to reference their own instance of SysCoreThread (also allowing
249 // them to extend the class and override virtual methods).
250 //
251 extern SysCoreThread& GetCoreThread();

  ViewVC Help
Powered by ViewVC 1.1.22