Kaynağa Gözat

core: hle: kernel: Ensure idle threads are closed before destroying scheduler.

bunnei 5 yıl önce
ebeveyn
işleme
2b9560428b

+ 5 - 1
src/core/hle/kernel/k_scheduler.cpp

@@ -617,13 +617,17 @@ KScheduler::KScheduler(Core::System& system_, s32 core_id_) : system{system_}, c
     state.highest_priority_thread = nullptr;
     state.highest_priority_thread = nullptr;
 }
 }
 
 
-KScheduler::~KScheduler() {
+void KScheduler::Finalize() {
     if (idle_thread) {
     if (idle_thread) {
         idle_thread->Close();
         idle_thread->Close();
         idle_thread = nullptr;
         idle_thread = nullptr;
     }
     }
 }
 }
 
 
+KScheduler::~KScheduler() {
+    ASSERT(!idle_thread);
+}
+
 KThread* KScheduler::GetCurrentThread() const {
 KThread* KScheduler::GetCurrentThread() const {
     if (auto result = current_thread.load(); result) {
     if (auto result = current_thread.load(); result) {
         return result;
         return result;

+ 2 - 0
src/core/hle/kernel/k_scheduler.h

@@ -33,6 +33,8 @@ public:
     explicit KScheduler(Core::System& system_, s32 core_id_);
     explicit KScheduler(Core::System& system_, s32 core_id_);
     ~KScheduler();
     ~KScheduler();
 
 
+    void Finalize();
+
     /// Reschedules to the next available thread (call after current thread is suspended)
     /// Reschedules to the next available thread (call after current thread is suspended)
     void RescheduleCurrentCore();
     void RescheduleCurrentCore();
 
 

+ 15 - 23
src/core/hle/kernel/kernel.cpp

@@ -85,8 +85,9 @@ struct KernelCore::Impl {
     }
     }
 
 
     void InitializeCores() {
     void InitializeCores() {
-        for (auto& core : cores) {
-            core.Initialize(current_process->Is64BitProcess());
+        for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
+            cores[core_id].Initialize(current_process->Is64BitProcess());
+            system.Memory().SetCurrentPageTable(*current_process, core_id);
         }
         }
     }
     }
 
 
@@ -131,15 +132,6 @@ struct KernelCore::Impl {
         next_user_process_id = KProcess::ProcessIDMin;
         next_user_process_id = KProcess::ProcessIDMin;
         next_thread_id = 1;
         next_thread_id = 1;
 
 
-        for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
-            if (suspend_threads[core_id]) {
-                suspend_threads[core_id]->Close();
-                suspend_threads[core_id] = nullptr;
-            }
-
-            schedulers[core_id].reset();
-        }
-
         cores.clear();
         cores.clear();
 
 
         global_handle_table->Finalize();
         global_handle_table->Finalize();
@@ -167,6 +159,16 @@ struct KernelCore::Impl {
         CleanupObject(time_shared_mem);
         CleanupObject(time_shared_mem);
         CleanupObject(system_resource_limit);
         CleanupObject(system_resource_limit);
 
 
+        for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
+            if (suspend_threads[core_id]) {
+                suspend_threads[core_id]->Close();
+                suspend_threads[core_id] = nullptr;
+            }
+
+            schedulers[core_id]->Finalize();
+            schedulers[core_id].reset();
+        }
+
         // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
         // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
         next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
         next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
 
 
@@ -257,14 +259,6 @@ struct KernelCore::Impl {
 
 
     void MakeCurrentProcess(KProcess* process) {
     void MakeCurrentProcess(KProcess* process) {
         current_process = process;
         current_process = process;
-        if (process == nullptr) {
-            return;
-        }
-
-        const u32 core_id = GetCurrentHostThreadID();
-        if (core_id < Core::Hardware::NUM_CPU_CORES) {
-            system.Memory().SetCurrentPageTable(*process, core_id);
-        }
     }
     }
 
 
     /// Creates a new host thread ID, should only be called by GetHostThreadId
     /// Creates a new host thread ID, should only be called by GetHostThreadId
@@ -1048,13 +1042,11 @@ void KernelCore::ExceptionalExit() {
 }
 }
 
 
 void KernelCore::EnterSVCProfile() {
 void KernelCore::EnterSVCProfile() {
-    std::size_t core = impl->GetCurrentHostThreadID();
-    impl->svc_ticks[core] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
+    impl->svc_ticks[CurrentPhysicalCoreIndex()] = MicroProfileEnter(MICROPROFILE_TOKEN(Kernel_SVC));
 }
 }
 
 
 void KernelCore::ExitSVCProfile() {
 void KernelCore::ExitSVCProfile() {
-    std::size_t core = impl->GetCurrentHostThreadID();
-    MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]);
+    MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);
 }
 }
 
 
 std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {
 std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {