diff options
| author | 2022-06-22 14:46:33 -0700 | |
|---|---|---|
| committer | 2022-06-22 14:46:33 -0700 | |
| commit | 9da4e62573cdaa8a48dd18068642b494cfed9a04 (patch) | |
| tree | c179c5fa993f3e840d6e0051ae28ad04520e2723 | |
| parent | Merge pull request #8455 from lat9nq/mingw-clang (diff) | |
| parent | kernel: wait for threads to stop on pause (diff) | |
| download | yuzu-9da4e62573cdaa8a48dd18068642b494cfed9a04.tar.gz yuzu-9da4e62573cdaa8a48dd18068642b494cfed9a04.tar.xz yuzu-9da4e62573cdaa8a48dd18068642b494cfed9a04.zip | |
Merge pull request #8483 from liamwhite/fire-emblem-three-semaphores
kernel: wait for threads to stop on pause
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 7 |
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() { | |||
| 748 | KScheduler::OnThreadStateChanged(kernel, this, old_state); | 748 | KScheduler::OnThreadStateChanged(kernel, this, old_state); |
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | void KThread::WaitUntilSuspended() { | ||
| 752 | // Make sure we have a suspend requested. | ||
| 753 | ASSERT(IsSuspendRequested()); | ||
| 754 | |||
| 755 | // Loop until the thread is not executing on any core. | ||
| 756 | for (std::size_t i = 0; i < static_cast<std::size_t>(Core::Hardware::NUM_CPU_CORES); ++i) { | ||
| 757 | KThread* core_thread{}; | ||
| 758 | do { | ||
| 759 | core_thread = kernel.Scheduler(i).GetCurrentThread(); | ||
| 760 | } while (core_thread == this); | ||
| 761 | } | ||
| 762 | } | ||
| 763 | |||
| 751 | ResultCode KThread::SetActivity(Svc::ThreadActivity activity) { | 764 | ResultCode KThread::SetActivity(Svc::ThreadActivity activity) { |
| 752 | // Lock ourselves. | 765 | // Lock ourselves. |
| 753 | KScopedLightLock lk(activity_pause_lock); | 766 | 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: | |||
| 207 | 207 | ||
| 208 | void Continue(); | 208 | void Continue(); |
| 209 | 209 | ||
| 210 | void WaitUntilSuspended(); | ||
| 211 | |||
| 210 | constexpr void SetSyncedIndex(s32 index) { | 212 | constexpr void SetSyncedIndex(s32 index) { |
| 211 | synced_index = index; | 213 | synced_index = index; |
| 212 | } | 214 | } |
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) { | |||
| 1078 | 1078 | ||
| 1079 | for (auto* process : GetProcessList()) { | 1079 | for (auto* process : GetProcessList()) { |
| 1080 | process->SetActivity(activity); | 1080 | process->SetActivity(activity); |
| 1081 | |||
| 1082 | if (should_suspend) { | ||
| 1083 | // Wait for execution to stop | ||
| 1084 | for (auto* thread : process->GetThreadList()) { | ||
| 1085 | thread->WaitUntilSuspended(); | ||
| 1086 | } | ||
| 1087 | } | ||
| 1081 | } | 1088 | } |
| 1082 | } | 1089 | } |
| 1083 | 1090 | ||