diff options
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 23 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 7 | 
2 files changed, 28 insertions, 2 deletions
| diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 3cb995ddb..7a5e6fc08 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -30,6 +30,7 @@  #include "core/hle/kernel/k_system_control.h"  #include "core/hle/kernel/k_thread.h"  #include "core/hle/kernel/k_thread_queue.h" +#include "core/hle/kernel/k_worker_task_manager.h"  #include "core/hle/kernel/kernel.h"  #include "core/hle/kernel/svc_results.h"  #include "core/hle/kernel/time_manager.h" @@ -332,7 +333,7 @@ void KThread::Finalize() {      }      // Perform inherited finalization. -    KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>::Finalize(); +    KSynchronizationObject::Finalize();  }  bool KThread::IsSignaled() const { @@ -376,11 +377,28 @@ void KThread::StartTermination() {      // Register terminated dpc flag.      RegisterDpc(DpcFlag::Terminated); +} + +void KThread::FinishTermination() { +    // Ensure that the thread is not executing on any core. +    if (parent != nullptr) { +        for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { +            KThread* core_thread{}; +            do { +                core_thread = kernel.Scheduler(i).GetCurrentThread(); +            } while (core_thread == this); +        } +    }      // Close the thread.      this->Close();  } +void KThread::DoWorkerTaskImpl() { +    // Finish the termination that was begun by Exit(). +    this->FinishTermination(); +} +  void KThread::Pin(s32 current_core) {      ASSERT(kernel.GlobalSchedulerContext().IsLocked()); @@ -1027,6 +1045,9 @@ void KThread::Exit() {          // Start termination.          StartTermination(); + +        // Register the thread as a work task. +        KWorkerTaskManager::AddTask(kernel, KWorkerTaskManager::WorkerType::Exit, this);      }  } diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 92c3493c5..cc427f6cf 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -19,6 +19,7 @@  #include "core/hle/kernel/k_light_lock.h"  #include "core/hle/kernel/k_spin_lock.h"  #include "core/hle/kernel/k_synchronization_object.h" +#include "core/hle/kernel/k_worker_task.h"  #include "core/hle/kernel/slab_helpers.h"  #include "core/hle/kernel/svc_common.h"  #include "core/hle/kernel/svc_types.h" @@ -100,7 +101,7 @@ enum class ThreadWaitReasonForDebugging : u32 {  [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel);  [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); -class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>, +class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>,                        public boost::intrusive::list_base_hook<> {      KERNEL_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject); @@ -385,6 +386,8 @@ public:      void OnTimer(); +    void DoWorkerTaskImpl(); +      static void PostDestroy(uintptr_t arg);      [[nodiscard]] static ResultCode InitializeDummyThread(KThread* thread); @@ -679,6 +682,8 @@ private:      void StartTermination(); +    void FinishTermination(); +      [[nodiscard]] ResultCode Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top,                                          s32 prio, s32 virt_core, KProcess* owner, ThreadType type); | 
