hle: kernel: KThread: Improve Increment/Decrement RunningThreadCount.
- Previously implementation was incorrect, and would occasionally underflow.
This commit is contained in:
		@@ -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!");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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<s32> num_created_threads{};
 | 
			
		||||
    std::atomic<u16> num_threads{};
 | 
			
		||||
    u16 peak_num_threads{};
 | 
			
		||||
    std::atomic<u16> num_running_threads{};
 | 
			
		||||
 | 
			
		||||
    std::array<KThread*, Core::Hardware::NUM_CPU_CORES> running_threads{};
 | 
			
		||||
    std::array<u64, Core::Hardware::NUM_CPU_CORES> running_thread_idle_counts{};
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user