diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2018-12-29 13:27:21 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2019-01-16 07:48:18 +0100 |
commit | e9bbb68829e972df2e458aa5beec0568d4737f02 (patch) | |
tree | b305103d53214dcddb76c1f26738d334972b17d3 | |
parent | a1a9a091093c9fb711a1665de9f4d46ae5c5ab67 (diff) |
compat/spinlock: implement and use it
-rw-r--r-- | compat/check-visible.cpp | 37 | ||||
-rw-r--r-- | compat/check-visible.hpp | 6 | ||||
-rw-r--r-- | compat/spinlock.hpp | 30 | ||||
-rw-r--r-- | dinput/dinput.cpp | 17 | ||||
-rw-r--r-- | dinput/dinput.hpp | 4 | ||||
-rw-r--r-- | gui/init.cpp | 9 | ||||
-rw-r--r-- | tracker-pt/ftnoir_tracker_pt.cpp | 12 |
7 files changed, 66 insertions, 49 deletions
diff --git a/compat/check-visible.cpp b/compat/check-visible.cpp index 4cdb1b46..d7f24177 100644 --- a/compat/check-visible.cpp +++ b/compat/check-visible.cpp @@ -1,31 +1,33 @@ #include "check-visible.hpp" -#if defined _WIN32 - +#include "macros.hpp" #include "timer.hpp" -#include "math.hpp" +#include "spinlock.hpp" -#include <QMutex> +#include <QWidget> #include <QDebug> -#include <windows.h> - constexpr int visible_timeout = 1000; constexpr int invisible_timeout = 250; static Timer timer; -static QMutex mtx; +static std::atomic_flag lock = ATOMIC_FLAG_INIT; static bool visible = true; +#if defined _WIN32 + +#include <windows.h> + void set_is_visible(const QWidget& w, bool force) { - QMutexLocker l(&mtx); + spinlock_guard l(lock); + + HWND hwnd = (HWND)w.winId(); if (!force && timer.elapsed_ms() < (visible ? visible_timeout : invisible_timeout)) return; timer.start(); - HWND hwnd = (HWND)w.winId(); if (RECT r; GetWindowRect(hwnd, &r)) { @@ -56,22 +58,21 @@ void set_is_visible(const QWidget& w, bool force) } } -bool check_is_visible() -{ - QMutexLocker l(&mtx); - - return visible; -} - #else void set_is_visible(const QWidget&, bool) { } -bool check_is_visible() +void check_is_visible(bool) { - return true; } #endif + +bool check_is_visible() +{ + spinlock_guard l(lock); + return visible; +} + diff --git a/compat/check-visible.hpp b/compat/check-visible.hpp index e24a654b..5b194c7c 100644 --- a/compat/check-visible.hpp +++ b/compat/check-visible.hpp @@ -1,12 +1,12 @@ #pragma once #include "export.hpp" -#include "macros.hpp" +#include "macros1.h" -#include <QWidget> +class QWidget; cc_noinline OTR_COMPAT_EXPORT void set_is_visible(QWidget const& w, bool force = false); -cc_noinline OTR_COMPAT_EXPORT +OTR_COMPAT_EXPORT bool check_is_visible(); diff --git a/compat/spinlock.hpp b/compat/spinlock.hpp new file mode 100644 index 00000000..7e4cd8cf --- /dev/null +++ b/compat/spinlock.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "macros1.h" +#include <atomic> + +struct spinlock_guard final +{ + spinlock_guard(const spinlock_guard&) = delete; + spinlock_guard& operator=(const spinlock_guard&) = delete; + constexpr spinlock_guard(spinlock_guard&&) noexcept = default; + + cc_forceinline + spinlock_guard(std::atomic_flag* lock) noexcept : spinlock_guard(*lock) {} + + cc_forceinline + spinlock_guard(std::atomic_flag& lock) noexcept : lock(lock) + { + while (lock.test_and_set(std::memory_order_acquire)) + (void)0; + } + + cc_forceinline + ~spinlock_guard() noexcept + { + lock.clear(std::memory_order_release); + } + +private: + std::atomic_flag& lock; +}; diff --git a/dinput/dinput.cpp b/dinput/dinput.cpp index 3931255b..75f398ad 100644 --- a/dinput/dinput.cpp +++ b/dinput/dinput.cpp @@ -1,8 +1,9 @@ #include "dinput.hpp" +#include "compat/spinlock.hpp" #include <QDebug> -std::atomic<int> di_t::refcnt; -std::atomic_flag di_t::init_lock = ATOMIC_FLAG_INIT; +int di_t::refcnt{0}; +std::atomic_flag di_t::lock = ATOMIC_FLAG_INIT; diptr di_t::handle; diptr di_t::init_di_() @@ -32,30 +33,24 @@ di_t::di_t() void di_t::ref_di() { - while (init_lock.test_and_set()) - (void)0; + spinlock_guard l(lock); if (!handle) handle = init_di_(); ++refcnt; - - init_lock.clear(); } void di_t::unref_di() { + spinlock_guard l(lock); + const int refcnt_ = --refcnt; if (refcnt_ == 0) { - while (init_lock.test_and_set()) - (void)0; - qDebug() << "exit: di handle"; handle->Release(); - - init_lock.clear(); } } diff --git a/dinput/dinput.hpp b/dinput/dinput.hpp index a9241504..7128229b 100644 --- a/dinput/dinput.hpp +++ b/dinput/dinput.hpp @@ -25,8 +25,8 @@ class OTR_DINPUT_EXPORT di_t final static void ref_di(); static diptr handle; - static std::atomic<int> refcnt; - static std::atomic_flag init_lock; + static int refcnt; + static std::atomic_flag lock; static diptr init_di_(); public: diff --git a/gui/init.cpp b/gui/init.cpp index 9e6b79dc..2b84beef 100644 --- a/gui/init.cpp +++ b/gui/init.cpp @@ -95,7 +95,8 @@ static void set_qt_style() #ifdef _WIN32 -#include <atomic> +#include "compat/spinlock.hpp" + #include <cstring> #include <cwchar> #include <windows.h> @@ -108,14 +109,10 @@ static void qdebug_to_console(QtMsgType, const QMessageLogContext& ctx, const QS if (IsDebuggerPresent()) { static std::atomic_flag lock = ATOMIC_FLAG_INIT; - - while (!lock.test_and_set()) - (void)0; + spinlock_guard l(lock); OutputDebugStringW(str); OutputDebugStringW(L"\n"); - - lock.clear(); } else { diff --git a/tracker-pt/ftnoir_tracker_pt.cpp b/tracker-pt/ftnoir_tracker_pt.cpp index 7589242d..cee9c2a0 100644 --- a/tracker-pt/ftnoir_tracker_pt.cpp +++ b/tracker-pt/ftnoir_tracker_pt.cpp @@ -10,6 +10,7 @@ #include "cv/video-widget.hpp" #include "compat/camera-names.hpp" #include "compat/math-imports.hpp" +#include "compat/spinlock.hpp" #include "pt-api.hpp" @@ -65,8 +66,7 @@ void Tracker_PT::run() if (new_frame) { - while (center_flag.test_and_set()) - (void)0; + spinlock_guard l(center_flag); *preview_frame = *frame; @@ -112,8 +112,6 @@ void Tracker_PT::run() preview_frame = traits->make_preview(w, h); } } - - center_flag.clear(); } } } @@ -189,13 +187,9 @@ void Tracker_PT::data(double *data) bool Tracker_PT::center() { - while (center_flag.test_and_set()) - (void)0; + spinlock_guard l(center_flag); point_tracker.reset_state(); - - center_flag.clear(); - return false; } |