summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2021-03-05 00:13:29 -0800
committerGravatar bunnei2021-03-05 17:10:57 -0800
commit47af34003b97a27ee8456cedb367b41f8687b517 (patch)
tree5e28f986f365d7f441997c3c7e5be8f61013e72b
parentMerge pull request #6039 from yuzu-emu/revert-6006-fiber-unique-ptr (diff)
downloadyuzu-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.cpp6
-rw-r--r--src/core/hle/kernel/k_thread.cpp50
-rw-r--r--src/core/hle/kernel/k_thread.h24
-rw-r--r--src/core/hle/kernel/kernel.cpp11
-rw-r--r--src/core/hle/kernel/process.cpp5
-rw-r--r--src/core/hle/kernel/svc.cpp5
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
998ResultVal<std::shared_ptr<KThread>> KThread::Create(Core::System& system, ThreadType type_flags, 998ResultVal<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
1008ResultVal<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
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
1036KThread* GetCurrentThreadPointer(KernelCore& kernel) { 1048KThread* 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 {
40void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { 40void 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);