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); |     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); | ||||||
|   | |||||||
| @@ -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; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1078,6 +1078,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(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user