mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-29 00:59:44 -06:00
Core: Threadsafety Synchronization Fixes (Frame Advance / FifoPlayer)
Fix Frame Advance and FifoPlayer pause/unpause/stop. CPU::EnableStepping is not atomic but is called from multiple threads which races and leaves the system in a random state; also instruction stepping was unstable, m_StepEvent had an almost random value because of the dual purpose it served which could cause races where CPU::Run would SingleStep when it was supposed to be sleeping. FifoPlayer never FinishStateMove()d which was causing it to deadlock. Rather than partially reimplementing CPU::Run, just use CPUCoreBase and then call CPU::Run(). More DRY and less likely to have weird bugs specific to the player (i.e the previous freezing on pause/stop). Refactor PowerPC::state into CPU since it manages the state of the CPU Thread which is controlled by CPU, not PowerPC. This simplifies the architecture somewhat and eliminates races that can be caused by calling PowerPC state functions directly instead of using CPU's (because they bypassed the EnableStepping lock).
This commit is contained in:
@ -52,7 +52,8 @@ bool IsRunningInCurrentThread(); // this tells us whether we are running in the
|
||||
bool IsCPUThread(); // this tells us whether we are the CPU thread.
|
||||
bool IsGPUThread();
|
||||
|
||||
void SetState(EState _State);
|
||||
// [NOT THREADSAFE] For use by Host only
|
||||
void SetState(EState state);
|
||||
EState GetState();
|
||||
|
||||
void SaveScreenShot();
|
||||
@ -80,13 +81,14 @@ void UpdateTitle();
|
||||
// or, if doLock is false, releases a lock on that state and optionally unpauses.
|
||||
// calls must be balanced (once with doLock true, then once with doLock false) but may be recursive.
|
||||
// the return value of the first call should be passed in as the second argument of the second call.
|
||||
bool PauseAndLock(bool doLock, bool unpauseOnUnlock=true);
|
||||
// [NOT THREADSAFE] Host only
|
||||
bool PauseAndLock(bool doLock, bool unpauseOnUnlock = true);
|
||||
|
||||
// for calling back into UI code without introducing a dependency on it in core
|
||||
typedef void(*StoppedCallbackFunc)(void);
|
||||
void SetOnStoppedCallback(StoppedCallbackFunc callback);
|
||||
|
||||
// Run on the GUI thread when the factors change.
|
||||
// Run on the Host thread when the factors change. [NOT THREADSAFE]
|
||||
void UpdateWantDeterminism(bool initial = false);
|
||||
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user