/[pcsx2_0.9.7]/trunk/pcsx2/System/SysCoreThread.cpp
ViewVC logotype

Contents of /trunk/pcsx2/System/SysCoreThread.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (show annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years ago) by william
File size: 7323 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 #include "PrecompiledHeader.h"
17 #include "Common.h"
18
19 #include "Counters.h"
20 #include "GS.h"
21 #include "Elfheader.h"
22 #include "Patch.h"
23 #include "PageFaultSource.h"
24 #include "SysThreads.h"
25
26 #include "Utilities/TlsVariable.inl"
27
28 #ifdef __WXMSW__
29 # include <wx/msw/wrapwin.h>
30 #endif
31
32 #include <xmmintrin.h>
33
34 // --------------------------------------------------------------------------------------
35 // SysCoreThread *External Thread* Implementations
36 // (Called from outside the context of this thread)
37 // --------------------------------------------------------------------------------------
38
39 SysCoreThread::SysCoreThread()
40 {
41 m_name = L"EE Core";
42 m_resetRecompilers = true;
43 m_resetProfilers = true;
44 m_resetVsyncTimers = true;
45 m_resetVirtualMachine = true;
46
47 m_hasActiveMachine = false;
48 }
49
50 SysCoreThread::~SysCoreThread() throw()
51 {
52 SysCoreThread::Cancel();
53 }
54
55 void SysCoreThread::Cancel( bool isBlocking )
56 {
57 m_hasActiveMachine = false;
58 _parent::Cancel();
59 }
60
61 bool SysCoreThread::Cancel( const wxTimeSpan& span )
62 {
63 m_hasActiveMachine = false;
64 if( _parent::Cancel( span ) )
65 return true;
66
67 return false;
68 }
69
70 void SysCoreThread::OnStart()
71 {
72 _parent::OnStart();
73 }
74
75 void SysCoreThread::Start()
76 {
77 if( !GetCorePlugins().AreLoaded() ) return;
78 GetCorePlugins().Init();
79 _parent::Start();
80 }
81
82 // Resumes the core execution state, or does nothing is the core is already running. If
83 // settings were changed, resets will be performed as needed and emulation state resumed from
84 // memory savestates.
85 //
86 // Exceptions (can occur on first call only):
87 // PluginInitError - thrown if a plugin fails init (init is performed on the current thread
88 // on the first time the thread is resumed from it's initial idle state)
89 // ThreadCreationError - Insufficient system resources to create thread.
90 //
91 void SysCoreThread::OnResumeReady()
92 {
93 if( m_resetVirtualMachine )
94 m_hasActiveMachine = false;
95
96 if( !m_hasActiveMachine )
97 m_resetRecompilers = true;
98 }
99
100 // This function *will* reset the emulator in order to allow the specified elf file to
101 // take effect. This is because it really doesn't make sense to change the elf file outside
102 // the context of a reset/restart.
103 void SysCoreThread::SetElfOverride( const wxString& elf )
104 {
105 //pxAssertDev( !m_hasValidMachine, "Thread synchronization error while assigning ELF override." );
106 m_elf_override = elf;
107 }
108
109 void SysCoreThread::Reset()
110 {
111 Suspend();
112 m_resetVirtualMachine = true;
113 m_hasActiveMachine = false;
114 }
115
116 // Applies a full suite of new settings, which will automatically facilitate the necessary
117 // resets of the core and components (including plugins, if needed). The scope of resetting
118 // is determined by comparing the current settings against the new settings, so that only
119 // real differences are applied.
120 void SysCoreThread::ApplySettings( const Pcsx2Config& src )
121 {
122 if( src == EmuConfig ) return;
123
124 if( !pxAssertDev( IsPaused(), "CoreThread is not paused; settings cannot be applied." ) ) return;
125
126 m_resetRecompilers = ( src.Cpu != EmuConfig.Cpu ) || ( src.Recompiler != EmuConfig.Recompiler ) ||
127 ( src.Gamefixes != EmuConfig.Gamefixes ) || ( src.Speedhacks != EmuConfig.Speedhacks );
128 m_resetProfilers = ( src.Profiler != EmuConfig.Profiler );
129 m_resetVsyncTimers = ( src.GS != EmuConfig.GS );
130
131 const_cast<Pcsx2Config&>(EmuConfig) = src;
132 }
133
134 void SysCoreThread::UploadStateCopy( const VmStateBuffer& copy )
135 {
136 if( !pxAssertDev( IsPaused(), "CoreThread is not paused; new VM state cannot be uploaded." ) ) return;
137
138 SysClearExecutionCache();
139 memLoadingState( copy ).FreezeAll();
140 m_resetVirtualMachine = false;
141 }
142
143 // --------------------------------------------------------------------------------------
144 // SysCoreThread *Worker* Implementations
145 // (Called from the context of this thread only)
146 // --------------------------------------------------------------------------------------
147 bool SysCoreThread::HasPendingStateChangeRequest() const
148 {
149 return !m_hasActiveMachine || GetMTGS().HasPendingException() || _parent::HasPendingStateChangeRequest();
150 }
151
152 void SysCoreThread::_reset_stuff_as_needed()
153 {
154 if( m_resetVirtualMachine || m_resetRecompilers || m_resetProfilers )
155 {
156 SysClearExecutionCache();
157 memBindConditionalHandlers();
158 m_resetRecompilers = false;
159 m_resetProfilers = false;
160 }
161
162 if( m_resetVirtualMachine )
163 {
164 DoCpuReset();
165 m_resetVirtualMachine = false;
166 m_resetRecompilers = true;
167 }
168
169 if( m_resetVsyncTimers )
170 {
171 UpdateVSyncRate();
172 frameLimitReset();
173 m_resetVsyncTimers = false;
174 }
175
176 SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR );
177 }
178
179 void SysCoreThread::DoCpuReset()
180 {
181 AffinityAssert_AllowFromSelf( pxDiagSpot );
182 cpuReset();
183 }
184
185 void SysCoreThread::PostVsyncToUI()
186 {
187 }
188
189 // This is called from the PS2 VM at the start of every vsync (either 59.94 or 50 hz by PS2
190 // clock scale, which does not correlate to the actual host machine vsync).
191 //
192 // Default tasks: Updates PADs and applies vsync patches. Derived classes can override this
193 // to change either PAD and/or Patching behaviors.
194 //
195 // [TODO]: Should probably also handle profiling and debugging updates, once those are
196 // re-implemented.
197 //
198 void SysCoreThread::VsyncInThread()
199 {
200 PostVsyncToUI();
201 if (EmuConfig.EnablePatches) ApplyPatch();
202 if (EmuConfig.EnableCheats) ApplyCheat();
203 }
204
205 void SysCoreThread::StateCheckInThread()
206 {
207 GetMTGS().RethrowException();
208 _parent::StateCheckInThread();
209
210 _reset_stuff_as_needed(); // kinda redundant but could catch unexpected threaded state changes...
211 }
212
213 // Runs CPU cycles indefinitely, until the user or another thread requests execution to break.
214 // Rationale: This very short function allows an override point and solves an SEH
215 // "exception-type boundary" problem (can't mix SEH and C++ exceptions in the same function).
216 void SysCoreThread::DoCpuExecute()
217 {
218 m_hasActiveMachine = true;
219 Cpu->Execute();
220 }
221
222 void SysCoreThread::ExecuteTaskInThread()
223 {
224 Threading::EnableHiresScheduler();
225 m_sem_event.WaitWithoutYield();
226
227 m_mxcsr_saved.bitmask = _mm_getcsr();
228
229 PCSX2_PAGEFAULT_PROTECT {
230 while(true) {
231 StateCheckInThread();
232 DoCpuExecute();
233 }
234 } PCSX2_PAGEFAULT_EXCEPT;
235 }
236
237 void SysCoreThread::OnSuspendInThread()
238 {
239 GetCorePlugins().Close();
240 }
241
242 void SysCoreThread::OnResumeInThread( bool isSuspended )
243 {
244 GetCorePlugins().Open();
245 }
246
247
248 // Invoked by the pthread_exit or pthread_cancel.
249 void SysCoreThread::OnCleanupInThread()
250 {
251 m_hasActiveMachine = false;
252
253 GetCorePlugins().Close();
254 GetCorePlugins().Shutdown();
255
256 _mm_setcsr( m_mxcsr_saved.bitmask );
257 Threading::DisableHiresScheduler();
258 _parent::OnCleanupInThread();
259 }
260

  ViewVC Help
Powered by ViewVC 1.1.22