mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-21 22:26: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 {
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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{};
|
||||
};
|
||||
|
||||
|
|
|
@ -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:
|
||||
AllocatedSetType allocatedSet{};
|
||||
KSlabHeap<T> slabHeap{};
|
||||
KMutex mutex{};
|
||||
mutable KMutex mutex{};
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue