diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-05-06 12:56:16 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-05-06 12:56:16 +0000 |
commit | f92674dbdb92b9e717f952166ffa8307beec4251 (patch) | |
tree | 90180e24c75a6be69d35b81d2ec58395a8380c78 /library/cpp | |
parent | da52d326c570ca0b3284ba4bb5f1a380360afaf5 (diff) | |
parent | 86fa90c3f199cb8af7bb07188a11da49f5e8e984 (diff) | |
download | ydb-f92674dbdb92b9e717f952166ffa8307beec4251.tar.gz |
Merge branch 'rightlib' into mergelibs-240506-1255
Diffstat (limited to 'library/cpp')
25 files changed, 209 insertions, 137 deletions
diff --git a/library/cpp/cache/cache.h b/library/cpp/cache/cache.h index ee65c30d41c..9fe98d53666 100644 --- a/library/cpp/cache/cache.h +++ b/library/cpp/cache/cache.h @@ -124,11 +124,11 @@ public: List.PushBack(item); } - size_t GetSize() const { + [[nodiscard]] size_t GetSize() const { return ItemsAmount; } - size_t GetTotalSize() const { + [[nodiscard]] size_t GetTotalSize() const { return TotalSize; } @@ -157,7 +157,8 @@ public: TLFUList(size_t maxSize, const TSizeProvider& sizeProvider = TSizeProvider()) : List() , SizeProvider(sizeProvider) - , ListSize(0) + , ItemsAmount(0) + , TotalSize(0) , MaxSize(maxSize) { } @@ -228,14 +229,15 @@ public: public: TItem* Insert(TItem* item) { List.PushBack(item); // give a chance for promotion - ListSize += SizeProvider(item->Value); + ++ItemsAmount; + TotalSize += SizeProvider(item->Value); return RemoveIfOverflown(); } TItem* RemoveIfOverflown() { TItem* deleted = nullptr; - if (ListSize > MaxSize) { + if (TotalSize > MaxSize && ItemsAmount > 1) { deleted = GetLeastFrequentlyUsed(); Erase(deleted); } @@ -250,7 +252,8 @@ public: void Erase(TItem* item) { item->Unlink(); - ListSize -= SizeProvider(item->Value); + --ItemsAmount; + TotalSize -= SizeProvider(item->Value); } void Promote(TItem* item) { @@ -262,8 +265,12 @@ public: item->LinkBefore(&*it); } - size_t GetSize() const { - return ListSize; + [[nodiscard]] size_t GetSize() const { + return ItemsAmount; + } + + [[nodiscard]] size_t GetTotalSize() const { + return TotalSize; } size_t GetMaxSize() const { @@ -280,7 +287,8 @@ private: typedef TIntrusiveList<TItem> TListType; TListType List; TSizeProvider SizeProvider; - size_t ListSize; + size_t ItemsAmount; + size_t TotalSize; size_t MaxSize; }; @@ -413,6 +421,10 @@ public: return Size; } + [[nodiscard]] size_t GetTotalSize() const { + return Size; + } + size_t GetMaxSize() const { return MaxSize; } @@ -515,10 +527,14 @@ public: Clear(); } - size_t Size() const { + [[nodiscard]] size_t Size() const { return Index.size(); } + [[nodiscard]] size_t TotalSize() const { + return List.GetTotalSize(); + } + TIterator Begin() const { return TIterator(Index.begin()); } diff --git a/library/cpp/cache/thread_safe_cache.h b/library/cpp/cache/thread_safe_cache.h index 71e14427173..2699c8f7b7f 100644 --- a/library/cpp/cache/thread_safe_cache.h +++ b/library/cpp/cache/thread_safe_cache.h @@ -96,6 +96,16 @@ namespace NPrivate { return TThreadSafeCacheSingleton<TCallbacks>::Clear(); } + size_t Size() const { + TReadGuard r(Mutex); + return Cache.Size(); + } + + size_t TotalSize() const { + TReadGuard r(Mutex); + return Cache.TotalSize(); + } + size_t GetMaxSize() const { TReadGuard w(Mutex); return Cache.GetMaxSize(); diff --git a/library/cpp/cache/ut/cache_ut.cpp b/library/cpp/cache/ut/cache_ut.cpp index 33731988c11..36a3eff0943 100644 --- a/library/cpp/cache/ut/cache_ut.cpp +++ b/library/cpp/cache/ut/cache_ut.cpp @@ -15,10 +15,14 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x1(1, "ttt"); list.Insert(&x1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 1); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); TListType::TItem x2(2, "yyy"); list.Insert(&x2); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); list.Promote(list.GetOldest()); @@ -26,6 +30,8 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x3(3, "zzz"); list.Insert(&x3); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); } @@ -39,12 +45,16 @@ Y_UNIT_TEST_SUITE(TCacheTest) { list.Insert(&x1); while (list.RemoveIfOverflown()) { } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 3); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); TListType::TItem x2(2, "yyy"); list.Insert(&x2); while (list.RemoveIfOverflown()) { } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 6); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); list.Promote(list.GetOldest()); @@ -56,13 +66,25 @@ Y_UNIT_TEST_SUITE(TCacheTest) { list.Insert(&x3); while (list.RemoveIfOverflown()) { } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 6); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); TListType::TItem x4(4, "longlong"); list.Insert(&x4); while (list.RemoveIfOverflown()) { } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 8); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 4); + + TListType::TItem x5(5, "xxx"); + list.Insert(&x5); + while (list.RemoveIfOverflown()) { + } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 3); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); + UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 5); } Y_UNIT_TEST(LFUListTest) { @@ -71,10 +93,14 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x1(1, "ttt"); list.Insert(&x1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 1); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); TListType::TItem x2(2, "yyy"); list.Insert(&x2); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); list.Promote(list.GetLeastFrequentlyUsed()); @@ -82,6 +108,8 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x3(3, "zzz"); list.Insert(&x3); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); } @@ -92,25 +120,30 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x1(1, "tt"); list.Insert(&x1); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 1); UNIT_ASSERT_EQUAL(list.GetSize(), 1); TListType::TItem x2(2, "yyyy"); list.Insert(&x2); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); UNIT_ASSERT_EQUAL(list.GetSize(), 2); TListType::TItem x3(3, "z"); list.Insert(&x3); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); UNIT_ASSERT_EQUAL(list.GetSize(), 2); TListType::TItem x4(4, "xxxxxx"); list.Insert(&x4); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 2); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); UNIT_ASSERT_EQUAL(list.GetSize(), 2); list.Erase(&x2); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 4); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 1); UNIT_ASSERT_EQUAL(list.GetSize(), 1); } @@ -118,11 +151,17 @@ Y_UNIT_TEST_SUITE(TCacheTest) { typedef TLRUCache<int, TString> TCache; TCache s(2); // size 2 s.Insert(1, "abcd"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 1); + UNIT_ASSERT_EQUAL(s.Size(), 1); UNIT_ASSERT(s.Find(1) != s.End()); UNIT_ASSERT_EQUAL(*s.Find(1), "abcd"); s.Insert(2, "defg"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 2); + UNIT_ASSERT_EQUAL(s.Size(), 2); UNIT_ASSERT(s.GetOldest() == "abcd"); s.Insert(3, "hjkl"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 2); + UNIT_ASSERT_EQUAL(s.Size(), 2); UNIT_ASSERT(s.GetOldest() == "defg"); // key 1 will be deleted UNIT_ASSERT(s.Find(1) == s.End()); @@ -135,9 +174,13 @@ Y_UNIT_TEST_SUITE(TCacheTest) { UNIT_ASSERT(*s.Find(3) == "hjkl"); s.Update(3, "abcd"); UNIT_ASSERT(*s.Find(3) == "abcd"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 2); + UNIT_ASSERT_EQUAL(s.Size(), 2); TCache::TIterator it = s.Find(3); s.Erase(it); + UNIT_ASSERT_EQUAL(s.TotalSize(), 1); + UNIT_ASSERT_EQUAL(s.Size(), 1); UNIT_ASSERT(s.Find(3) == s.End()); } @@ -145,13 +188,21 @@ Y_UNIT_TEST_SUITE(TCacheTest) { typedef TLRUCache<int, TString, TNoopDelete, size_t(*)(const TString&)> TCache; TCache s(10, false, [](auto& string) { return string.size(); }); // size 10 s.Insert(1, "abcd"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 4); + UNIT_ASSERT_EQUAL(s.Size(), 1); UNIT_ASSERT(s.Find(1) != s.End()); UNIT_ASSERT_EQUAL(*s.Find(1), "abcd"); s.Insert(2, "defg"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 8); + UNIT_ASSERT_EQUAL(s.Size(), 2); UNIT_ASSERT(s.GetOldest() == "abcd"); s.Insert(3, "2c"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 10); + UNIT_ASSERT_EQUAL(s.Size(), 3); UNIT_ASSERT(s.GetOldest() == "abcd"); s.Insert(4, "hjkl"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 10); + UNIT_ASSERT_EQUAL(s.Size(), 3); UNIT_ASSERT(s.GetOldest() == "defg"); // key 1 will be deleted UNIT_ASSERT(s.Find(1) == s.End()); @@ -165,10 +216,14 @@ Y_UNIT_TEST_SUITE(TCacheTest) { UNIT_ASSERT(!s.Insert(3, "abcd")); UNIT_ASSERT(*s.Find(3) == "2c"); s.Update(3, "abcd"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 8); + UNIT_ASSERT_EQUAL(s.Size(), 2); UNIT_ASSERT(*s.Find(3) == "abcd"); TCache::TIterator it = s.Find(3); s.Erase(it); + UNIT_ASSERT_EQUAL(s.TotalSize(), 4); + UNIT_ASSERT_EQUAL(s.Size(), 1); UNIT_ASSERT(s.Find(3) == s.End()); } @@ -317,10 +372,14 @@ Y_UNIT_TEST_SUITE(TCacheTest) { UNIT_ASSERT(s.Insert(1, "abcd")); UNIT_ASSERT(s.Insert(1, "bcde")); UNIT_ASSERT(s.Insert(2, "fghi")); - UNIT_ASSERT(s.Insert(2, "ghij")); // (1, "abcd") will be deleted - UNIT_ASSERT(*s.Find(1) == "bcde"); + UNIT_ASSERT(s.Insert(2, "ghij")); + + UNIT_ASSERT_EQUAL(s.TotalSize(), 3); + UNIT_ASSERT_EQUAL(s.Size(), 3); + // (1, "bcde") will be promoted + UNIT_ASSERT(*s.Find(1) == "bcde"); UNIT_ASSERT(*s.FindOldest() == "fghi"); } @@ -449,6 +508,8 @@ Y_UNIT_TEST_SUITE(TThreadSafeCacheTest) { cache.Update(2, MakeAtomicShared<TString>("hjk")); item = cache.Get(2); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 1); + UNIT_ASSERT_EQUAL(cache.Size(), 1); UNIT_ASSERT(callbacks.Creations == 0); UNIT_ASSERT(*item == "hjk"); } @@ -484,6 +545,8 @@ Y_UNIT_TEST_SUITE(TThreadSafeCacheUnsafeTest) { UNIT_ASSERT(*data == VALS[i]); } } + UNIT_ASSERT_EQUAL(cache.TotalSize(), Y_ARRAY_SIZE(VALS) - 1); + UNIT_ASSERT_EQUAL(cache.Size(), Y_ARRAY_SIZE(VALS) - 1); } } @@ -532,6 +595,8 @@ Y_UNIT_TEST_SUITE(TThreadSafeLRUCacheTest) { cache.Update(2, MakeAtomicShared<TString>("hjk")); item = cache.Get(2); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 1); + UNIT_ASSERT_EQUAL(cache.Size(), 1); UNIT_ASSERT(callbacks.Creations == 0); UNIT_ASSERT(*item == "hjk"); } @@ -630,17 +695,23 @@ Y_UNIT_TEST_SUITE(TThreadSafeLRUCacheTest) { UNIT_ASSERT_EQUAL(callbacks.Creations, expectedCreations); UNIT_ASSERT(*item == "one"); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 3); + UNIT_ASSERT_EQUAL(cache.Size(), 3); cache.SetMaxSize(4); item = cache.Get(0); expectedCreations++; UNIT_ASSERT_EQUAL(callbacks.Creations, expectedCreations); UNIT_ASSERT(*item == "zero"); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 4); + UNIT_ASSERT_EQUAL(cache.Size(), 4); item = cache.Get(4); expectedCreations++; UNIT_ASSERT_EQUAL(callbacks.Creations, expectedCreations); UNIT_ASSERT(*item == "four"); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 4); + UNIT_ASSERT_EQUAL(cache.Size(), 4); item = cache.Get(3); expectedCreations++; diff --git a/library/cpp/sanitizer/address/dynamic/ya.make b/library/cpp/sanitizer/address/dynamic/ya.make index c8928494147..4d76cb57f56 100644 --- a/library/cpp/sanitizer/address/dynamic/ya.make +++ b/library/cpp/sanitizer/address/dynamic/ya.make @@ -1,6 +1,6 @@ DYNAMIC_LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/sanitizer/address/static/ya.make b/library/cpp/sanitizer/address/static/ya.make index ddbd90f2f98..d8cf24a8487 100644 --- a/library/cpp/sanitizer/address/static/ya.make +++ b/library/cpp/sanitizer/address/static/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/sanitizer/leak/dynamic/ya.make b/library/cpp/sanitizer/leak/dynamic/ya.make index 79dcd4ad376..f52f739c770 100644 --- a/library/cpp/sanitizer/leak/dynamic/ya.make +++ b/library/cpp/sanitizer/leak/dynamic/ya.make @@ -1,6 +1,6 @@ DYNAMIC_LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/sanitizer/leak/static/ya.make b/library/cpp/sanitizer/leak/static/ya.make index 0d5a8fdfd76..27005709fee 100644 --- a/library/cpp/sanitizer/leak/static/ya.make +++ b/library/cpp/sanitizer/leak/static/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/sanitizer/memory/static/ya.make b/library/cpp/sanitizer/memory/static/ya.make index e6bb9c8c756..ab10fb9c88d 100644 --- a/library/cpp/sanitizer/memory/static/ya.make +++ b/library/cpp/sanitizer/memory/static/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/sanitizer/thread/dynamic/ya.make b/library/cpp/sanitizer/thread/dynamic/ya.make index 4d15cb066e5..84d4db4b408 100644 --- a/library/cpp/sanitizer/thread/dynamic/ya.make +++ b/library/cpp/sanitizer/thread/dynamic/ya.make @@ -1,6 +1,6 @@ DYNAMIC_LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/sanitizer/thread/static/ya.make b/library/cpp/sanitizer/thread/static/ya.make index f5bc931a51c..0a09b0098cc 100644 --- a/library/cpp/sanitizer/thread/static/ya.make +++ b/library/cpp/sanitizer/thread/static/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/sanitizer/undefined/dynamic/ya.make b/library/cpp/sanitizer/undefined/dynamic/ya.make index 330018d006e..7b3778f85a3 100644 --- a/library/cpp/sanitizer/undefined/dynamic/ya.make +++ b/library/cpp/sanitizer/undefined/dynamic/ya.make @@ -1,6 +1,6 @@ DYNAMIC_LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/sanitizer/undefined/static/ya.make b/library/cpp/sanitizer/undefined/static/ya.make index bab3149e740..3077d8ee56d 100644 --- a/library/cpp/sanitizer/undefined/static/ya.make +++ b/library/cpp/sanitizer/undefined/static/ya.make @@ -1,6 +1,6 @@ LIBRARY() -OWNER(g:devtools-contrib) +SUBSCRIBER(g:devtools-contrib) NO_UTIL() diff --git a/library/cpp/tld/tlds-alpha-by-domain.txt b/library/cpp/tld/tlds-alpha-by-domain.txt index 24c895894d1..29dc81150d7 100644 --- a/library/cpp/tld/tlds-alpha-by-domain.txt +++ b/library/cpp/tld/tlds-alpha-by-domain.txt @@ -1,4 +1,4 @@ -# Version 2024041900, Last Updated Fri Apr 19 07:07:01 2024 UTC +# Version 2024050100, Last Updated Wed May 1 07:07:01 2024 UTC AAA AARP ABB diff --git a/library/cpp/yt/cpu_clock/clock.cpp b/library/cpp/yt/cpu_clock/clock.cpp index 0ed65e3b920..22f665e1d35 100644 --- a/library/cpp/yt/cpu_clock/clock.cpp +++ b/library/cpp/yt/cpu_clock/clock.cpp @@ -31,18 +31,16 @@ double GetTicksToMicroseconds() return TicksToMicroseconds; } -TCalibrationState GetCalibrationState(TCpuInstant cpuInstant) +YT_PREVENT_TLS_CACHING TCalibrationState GetCalibrationState(TCpuInstant cpuInstant) { - YT_THREAD_LOCAL(TCalibrationState) State; + thread_local TCalibrationState State; - auto& state = GetTlsRef(State); - - if (state.CpuInstant + CalibrationCpuPeriod < cpuInstant) { - state.CpuInstant = cpuInstant; - state.Instant = TInstant::Now(); + if (State.CpuInstant + CalibrationCpuPeriod < cpuInstant) { + State.CpuInstant = cpuInstant; + State.Instant = TInstant::Now(); } - return state; + return State; } TCalibrationState GetCalibrationState() diff --git a/library/cpp/yt/logging/logger-inl.h b/library/cpp/yt/logging/logger-inl.h index 5e2b6795dcc..d076b3690eb 100644 --- a/library/cpp/yt/logging/logger-inl.h +++ b/library/cpp/yt/logging/logger-inl.h @@ -90,20 +90,8 @@ protected: void DoReserve(size_t newLength) override; private: - struct TPerThreadCache - { - ~TPerThreadCache(); - - TSharedMutableRef Chunk; - size_t ChunkOffset = 0; - }; - TSharedMutableRef Buffer_; - static YT_THREAD_LOCAL(TPerThreadCache*) Cache_; - static YT_THREAD_LOCAL(bool) CacheDestroyed_; - static TPerThreadCache* GetCache(); - static constexpr size_t ChunkSize = 128_KB - 64; }; diff --git a/library/cpp/yt/logging/logger.cpp b/library/cpp/yt/logging/logger.cpp index c11457f836f..58add384296 100644 --- a/library/cpp/yt/logging/logger.cpp +++ b/library/cpp/yt/logging/logger.cpp @@ -34,15 +34,45 @@ TSharedRef TMessageStringBuilder::Flush() return Buffer_.Slice(0, GetLength()); } -void TMessageStringBuilder::DisablePerThreadCache() +void TMessageStringBuilder::DoReset() { - Cache_ = nullptr; - CacheDestroyed_ = true; + Buffer_.Reset(); } -void TMessageStringBuilder::DoReset() +struct TPerThreadCache; + +YT_DEFINE_THREAD_LOCAL(TPerThreadCache*, Cache); +YT_DEFINE_THREAD_LOCAL(bool, CacheDestroyed); + +struct TPerThreadCache { - Buffer_.Reset(); + TSharedMutableRef Chunk; + size_t ChunkOffset = 0; + + ~TPerThreadCache() + { + TMessageStringBuilder::DisablePerThreadCache(); + } + + static YT_PREVENT_TLS_CACHING TPerThreadCache* GetCache() + { + auto& cache = Cache(); + if (Y_LIKELY(cache)) { + return cache; + } + if (CacheDestroyed()) { + return nullptr; + } + static thread_local TPerThreadCache CacheData; + cache = &CacheData; + return cache; + } +}; + +void TMessageStringBuilder::DisablePerThreadCache() +{ + Cache() = nullptr; + CacheDestroyed() = true; } void TMessageStringBuilder::DoReserve(size_t newCapacity) @@ -53,7 +83,7 @@ void TMessageStringBuilder::DoReserve(size_t newCapacity) auto newChunkSize = std::max(ChunkSize, newCapacity); // Hold the old buffer until the data is copied. auto oldBuffer = std::move(Buffer_); - auto* cache = GetCache(); + auto* cache = TPerThreadCache::GetCache(); if (Y_LIKELY(cache)) { auto oldCapacity = End_ - Begin_; auto deltaCapacity = newCapacity - oldCapacity; @@ -85,27 +115,6 @@ void TMessageStringBuilder::DoReserve(size_t newCapacity) End_ = Begin_ + newCapacity; } -TMessageStringBuilder::TPerThreadCache* TMessageStringBuilder::GetCache() -{ - if (Y_LIKELY(Cache_)) { - return Cache_; - } - if (CacheDestroyed_) { - return nullptr; - } - static YT_THREAD_LOCAL(TPerThreadCache) Cache; - Cache_ = &GetTlsRef(Cache); - return Cache_; -} - -TMessageStringBuilder::TPerThreadCache::~TPerThreadCache() -{ - TMessageStringBuilder::DisablePerThreadCache(); -} - -YT_THREAD_LOCAL(TMessageStringBuilder::TPerThreadCache*) TMessageStringBuilder::Cache_; -YT_THREAD_LOCAL(bool) TMessageStringBuilder::CacheDestroyed_; - } // namespace NDetail //////////////////////////////////////////////////////////////////////////////// @@ -126,16 +135,16 @@ Y_WEAK ILogManager* GetDefaultLogManager() //////////////////////////////////////////////////////////////////////////////// -YT_THREAD_LOCAL(ELogLevel) ThreadMinLogLevel = ELogLevel::Minimum; +YT_DEFINE_THREAD_LOCAL(ELogLevel, ThreadMinLogLevel, ELogLevel::Minimum); void SetThreadMinLogLevel(ELogLevel minLogLevel) { - ThreadMinLogLevel = minLogLevel; + ThreadMinLogLevel() = minLogLevel; } ELogLevel GetThreadMinLogLevel() { - return ThreadMinLogLevel; + return ThreadMinLogLevel(); } //////////////////////////////////////////////////////////////////////////////// @@ -173,7 +182,7 @@ bool TLogger::IsLevelEnabledHeavy(ELogLevel level) const return level >= Category_->MinPlainTextLevel && - level >= ThreadMinLogLevel; + level >= ThreadMinLogLevel(); } bool TLogger::GetAbortOnAlert() const diff --git a/library/cpp/yt/logging/logger.h b/library/cpp/yt/logging/logger.h index 082afcddd8c..0913b9ea08a 100644 --- a/library/cpp/yt/logging/logger.h +++ b/library/cpp/yt/logging/logger.h @@ -324,8 +324,8 @@ void LogStructuredEvent( break; \ } \ \ - static YT_THREAD_LOCAL(i64) localByteCounter__; \ - static YT_THREAD_LOCAL(ui8) localMessageCounter__; \ + static thread_local i64 localByteCounter__; \ + static thread_local ui8 localMessageCounter__; \ \ localByteCounter__ += message__.MessageRef.Size(); \ if (Y_UNLIKELY(++localMessageCounter__ == 0)) { \ diff --git a/library/cpp/yt/memory/memory_tag.cpp b/library/cpp/yt/memory/memory_tag.cpp index ebb0b433700..ee6a1a4ad0c 100644 --- a/library/cpp/yt/memory/memory_tag.cpp +++ b/library/cpp/yt/memory/memory_tag.cpp @@ -8,16 +8,16 @@ namespace NYT { //////////////////////////////////////////////////////////////////////////////// -YT_THREAD_LOCAL(TMemoryTag) CurrentMemoryTag; +YT_DEFINE_THREAD_LOCAL(TMemoryTag, CurrentMemoryTag); Y_WEAK TMemoryTag GetCurrentMemoryTag() { - return CurrentMemoryTag; + return CurrentMemoryTag(); } Y_WEAK void SetCurrentMemoryTag(TMemoryTag tag) { - CurrentMemoryTag = tag; + CurrentMemoryTag() = tag; } Y_WEAK size_t GetMemoryUsageForTag(TMemoryTag /*tag*/) diff --git a/library/cpp/yt/memory/tls_scratch-inl.h b/library/cpp/yt/memory/tls_scratch-inl.h index 32c26d67c08..0b4ef29bea7 100644 --- a/library/cpp/yt/memory/tls_scratch-inl.h +++ b/library/cpp/yt/memory/tls_scratch-inl.h @@ -6,21 +6,23 @@ #include <library/cpp/yt/misc/tls.h> +#include <util/generic/bitops.h> + namespace NYT { //////////////////////////////////////////////////////////////////////////////// template <class T> -TMutableRange<T> GetTlsScratchBuffer(size_t size) +YT_PREVENT_TLS_CACHING TMutableRange<T> GetTlsScratchBuffer(size_t size) { - // This is a workround for std::vector<bool>. - using TBoxed = std::array<T, 1>; - YT_THREAD_LOCAL(std::vector<TBoxed>) tlsVector; - auto& vector = GetTlsRef(tlsVector); - vector.reserve(size); - auto range = TMutableRange(reinterpret_cast<T*>(vector.data()), size); - std::fill(range.begin(), range.end(), T()); - return range; + thread_local std::unique_ptr<T[]> scratchBuffer; + thread_local size_t scratchBufferSize; + if (scratchBufferSize < size) { + scratchBufferSize = FastClp2(size); + scratchBuffer = std::unique_ptr<T[]>(new T[scratchBufferSize]); + } + std::fill(scratchBuffer.get(), scratchBuffer.get() + size, T()); + return TMutableRange(scratchBuffer.get(), size); } //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/misc/thread_name.cpp b/library/cpp/yt/misc/thread_name.cpp index d59043db51e..bb1737b08ad 100644 --- a/library/cpp/yt/misc/thread_name.cpp +++ b/library/cpp/yt/misc/thread_name.cpp @@ -29,19 +29,18 @@ TThreadName::TThreadName(const TString& name) //////////////////////////////////////////////////////////////////////////////// // This function uses cached TThread::CurrentThreadName() result -TThreadName GetCurrentThreadName() +YT_PREVENT_TLS_CACHING TThreadName GetCurrentThreadName() { - static YT_THREAD_LOCAL(TThreadName) ThreadName; - auto& threadName = GetTlsRef(ThreadName); + static thread_local TThreadName ThreadName; - if (threadName.Length == 0) { + if (ThreadName.Length == 0) { if (auto name = TThread::CurrentThreadName()) { auto length = std::min<int>(TThreadName::BufferCapacity - 1, name.length()); - threadName.Length = length; - ::memcpy(threadName.Buffer.data(), name.data(), length); + ThreadName.Length = length; + ::memcpy(ThreadName.Buffer.data(), name.data(), length); } } - return threadName; + return ThreadName; } //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/misc/tls-inl.h b/library/cpp/yt/misc/tls-inl.h deleted file mode 100644 index 51ef91517f9..00000000000 --- a/library/cpp/yt/misc/tls-inl.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef TLS_INL_H_ -#error "Direct inclusion of this file is not allowed, include tls.h" -// For the sake of sane code completion. -#include "tls.h" -#endif - -namespace NYT { - -//////////////////////////////////////////////////////////////////////////////// - -template <class T> -T& GetTlsRef(volatile T& arg) -{ - return const_cast<T&>(arg); -} -//////////////////////////////////////////////////////////////////////////////// - -} // namespace NYT diff --git a/library/cpp/yt/misc/tls.h b/library/cpp/yt/misc/tls.h index d1bda8ac684..a0656dedc15 100644 --- a/library/cpp/yt/misc/tls.h +++ b/library/cpp/yt/misc/tls.h @@ -2,21 +2,17 @@ #include <util/system/compiler.h> -// Workaround for fiber (un)friendly TLS. -// Volatile qualifier prevents caching access to thread local variables. -#define YT_THREAD_LOCAL(...) thread_local __VA_ARGS__ volatile - -namespace NYT { - -//////////////////////////////////////////////////////////////////////////////// +#define YT_PREVENT_TLS_CACHING Y_NO_INLINE -template <class T> -Y_FORCE_INLINE T& GetTlsRef(volatile T& arg); - -//////////////////////////////////////////////////////////////////////////////// +// Workaround for fiber (un)friendly TLS. +#define YT_DECLARE_THREAD_LOCAL(type, name) \ + type& name(); -} // namespace NYT +#define YT_DEFINE_THREAD_LOCAL(type, name, ...) \ + thread_local type name##Data { __VA_ARGS__ }; \ + Y_NO_INLINE type& name() \ + { \ + asm volatile(""); \ + return name##Data; \ + } -#define TLS_INL_H_ -#include "tls-inl.h" -#undef TLS_INL_H_ diff --git a/library/cpp/yt/system/thread_id-inl.h b/library/cpp/yt/system/thread_id-inl.h index 73434145e34..916d70436ed 100644 --- a/library/cpp/yt/system/thread_id-inl.h +++ b/library/cpp/yt/system/thread_id-inl.h @@ -14,15 +14,16 @@ namespace NYT { //////////////////////////////////////////////////////////////////////////////// -extern YT_THREAD_LOCAL(TSequentialThreadId) CachedSequentialThreadId; +YT_DECLARE_THREAD_LOCAL(TSequentialThreadId, CachedSequentialThreadId); extern std::atomic<TSequentialThreadId> SequentialThreadIdGenerator; inline TSequentialThreadId GetSequentialThreadId() { - if (Y_UNLIKELY(CachedSequentialThreadId == InvalidSequentialThreadId)) { - CachedSequentialThreadId = ++SequentialThreadIdGenerator; + auto& cachedSequentialThreadId = CachedSequentialThreadId(); + if (Y_UNLIKELY(cachedSequentialThreadId == InvalidSequentialThreadId)) { + cachedSequentialThreadId = ++SequentialThreadIdGenerator; } - return CachedSequentialThreadId; + return cachedSequentialThreadId; } //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/system/thread_id.cpp b/library/cpp/yt/system/thread_id.cpp index 1ecf1fe9bd6..a1971dd0dd8 100644 --- a/library/cpp/yt/system/thread_id.cpp +++ b/library/cpp/yt/system/thread_id.cpp @@ -6,7 +6,7 @@ namespace NYT { //////////////////////////////////////////////////////////////////////////////// -YT_THREAD_LOCAL(TSequentialThreadId) CachedSequentialThreadId = InvalidSequentialThreadId; +YT_DEFINE_THREAD_LOCAL(TSequentialThreadId, CachedSequentialThreadId, InvalidSequentialThreadId); std::atomic<TSequentialThreadId> SequentialThreadIdGenerator = InvalidSequentialThreadId; TSystemThreadId GetSystemThreadId() diff --git a/library/cpp/yt/threading/spin_lock_count.cpp b/library/cpp/yt/threading/spin_lock_count.cpp index 501a8bd73e7..b1670e92d4a 100644 --- a/library/cpp/yt/threading/spin_lock_count.cpp +++ b/library/cpp/yt/threading/spin_lock_count.cpp @@ -13,26 +13,26 @@ namespace NYT::NThreading::NPrivate { //////////////////////////////////////////////////////////////////////////////// -YT_THREAD_LOCAL(i64) ActiveSpinLockCount = 0; +YT_DEFINE_THREAD_LOCAL(i64, ActiveSpinLockCount, 0); //////////////////////////////////////////////////////////////////////////////// void RecordSpinLockAcquired(bool isAcquired) { if (isAcquired) { - ActiveSpinLockCount++; + ActiveSpinLockCount()++; } } void RecordSpinLockReleased() { - YT_VERIFY(ActiveSpinLockCount > 0); - ActiveSpinLockCount--; + YT_VERIFY(ActiveSpinLockCount() > 0); + ActiveSpinLockCount()--; } void VerifyNoSpinLockAffinity() { - YT_VERIFY(ActiveSpinLockCount == 0); + YT_VERIFY(ActiveSpinLockCount() == 0); } #endif |