/[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 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years, 1 month ago) by william
File MIME type: text/plain
File size: 8523 byte(s)
committing r3113 initial commit again...
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 PersistentThread
33 {
34 typedef PersistentThread _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
99 bool IsPaused() const { return !IsRunning() || (m_ExecMode <= ExecMode_Paused); }
100
101 bool HasPendingStateChangeRequest() const
102 {
103 ExecutionMode mode = m_ExecMode;
104 return (mode == ExecMode_Closing) || (mode == ExecMode_Pausing);
105 }
106
107 ExecutionMode GetExecutionMode() const { return m_ExecMode; }
108 Mutex& ExecutionModeMutex() { return m_ExecModeMutex; }
109
110 virtual void Suspend( bool isBlocking = true );
111 virtual void Resume();
112 virtual void Pause();
113
114 protected:
115 virtual void OnStart();
116
117 // This function is called by Resume immediately prior to releasing the suspension of
118 // the core emulation thread. You should overload this rather than Resume(), since
119 // Resume() has a lot of checks and balances to prevent re-entrance and race conditions.
120 virtual void OnResumeReady() {}
121
122 virtual void StateCheckInThread();
123 virtual void OnCleanupInThread();
124 virtual void OnStartInThread();
125
126 // Used internally from Resume(), so let's make it private here.
127 virtual void Start();
128
129 // Extending classes should implement this, but should not call it. The parent class
130 // handles invocation by the following guidelines: Called *in thread* from StateCheckInThread()
131 // prior to suspending the thread (ie, when Suspend() has been called on a separate
132 // thread, requesting this thread suspend itself temporarily). After this is called,
133 // the thread enters a waiting state on the m_sem_Resume semaphore.
134 virtual void OnSuspendInThread()=0;
135
136 // Extending classes should implement this, but should not call it. The parent class
137 // handles invocation by the following guidelines: Called *in thread* from StateCheckInThread()
138 // prior to pausing the thread (ie, when Pause() has been called on a separate thread,
139 // requesting this thread pause itself temporarily). After this is called, the thread
140 // enters a waiting state on the m_sem_Resume semaphore.
141 virtual void OnPauseInThread()=0;
142
143 // Extending classes should implement this, but should not call it. The parent class
144 // handles invocation by the following guidelines: Called from StateCheckInThread() after the
145 // thread has been suspended and then subsequently resumed.
146 // Parameter:
147 // isSuspended - set to TRUE if the thread is returning from a suspended state, or
148 // FALSE if it's returning from a paused state.
149 virtual void OnResumeInThread( bool isSuspended )=0;
150 };
151
152
153 // --------------------------------------------------------------------------------------
154 // SysCoreThread class
155 // --------------------------------------------------------------------------------------
156 class SysCoreThread : public SysThreadBase
157 {
158 typedef SysThreadBase _parent;
159
160 protected:
161 bool m_resetRecompilers;
162 bool m_resetProfilers;
163 bool m_resetVsyncTimers;
164 bool m_resetVirtualMachine;
165
166 // Indicates if the system has an active virtual machine state. Pretty much always
167 // true anytime between plugins being initialized and plugins being shutdown. Gets
168 // set false when plugins are shutdown, the corethread is canceled, or when an error
169 // occurs while trying to upload a new state into the VM.
170 volatile bool m_hasActiveMachine;
171
172 wxString m_elf_override;
173
174 SSE_MXCSR m_mxcsr_saved;
175
176 public:
177 explicit SysCoreThread();
178 virtual ~SysCoreThread() throw();
179
180 bool HasPendingStateChangeRequest() const;
181
182 virtual void OnResumeReady();
183 virtual void Reset();
184 virtual void Cancel( bool isBlocking=true );
185 virtual bool Cancel( const wxTimeSpan& timeout );
186
187 virtual void StateCheckInThread();
188 virtual void VsyncInThread();
189 virtual void PostVsyncToUI()=0;
190
191 virtual void ApplySettings( const Pcsx2Config& src );
192 virtual void UploadStateCopy( const VmStateBuffer& copy );
193
194 virtual bool HasActiveMachine() const { return m_hasActiveMachine; }
195
196 virtual const wxString& GetElfOverride() const { return m_elf_override; }
197 virtual void SetElfOverride( const wxString& elf );
198
199 protected:
200 void _reset_stuff_as_needed();
201
202 virtual void Start();
203 virtual void OnStart();
204 virtual void OnSuspendInThread();
205 virtual void OnPauseInThread() {}
206 virtual void OnResumeInThread( bool IsSuspended );
207 virtual void OnCleanupInThread();
208 virtual void ExecuteTaskInThread();
209 virtual void DoCpuReset();
210 virtual void DoCpuExecute();
211
212 void _StateCheckThrows();
213 };
214
215
216 struct SysStateUnlockedParams
217 {
218 SysStateUnlockedParams() {}
219 };
220
221 // --------------------------------------------------------------------------------------
222 // IEventListener_SaveStateThread
223 // --------------------------------------------------------------------------------------
224 class IEventListener_SysState : public IEventDispatcher<SysStateUnlockedParams>
225 {
226 public:
227 typedef SysStateUnlockedParams EvtParams;
228
229 public:
230 IEventListener_SysState() {}
231 virtual ~IEventListener_SysState() throw() {}
232
233 virtual void DispatchEvent( const SysStateUnlockedParams& status )
234 {
235 SysStateAction_OnUnlocked();
236 }
237
238 protected:
239 virtual void SysStateAction_OnUnlocked();
240 };
241
242 // GetCoreThread() is a required external implementation. This function is *NOT*
243 // provided by the PCSX2 core library. It provides an interface for the linking User
244 // Interface apps or DLLs to reference their own instance of SysCoreThread (also allowing
245 // them to extend the class and override virtual methods).
246 //
247 extern SysCoreThread& GetCoreThread();

  ViewVC Help
Powered by ViewVC 1.1.22