Merge pull request #8483 from liamwhite/fire-emblem-three-semaphores
kernel: wait for threads to stop on pause
This commit is contained in:
		| @@ -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); | ||||
|   | ||||
| @@ -207,6 +207,8 @@ public: | ||||
|  | ||||
|     void Continue(); | ||||
|  | ||||
|     void WaitUntilSuspended(); | ||||
|  | ||||
|     constexpr void SetSyncedIndex(s32 index) { | ||||
|         synced_index = index; | ||||
|     } | ||||
|   | ||||
| @@ -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(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user