/[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 31 - (hide 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 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     #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