diff options
| author | kulikov <[email protected]> | 2025-11-28 00:32:45 +0300 |
|---|---|---|
| committer | kulikov <[email protected]> | 2025-11-28 00:47:44 +0300 |
| commit | 909e306757b2da405daed2e0838e11b65e033c1a (patch) | |
| tree | ede331912522813f6f0f60f594306feaa9589b30 /library/cpp/threading | |
| parent | 2a1c1d7670e335bc967a309eda2e0beac81332d7 (diff) | |
Use generic thread-local value for kernel/groupattrs, crash context and eventlog scope
- fix StdThreadLocalImpl -- make static state refcounted, there is no guarantee that static fields will outlive threads or TThreadLocalValues;
- replace thread local values to generic local storage value in some places;
- call runtime Init and replace local values factory;
- don't disable NCurrentThreadEventlog for ytxx runtime, it should now work;
- ensure generic local storage values are allocated after runtime init;
- use function-scope static variables to prevent issues with order of construction and destruction;
- basesearch now almost works with coroutines (with NProfile disabled).
commit_hash:7fde81591b0dbc3a53b8d1cb11bb96930a2e9a80
Diffstat (limited to 'library/cpp/threading')
| -rw-r--r-- | library/cpp/threading/thread_local/generic.cpp | 22 | ||||
| -rw-r--r-- | library/cpp/threading/thread_local/generic.h | 8 | ||||
| -rw-r--r-- | library/cpp/threading/thread_local/thread_local.h | 32 |
3 files changed, 44 insertions, 18 deletions
diff --git a/library/cpp/threading/thread_local/generic.cpp b/library/cpp/threading/thread_local/generic.cpp index 41e1b381672..79161a846da 100644 --- a/library/cpp/threading/thread_local/generic.cpp +++ b/library/cpp/threading/thread_local/generic.cpp @@ -14,17 +14,29 @@ namespace { NThreading::TThreadLocalValue<TData, NThreading::EThreadLocalImpl::StdThreadLocal> Data_; }; - NThreading::TGenericLocalStorageFactory genericLocalStorageFactory = []() { - return MakeHolder<TThreadLocalStorage>(); - }; + std::atomic<size_t>& DefaultFactoryUsageCounter() { + static std::atomic<size_t> v; + return v; + } + + auto& genericLocalStorageFactory() { + static NThreading::TGenericLocalStorageFactory factory = [] { + DefaultFactoryUsageCounter() += 1; + return MakeHolder<TThreadLocalStorage>(); + }; + + return factory; + } } namespace NThreading { void SetGenericLocalStorageFactory(TGenericLocalStorageFactory factory) { - genericLocalStorageFactory = factory; + Y_ENSURE(DefaultFactoryUsageCounter() == 0, "There are some thread local values allocated with default factory"); + + genericLocalStorageFactory() = factory; } THolder<IGenericLocalStorage> MakeGenericLocalStorage() { - return genericLocalStorageFactory(); + return genericLocalStorageFactory()(); } } diff --git a/library/cpp/threading/thread_local/generic.h b/library/cpp/threading/thread_local/generic.h index 081562fa830..f60d5b786dd 100644 --- a/library/cpp/threading/thread_local/generic.h +++ b/library/cpp/threading/thread_local/generic.h @@ -4,6 +4,7 @@ #include <util/generic/vector.h> #include <functional> +#include <mutex> namespace NThreading { @@ -62,6 +63,10 @@ namespace NThreading { }; public: T* Get() const { + std::call_once(InitOnce_, [this]() { + Storage_ = MakeGenericLocalStorage(); + }); + return static_cast<T*>(Storage_->GetMemory(Traits())); } @@ -69,7 +74,8 @@ namespace NThreading { return *Get(); } private: - THolder<IGenericLocalStorage> Storage_ = MakeGenericLocalStorage(); + mutable std::once_flag InitOnce_; + mutable THolder<IGenericLocalStorage> Storage_; }; } diff --git a/library/cpp/threading/thread_local/thread_local.h b/library/cpp/threading/thread_local/thread_local.h index af4d7a07cf2..8f8e9aa9517 100644 --- a/library/cpp/threading/thread_local/thread_local.h +++ b/library/cpp/threading/thread_local/thread_local.h @@ -129,8 +129,8 @@ template <typename T, size_t NumShards> class TThreadLocalValue<T, EThreadLocalImpl::StdThreadLocal, NumShards> : private TNonCopyable { public: ~TThreadLocalValue() { - AllValues_.Destroy(ObjectId_); - FlatIds.Put(ObjectId_); + StaticState_->AllValues.Destroy(ObjectId_); + StaticState_->FlatIds.Put(ObjectId_); } template <typename ...ConstructArgs> @@ -156,23 +156,23 @@ public: return &*v; } private: - struct TAllValues; + struct TStaticState; struct TPerThreadValues { TAdaptiveLock Lock; TDeque<TMaybe<T>> Storage; public: - explicit TPerThreadValues(TAllValues* allValues) - : AllValues_(allValues) + explicit TPerThreadValues(TAtomicSharedPtr<TStaticState> staticState) + : StaticState_(std::move(staticState)) { - AllValues_->Add(this); + StaticState_->AllValues.Add(this); } ~TPerThreadValues() { - AllValues_->Remove(this); + StaticState_->AllValues.Remove(this); } private: - TAllValues* const AllValues_; + TAtomicSharedPtr<TStaticState> StaticState_; }; class TFlatIdGenerator { @@ -234,13 +234,21 @@ private: TAdaptiveLock Lock_; THashSet<TPerThreadValues*> Ptrs_; }; +private: + struct TStaticState { + TFlatIdGenerator FlatIds; + TAllValues AllValues; + }; + static TAtomicSharedPtr<TStaticState> GetStaticState() { + static TAtomicSharedPtr<TStaticState> state = MakeAtomicShared<TStaticState>(); + return state; + } private: - static inline TFlatIdGenerator FlatIds; - const ui32 ObjectId_ = FlatIds.Get(); + TAtomicSharedPtr<TStaticState> StaticState_ = GetStaticState(); + const ui32 ObjectId_ = StaticState_->FlatIds.Get(); - static inline TAllValues AllValues_; - static inline thread_local TPerThreadValues Values_{&AllValues_}; + static inline thread_local TPerThreadValues Values_{GetStaticState()}; }; |
