diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 9e29868ca..aca8a5fab 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -7,6 +7,7 @@ #include #include #include "common/common_types.h" +#include "core/hle/result.h" namespace Kernel { @@ -15,6 +16,7 @@ class Event; class Mutex; class CodeSet; class Process; +class Thread; enum class ResetType { OneShot, @@ -56,6 +58,21 @@ public: SharedPtr CreateCodeSet(std::string name, u64 program_id); SharedPtr CreateProcess(SharedPtr code_set); + + /** + * Creates and returns a new thread. The new thread is immediately scheduled + * @param name The friendly name desired for the thread + * @param entry_point The address at which the thread should start execution + * @param priority The thread's priority + * @param arg User data to pass to the thread + * @param processor_id The ID(s) of the processors on which the thread is desired to be run + * @param stack_top The address of the thread's stack top + * @param owner_process The parent process for the thread + * @return A shared pointer to the newly created thread + */ + ResultVal> CreateThread(std::string name, VAddr entry_point, u32 priority, + u32 arg, s32 processor_id, VAddr stack_top, + SharedPtr owner_process); }; } // namespace Kernel diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 3e95cc6f7..5d1b9389a 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -155,7 +155,7 @@ void Process::Run(s32 main_thread_priority, u32 stack_size) { status = ProcessStatus::Running; vm_manager.LogLayout(Log::Level::Debug); - Kernel::SetupMainThread(codeset->entrypoint, main_thread_priority, this); + Kernel::SetupMainThread(kernel, codeset->entrypoint, main_thread_priority, this); } VAddr Process::GetLinearHeapAreaAddress() const { diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 8ea242e6d..e61bf53b0 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -761,9 +761,9 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point break; } - CASCADE_RESULT(SharedPtr thread, - Thread::Create(name, entry_point, priority, arg, processor_id, stack_top, - g_current_process)); + CASCADE_RESULT(SharedPtr thread, Core::System::GetInstance().Kernel().CreateThread( + name, entry_point, priority, arg, processor_id, + stack_top, g_current_process)); thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 50fa061c4..bf7a18685 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -60,7 +60,7 @@ inline static u32 const NewThreadId() { return next_thread_id++; } -Thread::Thread() : context(Core::CPU().NewContext()) {} +Thread::Thread(KernelSystem&) : context(Core::CPU().NewContext()) {} Thread::~Thread() {} Thread* GetCurrentThread() { @@ -320,9 +320,10 @@ static void ResetThreadContext(const std::unique_ptrSetCpsr(USER32MODE | ((entry_point & 1) << 5)); // Usermode and THUMB mode } -ResultVal> Thread::Create(std::string name, VAddr entry_point, u32 priority, - u32 arg, s32 processor_id, VAddr stack_top, - SharedPtr owner_process) { +ResultVal> KernelSystem::CreateThread(std::string name, VAddr entry_point, + u32 priority, u32 arg, s32 processor_id, + VAddr stack_top, + SharedPtr owner_process) { // Check if priority is in ranged. Lowest priority -> highest priority id. if (priority > ThreadPrioLowest) { LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); @@ -343,7 +344,7 @@ ResultVal> Thread::Create(std::string name, VAddr entry_point, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } - SharedPtr thread(new Thread); + SharedPtr thread(new Thread(*this)); thread_list.push_back(thread); ready_queue.prepare(priority); @@ -443,11 +444,12 @@ void Thread::BoostPriority(u32 priority) { current_priority = priority; } -SharedPtr SetupMainThread(u32 entry_point, u32 priority, SharedPtr owner_process) { +SharedPtr SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority, + SharedPtr owner_process) { // Initialize new "main" thread auto thread_res = - Thread::Create("main", entry_point, priority, 0, owner_process->ideal_processor, - Memory::HEAP_VADDR_END, owner_process); + kernel.CreateThread("main", entry_point, priority, 0, owner_process->ideal_processor, + Memory::HEAP_VADDR_END, owner_process); SharedPtr thread = std::move(thread_res).Unwrap(); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 3fd72563f..9e6a22759 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -55,21 +55,6 @@ enum class ThreadWakeupReason { class Thread final : public WaitObject { public: - /** - * Creates and returns a new thread. The new thread is immediately scheduled - * @param name The friendly name desired for the thread - * @param entry_point The address at which the thread should start execution - * @param priority The thread's priority - * @param arg User data to pass to the thread - * @param processor_id The ID(s) of the processors on which the thread is desired to be run - * @param stack_top The address of the thread's stack top - * @param owner_process The parent process for the thread - * @return A shared pointer to the newly created thread - */ - static ResultVal> Create(std::string name, VAddr entry_point, u32 priority, - u32 arg, s32 processor_id, VAddr stack_top, - SharedPtr owner_process); - std::string GetName() const override { return name; } @@ -225,18 +210,22 @@ public: std::function wakeup_callback; private: - Thread(); + explicit Thread(KernelSystem&); ~Thread() override; + + friend class KernelSystem; }; /** * Sets up the primary application thread + * @param kernel The kernel instance on which the thread is created * @param entry_point The address at which the thread should start execution * @param priority The priority to give the main thread * @param owner_process The parent process for the main thread * @return A shared pointer to the main thread */ -SharedPtr SetupMainThread(u32 entry_point, u32 priority, SharedPtr owner_process); +SharedPtr SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 priority, + SharedPtr owner_process); /** * Returns whether there are any threads that are ready to run.