serenity/Kernel/Locking/Spinlock.h
James Mintram e8f09279d3 Kernel: Move spinlock into Arch
Spinlocks are tied to the platform they are built for, this is why they
have been moved into the Arch folder. They are still available via
"Locking/Spinlock.h"

An Aarch64 stub has been created
2021-10-15 21:48:45 +01:00

78 lines
1.5 KiB
C++

/*
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Atomic.h>
#include <AK/Types.h>
#include <Kernel/Arch/Spinlock.h>
#include <Kernel/Locking/LockRank.h>
namespace Kernel {
template<typename LockType>
class [[nodiscard]] SpinlockLocker {
AK_MAKE_NONCOPYABLE(SpinlockLocker);
public:
SpinlockLocker() = delete;
SpinlockLocker& operator=(SpinlockLocker&&) = delete;
SpinlockLocker(LockType& lock)
: m_lock(&lock)
{
VERIFY(m_lock);
m_prev_flags = m_lock->lock();
m_have_lock = true;
}
SpinlockLocker(SpinlockLocker&& from)
: m_lock(from.m_lock)
, m_prev_flags(from.m_prev_flags)
, m_have_lock(from.m_have_lock)
{
from.m_lock = nullptr;
from.m_prev_flags = 0;
from.m_have_lock = false;
}
~SpinlockLocker()
{
if (m_lock && m_have_lock) {
m_lock->unlock(m_prev_flags);
}
}
ALWAYS_INLINE void lock()
{
VERIFY(m_lock);
VERIFY(!m_have_lock);
m_prev_flags = m_lock->lock();
m_have_lock = true;
}
ALWAYS_INLINE void unlock()
{
VERIFY(m_lock);
VERIFY(m_have_lock);
m_lock->unlock(m_prev_flags);
m_prev_flags = 0;
m_have_lock = false;
}
[[nodiscard]] ALWAYS_INLINE bool have_lock() const
{
return m_have_lock;
}
private:
LockType* m_lock { nullptr };
u32 m_prev_flags { 0 };
bool m_have_lock { false };
};
}