diff options
author | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2023-11-16 17:24:02 +0300 |
---|---|---|
committer | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2023-11-16 18:51:45 +0300 |
commit | 6b40f0f1060a3e9d54347e52c7dc8fb278e6e86b (patch) | |
tree | da4c8447ff495a023682292e1ac90309312ddb8f /library/cpp/yt/threading/traceless_guard-inl.h | |
parent | 8f8023320207d4dfa6e9b6c595fe272382595cdd (diff) | |
download | ydb-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.h | 115 |
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 |