diff options
| author | 2022-11-02 20:08:19 -0400 | |
|---|---|---|
| committer | 2022-11-04 09:18:57 -0400 | |
| commit | 85527cc7c7dfce81278d0373ffce97c70e35d5d7 (patch) | |
| tree | cd59774e1d142ed346d8c97bfa0eea7fcb81c7cf /src/core/hle/kernel/kernel.cpp | |
| parent | Update shader cache version. (#9175) (diff) | |
| download | yuzu-85527cc7c7dfce81278d0373ffce97c70e35d5d7.tar.gz yuzu-85527cc7c7dfce81278d0373ffce97c70e35d5d7.tar.xz yuzu-85527cc7c7dfce81278d0373ffce97c70e35d5d7.zip | |
kernel: avoid racy behavior in global suspension
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 09c36ee09..6df77b423 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -1109,16 +1109,28 @@ void KernelCore::Suspend(bool suspended) { | |||
| 1109 | const bool should_suspend{exception_exited || suspended}; | 1109 | const bool should_suspend{exception_exited || suspended}; |
| 1110 | const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; | 1110 | const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; |
| 1111 | 1111 | ||
| 1112 | for (auto* process : GetProcessList()) { | 1112 | std::vector<KScopedAutoObject<KThread>> process_threads; |
| 1113 | process->SetActivity(activity); | 1113 | { |
| 1114 | KScopedSchedulerLock sl{*this}; | ||
| 1115 | |||
| 1116 | if (auto* process = CurrentProcess(); process != nullptr) { | ||
| 1117 | process->SetActivity(activity); | ||
| 1118 | |||
| 1119 | if (!should_suspend) { | ||
| 1120 | // Runnable now; no need to wait. | ||
| 1121 | return; | ||
| 1122 | } | ||
| 1114 | 1123 | ||
| 1115 | if (should_suspend) { | ||
| 1116 | // Wait for execution to stop | ||
| 1117 | for (auto* thread : process->GetThreadList()) { | 1124 | for (auto* thread : process->GetThreadList()) { |
| 1118 | thread->WaitUntilSuspended(); | 1125 | process_threads.emplace_back(thread); |
| 1119 | } | 1126 | } |
| 1120 | } | 1127 | } |
| 1121 | } | 1128 | } |
| 1129 | |||
| 1130 | // Wait for execution to stop. | ||
| 1131 | for (auto& thread : process_threads) { | ||
| 1132 | thread->WaitUntilSuspended(); | ||
| 1133 | } | ||
| 1122 | } | 1134 | } |
| 1123 | 1135 | ||
| 1124 | void KernelCore::ShutdownCores() { | 1136 | void KernelCore::ShutdownCores() { |