From 9e29e36a784496f7290c03b6a42e400a164a5b1e Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Wed, 2 Dec 2020 18:08:35 -0800
Subject: hle: kernel: Rewrite scheduler implementation based on Mesopshere.

---
 src/core/cpu_manager.cpp | 55 ++++++++++++++++++------------------------------
 1 file changed, 21 insertions(+), 34 deletions(-)

(limited to 'src/core/cpu_manager.cpp')

diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 0cff985e9a..1791543483 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -10,9 +10,9 @@
 #include "core/core.h"
 #include "core/core_timing.h"
 #include "core/cpu_manager.h"
+#include "core/hle/kernel/k_scheduler.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/physical_core.h"
-#include "core/hle/kernel/scheduler.h"
 #include "core/hle/kernel/thread.h"
 #include "video_core/gpu.h"
 
@@ -109,11 +109,8 @@ void* CpuManager::GetStartFuncParamater() {
 
 void CpuManager::MultiCoreRunGuestThread() {
     auto& kernel = system.Kernel();
-    {
-        auto& sched = kernel.CurrentScheduler();
-        sched.OnThreadStart();
-    }
-    auto* thread = kernel.CurrentScheduler().GetCurrentThread();
+    kernel.CurrentScheduler()->OnThreadStart();
+    auto* thread = kernel.CurrentScheduler()->GetCurrentThread();
     auto& host_context = thread->GetHostContext();
     host_context->SetRewindPoint(GuestRewindFunction, this);
     MultiCoreRunGuestLoop();
@@ -130,8 +127,8 @@ void CpuManager::MultiCoreRunGuestLoop() {
             physical_core = &kernel.CurrentPhysicalCore();
         }
         system.ExitDynarmicProfile();
-        auto& scheduler = kernel.CurrentScheduler();
-        scheduler.TryDoContextSwitch();
+        physical_core->ArmInterface().ClearExclusiveState();
+        kernel.CurrentScheduler()->RescheduleCurrentCore();
     }
 }
 
@@ -140,25 +137,21 @@ void CpuManager::MultiCoreRunIdleThread() {
     while (true) {
         auto& physical_core = kernel.CurrentPhysicalCore();
         physical_core.Idle();
-        auto& scheduler = kernel.CurrentScheduler();
-        scheduler.TryDoContextSwitch();
+        kernel.CurrentScheduler()->RescheduleCurrentCore();
     }
 }
 
 void CpuManager::MultiCoreRunSuspendThread() {
     auto& kernel = system.Kernel();
-    {
-        auto& sched = kernel.CurrentScheduler();
-        sched.OnThreadStart();
-    }
+    kernel.CurrentScheduler()->OnThreadStart();
     while (true) {
         auto core = kernel.GetCurrentHostThreadID();
-        auto& scheduler = kernel.CurrentScheduler();
+        auto& scheduler = *kernel.CurrentScheduler();
         Kernel::Thread* current_thread = scheduler.GetCurrentThread();
         Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[core].host_context);
         ASSERT(scheduler.ContextSwitchPending());
         ASSERT(core == kernel.GetCurrentHostThreadID());
-        scheduler.TryDoContextSwitch();
+        scheduler.RescheduleCurrentCore();
     }
 }
 
@@ -206,11 +199,8 @@ void CpuManager::MultiCorePause(bool paused) {
 
 void CpuManager::SingleCoreRunGuestThread() {
     auto& kernel = system.Kernel();
-    {
-        auto& sched = kernel.CurrentScheduler();
-        sched.OnThreadStart();
-    }
-    auto* thread = kernel.CurrentScheduler().GetCurrentThread();
+    kernel.CurrentScheduler()->OnThreadStart();
+    auto* thread = kernel.CurrentScheduler()->GetCurrentThread();
     auto& host_context = thread->GetHostContext();
     host_context->SetRewindPoint(GuestRewindFunction, this);
     SingleCoreRunGuestLoop();
@@ -218,7 +208,7 @@ void CpuManager::SingleCoreRunGuestThread() {
 
 void CpuManager::SingleCoreRunGuestLoop() {
     auto& kernel = system.Kernel();
-    auto* thread = kernel.CurrentScheduler().GetCurrentThread();
+    auto* thread = kernel.CurrentScheduler()->GetCurrentThread();
     while (true) {
         auto* physical_core = &kernel.CurrentPhysicalCore();
         system.EnterDynarmicProfile();
@@ -230,9 +220,10 @@ void CpuManager::SingleCoreRunGuestLoop() {
         thread->SetPhantomMode(true);
         system.CoreTiming().Advance();
         thread->SetPhantomMode(false);
+        physical_core->ArmInterface().ClearExclusiveState();
         PreemptSingleCore();
         auto& scheduler = kernel.Scheduler(current_core);
-        scheduler.TryDoContextSwitch();
+        scheduler.RescheduleCurrentCore();
     }
 }
 
@@ -244,24 +235,21 @@ void CpuManager::SingleCoreRunIdleThread() {
         system.CoreTiming().AddTicks(1000U);
         idle_count++;
         auto& scheduler = physical_core.Scheduler();
-        scheduler.TryDoContextSwitch();
+        scheduler.RescheduleCurrentCore();
     }
 }
 
 void CpuManager::SingleCoreRunSuspendThread() {
     auto& kernel = system.Kernel();
-    {
-        auto& sched = kernel.CurrentScheduler();
-        sched.OnThreadStart();
-    }
+    kernel.CurrentScheduler()->OnThreadStart();
     while (true) {
         auto core = kernel.GetCurrentHostThreadID();
-        auto& scheduler = kernel.CurrentScheduler();
+        auto& scheduler = *kernel.CurrentScheduler();
         Kernel::Thread* current_thread = scheduler.GetCurrentThread();
         Common::Fiber::YieldTo(current_thread->GetHostContext(), core_data[0].host_context);
         ASSERT(scheduler.ContextSwitchPending());
         ASSERT(core == kernel.GetCurrentHostThreadID());
-        scheduler.TryDoContextSwitch();
+        scheduler.RescheduleCurrentCore();
     }
 }
 
@@ -280,12 +268,12 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) {
     }
     current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES);
     system.CoreTiming().ResetTicks();
-    scheduler.Unload();
+    scheduler.Unload(scheduler.GetCurrentThread());
     auto& next_scheduler = system.Kernel().Scheduler(current_core);
     Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext());
     /// May have changed scheduler
     auto& current_scheduler = system.Kernel().Scheduler(current_core);
-    current_scheduler.Reload();
+    current_scheduler.Reload(scheduler.GetCurrentThread());
     auto* currrent_thread2 = current_scheduler.GetCurrentThread();
     if (!currrent_thread2->IsIdleThread()) {
         idle_count = 0;
@@ -369,8 +357,7 @@ void CpuManager::RunThread(std::size_t core) {
             return;
         }
 
-        auto& scheduler = system.Kernel().CurrentScheduler();
-        Kernel::Thread* current_thread = scheduler.GetCurrentThread();
+        auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread();
         data.is_running = true;
         Common::Fiber::YieldTo(data.host_context, current_thread->GetHostContext());
         data.is_running = false;
-- 
cgit v1.2.3-70-g09d2