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

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

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 MIME type: text/plain
File size: 8523 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     #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