From 54aabb00b05f64f4dd2721e0340bdef457c9e06c Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 26 Oct 2020 16:09:15 -0700 Subject: core: cpu_manager: Add missing call to MicroProfileOnThreadExit(). - Fixes an occasional crash when trying to launch subsequent games. --- src/core/cpu_manager.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core/cpu_manager.cpp') diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 688b99eba..983210197 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -365,6 +365,8 @@ void CpuManager::RunThread(std::size_t core) { data.enter_barrier.reset(); data.exit_barrier.reset(); data.initialized = false; + + MicroProfileOnThreadExit(); } } // namespace Core -- cgit v1.2.3 From 3359e5ab70d5c1a5d29a6bdf1d57df6ab616f592 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 21 Nov 2020 02:22:03 -0800 Subject: core: cpu_manager: Fix shutdown crash when closing before emulation starts. --- src/core/cpu_manager.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'src/core/cpu_manager.cpp') diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 983210197..100e90d82 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -4,6 +4,7 @@ #include "common/fiber.h" #include "common/microprofile.h" +#include "common/scope_exit.h" #include "common/thread.h" #include "core/arm/exclusive_monitor.h" #include "core/core.h" @@ -343,6 +344,16 @@ void CpuManager::RunThread(std::size_t core) { data.initialized = true; const bool sc_sync = !is_async_gpu && !is_multicore; bool sc_sync_first_use = sc_sync; + + // Cleanup + SCOPE_EXIT({ + data.host_context->Exit(); + data.enter_barrier.reset(); + data.exit_barrier.reset(); + data.initialized = false; + MicroProfileOnThreadExit(); + }); + /// Running while (running_mode) { data.is_running = false; @@ -351,6 +362,12 @@ void CpuManager::RunThread(std::size_t core) { system.GPU().ObtainContext(); sc_sync_first_use = false; } + + // Abort if emulation was killed before the session really starts + if (!system.IsPoweredOn()) { + return; + } + auto& scheduler = system.Kernel().CurrentScheduler(); Kernel::Thread* current_thread = scheduler.GetCurrentThread(); data.is_running = true; @@ -360,13 +377,6 @@ void CpuManager::RunThread(std::size_t core) { data.exit_barrier->Wait(); data.is_paused = false; } - /// Time to cleanup - data.host_context->Exit(); - data.enter_barrier.reset(); - data.exit_barrier.reset(); - data.initialized = false; - - MicroProfileOnThreadExit(); } } // namespace Core -- cgit v1.2.3 From 5bc4eabe36b7ef4dcd5ad8db1e944705655be432 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 27 Nov 2020 10:50:48 -0500 Subject: core: Eliminate remaining usages of the global system instance Removes all remaining usages of the global system instance. After this, migration can begin to migrate to being constructed and managed entirely by the various frontends. --- src/core/cpu_manager.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core/cpu_manager.cpp') diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 100e90d82..eeeb6e8df 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -10,7 +10,6 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/cpu_manager.h" -#include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/scheduler.h" -- cgit v1.2.3 From 7b642c77811dc3887756f5abac5a9710564b098e Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 13 Nov 2020 11:11:12 -0800 Subject: hle: kernel: multicore: Replace n-JITs impl. with 4 JITs. --- src/core/cpu_manager.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/core/cpu_manager.cpp') diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index eeeb6e8df..0cff985e9 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -113,22 +113,23 @@ void CpuManager::MultiCoreRunGuestThread() { auto& sched = kernel.CurrentScheduler(); sched.OnThreadStart(); } + auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + auto& host_context = thread->GetHostContext(); + host_context->SetRewindPoint(GuestRewindFunction, this); MultiCoreRunGuestLoop(); } void CpuManager::MultiCoreRunGuestLoop() { auto& kernel = system.Kernel(); - auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); - auto& arm_interface = thread->ArmInterface(); system.EnterDynarmicProfile(); while (!physical_core->IsInterrupted()) { - arm_interface.Run(); + physical_core->Run(); physical_core = &kernel.CurrentPhysicalCore(); } system.ExitDynarmicProfile(); - arm_interface.ClearExclusiveState(); auto& scheduler = kernel.CurrentScheduler(); scheduler.TryDoContextSwitch(); } @@ -209,6 +210,9 @@ void CpuManager::SingleCoreRunGuestThread() { auto& sched = kernel.CurrentScheduler(); sched.OnThreadStart(); } + auto* thread = kernel.CurrentScheduler().GetCurrentThread(); + auto& host_context = thread->GetHostContext(); + host_context->SetRewindPoint(GuestRewindFunction, this); SingleCoreRunGuestLoop(); } @@ -217,17 +221,15 @@ void CpuManager::SingleCoreRunGuestLoop() { auto* thread = kernel.CurrentScheduler().GetCurrentThread(); while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); - auto& arm_interface = thread->ArmInterface(); system.EnterDynarmicProfile(); if (!physical_core->IsInterrupted()) { - arm_interface.Run(); + physical_core->Run(); physical_core = &kernel.CurrentPhysicalCore(); } system.ExitDynarmicProfile(); thread->SetPhantomMode(true); system.CoreTiming().Advance(); thread->SetPhantomMode(false); - arm_interface.ClearExclusiveState(); PreemptSingleCore(); auto& scheduler = kernel.Scheduler(current_core); scheduler.TryDoContextSwitch(); -- cgit v1.2.3 From 9e29e36a784496f7290c03b6a42e400a164a5b1e Mon Sep 17 00:00:00 2001 From: bunnei 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 0cff985e9..179154348 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 From d4ae0ae0e9077c41499bb6a1d4bed2e047312748 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Dec 2020 00:16:39 -0800 Subject: core: cpu_manager: Fix a typo in PreemptSingleCore, which broke many games. - We were reload'ing the old current scheduler, which may have changed. --- src/core/cpu_manager.cpp | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) (limited to 'src/core/cpu_manager.cpp') diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 179154348..373395047 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -254,29 +254,34 @@ void CpuManager::SingleCoreRunSuspendThread() { } void CpuManager::PreemptSingleCore(bool from_running_enviroment) { - std::size_t old_core = current_core; - auto& scheduler = system.Kernel().Scheduler(old_core); - Kernel::Thread* current_thread = scheduler.GetCurrentThread(); - if (idle_count >= 4 || from_running_enviroment) { - if (!from_running_enviroment) { - system.CoreTiming().Idle(); - idle_count = 0; + { + auto& scheduler = system.Kernel().Scheduler(current_core); + Kernel::Thread* current_thread = scheduler.GetCurrentThread(); + if (idle_count >= 4 || from_running_enviroment) { + if (!from_running_enviroment) { + system.CoreTiming().Idle(); + idle_count = 0; + } + current_thread->SetPhantomMode(true); + system.CoreTiming().Advance(); + current_thread->SetPhantomMode(false); } - current_thread->SetPhantomMode(true); - system.CoreTiming().Advance(); - current_thread->SetPhantomMode(false); + current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); + system.CoreTiming().ResetTicks(); + scheduler.Unload(scheduler.GetCurrentThread()); + + auto& next_scheduler = system.Kernel().Scheduler(current_core); + Common::Fiber::YieldTo(current_thread->GetHostContext(), next_scheduler.ControlContext()); } - current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); - system.CoreTiming().ResetTicks(); - 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(scheduler.GetCurrentThread()); - auto* currrent_thread2 = current_scheduler.GetCurrentThread(); - if (!currrent_thread2->IsIdleThread()) { - idle_count = 0; + + // May have changed scheduler + { + auto& scheduler = system.Kernel().Scheduler(current_core); + scheduler.Reload(scheduler.GetCurrentThread()); + auto* currrent_thread2 = scheduler.GetCurrentThread(); + if (!currrent_thread2->IsIdleThread()) { + idle_count = 0; + } } } -- cgit v1.2.3