summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-11-19 02:45:39 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2025-11-19 02:59:01 -0600
commit9f0a5c2a371e178711956aec97aa4df447b66d7d (patch)
tree4245d87eea86dbb2d42ecdad0cec8609960ba87a /Source/Core
parent19f1d329c9216b4fbf055d9cfbec7426fee90f24 (diff)
Core: Allow CPUManager::SetStepping to be called from the CPU thread so a call doesn't need to be routed through the host thread on boot.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Core.cpp19
-rw-r--r--Source/Core/Core/Core.h3
-rw-r--r--Source/Core/Core/HW/CPU.cpp8
-rw-r--r--Source/Core/Core/HW/CPU.h2
4 files changed, 15 insertions, 17 deletions
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index a920d513d7..04ce3c75b8 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -314,15 +314,12 @@ void UndeclareAsGPUThread()
}
// For the CPU Thread only.
-static void CPUSetInitialExecutionState(bool force_paused = false)
+static void CPUSetInitialExecutionState(Core::System& system, bool force_paused = false)
{
// The CPU starts in stepping state, and will wait until a new state is set before executing.
- // SetState isn't safe to call from the CPU thread, so we ask the host thread to call it.
- QueueHostJob([force_paused](Core::System& system) {
- bool paused = SConfig::GetInstance().bBootToPause || force_paused;
- SetState(system, paused ? State::Paused : State::Running, true, true);
- Host_UpdateDisasmDialog();
- });
+ const bool paused = SConfig::GetInstance().bBootToPause || force_paused;
+ SetState(system, paused ? State::Paused : State::Running, true, true);
+ Host_UpdateDisasmDialog();
}
// Create the CPU thread, which is a CPU + Video thread in Single Core mode.
@@ -371,7 +368,7 @@ static void CpuThread(Core::System& system, const std::optional<std::string>& sa
if (!gdb_socket.empty() && !AchievementManager::GetInstance().IsHardcoreModeActive())
{
GDBStub::InitLocal(gdb_socket.data());
- CPUSetInitialExecutionState(true);
+ CPUSetInitialExecutionState(system, true);
}
else
#endif
@@ -380,11 +377,11 @@ static void CpuThread(Core::System& system, const std::optional<std::string>& sa
if (gdb_port > 0 && !AchievementManager::GetInstance().IsHardcoreModeActive())
{
GDBStub::Init(gdb_port);
- CPUSetInitialExecutionState(true);
+ CPUSetInitialExecutionState(system, true);
}
else
{
- CPUSetInitialExecutionState();
+ CPUSetInitialExecutionState(system);
}
}
}
@@ -430,7 +427,7 @@ static void FifoPlayerThread(Core::System& system, const std::optional<std::stri
s_state.compare_exchange_strong(expected, State::Running);
}
- CPUSetInitialExecutionState();
+ CPUSetInitialExecutionState(system);
system.GetCPU().Run();
diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h
index 815d049656..a50fa54937 100644
--- a/Source/Core/Core/Core.h
+++ b/Source/Core/Core/Core.h
@@ -143,8 +143,7 @@ bool IsGPUThread();
bool WantsDeterminism();
-// SetState can't be called by the CPU thread, but can be called by any thread that isn't launched
-// by the emulator core.
+// SetState can be called from any thread.
void SetState(Core::System& system, State state, bool report_state_change = true,
bool override_achievement_restrictions = false);
State GetState(Core::System& system);
diff --git a/Source/Core/Core/HW/CPU.cpp b/Source/Core/Core/HW/CPU.cpp
index d55f565c0c..558b2098ab 100644
--- a/Source/Core/Core/HW/CPU.cpp
+++ b/Source/Core/Core/HW/CPU.cpp
@@ -308,16 +308,18 @@ void CPUManager::SetStepping(bool stepping)
{
SetStateLocked(State::Stepping);
- while (m_state_cpu_thread_active)
+ if (!Core::IsCPUThread())
{
- m_state_cpu_idle_cvar.wait(state_lock);
+ while (m_state_cpu_thread_active)
+ m_state_cpu_idle_cvar.wait(state_lock);
}
RunAdjacentSystems(false);
}
else if (SetStateLocked(State::Running))
{
- m_state_cpu_cvar.notify_one();
+ if (!Core::IsCPUThread())
+ m_state_cpu_cvar.notify_one();
m_time_played_finish_sync.Set();
RunAdjacentSystems(true);
}
diff --git a/Source/Core/Core/HW/CPU.h b/Source/Core/Core/HW/CPU.h
index 887d899710..1cd5905d40 100644
--- a/Source/Core/Core/HW/CPU.h
+++ b/Source/Core/Core/HW/CPU.h
@@ -63,7 +63,7 @@ public:
// StepOpcode (Steps one Opcode)
void StepOpcode(Common::Event* event = nullptr);
- // Enable or Disable Stepping. [Will deadlock if called from a system thread]
+ // Enable or Disable Stepping.
void SetStepping(bool stepping);
// Breakpoint activation for system threads. Similar to SetStepping(true).