summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
authorEmptyChaos <EmptyChaos@users.noreply.github.com>2016-05-12 09:17:17 +0000
committerEmptyChaos <EmptyChaos@users.noreply.github.com>2016-05-13 09:23:44 +1000
commitc1922783f8125dee4f12fdb20bdcbcf764e7ade4 (patch)
treed3c3e58e3e6cb82c2957ab26f692090132c7e765 /Source/Core/Common
parent0283ce2a7c6dd1c48e987de9bc486bd1f613a0c6 (diff)
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).
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/Event.h6
1 files changed, 2 insertions, 4 deletions
diff --git a/Source/Core/Common/Event.h b/Source/Core/Common/Event.h
index e05bafac1f..49cf543ead 100644
--- a/Source/Core/Common/Event.h
+++ b/Source/Core/Common/Event.h
@@ -42,8 +42,7 @@ public:
return;
std::unique_lock<std::mutex> lk(m_mutex);
- m_condvar.wait(lk, [&]{ return m_flag.IsSet(); });
- m_flag.Clear();
+ m_condvar.wait(lk, [&]{ return m_flag.TestAndClear(); });
}
template<class Rep, class Period>
@@ -54,8 +53,7 @@ public:
std::unique_lock<std::mutex> lk(m_mutex);
bool signaled = m_condvar.wait_for(lk, rel_time,
- [&]{ return m_flag.IsSet(); });
- m_flag.Clear();
+ [&]{ return m_flag.TestAndClear(); });
return signaled;
}