diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp
index b38956fb2..885c1d07e 100644
--- a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp
+++ b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp
@@ -48,6 +48,7 @@ namespace ams::kern {
private:
friend class KScopedSchedulerLock;
friend class KScopedSchedulerLockAndSleep;
+ friend class KScopedDisableDispatch;
private:
SchedulingState state;
bool is_active;
@@ -161,8 +162,9 @@ namespace ams::kern {
}
ALWAYS_INLINE void ScheduleOnInterrupt() {
- KScopedDisableDispatch dd;
+ GetCurrentThread().DisableDispatch();
this->Schedule();
+ GetCurrentThread().EnableDispatch();
}
void RescheduleOtherCores(u64 cores_needing_scheduling);
diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp
index a7f36f95b..357e8d085 100644
--- a/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp
+++ b/libraries/libmesosphere/include/mesosphere/kern_k_thread.hpp
@@ -559,20 +559,7 @@ namespace ams::kern {
GetCurrentThread().DisableDispatch();
}
- ALWAYS_INLINE ~KScopedDisableDispatch() {
- GetCurrentThread().EnableDispatch();
- }
- };
-
- class KScopedEnableDispatch {
- public:
- explicit ALWAYS_INLINE KScopedEnableDispatch() {
- GetCurrentThread().EnableDispatch();
- }
-
- ALWAYS_INLINE ~KScopedEnableDispatch() {
- GetCurrentThread().DisableDispatch();
- }
+ ~KScopedDisableDispatch();
};
ALWAYS_INLINE KExceptionContext *GetExceptionContext(KThread *thread) {
diff --git a/libraries/libmesosphere/source/kern_k_scoped_disable_dispatch.cpp b/libraries/libmesosphere/source/kern_k_scoped_disable_dispatch.cpp
new file mode 100644
index 000000000..413390577
--- /dev/null
+++ b/libraries/libmesosphere/source/kern_k_scoped_disable_dispatch.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018-2020 Atmosphère-NX
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include
+
+namespace ams::kern {
+
+ KScopedDisableDispatch::~KScopedDisableDispatch() {
+ if (GetCurrentThread().GetDisableDispatchCount() <= 1) {
+ Kernel::GetScheduler().RescheduleCurrentCore();
+ } else {
+ GetCurrentThread().EnableDispatch();
+ }
+ }
+
+}