aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/threading/traceless_guard-inl.h
diff options
context:
space:
mode:
authorarkady-e1ppa <arkady-e1ppa@yandex-team.com>2023-11-16 17:24:02 +0300
committerarkady-e1ppa <arkady-e1ppa@yandex-team.com>2023-11-16 18:51:45 +0300
commit6b40f0f1060a3e9d54347e52c7dc8fb278e6e86b (patch)
treeda4c8447ff495a023682292e1ac90309312ddb8f /library/cpp/yt/threading/traceless_guard-inl.h
parent8f8023320207d4dfa6e9b6c595fe272382595cdd (diff)
downloadydb-6b40f0f1060a3e9d54347e52c7dc8fb278e6e86b.tar.gz
Active spinlock tracking from pr3151306. Added TracelessGuards to disable mentioned tracking
1) Добавлена возможность инструментировать ваш любимый мьютекс/спинлок/что-либо с методами Acquire/Release со схожим смыслом. Делается это засчет методов ```NThreading::NDetail::RecordSpinlockAcquired```/```NThreading::NDetail::RecordSpinlockReleased```. Они отслеживают число захваченных спинлоков. 2) Добавлен макрос ```REGISTER_TRACKED_SPIN_LOCK_CLASS```, который позволяет номинально проверить на этапе компиляции, что данный спинлок отслеживается. 3) Добавлен метод ```NThreading::VerifyNoSpinlockAffinity```, который коркается, если число захваченных спинлоков больше нуля. 4) Добавлены Traceless версии (почти) всех гардов, чтобы можно было не отслеживать конкретную критическую секцию, если очень нужно. 5) Внутри файберного ```WaitUntilSet``` вызывается ```VerifyNoSpinlockAffinity``` -- делать ```WaitFor``` или ```Yield``` внутри отслеживаемых критических секций нельзя. Если очень хочется -- используем TracelessGuard нужного вида. 6) Теперь отслеживаются такие спинлоки и их наследники: ```TSpinLock```, ```TRecursiveSpinLock```, ```TReaderWriterSpinLock```. 7) Зарегистрированы как отслеживаемые все вышеперечисленные спинлоки и их Padded версии. 8) Все эти действия имеют эффект только в дебаг сборке. В релизе вся эта диагностика стирается.
Diffstat (limited to 'library/cpp/yt/threading/traceless_guard-inl.h')
-rw-r--r--library/cpp/yt/threading/traceless_guard-inl.h115
1 files changed, 115 insertions, 0 deletions
diff --git a/library/cpp/yt/threading/traceless_guard-inl.h b/library/cpp/yt/threading/traceless_guard-inl.h
new file mode 100644
index 0000000000..e03d5196c4
--- /dev/null
+++ b/library/cpp/yt/threading/traceless_guard-inl.h
@@ -0,0 +1,115 @@
+#pragma once
+
+#ifndef TRACELESS_GUARD_INL_H_
+#error "Direct inclusion of this file is not allowed, include traceless_guard.h"
+#endif
+#undef TRACELESS_GUARD_INL_H_
+
+#include "rw_spin_lock.h"
+#include "spin_lock_count.h"
+
+#include <util/system/guard.h>
+
+#include <concepts>
+
+namespace NYT::NThreading::NPrivate {
+
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef NDEBUG
+
+template <class T, class TOps = TCommonLockOps<T>>
+using TTracelessGuard = TGuard<T, TOps>;
+
+template <class T, class TOps = TCommonLockOps<T>>
+using TTracelessInverseGuard = TInverseGuard<T, TOps>;
+
+template <class T, class TOps = TTryLockOps<T>>
+using TTracelessTryGuard = TTryGuard<T, TOps>;
+
+template <class T>
+using TTracelessReaderGuard = TReaderGuard<T>;
+
+template <class T>
+using TTracelessWriterGuard = TWriterGuard<T>;
+
+#else
+
+template <class TOps>
+struct TTracelessOps
+ : public TOps
+{
+ template <class T>
+ static void Acquire(T* t) noexcept
+ {
+ TOps::Acquire(t);
+ NDetail::RecordSpinLockReleased();
+ }
+
+ template <class T>
+ static void Release(T* t) noexcept
+ {
+ NDetail::RecordSpinLockAcquired();
+ TOps::Release(t);
+ }
+
+ template <class T>
+ requires requires (T* t) { { TOps::TryAcquire(t) } -> std::same_as<bool>; }
+ static bool TryAcquire(T* t) noexcept
+ {
+ bool isAcquired = TOps::TryAcquire(t);
+
+ if (isAcquired) {
+ NDetail::RecordSpinLockReleased();
+ }
+
+ return isAcquired;
+ }
+};
+
+template <CTrackedSpinLock T, class TOps = TCommonLockOps<T>>
+using TTracelessGuard = TGuard<T, TTracelessOps<TOps>>;
+
+template <CTrackedSpinLock T, class TOps = TCommonLockOps<T>>
+using TTracelessInverseGuard = TInverseGuard<T, TTracelessOps<TOps>>;
+
+template <CTrackedSpinLock T, class TOps = TTryLockOps<T>>
+using TTracelessTryGuard = TTryGuard<T, TTracelessOps<TOps>>;
+
+template <CTrackedSpinLock T>
+using TTracelessReaderGuard = TGuard<T, TTracelessOps<TReaderSpinlockTraits<T>>>;
+
+template <CTrackedSpinLock T>
+using TTracelessWriterGuard = TGuard<T, TTracelessOps<TWriterSpinlockTraits<T>>>;
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+template <CTrackedSpinLock T>
+TTracelessGuard<T> TracelessGuard(const T& mutex)
+{
+ return {&mutex};
+}
+
+template <CTrackedSpinLock T>
+TTracelessTryGuard<T> TracelessTryGuard(const T& mutex)
+{
+ return {&mutex};
+}
+
+template <CTrackedSpinLock T>
+TTracelessReaderGuard<T> TracelessReaderGuard(const T& mutex)
+{
+ return {&mutex};
+}
+
+template <CTrackedSpinLock T>
+TTracelessWriterGuard<T> TracelessWriterGuard(const T& mutex)
+{
+ return {&mutex};
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NThreading::NPrivate