|
|
|
@ -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
|
|
|
|
|