aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
authorLiam <byteslice@airmail.cc>2022-11-02 20:08:19 -0400
committerLiam <byteslice@airmail.cc>2022-11-04 09:18:57 -0400
commit85527cc7c7dfce81278d0373ffce97c70e35d5d7 (patch)
treecd59774e1d142ed346d8c97bfa0eea7fcb81c7cf /src/core/hle/kernel/kernel.cpp
parent9fc1bcc7b2da398d12327e8111c21e453a4af27d (diff)
kernel: avoid racy behavior in global suspension
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp22
1 files changed, 17 insertions, 5 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 09c36ee09d..6df77b4239 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -1109,16 +1109,28 @@ void KernelCore::Suspend(bool suspended) {
const bool should_suspend{exception_exited || suspended};
const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
- for (auto* process : GetProcessList()) {
- process->SetActivity(activity);
+ std::vector<KScopedAutoObject<KThread>> process_threads;
+ {
+ KScopedSchedulerLock sl{*this};
+
+ if (auto* process = CurrentProcess(); process != nullptr) {
+ process->SetActivity(activity);
+
+ if (!should_suspend) {
+ // Runnable now; no need to wait.
+ return;
+ }
- if (should_suspend) {
- // Wait for execution to stop
for (auto* thread : process->GetThreadList()) {
- thread->WaitUntilSuspended();
+ process_threads.emplace_back(thread);
}
}
}
+
+ // Wait for execution to stop.
+ for (auto& thread : process_threads) {
+ thread->WaitUntilSuspended();
+ }
}
void KernelCore::ShutdownCores() {