From 2e7214b6fa5c392eb42d69d0fd39c006a02f030c Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 13 Oct 2020 23:07:51 -0700 Subject: [PATCH] kern: perform rescheduling on dispatch re-enable (closes #1169) --- .../include/mesosphere/kern_k_scheduler.hpp | 4 ++- .../include/mesosphere/kern_k_thread.hpp | 15 +--------- .../source/kern_k_scoped_disable_dispatch.cpp | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 libraries/libmesosphere/source/kern_k_scoped_disable_dispatch.cpp 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(); + } + } + +}