diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp index d6097fd54..5de6009d8 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_light_lock.hpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace ams::kern { @@ -60,18 +61,6 @@ namespace ams::kern { void UnlockSlowPath(uintptr_t cur_thread); }; - class KScopedLightLock { - private: - KLightLock *lock; - public: - explicit ALWAYS_INLINE KScopedLightLock(KLightLock *l) : lock(l) { - this->lock->Lock(); - } - ALWAYS_INLINE ~KScopedLightLock() { - this->lock->Unlock(); - } - - explicit ALWAYS_INLINE KScopedLightLock(KLightLock &l) : KScopedLightLock(std::addressof(l)) { /* ... */ } - }; + using KScopedLightLock = KScopedLock; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp index 19639f326..756adac62 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler.hpp @@ -63,10 +63,8 @@ namespace ams::kern { static void EnableSchedulingAndSchedule(u64 cores_needing_scheduling); }; - class KScopedSchedulerLock { - public: - ALWAYS_INLINE KScopedSchedulerLock() { KScheduler::s_scheduler_lock.Lock(); } - ALWAYS_INLINE ~KScopedSchedulerLock() { KScheduler::s_scheduler_lock.Unlock(); } + class KScopedSchedulerLock : KScopedLock { + explicit ALWAYS_INLINE KScopedSchedulerLock() : KScopedLock(KScheduler::s_scheduler_lock) { /* ... */ } }; } diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler_lock.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler_lock.hpp index 5c951a438..251ba310c 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_scheduler_lock.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_scheduler_lock.hpp @@ -17,6 +17,7 @@ #include #include #include +#include namespace ams::kern { diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_scoped_lock.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_scoped_lock.hpp new file mode 100644 index 000000000..63d35b788 --- /dev/null +++ b/libraries/libmesosphere/include/mesosphere/kern_k_scoped_lock.hpp @@ -0,0 +1,44 @@ +/* + * 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 . + */ +#pragma once +#include + +namespace ams::kern { + + /* + TODO: C++20 + + template + concept KLockable = !std::is_reference::value && requires (T &t) { + { t.Lock() } -> std::same_as; + { t.Unlock() } -> std::same_as; + }; + + */ + + template /* TODO C++20: requires KLockable */ + class KScopedLock { + NON_COPYABLE(KScopedLock); + NON_MOVEABLE(KScopedLock); + private: + T *lock_ptr; + public: + explicit ALWAYS_INLINE KScopedLock(T *l) : lock_ptr(l) { this->lock_ptr->Lock(); } + explicit ALWAYS_INLINE KScopedLock(T &l) : KScopedLock(std::addressof(l)) { /* ... */} + ALWAYS_INLINE ~KScopedLock() { this->lock_ptr->Unlock(); } + }; + +} diff --git a/libraries/libmesosphere/include/mesosphere/kern_k_spin_lock.hpp b/libraries/libmesosphere/include/mesosphere/kern_k_spin_lock.hpp index c1088a3b8..3dec44cdf 100644 --- a/libraries/libmesosphere/include/mesosphere/kern_k_spin_lock.hpp +++ b/libraries/libmesosphere/include/mesosphere/kern_k_spin_lock.hpp @@ -15,6 +15,7 @@ */ #pragma once #include +#include #if defined(ATMOSPHERE_ARCH_ARM64) @@ -34,45 +35,8 @@ namespace ams::kern { - class KScopedSpinLock { - private: - KSpinLock *lock_ptr; - public: - explicit ALWAYS_INLINE KScopedSpinLock(KSpinLock *l) : lock_ptr(l) { - this->lock_ptr->Lock(); - } - ALWAYS_INLINE ~KScopedSpinLock() { - this->lock_ptr->Unlock(); - } - - explicit ALWAYS_INLINE KScopedSpinLock(KSpinLock &l) : KScopedSpinLock(std::addressof(l)) { /* ... */ } - }; - - class KScopedAlignedSpinLock { - private: - KAlignedSpinLock *lock_ptr; - public: - explicit ALWAYS_INLINE KScopedAlignedSpinLock(KAlignedSpinLock *l) : lock_ptr(l) { - this->lock_ptr->Lock(); - } - ALWAYS_INLINE ~KScopedAlignedSpinLock() { - this->lock_ptr->Unlock(); - } - explicit ALWAYS_INLINE KScopedAlignedSpinLock(KAlignedSpinLock &l) : KScopedAlignedSpinLock(std::addressof(l)) { /* ... */ } - }; - - class KScopedNotAlignedSpinLock { - private: - KNotAlignedSpinLock *lock_ptr; - public: - explicit ALWAYS_INLINE KScopedNotAlignedSpinLock(KNotAlignedSpinLock *l) : lock_ptr(l) { - this->lock_ptr->Lock(); - } - ALWAYS_INLINE ~KScopedNotAlignedSpinLock() { - this->lock_ptr->Unlock(); - } - - explicit ALWAYS_INLINE KScopedNotAlignedSpinLock(KNotAlignedSpinLock &l) : KScopedNotAlignedSpinLock(std::addressof(l)) { /* ... */ } - }; + using KScopedSpinLock = KScopedLock; + using KScopedAlignedSpinLock = KScopedLock; + using KScopedNotAlignedSpinLock = KScopedLock; }