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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22