diff options
author | Jean-Baptiste Boric <jblbeurope@gmail.com> | 2021-07-24 16:42:39 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-07 11:48:00 +0200 |
commit | 019ad8a507aaed2475aa179da3ffeecbf57feac7 (patch) | |
tree | 485a7e3378cfd6b80fc33cd70385608569011f9e /Kernel/Locking | |
parent | 3d684316c2d2361730e1f546971a94107a1f13ea (diff) | |
download | serenity-019ad8a507aaed2475aa179da3ffeecbf57feac7.zip |
Kernel: Introduce spin-locked contended and locked resource concepts
Diffstat (limited to 'Kernel/Locking')
-rw-r--r-- | Kernel/Locking/SpinLockProtectedValue.h | 64 | ||||
-rw-r--r-- | Kernel/Locking/SpinLockResource.h | 53 |
2 files changed, 117 insertions, 0 deletions
diff --git a/Kernel/Locking/SpinLockProtectedValue.h b/Kernel/Locking/SpinLockProtectedValue.h new file mode 100644 index 0000000000..e4af19d8a3 --- /dev/null +++ b/Kernel/Locking/SpinLockProtectedValue.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <Kernel/Locking/SpinLockResource.h> + +namespace Kernel { + +template<typename T> +class SpinLockProtectedValue : private T + , public SpinLockContendedResource { + AK_MAKE_NONCOPYABLE(SpinLockProtectedValue); + AK_MAKE_NONMOVABLE(SpinLockProtectedValue); + +protected: + using LockedConst = SpinLockLockedResource<T const>; + using LockedMutable = SpinLockLockedResource<T>; + + LockedConst lock_const() const { return LockedConst(static_cast<T const*>(this), this->SpinLockContendedResource::m_spinlock); } + LockedMutable lock_mutable() { return LockedMutable(static_cast<T*>(this), this->SpinLockContendedResource::m_spinlock); } + +public: + using T::T; + + SpinLockProtectedValue() = default; + + template<typename Callback> + decltype(auto) with(Callback callback) const + { + auto lock = lock_const(); + return callback(*lock); + } + + template<typename Callback> + decltype(auto) with(Callback callback) + { + auto lock = lock_mutable(); + return callback(*lock); + } + + template<typename Callback> + void for_each_const(Callback callback) const + { + with([&](const auto& value) { + for (auto& item : value) + callback(item); + }); + } + + template<typename Callback> + void for_each(Callback callback) + { + with([&](auto& value) { + for (auto& item : value) + callback(item); + }); + } +}; + +} diff --git a/Kernel/Locking/SpinLockResource.h b/Kernel/Locking/SpinLockResource.h new file mode 100644 index 0000000000..f8d23b5da0 --- /dev/null +++ b/Kernel/Locking/SpinLockResource.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/StdLibExtras.h> +#include <Kernel/Locking/SpinLock.h> + +namespace Kernel { + +template<typename T> +class SpinLockLockedResource { + AK_MAKE_NONCOPYABLE(SpinLockLockedResource); + +public: + SpinLockLockedResource(T* value, RecursiveSpinLock& spinlock) + : m_value(value) + , m_scoped_spinlock(spinlock) + { + } + + ALWAYS_INLINE T const* operator->() const { return m_value; } + ALWAYS_INLINE T const& operator*() const { return *m_value; } + + ALWAYS_INLINE T* operator->() { return m_value; } + ALWAYS_INLINE T& operator*() { return *m_value; } + + ALWAYS_INLINE T const* get() const { return m_value; } + ALWAYS_INLINE T* get() { return m_value; } + +private: + T* m_value; + ScopedSpinLock<RecursiveSpinLock> m_scoped_spinlock; +}; + +class SpinLockContendedResource { + template<typename> + friend class SpinLockLockedResource; + + AK_MAKE_NONCOPYABLE(SpinLockContendedResource); + AK_MAKE_NONMOVABLE(SpinLockContendedResource); + +public: + SpinLockContendedResource() = default; + +protected: + mutable RecursiveSpinLock m_spinlock; +}; + +} |