summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r--src/core/hle/kernel/kernel.cpp39
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) {
1198 const bool should_suspend{exception_exited || suspended}; 1198 const bool should_suspend{exception_exited || suspended};
1199 const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; 1199 const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable;
1200 1200
1201 std::vector<KScopedAutoObject<KThread>> process_threads; 1201 //! This refers to the application process, not the current process.
1202 { 1202 KScopedAutoObject<KProcess> process = CurrentProcess();
1203 KScopedSchedulerLock sl{*this}; 1203 if (process.IsNull()) {
1204 return;
1205 }
1204 1206
1205 if (auto* process = CurrentProcess(); process != nullptr) { 1207 // Set the new activity.
1206 process->SetActivity(activity); 1208 process->SetActivity(activity);
1207 1209
1208 if (!should_suspend) { 1210 // Wait for process execution to stop.
1209 // Runnable now; no need to wait. 1211 bool must_wait{should_suspend};
1210 return; 1212
1211 } 1213 // KernelCore::Suspend must be called from locked context, or we
1214 // could race another call to SetActivity, interfering with waiting.
1215 while (must_wait) {
1216 KScopedSchedulerLock sl{*this};
1217
1218 // Assume that all threads have finished running.
1219 must_wait = false;
1212 1220
1213 for (auto* thread : process->GetThreadList()) { 1221 for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) {
1214 process_threads.emplace_back(thread); 1222 if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() ==
1223 process.GetPointerUnsafe()) {
1224 // A thread has not finished running yet.
1225 // Continue waiting.
1226 must_wait = true;
1215 } 1227 }
1216 } 1228 }
1217 } 1229 }
1218
1219 // Wait for execution to stop.
1220 for (auto& thread : process_threads) {
1221 thread->WaitUntilSuspended();
1222 }
1223} 1230}
1224 1231
1225void KernelCore::ShutdownCores() { 1232void KernelCore::ShutdownCores() {