mirror of
https://github.com/yuzu-mirror/yuzu.git
synced 2024-11-07 08:29:59 +00:00
Merge pull request #6036 from bunnei/thread-leak
hle: kernel: KThread: Rework dummy threads & fix memory leak.
This commit is contained in:
commit
4cf5b860bd
6 changed files with 65 additions and 36 deletions
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue