hle: kernel: Add a flag for indicating that the kernel is currently shutting down.
This commit is contained in:
		| @@ -376,11 +376,21 @@ void KScheduler::ClearSchedulerUpdateNeeded(KernelCore& kernel) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void KScheduler::DisableScheduling(KernelCore& kernel) { | void KScheduler::DisableScheduling(KernelCore& kernel) { | ||||||
|  |     // If we are shutting down the kernel, none of this is relevant anymore. | ||||||
|  |     if (kernel.IsShuttingDown()) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     ASSERT(GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() >= 0); |     ASSERT(GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() >= 0); | ||||||
|     GetCurrentThreadPointer(kernel)->DisableDispatch(); |     GetCurrentThreadPointer(kernel)->DisableDispatch(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void KScheduler::EnableScheduling(KernelCore& kernel, u64 cores_needing_scheduling) { | void KScheduler::EnableScheduling(KernelCore& kernel, u64 cores_needing_scheduling) { | ||||||
|  |     // If we are shutting down the kernel, none of this is relevant anymore. | ||||||
|  |     if (kernel.IsShuttingDown()) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     ASSERT(GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() >= 1); |     ASSERT(GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() >= 1); | ||||||
|  |  | ||||||
|     if (GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() > 1) { |     if (GetCurrentThreadPointer(kernel)->GetDisableDispatchCount() > 1) { | ||||||
|   | |||||||
| @@ -23,6 +23,11 @@ public: | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     void Lock() { |     void Lock() { | ||||||
|  |         // If we are shutting down the kernel, none of this is relevant anymore. | ||||||
|  |         if (kernel.IsShuttingDown()) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         if (IsLockedByCurrentThread()) { |         if (IsLockedByCurrentThread()) { | ||||||
|             // If we already own the lock, we can just increment the count. |             // If we already own the lock, we can just increment the count. | ||||||
|             ASSERT(lock_count > 0); |             ASSERT(lock_count > 0); | ||||||
| @@ -43,6 +48,11 @@ public: | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     void Unlock() { |     void Unlock() { | ||||||
|  |         // If we are shutting down the kernel, none of this is relevant anymore. | ||||||
|  |         if (kernel.IsShuttingDown()) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         ASSERT(IsLockedByCurrentThread()); |         ASSERT(IsLockedByCurrentThread()); | ||||||
|         ASSERT(lock_count > 0); |         ASSERT(lock_count > 0); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1089,6 +1089,11 @@ s32 GetCurrentCoreId(KernelCore& kernel) { | |||||||
| } | } | ||||||
|  |  | ||||||
| KScopedDisableDispatch::~KScopedDisableDispatch() { | KScopedDisableDispatch::~KScopedDisableDispatch() { | ||||||
|  |     // If we are shutting down the kernel, none of this is relevant anymore. | ||||||
|  |     if (kernel.IsShuttingDown()) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (GetCurrentThread(kernel).GetDisableDispatchCount() <= 1) { |     if (GetCurrentThread(kernel).GetDisableDispatchCount() <= 1) { | ||||||
|         auto scheduler = kernel.CurrentScheduler(); |         auto scheduler = kernel.CurrentScheduler(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -794,6 +794,10 @@ public: | |||||||
| class KScopedDisableDispatch { | class KScopedDisableDispatch { | ||||||
| public: | public: | ||||||
|     [[nodiscard]] explicit KScopedDisableDispatch(KernelCore& kernel_) : kernel{kernel_} { |     [[nodiscard]] explicit KScopedDisableDispatch(KernelCore& kernel_) : kernel{kernel_} { | ||||||
|  |         // If we are shutting down the kernel, none of this is relevant anymore. | ||||||
|  |         if (kernel.IsShuttingDown()) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         GetCurrentThread(kernel).DisableDispatch(); |         GetCurrentThread(kernel).DisableDispatch(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ | |||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "common/microprofile.h" | #include "common/microprofile.h" | ||||||
|  | #include "common/scope_exit.h" | ||||||
| #include "common/thread.h" | #include "common/thread.h" | ||||||
| #include "common/thread_worker.h" | #include "common/thread_worker.h" | ||||||
| #include "core/arm/arm_interface.h" | #include "core/arm/arm_interface.h" | ||||||
| @@ -90,6 +91,9 @@ struct KernelCore::Impl { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     void Shutdown() { |     void Shutdown() { | ||||||
|  |         is_shutting_down.store(true, std::memory_order_relaxed); | ||||||
|  |         SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); }); | ||||||
|  |  | ||||||
|         process_list.clear(); |         process_list.clear(); | ||||||
|  |  | ||||||
|         // Close all open server ports. |         // Close all open server ports. | ||||||
| @@ -338,7 +342,16 @@ struct KernelCore::Impl { | |||||||
|         is_phantom_mode_for_singlecore = value; |         is_phantom_mode_for_singlecore = value; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     bool IsShuttingDown() const { | ||||||
|  |         return is_shutting_down.load(std::memory_order_relaxed); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     KThread* GetCurrentEmuThread() { |     KThread* GetCurrentEmuThread() { | ||||||
|  |         // If we are shutting down the kernel, none of this is relevant anymore. | ||||||
|  |         if (IsShuttingDown()) { | ||||||
|  |             return {}; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         const auto thread_id = GetCurrentHostThreadID(); |         const auto thread_id = GetCurrentHostThreadID(); | ||||||
|         if (thread_id >= Core::Hardware::NUM_CPU_CORES) { |         if (thread_id >= Core::Hardware::NUM_CPU_CORES) { | ||||||
|             return GetHostDummyThread(); |             return GetHostDummyThread(); | ||||||
| @@ -754,6 +767,7 @@ struct KernelCore::Impl { | |||||||
|     std::vector<std::unique_ptr<KThread>> dummy_threads; |     std::vector<std::unique_ptr<KThread>> dummy_threads; | ||||||
|  |  | ||||||
|     bool is_multicore{}; |     bool is_multicore{}; | ||||||
|  |     std::atomic_bool is_shutting_down{}; | ||||||
|     bool is_phantom_mode_for_singlecore{}; |     bool is_phantom_mode_for_singlecore{}; | ||||||
|     u32 single_core_thread_id{}; |     u32 single_core_thread_id{}; | ||||||
|  |  | ||||||
| @@ -1066,6 +1080,10 @@ bool KernelCore::IsMulticore() const { | |||||||
|     return impl->is_multicore; |     return impl->is_multicore; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool KernelCore::IsShuttingDown() const { | ||||||
|  |     return impl->IsShuttingDown(); | ||||||
|  | } | ||||||
|  |  | ||||||
| void KernelCore::ExceptionalExit() { | void KernelCore::ExceptionalExit() { | ||||||
|     exception_exited = true; |     exception_exited = true; | ||||||
|     Suspend(true); |     Suspend(true); | ||||||
|   | |||||||
| @@ -274,6 +274,8 @@ public: | |||||||
|  |  | ||||||
|     bool IsMulticore() const; |     bool IsMulticore() const; | ||||||
|  |  | ||||||
|  |     bool IsShuttingDown() const; | ||||||
|  |  | ||||||
|     void EnterSVCProfile(); |     void EnterSVCProfile(); | ||||||
|  |  | ||||||
|     void ExitSVCProfile(); |     void ExitSVCProfile(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user