diff options
author | Liam <byteslice@airmail.cc> | 2023-01-23 20:56:06 +0100 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2023-01-23 23:14:41 +0100 |
commit | 5086380a63bfbaa118ff48da14f505f842ac19cc (patch) | |
tree | 8129ee6653bbb551ac77e45f86ee2ee959b58969 /src/core/hle/kernel/kernel.cpp | |
parent | Merge pull request #9660 from german77/koreaToTaiwan (diff) | |
download | yuzu-5086380a63bfbaa118ff48da14f505f842ac19cc.tar yuzu-5086380a63bfbaa118ff48da14f505f842ac19cc.tar.gz yuzu-5086380a63bfbaa118ff48da14f505f842ac19cc.tar.bz2 yuzu-5086380a63bfbaa118ff48da14f505f842ac19cc.tar.lz yuzu-5086380a63bfbaa118ff48da14f505f842ac19cc.tar.xz yuzu-5086380a63bfbaa118ff48da14f505f842ac19cc.tar.zst yuzu-5086380a63bfbaa118ff48da14f505f842ac19cc.zip |
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1fb25f221..d9eafe261 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -1198,28 +1198,35 @@ void KernelCore::Suspend(bool suspended) { const bool should_suspend{exception_exited || suspended}; const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; - std::vector<KScopedAutoObject<KThread>> process_threads; - { - KScopedSchedulerLock sl{*this}; + //! This refers to the application process, not the current process. + KScopedAutoObject<KProcess> process = CurrentProcess(); + if (process.IsNull()) { + return; + } - if (auto* process = CurrentProcess(); process != nullptr) { - process->SetActivity(activity); + // Set the new activity. + process->SetActivity(activity); - if (!should_suspend) { - // Runnable now; no need to wait. - return; - } + // Wait for process execution to stop. + bool must_wait{should_suspend}; + + // KernelCore::Suspend must be called from locked context, or we + // could race another call to SetActivity, interfering with waiting. + while (must_wait) { + KScopedSchedulerLock sl{*this}; + + // Assume that all threads have finished running. + must_wait = false; - for (auto* thread : process->GetThreadList()) { - process_threads.emplace_back(thread); + for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { + if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == + process.GetPointerUnsafe()) { + // A thread has not finished running yet. + // Continue waiting. + must_wait = true; } } } - - // Wait for execution to stop. - for (auto& thread : process_threads) { - thread->WaitUntilSuspended(); - } } void KernelCore::ShutdownCores() { |