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(); + } + } + +}