yuzu-emu
/
yuzu
Archived
1
0
Fork 0

Redesign CPU Cores to work with the new scheduler

This commit is contained in:
Fernando Sahmkow 2019-03-29 17:09:10 -04:00 committed by FernandoS27
parent 57a71f899a
commit 47c6c78c03
2 changed files with 12 additions and 13 deletions

View File

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

View File

@ -13,6 +13,7 @@
namespace Kernel { namespace Kernel {
class Scheduler; class Scheduler;
class GlobalScheduler;
} }
namespace Core { namespace Core {
@ -90,6 +91,7 @@ private:
std::unique_ptr<ARM_Interface> arm_interface; std::unique_ptr<ARM_Interface> arm_interface;
CpuBarrier& cpu_barrier; CpuBarrier& cpu_barrier;
Kernel::GlobalScheduler& global_scheduler;
std::unique_ptr<Kernel::Scheduler> scheduler; std::unique_ptr<Kernel::Scheduler> scheduler;
Timing::CoreTiming& core_timing; Timing::CoreTiming& core_timing;