From 334c454eec8ba958d8625c091de87cb9fc7d0254 Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Mon, 26 Dec 2016 10:33:23 +0100 Subject: [PATCH] concurrency_util: Mutex wrapper --- include/utils/concurrency.hpp | 94 +++++++++++++++++------------------ src/utils/concurrency.cpp | 19 +++++-- 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/include/utils/concurrency.hpp b/include/utils/concurrency.hpp index 69186925..3fde2613 100644 --- a/include/utils/concurrency.hpp +++ b/include/utils/concurrency.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -10,6 +11,8 @@ POLYBAR_NS +namespace chrono =std::chrono; +using namespace std::chrono_literals; namespace this_thread = std::this_thread; using std::atomic; @@ -17,57 +20,50 @@ using std::map; using std::mutex; using std::thread; -namespace concurrency_util { - namespace locking_strategy { - struct no_backoff { - bool operator()() { - return true; - } - }; - - struct yield_backoff { - bool operator()() { - this_thread::yield(); - return false; - } - }; - } - - class spin_lock : public non_copyable_mixin { - public: - /** - * Construct spin_lock - */ - spin_lock() = default; - - /** - * Lock using custom strategy - */ - template - void lock(Backoff backoff) noexcept { - while (m_locked.test_and_set(std::memory_order_acquire)) { - backoff(); - } - } - - /** - * Lock using default strategy - */ - void lock() noexcept { - lock(locking_strategy::no_backoff{}); - } - - /** - * Unlock - */ - void unlock() noexcept { - m_locked.clear(std::memory_order_release); - } - - protected: - std::atomic_flag m_locked{false}; +class spin_lock : public non_copyable_mixin { + public: + struct no_backoff_strategy { + bool operator()(); + }; + struct yield_backoff_strategy { + bool operator()(); }; + public: + explicit spin_lock() = default; + + template + void lock(Backoff backoff) noexcept { + while (m_locked.test_and_set(std::memory_order_acquire)) { + backoff(); + } + } + + void lock() noexcept; + void unlock() noexcept; + + protected: + std::atomic_flag m_locked{false}; +}; + +template +class mutex_wrapper : public T { + public: + template + explicit mutex_wrapper(Args&&... args) : T(forward(args)...) {} + + void lock() const noexcept { + m_mtx.lock(); + } + void unlock() const noexcept { + m_mtx.unlock(); + }; + + private: + mutable mutex m_mtx; +}; + +namespace concurrency_util { size_t thread_id(const thread::id id); } diff --git a/src/utils/concurrency.cpp b/src/utils/concurrency.cpp index 058aa5c5..ee320aff 100644 --- a/src/utils/concurrency.cpp +++ b/src/utils/concurrency.cpp @@ -2,12 +2,25 @@ POLYBAR_NS +bool spin_lock::no_backoff_strategy::operator()() { + return true; +} +bool spin_lock::yield_backoff_strategy::operator()() { + this_thread::yield(); + return false; +} +void spin_lock::lock() noexcept { + lock(no_backoff_strategy{}); +} +void spin_lock::unlock() noexcept { + m_locked.clear(std::memory_order_release); +} + namespace concurrency_util { size_t thread_id(const thread::id id) { static size_t idx{1_z}; - static mutex mtx; - static map ids; - std::lock_guard lock(mtx); + static mutex_wrapper> ids; + std::lock_guard lock(ids); if (ids.find(id) == ids.end()) { ids[id] = idx++; }