hle: kernel: KThread: Rework dummy threads & fix memory leak.
- Dummy threads are created on thread local storage for all host threads. - Fixes a leak by removing creation of fibers, which are not applicable here.
This commit is contained in:
		| @@ -800,9 +800,9 @@ void KScheduler::Initialize() { | ||||
|     std::string name = "Idle Thread Id:" + std::to_string(core_id); | ||||
|     std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc(); | ||||
|     void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | ||||
|     auto thread_res = KThread::Create(system, ThreadType::Main, name, 0, | ||||
|                                       KThread::IdleThreadPriority, 0, static_cast<u32>(core_id), 0, | ||||
|                                       nullptr, std::move(init_func), init_func_parameter); | ||||
|     auto thread_res = KThread::CreateThread( | ||||
|         system, ThreadType::Main, name, 0, KThread::IdleThreadPriority, 0, | ||||
|         static_cast<u32>(core_id), 0, nullptr, std::move(init_func), init_func_parameter); | ||||
|     idle_thread = thread_res.Unwrap().get(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -995,22 +995,11 @@ std::shared_ptr<Common::Fiber>& KThread::GetHostContext() { | ||||
|     return host_context; | ||||
| } | ||||
|  | ||||
| ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, | ||||
|                                                     std::string name, VAddr entry_point, | ||||
|                                                     u32 priority, u64 arg, s32 processor_id, | ||||
|                                                     VAddr stack_top, Process* owner_process) { | ||||
|     std::function<void(void*)> init_func = Core::CpuManager::GetGuestThreadStartFunc(); | ||||
|     void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | ||||
|     return Create(system, type_flags, name, entry_point, priority, arg, processor_id, stack_top, | ||||
|                   owner_process, std::move(init_func), init_func_parameter); | ||||
| } | ||||
|  | ||||
| ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, | ||||
|                                                     std::string name, VAddr entry_point, | ||||
|                                                     u32 priority, u64 arg, s32 processor_id, | ||||
|                                                     VAddr stack_top, Process* owner_process, | ||||
|                                                     std::function<void(void*)>&& thread_start_func, | ||||
|                                                     void* thread_start_parameter) { | ||||
| ResultVal<std::shared_ptr<KThread>> KThread::CreateThread(Core::System& system, | ||||
|                                                           ThreadType type_flags, std::string name, | ||||
|                                                           VAddr entry_point, u32 priority, u64 arg, | ||||
|                                                           s32 processor_id, VAddr stack_top, | ||||
|                                                           Process* owner_process) { | ||||
|     auto& kernel = system.Kernel(); | ||||
|  | ||||
|     std::shared_ptr<KThread> thread = std::make_shared<KThread>(kernel); | ||||
| @@ -1027,12 +1016,35 @@ ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, Thread | ||||
|     auto& scheduler = kernel.GlobalSchedulerContext(); | ||||
|     scheduler.AddThread(thread); | ||||
|  | ||||
|     thread->host_context = | ||||
|         std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter); | ||||
|  | ||||
|     return MakeResult<std::shared_ptr<KThread>>(std::move(thread)); | ||||
| } | ||||
|  | ||||
| ResultVal<std::shared_ptr<KThread>> KThread::CreateThread( | ||||
|     Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, u32 priority, | ||||
|     u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process, | ||||
|     std::function<void(void*)>&& thread_start_func, void* thread_start_parameter) { | ||||
|     auto thread_result = CreateThread(system, type_flags, name, entry_point, priority, arg, | ||||
|                                       processor_id, stack_top, owner_process); | ||||
|  | ||||
|     if (thread_result.Succeeded()) { | ||||
|         (*thread_result)->host_context = | ||||
|             std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter); | ||||
|     } | ||||
|  | ||||
|     return thread_result; | ||||
| } | ||||
|  | ||||
| ResultVal<std::shared_ptr<KThread>> KThread::CreateUserThread( | ||||
|     Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, u32 priority, | ||||
|     u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process) { | ||||
|     std::function<void(void*)> init_func = Core::CpuManager::GetGuestThreadStartFunc(); | ||||
|  | ||||
|     void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | ||||
|  | ||||
|     return CreateThread(system, type_flags, name, entry_point, priority, arg, processor_id, | ||||
|                         stack_top, owner_process, std::move(init_func), init_func_parameter); | ||||
| } | ||||
|  | ||||
| KThread* GetCurrentThreadPointer(KernelCore& kernel) { | ||||
|     return kernel.GetCurrentEmuThread(); | ||||
| } | ||||
|   | ||||
| @@ -116,7 +116,7 @@ public: | ||||
|     using WaiterList = boost::intrusive::list<KThread>; | ||||
|  | ||||
|     /** | ||||
|      * Creates and returns a new thread. The new thread is immediately scheduled | ||||
|      * Creates and returns a new thread. | ||||
|      * @param system The instance of the whole system | ||||
|      * @param name The friendly name desired for the thread | ||||
|      * @param entry_point The address at which the thread should start execution | ||||
| @@ -127,12 +127,12 @@ public: | ||||
|      * @param owner_process The parent process for the thread, if null, it's a kernel thread | ||||
|      * @return A shared pointer to the newly created thread | ||||
|      */ | ||||
|     [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> Create( | ||||
|     [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateThread( | ||||
|         Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, | ||||
|         u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process); | ||||
|  | ||||
|     /** | ||||
|      * Creates and returns a new thread. The new thread is immediately scheduled | ||||
|      * Creates and returns a new thread, with a specified entry point. | ||||
|      * @param system The instance of the whole system | ||||
|      * @param name The friendly name desired for the thread | ||||
|      * @param entry_point The address at which the thread should start execution | ||||
| @@ -145,11 +145,27 @@ public: | ||||
|      * @param thread_start_parameter The parameter which will passed to host context on init | ||||
|      * @return A shared pointer to the newly created thread | ||||
|      */ | ||||
|     [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> Create( | ||||
|     [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateThread( | ||||
|         Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, | ||||
|         u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process, | ||||
|         std::function<void(void*)>&& thread_start_func, void* thread_start_parameter); | ||||
|  | ||||
|     /** | ||||
|      * Creates and returns a new thread for the emulated "user" process. | ||||
|      * @param system The instance of the whole system | ||||
|      * @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, if null, it's a kernel thread | ||||
|      * @return A shared pointer to the newly created thread | ||||
|      */ | ||||
|     [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateUserThread( | ||||
|         Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, | ||||
|         u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process); | ||||
|  | ||||
|     [[nodiscard]] std::string GetName() const override { | ||||
|         return name; | ||||
|     } | ||||
|   | ||||
| @@ -181,9 +181,9 @@ struct KernelCore::Impl { | ||||
|             std::string name = "Suspend Thread Id:" + std::to_string(i); | ||||
|             std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); | ||||
|             void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | ||||
|             auto thread_res = KThread::Create(system, ThreadType::HighPriority, std::move(name), 0, | ||||
|                                               0, 0, static_cast<u32>(i), 0, nullptr, | ||||
|                                               std::move(init_func), init_func_parameter); | ||||
|             auto thread_res = KThread::CreateThread( | ||||
|                 system, ThreadType::HighPriority, std::move(name), 0, 0, 0, static_cast<u32>(i), 0, | ||||
|                 nullptr, std::move(init_func), init_func_parameter); | ||||
|  | ||||
|             suspend_threads[i] = std::move(thread_res).Unwrap(); | ||||
|         } | ||||
| @@ -221,10 +221,9 @@ struct KernelCore::Impl { | ||||
|     // Gets the dummy KThread for the caller, allocating a new one if this is the first time | ||||
|     KThread* GetHostDummyThread() { | ||||
|         const thread_local auto thread = | ||||
|             KThread::Create( | ||||
|             KThread::CreateThread( | ||||
|                 system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, | ||||
|                 KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr, | ||||
|                 []([[maybe_unused]] void* arg) { UNREACHABLE(); }, nullptr) | ||||
|                 KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr) | ||||
|                 .Unwrap(); | ||||
|         return thread.get(); | ||||
|     } | ||||
|   | ||||
| @@ -40,8 +40,9 @@ namespace { | ||||
| void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { | ||||
|     const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); | ||||
|     ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); | ||||
|     auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0, | ||||
|                                       owner_process.GetIdealCoreId(), stack_top, &owner_process); | ||||
|     auto thread_res = | ||||
|         KThread::CreateUserThread(system, ThreadType::User, "main", entry_point, priority, 0, | ||||
|                                   owner_process.GetIdealCoreId(), stack_top, &owner_process); | ||||
|  | ||||
|     std::shared_ptr<KThread> thread = std::move(thread_res).Unwrap(); | ||||
|  | ||||
|   | ||||
| @@ -1532,8 +1532,9 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | ||||
|     std::shared_ptr<KThread> thread; | ||||
|     { | ||||
|         KScopedLightLock lk{process.GetStateLock()}; | ||||
|         CASCADE_RESULT(thread, KThread::Create(system, ThreadType::User, "", entry_point, priority, | ||||
|                                                arg, core_id, stack_bottom, &process)); | ||||
|         CASCADE_RESULT(thread, | ||||
|                        KThread::CreateUserThread(system, ThreadType::User, "", entry_point, | ||||
|                                                  priority, arg, core_id, stack_bottom, &process)); | ||||
|     } | ||||
|  | ||||
|     const auto new_thread_handle = process.GetHandleTable().Create(thread); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user