mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 18:54:14 +01:00 
			
		
		
		
	general: improve handling of system startup failure
This commit is contained in:
		
							parent
							
								
									08d4e7c7af
								
							
						
					
					
						commit
						9704acb982
					
				| @ -11,6 +11,7 @@ | ||||
| #include <mutex> | ||||
| #include <thread> | ||||
| #include "common/common_types.h" | ||||
| #include "common/polyfill_thread.h" | ||||
| 
 | ||||
| namespace Common { | ||||
| 
 | ||||
| @ -69,7 +70,7 @@ public: | ||||
|     explicit Barrier(std::size_t count_) : count(count_) {} | ||||
| 
 | ||||
|     /// Blocks until all "count" threads have called Sync()
 | ||||
|     void Sync() { | ||||
|     bool Sync(std::stop_token token = {}) { | ||||
|         std::unique_lock lk{mutex}; | ||||
|         const std::size_t current_generation = generation; | ||||
| 
 | ||||
| @ -77,14 +78,16 @@ public: | ||||
|             generation++; | ||||
|             waiting = 0; | ||||
|             condvar.notify_all(); | ||||
|             return true; | ||||
|         } else { | ||||
|             condvar.wait(lk, | ||||
|                          [this, current_generation] { return current_generation != generation; }); | ||||
|             CondvarWait(condvar, lk, token, | ||||
|                         [this, current_generation] { return current_generation != generation; }); | ||||
|             return !token.stop_requested(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     std::condition_variable condvar; | ||||
|     std::condition_variable_any condvar; | ||||
|     std::mutex mutex; | ||||
|     std::size_t count; | ||||
|     std::size_t waiting = 0; | ||||
|  | ||||
| @ -389,7 +389,9 @@ struct System::Impl { | ||||
|         kernel.ShutdownCores(); | ||||
|         cpu_manager.Shutdown(); | ||||
|         debugger.reset(); | ||||
|         services->KillNVNFlinger(); | ||||
|         if (services) { | ||||
|             services->KillNVNFlinger(); | ||||
|         } | ||||
|         kernel.CloseServices(); | ||||
|         services.reset(); | ||||
|         service_manager.reset(); | ||||
|  | ||||
| @ -20,23 +20,20 @@ namespace Core { | ||||
| CpuManager::CpuManager(System& system_) : system{system_} {} | ||||
| CpuManager::~CpuManager() = default; | ||||
| 
 | ||||
| void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, | ||||
|                              std::size_t core) { | ||||
|     cpu_manager.RunThread(core); | ||||
| } | ||||
| 
 | ||||
| void CpuManager::Initialize() { | ||||
|     num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1; | ||||
|     gpu_barrier = std::make_unique<Common::Barrier>(num_cores + 1); | ||||
| 
 | ||||
|     for (std::size_t core = 0; core < num_cores; core++) { | ||||
|         core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); | ||||
|         core_data[core].host_thread = | ||||
|             std::jthread([this, core](std::stop_token token) { RunThread(token, core); }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void CpuManager::Shutdown() { | ||||
|     for (std::size_t core = 0; core < num_cores; core++) { | ||||
|         if (core_data[core].host_thread.joinable()) { | ||||
|             core_data[core].host_thread.request_stop(); | ||||
|             core_data[core].host_thread.join(); | ||||
|         } | ||||
|     } | ||||
| @ -184,7 +181,7 @@ void CpuManager::ShutdownThread() { | ||||
|     UNREACHABLE(); | ||||
| } | ||||
| 
 | ||||
| void CpuManager::RunThread(std::size_t core) { | ||||
| void CpuManager::RunThread(std::stop_token token, std::size_t core) { | ||||
|     /// Initialization
 | ||||
|     system.RegisterCoreThread(core); | ||||
|     std::string name; | ||||
| @ -206,7 +203,9 @@ void CpuManager::RunThread(std::size_t core) { | ||||
|     }); | ||||
| 
 | ||||
|     // Running
 | ||||
|     gpu_barrier->Sync(); | ||||
|     if (!gpu_barrier->Sync(token)) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (!is_async_gpu && !is_multicore) { | ||||
|         system.GPU().ObtainContext(); | ||||
|  | ||||
| @ -81,12 +81,10 @@ private: | ||||
|     void SingleCoreRunGuestThread(); | ||||
|     void SingleCoreRunIdleThread(); | ||||
| 
 | ||||
|     static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core); | ||||
| 
 | ||||
|     void GuestActivate(); | ||||
|     void HandleInterrupt(); | ||||
|     void ShutdownThread(); | ||||
|     void RunThread(std::size_t core); | ||||
|     void RunThread(std::stop_token stop_token, std::size_t core); | ||||
| 
 | ||||
|     struct CoreData { | ||||
|         std::shared_ptr<Common::Fiber> host_context; | ||||
|  | ||||
| @ -104,12 +104,16 @@ struct KernelCore::Impl { | ||||
|     } | ||||
| 
 | ||||
|     void CloseCurrentProcess() { | ||||
|         (*current_process).Finalize(); | ||||
|         // current_process->Close();
 | ||||
|         // TODO: The current process should be destroyed based on accurate ref counting after
 | ||||
|         KProcess* old_process = current_process.exchange(nullptr); | ||||
|         if (old_process == nullptr) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // old_process->Close();
 | ||||
|         // TODO: The process should be destroyed based on accurate ref counting after
 | ||||
|         // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
 | ||||
|         (*current_process).Destroy(); | ||||
|         current_process = nullptr; | ||||
|         old_process->Finalize(); | ||||
|         old_process->Destroy(); | ||||
|     } | ||||
| 
 | ||||
|     void Shutdown() { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user