|
|
|
@ -52,7 +52,8 @@ bool CpuBarrier::Rendezvous() { |
|
|
|
|
|
|
|
Cpu::Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_barrier, |
|
|
|
std::size_t core_index) |
|
|
|
: cpu_barrier{cpu_barrier}, core_timing{system.CoreTiming()}, core_index{core_index} { |
|
|
|
: cpu_barrier{cpu_barrier}, global_scheduler{system.GlobalScheduler()}, |
|
|
|
core_timing{system.CoreTiming()}, core_index{core_index} { |
|
|
|
#ifdef ARCHITECTURE_x86_64
|
|
|
|
arm_interface = std::make_unique<ARM_Dynarmic>(system, exclusive_monitor, core_index); |
|
|
|
#else
|
|
|
|
@ -60,7 +61,7 @@ Cpu::Cpu(System& system, ExclusiveMonitor& exclusive_monitor, CpuBarrier& cpu_ba |
|
|
|
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available"); |
|
|
|
#endif
|
|
|
|
|
|
|
|
scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface); |
|
|
|
scheduler = std::make_unique<Kernel::Scheduler>(system, *arm_interface, core_index); |
|
|
|
} |
|
|
|
|
|
|
|
Cpu::~Cpu() = default; |
|
|
|
@ -81,21 +82,21 @@ void Cpu::RunLoop(bool tight_loop) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
Reschedule(); |
|
|
|
|
|
|
|
// If we don't have a currently active thread then don't execute instructions,
|
|
|
|
// instead advance to the next event and try to yield to the next thread
|
|
|
|
if (Kernel::GetCurrentThread() == nullptr) { |
|
|
|
LOG_TRACE(Core, "Core-{} idling", core_index); |
|
|
|
core_timing.Idle(); |
|
|
|
core_timing.Advance(); |
|
|
|
PrepareReschedule(); |
|
|
|
} else { |
|
|
|
if (tight_loop) { |
|
|
|
arm_interface->Run(); |
|
|
|
} else { |
|
|
|
arm_interface->Step(); |
|
|
|
} |
|
|
|
core_timing.Advance(); |
|
|
|
} |
|
|
|
core_timing.Advance(); |
|
|
|
|
|
|
|
Reschedule(); |
|
|
|
} |
|
|
|
@ -106,18 +107,14 @@ void Cpu::SingleStep() { |
|
|
|
|
|
|
|
void Cpu::PrepareReschedule() { |
|
|
|
arm_interface->PrepareReschedule(); |
|
|
|
reschedule_pending = true; |
|
|
|
} |
|
|
|
|
|
|
|
void Cpu::Reschedule() { |
|
|
|
if (!reschedule_pending) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
reschedule_pending = false; |
|
|
|
// Lock the global kernel mutex when we manipulate the HLE state
|
|
|
|
std::lock_guard lock{HLE::g_hle_lock}; |
|
|
|
scheduler->Reschedule(); |
|
|
|
std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); |
|
|
|
|
|
|
|
global_scheduler.SelectThread(core_index); |
|
|
|
scheduler->TryDoContextSwitch(); |
|
|
|
} |
|
|
|
|
|
|
|
} // namespace Core
|