From 4af450141b960666d2aebf164c51170ea9a074df Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 2 Oct 2020 17:41:12 +0200 Subject: [PATCH] Introduce SpinLock --- lib/base/CMakeLists.txt | 1 + lib/base/spinlock.cpp | 22 ++++++++++++++++++++++ lib/base/spinlock.hpp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 lib/base/spinlock.cpp create mode 100644 lib/base/spinlock.hpp diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index 108ca27c1..c1f28a06d 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -64,6 +64,7 @@ set(base_SOURCES shared-object.hpp singleton.hpp socket.cpp socket.hpp + spinlock.cpp spinlock.hpp stacktrace.cpp stacktrace.hpp statsfunction.hpp stdiostream.cpp stdiostream.hpp diff --git a/lib/base/spinlock.cpp b/lib/base/spinlock.cpp new file mode 100644 index 000000000..03de2e6be --- /dev/null +++ b/lib/base/spinlock.cpp @@ -0,0 +1,22 @@ +/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */ + +#include "base/spinlock.hpp" +#include + +using namespace icinga; + +void SpinLock::lock() +{ + while (m_Locked.test_and_set(std::memory_order_acquire)) { + } +} + +bool SpinLock::try_lock() +{ + return !m_Locked.test_and_set(std::memory_order_acquire); +} + +void SpinLock::unlock() +{ + m_Locked.clear(std::memory_order_release); +} diff --git a/lib/base/spinlock.hpp b/lib/base/spinlock.hpp new file mode 100644 index 000000000..d6da5876e --- /dev/null +++ b/lib/base/spinlock.hpp @@ -0,0 +1,35 @@ +/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */ + +#ifndef SPINLOCK_H +#define SPINLOCK_H + +#include + +namespace icinga +{ + +/** + * A spin lock. + * + * @ingroup base + */ +class SpinLock +{ +public: + SpinLock() = default; + SpinLock(const SpinLock&) = delete; + SpinLock& operator=(const SpinLock&) = delete; + SpinLock(SpinLock&&) = delete; + SpinLock& operator=(SpinLock&&) = delete; + + void lock(); + bool try_lock(); + void unlock(); + +private: + std::atomic_flag m_Locked = ATOMIC_FLAG_INIT; +}; + +} + +#endif /* SPINLOCK_H */