From 47c6c78c031b33af877a64aa1da2705558ab02c2 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow <fsahmkow27@gmail.com>
Date: Fri, 29 Mar 2019 17:09:10 -0400
Subject: [PATCH] Redesign CPU Cores to work with the new scheduler

---
 src/core/core_cpu.cpp | 23 ++++++++++-------------
 src/core/core_cpu.h   |  2 ++
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp
index 6bd9639c6e..2a7c3af240 100644
--- a/src/core/core_cpu.cpp
+++ b/src/core/core_cpu.cpp
@@ -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
diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h
index 7589beb8c8..5dde2994ce 100644
--- a/src/core/core_cpu.h
+++ b/src/core/core_cpu.h
@@ -13,6 +13,7 @@
 
 namespace Kernel {
 class Scheduler;
+class GlobalScheduler;
 }
 
 namespace Core {
@@ -90,6 +91,7 @@ private:
 
     std::unique_ptr<ARM_Interface> arm_interface;
     CpuBarrier& cpu_barrier;
+    Kernel::GlobalScheduler& global_scheduler;
     std::unique_ptr<Kernel::Scheduler> scheduler;
     Timing::CoreTiming& core_timing;