summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2018-12-29 13:27:21 +0100
committerStanislaw Halik <sthalik@misaki.pl>2019-01-16 07:48:18 +0100
commite9bbb68829e972df2e458aa5beec0568d4737f02 (patch)
treeb305103d53214dcddb76c1f26738d334972b17d3
parenta1a9a091093c9fb711a1665de9f4d46ae5c5ab67 (diff)
compat/spinlock: implement and use it
-rw-r--r--compat/check-visible.cpp37
-rw-r--r--compat/check-visible.hpp6
-rw-r--r--compat/spinlock.hpp30
-rw-r--r--dinput/dinput.cpp17
-rw-r--r--dinput/dinput.hpp4
-rw-r--r--gui/init.cpp9
-rw-r--r--tracker-pt/ftnoir_tracker_pt.cpp12
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;
}