mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-22 06:36:10 +00:00
Add KInterruptSpinLock, which is what is really used in the official kernel
This commit is contained in:
parent
7b726c3184
commit
4238d2e97f
6 changed files with 108 additions and 9 deletions
|
@ -15,13 +15,26 @@ inline namespace arm64
|
||||||
class KInterruptMaskGuard final {
|
class KInterruptMaskGuard final {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
using FlagsType = u64;
|
||||||
|
|
||||||
KInterruptMaskGuard()
|
KInterruptMaskGuard()
|
||||||
{
|
{
|
||||||
flags = MESOSPHERE_READ_SYSREG(daif);
|
flags = MaskInterrupts();
|
||||||
MESOSPHERE_WRITE_SYSREG(flags | PSR_I_BIT, daif);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~KInterruptMaskGuard()
|
~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);
|
MESOSPHERE_WRITE_SYSREG(MESOSPHERE_READ_SYSREG(daif) | (flags & PSR_I_BIT), daif);
|
||||||
}
|
}
|
||||||
|
@ -32,7 +45,7 @@ class KInterruptMaskGuard final {
|
||||||
KInterruptMaskGuard &operator=(KInterruptMaskGuard &&) = delete;
|
KInterruptMaskGuard &operator=(KInterruptMaskGuard &&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u64 flags;
|
FlagsType flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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).
|
// 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:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <mesosphere/interfaces/IInterruptibleWork.hpp>
|
#include <mesosphere/interfaces/IInterruptibleWork.hpp>
|
||||||
#include <mesosphere/interfaces/IAlarmable.hpp>
|
#include <mesosphere/interfaces/IAlarmable.hpp>
|
||||||
#include <mesosphere/arch/KSpinLock.hpp>
|
#include <mesosphere/interrupts/KInterruptSpinLock.hpp>
|
||||||
#include <mesosphere/board/KSystemClock.hpp>
|
#include <mesosphere/board/KSystemClock.hpp>
|
||||||
|
|
||||||
namespace mesosphere
|
namespace mesosphere
|
||||||
|
@ -27,7 +27,7 @@ class KAlarm final : public IInterruptibleWork {
|
||||||
KAlarm &operator=(KAlarm &&) = delete;
|
KAlarm &operator=(KAlarm &&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KSpinLock spinlock{};
|
mutable KInterruptSpinLock<false> spinlock{};
|
||||||
AlarmableSetType alarmables{};
|
AlarmableSetType alarmables{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ class KObjectAllocator {
|
||||||
private:
|
private:
|
||||||
AllocatedSetType allocatedSet{};
|
AllocatedSetType allocatedSet{};
|
||||||
KSlabHeap<T> slabHeap{};
|
KSlabHeap<T> slabHeap{};
|
||||||
KMutex mutex{};
|
mutable KMutex mutex{};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#include <mesosphere/core/Handle.hpp>
|
#include <mesosphere/core/Handle.hpp>
|
||||||
#include <mesosphere/core/Result.hpp>
|
#include <mesosphere/core/Result.hpp>
|
||||||
#include <mesosphere/core/KAutoObject.hpp>
|
#include <mesosphere/core/KAutoObject.hpp>
|
||||||
#include <mesosphere/arch/KSpinLock.hpp>
|
#include <mesosphere/interrupts/KInterruptSpinLock.hpp>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class KHandleTable final {
|
||||||
|
|
||||||
u16 numActive = 0, size = 0, capacity = 0;
|
u16 numActive = 0, size = 0, capacity = 0;
|
||||||
|
|
||||||
mutable KSpinLock spinlock;
|
mutable KInterruptSpinLock<false> spinlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue