From da07e13e0798a4ebd423595830f04e2234a03942 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Thu, 7 Jul 2022 12:34:46 -0400
Subject: kernel: fix single-core preemption points

---
 src/core/cpu_manager.cpp | 42 ++++++++++++++----------------------------
 1 file changed, 14 insertions(+), 28 deletions(-)

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

diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 838d6be21c..9b1565ae1d 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -144,39 +144,25 @@ void CpuManager::SingleCoreRunIdleThread() {
 }
 
 void CpuManager::PreemptSingleCore(bool from_running_environment) {
-    {
-        auto& kernel = system.Kernel();
-        auto& scheduler = kernel.Scheduler(current_core);
-
-        Kernel::KThread* current_thread = scheduler.GetSchedulerCurrentThread();
-        if (idle_count >= 4 || from_running_environment) {
-            if (!from_running_environment) {
-                system.CoreTiming().Idle();
-                idle_count = 0;
-            }
-            kernel.SetIsPhantomModeForSingleCore(true);
-            system.CoreTiming().Advance();
-            kernel.SetIsPhantomModeForSingleCore(false);
-        }
-        current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES);
-        system.CoreTiming().ResetTicks();
-        scheduler.Unload(scheduler.GetSchedulerCurrentThread());
-
-        auto& next_scheduler = kernel.Scheduler(current_core);
+    auto& kernel = system.Kernel();
 
-        // Disable dispatch. We're about to preempt this thread.
-        Kernel::KScopedDisableDispatch dd{kernel};
-        Common::Fiber::YieldTo(current_thread->GetHostContext(), *next_scheduler.GetSwitchFiber());
+    if (idle_count >= 4 || from_running_environment) {
+        if (!from_running_environment) {
+            system.CoreTiming().Idle();
+            idle_count = 0;
+        }
+        kernel.SetIsPhantomModeForSingleCore(true);
+        system.CoreTiming().Advance();
+        kernel.SetIsPhantomModeForSingleCore(false);
     }
+    current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES);
+    system.CoreTiming().ResetTicks();
+    kernel.Scheduler(current_core).PreemptSingleCore();
 
     // We've now been scheduled again, and we may have exchanged schedulers.
     // Reload the scheduler in case it's different.
-    {
-        auto& scheduler = system.Kernel().Scheduler(current_core);
-        scheduler.Reload(scheduler.GetSchedulerCurrentThread());
-        if (!scheduler.IsIdle()) {
-            idle_count = 0;
-        }
+    if (!kernel.Scheduler(current_core).IsIdle()) {
+        idle_count = 0;
     }
 }
 
-- 
cgit v1.2.3-70-g09d2