diff options
| author | 2020-11-21 02:22:03 -0800 | |
|---|---|---|
| committer | 2020-11-24 15:25:39 -0800 | |
| commit | 3359e5ab70d5c1a5d29a6bdf1d57df6ab616f592 (patch) | |
| tree | 645810758403970f6894160192dd6dc7dad61b8a /src/core/cpu_manager.cpp | |
| parent | hle: services: Fix a crash with improper NVFlinger lifetime management. (#4977) (diff) | |
| download | yuzu-3359e5ab70d5c1a5d29a6bdf1d57df6ab616f592.tar.gz yuzu-3359e5ab70d5c1a5d29a6bdf1d57df6ab616f592.tar.xz yuzu-3359e5ab70d5c1a5d29a6bdf1d57df6ab616f592.zip | |
core: cpu_manager: Fix shutdown crash when closing before emulation starts.
Diffstat (limited to 'src/core/cpu_manager.cpp')
| -rw-r--r-- | src/core/cpu_manager.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 983210197..100e90d82 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/fiber.h" | 5 | #include "common/fiber.h" |
| 6 | #include "common/microprofile.h" | 6 | #include "common/microprofile.h" |
| 7 | #include "common/scope_exit.h" | ||
| 7 | #include "common/thread.h" | 8 | #include "common/thread.h" |
| 8 | #include "core/arm/exclusive_monitor.h" | 9 | #include "core/arm/exclusive_monitor.h" |
| 9 | #include "core/core.h" | 10 | #include "core/core.h" |
| @@ -343,6 +344,16 @@ void CpuManager::RunThread(std::size_t core) { | |||
| 343 | data.initialized = true; | 344 | data.initialized = true; |
| 344 | const bool sc_sync = !is_async_gpu && !is_multicore; | 345 | const bool sc_sync = !is_async_gpu && !is_multicore; |
| 345 | bool sc_sync_first_use = sc_sync; | 346 | bool sc_sync_first_use = sc_sync; |
| 347 | |||
| 348 | // Cleanup | ||
| 349 | SCOPE_EXIT({ | ||
| 350 | data.host_context->Exit(); | ||
| 351 | data.enter_barrier.reset(); | ||
| 352 | data.exit_barrier.reset(); | ||
| 353 | data.initialized = false; | ||
| 354 | MicroProfileOnThreadExit(); | ||
| 355 | }); | ||
| 356 | |||
| 346 | /// Running | 357 | /// Running |
| 347 | while (running_mode) { | 358 | while (running_mode) { |
| 348 | data.is_running = false; | 359 | data.is_running = false; |
| @@ -351,6 +362,12 @@ void CpuManager::RunThread(std::size_t core) { | |||
| 351 | system.GPU().ObtainContext(); | 362 | system.GPU().ObtainContext(); |
| 352 | sc_sync_first_use = false; | 363 | sc_sync_first_use = false; |
| 353 | } | 364 | } |
| 365 | |||
| 366 | // Abort if emulation was killed before the session really starts | ||
| 367 | if (!system.IsPoweredOn()) { | ||
| 368 | return; | ||
| 369 | } | ||
| 370 | |||
| 354 | auto& scheduler = system.Kernel().CurrentScheduler(); | 371 | auto& scheduler = system.Kernel().CurrentScheduler(); |
| 355 | Kernel::Thread* current_thread = scheduler.GetCurrentThread(); | 372 | Kernel::Thread* current_thread = scheduler.GetCurrentThread(); |
| 356 | data.is_running = true; | 373 | data.is_running = true; |
| @@ -360,13 +377,6 @@ void CpuManager::RunThread(std::size_t core) { | |||
| 360 | data.exit_barrier->Wait(); | 377 | data.exit_barrier->Wait(); |
| 361 | data.is_paused = false; | 378 | data.is_paused = false; |
| 362 | } | 379 | } |
| 363 | /// Time to cleanup | ||
| 364 | data.host_context->Exit(); | ||
| 365 | data.enter_barrier.reset(); | ||
| 366 | data.exit_barrier.reset(); | ||
| 367 | data.initialized = false; | ||
| 368 | |||
| 369 | MicroProfileOnThreadExit(); | ||
| 370 | } | 380 | } |
| 371 | 381 | ||
| 372 | } // namespace Core | 382 | } // namespace Core |