kernel: wait for threads to stop on pause

This commit is contained in:
Liam 2022-06-18 16:54:33 -04:00
parent 5b2b15091f
commit 24d7aaf43c
3 changed files with 22 additions and 0 deletions

View file

@ -748,6 +748,19 @@ void KThread::Continue() {
KScheduler::OnThreadStateChanged(kernel, this, old_state); 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) { ResultCode KThread::SetActivity(Svc::ThreadActivity activity) {
// Lock ourselves. // Lock ourselves.
KScopedLightLock lk(activity_pause_lock); KScopedLightLock lk(activity_pause_lock);

View file

@ -207,6 +207,8 @@ public:
void Continue(); void Continue();
void WaitUntilSuspended();
constexpr void SetSyncedIndex(s32 index) { constexpr void SetSyncedIndex(s32 index) {
synced_index = index; synced_index = index;
} }

View file

@ -1079,6 +1079,13 @@ void KernelCore::Suspend(bool suspended) {
for (auto* process : GetProcessList()) { for (auto* process : GetProcessList()) {
process->SetActivity(activity); process->SetActivity(activity);
if (should_suspend) {
// Wait for execution to stop
for (auto* thread : process->GetThreadList()) {
thread->WaitUntilSuspended();
}
}
} }
} }