summaryrefslogtreecommitdiffstats
path: root/library/cpp/threading
diff options
context:
space:
mode:
authorkulikov <[email protected]>2025-11-28 00:32:45 +0300
committerkulikov <[email protected]>2025-11-28 00:47:44 +0300
commit909e306757b2da405daed2e0838e11b65e033c1a (patch)
treeede331912522813f6f0f60f594306feaa9589b30 /library/cpp/threading
parent2a1c1d7670e335bc967a309eda2e0beac81332d7 (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.cpp22
-rw-r--r--library/cpp/threading/thread_local/generic.h8
-rw-r--r--library/cpp/threading/thread_local/thread_local.h32
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()};
};