diff options
Diffstat (limited to 'src')
| -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 @@ | |||
| 30 | #include "core/hle/kernel/k_system_control.h" | 30 | #include "core/hle/kernel/k_system_control.h" |
| 31 | #include "core/hle/kernel/k_thread.h" | 31 | #include "core/hle/kernel/k_thread.h" |
| 32 | #include "core/hle/kernel/k_thread_queue.h" | 32 | #include "core/hle/kernel/k_thread_queue.h" |
| 33 | #include "core/hle/kernel/k_worker_task_manager.h" | ||
| 33 | #include "core/hle/kernel/kernel.h" | 34 | #include "core/hle/kernel/kernel.h" |
| 34 | #include "core/hle/kernel/svc_results.h" | 35 | #include "core/hle/kernel/svc_results.h" |
| 35 | #include "core/hle/kernel/time_manager.h" | 36 | #include "core/hle/kernel/time_manager.h" |
| @@ -332,7 +333,7 @@ void KThread::Finalize() { | |||
| 332 | } | 333 | } |
| 333 | 334 | ||
| 334 | // Perform inherited finalization. | 335 | // Perform inherited finalization. |
| 335 | KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>::Finalize(); | 336 | KSynchronizationObject::Finalize(); |
| 336 | } | 337 | } |
| 337 | 338 | ||
| 338 | bool KThread::IsSignaled() const { | 339 | bool KThread::IsSignaled() const { |
| @@ -376,11 +377,28 @@ void KThread::StartTermination() { | |||
| 376 | 377 | ||
| 377 | // Register terminated dpc flag. | 378 | // Register terminated dpc flag. |
| 378 | RegisterDpc(DpcFlag::Terminated); | 379 | RegisterDpc(DpcFlag::Terminated); |
| 380 | } | ||
| 381 | |||
| 382 | void KThread::FinishTermination() { | ||
| 383 | // Ensure that the thread is not executing on any core. | ||
| 384 | if (parent != nullptr) { | ||
| 385 | for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { | ||
| 386 | KThread* core_thread{}; | ||
| 387 | do { | ||
| 388 | core_thread = kernel.Scheduler(i).GetCurrentThread(); | ||
| 389 | } while (core_thread == this); | ||
| 390 | } | ||
| 391 | } | ||
| 379 | 392 | ||
| 380 | // Close the thread. | 393 | // Close the thread. |
| 381 | this->Close(); | 394 | this->Close(); |
| 382 | } | 395 | } |
| 383 | 396 | ||
| 397 | void KThread::DoWorkerTaskImpl() { | ||
| 398 | // Finish the termination that was begun by Exit(). | ||
| 399 | this->FinishTermination(); | ||
| 400 | } | ||
| 401 | |||
| 384 | void KThread::Pin(s32 current_core) { | 402 | void KThread::Pin(s32 current_core) { |
| 385 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); | 403 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); |
| 386 | 404 | ||
| @@ -1027,6 +1045,9 @@ void KThread::Exit() { | |||
| 1027 | 1045 | ||
| 1028 | // Start termination. | 1046 | // Start termination. |
| 1029 | StartTermination(); | 1047 | StartTermination(); |
| 1048 | |||
| 1049 | // Register the thread as a work task. | ||
| 1050 | KWorkerTaskManager::AddTask(kernel, KWorkerTaskManager::WorkerType::Exit, this); | ||
| 1030 | } | 1051 | } |
| 1031 | } | 1052 | } |
| 1032 | 1053 | ||
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 @@ | |||
| 19 | #include "core/hle/kernel/k_light_lock.h" | 19 | #include "core/hle/kernel/k_light_lock.h" |
| 20 | #include "core/hle/kernel/k_spin_lock.h" | 20 | #include "core/hle/kernel/k_spin_lock.h" |
| 21 | #include "core/hle/kernel/k_synchronization_object.h" | 21 | #include "core/hle/kernel/k_synchronization_object.h" |
| 22 | #include "core/hle/kernel/k_worker_task.h" | ||
| 22 | #include "core/hle/kernel/slab_helpers.h" | 23 | #include "core/hle/kernel/slab_helpers.h" |
| 23 | #include "core/hle/kernel/svc_common.h" | 24 | #include "core/hle/kernel/svc_common.h" |
| 24 | #include "core/hle/kernel/svc_types.h" | 25 | #include "core/hle/kernel/svc_types.h" |
| @@ -100,7 +101,7 @@ enum class ThreadWaitReasonForDebugging : u32 { | |||
| 100 | [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); | 101 | [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); |
| 101 | [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); | 102 | [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); |
| 102 | 103 | ||
| 103 | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>, | 104 | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, |
| 104 | public boost::intrusive::list_base_hook<> { | 105 | public boost::intrusive::list_base_hook<> { |
| 105 | KERNEL_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject); | 106 | KERNEL_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject); |
| 106 | 107 | ||
| @@ -385,6 +386,8 @@ public: | |||
| 385 | 386 | ||
| 386 | void OnTimer(); | 387 | void OnTimer(); |
| 387 | 388 | ||
| 389 | void DoWorkerTaskImpl(); | ||
| 390 | |||
| 388 | static void PostDestroy(uintptr_t arg); | 391 | static void PostDestroy(uintptr_t arg); |
| 389 | 392 | ||
| 390 | [[nodiscard]] static ResultCode InitializeDummyThread(KThread* thread); | 393 | [[nodiscard]] static ResultCode InitializeDummyThread(KThread* thread); |
| @@ -679,6 +682,8 @@ private: | |||
| 679 | 682 | ||
| 680 | void StartTermination(); | 683 | void StartTermination(); |
| 681 | 684 | ||
| 685 | void FinishTermination(); | ||
| 686 | |||
| 682 | [[nodiscard]] ResultCode Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, | 687 | [[nodiscard]] ResultCode Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, |
| 683 | s32 prio, s32 virt_core, KProcess* owner, ThreadType type); | 688 | s32 prio, s32 virt_core, KProcess* owner, ThreadType type); |
| 684 | 689 | ||