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::string name = "Idle Thread Id:" + std::to_string(core_id); | ||||||
|     std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc(); |     std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc(); | ||||||
|     void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); |     void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | ||||||
|     auto thread_res = KThread::Create(system, ThreadType::Main, name, 0, |     auto thread_res = KThread::CreateThread( | ||||||
|                                       KThread::IdleThreadPriority, 0, static_cast<u32>(core_id), 0, |         system, ThreadType::Main, name, 0, KThread::IdleThreadPriority, 0, | ||||||
|                                       nullptr, std::move(init_func), init_func_parameter); |         static_cast<u32>(core_id), 0, nullptr, std::move(init_func), init_func_parameter); | ||||||
|     idle_thread = thread_res.Unwrap().get(); |     idle_thread = thread_res.Unwrap().get(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -995,22 +995,11 @@ std::shared_ptr<Common::Fiber>& KThread::GetHostContext() { | |||||||
|     return host_context; |     return host_context; | ||||||
| } | } | ||||||
|  |  | ||||||
| ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, | ResultVal<std::shared_ptr<KThread>> KThread::CreateThread(Core::System& system, | ||||||
|                                                     std::string name, VAddr entry_point, |                                                           ThreadType type_flags, std::string name, | ||||||
|                                                     u32 priority, u64 arg, s32 processor_id, |                                                           VAddr entry_point, u32 priority, u64 arg, | ||||||
|                                                     VAddr stack_top, Process* owner_process) { |                                                           s32 processor_id, VAddr stack_top, | ||||||
|     std::function<void(void*)> init_func = Core::CpuManager::GetGuestThreadStartFunc(); |                                                           Process* owner_process) { | ||||||
|     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) { |  | ||||||
|     auto& kernel = system.Kernel(); |     auto& kernel = system.Kernel(); | ||||||
|  |  | ||||||
|     std::shared_ptr<KThread> thread = std::make_shared<KThread>(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(); |     auto& scheduler = kernel.GlobalSchedulerContext(); | ||||||
|     scheduler.AddThread(thread); |     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)); |     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) { | KThread* GetCurrentThreadPointer(KernelCore& kernel) { | ||||||
|     return kernel.GetCurrentEmuThread(); |     return kernel.GetCurrentEmuThread(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -116,7 +116,7 @@ public: | |||||||
|     using WaiterList = boost::intrusive::list<KThread>; |     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 system The instance of the whole system | ||||||
|      * @param name The friendly name desired for the thread |      * @param name The friendly name desired for the thread | ||||||
|      * @param entry_point The address at which the thread should start execution |      * @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 |      * @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 |      * @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, |         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); |         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 system The instance of the whole system | ||||||
|      * @param name The friendly name desired for the thread |      * @param name The friendly name desired for the thread | ||||||
|      * @param entry_point The address at which the thread should start execution |      * @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 |      * @param thread_start_parameter The parameter which will passed to host context on init | ||||||
|      * @return A shared pointer to the newly created 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, |         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, |         u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process, | ||||||
|         std::function<void(void*)>&& thread_start_func, void* thread_start_parameter); |         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 { |     [[nodiscard]] std::string GetName() const override { | ||||||
|         return name; |         return name; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -181,9 +181,9 @@ struct KernelCore::Impl { | |||||||
|             std::string name = "Suspend Thread Id:" + std::to_string(i); |             std::string name = "Suspend Thread Id:" + std::to_string(i); | ||||||
|             std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); |             std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); | ||||||
|             void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); |             void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | ||||||
|             auto thread_res = KThread::Create(system, ThreadType::HighPriority, std::move(name), 0, |             auto thread_res = KThread::CreateThread( | ||||||
|                                               0, 0, static_cast<u32>(i), 0, nullptr, |                 system, ThreadType::HighPriority, std::move(name), 0, 0, 0, static_cast<u32>(i), 0, | ||||||
|                                               std::move(init_func), init_func_parameter); |                 nullptr, std::move(init_func), init_func_parameter); | ||||||
|  |  | ||||||
|             suspend_threads[i] = std::move(thread_res).Unwrap(); |             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 |     // Gets the dummy KThread for the caller, allocating a new one if this is the first time | ||||||
|     KThread* GetHostDummyThread() { |     KThread* GetHostDummyThread() { | ||||||
|         const thread_local auto thread = |         const thread_local auto thread = | ||||||
|             KThread::Create( |             KThread::CreateThread( | ||||||
|                 system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, |                 system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, | ||||||
|                 KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr, |                 KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr) | ||||||
|                 []([[maybe_unused]] void* arg) { UNREACHABLE(); }, nullptr) |  | ||||||
|                 .Unwrap(); |                 .Unwrap(); | ||||||
|         return thread.get(); |         return thread.get(); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -40,7 +40,8 @@ namespace { | |||||||
| void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { | void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { | ||||||
|     const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); |     const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); | ||||||
|     ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); |     ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); | ||||||
|     auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0, |     auto thread_res = | ||||||
|  |         KThread::CreateUserThread(system, ThreadType::User, "main", entry_point, priority, 0, | ||||||
|                                   owner_process.GetIdealCoreId(), stack_top, &owner_process); |                                   owner_process.GetIdealCoreId(), stack_top, &owner_process); | ||||||
|  |  | ||||||
|     std::shared_ptr<KThread> thread = std::move(thread_res).Unwrap(); |     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; |     std::shared_ptr<KThread> thread; | ||||||
|     { |     { | ||||||
|         KScopedLightLock lk{process.GetStateLock()}; |         KScopedLightLock lk{process.GetStateLock()}; | ||||||
|         CASCADE_RESULT(thread, KThread::Create(system, ThreadType::User, "", entry_point, priority, |         CASCADE_RESULT(thread, | ||||||
|                                                arg, core_id, stack_bottom, &process)); |                        KThread::CreateUserThread(system, ThreadType::User, "", entry_point, | ||||||
|  |                                                  priority, arg, core_id, stack_bottom, &process)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const auto new_thread_handle = process.GetHandleTable().Create(thread); |     const auto new_thread_handle = process.GetHandleTable().Create(thread); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user