diff options
| author | 2021-03-05 00:13:29 -0800 | |
|---|---|---|
| committer | 2021-03-05 17:10:57 -0800 | |
| commit | 47af34003b97a27ee8456cedb367b41f8687b517 (patch) | |
| tree | 5e28f986f365d7f441997c3c7e5be8f61013e72b | |
| parent | Merge pull request #6039 from yuzu-emu/revert-6006-fiber-unique-ptr (diff) | |
| download | yuzu-47af34003b97a27ee8456cedb367b41f8687b517.tar.gz yuzu-47af34003b97a27ee8456cedb367b41f8687b517.tar.xz yuzu-47af34003b97a27ee8456cedb367b41f8687b517.zip | |
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.
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 50 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 24 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 5 |
6 files changed, 65 insertions, 36 deletions
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index bb5f43b53..6e89c3042 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp | |||
| @@ -800,9 +800,9 @@ void KScheduler::Initialize() { | |||
| 800 | std::string name = "Idle Thread Id:" + std::to_string(core_id); | 800 | std::string name = "Idle Thread Id:" + std::to_string(core_id); |
| 801 | std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc(); | 801 | std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc(); |
| 802 | void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | 802 | void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); |
| 803 | auto thread_res = KThread::Create(system, ThreadType::Main, name, 0, | 803 | auto thread_res = KThread::CreateThread( |
| 804 | KThread::IdleThreadPriority, 0, static_cast<u32>(core_id), 0, | 804 | system, ThreadType::Main, name, 0, KThread::IdleThreadPriority, 0, |
| 805 | nullptr, std::move(init_func), init_func_parameter); | 805 | static_cast<u32>(core_id), 0, nullptr, std::move(init_func), init_func_parameter); |
| 806 | idle_thread = thread_res.Unwrap().get(); | 806 | idle_thread = thread_res.Unwrap().get(); |
| 807 | } | 807 | } |
| 808 | 808 | ||
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 1661afbd9..e0f53287c 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -995,22 +995,11 @@ std::shared_ptr<Common::Fiber>& KThread::GetHostContext() { | |||
| 995 | return host_context; | 995 | return host_context; |
| 996 | } | 996 | } |
| 997 | 997 | ||
| 998 | ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, | 998 | ResultVal<std::shared_ptr<KThread>> KThread::CreateThread(Core::System& system, |
| 999 | std::string name, VAddr entry_point, | 999 | ThreadType type_flags, std::string name, |
| 1000 | u32 priority, u64 arg, s32 processor_id, | 1000 | VAddr entry_point, u32 priority, u64 arg, |
| 1001 | VAddr stack_top, Process* owner_process) { | 1001 | s32 processor_id, VAddr stack_top, |
| 1002 | std::function<void(void*)> init_func = Core::CpuManager::GetGuestThreadStartFunc(); | 1002 | Process* owner_process) { |
| 1003 | void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | ||
| 1004 | return Create(system, type_flags, name, entry_point, priority, arg, processor_id, stack_top, | ||
| 1005 | owner_process, std::move(init_func), init_func_parameter); | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, | ||
| 1009 | std::string name, VAddr entry_point, | ||
| 1010 | u32 priority, u64 arg, s32 processor_id, | ||
| 1011 | VAddr stack_top, Process* owner_process, | ||
| 1012 | std::function<void(void*)>&& thread_start_func, | ||
| 1013 | void* thread_start_parameter) { | ||
| 1014 | auto& kernel = system.Kernel(); | 1003 | auto& kernel = system.Kernel(); |
| 1015 | 1004 | ||
| 1016 | std::shared_ptr<KThread> thread = std::make_shared<KThread>(kernel); | 1005 | 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 | |||
| 1027 | auto& scheduler = kernel.GlobalSchedulerContext(); | 1016 | auto& scheduler = kernel.GlobalSchedulerContext(); |
| 1028 | scheduler.AddThread(thread); | 1017 | scheduler.AddThread(thread); |
| 1029 | 1018 | ||
| 1030 | thread->host_context = | ||
| 1031 | std::make_shared<Common::Fiber>(std::move(thread_start_func), thread_start_parameter); | ||
| 1032 | |||
| 1033 | return MakeResult<std::shared_ptr<KThread>>(std::move(thread)); | 1019 | return MakeResult<std::shared_ptr<KThread>>(std::move(thread)); |
| 1034 | } | 1020 | } |
| 1035 | 1021 | ||
| 1022 | ResultVal<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 | |||
| 1037 | ResultVal<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 | |||
| 1036 | KThread* GetCurrentThreadPointer(KernelCore& kernel) { | 1048 | KThread* GetCurrentThreadPointer(KernelCore& kernel) { |
| 1037 | return kernel.GetCurrentEmuThread(); | 1049 | return kernel.GetCurrentEmuThread(); |
| 1038 | } | 1050 | } |
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index c8ac656a4..1c19b23dc 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -116,7 +116,7 @@ public: | |||
| 116 | using WaiterList = boost::intrusive::list<KThread>; | 116 | using WaiterList = boost::intrusive::list<KThread>; |
| 117 | 117 | ||
| 118 | /** | 118 | /** |
| 119 | * Creates and returns a new thread. The new thread is immediately scheduled | 119 | * Creates and returns a new thread. |
| 120 | * @param system The instance of the whole system | 120 | * @param system The instance of the whole system |
| 121 | * @param name The friendly name desired for the thread | 121 | * @param name The friendly name desired for the thread |
| 122 | * @param entry_point The address at which the thread should start execution | 122 | * @param entry_point The address at which the thread should start execution |
| @@ -127,12 +127,12 @@ public: | |||
| 127 | * @param owner_process The parent process for the thread, if null, it's a kernel thread | 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 | 128 | * @return A shared pointer to the newly created thread |
| 129 | */ | 129 | */ |
| 130 | [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> Create( | 130 | [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateThread( |
| 131 | Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, | 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); | 132 | u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process); |
| 133 | 133 | ||
| 134 | /** | 134 | /** |
| 135 | * Creates and returns a new thread. The new thread is immediately scheduled | 135 | * Creates and returns a new thread, with a specified entry point. |
| 136 | * @param system The instance of the whole system | 136 | * @param system The instance of the whole system |
| 137 | * @param name The friendly name desired for the thread | 137 | * @param name The friendly name desired for the thread |
| 138 | * @param entry_point The address at which the thread should start execution | 138 | * @param entry_point The address at which the thread should start execution |
| @@ -145,11 +145,27 @@ public: | |||
| 145 | * @param thread_start_parameter The parameter which will passed to host context on init | 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 | 146 | * @return A shared pointer to the newly created thread |
| 147 | */ | 147 | */ |
| 148 | [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> Create( | 148 | [[nodiscard]] static ResultVal<std::shared_ptr<KThread>> CreateThread( |
| 149 | Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, | 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, | 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); | 151 | std::function<void(void*)>&& thread_start_func, void* thread_start_parameter); |
| 152 | 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 | |||
| 153 | [[nodiscard]] std::string GetName() const override { | 169 | [[nodiscard]] std::string GetName() const override { |
| 154 | return name; | 170 | return name; |
| 155 | } | 171 | } |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 331cf3a60..780008b08 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -181,9 +181,9 @@ struct KernelCore::Impl { | |||
| 181 | std::string name = "Suspend Thread Id:" + std::to_string(i); | 181 | std::string name = "Suspend Thread Id:" + std::to_string(i); |
| 182 | std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); | 182 | std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc(); |
| 183 | void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); | 183 | void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); |
| 184 | auto thread_res = KThread::Create(system, ThreadType::HighPriority, std::move(name), 0, | 184 | auto thread_res = KThread::CreateThread( |
| 185 | 0, 0, static_cast<u32>(i), 0, nullptr, | 185 | system, ThreadType::HighPriority, std::move(name), 0, 0, 0, static_cast<u32>(i), 0, |
| 186 | std::move(init_func), init_func_parameter); | 186 | nullptr, std::move(init_func), init_func_parameter); |
| 187 | 187 | ||
| 188 | suspend_threads[i] = std::move(thread_res).Unwrap(); | 188 | suspend_threads[i] = std::move(thread_res).Unwrap(); |
| 189 | } | 189 | } |
| @@ -221,10 +221,9 @@ struct KernelCore::Impl { | |||
| 221 | // Gets the dummy KThread for the caller, allocating a new one if this is the first time | 221 | // Gets the dummy KThread for the caller, allocating a new one if this is the first time |
| 222 | KThread* GetHostDummyThread() { | 222 | KThread* GetHostDummyThread() { |
| 223 | const thread_local auto thread = | 223 | const thread_local auto thread = |
| 224 | KThread::Create( | 224 | KThread::CreateThread( |
| 225 | system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, | 225 | system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, |
| 226 | KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr, | 226 | KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr) |
| 227 | []([[maybe_unused]] void* arg) { UNREACHABLE(); }, nullptr) | ||
| 228 | .Unwrap(); | 227 | .Unwrap(); |
| 229 | return thread.get(); | 228 | return thread.get(); |
| 230 | } | 229 | } |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 73b85d6f9..9d5956ead 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -40,8 +40,9 @@ namespace { | |||
| 40 | void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { | 40 | void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { |
| 41 | const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); | 41 | const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); |
| 42 | ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); | 42 | ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); |
| 43 | auto thread_res = KThread::Create(system, ThreadType::User, "main", entry_point, priority, 0, | 43 | auto thread_res = |
| 44 | owner_process.GetIdealCoreId(), stack_top, &owner_process); | 44 | KThread::CreateUserThread(system, ThreadType::User, "main", entry_point, priority, 0, |
| 45 | owner_process.GetIdealCoreId(), stack_top, &owner_process); | ||
| 45 | 46 | ||
| 46 | std::shared_ptr<KThread> thread = std::move(thread_res).Unwrap(); | 47 | std::shared_ptr<KThread> thread = std::move(thread_res).Unwrap(); |
| 47 | 48 | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index cc8fa6576..326d3b9ec 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -1532,8 +1532,9 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1532 | std::shared_ptr<KThread> thread; | 1532 | std::shared_ptr<KThread> thread; |
| 1533 | { | 1533 | { |
| 1534 | KScopedLightLock lk{process.GetStateLock()}; | 1534 | KScopedLightLock lk{process.GetStateLock()}; |
| 1535 | CASCADE_RESULT(thread, KThread::Create(system, ThreadType::User, "", entry_point, priority, | 1535 | CASCADE_RESULT(thread, |
| 1536 | arg, core_id, stack_bottom, &process)); | 1536 | KThread::CreateUserThread(system, ThreadType::User, "", entry_point, |
| 1537 | priority, arg, core_id, stack_bottom, &process)); | ||
| 1537 | } | 1538 | } |
| 1538 | 1539 | ||
| 1539 | const auto new_thread_handle = process.GetHandleTable().Create(thread); | 1540 | const auto new_thread_handle = process.GetHandleTable().Create(thread); |