From 25f8606a6dab595eb7a92fce9be32e0489079964 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 12 Oct 2019 08:21:51 -0400 Subject: Kernel Scheduler: Make sure the global scheduler shutdowns correctly. --- src/common/multi_level_queue.h | 7 +++++++ src/core/core_cpu.cpp | 4 ++++ src/core/core_cpu.h | 2 ++ src/core/cpu_core_manager.cpp | 1 + src/core/hle/kernel/kernel.cpp | 2 ++ src/core/hle/kernel/scheduler.cpp | 8 ++++++++ src/core/hle/kernel/scheduler.h | 7 +++++++ 7 files changed, 31 insertions(+) diff --git a/src/common/multi_level_queue.h b/src/common/multi_level_queue.h index 9cb448f56..50acfdbf2 100644 --- a/src/common/multi_level_queue.h +++ b/src/common/multi_level_queue.h @@ -304,6 +304,13 @@ public: return levels[priority == Depth ? 63 : priority].back(); } + void clear() { + used_priorities = 0; + for (std::size_t i = 0; i < Depth; i++) { + levels[i].clear(); + } + } + private: using const_list_iterator = typename std::list::const_iterator; diff --git a/src/core/core_cpu.cpp b/src/core/core_cpu.cpp index a6f63e437..233ea572c 100644 --- a/src/core/core_cpu.cpp +++ b/src/core/core_cpu.cpp @@ -117,4 +117,8 @@ void Cpu::Reschedule() { scheduler->TryDoContextSwitch(); } +void Cpu::Shutdown() { + scheduler->Shutdown(); +} + } // namespace Core diff --git a/src/core/core_cpu.h b/src/core/core_cpu.h index 80261daf7..cafca8df7 100644 --- a/src/core/core_cpu.h +++ b/src/core/core_cpu.h @@ -84,6 +84,8 @@ public: return core_index; } + void Shutdown(); + static std::unique_ptr MakeExclusiveMonitor(std::size_t num_cores); private: diff --git a/src/core/cpu_core_manager.cpp b/src/core/cpu_core_manager.cpp index 16b384076..8efd410bb 100644 --- a/src/core/cpu_core_manager.cpp +++ b/src/core/cpu_core_manager.cpp @@ -58,6 +58,7 @@ void CpuCoreManager::Shutdown() { thread_to_cpu.clear(); for (auto& cpu_core : cores) { + cpu_core->Shutdown(); cpu_core.reset(); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 002c5af2b..0d6286f84 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -116,6 +116,8 @@ struct KernelCore::Impl { thread_wakeup_event_type = nullptr; preemption_event = nullptr; + global_scheduler.Shutdown(); + named_ports.clear(); } diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 226d15d88..122106267 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -342,6 +342,14 @@ bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread, T } } +void GlobalScheduler::Shutdown() { + for (std::size_t core = 0; core < NUM_CPU_CORES; core++) { + scheduled_queue[core].clear(); + suggested_queue[core].clear(); + } + thread_list.clear(); +} + GlobalScheduler::~GlobalScheduler() = default; Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id) diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index 408e20c88..617553ae3 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -147,6 +147,8 @@ public: return reselection_pending.load(); } + void Shutdown(); + private: bool AskForReselectionOrMarkRedundant(Thread* current_thread, Thread* winner); @@ -189,6 +191,11 @@ public: return context_switch_pending; } + void Shutdown() { + current_thread = nullptr; + selected_thread = nullptr; + } + private: friend class GlobalScheduler; /** -- cgit v1.2.3