From 59add00d4a37a8f7b1bc8b4c39e46fae35150540 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 22 Jan 2022 21:09:45 -0800 Subject: hle: kernel: KThread: Improve Increment/Decrement RunningThreadCount. - Previously implementation was incorrect, and would occasionally underflow. --- src/core/hle/kernel/k_process.cpp | 26 +++++++++++++++----------- src/core/hle/kernel/k_process.h | 8 +++----- src/core/hle/kernel/k_thread.cpp | 11 +++-------- 3 files changed, 21 insertions(+), 24 deletions(-) (limited to 'src/core/hle/kernel') diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 265ac6fa1..85c506979 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -146,6 +146,13 @@ ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::st // Open a reference to the resource limit. process->resource_limit->Open(); + // Clear remaining fields. + process->num_running_threads = 0; + process->is_signaled = false; + process->exception_thread = nullptr; + process->is_suspended = false; + process->schedule_count = 0; + return ResultSuccess; } @@ -157,20 +164,17 @@ KResourceLimit* KProcess::GetResourceLimit() const { return resource_limit; } -void KProcess::IncrementThreadCount() { - ASSERT(num_threads >= 0); - num_created_threads++; - - if (const auto count = ++num_threads; count > peak_num_threads) { - peak_num_threads = count; - } +void KProcess::IncrementRunningThreadCount() { + ASSERT(num_running_threads.load() >= 0); + ++num_running_threads; } -void KProcess::DecrementThreadCount() { - ASSERT(num_threads > 0); +void KProcess::DecrementRunningThreadCount() { + ASSERT(num_running_threads.load() > 0); - if (const auto count = --num_threads; count == 0) { - LOG_WARNING(Kernel, "Process termination is not fully implemented."); + if (const auto prev = num_running_threads--; prev == 1) { + // TODO(bunnei): Process termination to be implemented when multiprocess is supported. + UNIMPLEMENTED_MSG("KProcess termination is not implemennted!"); } } diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index c2a672021..38b446350 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -235,8 +235,8 @@ public: ++schedule_count; } - void IncrementThreadCount(); - void DecrementThreadCount(); + void IncrementRunningThreadCount(); + void DecrementRunningThreadCount(); void SetRunningThread(s32 core, KThread* thread, u64 idle_count) { running_threads[core] = thread; @@ -473,9 +473,7 @@ private: bool is_suspended{}; bool is_initialized{}; - std::atomic num_created_threads{}; - std::atomic num_threads{}; - u16 peak_num_threads{}; + std::atomic num_running_threads{}; std::array running_threads{}; std::array running_thread_idle_counts{}; diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index f42abb8a1..de3ffe0c7 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -215,7 +215,6 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s parent = owner; parent->Open(); - parent->IncrementThreadCount(); } // Initialize thread context. @@ -327,11 +326,6 @@ void KThread::Finalize() { } } - // Decrement the parent process's thread count. - if (parent != nullptr) { - parent->DecrementThreadCount(); - } - // Perform inherited finalization. KSynchronizationObject::Finalize(); } @@ -1011,7 +1005,7 @@ ResultCode KThread::Run() { if (IsUserThread() && IsSuspended()) { this->UpdateState(); } - owner->IncrementThreadCount(); + owner->IncrementRunningThreadCount(); } // Set our state and finish. @@ -1026,10 +1020,11 @@ ResultCode KThread::Run() { void KThread::Exit() { ASSERT(this == GetCurrentThreadPointer(kernel)); - // Release the thread resource hint from parent. + // Release the thread resource hint, running thread count from parent. if (parent != nullptr) { parent->GetResourceLimit()->Release(Kernel::LimitableResource::Threads, 0, 1); resource_limit_release_hint = true; + parent->DecrementRunningThreadCount(); } // Perform termination. -- cgit v1.2.3