/* * Copyright (c) 2020, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Kernel { template 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 }; }; }