From 3ff10baa68f565a8a4fcec18216090f12cd73625 Mon Sep 17 00:00:00 2001 From: FritzFlorian Date: Tue, 16 Apr 2019 11:54:11 +0200 Subject: [PATCH] Add try_lock method to spin_lock implementations. --- lib/pls/include/pls/internal/base/tas_spin_lock.h | 2 +- lib/pls/include/pls/internal/base/ttas_spin_lock.h | 6 ++---- lib/pls/include/pls/internal/helpers/profiler.h | 5 +++++ lib/pls/src/internal/base/tas_spin_lock.cpp | 11 +++++++++-- lib/pls/src/internal/base/ttas_spin_lock.cpp | 17 +++++++++++++++-- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/pls/include/pls/internal/base/tas_spin_lock.h b/lib/pls/include/pls/internal/base/tas_spin_lock.h index 173ee76..17db757 100644 --- a/lib/pls/include/pls/internal/base/tas_spin_lock.h +++ b/lib/pls/include/pls/internal/base/tas_spin_lock.h @@ -28,7 +28,7 @@ namespace pls { tas_spin_lock(const tas_spin_lock& other): flag_{ATOMIC_FLAG_INIT}, yield_at_tries_{other.yield_at_tries_} {} void lock(); - bool try_lock(); + bool try_lock(unsigned int num_tries=1); void unlock(); }; } diff --git a/lib/pls/include/pls/internal/base/ttas_spin_lock.h b/lib/pls/include/pls/internal/base/ttas_spin_lock.h index 821865e..592c847 100644 --- a/lib/pls/include/pls/internal/base/ttas_spin_lock.h +++ b/lib/pls/include/pls/internal/base/ttas_spin_lock.h @@ -2,8 +2,6 @@ #ifndef PLS_TTAS_SPIN_LOCK_H #define PLS_TTAS_SPIN_LOCK_H -#include "tas_spin_lock.h" - #include #include @@ -20,7 +18,7 @@ namespace pls { */ class ttas_spin_lock { std::atomic flag_; - unsigned int yield_at_tries_; + const unsigned int yield_at_tries_; public: @@ -28,7 +26,7 @@ namespace pls { ttas_spin_lock(const ttas_spin_lock& other): flag_{0}, yield_at_tries_{other.yield_at_tries_} {} void lock(); - bool try_lock(); + bool try_lock(unsigned int num_tries=1); void unlock(); }; } diff --git a/lib/pls/include/pls/internal/helpers/profiler.h b/lib/pls/include/pls/internal/helpers/profiler.h index 221994d..2902344 100644 --- a/lib/pls/include/pls/internal/helpers/profiler.h +++ b/lib/pls/include/pls/internal/helpers/profiler.h @@ -4,6 +4,7 @@ #ifdef ENABLE_EASY_PROFILER #include +#include #define PROFILE_WORK_BLOCK(msg) EASY_BLOCK(msg, profiler::colors::LightGreen) #define PROFILE_FORK_JOIN_STEALING(msg) EASY_BLOCK(msg, profiler::colors::LightBlue) @@ -16,6 +17,8 @@ #define PROFILE_ENABLE EASY_PROFILER_ENABLE #define PROFILE_MAIN_THREAD EASY_MAIN_THREAD +#define PROFILE_VALUE(name, value) EASY_VALUE(name, value) + #else //ENABLE_EASY_PROFILER #define PROFILE_WORK_BLOCK(msg) @@ -29,5 +32,7 @@ #define PROFILE_ENABLE #define PROFILE_MAIN_THREAD +#define PROFILE_VALUE(name, value) + #endif //ENABLE_EASY_PROFILER #endif //PLS_PROFILER_H diff --git a/lib/pls/src/internal/base/tas_spin_lock.cpp b/lib/pls/src/internal/base/tas_spin_lock.cpp index 3ad4e42..e6f9d1e 100644 --- a/lib/pls/src/internal/base/tas_spin_lock.cpp +++ b/lib/pls/src/internal/base/tas_spin_lock.cpp @@ -15,8 +15,15 @@ namespace pls { } } - bool tas_spin_lock::try_lock() { - return flag_.test_and_set(std::memory_order_acquire) == 0; + bool tas_spin_lock::try_lock(unsigned int num_tries) { + PROFILE_LOCK("Try Acquire Lock") + while (flag_.test_and_set(std::memory_order_acquire)) { + num_tries--; + if (num_tries <= 0) { + return false; + } + } + return true; } void tas_spin_lock::unlock() { diff --git a/lib/pls/src/internal/base/ttas_spin_lock.cpp b/lib/pls/src/internal/base/ttas_spin_lock.cpp index b60934b..e2c8bff 100644 --- a/lib/pls/src/internal/base/ttas_spin_lock.cpp +++ b/lib/pls/src/internal/base/ttas_spin_lock.cpp @@ -21,9 +21,22 @@ namespace pls { } while (!flag_.compare_exchange_weak(expected, 1, std::memory_order_acquire)); } - bool ttas_spin_lock::try_lock() { + bool ttas_spin_lock::try_lock(unsigned int num_tries) { + PROFILE_LOCK("Try Acquire Lock") int expected = 0; - return flag_.load(std::memory_order_relaxed) == 0 && flag_.compare_exchange_weak(expected, 1, std::memory_order_acquire); + + do { + while (flag_.load(std::memory_order_relaxed) == 1) { + num_tries--; + if (num_tries <= 0) { + return false; + } + } + + expected = 0; + } while (!flag_.compare_exchange_weak(expected, 1, std::memory_order_acquire)); + + return true; } void ttas_spin_lock::unlock() { -- libgit2 0.26.0