Add KInterruptSpinLock, which is what is really used in the official kernel

This commit is contained in:
TuxSH 2018-11-08 00:11:30 +01:00 committed by Michael Scire
parent 7b726c3184
commit 4238d2e97f
6 changed files with 108 additions and 9 deletions

View file

@ -15,13 +15,26 @@ inline namespace arm64
class KInterruptMaskGuard final {
public:
using FlagsType = u64;
KInterruptMaskGuard()
{
flags = MESOSPHERE_READ_SYSREG(daif);
MESOSPHERE_WRITE_SYSREG(flags | PSR_I_BIT, daif);
flags = MaskInterrupts();
}
~KInterruptMaskGuard()
{
RestoreInterrupts(flags);
}
static FlagsType MaskInterrupts()
{
FlagsType flags = MESOSPHERE_READ_SYSREG(daif);
MESOSPHERE_WRITE_SYSREG(flags | PSR_I_BIT, daif);
return flags;
}
static void RestoreInterrupts(FlagsType flags)
{
MESOSPHERE_WRITE_SYSREG(MESOSPHERE_READ_SYSREG(daif) | (flags & PSR_I_BIT), daif);
}
@ -32,7 +45,7 @@ class KInterruptMaskGuard final {
KInterruptMaskGuard &operator=(KInterruptMaskGuard &&) = delete;
private:
u64 flags;
FlagsType flags;
};
}

View file

@ -10,7 +10,7 @@ inline namespace arm64
{
// This largely uses the Linux kernel spinlock code, which is more efficient than Nintendo's (serializing two u16s into an u32).
class KSpinLock final {
class KSpinLock {
private:

View file

@ -2,7 +2,7 @@
#include <mesosphere/interfaces/IInterruptibleWork.hpp>
#include <mesosphere/interfaces/IAlarmable.hpp>
#include <mesosphere/arch/KSpinLock.hpp>
#include <mesosphere/interrupts/KInterruptSpinLock.hpp>
#include <mesosphere/board/KSystemClock.hpp>
namespace mesosphere
@ -27,7 +27,7 @@ class KAlarm final : public IInterruptibleWork {
KAlarm &operator=(KAlarm &&) = delete;
private:
KSpinLock spinlock{};
mutable KInterruptSpinLock<false> spinlock{};
AlarmableSetType alarmables{};
};

View file

@ -0,0 +1,86 @@
#pragma once
#include <mesosphere/core/KCoreContext.hpp>
#include <mesosphere/arch/KInterruptMaskGuard.hpp>
#include <mesosphere/arch/KSpinLock.hpp>
namespace mesosphere
{
class KThread;
inline void IncrementThreadInterruptBottomHalfLockCount(KThread &thread);
inline void DecrementThreadInterruptBottomHalfLockCount(KThread &thread);
template<bool disableInterrupts = false>
class KInterruptSpinLock final : public KSpinLock {
public:
bool try_lock()
{
KThread *curThread = KCoreContext::GetCurrentInstance().GetCurrentThread();
IncrementThreadInterruptBottomHalfLockCount(*curThread);
if (!KSpinLock::try_lock()) {
DecrementThreadInterruptBottomHalfLockCount(*curThread);
return false;
}
return true;
}
void lock()
{
KThread *curThread = KCoreContext::GetCurrentInstance().GetCurrentThread();
IncrementThreadInterruptBottomHalfLockCount(*curThread);
KSpinLock::lock();
}
void unlock()
{
KThread *curThread = KCoreContext::GetCurrentInstance().GetCurrentThread();
KSpinLock::unlock();
DecrementThreadInterruptBottomHalfLockCount(*curThread);
}
KInterruptSpinLock() = default;
KInterruptSpinLock(const KInterruptSpinLock &) = delete;
KInterruptSpinLock(KInterruptSpinLock &&) = delete;
KInterruptSpinLock &operator=(const KInterruptSpinLock &) = delete;
KInterruptSpinLock &operator=(KInterruptSpinLock &&) = delete;
};
template<>
class KInterruptSpinLock<true> final : public KSpinLock {
public:
bool try_lock()
{
flags = KInterruptMaskGuard::MaskInterrupts();
if (!KSpinLock::try_lock()) {
KInterruptMaskGuard::RestoreInterrupts(flags);
return false;
}
return true;
}
void lock()
{
flags = KInterruptMaskGuard::MaskInterrupts();
KSpinLock::lock();
}
void unlock()
{
KSpinLock::unlock();
KInterruptMaskGuard::RestoreInterrupts(flags);
}
KInterruptSpinLock() = default;
KInterruptSpinLock(const KInterruptSpinLock &) = delete;
KInterruptSpinLock(KInterruptSpinLock &&) = delete;
KInterruptSpinLock &operator=(const KInterruptSpinLock &) = delete;
KInterruptSpinLock &operator=(KInterruptSpinLock &&) = delete;
private:
typename KInterruptMaskGuard::FlagsType flags;
};
}

View file

@ -64,7 +64,7 @@ class KObjectAllocator {
private:
AllocatedSetType allocatedSet{};
KSlabHeap<T> slabHeap{};
KMutex mutex{};
mutable KMutex mutex{};
};
}

View file

@ -4,7 +4,7 @@
#include <mesosphere/core/Handle.hpp>
#include <mesosphere/core/Result.hpp>
#include <mesosphere/core/KAutoObject.hpp>
#include <mesosphere/arch/KSpinLock.hpp>
#include <mesosphere/interrupts/KInterruptSpinLock.hpp>
#include <array>
#include <tuple>
@ -72,7 +72,7 @@ class KHandleTable final {
u16 numActive = 0, size = 0, capacity = 0;
mutable KSpinLock spinlock;
mutable KInterruptSpinLock<false> spinlock;
};
}