summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_thread.cpp100
-rw-r--r--src/core/hle/kernel/k_thread.h100
2 files changed, 91 insertions, 109 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index e0f53287c..5d0b266c5 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -62,7 +62,7 @@ static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context,
62namespace Kernel { 62namespace Kernel {
63 63
64KThread::KThread(KernelCore& kernel) 64KThread::KThread(KernelCore& kernel)
65 : KSynchronizationObject{kernel}, activity_pause_lock{kernel} {} 65 : KAutoObjectWithSlabHeapAndContainer{kernel}, activity_pause_lock{kernel} {}
66KThread::~KThread() = default; 66KThread::~KThread() = default;
67 67
68ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, 68ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio,
@@ -177,6 +177,7 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s
177 // Set parent, if relevant. 177 // Set parent, if relevant.
178 if (owner != nullptr) { 178 if (owner != nullptr) {
179 parent = owner; 179 parent = owner;
180 parent->Open();
180 parent->IncrementThreadCount(); 181 parent->IncrementThreadCount();
181 } 182 }
182 183
@@ -210,13 +211,55 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s
210 211
211ResultCode KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, 212ResultCode KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
212 VAddr user_stack_top, s32 prio, s32 core, Process* owner, 213 VAddr user_stack_top, s32 prio, s32 core, Process* owner,
213 ThreadType type) { 214 ThreadType type, std::function<void(void*)>&& init_func,
215 void* init_func_parameter) {
214 // Initialize the thread. 216 // Initialize the thread.
215 R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type)); 217 R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type));
216 218
219 // Initialize host context.
220 thread->host_context =
221 std::make_shared<Common::Fiber>(std::move(init_func), init_func_parameter);
222
217 return RESULT_SUCCESS; 223 return RESULT_SUCCESS;
218} 224}
219 225
226ResultCode KThread::InitializeDummyThread(KThread* thread) {
227 return thread->Initialize({}, {}, {}, DefaultThreadPriority, 3, {}, ThreadType::Main);
228}
229
230ResultCode KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) {
231 return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main,
232 Core::CpuManager::GetIdleThreadStartFunc(),
233 system.GetCpuManager().GetStartFuncParamater());
234}
235
236ResultCode KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread,
237 KThreadFunction func, uintptr_t arg,
238 s32 virt_core) {
239 return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority,
240 Core::CpuManager::GetSuspendThreadStartFunc(),
241 system.GetCpuManager().GetStartFuncParamater());
242}
243
244ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread,
245 KThreadFunction func, uintptr_t arg, VAddr user_stack_top,
246 s32 prio, s32 virt_core, Process* owner) {
247 system.Kernel().GlobalSchedulerContext().AddThread(thread);
248 return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner,
249 ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(),
250 system.GetCpuManager().GetStartFuncParamater());
251}
252
253void KThread::PostDestroy(uintptr_t arg) {
254 Process* owner = reinterpret_cast<Process*>(arg & ~1ULL);
255 const bool resource_limit_release_hint = (arg & 1);
256 const s64 hint_value = (resource_limit_release_hint ? 0 : 1);
257 if (owner != nullptr) {
258 owner->GetResourceLimit()->Release(Kernel::LimitableResource::Threads, 1, hint_value);
259 owner->Close();
260 }
261}
262
220void KThread::Finalize() { 263void KThread::Finalize() {
221 // If the thread has an owner process, unregister it. 264 // If the thread has an owner process, unregister it.
222 if (parent != nullptr) { 265 if (parent != nullptr) {
@@ -294,6 +337,9 @@ void KThread::StartTermination() {
294 337
295 // Register terminated dpc flag. 338 // Register terminated dpc flag.
296 RegisterDpc(DpcFlag::Terminated); 339 RegisterDpc(DpcFlag::Terminated);
340
341 // Close the thread.
342 this->Close();
297} 343}
298 344
299void KThread::Pin() { 345void KThread::Pin() {
@@ -995,56 +1041,6 @@ std::shared_ptr<Common::Fiber>& KThread::GetHostContext() {
995 return host_context; 1041 return host_context;
996} 1042}
997 1043
998ResultVal<std::shared_ptr<KThread>> KThread::CreateThread(Core::System& system,
999 ThreadType type_flags, std::string name,
1000 VAddr entry_point, u32 priority, u64 arg,
1001 s32 processor_id, VAddr stack_top,
1002 Process* owner_process) {
1003 auto& kernel = system.Kernel();
1004
1005 std::shared_ptr<KThread> thread = std::make_shared<KThread>(kernel);
1006
1007 if (const auto result =
1008 thread->InitializeThread(thread.get(), entry_point, arg, stack_top, priority,
1009 processor_id, owner_process, type_flags);
1010 result.IsError()) {
1011 return result;
1012 }
1013
1014 thread->name = name;
1015
1016 auto& scheduler = kernel.GlobalSchedulerContext();
1017 scheduler.AddThread(thread);
1018
1019 return MakeResult<std::shared_ptr<KThread>>(std::move(thread));
1020}
1021
1022ResultVal<std::shared_ptr<KThread>> KThread::CreateThread(
1023 Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, u32 priority,
1024 u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process,
1025 std::function<void(void*)>&& thread_start_func, void* thread_start_parameter) {
1026 auto thread_result = CreateThread(system, type_flags, name, entry_point, priority, arg,
1027 processor_id, stack_top, owner_process);
1028
1029 if (thread_result.Succeeded()) {
1030 (*thread_result)->host_context =
1031 std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter);
1032 }
1033
1034 return thread_result;
1035}
1036
1037ResultVal<std::shared_ptr<KThread>> KThread::CreateUserThread(
1038 Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, u32 priority,
1039 u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process) {
1040 std::function<void(void*)> init_func = Core::CpuManager::GetGuestThreadStartFunc();
1041
1042 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
1043
1044 return CreateThread(system, type_flags, name, entry_point, priority, arg, processor_id,
1045 stack_top, owner_process, std::move(init_func), init_func_parameter);
1046}
1047
1048KThread* GetCurrentThreadPointer(KernelCore& kernel) { 1044KThread* GetCurrentThreadPointer(KernelCore& kernel) {
1049 return kernel.GetCurrentEmuThread(); 1045 return kernel.GetCurrentEmuThread();
1050} 1046}
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index b442dfe57..5c1c17d48 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -20,6 +20,7 @@
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/object.h" 22#include "core/hle/kernel/object.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"
25#include "core/hle/result.h" 26#include "core/hle/result.h"
@@ -99,7 +100,11 @@ enum class ThreadWaitReasonForDebugging : u32 {
99[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); 100[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel);
100[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); 101[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel);
101 102
102class KThread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> { 103class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>,
104 public boost::intrusive::list_base_hook<> {
105 KERNEL_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject);
106
107private:
103 friend class KScheduler; 108 friend class KScheduler;
104 friend class Process; 109 friend class Process;
105 110
@@ -115,57 +120,6 @@ public:
115 using ThreadContext64 = Core::ARM_Interface::ThreadContext64; 120 using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
116 using WaiterList = boost::intrusive::list<KThread>; 121 using WaiterList = boost::intrusive::list<KThread>;
117 122
118 /**
119 * Creates and returns a new thread.
120 * @param system The instance of the whole system
121 * @param name The friendly name desired for the thread
122 * @param entry_point The address at which the thread should start execution
123 * @param priority The thread's priority
124 * @param arg User data to pass to the thread
125 * @param processor_id The ID(s) of the processors on which the thread is desired to be run
126 * @param stack_top The address of the thread's stack top
127 * @param owner_process The parent process for the thread, if null, it's a kernel thread
128 * @return A shared pointer to the newly created thread
129 */
130 [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateThread(
131 Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point,
132 u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process);
133
134 /**
135 * Creates and returns a new thread, with a specified entry point.
136 * @param system The instance of the whole system
137 * @param name The friendly name desired for the thread
138 * @param entry_point The address at which the thread should start execution
139 * @param priority The thread's priority
140 * @param arg User data to pass to the thread
141 * @param processor_id The ID(s) of the processors on which the thread is desired to be run
142 * @param stack_top The address of the thread's stack top
143 * @param owner_process The parent process for the thread, if null, it's a kernel thread
144 * @param thread_start_func The function where the host context will start.
145 * @param thread_start_parameter The parameter which will passed to host context on init
146 * @return A shared pointer to the newly created thread
147 */
148 [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateThread(
149 Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point,
150 u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process,
151 std::function<void(void*)>&& thread_start_func, void* thread_start_parameter);
152
153 /**
154 * Creates and returns a new thread for the emulated "user" process.
155 * @param system The instance of the whole system
156 * @param name The friendly name desired for the thread
157 * @param entry_point The address at which the thread should start execution
158 * @param priority The thread's priority
159 * @param arg User data to pass to the thread
160 * @param processor_id The ID(s) of the processors on which the thread is desired to be run
161 * @param stack_top The address of the thread's stack top
162 * @param owner_process The parent process for the thread, if null, it's a kernel thread
163 * @return A shared pointer to the newly created thread
164 */
165 [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateUserThread(
166 Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point,
167 u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process);
168
169 [[nodiscard]] std::string GetName() const override { 123 [[nodiscard]] std::string GetName() const override {
170 return name; 124 return name;
171 } 125 }
@@ -257,10 +211,6 @@ public:
257 211
258 void Suspend(); 212 void Suspend();
259 213
260 void Finalize() override;
261
262 bool IsSignaled() const override;
263
264 void SetSyncedObject(KSynchronizationObject* obj, ResultCode wait_res) { 214 void SetSyncedObject(KSynchronizationObject* obj, ResultCode wait_res) {
265 synced_object = obj; 215 synced_object = obj;
266 wait_result = wait_res; 216 wait_result = wait_res;
@@ -422,6 +372,40 @@ public:
422 return termination_requested || GetRawState() == ThreadState::Terminated; 372 return termination_requested || GetRawState() == ThreadState::Terminated;
423 } 373 }
424 374
375 [[nodiscard]] virtual u64 GetId() const override final {
376 return this->GetThreadID();
377 }
378
379 [[nodiscard]] virtual bool IsInitialized() const override {
380 return initialized;
381 }
382
383 [[nodiscard]] virtual uintptr_t GetPostDestroyArgument() const override {
384 return reinterpret_cast<uintptr_t>(parent) | (resource_limit_release_hint ? 1 : 0);
385 }
386
387 virtual void Finalize() override;
388
389 [[nodiscard]] virtual bool IsSignaled() const override;
390
391 static void PostDestroy(uintptr_t arg);
392
393 [[nodiscard]] static ResultCode InitializeDummyThread(KThread* thread);
394
395 [[nodiscard]] static ResultCode InitializeIdleThread(Core::System& system, KThread* thread,
396 s32 virt_core);
397
398 [[nodiscard]] static ResultCode InitializeHighPriorityThread(Core::System& system,
399 KThread* thread,
400 KThreadFunction func,
401 uintptr_t arg, s32 virt_core);
402
403 [[nodiscard]] static ResultCode InitializeUserThread(Core::System& system, KThread* thread,
404 KThreadFunction func, uintptr_t arg,
405 VAddr user_stack_top, s32 prio,
406 s32 virt_core, Process* owner);
407
408public:
425 struct StackParameters { 409 struct StackParameters {
426 u8 svc_permission[0x10]; 410 u8 svc_permission[0x10];
427 std::atomic<u8> dpc_flags; 411 std::atomic<u8> dpc_flags;
@@ -675,7 +659,9 @@ private:
675 659
676 [[nodiscard]] static ResultCode InitializeThread(KThread* thread, KThreadFunction func, 660 [[nodiscard]] static ResultCode InitializeThread(KThread* thread, KThreadFunction func,
677 uintptr_t arg, VAddr user_stack_top, s32 prio, 661 uintptr_t arg, VAddr user_stack_top, s32 prio,
678 s32 core, Process* owner, ThreadType type); 662 s32 core, Process* owner, ThreadType type,
663 std::function<void(void*)>&& init_func,
664 void* init_func_parameter);
679 665
680 static void RestorePriority(KernelCore& kernel, KThread* thread); 666 static void RestorePriority(KernelCore& kernel, KThread* thread);
681 667