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

@@ -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;
};
}