summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_thread.cpp23
-rw-r--r--src/core/hle/kernel/k_thread.h7
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
338bool KThread::IsSignaled() const { 339bool 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
382void 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
397void KThread::DoWorkerTaskImpl() {
398 // Finish the termination that was begun by Exit().
399 this->FinishTermination();
400}
401
384void KThread::Pin(s32 current_core) { 402void 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
103class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>, 104class 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