summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/kernel/k_thread.cpp13
-rw-r--r--src/core/hle/kernel/k_thread.h2
-rw-r--r--src/core/hle/kernel/kernel.cpp7
3 files changed, 22 insertions, 0 deletions
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 268789150..c0a091bb6 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -748,6 +748,19 @@ void KThread::Continue() {
KScheduler::OnThreadStateChanged(kernel, this, old_state);
}
+void KThread::WaitUntilSuspended() {
+ // Make sure we have a suspend requested.
+ ASSERT(IsSuspendRequested());
+
+ // Loop until the thread is not executing on any core.
+ for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) {
+ KThread* core_thread{};
+ do {
+ core_thread = kernel.Scheduler(i).GetCurrentThread();
+ } while (core_thread == this);
+ }
+}
+
ResultCode KThread::SetActivity(Svc::ThreadActivity activity) {
// Lock ourselves.
KScopedLightLock lk(activity_pause_lock);
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index f4d83f99a..8c1f8a344 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -207,6 +207,8 @@ public:
void Continue();
+ void WaitUntilSuspended();
+
constexpr void SetSyncedIndex(s32 index) {
synced_index = index;
}
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 66c8f4455..94953e257 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -1078,6 +1078,13 @@ void KernelCore::Suspend(bool suspended) {
for (auto* process : GetProcessList()) {
process->SetActivity(activity);
+
+ if (should_suspend) {
+ // Wait for execution to stop
+ for (auto* thread : process->GetThreadList()) {
+ thread->WaitUntilSuspended();
+ }
+ }
}
}