mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-29 17:54:06 +01:00 
			
		
		
		
	kernel: add and enable system suspend type
This commit is contained in:
		
							parent
							
								
									a40adbc142
								
							
						
					
					
						commit
						af42482565
					
				| @ -242,7 +242,7 @@ struct System::Impl { | ||||
|     void Run() { | ||||
|         std::unique_lock<std::mutex> lk(suspend_guard); | ||||
| 
 | ||||
|         kernel.SuspendApplication(false); | ||||
|         kernel.SuspendEmulation(false); | ||||
|         core_timing.SyncPause(false); | ||||
|         is_paused.store(false, std::memory_order_relaxed); | ||||
|     } | ||||
| @ -251,7 +251,7 @@ struct System::Impl { | ||||
|         std::unique_lock<std::mutex> lk(suspend_guard); | ||||
| 
 | ||||
|         core_timing.SyncPause(true); | ||||
|         kernel.SuspendApplication(true); | ||||
|         kernel.SuspendEmulation(true); | ||||
|         is_paused.store(true, std::memory_order_relaxed); | ||||
|     } | ||||
| 
 | ||||
| @ -261,7 +261,7 @@ struct System::Impl { | ||||
| 
 | ||||
|     std::unique_lock<std::mutex> StallApplication() { | ||||
|         std::unique_lock<std::mutex> lk(suspend_guard); | ||||
|         kernel.SuspendApplication(true); | ||||
|         kernel.SuspendEmulation(true); | ||||
|         core_timing.SyncPause(true); | ||||
|         return lk; | ||||
|     } | ||||
| @ -269,7 +269,7 @@ struct System::Impl { | ||||
|     void UnstallApplication() { | ||||
|         if (!IsPaused()) { | ||||
|             core_timing.SyncPause(false); | ||||
|             kernel.SuspendApplication(false); | ||||
|             kernel.SuspendEmulation(false); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -459,7 +459,7 @@ struct System::Impl { | ||||
|         } | ||||
| 
 | ||||
|         Network::CancelPendingSocketOperations(); | ||||
|         kernel.SuspendApplication(true); | ||||
|         kernel.SuspendEmulation(true); | ||||
|         if (services) { | ||||
|             services->KillNVNFlinger(); | ||||
|         } | ||||
|  | ||||
| @ -66,6 +66,7 @@ enum class SuspendType : u32 { | ||||
|     Debug = 2, | ||||
|     Backtrace = 3, | ||||
|     Init = 4, | ||||
|     System = 5, | ||||
| 
 | ||||
|     Count, | ||||
| }; | ||||
| @ -84,8 +85,9 @@ enum class ThreadState : u16 { | ||||
|     DebugSuspended = (1 << (2 + SuspendShift)), | ||||
|     BacktraceSuspended = (1 << (3 + SuspendShift)), | ||||
|     InitSuspended = (1 << (4 + SuspendShift)), | ||||
|     SystemSuspended = (1 << (5 + SuspendShift)), | ||||
| 
 | ||||
|     SuspendFlagMask = ((1 << 5) - 1) << SuspendShift, | ||||
|     SuspendFlagMask = ((1 << 6) - 1) << SuspendShift, | ||||
| }; | ||||
| DECLARE_ENUM_FLAG_OPERATORS(ThreadState); | ||||
| 
 | ||||
|  | ||||
| @ -1204,39 +1204,48 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const { | ||||
|     return *impl->hidbus_shared_mem; | ||||
| } | ||||
| 
 | ||||
| void KernelCore::SuspendApplication(bool suspended) { | ||||
| void KernelCore::SuspendEmulation(bool suspended) { | ||||
|     const bool should_suspend{exception_exited || suspended}; | ||||
|     const auto activity = | ||||
|         should_suspend ? Svc::ProcessActivity::Paused : Svc::ProcessActivity::Runnable; | ||||
|     auto processes = GetProcessList(); | ||||
| 
 | ||||
|     // Get the application process.
 | ||||
|     KScopedAutoObject<KProcess> process = ApplicationProcess(); | ||||
|     if (process.IsNull()) { | ||||
|     for (auto& process : processes) { | ||||
|         KScopedLightLock ll{process->GetListLock()}; | ||||
| 
 | ||||
|         for (auto& thread : process->GetThreadList()) { | ||||
|             if (should_suspend) { | ||||
|                 thread.RequestSuspend(SuspendType::System); | ||||
|             } else { | ||||
|                 thread.Resume(SuspendType::System); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (!should_suspend) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // Set the new activity.
 | ||||
|     process->SetActivity(activity); | ||||
| 
 | ||||
|     // Wait for process execution to stop.
 | ||||
|     bool must_wait{should_suspend}; | ||||
| 
 | ||||
|     // KernelCore::SuspendApplication must be called from locked context,
 | ||||
|     // or we could race another call to SetActivity, interfering with waiting.
 | ||||
|     while (must_wait) { | ||||
|     // KernelCore::SuspendEmulation must be called from locked context,
 | ||||
|     // or we could race another call, interfering with waiting.
 | ||||
|     const auto TryWait = [&]() { | ||||
|         KScopedSchedulerLock sl{*this}; | ||||
| 
 | ||||
|         // Assume that all threads have finished running.
 | ||||
|         must_wait = false; | ||||
| 
 | ||||
|         for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { | ||||
|             if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == | ||||
|                 process.GetPointerUnsafe()) { | ||||
|                 // A thread has not finished running yet.
 | ||||
|                 // Continue waiting.
 | ||||
|                 must_wait = true; | ||||
|         for (auto& process : processes) { | ||||
|             for (auto i = 0; i < static_cast<s32>(Core::Hardware::NUM_CPU_CORES); ++i) { | ||||
|                 if (Scheduler(i).GetSchedulerCurrentThread()->GetOwnerProcess() == | ||||
|                     process.GetPointerUnsafe()) { | ||||
|                     // A thread has not finished running yet.
 | ||||
|                     // Continue waiting.
 | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
|     }; | ||||
| 
 | ||||
|     while (!TryWait()) { | ||||
|         // ...
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -1260,7 +1269,7 @@ bool KernelCore::IsShuttingDown() const { | ||||
| 
 | ||||
| void KernelCore::ExceptionalExitApplication() { | ||||
|     exception_exited = true; | ||||
|     SuspendApplication(true); | ||||
|     SuspendEmulation(true); | ||||
| } | ||||
| 
 | ||||
| void KernelCore::EnterSVCProfile() { | ||||
|  | ||||
| @ -258,8 +258,8 @@ public: | ||||
|     /// Gets the shared memory object for HIDBus services.
 | ||||
|     const Kernel::KSharedMemory& GetHidBusSharedMem() const; | ||||
| 
 | ||||
|     /// Suspend/unsuspend application process.
 | ||||
|     void SuspendApplication(bool suspend); | ||||
|     /// Suspend/unsuspend emulated processes.
 | ||||
|     void SuspendEmulation(bool suspend); | ||||
| 
 | ||||
|     /// Exceptional exit application process.
 | ||||
|     void ExceptionalExitApplication(); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user