diff options
author | vskipin <vskipin@yandex-team.ru> | 2022-02-10 16:46:00 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:00 +0300 |
commit | 4e4b78bd7b67e2533da4dbb9696374a6d6068e32 (patch) | |
tree | a7a5543d815c451256ece74081d960b4e1d70ec2 /library | |
parent | 5b00ed04a5137a452fa6d3423cb0c9b54ac27408 (diff) | |
download | ydb-4e4b78bd7b67e2533da4dbb9696374a6d6068e32.tar.gz |
Restoring authorship annotation for <vskipin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'library')
66 files changed, 2216 insertions, 2216 deletions
diff --git a/library/cpp/actors/core/executor_thread.cpp b/library/cpp/actors/core/executor_thread.cpp index 446b651efd..ebfb8599b3 100644 --- a/library/cpp/actors/core/executor_thread.cpp +++ b/library/cpp/actors/core/executor_thread.cpp @@ -4,12 +4,12 @@ #include "mailbox.h" #include "event.h" #include "events.h" - + #include <library/cpp/actors/prof/tag.h> #include <library/cpp/actors/util/affinity.h> #include <library/cpp/actors/util/datetime.h> #include <library/cpp/actors/util/thread.h> - + #ifdef BALLOC #include <library/cpp/balloc/optional/operators.h> #endif @@ -174,8 +174,8 @@ namespace NActors { if (activityType != prevActivityType) { prevActivityType = activityType; NProfiling::TMemoryTagScope::Reset(ActorSystem->MemProfActivityBase + activityType); - } - + } + actor->Receive(ev, ctx); size_t dyingActorsCnt = DyingActors.size(); diff --git a/library/cpp/actors/core/log.cpp b/library/cpp/actors/core/log.cpp index 5f63b5af58..651c04cc11 100644 --- a/library/cpp/actors/core/log.cpp +++ b/library/cpp/actors/core/log.cpp @@ -171,21 +171,21 @@ namespace NActors { TIntrusivePtr<NMonitoring::TDynamicCounters> counters) : TActor(&TLoggerActor::StateFunc) , Settings(settings) - , LogBackend(logBackend.Release()) + , LogBackend(logBackend.Release()) , Metrics(std::make_unique<TLoggerCounters>(counters)) { - } - - TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, - std::shared_ptr<TLogBackend> logBackend, - TIntrusivePtr<NMonitoring::TDynamicCounters> counters) - : TActor(&TLoggerActor::StateFunc) - , Settings(settings) - , LogBackend(logBackend) + } + + TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, + std::shared_ptr<TLogBackend> logBackend, + TIntrusivePtr<NMonitoring::TDynamicCounters> counters) + : TActor(&TLoggerActor::StateFunc) + , Settings(settings) + , LogBackend(logBackend) , Metrics(std::make_unique<TLoggerCounters>(counters)) - { - } - + { + } + TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, TAutoPtr<TLogBackend> logBackend, std::shared_ptr<NMonitoring::TMetricRegistry> metrics) @@ -193,7 +193,7 @@ namespace NActors { , Settings(settings) , LogBackend(logBackend.Release()) , Metrics(std::make_unique<TLoggerMetrics>(metrics)) - { + { } TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, @@ -580,31 +580,31 @@ namespace NActors { char buf[TimeBufSize]; switch (Settings->Format) { - case NActors::NLog::TSettings::PLAIN_FULL_FORMAT: { - TStringBuilder logRecord; - if (Settings->UseLocalTimestamps) { + case NActors::NLog::TSettings::PLAIN_FULL_FORMAT: { + TStringBuilder logRecord; + if (Settings->UseLocalTimestamps) { logRecord << FormatLocalTimestamp(time, buf); - } else { - logRecord << time; - } - logRecord + } else { + logRecord << time; + } + logRecord << Settings->MessagePrefix - << " :" << Settings->ComponentName(component) - << " " << PriorityToString(priority) - << ": " << formatted; - LogBackend->WriteData( - TLogRecord(logPrio, logRecord.data(), logRecord.size())); - } break; - - case NActors::NLog::TSettings::PLAIN_SHORT_FORMAT: { - TStringBuilder logRecord; - logRecord - << Settings->ComponentName(component) - << ": " << formatted; - LogBackend->WriteData( - TLogRecord(logPrio, logRecord.data(), logRecord.size())); - } break; - + << " :" << Settings->ComponentName(component) + << " " << PriorityToString(priority) + << ": " << formatted; + LogBackend->WriteData( + TLogRecord(logPrio, logRecord.data(), logRecord.size())); + } break; + + case NActors::NLog::TSettings::PLAIN_SHORT_FORMAT: { + TStringBuilder logRecord; + logRecord + << Settings->ComponentName(component) + << ": " << formatted; + LogBackend->WriteData( + TLogRecord(logPrio, logRecord.data(), logRecord.size())); + } break; + case NActors::NLog::TSettings::JSON_FORMAT: { NJsonWriter::TBuf json; json.BeginObject() @@ -629,9 +629,9 @@ namespace NActors { .WriteKey("message") .WriteString(formatted) .EndObject(); - auto logRecord = json.Str(); - LogBackend->WriteData( - TLogRecord(logPrio, logRecord.data(), logRecord.size())); + auto logRecord = json.Str(); + LogBackend->WriteData( + TLogRecord(logPrio, logRecord.data(), logRecord.size())); } break; } diff --git a/library/cpp/actors/core/log.h b/library/cpp/actors/core/log.h index c11a7cf3c1..d4047e8164 100644 --- a/library/cpp/actors/core/log.h +++ b/library/cpp/actors/core/log.h @@ -199,9 +199,9 @@ namespace NActors { TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, TAutoPtr<TLogBackend> logBackend, TIntrusivePtr<NMonitoring::TDynamicCounters> counters); - TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, - std::shared_ptr<TLogBackend> logBackend, - TIntrusivePtr<NMonitoring::TDynamicCounters> counters); + TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, + std::shared_ptr<TLogBackend> logBackend, + TIntrusivePtr<NMonitoring::TDynamicCounters> counters); TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, TAutoPtr<TLogBackend> logBackend, std::shared_ptr<NMonitoring::TMetricRegistry> metrics); @@ -236,9 +236,9 @@ namespace NActors { private: TIntrusivePtr<NLog::TSettings> Settings; - std::shared_ptr<TLogBackend> LogBackend; - ui64 IgnoredCount = 0; - ui64 PassedCount = 0; + std::shared_ptr<TLogBackend> LogBackend; + ui64 IgnoredCount = 0; + ui64 PassedCount = 0; static TAtomic IsOverflow; TDuration WakeupInterval{TDuration::Seconds(5)}; std::unique_ptr<ILoggerMetrics> Metrics; diff --git a/library/cpp/actors/core/mon.h b/library/cpp/actors/core/mon.h index c450f2338e..4bf41e8c63 100644 --- a/library/cpp/actors/core/mon.h +++ b/library/cpp/actors/core/mon.h @@ -42,11 +42,11 @@ namespace NActors { // base class for HTTP info response struct IEvHttpInfoRes: public NActors::TEventLocal<IEvHttpInfoRes, HttpInfoRes> { - enum EContentType { - Html, - Custom, - }; - + enum EContentType { + Html, + Custom, + }; + IEvHttpInfoRes() { } @@ -54,7 +54,7 @@ namespace NActors { } virtual void Output(IOutputStream& out) const = 0; - virtual EContentType GetContentType() const = 0; + virtual EContentType GetContentType() const = 0; }; // Ready to output HTML in TString @@ -62,7 +62,7 @@ namespace NActors { TEvHttpInfoRes(const TString& answer, int subReqId = 0, EContentType contentType = Html) : Answer(answer) , SubRequestId(subReqId) - , ContentType(contentType) + , ContentType(contentType) { } @@ -70,13 +70,13 @@ namespace NActors { out << Answer; } - EContentType GetContentType() const override { - return ContentType; - } - + EContentType GetContentType() const override { + return ContentType; + } + const TString Answer; const int SubRequestId; - const EContentType ContentType; + const EContentType ContentType; }; struct TEvRemoteHttpInfo: public NActors::TEventBase<TEvRemoteHttpInfo, RemoteHttpInfo> { diff --git a/library/cpp/actors/core/ya.make b/library/cpp/actors/core/ya.make index 880a9d00db..e534912e7c 100644 --- a/library/cpp/actors/core/ya.make +++ b/library/cpp/actors/core/ya.make @@ -7,10 +7,10 @@ OWNER( NO_WSHADOW() -IF (PROFILE_MEMORY_ALLOCATIONS) - CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS) -ENDIF() - +IF (PROFILE_MEMORY_ALLOCATIONS) + CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS) +ENDIF() + IF (ALLOCATOR == "B" OR ALLOCATOR == "BS" OR ALLOCATOR == "C") CXXFLAGS(-DBALLOC) PEERDIR( diff --git a/library/cpp/actors/interconnect/events_local.h b/library/cpp/actors/interconnect/events_local.h index 8a46ffd535..bf05879b5b 100644 --- a/library/cpp/actors/interconnect/events_local.h +++ b/library/cpp/actors/interconnect/events_local.h @@ -216,7 +216,7 @@ namespace NActors { HANDSHAKE_FAIL_SESSION_MISMATCH, }; - TEvHandshakeFail(EnumHandshakeFail temporary, TString explanation) + TEvHandshakeFail(EnumHandshakeFail temporary, TString explanation) : Temporary(temporary) , Explanation(std::move(explanation)) { diff --git a/library/cpp/actors/interconnect/poller_tcp_unit.cpp b/library/cpp/actors/interconnect/poller_tcp_unit.cpp index 59e7dda810..2ec9339115 100644 --- a/library/cpp/actors/interconnect/poller_tcp_unit.cpp +++ b/library/cpp/actors/interconnect/poller_tcp_unit.cpp @@ -9,7 +9,7 @@ #include <library/cpp/actors/prof/tag.h> #include <library/cpp/actors/util/intrinsics.h> - + #if defined _linux_ #include <pthread.h> #endif @@ -101,7 +101,7 @@ namespace NInterconnect { template <> void TPollerUnit::RunLoop<false>() { - NProfiling::TMemoryTagScope tag("INTERCONNECT_RECEIVED_DATA"); + NProfiling::TMemoryTagScope tag("INTERCONNECT_RECEIVED_DATA"); while (!AtomicLoad(&StopFlag)) ProcessRead(); } @@ -109,7 +109,7 @@ namespace NInterconnect { template <> void TPollerUnit::RunLoop<true>() { - NProfiling::TMemoryTagScope tag("INTERCONNECT_SEND_DATA"); + NProfiling::TMemoryTagScope tag("INTERCONNECT_SEND_DATA"); while (!AtomicLoad(&StopFlag)) ProcessWrite(); } diff --git a/library/cpp/actors/interconnect/ut/lib/node.h b/library/cpp/actors/interconnect/ut/lib/node.h index ff30b1445e..496a54c1c9 100644 --- a/library/cpp/actors/interconnect/ut/lib/node.h +++ b/library/cpp/actors/interconnect/ut/lib/node.h @@ -66,26 +66,26 @@ public: constexpr ui32 LoggerComponentId = 410; // NKikimrServices::LOGGER auto loggerSettings = MakeIntrusive<NLog::TSettings>( - loggerActorId, + loggerActorId, (NLog::EComponent)LoggerComponentId, NLog::PRI_INFO, NLog::PRI_DEBUG, - 0U); - - loggerSettings->Append( - NActorsServices::EServiceCommon_MIN, + 0U); + + loggerSettings->Append( + NActorsServices::EServiceCommon_MIN, NActorsServices::EServiceCommon_MAX, NActorsServices::EServiceCommon_Name ); - + constexpr ui32 WilsonComponentId = 430; // NKikimrServices::WILSON - static const TString WilsonComponentName = "WILSON"; - - loggerSettings->Append( + static const TString WilsonComponentName = "WILSON"; + + loggerSettings->Append( (NLog::EComponent)WilsonComponentId, (NLog::EComponent)WilsonComponentId + 1, [](NLog::EComponent) -> const TString & { return WilsonComponentName; }); - + // register nameserver table auto names = MakeIntrusive<TTableNameserverSetup>(); for (ui32 i = 1; i <= numNodes; ++i) { diff --git a/library/cpp/actors/interconnect/ya.make b/library/cpp/actors/interconnect/ya.make index 60d29b0fc0..80055e4245 100644 --- a/library/cpp/actors/interconnect/ya.make +++ b/library/cpp/actors/interconnect/ya.make @@ -8,10 +8,10 @@ OWNER( NO_WSHADOW() -IF (PROFILE_MEMORY_ALLOCATIONS) - CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS) -ENDIF() - +IF (PROFILE_MEMORY_ALLOCATIONS) + CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS) +ENDIF() + SRCS( channel_scheduler.h event_filter.h diff --git a/library/cpp/actors/prof/tag.cpp b/library/cpp/actors/prof/tag.cpp index 9ccf03e1a9..ff4ea01f3c 100644 --- a/library/cpp/actors/prof/tag.cpp +++ b/library/cpp/actors/prof/tag.cpp @@ -4,108 +4,108 @@ #include <library/cpp/charset/ci_string.h> #include <library/cpp/containers/atomizer/atomizer.h> #include <library/cpp/malloc/api/malloc.h> - -#if defined(PROFILE_MEMORY_ALLOCATIONS) + +#if defined(PROFILE_MEMORY_ALLOCATIONS) #include <library/cpp/lfalloc/dbg_info/dbg_info.h> #include <library/cpp/ytalloc/api/ytalloc.h> -#endif - -#include <util/generic/singleton.h> -#include <util/generic/string.h> -#include <util/generic/vector.h> +#endif + +#include <util/generic/singleton.h> +#include <util/generic/string.h> +#include <util/generic/vector.h> #include <util/system/mutex.h> namespace NProfiling { - class TStringAtoms { - private: + class TStringAtoms { + private: TMutex Mutex; atomizer<ci_hash, ci_equal_to> Tags; - - public: - static TStringAtoms& Instance() { - return *Singleton<TStringAtoms>(); - } - - ui32 MakeTag(const char* s) { - Y_VERIFY(s); - with_lock (Mutex) { - return Tags.string_to_atom(s); - } - } - - ui32 MakeTags(const TVector<const char*>& ss) { - Y_VERIFY(ss); - with_lock (Mutex) { - ui32 baseTag = Tags.string_to_atom(ss[0]); - ui32 nextTag = baseTag + 1; - for (auto i = ss.begin() + 1; i != ss.end(); ++i, ++nextTag) { - Y_VERIFY(*i); - ui32 ctag = Tags.string_to_atom(*i); - Y_VERIFY(ctag == nextTag); - } - return baseTag; - } - } - - const char* GetTag(ui32 tag) const { - with_lock (Mutex) { - return Tags.get_atom_name(tag); - } - } - - size_t GetTagsCount() const { - with_lock (Mutex) { - return Tags.size(); - } - } + + public: + static TStringAtoms& Instance() { + return *Singleton<TStringAtoms>(); + } + + ui32 MakeTag(const char* s) { + Y_VERIFY(s); + with_lock (Mutex) { + return Tags.string_to_atom(s); + } + } + + ui32 MakeTags(const TVector<const char*>& ss) { + Y_VERIFY(ss); + with_lock (Mutex) { + ui32 baseTag = Tags.string_to_atom(ss[0]); + ui32 nextTag = baseTag + 1; + for (auto i = ss.begin() + 1; i != ss.end(); ++i, ++nextTag) { + Y_VERIFY(*i); + ui32 ctag = Tags.string_to_atom(*i); + Y_VERIFY(ctag == nextTag); + } + return baseTag; + } + } + + const char* GetTag(ui32 tag) const { + with_lock (Mutex) { + return Tags.get_atom_name(tag); + } + } + + size_t GetTagsCount() const { + with_lock (Mutex) { + return Tags.size(); + } + } }; ui32 MakeTag(const char* s) { - return TStringAtoms::Instance().MakeTag(s); + return TStringAtoms::Instance().MakeTag(s); } ui32 MakeTags(const TVector<const char*>& ss) { - return TStringAtoms::Instance().MakeTags(ss); + return TStringAtoms::Instance().MakeTags(ss); } const char* GetTag(ui32 tag) { - return TStringAtoms::Instance().GetTag(tag); - } - - size_t GetTagsCount() { - return TStringAtoms::Instance().GetTagsCount(); + return TStringAtoms::Instance().GetTag(tag); } + size_t GetTagsCount() { + return TStringAtoms::Instance().GetTagsCount(); + } + static ui32 SetThreadAllocTag_Default(ui32 tag) { Y_UNUSED(tag); return 0; } -#if defined(PROFILE_MEMORY_ALLOCATIONS) - static ui32 SetThreadAllocTag_YT(ui32 tag) { - auto prev = NYT::NYTAlloc::GetCurrentMemoryTag(); - NYT::NYTAlloc::SetCurrentMemoryTag(tag); - return prev; - } - - static TSetThreadAllocTag* SetThreadAllocTagFn() { - const auto& info = NMalloc::MallocInfo(); - - TStringBuf name(info.Name); - if (name.StartsWith("lf")) { - return (TSetThreadAllocTag*)NAllocDbg::SetThreadAllocTag; - } else if (name.StartsWith("yt")) { - return SetThreadAllocTag_YT; +#if defined(PROFILE_MEMORY_ALLOCATIONS) + static ui32 SetThreadAllocTag_YT(ui32 tag) { + auto prev = NYT::NYTAlloc::GetCurrentMemoryTag(); + NYT::NYTAlloc::SetCurrentMemoryTag(tag); + return prev; + } + + static TSetThreadAllocTag* SetThreadAllocTagFn() { + const auto& info = NMalloc::MallocInfo(); + + TStringBuf name(info.Name); + if (name.StartsWith("lf")) { + return (TSetThreadAllocTag*)NAllocDbg::SetThreadAllocTag; + } else if (name.StartsWith("yt")) { + return SetThreadAllocTag_YT; } else if (name.StartsWith("tc")) { return SetTCMallocThreadAllocTag; - } else { - return SetThreadAllocTag_Default; - } - } + } else { + return SetThreadAllocTag_Default; + } + } #else static TSetThreadAllocTag* SetThreadAllocTagFn() { const auto& info = NMalloc::MallocInfo(); - + TStringBuf name(info.Name); if (name.StartsWith("tc")) { return SetTCMallocThreadAllocTag; @@ -115,5 +115,5 @@ namespace NProfiling { } #endif - TSetThreadAllocTag* SetThreadAllocTag = SetThreadAllocTagFn(); + TSetThreadAllocTag* SetThreadAllocTag = SetThreadAllocTagFn(); } diff --git a/library/cpp/actors/prof/tag.h b/library/cpp/actors/prof/tag.h index 357e264a22..5ef36f588b 100644 --- a/library/cpp/actors/prof/tag.h +++ b/library/cpp/actors/prof/tag.h @@ -1,6 +1,6 @@ #pragma once -#include <util/generic/fwd.h> +#include <util/generic/fwd.h> /* Common registry for tagging memory profiler. @@ -15,21 +15,21 @@ namespace NProfiling { ui32 MakeTags(const TVector<const char*>& ss); const char* GetTag(ui32 tag); - size_t GetTagsCount(); - - using TSetThreadAllocTag = ui32(ui32 tag); - extern TSetThreadAllocTag* SetThreadAllocTag; + size_t GetTagsCount(); + using TSetThreadAllocTag = ui32(ui32 tag); + extern TSetThreadAllocTag* SetThreadAllocTag; + class TMemoryTagScope { public: explicit TMemoryTagScope(ui32 tag) - : RestoreTag(SetThreadAllocTag(tag)) + : RestoreTag(SetThreadAllocTag(tag)) { } - + explicit TMemoryTagScope(const char* tagName) { ui32 newTag = MakeTag(tagName); - RestoreTag = SetThreadAllocTag(newTag); + RestoreTag = SetThreadAllocTag(newTag); } TMemoryTagScope(TMemoryTagScope&& move) @@ -47,20 +47,20 @@ namespace NProfiling { } static void Reset(ui32 tag) { - SetThreadAllocTag(tag); + SetThreadAllocTag(tag); } void Release() { if (!Released) { - SetThreadAllocTag(RestoreTag); + SetThreadAllocTag(RestoreTag); Released = true; } } - ~TMemoryTagScope() { + ~TMemoryTagScope() { if (!Released) { - SetThreadAllocTag(RestoreTag); - } + SetThreadAllocTag(RestoreTag); + } } protected: diff --git a/library/cpp/actors/prof/ya.make b/library/cpp/actors/prof/ya.make index b5e2497563..4d15d4e962 100644 --- a/library/cpp/actors/prof/ya.make +++ b/library/cpp/actors/prof/ya.make @@ -14,15 +14,15 @@ PEERDIR( library/cpp/containers/atomizer ) -IF (PROFILE_MEMORY_ALLOCATIONS) +IF (PROFILE_MEMORY_ALLOCATIONS) CFLAGS(-DPROFILE_MEMORY_ALLOCATIONS) - PEERDIR( + PEERDIR( library/cpp/malloc/api library/cpp/lfalloc/dbg_info library/cpp/ytalloc/api - ) -ENDIF() - + ) +ENDIF() + IF(ALLOCATOR == "TCMALLOC_256K") SRCS(tcmalloc.cpp) PEERDIR(contrib/libs/tcmalloc) diff --git a/library/cpp/actors/util/funnel_queue.h b/library/cpp/actors/util/funnel_queue.h index 0e21e2617c..d91a8a711b 100644 --- a/library/cpp/actors/util/funnel_queue.h +++ b/library/cpp/actors/util/funnel_queue.h @@ -22,7 +22,7 @@ public: Push(ElementType&& element) noexcept { TEntry* const next = NewEntry(static_cast<ElementType&&>(element)); TEntry* const prev = AtomicSwap(&Back, next); - AtomicSet(prev ? prev->Next : Front, next); + AtomicSet(prev ? prev->Next : Front, next); return !prev; } @@ -52,7 +52,7 @@ public: /// Peek top element. Must be used only from one thread. ElementType& Top() const noexcept { - return AtomicGet(Front)->Data; + return AtomicGet(Front)->Data; } bool @@ -191,8 +191,8 @@ private: protected: virtual typename TBase::TEntry* NewEntry(ElementType&& element) noexcept override { - while (const auto top = AtomicGet(Stack)) - if (AtomicCas(&Stack, top->Next, top)) { + while (const auto top = AtomicGet(Stack)) + if (AtomicCas(&Stack, top->Next, top)) { top->Data = static_cast<ElementType&&>(element); AtomicSet(top->Next, nullptr); return top; @@ -206,7 +206,7 @@ protected: const auto next = entry->Next; do AtomicSet(entry->Next, AtomicGet(Stack)); - while (!AtomicCas(&Stack, entry, entry->Next)); + while (!AtomicCas(&Stack, entry, entry->Next)); return next; } }; diff --git a/library/cpp/actors/wilson/wilson_event.h b/library/cpp/actors/wilson/wilson_event.h index 7d89c33b51..527710da13 100644 --- a/library/cpp/actors/wilson/wilson_event.h +++ b/library/cpp/actors/wilson/wilson_event.h @@ -114,7 +114,7 @@ namespace NWilson { // generate wilson event having parent TRACE_ID and span TRACE_ID to become parent of logged event #define WILSON_TRACE(CTX, TRACE_ID, EVENT_NAME, ...) \ - if (::NWilson::TraceEnabled(CTX)) { \ + if (::NWilson::TraceEnabled(CTX)) { \ ::NWilson::TTraceId* __traceId = (TRACE_ID); \ if (__traceId && *__traceId) { \ TInstant now = Now(); \ @@ -123,7 +123,7 @@ namespace NWilson { __UNROLL_PARAMS(__FILL_PARAM, ##__VA_ARGS__) \ ::NWilson::TraceEvent((CTX), __traceId, event, now); \ } \ - } + } inline ui32 GetNodeId(const NActors::TActorSystem& actorSystem) { return actorSystem.NodeId; @@ -133,13 +133,13 @@ namespace NWilson { } constexpr ui32 WilsonComponentId = 430; // kikimrservices: wilson - - template <typename TActorSystem> - bool TraceEnabled(const TActorSystem& ctx) { - const auto* loggerSettings = ctx.LoggerSettings(); + + template <typename TActorSystem> + bool TraceEnabled(const TActorSystem& ctx) { + const auto* loggerSettings = ctx.LoggerSettings(); return loggerSettings && loggerSettings->Satisfies(NActors::NLog::PRI_DEBUG, WilsonComponentId); - } - + } + template <typename TActorSystem, typename TEvent> void TraceEvent(const TActorSystem& actorSystem, TTraceId* traceId, TEvent&& event, TInstant timestamp) { // ensure that we are not using obsolete TraceId diff --git a/library/cpp/cache/cache.h b/library/cpp/cache/cache.h index 6dc997076d..93c24f691d 100644 --- a/library/cpp/cache/cache.h +++ b/library/cpp/cache/cache.h @@ -124,94 +124,94 @@ private: size_t MaxSize; }; -template <typename TKey, typename TValue> -class TLFUList { -public: - TLFUList(size_t maxSize) - : List() - , ListSize(0) - , MaxSize(maxSize) - { - } - +template <typename TKey, typename TValue> +class TLFUList { +public: + TLFUList(size_t maxSize) + : List() + , ListSize(0) + , MaxSize(maxSize) + { + } + struct TItem: public TIntrusiveListItem<TItem> { - typedef TIntrusiveListItem<TItem> TBase; - TItem(const TKey& key, const TValue& value = TValue()) - : TBase() - , Key(key) - , Value(value) - , Counter(0) - { - } - - TItem(const TItem& rhs) - : TBase() - , Key(rhs.Key) - , Value(rhs.Value) - , Counter(rhs.Counter) - { - } - + typedef TIntrusiveListItem<TItem> TBase; + TItem(const TKey& key, const TValue& value = TValue()) + : TBase() + , Key(key) + , Value(value) + , Counter(0) + { + } + + TItem(const TItem& rhs) + : TBase() + , Key(rhs.Key) + , Value(rhs.Value) + , Counter(rhs.Counter) + { + } + bool operator<(const TItem& rhs) const { - return Key < rhs.Key; - } - + return Key < rhs.Key; + } + bool operator==(const TItem& rhs) const { - return Key == rhs.Key; - } - - TKey Key; - TValue Value; - size_t Counter; - - struct THash { + return Key == rhs.Key; + } + + TKey Key; + TValue Value; + size_t Counter; + + struct THash { size_t operator()(const TItem& item) const { - return ::THash<TKey>()(item.Key); - } - }; - }; - -public: - TItem* Insert(TItem* item) { - List.PushBack(item); // give a chance for promotion - ++ListSize; + return ::THash<TKey>()(item.Key); + } + }; + }; + +public: + TItem* Insert(TItem* item) { + List.PushBack(item); // give a chance for promotion + ++ListSize; return RemoveIfOverflown(); } TItem* RemoveIfOverflown() { TItem* deleted = nullptr; - if (ListSize > MaxSize) { - deleted = GetLeastFrequentlyUsed(); - Erase(deleted); - } - return deleted; - } - - TItem* GetLeastFrequentlyUsed() { + if (ListSize > MaxSize) { + deleted = GetLeastFrequentlyUsed(); + Erase(deleted); + } + return deleted; + } + + TItem* GetLeastFrequentlyUsed() { typename TListType::TIterator it = List.Begin(); Y_ASSERT(it != List.End()); - return &*it; - } - - void Erase(TItem* item) { - item->Unlink(); - --ListSize; - } - - void Promote(TItem* item) { - size_t counter = ++item->Counter; + return &*it; + } + + void Erase(TItem* item) { + item->Unlink(); + --ListSize; + } + + void Promote(TItem* item) { + size_t counter = ++item->Counter; typename TListType::TIterator it = item; - while (it != List.End() && counter >= it->Counter) { - ++it; - } - item->LinkBefore(&*it); - } - - size_t GetSize() const { - return ListSize; - } - + while (it != List.End() && counter >= it->Counter) { + ++it; + } + item->LinkBefore(&*it); + } + + size_t GetSize() const { + return ListSize; + } + size_t GetMaxSize() const { return MaxSize; } @@ -222,13 +222,13 @@ public: MaxSize = newSize; } -private: +private: typedef TIntrusiveList<TItem> TListType; TListType List; - size_t ListSize; - size_t MaxSize; -}; - + size_t ListSize; + size_t MaxSize; +}; + // Least Weighted list // discards the least weighted items first // doesn't support promotion @@ -578,7 +578,7 @@ template <typename TKey, typename TValue, typename TDeleter = TNoopDelete, class class TLRUCache: public TCache<TKey, TValue, TLRUList<TKey, TValue, TSizeProvider>, TDeleter> { using TListType = TLRUList<TKey, TValue, TSizeProvider>; typedef TCache<TKey, TValue, TListType, TDeleter> TBase; - + public: TLRUCache(size_t maxSize, bool multiValue = false, const TSizeProvider& sizeProvider = TSizeProvider()) : TBase(TListType(maxSize, sizeProvider), multiValue) @@ -600,28 +600,28 @@ public: return TBase::List.GetTotalSize(); } }; - -template <typename TKey, typename TValue, typename TDeleter = TNoopDelete> + +template <typename TKey, typename TValue, typename TDeleter = TNoopDelete> class TLFUCache: public TCache<TKey, TValue, TLFUList<TKey, TValue>, TDeleter> { typedef TCache<TKey, TValue, TLFUList<TKey, TValue>, TDeleter> TBase; using TListType = TLFUList<TKey, TValue>; - -public: - typedef typename TBase::TIterator TIterator; - - TLFUCache(size_t maxSize, bool multiValue = false) + +public: + typedef typename TBase::TIterator TIterator; + + TLFUCache(size_t maxSize, bool multiValue = false) : TBase(TListType(maxSize), multiValue) - { - } - - TValue& GetLeastFrequentlyUsed() { - return TBase::List.GetLeastFrequentlyUsed()->Value; - } - - TIterator FindLeastFrequentlyUsed() { - return TBase::Empty() ? TBase::End() : this->FindByItem(TBase::List.GetLeastFrequentlyUsed()); - } -}; + { + } + + TValue& GetLeastFrequentlyUsed() { + return TBase::List.GetLeastFrequentlyUsed()->Value; + } + + TIterator FindLeastFrequentlyUsed() { + return TBase::Empty() ? TBase::End() : this->FindByItem(TBase::List.GetLeastFrequentlyUsed()); + } +}; // Least Weighted cache // discards the least weighted items first diff --git a/library/cpp/cache/ut/cache_ut.cpp b/library/cpp/cache/ut/cache_ut.cpp index 329872cfde..96fabc10d7 100644 --- a/library/cpp/cache/ut/cache_ut.cpp +++ b/library/cpp/cache/ut/cache_ut.cpp @@ -12,23 +12,23 @@ Y_UNIT_TEST_SUITE(TCacheTest) { Y_UNIT_TEST(LRUListTest) { typedef TLRUList<int, TString> TListType; TListType list(2); - + TListType::TItem x1(1, "ttt"); list.Insert(&x1); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); - + TListType::TItem x2(2, "yyy"); list.Insert(&x2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); - + list.Promote(list.GetOldest()); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 2); - + TListType::TItem x3(3, "zzz"); list.Insert(&x3); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); - } - + } + Y_UNIT_TEST(LRUListWeightedTest) { typedef TLRUList<int, TString, size_t (*)(const TString&)> TListType; TListType list(7, [](auto& string) { @@ -68,23 +68,23 @@ Y_UNIT_TEST_SUITE(TCacheTest) { Y_UNIT_TEST(LFUListTest) { typedef TLFUList<int, TString> TListType; TListType list(2); - + TListType::TItem x1(1, "ttt"); list.Insert(&x1); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); - + TListType::TItem x2(2, "yyy"); list.Insert(&x2); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); - + list.Promote(list.GetLeastFrequentlyUsed()); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 2); - + TListType::TItem x3(3, "zzz"); list.Insert(&x3); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); - } - + } + Y_UNIT_TEST(LWListTest) { typedef TLWList<int, TString, size_t, TStrokaWeighter> TListType; TListType list(2); diff --git a/library/cpp/containers/paged_vector/ya.make b/library/cpp/containers/paged_vector/ya.make index e14548bc2c..ebb5349c27 100644 --- a/library/cpp/containers/paged_vector/ya.make +++ b/library/cpp/containers/paged_vector/ya.make @@ -1,9 +1,9 @@ -LIBRARY() - -OWNER(velavokr) - -SRCS( - paged_vector.cpp -) - -END() +LIBRARY() + +OWNER(velavokr) + +SRCS( + paged_vector.cpp +) + +END() diff --git a/library/cpp/containers/stack_vector/stack_vec.h b/library/cpp/containers/stack_vector/stack_vec.h index fcc5d9a2a5..6fe57e2e91 100644 --- a/library/cpp/containers/stack_vector/stack_vec.h +++ b/library/cpp/containers/stack_vector/stack_vec.h @@ -135,21 +135,21 @@ public: { } - template <class A> + template <class A> TStackVec(const TVector<T, A>& src) : TStackVec(src.begin(), src.end()) - { - } - + { + } + TStackVec(std::initializer_list<T> il, const TAllocator& alloc = TAllocator()) : TStackVec(il.begin(), il.end(), alloc) - { - } - - template <class TIter> + { + } + + template <class TIter> TStackVec(TIter first, TIter last, const TAllocator& alloc = TAllocator()) : TBase(alloc) - { + { // NB(eeight) Since we want to call 'reserve' here, we cannot just delegate to TVector ctor. // The best way to insert values afterwards is to call TVector::insert. However there is a caveat. // In order to call this ctor of TVector, T needs to be just move-constructible. Insert however @@ -164,27 +164,27 @@ public: TBase::push_back(*first); } } - } - + } + public: void swap(TStackVec&) = delete; void shrink_to_fit() = delete; TStackVec& operator=(const TStackVec& src) { - TBase::assign(src.begin(), src.end()); + TBase::assign(src.begin(), src.end()); return *this; } - - template <class A> + + template <class A> TStackVec& operator=(const TVector<T, A>& src) { - TBase::assign(src.begin(), src.end()); - return *this; - } - + TBase::assign(src.begin(), src.end()); + return *this; + } + TStackVec& operator=(std::initializer_list<T> il) { - TBase::assign(il.begin(), il.end()); - return *this; - } + TBase::assign(il.begin(), il.end()); + return *this; + } }; template <typename T, size_t CountOnStack, class Alloc> diff --git a/library/cpp/lfalloc/alloc_profiler/profiler.cpp b/library/cpp/lfalloc/alloc_profiler/profiler.cpp index 0e30927a5a..4c081bf64f 100644 --- a/library/cpp/lfalloc/alloc_profiler/profiler.cpp +++ b/library/cpp/lfalloc/alloc_profiler/profiler.cpp @@ -1,81 +1,81 @@ -#include "profiler.h" +#include "profiler.h" -#include "stackcollect.h" - -#include <util/generic/algorithm.h> -#include <util/generic/singleton.h> +#include "stackcollect.h" + +#include <util/generic/algorithm.h> +#include <util/generic/singleton.h> #include <util/generic/string.h> -#include <util/generic/vector.h> -#include <util/stream/str.h> - +#include <util/generic/vector.h> +#include <util/stream/str.h> + namespace NAllocProfiler { - -namespace { - -static TAllocationStackCollector& AllocationStackCollector() -{ - return *Singleton<TAllocationStackCollector>(); -} - -int AllocationCallback(int tag, size_t size, int sizeIdx) -{ - Y_UNUSED(sizeIdx); - - static const size_t STACK_FRAMES_COUNT = 32; - static const size_t STACK_FRAMES_SKIP = 1; - - void* frames[STACK_FRAMES_COUNT]; - size_t frameCount = BackTrace(frames, Y_ARRAY_SIZE(frames)); - if (frameCount <= STACK_FRAMES_SKIP) { - return -1; - } - - void** stack = &frames[STACK_FRAMES_SKIP]; - frameCount -= STACK_FRAMES_SKIP; - - auto& collector = AllocationStackCollector(); - return collector.Alloc(stack, frameCount, tag, size); -} - -void DeallocationCallback(int stackId, int tag, size_t size, int sizeIdx) -{ - Y_UNUSED(tag); - Y_UNUSED(sizeIdx); - - auto& collector = AllocationStackCollector(); - collector.Free(stackId, size); -} - -} // namespace - -//////////////////////////////////////////////////////////////////////////////// - + +namespace { + +static TAllocationStackCollector& AllocationStackCollector() +{ + return *Singleton<TAllocationStackCollector>(); +} + +int AllocationCallback(int tag, size_t size, int sizeIdx) +{ + Y_UNUSED(sizeIdx); + + static const size_t STACK_FRAMES_COUNT = 32; + static const size_t STACK_FRAMES_SKIP = 1; + + void* frames[STACK_FRAMES_COUNT]; + size_t frameCount = BackTrace(frames, Y_ARRAY_SIZE(frames)); + if (frameCount <= STACK_FRAMES_SKIP) { + return -1; + } + + void** stack = &frames[STACK_FRAMES_SKIP]; + frameCount -= STACK_FRAMES_SKIP; + + auto& collector = AllocationStackCollector(); + return collector.Alloc(stack, frameCount, tag, size); +} + +void DeallocationCallback(int stackId, int tag, size_t size, int sizeIdx) +{ + Y_UNUSED(tag); + Y_UNUSED(sizeIdx); + + auto& collector = AllocationStackCollector(); + collector.Free(stackId, size); +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// + bool StartAllocationSampling(bool profileAllThreads) -{ - auto& collector = AllocationStackCollector(); - collector.Clear(); - +{ + auto& collector = AllocationStackCollector(); + collector.Clear(); + NAllocDbg::SetProfileAllThreads(profileAllThreads); - NAllocDbg::SetAllocationCallback(AllocationCallback); - NAllocDbg::SetDeallocationCallback(DeallocationCallback); - NAllocDbg::SetAllocationSamplingEnabled(true); - return true; -} - + NAllocDbg::SetAllocationCallback(AllocationCallback); + NAllocDbg::SetDeallocationCallback(DeallocationCallback); + NAllocDbg::SetAllocationSamplingEnabled(true); + return true; +} + bool StopAllocationSampling(IAllocationStatsDumper &out, int count) -{ - NAllocDbg::SetAllocationCallback(nullptr); - NAllocDbg::SetDeallocationCallback(nullptr); - NAllocDbg::SetAllocationSamplingEnabled(false); - - auto& collector = AllocationStackCollector(); +{ + NAllocDbg::SetAllocationCallback(nullptr); + NAllocDbg::SetDeallocationCallback(nullptr); + NAllocDbg::SetAllocationSamplingEnabled(false); + + auto& collector = AllocationStackCollector(); collector.Dump(count, out); - return true; -} - + return true; +} + bool StopAllocationSampling(IOutputStream& out, int count) { TAllocationStatsDumper dumper(out); return StopAllocationSampling(dumper, count); -} - -} // namespace NProfiler +} + +} // namespace NProfiler diff --git a/library/cpp/lfalloc/alloc_profiler/profiler.h b/library/cpp/lfalloc/alloc_profiler/profiler.h index 4ea49b9dcc..0cd816fa03 100644 --- a/library/cpp/lfalloc/alloc_profiler/profiler.h +++ b/library/cpp/lfalloc/alloc_profiler/profiler.h @@ -1,45 +1,45 @@ -#pragma once - +#pragma once + #include "stackcollect.h" - + #include <library/cpp/lfalloc/dbg_info/dbg_info.h> - -#include <util/generic/noncopyable.h> + +#include <util/generic/noncopyable.h> #include <util/stream/output.h> - + namespace NAllocProfiler { - -//////////////////////////////////////////////////////////////////////////////// - -inline int SetCurrentScopeTag(int value) -{ - return NAllocDbg::SetThreadAllocTag(value); -} - -inline bool SetProfileCurrentThread(bool value) -{ - return NAllocDbg::SetProfileCurrentThread(value); -} - + +//////////////////////////////////////////////////////////////////////////////// + +inline int SetCurrentScopeTag(int value) +{ + return NAllocDbg::SetThreadAllocTag(value); +} + +inline bool SetProfileCurrentThread(bool value) +{ + return NAllocDbg::SetProfileCurrentThread(value); +} + bool StartAllocationSampling(bool profileAllThreads = false); bool StopAllocationSampling(IAllocationStatsDumper& out, int count = 100); bool StopAllocationSampling(IOutputStream& out, int count = 100); - -//////////////////////////////////////////////////////////////////////////////// - -class TProfilingScope: private TNonCopyable { -private: - const int Prev; - -public: - explicit TProfilingScope(int value) - : Prev(SetCurrentScopeTag(value)) - {} - - ~TProfilingScope() - { - SetCurrentScopeTag(Prev); - } -}; - + +//////////////////////////////////////////////////////////////////////////////// + +class TProfilingScope: private TNonCopyable { +private: + const int Prev; + +public: + explicit TProfilingScope(int value) + : Prev(SetCurrentScopeTag(value)) + {} + + ~TProfilingScope() + { + SetCurrentScopeTag(Prev); + } +}; + } // namespace NAllocProfiler diff --git a/library/cpp/lfalloc/alloc_profiler/stackcollect.cpp b/library/cpp/lfalloc/alloc_profiler/stackcollect.cpp index fded4e2fd1..5a0c920451 100644 --- a/library/cpp/lfalloc/alloc_profiler/stackcollect.cpp +++ b/library/cpp/lfalloc/alloc_profiler/stackcollect.cpp @@ -1,278 +1,278 @@ -#include "stackcollect.h" +#include "stackcollect.h" -#include "profiler.h" - -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> -#include <util/stream/format.h> +#include "profiler.h" + +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> +#include <util/stream/format.h> #include <util/stream/str.h> #include <util/string/cast.h> #include <util/string/printf.h> -#include <util/system/backtrace.h> -#include <util/system/spinlock.h> -#include <util/system/yassert.h> - - +#include <util/system/backtrace.h> +#include <util/system/spinlock.h> +#include <util/system/yassert.h> + + namespace NAllocProfiler { -//////////////////////////////////////////////////////////////////////////////// - -template <typename T> -class TStackCollector: private TNonCopyable { -public: - struct TFrameInfo { - int PrevInd; - void* Addr; - int Tag; - T Stats; - - void Clear() - { - PrevInd = 0; - Addr = nullptr; - Tag = 0; - Stats.Clear(); - } - }; - -private: - static const size_t STACKS_HASH_MAP_SIZE = 256 * 1024; - TFrameInfo Frames[STACKS_HASH_MAP_SIZE]; - - ui64 Samples; // Saved samples count - ui64 UniqueSamples; // Number of unique addresses - ui64 UsedSlots; // Number of occupied slots in the hashtable - ui64 DroppedSamples; // Number of unsaved addresses - ui64 SearchSkipCount; // Total number of linear hash table probes due to collisions - - TAdaptiveLock Lock; - -public: - TStackCollector() - { - Clear(); - } - - int AddStack(void** stack, size_t frameCount, int tag) - { - Y_ASSERT(frameCount > 0); - - int prevInd = -1; - with_lock (Lock) { - for (int i = frameCount - 1; i >= 0; --i) { - prevInd = AddFrame(stack[i], prevInd, ((i == 0) ? tag : 0), (i == 0)); - if (prevInd == -1) { - break; - } - } - } - return prevInd; - } - - T& GetStats(int stackId) - { - Y_ASSERT(stackId >= 0 && (size_t)stackId < Y_ARRAY_SIZE(Frames)); - Y_ASSERT(!IsSlotEmpty(stackId)); - - return Frames[stackId].Stats; - } - - const TFrameInfo* GetFrames() const - { - return Frames; - } - - size_t GetFramesCount() const - { - return Y_ARRAY_SIZE(Frames); - } - +//////////////////////////////////////////////////////////////////////////////// + +template <typename T> +class TStackCollector: private TNonCopyable { +public: + struct TFrameInfo { + int PrevInd; + void* Addr; + int Tag; + T Stats; + + void Clear() + { + PrevInd = 0; + Addr = nullptr; + Tag = 0; + Stats.Clear(); + } + }; + +private: + static const size_t STACKS_HASH_MAP_SIZE = 256 * 1024; + TFrameInfo Frames[STACKS_HASH_MAP_SIZE]; + + ui64 Samples; // Saved samples count + ui64 UniqueSamples; // Number of unique addresses + ui64 UsedSlots; // Number of occupied slots in the hashtable + ui64 DroppedSamples; // Number of unsaved addresses + ui64 SearchSkipCount; // Total number of linear hash table probes due to collisions + + TAdaptiveLock Lock; + +public: + TStackCollector() + { + Clear(); + } + + int AddStack(void** stack, size_t frameCount, int tag) + { + Y_ASSERT(frameCount > 0); + + int prevInd = -1; + with_lock (Lock) { + for (int i = frameCount - 1; i >= 0; --i) { + prevInd = AddFrame(stack[i], prevInd, ((i == 0) ? tag : 0), (i == 0)); + if (prevInd == -1) { + break; + } + } + } + return prevInd; + } + + T& GetStats(int stackId) + { + Y_ASSERT(stackId >= 0 && (size_t)stackId < Y_ARRAY_SIZE(Frames)); + Y_ASSERT(!IsSlotEmpty(stackId)); + + return Frames[stackId].Stats; + } + + const TFrameInfo* GetFrames() const + { + return Frames; + } + + size_t GetFramesCount() const + { + return Y_ARRAY_SIZE(Frames); + } + void BackTrace(const TFrameInfo* stack, TStackVec<void*, 64>& frames) const - { + { frames.clear(); - for (size_t i = 0; i < 100; ++i) { + for (size_t i = 0; i < 100; ++i) { frames.push_back(stack->Addr); - int prevInd = stack->PrevInd; - if (prevInd == -1) { - break; - } - stack = &Frames[prevInd]; - } - } - - void Clear() - { - for (auto& frame: Frames) { - frame.Clear(); - } - - Samples = 0; - DroppedSamples = 0; - UniqueSamples = 0; - UsedSlots = 0; - SearchSkipCount = 0; - } - -private: - // Hash function applied to the addresses - static ui32 Hash(void* addr, int prevInd, int tag) - { - return (((size_t)addr + ((size_t)addr / STACKS_HASH_MAP_SIZE)) + prevInd + tag) % STACKS_HASH_MAP_SIZE; - } - - static bool EqualFrame(const TFrameInfo& frame, void* addr, int prevInd, int tag) - { - return (frame.Addr == addr && frame.PrevInd == prevInd && frame.Tag == tag); - } - - bool IsSlotEmpty(ui32 slot) const - { - return Frames[slot].Addr == 0; - } - - bool InsertsAllowed() const - { - return UsedSlots < STACKS_HASH_MAP_SIZE / 2; - } - - // returns the index in the hashmap - int AddFrame(void* addr, int prevFrameIndex, int tag, bool last) - { - ui32 slot = Hash(addr, prevFrameIndex, tag); - ui32 prevSlot = (slot - 1) % STACKS_HASH_MAP_SIZE; - - while (!EqualFrame(Frames[slot], addr, prevFrameIndex, tag) && !IsSlotEmpty(slot) && slot != prevSlot) { - slot = (slot + 1) % STACKS_HASH_MAP_SIZE; - SearchSkipCount++; - } - - if (EqualFrame(Frames[slot], addr, prevFrameIndex, tag)) { - if (last) { - ++Samples; - } - } else if (InsertsAllowed() && IsSlotEmpty(slot)) { - // add new sample - Frames[slot].Clear(); - Frames[slot].Addr = addr; - Frames[slot].PrevInd = prevFrameIndex; - Frames[slot].Tag = tag; - ++UsedSlots; - if (last) { - ++UniqueSamples; - ++Samples; - } - } else { - // don't insert new sample if the search is becoming too slow - ++DroppedSamples; - return -1; - } - - return slot; - } -}; - - -//////////////////////////////////////////////////////////////////////////////// - + int prevInd = stack->PrevInd; + if (prevInd == -1) { + break; + } + stack = &Frames[prevInd]; + } + } + + void Clear() + { + for (auto& frame: Frames) { + frame.Clear(); + } + + Samples = 0; + DroppedSamples = 0; + UniqueSamples = 0; + UsedSlots = 0; + SearchSkipCount = 0; + } + +private: + // Hash function applied to the addresses + static ui32 Hash(void* addr, int prevInd, int tag) + { + return (((size_t)addr + ((size_t)addr / STACKS_HASH_MAP_SIZE)) + prevInd + tag) % STACKS_HASH_MAP_SIZE; + } + + static bool EqualFrame(const TFrameInfo& frame, void* addr, int prevInd, int tag) + { + return (frame.Addr == addr && frame.PrevInd == prevInd && frame.Tag == tag); + } + + bool IsSlotEmpty(ui32 slot) const + { + return Frames[slot].Addr == 0; + } + + bool InsertsAllowed() const + { + return UsedSlots < STACKS_HASH_MAP_SIZE / 2; + } + + // returns the index in the hashmap + int AddFrame(void* addr, int prevFrameIndex, int tag, bool last) + { + ui32 slot = Hash(addr, prevFrameIndex, tag); + ui32 prevSlot = (slot - 1) % STACKS_HASH_MAP_SIZE; + + while (!EqualFrame(Frames[slot], addr, prevFrameIndex, tag) && !IsSlotEmpty(slot) && slot != prevSlot) { + slot = (slot + 1) % STACKS_HASH_MAP_SIZE; + SearchSkipCount++; + } + + if (EqualFrame(Frames[slot], addr, prevFrameIndex, tag)) { + if (last) { + ++Samples; + } + } else if (InsertsAllowed() && IsSlotEmpty(slot)) { + // add new sample + Frames[slot].Clear(); + Frames[slot].Addr = addr; + Frames[slot].PrevInd = prevFrameIndex; + Frames[slot].Tag = tag; + ++UsedSlots; + if (last) { + ++UniqueSamples; + ++Samples; + } + } else { + // don't insert new sample if the search is becoming too slow + ++DroppedSamples; + return -1; + } + + return slot; + } +}; + + +//////////////////////////////////////////////////////////////////////////////// + class TAllocationStackCollector::TImpl: public TStackCollector<TStats> { using TBase = TStackCollector<TStats>; - -private: + +private: TStats Total; - -public: - int Alloc(void** stack, size_t frameCount, int tag, size_t size) - { - int stackId = TBase::AddStack(stack, frameCount, tag); - if (stackId >= 0) { - TBase::GetStats(stackId).Alloc(size); - Total.Alloc(size); - } - return stackId; - } - - void Free(int stackId, size_t size) - { - TBase::GetStats(stackId).Free(size); - Total.Free(size); - } - - void Clear() - { - TBase::Clear(); - Total.Clear(); - } - + +public: + int Alloc(void** stack, size_t frameCount, int tag, size_t size) + { + int stackId = TBase::AddStack(stack, frameCount, tag); + if (stackId >= 0) { + TBase::GetStats(stackId).Alloc(size); + Total.Alloc(size); + } + return stackId; + } + + void Free(int stackId, size_t size) + { + TBase::GetStats(stackId).Free(size); + Total.Free(size); + } + + void Clear() + { + TBase::Clear(); + Total.Clear(); + } + void Dump(int count, IAllocationStatsDumper& out) const - { - const TFrameInfo* frames = TBase::GetFrames(); - size_t framesCount = TBase::GetFramesCount(); - + { + const TFrameInfo* frames = TBase::GetFrames(); + size_t framesCount = TBase::GetFramesCount(); + TVector<const TFrameInfo*> stacks; - for (size_t i = 0; i < framesCount; ++i) { - if (frames[i].Stats.Allocs) { - stacks.push_back(&frames[i]); - } - } - - Sort(stacks, [] (const TFrameInfo* l, const TFrameInfo* r) { - const auto& ls = l->Stats; - const auto& rs = r->Stats; - return ls.CurrentSize != rs.CurrentSize - ? ls.CurrentSize > rs.CurrentSize - : ls.Allocs != rs.Allocs - ? ls.Allocs > rs.Allocs - : ls.Frees > rs.Frees; - }); - + for (size_t i = 0; i < framesCount; ++i) { + if (frames[i].Stats.Allocs) { + stacks.push_back(&frames[i]); + } + } + + Sort(stacks, [] (const TFrameInfo* l, const TFrameInfo* r) { + const auto& ls = l->Stats; + const auto& rs = r->Stats; + return ls.CurrentSize != rs.CurrentSize + ? ls.CurrentSize > rs.CurrentSize + : ls.Allocs != rs.Allocs + ? ls.Allocs > rs.Allocs + : ls.Frees > rs.Frees; + }); + out.DumpTotal(Total); - + TAllocationInfo allocInfo; - int printedCount = 0; - for (const TFrameInfo* stack: stacks) { + int printedCount = 0; + for (const TFrameInfo* stack: stacks) { allocInfo.Clear(); allocInfo.Tag = stack->Tag; allocInfo.Stats = stack->Stats; TBase::BackTrace(stack, allocInfo.Stack); - + out.DumpEntry(allocInfo); - if (++printedCount >= count) { - break; - } - } - } -}; - -//////////////////////////////////////////////////////////////////////////////// - -TAllocationStackCollector::TAllocationStackCollector() - : Impl(new TImpl()) -{} - -TAllocationStackCollector::~TAllocationStackCollector() -{} - -int TAllocationStackCollector::Alloc(void** stack, size_t frameCount, int tag, size_t size) -{ - return Impl->Alloc(stack, frameCount, tag, size); -} - -void TAllocationStackCollector::Free(int stackId, size_t size) -{ - Impl->Free(stackId, size); -} - -void TAllocationStackCollector::Clear() -{ - Impl->Clear(); -} - + if (++printedCount >= count) { + break; + } + } + } +}; + +//////////////////////////////////////////////////////////////////////////////// + +TAllocationStackCollector::TAllocationStackCollector() + : Impl(new TImpl()) +{} + +TAllocationStackCollector::~TAllocationStackCollector() +{} + +int TAllocationStackCollector::Alloc(void** stack, size_t frameCount, int tag, size_t size) +{ + return Impl->Alloc(stack, frameCount, tag, size); +} + +void TAllocationStackCollector::Free(int stackId, size_t size) +{ + Impl->Free(stackId, size); +} + +void TAllocationStackCollector::Clear() +{ + Impl->Clear(); +} + void TAllocationStackCollector::Dump(int count, IAllocationStatsDumper &out) const -{ - Impl->Dump(count, out); -} - +{ + Impl->Dump(count, out); +} + TString IAllocationStatsDumper::FormatTag(int tag) { return ToString(tag); diff --git a/library/cpp/lfalloc/alloc_profiler/stackcollect.h b/library/cpp/lfalloc/alloc_profiler/stackcollect.h index 80715ed7cb..8c0d65b296 100644 --- a/library/cpp/lfalloc/alloc_profiler/stackcollect.h +++ b/library/cpp/lfalloc/alloc_profiler/stackcollect.h @@ -1,14 +1,14 @@ -#pragma once - +#pragma once + #include <library/cpp/containers/stack_vector/stack_vec.h> #include <library/cpp/cache/cache.h> -#include <util/generic/noncopyable.h> -#include <util/generic/ptr.h> +#include <util/generic/noncopyable.h> +#include <util/generic/ptr.h> #include <util/stream/output.h> - + namespace NAllocProfiler { - + struct TStats { intptr_t Allocs = 0; intptr_t Frees = 0; @@ -85,23 +85,23 @@ private: TLFUCache<void*, TSymbol> SymbolCache; }; -//////////////////////////////////////////////////////////////////////////////// - -class TAllocationStackCollector: private TNonCopyable { -private: - class TImpl; - THolder<TImpl> Impl; - -public: - TAllocationStackCollector(); - ~TAllocationStackCollector(); - - int Alloc(void** stack, size_t frameCount, int tag, size_t size); - void Free(int stackId, size_t size); - - void Clear(); - +//////////////////////////////////////////////////////////////////////////////// + +class TAllocationStackCollector: private TNonCopyable { +private: + class TImpl; + THolder<TImpl> Impl; + +public: + TAllocationStackCollector(); + ~TAllocationStackCollector(); + + int Alloc(void** stack, size_t frameCount, int tag, size_t size); + void Free(int stackId, size_t size); + + void Clear(); + void Dump(int count, IAllocationStatsDumper& out) const; -}; - +}; + } // namespace NAllocProfiler diff --git a/library/cpp/lfalloc/dbg/ya.make b/library/cpp/lfalloc/dbg/ya.make index 3dce653a8c..387050fc67 100644 --- a/library/cpp/lfalloc/dbg/ya.make +++ b/library/cpp/lfalloc/dbg/ya.make @@ -1,32 +1,32 @@ -LIBRARY() +LIBRARY() -OWNER(vskipin) +OWNER(vskipin) + +NO_UTIL() -NO_UTIL() - -NO_COMPILER_WARNINGS() - -IF (ARCH_AARCH64) - PEERDIR( - contrib/libs/jemalloc - ) -ELSE() - IF ("${YMAKE}" MATCHES "devtools") - CFLAGS(-DYMAKE=1) - ENDIF() +NO_COMPILER_WARNINGS() + +IF (ARCH_AARCH64) + PEERDIR( + contrib/libs/jemalloc + ) +ELSE() + IF ("${YMAKE}" MATCHES "devtools") + CFLAGS(-DYMAKE=1) + ENDIF() CXXFLAGS( -DLFALLOC_DBG -DLFALLOC_YT ) - SRCS( - ../lf_allocX64.cpp - ) -ENDIF() - -PEERDIR( + SRCS( + ../lf_allocX64.cpp + ) +ENDIF() + +PEERDIR( library/cpp/malloc/api -) - -SET(IDE_FOLDER "util") - -END() +) + +SET(IDE_FOLDER "util") + +END() diff --git a/library/cpp/lfalloc/dbg_info/dbg_info.cpp b/library/cpp/lfalloc/dbg_info/dbg_info.cpp index 1fb9f7ad93..c900cb4f96 100644 --- a/library/cpp/lfalloc/dbg_info/dbg_info.cpp +++ b/library/cpp/lfalloc/dbg_info/dbg_info.cpp @@ -1,83 +1,83 @@ -#include "dbg_info.h" - +#include "dbg_info.h" + #include <library/cpp/malloc/api/malloc.h> - -namespace NAllocDbg { + +namespace NAllocDbg { //////////////////////////////////////////////////////////////////////////////// - + using TGetAllocationCounter = i64(int counter); - + using TSetThreadAllocTag = int(int tag); using TGetPerTagAllocInfo = void( bool flushPerThreadCounters, TPerTagAllocInfo* info, int& maxTag, int& numSizes); - + using TSetProfileCurrentThread = bool(bool newVal); using TSetProfileAllThreads = bool(bool newVal); using TSetAllocationSamplingEnabled = bool(bool newVal); - + using TSetAllocationSampleRate = size_t(size_t newVal); using TSetAllocationSampleMaxSize = size_t(size_t newVal); - + using TSetAllocationCallback = TAllocationCallback*(TAllocationCallback* newVal); using TSetDeallocationCallback = TDeallocationCallback*(TDeallocationCallback* newVal); - + struct TAllocFn { TGetAllocationCounter* GetAllocationCounterFast = nullptr; TGetAllocationCounter* GetAllocationCounterFull = nullptr; - + TSetThreadAllocTag* SetThreadAllocTag = nullptr; TGetPerTagAllocInfo* GetPerTagAllocInfo = nullptr; - + TSetProfileCurrentThread* SetProfileCurrentThread = nullptr; TSetProfileAllThreads* SetProfileAllThreads = nullptr; TSetAllocationSamplingEnabled* SetAllocationSamplingEnabled = nullptr; - + TSetAllocationSampleRate* SetAllocationSampleRate = nullptr; TSetAllocationSampleMaxSize* SetAllocationSampleMaxSize = nullptr; - + TSetAllocationCallback* SetAllocationCallback = nullptr; TSetDeallocationCallback* SetDeallocationCallback = nullptr; - + TAllocFn() { auto mallocInfo = NMalloc::MallocInfo(); - + GetAllocationCounterFast = (TGetAllocationCounter*)mallocInfo.GetParam("GetLFAllocCounterFast"); GetAllocationCounterFull = (TGetAllocationCounter*)mallocInfo.GetParam("GetLFAllocCounterFull"); - + SetThreadAllocTag = (TSetThreadAllocTag*)mallocInfo.GetParam("SetThreadAllocTag"); GetPerTagAllocInfo = (TGetPerTagAllocInfo*)mallocInfo.GetParam("GetPerTagAllocInfo"); - + SetProfileCurrentThread = (TSetProfileCurrentThread*)mallocInfo.GetParam("SetProfileCurrentThread"); SetProfileAllThreads = (TSetProfileAllThreads*)mallocInfo.GetParam("SetProfileAllThreads"); SetAllocationSamplingEnabled = (TSetAllocationSamplingEnabled*)mallocInfo.GetParam("SetAllocationSamplingEnabled"); - + SetAllocationSampleRate = (TSetAllocationSampleRate*)mallocInfo.GetParam("SetAllocationSampleRate"); SetAllocationSampleMaxSize = (TSetAllocationSampleMaxSize*)mallocInfo.GetParam("SetAllocationSampleMaxSize"); - + SetAllocationCallback = (TSetAllocationCallback*)mallocInfo.GetParam("SetAllocationCallback"); SetDeallocationCallback = (TSetDeallocationCallback*)mallocInfo.GetParam("SetDeallocationCallback"); } }; - + //////////////////////////////////////////////////////////////////////////////// - + static TAllocFn AllocFn; - + i64 GetAllocationCounterFast(ELFAllocCounter counter) { return AllocFn.GetAllocationCounterFast ? AllocFn.GetAllocationCounterFast(counter) : 0; } - + i64 GetAllocationCounterFull(ELFAllocCounter counter) { return AllocFn.GetAllocationCounterFull ? AllocFn.GetAllocationCounterFull(counter) : 0; } - + int SetThreadAllocTag(int tag) { return AllocFn.SetThreadAllocTag ? AllocFn.SetThreadAllocTag(tag) : 0; } - + TArrayPtr<TPerTagAllocInfo> GetPerTagAllocInfo( bool flushPerThreadCounters, int& maxTag, @@ -92,11 +92,11 @@ namespace NAllocDbg { numSizes = 0; return nullptr; } - + bool SetProfileCurrentThread(bool newVal) { return AllocFn.SetProfileCurrentThread ? AllocFn.SetProfileCurrentThread(newVal) : false; - } - + } + bool SetProfileAllThreads(bool newVal) { return AllocFn.SetProfileAllThreads ? AllocFn.SetProfileAllThreads(newVal) : false; } @@ -104,21 +104,21 @@ namespace NAllocDbg { bool SetAllocationSamplingEnabled(bool newVal) { return AllocFn.SetAllocationSamplingEnabled ? AllocFn.SetAllocationSamplingEnabled(newVal) : false; } - + size_t SetAllocationSampleRate(size_t newVal) { return AllocFn.SetAllocationSampleRate ? AllocFn.SetAllocationSampleRate(newVal) : 0; } - + size_t SetAllocationSampleMaxSize(size_t newVal) { return AllocFn.SetAllocationSampleMaxSize ? AllocFn.SetAllocationSampleMaxSize(newVal) : 0; } - + TAllocationCallback* SetAllocationCallback(TAllocationCallback* newVal) { return AllocFn.SetAllocationCallback ? AllocFn.SetAllocationCallback(newVal) : nullptr; } - + TDeallocationCallback* SetDeallocationCallback(TDeallocationCallback* newVal) { return AllocFn.SetDeallocationCallback ? AllocFn.SetDeallocationCallback(newVal) : nullptr; } - -} + +} diff --git a/library/cpp/lfalloc/dbg_info/dbg_info.h b/library/cpp/lfalloc/dbg_info/dbg_info.h index 071562a81a..0c3299216d 100644 --- a/library/cpp/lfalloc/dbg_info/dbg_info.h +++ b/library/cpp/lfalloc/dbg_info/dbg_info.h @@ -1,12 +1,12 @@ -#pragma once - +#pragma once + #include <util/generic/ptr.h> -#include <util/system/types.h> - -namespace NAllocDbg { +#include <util/system/types.h> + +namespace NAllocDbg { //////////////////////////////////////////////////////////////////////////////// // Allocation statistics - + enum ELFAllocCounter { CT_USER_ALLOC, // accumulated size requested by user code CT_MMAP, // accumulated mmapped size @@ -23,55 +23,55 @@ namespace NAllocDbg { CT_DEGRAGMENT_CNT, // number of memory defragmentations CT_MAX }; - + i64 GetAllocationCounterFast(ELFAllocCounter counter); i64 GetAllocationCounterFull(ELFAllocCounter counter); - + //////////////////////////////////////////////////////////////////////////////// // Allocation statistics could be tracked on per-tag basis - + int SetThreadAllocTag(int tag); - + class TScopedTag { private: int PrevTag; - + public: explicit TScopedTag(int tag) { PrevTag = SetThreadAllocTag(tag); } - + ~TScopedTag() { SetThreadAllocTag(PrevTag); } }; - + struct TPerTagAllocInfo { ssize_t Count; ssize_t Size; }; - + TArrayPtr<TPerTagAllocInfo> GetPerTagAllocInfo( bool flushPerThreadCounters, int& maxTag, int& numSizes); - + //////////////////////////////////////////////////////////////////////////////// // Allocation sampling could be used to collect detailed information - + bool SetProfileCurrentThread(bool newVal); bool SetProfileAllThreads(bool newVal); bool SetAllocationSamplingEnabled(bool newVal); - + size_t SetAllocationSampleRate(size_t newVal); size_t SetAllocationSampleMaxSize(size_t newVal); - -#define DBG_ALLOC_INVALID_COOKIE (-1) - + +#define DBG_ALLOC_INVALID_COOKIE (-1) + using TAllocationCallback = int(int tag, size_t size, int sizeIdx); using TDeallocationCallback = void(int cookie, int tag, size_t size, int sizeIdx); - + TAllocationCallback* SetAllocationCallback(TAllocationCallback* newVal); TDeallocationCallback* SetDeallocationCallback(TDeallocationCallback* newVal); - + } diff --git a/library/cpp/lfalloc/dbg_info/ya.make b/library/cpp/lfalloc/dbg_info/ya.make index efecba5993..e7068a0b10 100644 --- a/library/cpp/lfalloc/dbg_info/ya.make +++ b/library/cpp/lfalloc/dbg_info/ya.make @@ -1,15 +1,15 @@ -LIBRARY() +LIBRARY() -OWNER(vskipin) - -PEERDIR( +OWNER(vskipin) + +PEERDIR( library/cpp/malloc/api -) - -SRCS( - dbg_info.cpp -) - -SET(IDE_FOLDER "util") - -END() +) + +SRCS( + dbg_info.cpp +) + +SET(IDE_FOLDER "util") + +END() diff --git a/library/cpp/lfalloc/lf_allocX64.h b/library/cpp/lfalloc/lf_allocX64.h index fd2a906d6f..616253d689 100644 --- a/library/cpp/lfalloc/lf_allocX64.h +++ b/library/cpp/lfalloc/lf_allocX64.h @@ -37,10 +37,10 @@ static inline long AtomicAdd(TAtomic& a, long b) { return _InterlockedExchangeAdd(&a, b) + b; } -static inline long AtomicSub(TAtomic& a, long b) { - return AtomicAdd(a, -b); -} - +static inline long AtomicSub(TAtomic& a, long b) { + return AtomicAdd(a, -b); +} + #pragma comment(lib, "synchronization.lib") #ifndef NDEBUG @@ -121,7 +121,7 @@ static inline long AtomicSub(TAtomic& a, long b) { #ifndef NDEBUG #define DBG_FILL_MEMORY -static bool FillMemoryOnAllocation = true; +static bool FillMemoryOnAllocation = true; #endif static bool TransparentHugePages = false; // force MADV_HUGEPAGE for large allocs @@ -189,9 +189,9 @@ const int N_SIZES = 25; #endif const int nSizeIdxToSize[N_SIZES] = { -1, -#if defined(_64_) - 16, 16, 32, 32, 48, 64, 96, 128, -#else +#if defined(_64_) + 16, 16, 32, 32, 48, 64, 96, 128, +#else 8, 16, 24, @@ -200,7 +200,7 @@ const int nSizeIdxToSize[N_SIZES] = { 64, 96, 128, -#endif +#endif 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, #ifdef LFALLOC_YT @@ -214,11 +214,11 @@ const size_t N_MAX_FAST_SIZE = 32768; #endif const unsigned char size2idxArr1[64 + 1] = { 1, -#if defined(_64_) +#if defined(_64_) 2, 2, 4, 4, // 16, 16, 32, 32 -#else +#else 1, 2, 3, 4, // 8, 16, 24, 32 -#endif +#endif 5, 5, 6, 6, // 48, 64 7, 7, 7, 7, 8, 8, 8, 8, // 96, 128 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, // 192, 256 @@ -312,25 +312,25 @@ inline void VerifyMmapResult(void* result) { static char* AllocWithMMapLinuxImpl(uintptr_t sz, EMMapMode mode) { char* volatile* areaPtr; char* areaStart; - uintptr_t areaFinish; - + uintptr_t areaFinish; + int mapProt = PROT_READ | PROT_WRITE; int mapFlags = MAP_PRIVATE | MAP_ANON; - - if (mode == MM_HUGE) { - areaPtr = reinterpret_cast<char* volatile*>(&linuxAllocPointerHuge); - areaStart = reinterpret_cast<char*>(LINUX_MMAP_AREA_START + N_MAX_WORKSET_SIZE); - areaFinish = N_HUGE_AREA_FINISH; - } else { - areaPtr = reinterpret_cast<char* volatile*>(&linuxAllocPointer); - areaStart = reinterpret_cast<char*>(LINUX_MMAP_AREA_START); - areaFinish = N_MAX_WORKSET_SIZE; - - if (MapHugeTLB) { - mapFlags |= MAP_HUGETLB; - } - } - + + if (mode == MM_HUGE) { + areaPtr = reinterpret_cast<char* volatile*>(&linuxAllocPointerHuge); + areaStart = reinterpret_cast<char*>(LINUX_MMAP_AREA_START + N_MAX_WORKSET_SIZE); + areaFinish = N_HUGE_AREA_FINISH; + } else { + areaPtr = reinterpret_cast<char* volatile*>(&linuxAllocPointer); + areaStart = reinterpret_cast<char*>(LINUX_MMAP_AREA_START); + areaFinish = N_MAX_WORKSET_SIZE; + + if (MapHugeTLB) { + mapFlags |= MAP_HUGETLB; + } + } + bool wrapped = false; for (;;) { char* prevAllocPtr = *areaPtr; @@ -340,24 +340,24 @@ static char* AllocWithMMapLinuxImpl(uintptr_t sz, EMMapMode mode) { NMalloc::AbortFromCorruptedAllocator("virtual memory is over fragmented"); } // wrap after all area is used - DoCas(areaPtr, areaStart, prevAllocPtr); + DoCas(areaPtr, areaStart, prevAllocPtr); wrapped = true; continue; } - if (DoCas(areaPtr, nextAllocPtr, prevAllocPtr) != prevAllocPtr) + if (DoCas(areaPtr, nextAllocPtr, prevAllocPtr) != prevAllocPtr) continue; char* largeBlock = (char*)mmap(prevAllocPtr, sz, mapProt, mapFlags, -1, 0); VerifyMmapResult(largeBlock); if (largeBlock == prevAllocPtr) - return largeBlock; + return largeBlock; if (largeBlock) munmap(largeBlock, sz); if (sz < 0x80000) { // skip utilized area with big steps - DoCas(areaPtr, nextAllocPtr + 0x10 * 0x10000, nextAllocPtr); + DoCas(areaPtr, nextAllocPtr + 0x10 * 0x10000, nextAllocPtr); } } } @@ -367,14 +367,14 @@ static char* AllocWithMMap(uintptr_t sz, EMMapMode mode) { (void)mode; #ifdef _MSC_VER char* largeBlock = (char*)VirtualAlloc(0, sz, MEM_RESERVE, PAGE_READWRITE); - if (Y_UNLIKELY(largeBlock == nullptr)) + if (Y_UNLIKELY(largeBlock == nullptr)) NMalloc::AbortFromCorruptedAllocator("out of memory"); if (Y_UNLIKELY(uintptr_t(((char*)largeBlock - ALLOC_START) + sz) >= N_MAX_WORKSET_SIZE)) NMalloc::AbortFromCorruptedAllocator("out of working set, something has broken"); #else #if defined(_freebsd_) || !defined(_64_) char* largeBlock = (char*)mmap(0, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); - VerifyMmapResult(largeBlock); + VerifyMmapResult(largeBlock); if (Y_UNLIKELY(uintptr_t(((char*)largeBlock - ALLOC_START) + sz) >= N_MAX_WORKSET_SIZE)) NMalloc::AbortFromCorruptedAllocator("out of working set, something has broken"); #else @@ -384,7 +384,7 @@ static char* AllocWithMMap(uintptr_t sz, EMMapMode mode) { } #endif #endif - Y_ASSERT_NOBT(largeBlock); + Y_ASSERT_NOBT(largeBlock); IncrementCounter(CT_MMAP, sz); IncrementCounter(CT_MMAP_CNT, 1); return largeBlock; @@ -779,8 +779,8 @@ static bool DefragmentMem() { return false; } - IncrementCounter(CT_DEGRAGMENT_CNT, 1); - + IncrementCounter(CT_DEGRAGMENT_CNT, 1); + int* nFreeCount = (int*)SystemAlloc(N_CHUNKS * sizeof(int)); if (Y_UNLIKELY(!nFreeCount)) { //__debugbreak(); @@ -886,8 +886,8 @@ enum EDefrag { }; static void* SlowLFAlloc(int nSizeIdx, int blockSize, EDefrag defrag) { - IncrementCounter(CT_SLOW_ALLOC_CNT, 1); - + IncrementCounter(CT_SLOW_ALLOC_CNT, 1); + TLFLockHolder ls; for (;;) { bool locked = ls.TryLock(&LFGlobalLock); @@ -918,9 +918,9 @@ static void* SlowLFAlloc(int nSizeIdx, int blockSize, EDefrag defrag) { } char* largeBlock = AllocWithMMap(N_LARGE_ALLOC_SIZE, MM_NORMAL); - uintptr_t addr = ((largeBlock - ALLOC_START) + N_CHUNK_SIZE - 1) & (~(N_CHUNK_SIZE - 1)); - uintptr_t endAddr = ((largeBlock - ALLOC_START) + N_LARGE_ALLOC_SIZE) & (~(N_CHUNK_SIZE - 1)); - for (uintptr_t p = addr; p < endAddr; p += N_CHUNK_SIZE) { + uintptr_t addr = ((largeBlock - ALLOC_START) + N_CHUNK_SIZE - 1) & (~(N_CHUNK_SIZE - 1)); + uintptr_t endAddr = ((largeBlock - ALLOC_START) + N_LARGE_ALLOC_SIZE) & (~(N_CHUNK_SIZE - 1)); + for (uintptr_t p = addr; p < endAddr; p += N_CHUNK_SIZE) { uintptr_t chunk = p / N_CHUNK_SIZE; Y_ASSERT_NOBT(chunk * N_CHUNK_SIZE == p); Y_ASSERT_NOBT(chunkSizeIdx[chunk] == 0); @@ -1031,70 +1031,70 @@ struct TLocalCounter { } }; -//////////////////////////////////////////////////////////////////////////////// -// DBG stuff -//////////////////////////////////////////////////////////////////////////////// - -#if defined(LFALLOC_DBG) - -struct TPerTagAllocCounter { - TAtomic Size; - TAtomic Count; +//////////////////////////////////////////////////////////////////////////////// +// DBG stuff +//////////////////////////////////////////////////////////////////////////////// +#if defined(LFALLOC_DBG) + +struct TPerTagAllocCounter { + TAtomic Size; + TAtomic Count; + Y_FORCE_INLINE void Alloc(size_t size) { - AtomicAdd(Size, size); - AtomicAdd(Count, 1); - } - + AtomicAdd(Size, size); + AtomicAdd(Count, 1); + } + Y_FORCE_INLINE void Free(size_t size) { - AtomicSub(Size, size); - AtomicSub(Count, 1); - } -}; - -struct TLocalPerTagAllocCounter { - intptr_t Size; - int Count; - int Updates; - + AtomicSub(Size, size); + AtomicSub(Count, 1); + } +}; + +struct TLocalPerTagAllocCounter { + intptr_t Size; + int Count; + int Updates; + Y_FORCE_INLINE void Init() { - Size = 0; - Count = 0; - Updates = 0; - } - + Size = 0; + Count = 0; + Updates = 0; + } + Y_FORCE_INLINE void Alloc(TPerTagAllocCounter& parent, size_t size) { - Size += size; - ++Count; - if (++Updates > MAX_LOCAL_UPDATES) { - Flush(parent); - } - } - + Size += size; + ++Count; + if (++Updates > MAX_LOCAL_UPDATES) { + Flush(parent); + } + } + Y_FORCE_INLINE void Free(TPerTagAllocCounter& parent, size_t size) { - Size -= size; - --Count; - if (++Updates > MAX_LOCAL_UPDATES) { - Flush(parent); - } - } - + Size -= size; + --Count; + if (++Updates > MAX_LOCAL_UPDATES) { + Flush(parent); + } + } + Y_FORCE_INLINE void Flush(TPerTagAllocCounter& parent) { AtomicAdd(parent.Size, Size); Size = 0; AtomicAdd(parent.Count, Count); Count = 0; - Updates = 0; - } -}; - -static const int DBG_ALLOC_MAX_TAG = 1000; + Updates = 0; + } +}; + +static const int DBG_ALLOC_MAX_TAG = 1000; static const int DBG_ALLOC_ALIGNED_TAG = 0xF0000000; -static const int DBG_ALLOC_NUM_SIZES = 30; -static TPerTagAllocCounter GlobalPerTagAllocCounters[DBG_ALLOC_MAX_TAG][DBG_ALLOC_NUM_SIZES]; - +static const int DBG_ALLOC_NUM_SIZES = 30; +static TPerTagAllocCounter GlobalPerTagAllocCounters[DBG_ALLOC_MAX_TAG][DBG_ALLOC_NUM_SIZES]; + #endif // LFALLOC_DBG - + ////////////////////////////////////////////////////////////////////////// const int THREAD_BUF = 256; static int borderSizes[N_SIZES]; @@ -1107,9 +1107,9 @@ struct TThreadAllocInfo { TThreadAllocInfo* pNextInfo; TLocalCounter LocalCounters[CT_MAX]; -#if defined(LFALLOC_DBG) - TLocalPerTagAllocCounter LocalPerTagAllocCounters[DBG_ALLOC_MAX_TAG][DBG_ALLOC_NUM_SIZES]; -#endif +#if defined(LFALLOC_DBG) + TLocalPerTagAllocCounter LocalPerTagAllocCounters[DBG_ALLOC_MAX_TAG][DBG_ALLOC_NUM_SIZES]; +#endif #ifdef _win_ HANDLE hThread; #endif @@ -1136,14 +1136,14 @@ struct TThreadAllocInfo { for (int i = 0; i < CT_MAX; ++i) { LocalCounters[i].Init(&GlobalCounters[i]); } -#if defined(LFALLOC_DBG) - for (int tag = 0; tag < DBG_ALLOC_MAX_TAG; ++tag) { - for (int sizeIdx = 0; sizeIdx < DBG_ALLOC_NUM_SIZES; ++sizeIdx) { - auto& local = LocalPerTagAllocCounters[tag][sizeIdx]; - local.Init(); - } - } -#endif +#if defined(LFALLOC_DBG) + for (int tag = 0; tag < DBG_ALLOC_MAX_TAG; ++tag) { + for (int sizeIdx = 0; sizeIdx < DBG_ALLOC_NUM_SIZES; ++sizeIdx) { + auto& local = LocalPerTagAllocCounters[tag][sizeIdx]; + local.Init(); + } + } +#endif } void Done() { for (auto sizeIdx : FreePtrIndex) { @@ -1152,15 +1152,15 @@ struct TThreadAllocInfo { for (auto& localCounter : LocalCounters) { localCounter.Flush(); } -#if defined(LFALLOC_DBG) - for (int tag = 0; tag < DBG_ALLOC_MAX_TAG; ++tag) { - for (int sizeIdx = 0; sizeIdx < DBG_ALLOC_NUM_SIZES; ++sizeIdx) { - auto& local = LocalPerTagAllocCounters[tag][sizeIdx]; - auto& global = GlobalPerTagAllocCounters[tag][sizeIdx]; - local.Flush(global); - } - } -#endif +#if defined(LFALLOC_DBG) + for (int tag = 0; tag < DBG_ALLOC_MAX_TAG; ++tag) { + for (int sizeIdx = 0; sizeIdx < DBG_ALLOC_NUM_SIZES; ++sizeIdx) { + auto& local = LocalPerTagAllocCounters[tag][sizeIdx]; + auto& global = GlobalPerTagAllocCounters[tag][sizeIdx]; + local.Flush(global); + } + } +#endif #ifdef _win_ if (hThread) CloseHandle(hThread); @@ -1304,21 +1304,21 @@ static void AllocThreadInfo() { // DBG stuff ////////////////////////////////////////////////////////////////////////// -#if defined(LFALLOC_DBG) +#if defined(LFALLOC_DBG) -struct TAllocHeader { +struct TAllocHeader { uint64_t Size; int Tag; - int Cookie; -}; - + int Cookie; +}; + // should be power of 2 static_assert(sizeof(TAllocHeader) == 16); static inline void* GetAllocPtr(TAllocHeader* p) { - return p + 1; -} - + return p + 1; +} + static inline TAllocHeader* GetAllocHeader(void* p) { auto* header = ((TAllocHeader*)p) - 1; if (header->Tag == DBG_ALLOC_ALIGNED_TAG) { @@ -1326,24 +1326,24 @@ static inline TAllocHeader* GetAllocHeader(void* p) { } return header; -} - -PERTHREAD int AllocationTag; +} + +PERTHREAD int AllocationTag; extern "C" int SetThreadAllocTag(int tag) { - int prevTag = AllocationTag; + int prevTag = AllocationTag; if (tag < DBG_ALLOC_MAX_TAG && tag >= 0) { - AllocationTag = tag; - } - return prevTag; -} - -PERTHREAD bool ProfileCurrentThread; + AllocationTag = tag; + } + return prevTag; +} + +PERTHREAD bool ProfileCurrentThread; extern "C" bool SetProfileCurrentThread(bool newVal) { - bool prevVal = ProfileCurrentThread; - ProfileCurrentThread = newVal; - return prevVal; -} - + bool prevVal = ProfileCurrentThread; + ProfileCurrentThread = newVal; + return prevVal; +} + static volatile bool ProfileAllThreads; extern "C" bool SetProfileAllThreads(bool newVal) { bool prevVal = ProfileAllThreads; @@ -1351,176 +1351,176 @@ extern "C" bool SetProfileAllThreads(bool newVal) { return prevVal; } -static volatile bool AllocationSamplingEnabled; +static volatile bool AllocationSamplingEnabled; extern "C" bool SetAllocationSamplingEnabled(bool newVal) { - bool prevVal = AllocationSamplingEnabled; - AllocationSamplingEnabled = newVal; - return prevVal; -} - -static size_t AllocationSampleRate = 1000; + bool prevVal = AllocationSamplingEnabled; + AllocationSamplingEnabled = newVal; + return prevVal; +} + +static size_t AllocationSampleRate = 1000; extern "C" size_t SetAllocationSampleRate(size_t newVal) { - size_t prevVal = AllocationSampleRate; - AllocationSampleRate = newVal; - return prevVal; -} - -static size_t AllocationSampleMaxSize = N_MAX_FAST_SIZE; + size_t prevVal = AllocationSampleRate; + AllocationSampleRate = newVal; + return prevVal; +} + +static size_t AllocationSampleMaxSize = N_MAX_FAST_SIZE; extern "C" size_t SetAllocationSampleMaxSize(size_t newVal) { - size_t prevVal = AllocationSampleMaxSize; - AllocationSampleMaxSize = newVal; - return prevVal; -} - -using TAllocationCallback = int(int tag, size_t size, int sizeIdx); -static TAllocationCallback* AllocationCallback; + size_t prevVal = AllocationSampleMaxSize; + AllocationSampleMaxSize = newVal; + return prevVal; +} + +using TAllocationCallback = int(int tag, size_t size, int sizeIdx); +static TAllocationCallback* AllocationCallback; extern "C" TAllocationCallback* SetAllocationCallback(TAllocationCallback* newVal) { - TAllocationCallback* prevVal = AllocationCallback; - AllocationCallback = newVal; - return prevVal; -} - -using TDeallocationCallback = void(int cookie, int tag, size_t size, int sizeIdx); -static TDeallocationCallback* DeallocationCallback; + TAllocationCallback* prevVal = AllocationCallback; + AllocationCallback = newVal; + return prevVal; +} + +using TDeallocationCallback = void(int cookie, int tag, size_t size, int sizeIdx); +static TDeallocationCallback* DeallocationCallback; extern "C" TDeallocationCallback* SetDeallocationCallback(TDeallocationCallback* newVal) { - TDeallocationCallback* prevVal = DeallocationCallback; - DeallocationCallback = newVal; - return prevVal; -} - -PERTHREAD TAtomic AllocationsCount; -PERTHREAD bool InAllocationCallback; - -static const int DBG_ALLOC_INVALID_COOKIE = -1; + TDeallocationCallback* prevVal = DeallocationCallback; + DeallocationCallback = newVal; + return prevVal; +} + +PERTHREAD TAtomic AllocationsCount; +PERTHREAD bool InAllocationCallback; + +static const int DBG_ALLOC_INVALID_COOKIE = -1; static inline int SampleAllocation(TAllocHeader* p, int sizeIdx) { - int cookie = DBG_ALLOC_INVALID_COOKIE; + int cookie = DBG_ALLOC_INVALID_COOKIE; if (AllocationSamplingEnabled && (ProfileCurrentThread || ProfileAllThreads) && !InAllocationCallback) { - if (p->Size > AllocationSampleMaxSize || ++AllocationsCount % AllocationSampleRate == 0) { - if (AllocationCallback) { - InAllocationCallback = true; - cookie = AllocationCallback(p->Tag, p->Size, sizeIdx); - InAllocationCallback = false; - } - } - } - return cookie; -} - + if (p->Size > AllocationSampleMaxSize || ++AllocationsCount % AllocationSampleRate == 0) { + if (AllocationCallback) { + InAllocationCallback = true; + cookie = AllocationCallback(p->Tag, p->Size, sizeIdx); + InAllocationCallback = false; + } + } + } + return cookie; +} + static inline void SampleDeallocation(TAllocHeader* p, int sizeIdx) { - if (p->Cookie != DBG_ALLOC_INVALID_COOKIE && !InAllocationCallback) { - if (DeallocationCallback) { - InAllocationCallback = true; - DeallocationCallback(p->Cookie, p->Tag, p->Size, sizeIdx); - InAllocationCallback = false; - } - } -} - + if (p->Cookie != DBG_ALLOC_INVALID_COOKIE && !InAllocationCallback) { + if (DeallocationCallback) { + InAllocationCallback = true; + DeallocationCallback(p->Cookie, p->Tag, p->Size, sizeIdx); + InAllocationCallback = false; + } + } +} + static inline void TrackPerTagAllocation(TAllocHeader* p, int sizeIdx) { if (p->Tag < DBG_ALLOC_MAX_TAG && p->Tag >= 0) { Y_ASSERT_NOBT(sizeIdx < DBG_ALLOC_NUM_SIZES); - auto& global = GlobalPerTagAllocCounters[p->Tag][sizeIdx]; - - TThreadAllocInfo* thr = pThreadInfo; - if (thr) { - auto& local = thr->LocalPerTagAllocCounters[p->Tag][sizeIdx]; - local.Alloc(global, p->Size); - } else { - global.Alloc(p->Size); - } - } -} - + auto& global = GlobalPerTagAllocCounters[p->Tag][sizeIdx]; + + TThreadAllocInfo* thr = pThreadInfo; + if (thr) { + auto& local = thr->LocalPerTagAllocCounters[p->Tag][sizeIdx]; + local.Alloc(global, p->Size); + } else { + global.Alloc(p->Size); + } + } +} + static inline void TrackPerTagDeallocation(TAllocHeader* p, int sizeIdx) { if (p->Tag < DBG_ALLOC_MAX_TAG && p->Tag >= 0) { Y_ASSERT_NOBT(sizeIdx < DBG_ALLOC_NUM_SIZES); - auto& global = GlobalPerTagAllocCounters[p->Tag][sizeIdx]; - - TThreadAllocInfo* thr = pThreadInfo; - if (thr) { - auto& local = thr->LocalPerTagAllocCounters[p->Tag][sizeIdx]; - local.Free(global, p->Size); - } else { - global.Free(p->Size); - } - } -} - + auto& global = GlobalPerTagAllocCounters[p->Tag][sizeIdx]; + + TThreadAllocInfo* thr = pThreadInfo; + if (thr) { + auto& local = thr->LocalPerTagAllocCounters[p->Tag][sizeIdx]; + local.Free(global, p->Size); + } else { + global.Free(p->Size); + } + } +} + static void* TrackAllocation(void* ptr, size_t size, int sizeIdx) { - TAllocHeader* p = (TAllocHeader*)ptr; - p->Size = size; - p->Tag = AllocationTag; - p->Cookie = SampleAllocation(p, sizeIdx); - TrackPerTagAllocation(p, sizeIdx); - return GetAllocPtr(p); -} - + TAllocHeader* p = (TAllocHeader*)ptr; + p->Size = size; + p->Tag = AllocationTag; + p->Cookie = SampleAllocation(p, sizeIdx); + TrackPerTagAllocation(p, sizeIdx); + return GetAllocPtr(p); +} + static void TrackDeallocation(void* ptr, int sizeIdx) { - TAllocHeader* p = (TAllocHeader*)ptr; - SampleDeallocation(p, sizeIdx); - TrackPerTagDeallocation(p, sizeIdx); -} - -struct TPerTagAllocInfo { - ssize_t Count; - ssize_t Size; -}; - -extern "C" void GetPerTagAllocInfo( - bool flushPerThreadCounters, - TPerTagAllocInfo* info, - int& maxTag, + TAllocHeader* p = (TAllocHeader*)ptr; + SampleDeallocation(p, sizeIdx); + TrackPerTagDeallocation(p, sizeIdx); +} + +struct TPerTagAllocInfo { + ssize_t Count; + ssize_t Size; +}; + +extern "C" void GetPerTagAllocInfo( + bool flushPerThreadCounters, + TPerTagAllocInfo* info, + int& maxTag, int& numSizes) { - maxTag = DBG_ALLOC_MAX_TAG; - numSizes = DBG_ALLOC_NUM_SIZES; - - if (info) { - if (flushPerThreadCounters) { + maxTag = DBG_ALLOC_MAX_TAG; + numSizes = DBG_ALLOC_NUM_SIZES; + + if (info) { + if (flushPerThreadCounters) { TLFLockHolder ll(&LFLockThreadInfo); for (TThreadAllocInfo** p = &pThreadInfoList; *p;) { TThreadAllocInfo* pInfo = *p; - for (int tag = 0; tag < DBG_ALLOC_MAX_TAG; ++tag) { - for (int sizeIdx = 0; sizeIdx < DBG_ALLOC_NUM_SIZES; ++sizeIdx) { - auto& local = pInfo->LocalPerTagAllocCounters[tag][sizeIdx]; - auto& global = GlobalPerTagAllocCounters[tag][sizeIdx]; - local.Flush(global); - } - } - p = &pInfo->pNextInfo; - } - } - - for (int tag = 0; tag < DBG_ALLOC_MAX_TAG; ++tag) { - for (int sizeIdx = 0; sizeIdx < DBG_ALLOC_NUM_SIZES; ++sizeIdx) { - auto& global = GlobalPerTagAllocCounters[tag][sizeIdx]; + for (int tag = 0; tag < DBG_ALLOC_MAX_TAG; ++tag) { + for (int sizeIdx = 0; sizeIdx < DBG_ALLOC_NUM_SIZES; ++sizeIdx) { + auto& local = pInfo->LocalPerTagAllocCounters[tag][sizeIdx]; + auto& global = GlobalPerTagAllocCounters[tag][sizeIdx]; + local.Flush(global); + } + } + p = &pInfo->pNextInfo; + } + } + + for (int tag = 0; tag < DBG_ALLOC_MAX_TAG; ++tag) { + for (int sizeIdx = 0; sizeIdx < DBG_ALLOC_NUM_SIZES; ++sizeIdx) { + auto& global = GlobalPerTagAllocCounters[tag][sizeIdx]; auto& res = info[tag * DBG_ALLOC_NUM_SIZES + sizeIdx]; - res.Count = global.Count; - res.Size = global.Size; - } - } - } -} - + res.Count = global.Count; + res.Size = global.Size; + } + } + } +} + #endif // LFALLOC_DBG - + ////////////////////////////////////////////////////////////////////////// static Y_FORCE_INLINE void* LFAllocImpl(size_t _nSize) { -#if defined(LFALLOC_DBG) - size_t size = _nSize; - _nSize += sizeof(TAllocHeader); -#endif - +#if defined(LFALLOC_DBG) + size_t size = _nSize; + _nSize += sizeof(TAllocHeader); +#endif + IncrementCounter(CT_USER_ALLOC, _nSize); int nSizeIdx; if (_nSize > 512) { - if (_nSize > N_MAX_FAST_SIZE) { - void* ptr = LargeBlockAlloc(_nSize, CT_LARGE_ALLOC); -#if defined(LFALLOC_DBG) - ptr = TrackAllocation(ptr, size, N_SIZES); -#endif - return ptr; - } + if (_nSize > N_MAX_FAST_SIZE) { + void* ptr = LargeBlockAlloc(_nSize, CT_LARGE_ALLOC); +#if defined(LFALLOC_DBG) + ptr = TrackAllocation(ptr, size, N_SIZES); +#endif + return ptr; + } nSizeIdx = size2idxArr2[(_nSize - 1) >> 8]; } else nSizeIdx = size2idxArr1[1 + (((int)_nSize - 1) >> 3)]; @@ -1533,22 +1533,22 @@ static Y_FORCE_INLINE void* LFAllocImpl(size_t _nSize) { AllocThreadInfo(); thr = pThreadInfo; if (!thr) { - void* ptr = LFAllocNoCache(nSizeIdx, MEM_DEFRAG); -#if defined(LFALLOC_DBG) - ptr = TrackAllocation(ptr, size, nSizeIdx); -#endif - return ptr; + void* ptr = LFAllocNoCache(nSizeIdx, MEM_DEFRAG); +#if defined(LFALLOC_DBG) + ptr = TrackAllocation(ptr, size, nSizeIdx); +#endif + return ptr; } } { int& freePtrIdx = thr->FreePtrIndex[nSizeIdx]; - if (freePtrIdx < THREAD_BUF) { - void* ptr = thr->FreePtrs[nSizeIdx][freePtrIdx++]; -#if defined(LFALLOC_DBG) - ptr = TrackAllocation(ptr, size, nSizeIdx); -#endif - return ptr; - } + if (freePtrIdx < THREAD_BUF) { + void* ptr = thr->FreePtrs[nSizeIdx][freePtrIdx++]; +#if defined(LFALLOC_DBG) + ptr = TrackAllocation(ptr, size, nSizeIdx); +#endif + return ptr; + } // try to alloc from global free list char* buf[FL_GROUP_SIZE]; @@ -1563,11 +1563,11 @@ static Y_FORCE_INLINE void* LFAllocImpl(size_t _nSize) { for (int i = 0; i < count - 1; ++i) dstBuf[-i] = buf[i]; freePtrIdx -= count - 1; - void* ptr = buf[count - 1]; -#if defined(LFALLOC_DBG) - ptr = TrackAllocation(ptr, size, nSizeIdx); -#endif - return ptr; + void* ptr = buf[count - 1]; +#if defined(LFALLOC_DBG) + ptr = TrackAllocation(ptr, size, nSizeIdx); +#endif + return ptr; } } @@ -1582,33 +1582,33 @@ static Y_FORCE_INLINE void* LFAlloc(size_t _nSize) { } static Y_FORCE_INLINE void LFFree(void* p) { -#if defined(LFALLOC_DBG) - if (p == nullptr) - return; - p = GetAllocHeader(p); -#endif - +#if defined(LFALLOC_DBG) + if (p == nullptr) + return; + p = GetAllocHeader(p); +#endif + uintptr_t chkOffset = ((char*)p - ALLOC_START) - 1ll; if (chkOffset >= N_MAX_WORKSET_SIZE) { if (p == nullptr) return; -#if defined(LFALLOC_DBG) - TrackDeallocation(p, N_SIZES); -#endif +#if defined(LFALLOC_DBG) + TrackDeallocation(p, N_SIZES); +#endif LargeBlockFree(p, CT_LARGE_FREE); return; } - + uintptr_t chunk = ((char*)p - ALLOC_START) / N_CHUNK_SIZE; ptrdiff_t nSizeIdx = chunkSizeIdx[chunk]; if (nSizeIdx <= 0) { -#if defined(LFALLOC_DBG) - TrackDeallocation(p, N_SIZES); -#endif +#if defined(LFALLOC_DBG) + TrackDeallocation(p, N_SIZES); +#endif LargeBlockFree(p, CT_LARGE_FREE); return; } - + #if defined(LFALLOC_DBG) TrackDeallocation(p, nSizeIdx); #endif @@ -1645,12 +1645,12 @@ static Y_FORCE_INLINE void LFFree(void* p) { } static size_t LFGetSize(const void* p) { -#if defined(LFALLOC_DBG) - if (p == nullptr) - return 0; +#if defined(LFALLOC_DBG) + if (p == nullptr) + return 0; return GetAllocHeader(const_cast<void*>(p))->Size; -#endif - +#endif + uintptr_t chkOffset = ((const char*)p - ALLOC_START); if (chkOffset >= N_MAX_WORKSET_SIZE) { if (p == nullptr) @@ -1827,10 +1827,10 @@ static bool LFAlloc_SetParam(const char* param, const char* value) { TransparentHugePages = !strcmp(value, "true"); return true; } - if (!strcmp(param, "MapHugeTLB")) { - MapHugeTLB = !strcmp(value, "true"); - return true; - } + if (!strcmp(param, "MapHugeTLB")) { + MapHugeTLB = !strcmp(value, "true"); + return true; + } if (!strcmp(param, "EnableDefrag")) { EnableDefrag = !strcmp(value, "true"); return true; @@ -1839,15 +1839,15 @@ static bool LFAlloc_SetParam(const char* param, const char* value) { }; static const char* LFAlloc_GetParam(const char* param) { - struct TParam { - const char* Name; - const char* Value; - }; - - static const TParam Params[] = { + struct TParam { + const char* Name; + const char* Value; + }; + + static const TParam Params[] = { {"GetLFAllocCounterFast", (const char*)&GetLFAllocCounterFast}, {"GetLFAllocCounterFull", (const char*)&GetLFAllocCounterFull}, -#if defined(LFALLOC_DBG) +#if defined(LFALLOC_DBG) {"SetThreadAllocTag", (const char*)&SetThreadAllocTag}, {"SetProfileCurrentThread", (const char*)&SetProfileCurrentThread}, {"SetProfileAllThreads", (const char*)&SetProfileAllThreads}, @@ -1858,12 +1858,12 @@ static const char* LFAlloc_GetParam(const char* param) { {"SetDeallocationCallback", (const char*)&SetDeallocationCallback}, {"GetPerTagAllocInfo", (const char*)&GetPerTagAllocInfo}, #endif // LFALLOC_DBG - }; - - for (int i = 0; i < Y_ARRAY_SIZE(Params); ++i) { - if (strcmp(param, Params[i].Name) == 0) { - return Params[i].Value; - } + }; + + for (int i = 0; i < Y_ARRAY_SIZE(Params); ++i) { + if (strcmp(param, Params[i].Name) == 0) { + return Params[i].Value; + } } return nullptr; } diff --git a/library/cpp/messagebus/actor/executor.cpp b/library/cpp/messagebus/actor/executor.cpp index 7a2227a458..d0ed3647fa 100644 --- a/library/cpp/messagebus/actor/executor.cpp +++ b/library/cpp/messagebus/actor/executor.cpp @@ -176,7 +176,7 @@ TExecutor::TExecutor(const TExecutor::TConfig& config) void TExecutor::Init() { Impl.Reset(new TImpl(this)); - AtomicSet(ExitWorkers, 0); + AtomicSet(ExitWorkers, 0); Y_VERIFY(Config.WorkerCount > 0); @@ -192,7 +192,7 @@ TExecutor::~TExecutor() { } void TExecutor::Stop() { - AtomicSet(ExitWorkers, 1); + AtomicSet(ExitWorkers, 1); Impl->HelperStopSignal.Signal(); Impl->HelperThread.Join(); @@ -214,7 +214,7 @@ void TExecutor::EnqueueWork(TArrayRef<IWorkItem* const> wis) { if (wis.empty()) return; - if (Y_UNLIKELY(AtomicGet(ExitWorkers) != 0)) { + if (Y_UNLIKELY(AtomicGet(ExitWorkers) != 0)) { Y_VERIFY(WorkItems.Empty(), "executor %s: cannot add tasks after queue shutdown", Config.Name); } @@ -289,7 +289,7 @@ TAutoPtr<IWorkItem> TExecutor::DequeueWork() { if (!WorkItems.TryPop(&wi, &queueSize)) { TWhatThreadDoesAcquireGuard<TMutex> g(WorkMutex, "executor: acquiring lock for DequeueWork"); while (!WorkItems.TryPop(&wi, &queueSize)) { - if (AtomicGet(ExitWorkers) != 0) + if (AtomicGet(ExitWorkers) != 0) return nullptr; TWhatThreadDoesPushPop pp("waiting for work on condvar"); diff --git a/library/cpp/messagebus/actor/ring_buffer_with_spin_lock.h b/library/cpp/messagebus/actor/ring_buffer_with_spin_lock.h index f0b7cd90e4..b49bfd6cfb 100644 --- a/library/cpp/messagebus/actor/ring_buffer_with_spin_lock.h +++ b/library/cpp/messagebus/actor/ring_buffer_with_spin_lock.h @@ -9,11 +9,11 @@ class TRingBufferWithSpinLock { private: TRingBuffer<T> RingBuffer; TSpinLock SpinLock; - TAtomic CachedSize; - + TAtomic CachedSize; + public: TRingBufferWithSpinLock() - : CachedSize(0) + : CachedSize(0) { } @@ -28,11 +28,11 @@ public: TGuard<TSpinLock> Guard(SpinLock); RingBuffer.PushAll(collection); - AtomicSet(CachedSize, RingBuffer.Size()); + AtomicSet(CachedSize, RingBuffer.Size()); } bool TryPop(T* r, size_t* sizePtr = nullptr) { - if (AtomicGet(CachedSize) == 0) { + if (AtomicGet(CachedSize) == 0) { return false; } @@ -42,7 +42,7 @@ public: TGuard<TSpinLock> Guard(SpinLock); ok = RingBuffer.TryPop(r); size = RingBuffer.Size(); - AtomicSet(CachedSize, size); + AtomicSet(CachedSize, size); } if (!!sizePtr) { *sizePtr = size; @@ -63,25 +63,25 @@ public: if (collection.size() == 0) { return TryPop(r); } else { - if (AtomicGet(CachedSize) == 0) { + if (AtomicGet(CachedSize) == 0) { *r = collection[0]; if (collection.size() > 1) { TGuard<TSpinLock> guard(SpinLock); RingBuffer.PushAll(MakeArrayRef(collection.data() + 1, collection.size() - 1)); - AtomicSet(CachedSize, RingBuffer.Size()); + AtomicSet(CachedSize, RingBuffer.Size()); } } else { TGuard<TSpinLock> guard(SpinLock); RingBuffer.PushAll(collection); *r = RingBuffer.Pop(); - AtomicSet(CachedSize, RingBuffer.Size()); + AtomicSet(CachedSize, RingBuffer.Size()); } return true; } } bool Empty() const { - return AtomicGet(CachedSize) == 0; + return AtomicGet(CachedSize) == 0; } size_t Size() const { diff --git a/library/cpp/messagebus/event_loop.cpp b/library/cpp/messagebus/event_loop.cpp index f685135bed..6946ccdea4 100644 --- a/library/cpp/messagebus/event_loop.cpp +++ b/library/cpp/messagebus/event_loop.cpp @@ -79,7 +79,7 @@ public: const char* Name; TAtomic RunningState; - TAtomic StopSignal; + TAtomic StopSignal; TSystemEvent StoppedEvent; TData Data; @@ -255,7 +255,7 @@ void TChannel::TImpl::CallHandler() { TEventLoop::TImpl::TImpl(const char* name) : Name(name) , RunningState(EVENT_LOOP_CREATED) - , StopSignal(0) + , StopSignal(0) { SOCKET wakeupSockets[2]; @@ -284,7 +284,7 @@ void TEventLoop::TImpl::Run() { SetCurrentThreadName(Name); } - while (AtomicGet(StopSignal) == 0) { + while (AtomicGet(StopSignal) == 0) { void* cookies[1024]; const size_t count = Poller.WaitI(cookies, Y_ARRAY_SIZE(cookies)); @@ -328,7 +328,7 @@ void TEventLoop::TImpl::Run() { } void TEventLoop::TImpl::Stop() { - AtomicSet(StopSignal, 1); + AtomicSet(StopSignal, 1); if (AtomicGet(RunningState) == EVENT_LOOP_RUNNING) { Wakeup(); diff --git a/library/cpp/messagebus/futex_like.h b/library/cpp/messagebus/futex_like.h index 31d60c60f1..f40594918f 100644 --- a/library/cpp/messagebus/futex_like.h +++ b/library/cpp/messagebus/futex_like.h @@ -39,7 +39,7 @@ public: #ifdef _linux_ return __atomic_exchange_n(&Value, newValue, __ATOMIC_SEQ_CST); #else - return AtomicSwap(&Value, newValue); + return AtomicSwap(&Value, newValue); #endif } #endif diff --git a/library/cpp/messagebus/misc/tokenquota.h b/library/cpp/messagebus/misc/tokenquota.h index 190547fa54..656da42b10 100644 --- a/library/cpp/messagebus/misc/tokenquota.h +++ b/library/cpp/messagebus/misc/tokenquota.h @@ -29,7 +29,7 @@ namespace NBus { level = Max(TAtomicBase(level), TAtomicBase(1)); if (Enabled && (Acquired < level || force)) { - Acquired += AtomicSwap(&Tokens_, 0); + Acquired += AtomicSwap(&Tokens_, 0); } return !Enabled || Acquired >= level; diff --git a/library/cpp/protobuf/json/ut/json2proto_ut.cpp b/library/cpp/protobuf/json/ut/json2proto_ut.cpp index 0dfe57bc7a..fb3139d055 100644 --- a/library/cpp/protobuf/json/ut/json2proto_ut.cpp +++ b/library/cpp/protobuf/json/ut/json2proto_ut.cpp @@ -636,21 +636,21 @@ Y_UNIT_TEST(TestCastFromString) { Y_UNIT_TEST(TestMap) { TMapType modelProto; - + auto& items = *modelProto.MutableItems(); items["key1"] = "value1"; items["key2"] = "value2"; items["key3"] = "value3"; - + TString modelStr(R"_({"Items":[{"key":"key3","value":"value3"},{"key":"key2","value":"value2"},{"key":"key1","value":"value1"}]})_"); - + TJson2ProtoConfig config; TMapType proto; UNIT_ASSERT_NO_EXCEPTION(proto = Json2Proto<TMapType>(modelStr, config)); - + UNIT_ASSERT_PROTOS_EQUAL(proto, modelProto); } // TestMap - + Y_UNIT_TEST(TestCastRobust) { NJson::TJsonValue json; json["I32"] = "5"; diff --git a/library/cpp/protobuf/json/ut/proto2json_ut.cpp b/library/cpp/protobuf/json/ut/proto2json_ut.cpp index 07e52d7f2f..faab2efeaf 100644 --- a/library/cpp/protobuf/json/ut/proto2json_ut.cpp +++ b/library/cpp/protobuf/json/ut/proto2json_ut.cpp @@ -901,21 +901,21 @@ Y_UNIT_TEST(TestInf) { UNIT_ASSERT_EXCEPTION(Proto2Json(proto, TProto2JsonConfig()), yexception); } // TestInf - + Y_UNIT_TEST(TestMap) { TMapType proto; - + auto& items = *proto.MutableItems(); items["key1"] = "value1"; items["key2"] = "value2"; items["key3"] = "value3"; - + TString modelStr(R"_({"Items":[{"key":"key3","value":"value3"},{"key":"key2","value":"value2"},{"key":"key1","value":"value1"}]})_"); - + TStringStream jsonStr; TProto2JsonConfig config; UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr, config)); - + NJson::TJsonValue jsonValue, modelValue; NJson::TJsonValue::TArray jsonItems, modelItems; UNIT_ASSERT(NJson::ReadJsonTree(jsonStr.Str(), &jsonValue)); @@ -930,7 +930,7 @@ Y_UNIT_TEST(TestMap) { SortBy(modelItems, itemKey); UNIT_ASSERT_EQUAL(jsonItems, modelItems); } // TestMap - + Y_UNIT_TEST(TestMapAsObject) { TMapType proto; @@ -951,20 +951,20 @@ Y_UNIT_TEST(TestMapAsObject) { Y_UNIT_TEST(TestMapWTF) { TMapType proto; - + auto& items = *proto.MutableItems(); items["key1"] = "value1"; items["key2"] = "value2"; items["key3"] = "value3"; - + TString modelStr(R"_({"Items":{"key3":"value3","key2":"value2","key1":"value1"}})_"); - + TStringStream jsonStr; UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr)); - + UNIT_ASSERT_JSON_STRINGS_EQUAL(jsonStr.Str(), modelStr); } // TestMapWTF - + Y_UNIT_TEST(TestStringifyLongNumbers) { #define TEST_SINGLE(flag, value, expectString) \ do { \ diff --git a/library/cpp/protobuf/json/ut/test.proto b/library/cpp/protobuf/json/ut/test.proto index 0fa996fd41..8449399c81 100644 --- a/library/cpp/protobuf/json/ut/test.proto +++ b/library/cpp/protobuf/json/ut/test.proto @@ -130,10 +130,10 @@ message TCompositeRequired { message TCompositeRepeated { repeated TFlatOptional Part = 1; }; - + message TMapType { - map<string, string> Items = 1; -}; + map<string, string> Items = 1; +}; message TNameGeneratorType { optional int32 Field = 1; diff --git a/library/cpp/scheme/scheme.h b/library/cpp/scheme/scheme.h index 3d7c59f3c9..857a7fb9e0 100644 --- a/library/cpp/scheme/scheme.h +++ b/library/cpp/scheme/scheme.h @@ -388,7 +388,7 @@ namespace NSc { static TValue From(const ::google::protobuf::Message&, bool mapAsDict = false); void To(::google::protobuf::Message&, const TProtoOpts& opts = {}) const; - + public: inline explicit TValue(TPoolPtr&); @@ -420,7 +420,7 @@ namespace NSc { static TValue FromField(const ::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*); static TValue FromRepeatedField(const ::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*, int index); - + void ValueToField(const TValue& value, ::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*, const TProtoOpts& opts) const; void ToField(::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*, const TProtoOpts& opts) const; void ToEnumField(::google::protobuf::Message&, const ::google::protobuf::FieldDescriptor*, const TProtoOpts& opts) const; diff --git a/library/cpp/scheme/scimpl_protobuf.cpp b/library/cpp/scheme/scimpl_protobuf.cpp index 0c99122c69..e24be0aad3 100644 --- a/library/cpp/scheme/scimpl_protobuf.cpp +++ b/library/cpp/scheme/scimpl_protobuf.cpp @@ -130,41 +130,41 @@ namespace NSc { } void TValue::To(Message& msg, const TProtoOpts& opts) const { - msg.Clear(); - - if (IsNull()) { - return; - } - - if (!IsDict()) { - ythrow TSchemeException() << "expected dictionary"; - } - - const Descriptor* descriptor = msg.GetDescriptor(); - for (int i = 0, count = descriptor->field_count(); i < count; ++i) { - const FieldDescriptor* field = descriptor->field(i); + msg.Clear(); + + if (IsNull()) { + return; + } + + if (!IsDict()) { + ythrow TSchemeException() << "expected dictionary"; + } + + const Descriptor* descriptor = msg.GetDescriptor(); + for (int i = 0, count = descriptor->field_count(); i < count; ++i) { + const FieldDescriptor* field = descriptor->field(i); if (field->is_map()) { ToMapField(msg, field, opts); } else if (field->is_repeated()) { ToRepeatedField(msg, field, opts); - } else { + } else { ToField(msg, field, opts); - } - } - } - + } + } + } + void TValue::ValueToField(const TValue& value, Message& msg, const FieldDescriptor* field, const TProtoOpts& opts) const { const TString& name = field->name(); - if (value.IsNull()) { - if (field->is_required() && !field->has_default_value()) { - ythrow TSchemeException() << "has no value for required field " << name; - } - return; - } - - const Reflection* reflection = msg.GetReflection(); - - switch (field->cpp_type()) { + if (value.IsNull()) { + if (field->is_required() && !field->has_default_value()) { + ythrow TSchemeException() << "has no value for required field " << name; + } + return; + } + + const Reflection* reflection = msg.GetReflection(); + + switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: reflection->SetInt32(&msg, field, value.ForceIntNumber()); break; @@ -199,9 +199,9 @@ namespace NSc { ythrow TSchemeException() << "field " << field->full_name() << " unexpected type " << (int)field->cpp_type(); - } - } - + } + } + void TValue::ToField(Message& msg, const FieldDescriptor* field, const TProtoOpts& opts) const { const TString& name = field->name(); const TValue& value = Get(name); @@ -209,49 +209,49 @@ namespace NSc { } void TValue::ToEnumField(Message& msg, const FieldDescriptor* field, const TProtoOpts& opts) const { - const EnumDescriptor* enumField = field->enum_type(); - - const EnumValueDescriptor* enumFieldValue = IsString() + const EnumDescriptor* enumField = field->enum_type(); + + const EnumValueDescriptor* enumFieldValue = IsString() ? enumField->FindValueByName(ForceString()) : enumField->FindValueByNumber(ForceIntNumber()); - - if (!enumFieldValue) { + + if (!enumFieldValue) { if (opts.UnknownEnumValueIsDefault) { enumFieldValue = field->default_value_enum(); } else { ythrow TSchemeException() << "invalid value of enum field " << field->name(); } - } - - const Reflection* reflection = msg.GetReflection(); - - if (field->is_repeated()) { - reflection->AddEnum(&msg, field, enumFieldValue); - } else { - reflection->SetEnum(&msg, field, enumFieldValue); - } - } - + } + + const Reflection* reflection = msg.GetReflection(); + + if (field->is_repeated()) { + reflection->AddEnum(&msg, field, enumFieldValue); + } else { + reflection->SetEnum(&msg, field, enumFieldValue); + } + } + void TValue::ToRepeatedField(Message& msg, const FieldDescriptor* field, const TProtoOpts& opts) const { const TString& name = field->name(); - - const TValue& fieldValue = Get(name); - if (fieldValue.IsNull()) { - return; - } - - if (!fieldValue.IsArray()) { + + const TValue& fieldValue = Get(name); + if (fieldValue.IsNull()) { + return; + } + + if (!fieldValue.IsArray()) { if (opts.SkipTypeMismatch) { return; // leave repeated field empty } else { ythrow TSchemeException() << "invalid type of repeated field " << name << ": not an array"; } - } - - const Reflection* reflection = msg.GetReflection(); - + } + + const Reflection* reflection = msg.GetReflection(); + for (const TValue& value : fieldValue.GetArray()) { - switch (field->cpp_type()) { + switch (field->cpp_type()) { case FieldDescriptor::CPPTYPE_INT32: reflection->AddInt32(&msg, field, value.ForceIntNumber()); break; @@ -286,10 +286,10 @@ namespace NSc { ythrow TSchemeException() << "field " << field->full_name() << " unexpected type " << (int)field->cpp_type(); - } - } - } - + } + } + } + void TValue::ToMapField(Message& msg, const FieldDescriptor* field, const TProtoOpts& opts) const { const TString& name = field->name(); diff --git a/library/cpp/scheme/tests/ut/scheme_proto_ut.cpp b/library/cpp/scheme/tests/ut/scheme_proto_ut.cpp index e711a0d092..24c2addac9 100644 --- a/library/cpp/scheme/tests/ut/scheme_proto_ut.cpp +++ b/library/cpp/scheme/tests/ut/scheme_proto_ut.cpp @@ -8,12 +8,12 @@ Y_UNIT_TEST_SUITE(TSchemeProtoTest) { Y_UNIT_TEST(TestFromProtobuf) { DoTestProtobuf(true, false); - } - + } + Y_UNIT_TEST(TestToProtobuf) { DoTestProtobuf(false, false); - } - + } + Y_UNIT_TEST(TestFromProtobufWithDict) { DoTestProtobuf(true, true); } @@ -207,14 +207,14 @@ Y_UNIT_TEST_SUITE(TSchemeProtoTest) { *(m.AddMessages()) = m2, v["Messages"][0] = v2; *(m.AddMessages()) = m2, v["Messages"][1] = v2; - if (fromProto) { + if (fromProto) { UNIT_ASSERT(NSc::TValue::Equal(v, NSc::TValue::From(m, mapAsDict))); - } else { - NSc::TMessage proto; - v.To(proto); - + } else { + NSc::TMessage proto; + v.To(proto); + TString differentPath; - UNIT_ASSERT_C(NProtoBuf::IsEqual(m, proto, &differentPath), differentPath); - } + UNIT_ASSERT_C(NProtoBuf::IsEqual(m, proto, &differentPath), differentPath); + } } }; diff --git a/library/cpp/threading/chunk_queue/queue.cpp b/library/cpp/threading/chunk_queue/queue.cpp index 4ebd3f3205..52dd119921 100644 --- a/library/cpp/threading/chunk_queue/queue.cpp +++ b/library/cpp/threading/chunk_queue/queue.cpp @@ -1 +1 @@ -#include "queue.h" +#include "queue.h" diff --git a/library/cpp/threading/chunk_queue/queue.h b/library/cpp/threading/chunk_queue/queue.h index 55859601a1..fdf4c93f92 100644 --- a/library/cpp/threading/chunk_queue/queue.h +++ b/library/cpp/threading/chunk_queue/queue.h @@ -1,35 +1,35 @@ -#pragma once - -#include <util/datetime/base.h> -#include <util/generic/noncopyable.h> -#include <util/generic/ptr.h> -#include <util/generic/typetraits.h> -#include <util/generic/vector.h> -#include <util/generic/ylimits.h> -#include <util/system/atomic.h> -#include <util/system/guard.h> -#include <util/system/spinlock.h> -#include <util/system/yassert.h> - -#include <type_traits> -#include <utility> - -namespace NThreading { -//////////////////////////////////////////////////////////////////////////////// -// Platform helpers - -#if !defined(PLATFORM_CACHE_LINE) +#pragma once + +#include <util/datetime/base.h> +#include <util/generic/noncopyable.h> +#include <util/generic/ptr.h> +#include <util/generic/typetraits.h> +#include <util/generic/vector.h> +#include <util/generic/ylimits.h> +#include <util/system/atomic.h> +#include <util/system/guard.h> +#include <util/system/spinlock.h> +#include <util/system/yassert.h> + +#include <type_traits> +#include <utility> + +namespace NThreading { +//////////////////////////////////////////////////////////////////////////////// +// Platform helpers + +#if !defined(PLATFORM_CACHE_LINE) #define PLATFORM_CACHE_LINE 64 -#endif - -#if !defined(PLATFORM_PAGE_SIZE) +#endif + +#if !defined(PLATFORM_PAGE_SIZE) #define PLATFORM_PAGE_SIZE 4 * 1024 -#endif - +#endif + template <typename T, size_t PadSize = PLATFORM_CACHE_LINE> struct TPadded: public T { char Pad[PadSize - sizeof(T) % PadSize]; - + TPadded() { static_assert(sizeof(*this) % PadSize == 0, "padding does not work"); Y_UNUSED(Pad); @@ -43,10 +43,10 @@ namespace NThreading { Y_UNUSED(Pad); } }; - + //////////////////////////////////////////////////////////////////////////////// // Type helpers - + namespace NImpl { template <typename T> struct TPodTypeHelper { @@ -54,99 +54,99 @@ namespace NThreading { static void Write(T* ptr, TT&& value) { *ptr = value; } - + static T Read(T* ptr) { return *ptr; } - + static void Destroy(T* ptr) { Y_UNUSED(ptr); } }; - + template <typename T> struct TNonPodTypeHelper { template <typename TT> static void Write(T* ptr, TT&& value) { new (ptr) T(std::forward<TT>(value)); } - + static T Read(T* ptr) { return std::move(*ptr); } - + static void Destroy(T* ptr) { (void)ptr; /* Make MSVC happy. */ ptr->~T(); } }; - + template <typename T> using TTypeHelper = std::conditional_t< TTypeTraits<T>::IsPod, TPodTypeHelper<T>, TNonPodTypeHelper<T>>; - + } - + //////////////////////////////////////////////////////////////////////////////// // One producer/one consumer chunked queue. - + template <typename T, size_t ChunkSize = PLATFORM_PAGE_SIZE> class TOneOneQueue: private TNonCopyable { using TTypeHelper = NImpl::TTypeHelper<T>; - + struct TChunk; - + struct TChunkHeader { size_t Count = 0; TChunk* Next = nullptr; }; - + struct TChunk: public TChunkHeader { static constexpr size_t MaxCount = (ChunkSize - sizeof(TChunkHeader)) / sizeof(T); - + char Entries[MaxCount * sizeof(T)]; - + TChunk() { Y_UNUSED(Entries); // uninitialized } - + ~TChunk() { for (size_t i = 0; i < this->Count; ++i) { TTypeHelper::Destroy(GetPtr(i)); } - } - + } + T* GetPtr(size_t i) { return (T*)Entries + i; } }; - + struct TWriterState { TChunk* Chunk = nullptr; }; - + struct TReaderState { TChunk* Chunk = nullptr; size_t Count = 0; }; - + private: TPadded<TWriterState> Writer; TPadded<TReaderState> Reader; - + public: using TItem = T; - + TOneOneQueue() { Writer.Chunk = Reader.Chunk = new TChunk(); } - + ~TOneOneQueue() { DeleteChunks(Reader.Chunk); } - + template <typename TT> void Enqueue(TT&& value) { T* ptr = PrepareWrite(); @@ -154,7 +154,7 @@ namespace NThreading { TTypeHelper::Write(ptr, std::forward<TT>(value)); CompleteWrite(); } - + bool Dequeue(T& value) { if (T* ptr = PrepareRead()) { value = TTypeHelper::Read(ptr); @@ -162,17 +162,17 @@ namespace NThreading { return true; } return false; - } - + } + bool IsEmpty() { return !PrepareRead(); } - + protected: T* PrepareWrite() { TChunk* chunk = Writer.Chunk; Y_ASSERT(chunk && !chunk->Next); - + if (chunk->Count != TChunk::MaxCount) { return chunk->GetPtr(chunk->Count); } @@ -181,41 +181,41 @@ namespace NThreading { AtomicSet(Writer.Chunk->Next, chunk); Writer.Chunk = chunk; return chunk->GetPtr(0); - } - + } + void CompleteWrite() { AtomicSet(Writer.Chunk->Count, Writer.Chunk->Count + 1); } - + T* PrepareRead() { TChunk* chunk = Reader.Chunk; Y_ASSERT(chunk); - + for (;;) { size_t writerCount = AtomicGet(chunk->Count); if (Reader.Count != writerCount) { return chunk->GetPtr(Reader.Count); } - + if (writerCount != TChunk::MaxCount) { return nullptr; } - + chunk = AtomicGet(chunk->Next); if (!chunk) { return nullptr; } - + delete Reader.Chunk; Reader.Chunk = chunk; Reader.Count = 0; - } + } } - + void CompleteRead() { ++Reader.Count; - } - + } + private: static void DeleteChunks(TChunk* chunk) { while (chunk) { @@ -223,51 +223,51 @@ namespace NThreading { delete chunk; chunk = next; } - } + } }; - + //////////////////////////////////////////////////////////////////////////////// // Multiple producers/single consumer partitioned queue. // Provides FIFO guaranties for each producer. - + template <typename T, size_t Concurrency = 4, size_t ChunkSize = PLATFORM_PAGE_SIZE> class TManyOneQueue: private TNonCopyable { using TTypeHelper = NImpl::TTypeHelper<T>; - + struct TEntry { T Value; ui64 Tag; }; - + struct TQueueType: public TOneOneQueue<TEntry, ChunkSize> { TAtomic WriteLock = 0; - + using TOneOneQueue<TEntry, ChunkSize>::PrepareWrite; using TOneOneQueue<TEntry, ChunkSize>::CompleteWrite; - + using TOneOneQueue<TEntry, ChunkSize>::PrepareRead; using TOneOneQueue<TEntry, ChunkSize>::CompleteRead; }; - + private: union { TAtomic WriteTag = 0; char Pad[PLATFORM_CACHE_LINE]; }; - + TQueueType Queues[Concurrency]; - + public: using TItem = T; - + template <typename TT> void Enqueue(TT&& value) { ui64 tag = NextTag(); while (!TryEnqueue(std::forward<TT>(value), tag)) { SpinLockPause(); } - } - + } + bool Dequeue(T& value) { size_t index = 0; if (TEntry* entry = PrepareRead(index)) { @@ -276,24 +276,24 @@ namespace NThreading { return true; } return false; - } - + } + bool IsEmpty() { for (size_t i = 0; i < Concurrency; ++i) { if (!Queues[i].IsEmpty()) { return false; } - } + } return true; - } - + } + private: ui64 NextTag() { // TODO: can we avoid synchronization here? it costs 1.5x performance penalty // return GetCycleCount(); return AtomicIncrement(WriteTag); } - + template <typename TT> bool TryEnqueue(TT&& value, ui64 tag) { for (size_t i = 0; i < Concurrency; ++i) { @@ -307,22 +307,22 @@ namespace NThreading { AtomicUnlock(&queue.WriteLock); return true; } - } + } return false; - } - + } + TEntry* PrepareRead(size_t& index) { TEntry* entry = nullptr; ui64 tag = Max(); - + for (size_t i = 0; i < Concurrency; ++i) { - TEntry* e = Queues[i].PrepareRead(); - if (e && e->Tag < tag) { - index = i; - entry = e; - tag = e->Tag; - } - } + TEntry* e = Queues[i].PrepareRead(); + if (e && e->Tag < tag) { + index = i; + entry = e; + tag = e->Tag; + } + } if (entry) { // need second pass to catch updates within already scanned range @@ -338,91 +338,91 @@ namespace NThreading { } return entry; - } + } }; - + //////////////////////////////////////////////////////////////////////////////// // Concurrent many-many queue with strong FIFO guaranties. // Writers will not block readers (and vice versa), but will block each other. - + template <typename T, size_t ChunkSize = PLATFORM_PAGE_SIZE, typename TLock = TAdaptiveLock> class TManyManyQueue: private TNonCopyable { private: TPadded<TLock> WriteLock; TPadded<TLock> ReadLock; - + TOneOneQueue<T, ChunkSize> Queue; - + public: using TItem = T; - + template <typename TT> void Enqueue(TT&& value) { with_lock (WriteLock) { Queue.Enqueue(std::forward<TT>(value)); } - } - + } + bool Dequeue(T& value) { with_lock (ReadLock) { return Queue.Dequeue(value); } - } - + } + bool IsEmpty() { with_lock (ReadLock) { return Queue.IsEmpty(); } - } + } }; - + //////////////////////////////////////////////////////////////////////////////// // Multiple producers/single consumer partitioned queue. // Because of random partitioning reordering possible - FIFO not guaranteed! - + template <typename T, size_t Concurrency = 4, size_t ChunkSize = PLATFORM_PAGE_SIZE> class TRelaxedManyOneQueue: private TNonCopyable { struct TQueueType: public TOneOneQueue<T, ChunkSize> { TAtomic WriteLock = 0; }; - + private: union { size_t ReadPos = 0; char Pad[PLATFORM_CACHE_LINE]; }; - + TQueueType Queues[Concurrency]; - + public: using TItem = T; - + template <typename TT> void Enqueue(TT&& value) { while (!TryEnqueue(std::forward<TT>(value))) { SpinLockPause(); } - } - + } + bool Dequeue(T& value) { for (size_t i = 0; i < Concurrency; ++i) { TQueueType& queue = Queues[ReadPos++ % Concurrency]; if (queue.Dequeue(value)) { return true; } - } + } return false; - } - + } + bool IsEmpty() { for (size_t i = 0; i < Concurrency; ++i) { if (!Queues[i].IsEmpty()) { return false; } - } + } return true; - } - + } + private: template <typename TT> bool TryEnqueue(TT&& value) { @@ -434,15 +434,15 @@ namespace NThreading { AtomicUnlock(&queue.WriteLock); return true; } - } + } return false; - } + } }; - + //////////////////////////////////////////////////////////////////////////////// // Concurrent many-many partitioned queue. // Because of random partitioning reordering possible - FIFO not guaranteed! - + template <typename T, size_t Concurrency = 4, size_t ChunkSize = PLATFORM_PAGE_SIZE> class TRelaxedManyManyQueue: private TNonCopyable { struct TQueueType: public TOneOneQueue<T, ChunkSize> { @@ -454,21 +454,21 @@ namespace NThreading { TAtomic ReadLock = 0; char Pad2[PLATFORM_CACHE_LINE]; }; - }; - + }; + private: TQueueType Queues[Concurrency]; - + public: using TItem = T; - + template <typename TT> void Enqueue(TT&& value) { while (!TryEnqueue(std::forward<TT>(value))) { SpinLockPause(); } - } - + } + bool Dequeue(T& value) { size_t readPos = GetCycleCount(); for (size_t i = 0; i < Concurrency; ++i) { @@ -479,11 +479,11 @@ namespace NThreading { if (dequeued) { return true; } - } - } + } + } return false; - } - + } + bool IsEmpty() { for (size_t i = 0; i < Concurrency; ++i) { TQueueType& queue = Queues[i]; @@ -493,11 +493,11 @@ namespace NThreading { if (!empty) { return false; } - } - } + } + } return true; - } - + } + private: template <typename TT> bool TryEnqueue(TT&& value) { @@ -509,34 +509,34 @@ namespace NThreading { AtomicUnlock(&queue.WriteLock); return true; } - } + } return false; - } + } }; - + //////////////////////////////////////////////////////////////////////////////// // Simple wrapper to deal with AutoPtrs - + template <typename T, typename TImpl> class TAutoQueueBase: private TNonCopyable { private: TImpl Impl; - + public: using TItem = TAutoPtr<T>; - + ~TAutoQueueBase() { TAutoPtr<T> value; while (Dequeue(value)) { // do nothing } - } - + } + void Enqueue(TAutoPtr<T> value) { Impl.Enqueue(value.Get()); Y_UNUSED(value.Release()); } - + bool Dequeue(TAutoPtr<T>& value) { T* ptr = nullptr; if (Impl.Dequeue(ptr)) { @@ -544,25 +544,25 @@ namespace NThreading { return true; } return false; - } - + } + bool IsEmpty() { return Impl.IsEmpty(); } }; - + template <typename T, size_t ChunkSize = PLATFORM_PAGE_SIZE> using TAutoOneOneQueue = TAutoQueueBase<T, TOneOneQueue<T*, ChunkSize>>; - + template <typename T, size_t Concurrency = 4, size_t ChunkSize = PLATFORM_PAGE_SIZE> using TAutoManyOneQueue = TAutoQueueBase<T, TManyOneQueue<T*, Concurrency, ChunkSize>>; - + template <typename T, size_t ChunkSize = PLATFORM_PAGE_SIZE, typename TLock = TAdaptiveLock> using TAutoManyManyQueue = TAutoQueueBase<T, TManyManyQueue<T*, ChunkSize, TLock>>; - + template <typename T, size_t Concurrency = 4, size_t ChunkSize = PLATFORM_PAGE_SIZE> using TAutoRelaxedManyOneQueue = TAutoQueueBase<T, TRelaxedManyOneQueue<T*, Concurrency, ChunkSize>>; - + template <typename T, size_t Concurrency = 4, size_t ChunkSize = PLATFORM_PAGE_SIZE> using TAutoRelaxedManyManyQueue = TAutoQueueBase<T, TRelaxedManyManyQueue<T*, Concurrency, ChunkSize>>; } diff --git a/library/cpp/threading/chunk_queue/queue_ut.cpp b/library/cpp/threading/chunk_queue/queue_ut.cpp index 8cb36d8dd1..dc103202e8 100644 --- a/library/cpp/threading/chunk_queue/queue_ut.cpp +++ b/library/cpp/threading/chunk_queue/queue_ut.cpp @@ -1,202 +1,202 @@ -#include "queue.h" - +#include "queue.h" + #include <library/cpp/testing/unittest/registar.h> - -#include <util/generic/set.h> - -namespace NThreading { + +#include <util/generic/set.h> + +namespace NThreading { //////////////////////////////////////////////////////////////////////////////// - + Y_UNIT_TEST_SUITE(TOneOneQueueTest){ Y_UNIT_TEST(ShouldBeEmptyAtStart){ TOneOneQueue<int> queue; - + int result = 0; UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } - + Y_UNIT_TEST(ShouldReturnEntries) { TOneOneQueue<int> queue; queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); - + int result = 0; UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 1); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 2); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 3); - + UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } - + Y_UNIT_TEST(ShouldStoreMultipleChunks) { TOneOneQueue<int, 100> queue; for (int i = 0; i < 1000; ++i) { queue.Enqueue(i); - } - + } + for (int i = 0; i < 1000; ++i) { int result = 0; UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, i); - } + } } } ; - -//////////////////////////////////////////////////////////////////////////////// - + +//////////////////////////////////////////////////////////////////////////////// + Y_UNIT_TEST_SUITE(TManyOneQueueTest){ Y_UNIT_TEST(ShouldBeEmptyAtStart){ - TManyOneQueue<int> queue; - + TManyOneQueue<int> queue; + int result; UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } - + Y_UNIT_TEST(ShouldReturnEntries) { TManyOneQueue<int> queue; queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); - + int result = 0; UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 1); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 2); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 3); - + UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } } ; - -//////////////////////////////////////////////////////////////////////////////// - + +//////////////////////////////////////////////////////////////////////////////// + Y_UNIT_TEST_SUITE(TManyManyQueueTest){ Y_UNIT_TEST(ShouldBeEmptyAtStart){ - TManyManyQueue<int> queue; - + TManyManyQueue<int> queue; + int result = 0; UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } - + Y_UNIT_TEST(ShouldReturnEntries) { TManyManyQueue<int> queue; queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); - + int result = 0; UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 1); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 2); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT_EQUAL(result, 3); - + UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } } ; - -//////////////////////////////////////////////////////////////////////////////// - + +//////////////////////////////////////////////////////////////////////////////// + Y_UNIT_TEST_SUITE(TRelaxedManyOneQueueTest){ Y_UNIT_TEST(ShouldBeEmptyAtStart){ - TRelaxedManyOneQueue<int> queue; - + TRelaxedManyOneQueue<int> queue; + int result; UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } - + Y_UNIT_TEST(ShouldReturnEntries) { TSet<int> items = {1, 2, 3}; - + TRelaxedManyOneQueue<int> queue; for (int item : items) { queue.Enqueue(item); } - + int result = 0; UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT(items.erase(result)); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT(items.erase(result)); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT(items.erase(result)); - + UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } } ; - -//////////////////////////////////////////////////////////////////////////////// - + +//////////////////////////////////////////////////////////////////////////////// + Y_UNIT_TEST_SUITE(TRelaxedManyManyQueueTest){ Y_UNIT_TEST(ShouldBeEmptyAtStart){ - TRelaxedManyManyQueue<int> queue; - + TRelaxedManyManyQueue<int> queue; + int result = 0; UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } - + Y_UNIT_TEST(ShouldReturnEntries) { TSet<int> items = {1, 2, 3}; - + TRelaxedManyManyQueue<int> queue; for (int item : items) { queue.Enqueue(item); } - + int result = 0; UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT(items.erase(result)); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT(items.erase(result)); - + UNIT_ASSERT(!queue.IsEmpty()); UNIT_ASSERT(queue.Dequeue(result)); UNIT_ASSERT(items.erase(result)); - + UNIT_ASSERT(queue.IsEmpty()); UNIT_ASSERT(!queue.Dequeue(result)); } diff --git a/library/cpp/threading/chunk_queue/readme.txt b/library/cpp/threading/chunk_queue/readme.txt index 7c9f046a86..104a8ec744 100644 --- a/library/cpp/threading/chunk_queue/readme.txt +++ b/library/cpp/threading/chunk_queue/readme.txt @@ -1,60 +1,60 @@ -vskipin@dev-kiwi09:~$ ./rtmr-queue-perf -w 4 -r 4 AdaptiveLock64 Mutex64 LFManyMany64 FastLFManyMany64 LFManyOne64 FastLFManyOne64 ManyMany64 ManyOne64 -2016-05-08T11:49:56.729254Z INFO: [-i] Iterations: 10000000 -2016-05-08T11:49:56.729319Z INFO: [-r] NumReaders: 4 -2016-05-08T11:49:56.729355Z INFO: [-w] NumWriters: 4 -2016-05-08T11:49:56.729502Z INFO: starting consumers... -2016-05-08T11:49:56.729621Z INFO: starting producers... -2016-05-08T11:49:56.729711Z INFO: wait for producers... -2016-05-08T11:50:14.650803Z INFO: wait for consumers... -2016-05-08T11:50:14.650859Z INFO: average producer time: 15.96846675 seconds -2016-05-08T11:50:14.650885Z INFO: average consumer time: 17.9209995 seconds -2016-05-08T11:50:14.650897Z INFO: test AdaptiveLock64 duration: 17.921395s (0.448034875us per iteration) -2016-05-08T11:50:14.650913Z INFO: starting consumers... -2016-05-08T11:50:14.651028Z INFO: starting producers... -2016-05-08T11:50:14.651122Z INFO: wait for producers... -2016-05-08T11:50:31.426378Z INFO: wait for consumers... -2016-05-08T11:50:31.426447Z INFO: average producer time: 15.58770475 seconds -2016-05-08T11:50:31.426491Z INFO: average consumer time: 16.775301 seconds -2016-05-08T11:50:31.426527Z INFO: test Mutex64 duration: 16.775614s (0.41939035us per iteration) -2016-05-08T11:50:31.426584Z INFO: starting consumers... -2016-05-08T11:50:31.426655Z INFO: starting producers... -2016-05-08T11:50:31.426749Z INFO: wait for producers... -2016-05-08T11:50:40.578425Z INFO: wait for consumers... -2016-05-08T11:50:40.578523Z INFO: average producer time: 8.69236075 seconds -2016-05-08T11:50:40.578577Z INFO: average consumer time: 9.15165125 seconds -2016-05-08T11:50:40.578617Z INFO: test LFManyMany64 duration: 9.152033s (0.228800825us per iteration) -2016-05-08T11:50:40.578670Z INFO: starting consumers... -2016-05-08T11:50:40.578742Z INFO: starting producers... -2016-05-08T11:50:40.578893Z INFO: wait for producers... -2016-05-08T11:50:47.447686Z INFO: wait for consumers... -2016-05-08T11:50:47.447758Z INFO: average producer time: 6.81136025 seconds -2016-05-08T11:50:47.447793Z INFO: average consumer time: 6.86875825 seconds -2016-05-08T11:50:47.447834Z INFO: test FastLFManyMany64 duration: 6.869165s (0.171729125us per iteration) -2016-05-08T11:50:47.447901Z INFO: starting consumers... -2016-05-08T11:50:47.447967Z INFO: starting producers... -2016-05-08T11:50:47.448058Z INFO: wait for producers... -2016-05-08T11:50:50.469710Z INFO: wait for consumers... -2016-05-08T11:50:50.469798Z INFO: average producer time: 2.9915505 seconds -2016-05-08T11:50:50.469848Z INFO: average consumer time: 3.02161675 seconds -2016-05-08T11:50:50.469883Z INFO: test LFManyOne64 duration: 3.021983s (0.075549575us per iteration) -2016-05-08T11:50:50.469947Z INFO: starting consumers... -2016-05-08T11:50:50.470012Z INFO: starting producers... -2016-05-08T11:50:50.470104Z INFO: wait for producers... -2016-05-08T11:50:53.139964Z INFO: wait for consumers... -2016-05-08T11:50:53.140050Z INFO: average producer time: 2.5656465 seconds -2016-05-08T11:50:53.140102Z INFO: average consumer time: 2.6697755 seconds -2016-05-08T11:50:53.140149Z INFO: test FastLFManyOne64 duration: 2.670202s (0.06675505us per iteration) -2016-05-08T11:50:53.140206Z INFO: starting consumers... -2016-05-08T11:50:53.140281Z INFO: starting producers... -2016-05-08T11:50:53.140371Z INFO: wait for producers... -2016-05-08T11:50:59.067812Z INFO: wait for consumers... -2016-05-08T11:50:59.067895Z INFO: average producer time: 5.8925505 seconds -2016-05-08T11:50:59.067946Z INFO: average consumer time: 5.9273365 seconds -2016-05-08T11:50:59.067978Z INFO: test ManyMany64 duration: 5.927773s (0.148194325us per iteration) -2016-05-08T11:50:59.068068Z INFO: starting consumers... -2016-05-08T11:50:59.068179Z INFO: starting producers... -2016-05-08T11:50:59.068288Z INFO: wait for producers... -2016-05-08T11:51:03.427416Z INFO: wait for consumers... -2016-05-08T11:51:03.427514Z INFO: average producer time: 4.1055505 seconds -2016-05-08T11:51:03.427560Z INFO: average consumer time: 4.35914975 seconds -2016-05-08T11:51:03.427596Z INFO: test ManyOne64 duration: 4.359529s (0.108988225us per iteration) +vskipin@dev-kiwi09:~$ ./rtmr-queue-perf -w 4 -r 4 AdaptiveLock64 Mutex64 LFManyMany64 FastLFManyMany64 LFManyOne64 FastLFManyOne64 ManyMany64 ManyOne64 +2016-05-08T11:49:56.729254Z INFO: [-i] Iterations: 10000000 +2016-05-08T11:49:56.729319Z INFO: [-r] NumReaders: 4 +2016-05-08T11:49:56.729355Z INFO: [-w] NumWriters: 4 +2016-05-08T11:49:56.729502Z INFO: starting consumers... +2016-05-08T11:49:56.729621Z INFO: starting producers... +2016-05-08T11:49:56.729711Z INFO: wait for producers... +2016-05-08T11:50:14.650803Z INFO: wait for consumers... +2016-05-08T11:50:14.650859Z INFO: average producer time: 15.96846675 seconds +2016-05-08T11:50:14.650885Z INFO: average consumer time: 17.9209995 seconds +2016-05-08T11:50:14.650897Z INFO: test AdaptiveLock64 duration: 17.921395s (0.448034875us per iteration) +2016-05-08T11:50:14.650913Z INFO: starting consumers... +2016-05-08T11:50:14.651028Z INFO: starting producers... +2016-05-08T11:50:14.651122Z INFO: wait for producers... +2016-05-08T11:50:31.426378Z INFO: wait for consumers... +2016-05-08T11:50:31.426447Z INFO: average producer time: 15.58770475 seconds +2016-05-08T11:50:31.426491Z INFO: average consumer time: 16.775301 seconds +2016-05-08T11:50:31.426527Z INFO: test Mutex64 duration: 16.775614s (0.41939035us per iteration) +2016-05-08T11:50:31.426584Z INFO: starting consumers... +2016-05-08T11:50:31.426655Z INFO: starting producers... +2016-05-08T11:50:31.426749Z INFO: wait for producers... +2016-05-08T11:50:40.578425Z INFO: wait for consumers... +2016-05-08T11:50:40.578523Z INFO: average producer time: 8.69236075 seconds +2016-05-08T11:50:40.578577Z INFO: average consumer time: 9.15165125 seconds +2016-05-08T11:50:40.578617Z INFO: test LFManyMany64 duration: 9.152033s (0.228800825us per iteration) +2016-05-08T11:50:40.578670Z INFO: starting consumers... +2016-05-08T11:50:40.578742Z INFO: starting producers... +2016-05-08T11:50:40.578893Z INFO: wait for producers... +2016-05-08T11:50:47.447686Z INFO: wait for consumers... +2016-05-08T11:50:47.447758Z INFO: average producer time: 6.81136025 seconds +2016-05-08T11:50:47.447793Z INFO: average consumer time: 6.86875825 seconds +2016-05-08T11:50:47.447834Z INFO: test FastLFManyMany64 duration: 6.869165s (0.171729125us per iteration) +2016-05-08T11:50:47.447901Z INFO: starting consumers... +2016-05-08T11:50:47.447967Z INFO: starting producers... +2016-05-08T11:50:47.448058Z INFO: wait for producers... +2016-05-08T11:50:50.469710Z INFO: wait for consumers... +2016-05-08T11:50:50.469798Z INFO: average producer time: 2.9915505 seconds +2016-05-08T11:50:50.469848Z INFO: average consumer time: 3.02161675 seconds +2016-05-08T11:50:50.469883Z INFO: test LFManyOne64 duration: 3.021983s (0.075549575us per iteration) +2016-05-08T11:50:50.469947Z INFO: starting consumers... +2016-05-08T11:50:50.470012Z INFO: starting producers... +2016-05-08T11:50:50.470104Z INFO: wait for producers... +2016-05-08T11:50:53.139964Z INFO: wait for consumers... +2016-05-08T11:50:53.140050Z INFO: average producer time: 2.5656465 seconds +2016-05-08T11:50:53.140102Z INFO: average consumer time: 2.6697755 seconds +2016-05-08T11:50:53.140149Z INFO: test FastLFManyOne64 duration: 2.670202s (0.06675505us per iteration) +2016-05-08T11:50:53.140206Z INFO: starting consumers... +2016-05-08T11:50:53.140281Z INFO: starting producers... +2016-05-08T11:50:53.140371Z INFO: wait for producers... +2016-05-08T11:50:59.067812Z INFO: wait for consumers... +2016-05-08T11:50:59.067895Z INFO: average producer time: 5.8925505 seconds +2016-05-08T11:50:59.067946Z INFO: average consumer time: 5.9273365 seconds +2016-05-08T11:50:59.067978Z INFO: test ManyMany64 duration: 5.927773s (0.148194325us per iteration) +2016-05-08T11:50:59.068068Z INFO: starting consumers... +2016-05-08T11:50:59.068179Z INFO: starting producers... +2016-05-08T11:50:59.068288Z INFO: wait for producers... +2016-05-08T11:51:03.427416Z INFO: wait for consumers... +2016-05-08T11:51:03.427514Z INFO: average producer time: 4.1055505 seconds +2016-05-08T11:51:03.427560Z INFO: average consumer time: 4.35914975 seconds +2016-05-08T11:51:03.427596Z INFO: test ManyOne64 duration: 4.359529s (0.108988225us per iteration) diff --git a/library/cpp/threading/chunk_queue/ut/ya.make b/library/cpp/threading/chunk_queue/ut/ya.make index a35ed6bc4b..d69e219f66 100644 --- a/library/cpp/threading/chunk_queue/ut/ya.make +++ b/library/cpp/threading/chunk_queue/ut/ya.make @@ -1,9 +1,9 @@ UNITTEST_FOR(library/cpp/threading/chunk_queue) - + OWNER(g:rtmr) - -SRCS( - queue_ut.cpp -) - -END() + +SRCS( + queue_ut.cpp +) + +END() diff --git a/library/cpp/threading/chunk_queue/ya.make b/library/cpp/threading/chunk_queue/ya.make index 2f883140ba..7e6ead7b36 100644 --- a/library/cpp/threading/chunk_queue/ya.make +++ b/library/cpp/threading/chunk_queue/ya.make @@ -1,9 +1,9 @@ -LIBRARY() - +LIBRARY() + OWNER(g:rtmr) - -SRCS( - queue.cpp -) - -END() + +SRCS( + queue.cpp +) + +END() diff --git a/library/cpp/threading/future/core/future-inl.h b/library/cpp/threading/future/core/future-inl.h index 5fd4296a93..a72985ec47 100644 --- a/library/cpp/threading/future/core/future-inl.h +++ b/library/cpp/threading/future/core/future-inl.h @@ -1,21 +1,21 @@ -#pragma once - -#if !defined(INCLUDE_FUTURE_INL_H) -#error "you should never include future-inl.h directly" +#pragma once + +#if !defined(INCLUDE_FUTURE_INL_H) +#error "you should never include future-inl.h directly" #endif // INCLUDE_FUTURE_INL_H - + namespace NThreading { namespace NImpl { //////////////////////////////////////////////////////////////////////////////// - + template <typename T> using TCallback = std::function<void(const TFuture<T>&)>; - + template <typename T> using TCallbackList = TVector<TCallback<T>>; // TODO: small vector - + //////////////////////////////////////////////////////////////////////////////// - + enum class TError { Error }; @@ -29,28 +29,28 @@ namespace NThreading { ValueSet, ValueRead, }; - + private: mutable TAtomic State; TAdaptiveLock StateLock; - + TCallbackList<T> Callbacks; mutable THolder<TSystemEvent> ReadyEvent; - + std::exception_ptr Exception; - + union { char NullValue; T Value; }; - + void AccessValue(TDuration timeout, int acquireState) const { int state = AtomicGet(State); if (Y_UNLIKELY(state == NotReady)) { if (timeout == TDuration::Zero()) { ythrow TFutureException() << "value not set"; } - + if (!Wait(timeout)) { ythrow TFutureException() << "wait timeout"; } @@ -114,17 +114,17 @@ namespace NThreading { bool HasException() const { return AtomicGet(State) == ExceptionSet; } - + const T& GetValue(TDuration timeout = TDuration::Zero()) const { AccessValue(timeout, ValueRead); return Value; } - + T ExtractValue(TDuration timeout = TDuration::Zero()) { AccessValue(timeout, ValueMoved); return std::move(Value); } - + template <typename TT> void SetValue(TT&& value) { bool success = TrySetValue(std::forward<TT>(value)); @@ -137,21 +137,21 @@ namespace NThreading { bool TrySetValue(TT&& value) { TSystemEvent* readyEvent = nullptr; TCallbackList<T> callbacks; - + with_lock (StateLock) { int state = AtomicGet(State); if (Y_UNLIKELY(state != NotReady)) { return false; } - + new (&Value) T(std::forward<TT>(value)); - + readyEvent = ReadyEvent.Get(); callbacks = std::move(Callbacks); AtomicSet(State, ValueSet); } - + if (readyEvent) { readyEvent->Signal(); } @@ -164,8 +164,8 @@ namespace NThreading { } return true; - } - + } + void SetException(std::exception_ptr e) { bool success = TrySetException(std::move(e)); if (Y_UNLIKELY(!success)) { @@ -176,18 +176,18 @@ namespace NThreading { bool TrySetException(std::exception_ptr e) { TSystemEvent* readyEvent; TCallbackList<T> callbacks; - + with_lock (StateLock) { int state = AtomicGet(State); if (Y_UNLIKELY(state != NotReady)) { return false; } - + Exception = std::move(e); - + readyEvent = ReadyEvent.Get(); callbacks = std::move(Callbacks); - + AtomicSet(State, ExceptionSet); } @@ -203,8 +203,8 @@ namespace NThreading { } return true; - } - + } + template <typename F> bool Subscribe(F&& func) { with_lock (StateLock) { @@ -216,33 +216,33 @@ namespace NThreading { } return false; } - + void Wait() const { Wait(TInstant::Max()); - } - + } + bool Wait(TDuration timeout) const { return Wait(timeout.ToDeadLine()); } - + bool Wait(TInstant deadline) const { TSystemEvent* readyEvent = nullptr; - + with_lock (StateLock) { int state = AtomicGet(State); if (state != NotReady) { return true; } - + if (!ReadyEvent) { ReadyEvent.Reset(new TSystemEvent()); } readyEvent = ReadyEvent.Get(); } - + Y_ASSERT(readyEvent); return readyEvent->WaitD(deadline); - } + } void TryRethrowWithState(int state) const { if (Y_UNLIKELY(state == ExceptionSet)) { @@ -251,9 +251,9 @@ namespace NThreading { } } }; - + //////////////////////////////////////////////////////////////////////////////// - + template <> class TFutureState<void>: public TAtomicRefCount<TFutureState<void>> { enum { @@ -261,22 +261,22 @@ namespace NThreading { ValueSet, ExceptionSet, }; - + private: TAtomic State; TAdaptiveLock StateLock; - + TCallbackList<void> Callbacks; mutable THolder<TSystemEvent> ReadyEvent; - + std::exception_ptr Exception; public: TFutureState(bool valueSet = false) : State(valueSet ? ValueSet : NotReady) { - } - + } + TFutureState(std::exception_ptr exception, TError) : State(ExceptionSet) , Exception(std::move(exception)) @@ -285,8 +285,8 @@ namespace NThreading { bool HasValue() const { return AtomicGet(State) == ValueSet; - } - + } + void TryRethrow() const { int state = AtomicGet(State); TryRethrowWithState(state); @@ -295,26 +295,26 @@ namespace NThreading { bool HasException() const { return AtomicGet(State) == ExceptionSet; } - + void GetValue(TDuration timeout = TDuration::Zero()) const { int state = AtomicGet(State); if (Y_UNLIKELY(state == NotReady)) { if (timeout == TDuration::Zero()) { ythrow TFutureException() << "value not set"; } - + if (!Wait(timeout)) { ythrow TFutureException() << "wait timeout"; } - + state = AtomicGet(State); } - + TryRethrowWithState(state); - + Y_ASSERT(state == ValueSet); } - + void SetValue() { bool success = TrySetValue(); if (Y_UNLIKELY(!success)) { @@ -325,19 +325,19 @@ namespace NThreading { bool TrySetValue() { TSystemEvent* readyEvent = nullptr; TCallbackList<void> callbacks; - + with_lock (StateLock) { int state = AtomicGet(State); if (Y_UNLIKELY(state != NotReady)) { return false; } - + readyEvent = ReadyEvent.Get(); callbacks = std::move(Callbacks); - + AtomicSet(State, ValueSet); } - + if (readyEvent) { readyEvent->Signal(); } @@ -350,8 +350,8 @@ namespace NThreading { } return true; - } - + } + void SetException(std::exception_ptr e) { bool success = TrySetException(std::move(e)); if (Y_UNLIKELY(!success)) { @@ -362,25 +362,25 @@ namespace NThreading { bool TrySetException(std::exception_ptr e) { TSystemEvent* readyEvent = nullptr; TCallbackList<void> callbacks; - + with_lock (StateLock) { int state = AtomicGet(State); if (Y_UNLIKELY(state != NotReady)) { return false; } - + Exception = std::move(e); - + readyEvent = ReadyEvent.Get(); callbacks = std::move(Callbacks); - + AtomicSet(State, ExceptionSet); } - + if (readyEvent) { readyEvent->Signal(); } - + if (callbacks) { TFuture<void> temp(this); for (auto& callback : callbacks) { @@ -390,7 +390,7 @@ namespace NThreading { return true; } - + template <typename F> bool Subscribe(F&& func) { with_lock (StateLock) { @@ -402,15 +402,15 @@ namespace NThreading { } return false; } - + void Wait() const { Wait(TInstant::Max()); - } - + } + bool Wait(TDuration timeout) const { return Wait(timeout.ToDeadLine()); } - + bool Wait(TInstant deadline) const { TSystemEvent* readyEvent = nullptr; @@ -428,7 +428,7 @@ namespace NThreading { Y_ASSERT(readyEvent); return readyEvent->WaitD(deadline); - } + } void TryRethrowWithState(int state) const { if (Y_UNLIKELY(state == ExceptionSet)) { @@ -437,19 +437,19 @@ namespace NThreading { } } }; - + //////////////////////////////////////////////////////////////////////////////// - + template <typename T> inline void SetValueImpl(TPromise<T>& promise, const T& value) { promise.SetValue(value); } - + template <typename T> inline void SetValueImpl(TPromise<T>& promise, T&& value) { promise.SetValue(std::move(value)); - } - + } + template <typename T> inline void SetValueImpl(TPromise<T>& promise, const TFuture<T>& future, std::enable_if_t<!std::is_void<T>::value, bool> = false) { @@ -463,8 +463,8 @@ namespace NThreading { } promise.SetValue(*value); }); - } - + } + template <typename T> inline void SetValueImpl(TPromise<void>& promise, const TFuture<T>& future) { future.Subscribe([=](const TFuture<T>& f) mutable { @@ -487,9 +487,9 @@ namespace NThreading { if (Y_UNLIKELY(!success)) { throw; } - } - } - + } + } + template <typename F> inline void SetValue(TPromise<void>& promise, F&& func, std::enable_if_t<std::is_void<TFunctionResult<F>>::value, bool> = false) { @@ -498,14 +498,14 @@ namespace NThreading { } catch (...) { promise.SetException(std::current_exception()); return; - } + } promise.SetValue(); - } - + } + } - + //////////////////////////////////////////////////////////////////////////////// - + class TFutureStateId { private: const void* Id; @@ -535,41 +535,41 @@ namespace NThreading { template <typename T> inline TFuture<T>::TFuture(const TIntrusivePtr<TFutureState>& state) noexcept : State(state) - { - } - + { + } + template <typename T> inline void TFuture<T>::Swap(TFuture<T>& other) { State.Swap(other.State); } - + template <typename T> inline bool TFuture<T>::HasValue() const { return State && State->HasValue(); } - + template <typename T> inline const T& TFuture<T>::GetValue(TDuration timeout) const { EnsureInitialized(); return State->GetValue(timeout); - } - + } + template <typename T> inline T TFuture<T>::ExtractValue(TDuration timeout) { EnsureInitialized(); return State->ExtractValue(timeout); } - + template <typename T> inline const T& TFuture<T>::GetValueSync() const { return GetValue(TDuration::Max()); } - + template <typename T> inline T TFuture<T>::ExtractValueSync() { return ExtractValue(TDuration::Max()); } - + template <typename T> inline void TFuture<T>::TryRethrow() const { if (State) { @@ -581,25 +581,25 @@ namespace NThreading { inline bool TFuture<T>::HasException() const { return State && State->HasException(); } - + template <typename T> inline void TFuture<T>::Wait() const { EnsureInitialized(); return State->Wait(); } - + template <typename T> inline bool TFuture<T>::Wait(TDuration timeout) const { EnsureInitialized(); return State->Wait(timeout); } - + template <typename T> inline bool TFuture<T>::Wait(TInstant deadline) const { EnsureInitialized(); return State->Wait(deadline); } - + template <typename T> template <typename F> inline const TFuture<T>& TFuture<T>::Subscribe(F&& func) const { @@ -609,7 +609,7 @@ namespace NThreading { } return *this; } - + template <typename T> template <typename F> inline const TFuture<T>& TFuture<T>::NoexceptSubscribe(F&& func) const noexcept { @@ -626,7 +626,7 @@ namespace NThreading { }); return promise; } - + template <typename T> inline TFuture<void> TFuture<T>::IgnoreResult() const { auto promise = NewPromise(); @@ -639,8 +639,8 @@ namespace NThreading { template <typename T> inline bool TFuture<T>::Initialized() const { return bool(State); - } - + } + template <typename T> inline TMaybe<TFutureStateId> TFuture<T>::StateId() const noexcept { return State != nullptr ? MakeMaybe<TFutureStateId>(*State) : Nothing(); @@ -650,33 +650,33 @@ namespace NThreading { inline void TFuture<T>::EnsureInitialized() const { if (!State) { ythrow TFutureException() << "state not initialized"; - } + } } - + //////////////////////////////////////////////////////////////////////////////// - + inline TFuture<void>::TFuture(const TIntrusivePtr<TFutureState>& state) noexcept : State(state) { } - + inline void TFuture<void>::Swap(TFuture<void>& other) { State.Swap(other.State); } - + inline bool TFuture<void>::HasValue() const { return State && State->HasValue(); } - + inline void TFuture<void>::GetValue(TDuration timeout) const { EnsureInitialized(); State->GetValue(timeout); } - + inline void TFuture<void>::GetValueSync() const { GetValue(TDuration::Max()); } - + inline void TFuture<void>::TryRethrow() const { if (State) { State->TryRethrow(); @@ -686,7 +686,7 @@ namespace NThreading { inline bool TFuture<void>::HasException() const { return State && State->HasException(); } - + inline void TFuture<void>::Wait() const { EnsureInitialized(); return State->Wait(); @@ -696,12 +696,12 @@ namespace NThreading { EnsureInitialized(); return State->Wait(timeout); } - + inline bool TFuture<void>::Wait(TInstant deadline) const { EnsureInitialized(); return State->Wait(deadline); } - + template <typename F> inline const TFuture<void>& TFuture<void>::Subscribe(F&& func) const { EnsureInitialized(); @@ -710,7 +710,7 @@ namespace NThreading { } return *this; } - + template <typename F> inline const TFuture<void>& TFuture<void>::NoexceptSubscribe(F&& func) const noexcept { return Subscribe(std::forward<F>(func)); @@ -725,7 +725,7 @@ namespace NThreading { }); return promise; } - + template <typename R> inline TFuture<R> TFuture<void>::Return(const R& value) const { auto promise = NewPromise<R>(); @@ -739,12 +739,12 @@ namespace NThreading { promise.SetValue(value); }); return promise; - } - + } + inline bool TFuture<void>::Initialized() const { return bool(State); } - + inline TMaybe<TFutureStateId> TFuture<void>::StateId() const noexcept { return State != nullptr ? MakeMaybe<TFutureStateId>(*State) : Nothing(); } @@ -752,39 +752,39 @@ namespace NThreading { inline void TFuture<void>::EnsureInitialized() const { if (!State) { ythrow TFutureException() << "state not initialized"; - } + } } - + //////////////////////////////////////////////////////////////////////////////// - + template <typename T> inline TPromise<T>::TPromise(const TIntrusivePtr<TFutureState>& state) noexcept : State(state) { } - + template <typename T> inline void TPromise<T>::Swap(TPromise<T>& other) { State.Swap(other.State); } - + template <typename T> inline const T& TPromise<T>::GetValue() const { EnsureInitialized(); return State->GetValue(); } - + template <typename T> inline T TPromise<T>::ExtractValue() { EnsureInitialized(); return State->ExtractValue(); } - + template <typename T> inline bool TPromise<T>::HasValue() const { return State && State->HasValue(); } - + template <typename T> inline void TPromise<T>::SetValue(const T& value) { EnsureInitialized(); @@ -796,7 +796,7 @@ namespace NThreading { EnsureInitialized(); State->SetValue(std::move(value)); } - + template <typename T> inline bool TPromise<T>::TrySetValue(const T& value) { EnsureInitialized(); @@ -820,19 +820,19 @@ namespace NThreading { inline bool TPromise<T>::HasException() const { return State && State->HasException(); } - + template <typename T> inline void TPromise<T>::SetException(const TString& e) { EnsureInitialized(); State->SetException(std::make_exception_ptr(yexception() << e)); } - + template <typename T> inline void TPromise<T>::SetException(std::exception_ptr e) { EnsureInitialized(); State->SetException(std::move(e)); } - + template <typename T> inline bool TPromise<T>::TrySetException(std::exception_ptr e) { EnsureInitialized(); @@ -844,49 +844,49 @@ namespace NThreading { EnsureInitialized(); return TFuture<T>(State); } - + template <typename T> inline TPromise<T>::operator TFuture<T>() const { return GetFuture(); } - + template <typename T> inline bool TPromise<T>::Initialized() const { return bool(State); } - + template <typename T> inline void TPromise<T>::EnsureInitialized() const { if (!State) { ythrow TFutureException() << "state not initialized"; } } - + //////////////////////////////////////////////////////////////////////////////// - + inline TPromise<void>::TPromise(const TIntrusivePtr<TFutureState>& state) noexcept : State(state) { } - + inline void TPromise<void>::Swap(TPromise<void>& other) { State.Swap(other.State); } - + inline void TPromise<void>::GetValue() const { EnsureInitialized(); State->GetValue(); } - + inline bool TPromise<void>::HasValue() const { return State && State->HasValue(); } - + inline void TPromise<void>::SetValue() { EnsureInitialized(); State->SetValue(); } - + inline bool TPromise<void>::TrySetValue() { EnsureInitialized(); return State->TrySetValue(); @@ -901,17 +901,17 @@ namespace NThreading { inline bool TPromise<void>::HasException() const { return State && State->HasException(); } - + inline void TPromise<void>::SetException(const TString& e) { EnsureInitialized(); State->SetException(std::make_exception_ptr(yexception() << e)); } - + inline void TPromise<void>::SetException(std::exception_ptr e) { EnsureInitialized(); State->SetException(std::move(e)); } - + inline bool TPromise<void>::TrySetException(std::exception_ptr e) { EnsureInitialized(); return State->TrySetException(std::move(e)); @@ -921,42 +921,42 @@ namespace NThreading { EnsureInitialized(); return TFuture<void>(State); } - + inline TPromise<void>::operator TFuture<void>() const { return GetFuture(); } - + inline bool TPromise<void>::Initialized() const { return bool(State); } - + inline void TPromise<void>::EnsureInitialized() const { if (!State) { ythrow TFutureException() << "state not initialized"; } } - + //////////////////////////////////////////////////////////////////////////////// - + template <typename T> inline TPromise<T> NewPromise() { return {new NImpl::TFutureState<T>()}; - } - + } + inline TPromise<void> NewPromise() { return {new NImpl::TFutureState<void>()}; } - + template <typename T> inline TFuture<T> MakeFuture(const T& value) { return {new NImpl::TFutureState<T>(value)}; } - + template <typename T> inline TFuture<std::remove_reference_t<T>> MakeFuture(T&& value) { return {new NImpl::TFutureState<std::remove_reference_t<T>>(std::forward<T>(value))}; } - + template <typename T> inline TFuture<T> MakeFuture() { struct TCache { @@ -970,7 +970,7 @@ namespace NThreading { }; return Singleton<TCache>()->Instance; } - + template <typename T> inline TFuture<T> MakeErrorFuture(std::exception_ptr exception) { @@ -983,4 +983,4 @@ namespace NThreading { }; return Singleton<TCache>()->Instance; } -} +} diff --git a/library/cpp/threading/future/core/future.cpp b/library/cpp/threading/future/core/future.cpp index 3243afcb40..257a2a218f 100644 --- a/library/cpp/threading/future/core/future.cpp +++ b/library/cpp/threading/future/core/future.cpp @@ -1 +1 @@ -#include "future.h" +#include "future.h" diff --git a/library/cpp/threading/future/core/future.h b/library/cpp/threading/future/core/future.h index 2e82bb953e..2dfc4e0f25 100644 --- a/library/cpp/threading/future/core/future.h +++ b/library/cpp/threading/future/core/future.h @@ -1,26 +1,26 @@ -#pragma once - +#pragma once + #include "fwd.h" -#include <util/datetime/base.h> -#include <util/generic/function.h> +#include <util/datetime/base.h> +#include <util/generic/function.h> #include <util/generic/maybe.h> -#include <util/generic/ptr.h> -#include <util/generic/vector.h> -#include <util/generic/yexception.h> -#include <util/system/event.h> -#include <util/system/spinlock.h> - +#include <util/generic/ptr.h> +#include <util/generic/vector.h> +#include <util/generic/yexception.h> +#include <util/system/event.h> +#include <util/system/spinlock.h> + namespace NThreading { //////////////////////////////////////////////////////////////////////////////// - + struct TFutureException: public yexception {}; - + // creates unset promise template <typename T> TPromise<T> NewPromise(); TPromise<void> NewPromise(); - + // creates preset future template <typename T> TFuture<T> MakeFuture(const T& value); @@ -31,18 +31,18 @@ namespace NThreading { template <typename T> TFuture<T> MakeErrorFuture(std::exception_ptr exception); TFuture<void> MakeFuture(); - + //////////////////////////////////////////////////////////////////////////////// - + namespace NImpl { template <typename T> class TFutureState; - + template <typename T> struct TFutureType { using TType = T; }; - + template <typename T> struct TFutureType<TFuture<T>> { using TType = typename TFutureType<T>::TType; @@ -54,10 +54,10 @@ namespace NThreading { using TType = decltype(std::declval<F&>()(std::declval<const TFuture<T>&>())); }; } - + template <typename F> using TFutureType = typename NImpl::TFutureType<F>::TType; - + template <typename F, typename T> using TFutureCallResult = typename NImpl::TFutureCallResult<F, T>::TType; @@ -65,14 +65,14 @@ namespace NThreading { class TFutureStateId; //////////////////////////////////////////////////////////////////////////////// - + template <typename T> class TFuture { using TFutureState = NImpl::TFutureState<T>; - + private: TIntrusivePtr<TFutureState> State; - + public: using value_type = T; @@ -80,29 +80,29 @@ namespace NThreading { TFuture(const TFuture<T>& other) noexcept = default; TFuture(TFuture<T>&& other) noexcept = default; TFuture(const TIntrusivePtr<TFutureState>& state) noexcept; - + TFuture<T>& operator=(const TFuture<T>& other) noexcept = default; TFuture<T>& operator=(TFuture<T>&& other) noexcept = default; void Swap(TFuture<T>& other); - + bool Initialized() const; - + bool HasValue() const; const T& GetValue(TDuration timeout = TDuration::Zero()) const; const T& GetValueSync() const; T ExtractValue(TDuration timeout = TDuration::Zero()); T ExtractValueSync(); - + void TryRethrow() const; bool HasException() const; - + void Wait() const; bool Wait(TDuration timeout) const; bool Wait(TInstant deadline) const; - + template <typename F> const TFuture<T>& Subscribe(F&& callback) const; - + // precondition: EnsureInitialized() passes // postcondition: std::terminate is highly unlikely template <typename F> @@ -110,9 +110,9 @@ namespace NThreading { template <typename F> TFuture<TFutureType<TFutureCallResult<F, T>>> Apply(F&& func) const; - + TFuture<void> IgnoreResult() const; - + //! If the future is initialized returns the future state identifier. Otherwise returns an empty optional /** The state identifier is guaranteed to be unique during the future state lifetime and could be reused after its death **/ @@ -120,16 +120,16 @@ namespace NThreading { void EnsureInitialized() const; }; - + //////////////////////////////////////////////////////////////////////////////// - + template <> class TFuture<void> { using TFutureState = NImpl::TFutureState<void>; - + private: TIntrusivePtr<TFutureState> State = nullptr; - + public: using value_type = void; @@ -137,27 +137,27 @@ namespace NThreading { TFuture(const TFuture<void>& other) noexcept = default; TFuture(TFuture<void>&& other) noexcept = default; TFuture(const TIntrusivePtr<TFutureState>& state) noexcept; - + TFuture<void>& operator=(const TFuture<void>& other) noexcept = default; TFuture<void>& operator=(TFuture<void>&& other) noexcept = default; void Swap(TFuture<void>& other); - + bool Initialized() const; - + bool HasValue() const; void GetValue(TDuration timeout = TDuration::Zero()) const; void GetValueSync() const; - + void TryRethrow() const; bool HasException() const; - + void Wait() const; bool Wait(TDuration timeout) const; bool Wait(TInstant deadline) const; - + template <typename F> const TFuture<void>& Subscribe(F&& callback) const; - + // precondition: EnsureInitialized() passes // postcondition: std::terminate is highly unlikely template <typename F> @@ -165,10 +165,10 @@ namespace NThreading { template <typename F> TFuture<TFutureType<TFutureCallResult<F, void>>> Apply(F&& func) const; - + template <typename R> TFuture<R> Return(const R& value) const; - + TFuture<void> IgnoreResult() const { return *this; } @@ -180,35 +180,35 @@ namespace NThreading { void EnsureInitialized() const; }; - + //////////////////////////////////////////////////////////////////////////////// - + template <typename T> class TPromise { using TFutureState = NImpl::TFutureState<T>; - + private: TIntrusivePtr<TFutureState> State = nullptr; - + public: TPromise() noexcept = default; TPromise(const TPromise<T>& other) noexcept = default; TPromise(TPromise<T>&& other) noexcept = default; TPromise(const TIntrusivePtr<TFutureState>& state) noexcept; - + TPromise<T>& operator=(const TPromise<T>& other) noexcept = default; TPromise<T>& operator=(TPromise<T>&& other) noexcept = default; void Swap(TPromise<T>& other); - + bool Initialized() const; - + bool HasValue() const; const T& GetValue() const; T ExtractValue(); - + void SetValue(const T& value); void SetValue(T&& value); - + bool TrySetValue(const T& value); bool TrySetValue(T&& value); @@ -217,56 +217,56 @@ namespace NThreading { void SetException(const TString& e); void SetException(std::exception_ptr e); bool TrySetException(std::exception_ptr e); - + TFuture<T> GetFuture() const; operator TFuture<T>() const; - + private: void EnsureInitialized() const; }; - + //////////////////////////////////////////////////////////////////////////////// - + template <> class TPromise<void> { using TFutureState = NImpl::TFutureState<void>; - + private: TIntrusivePtr<TFutureState> State; - + public: TPromise() noexcept = default; TPromise(const TPromise<void>& other) noexcept = default; TPromise(TPromise<void>&& other) noexcept = default; TPromise(const TIntrusivePtr<TFutureState>& state) noexcept; - + TPromise<void>& operator=(const TPromise<void>& other) noexcept = default; TPromise<void>& operator=(TPromise<void>&& other) noexcept = default; void Swap(TPromise<void>& other); - + bool Initialized() const; - + bool HasValue() const; void GetValue() const; - + void SetValue(); bool TrySetValue(); - + void TryRethrow() const; bool HasException() const; void SetException(const TString& e); void SetException(std::exception_ptr e); bool TrySetException(std::exception_ptr e); - + TFuture<void> GetFuture() const; operator TFuture<void>() const; - + private: void EnsureInitialized() const; }; - + } - -#define INCLUDE_FUTURE_INL_H -#include "future-inl.h" -#undef INCLUDE_FUTURE_INL_H + +#define INCLUDE_FUTURE_INL_H +#include "future-inl.h" +#undef INCLUDE_FUTURE_INL_H diff --git a/library/cpp/threading/future/future.h b/library/cpp/threading/future/future.h index 35db9abbe2..6b138a3583 100644 --- a/library/cpp/threading/future/future.h +++ b/library/cpp/threading/future/future.h @@ -1,4 +1,4 @@ -#pragma once - +#pragma once + #include "core/future.h" #include "wait/wait.h" diff --git a/library/cpp/threading/future/future_ut.cpp b/library/cpp/threading/future/future_ut.cpp index 05950a568d..a9d5a6cfbd 100644 --- a/library/cpp/threading/future/future_ut.cpp +++ b/library/cpp/threading/future/future_ut.cpp @@ -1,7 +1,7 @@ -#include "future.h" - +#include "future.h" + #include <library/cpp/testing/unittest/registar.h> - + #include <list> #include <type_traits> @@ -63,168 +63,168 @@ namespace { } //////////////////////////////////////////////////////////////////////////////// - + Y_UNIT_TEST_SUITE(TFutureTest) { Y_UNIT_TEST(ShouldInitiallyHasNoValue) { TPromise<int> promise; UNIT_ASSERT(!promise.HasValue()); - + promise = NewPromise<int>(); UNIT_ASSERT(!promise.HasValue()); - + TFuture<int> future; UNIT_ASSERT(!future.HasValue()); - + future = promise.GetFuture(); UNIT_ASSERT(!future.HasValue()); } - + Y_UNIT_TEST(ShouldInitiallyHasNoValueVoid) { TPromise<void> promise; UNIT_ASSERT(!promise.HasValue()); - + promise = NewPromise(); UNIT_ASSERT(!promise.HasValue()); - + TFuture<void> future; UNIT_ASSERT(!future.HasValue()); - + future = promise.GetFuture(); UNIT_ASSERT(!future.HasValue()); } - + Y_UNIT_TEST(ShouldStoreValue) { TPromise<int> promise = NewPromise<int>(); promise.SetValue(123); UNIT_ASSERT(promise.HasValue()); UNIT_ASSERT_EQUAL(promise.GetValue(), 123); - + TFuture<int> future = promise.GetFuture(); UNIT_ASSERT(future.HasValue()); UNIT_ASSERT_EQUAL(future.GetValue(), 123); - + future = MakeFuture(345); UNIT_ASSERT(future.HasValue()); UNIT_ASSERT_EQUAL(future.GetValue(), 345); } - + Y_UNIT_TEST(ShouldStoreValueVoid) { TPromise<void> promise = NewPromise(); promise.SetValue(); UNIT_ASSERT(promise.HasValue()); - + TFuture<void> future = promise.GetFuture(); UNIT_ASSERT(future.HasValue()); - + future = MakeFuture(); UNIT_ASSERT(future.HasValue()); } - + struct TTestCallback { int Value; - + TTestCallback(int value) : Value(value) { } - + void Callback(const TFuture<int>& future) { Value += future.GetValue(); } - + int Func(const TFuture<int>& future) { return (Value += future.GetValue()); } - + void VoidFunc(const TFuture<int>& future) { future.GetValue(); } - + TFuture<int> FutureFunc(const TFuture<int>& future) { return MakeFuture(Value += future.GetValue()); } - + TPromise<void> Signal = NewPromise(); TFuture<void> FutureVoidFunc(const TFuture<int>& future) { future.GetValue(); return Signal; } }; - + Y_UNIT_TEST(ShouldInvokeCallback) { TPromise<int> promise = NewPromise<int>(); - + TTestCallback callback(123); TFuture<int> future = promise.GetFuture() .Subscribe([&](const TFuture<int>& theFuture) { return callback.Callback(theFuture); }); - + promise.SetValue(456); UNIT_ASSERT_EQUAL(future.GetValue(), 456); UNIT_ASSERT_EQUAL(callback.Value, 123 + 456); } - + Y_UNIT_TEST(ShouldApplyFunc) { TPromise<int> promise = NewPromise<int>(); - + TTestCallback callback(123); TFuture<int> future = promise.GetFuture() .Apply([&](const auto& theFuture) { return callback.Func(theFuture); }); - + promise.SetValue(456); UNIT_ASSERT_EQUAL(future.GetValue(), 123 + 456); UNIT_ASSERT_EQUAL(callback.Value, 123 + 456); } - + Y_UNIT_TEST(ShouldApplyVoidFunc) { TPromise<int> promise = NewPromise<int>(); - + TTestCallback callback(123); TFuture<void> future = promise.GetFuture() .Apply([&](const auto& theFuture) { return callback.VoidFunc(theFuture); }); - + promise.SetValue(456); UNIT_ASSERT(future.HasValue()); } - + Y_UNIT_TEST(ShouldApplyFutureFunc) { TPromise<int> promise = NewPromise<int>(); - + TTestCallback callback(123); TFuture<int> future = promise.GetFuture() .Apply([&](const auto& theFuture) { return callback.FutureFunc(theFuture); }); - + promise.SetValue(456); UNIT_ASSERT_EQUAL(future.GetValue(), 123 + 456); UNIT_ASSERT_EQUAL(callback.Value, 123 + 456); } - + Y_UNIT_TEST(ShouldApplyFutureVoidFunc) { TPromise<int> promise = NewPromise<int>(); - + TTestCallback callback(123); TFuture<void> future = promise.GetFuture() .Apply([&](const auto& theFuture) { return callback.FutureVoidFunc(theFuture); }); - + promise.SetValue(456); UNIT_ASSERT(!future.HasValue()); - + callback.Signal.SetValue(); UNIT_ASSERT(future.HasValue()); } - + Y_UNIT_TEST(ShouldIgnoreResultIfAsked) { TPromise<int> promise = NewPromise<int>(); - + TTestCallback callback(123); TFuture<int> future = promise.GetFuture().IgnoreResult().Return(42); - + promise.SetValue(456); UNIT_ASSERT_EQUAL(future.GetValue(), 42); } - + class TCustomException: public yexception { }; - + Y_UNIT_TEST(ShouldRethrowException) { TPromise<int> promise = NewPromise<int>(); try { @@ -238,7 +238,7 @@ namespace { UNIT_ASSERT_EXCEPTION(promise.GetValue(), TCustomException); UNIT_ASSERT_EXCEPTION(promise.TryRethrow(), TCustomException); } - + Y_UNIT_TEST(ShouldRethrowCallbackException) { TPromise<int> promise = NewPromise<int>(); TFuture<int> future = promise.GetFuture(); @@ -263,21 +263,21 @@ namespace { Y_UNIT_TEST(ShouldWaitExceptionOrAll) { TPromise<void> promise1 = NewPromise(); TPromise<void> promise2 = NewPromise(); - + TFuture<void> future = WaitExceptionOrAll(promise1, promise2); UNIT_ASSERT(!future.HasValue()); - + promise1.SetValue(); UNIT_ASSERT(!future.HasValue()); - + promise2.SetValue(); UNIT_ASSERT(future.HasValue()); } - + Y_UNIT_TEST(ShouldWaitExceptionOrAllVector) { TPromise<void> promise1 = NewPromise(); TPromise<void> promise2 = NewPromise(); - + TVector<TFuture<void>> promises; promises.push_back(promise1); promises.push_back(promise2); @@ -403,21 +403,21 @@ namespace { TFuture<void> future = WaitAny(promise1, promise2); UNIT_ASSERT(!future.HasValue()); - + promise1.SetValue(); UNIT_ASSERT(future.HasValue()); - + promise2.SetValue(); UNIT_ASSERT(future.HasValue()); } - + Y_UNIT_TEST(ShouldStoreTypesWithoutDefaultConstructor) { // compileability test struct TRec { explicit TRec(int) { } }; - + auto promise = NewPromise<TRec>(); promise.SetValue(TRec(1)); @@ -425,22 +425,22 @@ namespace { const auto& rec = future.GetValue(); Y_UNUSED(rec); } - + Y_UNIT_TEST(ShouldStoreMovableTypes) { // compileability test struct TRec : TMoveOnly { explicit TRec(int) { } }; - + auto promise = NewPromise<TRec>(); promise.SetValue(TRec(1)); - + auto future = MakeFuture(TRec(1)); const auto& rec = future.GetValue(); Y_UNUSED(rec); } - + Y_UNIT_TEST(ShouldMoveMovableTypes) { // compileability test struct TRec : TMoveOnly { diff --git a/library/cpp/threading/future/perf/main.cpp b/library/cpp/threading/future/perf/main.cpp index 5a0690af47..71e9e293de 100644 --- a/library/cpp/threading/future/perf/main.cpp +++ b/library/cpp/threading/future/perf/main.cpp @@ -1,50 +1,50 @@ #include <library/cpp/testing/benchmark/bench.h> #include <library/cpp/threading/future/future.h> - + #include <util/generic/string.h> -#include <util/generic/xrange.h> - -using namespace NThreading; - -template <typename T> +#include <util/generic/xrange.h> + +using namespace NThreading; + +template <typename T> void TestAllocPromise(const NBench::NCpu::TParams& iface) { for (const auto it : xrange(iface.Iterations())) { - Y_UNUSED(it); - Y_DO_NOT_OPTIMIZE_AWAY(NewPromise<T>()); - } -} - -template <typename T> + Y_UNUSED(it); + Y_DO_NOT_OPTIMIZE_AWAY(NewPromise<T>()); + } +} + +template <typename T> TPromise<T> SetPromise(T value) { - auto promise = NewPromise<T>(); - promise.SetValue(value); - return promise; -} - -template <typename T> + auto promise = NewPromise<T>(); + promise.SetValue(value); + return promise; +} + +template <typename T> void TestSetPromise(const NBench::NCpu::TParams& iface, T value) { for (const auto it : xrange(iface.Iterations())) { - Y_UNUSED(it); - Y_DO_NOT_OPTIMIZE_AWAY(SetPromise(value)); - } -} - + Y_UNUSED(it); + Y_DO_NOT_OPTIMIZE_AWAY(SetPromise(value)); + } +} + Y_CPU_BENCHMARK(AllocPromiseVoid, iface) { - TestAllocPromise<void>(iface); -} - + TestAllocPromise<void>(iface); +} + Y_CPU_BENCHMARK(AllocPromiseUI64, iface) { - TestAllocPromise<ui64>(iface); -} - + TestAllocPromise<ui64>(iface); +} + Y_CPU_BENCHMARK(AllocPromiseStroka, iface) { TestAllocPromise<TString>(iface); -} - +} + Y_CPU_BENCHMARK(SetPromiseUI64, iface) { - TestSetPromise<ui64>(iface, 1234567890ull); -} - + TestSetPromise<ui64>(iface, 1234567890ull); +} + Y_CPU_BENCHMARK(SetPromiseStroka, iface) { TestSetPromise<TString>(iface, "test test test"); -} +} diff --git a/library/cpp/threading/future/perf/ya.make b/library/cpp/threading/future/perf/ya.make index 943d585d4b..b56e66a838 100644 --- a/library/cpp/threading/future/perf/ya.make +++ b/library/cpp/threading/future/perf/ya.make @@ -1,16 +1,16 @@ Y_BENCHMARK(library-threading-future-perf) - + OWNER( g:rtmr ishfb ) - -SRCS( - main.cpp -) - -PEERDIR( + +SRCS( + main.cpp +) + +PEERDIR( library/cpp/threading/future -) - -END() +) + +END() diff --git a/library/cpp/threading/future/ut/ya.make b/library/cpp/threading/future/ut/ya.make index 566b622370..c4d5a7e1d2 100644 --- a/library/cpp/threading/future/ut/ya.make +++ b/library/cpp/threading/future/ut/ya.make @@ -6,7 +6,7 @@ OWNER( ) SRCS( - async_ut.cpp + async_ut.cpp future_ut.cpp legacy_future_ut.cpp ) diff --git a/library/cpp/threading/future/wait/wait-inl.h b/library/cpp/threading/future/wait/wait-inl.h index 2753d5446c..f778cf7fd5 100644 --- a/library/cpp/threading/future/wait/wait-inl.h +++ b/library/cpp/threading/future/wait/wait-inl.h @@ -1,16 +1,16 @@ -#pragma once - -#if !defined(INCLUDE_FUTURE_INL_H) +#pragma once + +#if !defined(INCLUDE_FUTURE_INL_H) #error "you should never include wait-inl.h directly" #endif // INCLUDE_FUTURE_INL_H - + namespace NThreading { namespace NImpl { template <typename TContainer> TVector<TFuture<void>> ToVoidFutures(const TContainer& futures) { TVector<TFuture<void>> voidFutures; voidFutures.reserve(futures.size()); - + for (const auto& future: futures) { voidFutures.push_back(future.IgnoreResult()); } @@ -18,7 +18,7 @@ namespace NThreading { return voidFutures; } } - + template <typename TContainer> [[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitAll(const TContainer& futures) { return WaitAll(NImpl::ToVoidFutures(futures)); @@ -27,10 +27,10 @@ namespace NThreading { template <typename TContainer> [[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitExceptionOrAll(const TContainer& futures) { return WaitExceptionOrAll(NImpl::ToVoidFutures(futures)); - } + } template <typename TContainer> [[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitAny(const TContainer& futures) { return WaitAny(NImpl::ToVoidFutures(futures)); - } -} + } +} diff --git a/library/cpp/threading/future/wait/wait.cpp b/library/cpp/threading/future/wait/wait.cpp index a173833a7f..5d040985f2 100644 --- a/library/cpp/threading/future/wait/wait.cpp +++ b/library/cpp/threading/future/wait/wait.cpp @@ -1,5 +1,5 @@ #include "wait.h" - + #include "wait_group.h" #include "wait_policy.h" @@ -9,16 +9,16 @@ namespace NThreading { TFuture<void> WaitGeneric(const TFuture<void>& f1) { return f1; } - + template <class WaitPolicy> TFuture<void> WaitGeneric(const TFuture<void>& f1, const TFuture<void>& f2) { TWaitGroup<WaitPolicy> wg; - + wg.Add(f1).Add(f2); - + return std::move(wg).Finish(); } - + template <class WaitPolicy> TFuture<void> WaitGeneric(TArrayRef<const TFuture<void>> futures) { if (futures.empty()) { @@ -32,13 +32,13 @@ namespace NThreading { for (const auto& fut : futures) { wg.Add(fut); } - + return std::move(wg).Finish(); } } - + //////////////////////////////////////////////////////////////////////////////// - + TFuture<void> WaitAll(const TFuture<void>& f1) { return WaitGeneric<TWaitPolicy::TAll>(f1); } @@ -57,26 +57,26 @@ namespace NThreading { TFuture<void> WaitExceptionOrAll(const TFuture<void>& f1) { return WaitGeneric<TWaitPolicy::TExceptionOrAll>(f1); } - + TFuture<void> WaitExceptionOrAll(const TFuture<void>& f1, const TFuture<void>& f2) { return WaitGeneric<TWaitPolicy::TExceptionOrAll>(f1, f2); } - + TFuture<void> WaitExceptionOrAll(TArrayRef<const TFuture<void>> futures) { return WaitGeneric<TWaitPolicy::TExceptionOrAll>(futures); - } + } //////////////////////////////////////////////////////////////////////////////// - + TFuture<void> WaitAny(const TFuture<void>& f1) { return WaitGeneric<TWaitPolicy::TAny>(f1); } - + TFuture<void> WaitAny(const TFuture<void>& f1, const TFuture<void>& f2) { return WaitGeneric<TWaitPolicy::TAny>(f1, f2); } - + TFuture<void> WaitAny(TArrayRef<const TFuture<void>> futures) { return WaitGeneric<TWaitPolicy::TAny>(futures); - } -} + } +} diff --git a/library/cpp/threading/future/wait/wait.h b/library/cpp/threading/future/wait/wait.h index 6ff7d57baa..bfccede548 100644 --- a/library/cpp/threading/future/wait/wait.h +++ b/library/cpp/threading/future/wait/wait.h @@ -1,10 +1,10 @@ -#pragma once - +#pragma once + #include "fwd.h" #include <library/cpp/threading/future/core/future.h> #include <library/cpp/threading/future/wait/wait_group.h> - + #include <util/generic/array_ref.h> namespace NThreading { @@ -27,7 +27,7 @@ namespace NThreading { [[nodiscard]] TFuture<void> WaitExceptionOrAll(TArrayRef<const TFuture<void>> futures); template <typename TContainer> [[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitExceptionOrAll(const TContainer& futures); - + // waits for any future [[nodiscard]] TFuture<void> WaitAny(const TFuture<void>& f1); [[nodiscard]] TFuture<void> WaitAny(const TFuture<void>& f1, const TFuture<void>& f2); @@ -35,7 +35,7 @@ namespace NThreading { template <typename TContainer> [[nodiscard]] NImpl::EnableGenericWait<TContainer> WaitAny(const TContainer& futures); } - -#define INCLUDE_FUTURE_INL_H + +#define INCLUDE_FUTURE_INL_H #include "wait-inl.h" -#undef INCLUDE_FUTURE_INL_H +#undef INCLUDE_FUTURE_INL_H diff --git a/library/cpp/threading/future/ya.make b/library/cpp/threading/future/ya.make index 6591031f46..3a0db18662 100644 --- a/library/cpp/threading/future/ya.make +++ b/library/cpp/threading/future/ya.make @@ -4,7 +4,7 @@ OWNER( LIBRARY() -SRCS( +SRCS( async.cpp core/future.cpp core/fwd.cpp @@ -13,8 +13,8 @@ SRCS( wait/wait.cpp wait/wait_group.cpp wait/wait_policy.cpp -) - +) + END() RECURSE_FOR_TESTS( diff --git a/library/cpp/threading/skip_list/compare.h b/library/cpp/threading/skip_list/compare.h index ac98b3e1ce..c63003d67f 100644 --- a/library/cpp/threading/skip_list/compare.h +++ b/library/cpp/threading/skip_list/compare.h @@ -1,14 +1,14 @@ -#pragma once - -#include <util/generic/typetraits.h> -#include <util/str_stl.h> - -namespace NThreading { +#pragma once + +#include <util/generic/typetraits.h> +#include <util/str_stl.h> + +namespace NThreading { namespace NImpl { Y_HAS_MEMBER(compare); Y_HAS_MEMBER(Compare); - - template <typename T> + + template <typename T> inline int CompareImpl(const T& l, const T& r) { if (l < r) { return -1; @@ -17,8 +17,8 @@ namespace NThreading { } else { return 0; } - } - + } + template <bool val> struct TSmallCompareSelector { template <typename T> @@ -26,7 +26,7 @@ namespace NThreading { return CompareImpl(l, r); } }; - + template <> struct TSmallCompareSelector<true> { template <typename T> @@ -34,7 +34,7 @@ namespace NThreading { return l.compare(r); } }; - + template <bool val> struct TBigCompareSelector { template <typename T> @@ -51,15 +51,15 @@ namespace NThreading { } }; - template <typename T> + template <typename T> struct TCompareSelector: public TBigCompareSelector<THasCompare<T>::value> { }; } - + //////////////////////////////////////////////////////////////////////////////// // Generic compare function - template <typename T> + template <typename T> inline int Compare(const T& l, const T& r) { return NImpl::TCompareSelector<T>::Compare(l, r); } @@ -72,6 +72,6 @@ namespace NThreading { inline int operator()(const T& l, const T& r) const { return Compare(l, r); } - }; - -} + }; + +} diff --git a/library/cpp/threading/skip_list/perf/main.cpp b/library/cpp/threading/skip_list/perf/main.cpp index 4ad52049e7..4e8d5b4082 100644 --- a/library/cpp/threading/skip_list/perf/main.cpp +++ b/library/cpp/threading/skip_list/perf/main.cpp @@ -1,56 +1,56 @@ #include <library/cpp/threading/skip_list/skiplist.h> - + #include <library/cpp/getopt/small/last_getopt.h> #include <library/cpp/charset/ci_string.h> -#include <util/datetime/base.h> -#include <util/generic/map.h> -#include <util/generic/vector.h> +#include <util/datetime/base.h> +#include <util/generic/map.h> +#include <util/generic/vector.h> #include <functional> -#include <util/memory/pool.h> -#include <util/random/random.h> -#include <util/string/join.h> -#include <util/system/mutex.h> -#include <util/system/thread.h> - -namespace { +#include <util/memory/pool.h> +#include <util/random/random.h> +#include <util/string/join.h> +#include <util/system/mutex.h> +#include <util/system/thread.h> + +namespace { using namespace NThreading; - + //////////////////////////////////////////////////////////////////////////////// - + IOutputStream& LogInfo() { return Cerr << TInstant::Now() << " INFO: "; } - + IOutputStream& LogError() { return Cerr << TInstant::Now() << " ERROR: "; } - + //////////////////////////////////////////////////////////////////////////////// - + struct TListItem { TStringBuf Key; TStringBuf Value; - + TListItem(const TStringBuf& key, const TStringBuf& value) : Key(key) , Value(value) { } - + int Compare(const TListItem& other) const { return Key.compare(other.Key); } }; - + using TListType = TSkipList<TListItem>; - + //////////////////////////////////////////////////////////////////////////////// - + class TRandomData { private: TVector<char> Buffer; - + public: TRandomData() : Buffer(1024 * 1024) @@ -59,34 +59,34 @@ namespace { Buffer[i] = RandomNumber<char>(); } } - + TStringBuf GetString(size_t len) const { size_t start = RandomNumber(Buffer.size() - len); return TStringBuf(&Buffer[start], len); - } - + } + TStringBuf GetString(size_t min, size_t max) const { return GetString(min + RandomNumber(max - min)); } }; - + //////////////////////////////////////////////////////////////////////////////// - + class TWorkerThread: public ISimpleThread { private: std::function<void()> Func; TDuration Time; - + public: TWorkerThread(std::function<void()> func) : Func(func) { } - + TDuration GetTime() const { return Time; } - + private: void* ThreadProc() noexcept override { TInstant started = TInstant::Now(); @@ -95,33 +95,33 @@ namespace { return nullptr; } }; - + inline TAutoPtr<TWorkerThread> StartThread(std::function<void()> func) { TAutoPtr<TWorkerThread> thread = new TWorkerThread(func); thread->Start(); return thread; - } - + } + //////////////////////////////////////////////////////////////////////////////// - + typedef std::function<void()> TTestFunc; - + struct TTest { TString Name; TTestFunc Func; - + TTest() { } - + TTest(const TString& name, const TTestFunc& func) : Name(name) , Func(func) { } }; - + //////////////////////////////////////////////////////////////////////////////// - + class TTestSuite { private: size_t Iterations = 1000000; @@ -130,72 +130,72 @@ namespace { size_t NumReaders = 4; size_t NumWriters = 1; size_t BatchSize = 20; - + TMemoryPool MemoryPool; TListType List; TMutex Mutex; TRandomData Random; - + TMap<TCiString, TTest> AllTests; TVector<TTest> Tests; - + public: TTestSuite() : MemoryPool(64 * 1024) , List(MemoryPool) { } - + bool Init(int argc, const char* argv[]) { TVector<TString> tests; try { NLastGetopt::TOpts opts; opts.AddHelpOption(); - + #define OPTION(opt, x) \ opts.AddLongOption(opt, #x) \ .Optional() \ .DefaultValue(ToString(x)) \ .StoreResult(&x) // end of OPTION - + OPTION('i', Iterations); OPTION('k', KeyLen); OPTION('v', ValueLen); OPTION('r', NumReaders); OPTION('w', NumWriters); OPTION('b', BatchSize); - -#undef OPTION - + +#undef OPTION + NLastGetopt::TOptsParseResultException optsRes(&opts, argc, argv); for (const auto& opt : opts.Opts_) { const NLastGetopt::TOptParseResult* r = optsRes.FindOptParseResult(opt.Get(), true); if (r) { LogInfo() << "[-" << opt->GetChar() << "] " << opt->GetName() << ": " << r->Back() << Endl; } - } + } tests = optsRes.GetFreeArgs(); } catch (...) { LogError() << CurrentExceptionMessage() << Endl; return false; - } - -#define TEST(type) \ + } + +#define TEST(type) \ AddTest(#type, std::bind(&TTestSuite::Y_CAT(TEST_, type), this)) // end of TEST - + TEST(Clear); TEST(InsertRandom); TEST(InsertSequential); TEST(InsertSequentialSimple); TEST(LookupRandom); TEST(Concurrent); - -#undef TEST - + +#undef TEST + if (tests.empty()) { LogError() << "no tests specified, choose from: " << PrintTests() << Endl; - return false; - } + return false; + } for (size_t i = 0; i < tests.size(); ++i) { if (!AllTests.contains(tests[i])) { @@ -206,13 +206,13 @@ namespace { } return true; - } - + } + void Run() { -#if !defined(NDEBUG) +#if !defined(NDEBUG) LogInfo() << "*** DEBUG build! ***" << Endl; -#endif - +#endif + for (const TTest& test : Tests) { LogInfo() << "Starting test " << test.Name << Endl; @@ -224,7 +224,7 @@ namespace { << " failed: " << CurrentExceptionMessage() << Endl; } - + LogInfo() << "List size = " << List.GetSize() << Endl; TDuration duration = TInstant::Now() - started; @@ -234,31 +234,31 @@ namespace { << Endl; LogInfo() << "Finished test " << test.Name << Endl; } - } - + } + private: void AddTest(const char* name, TTestFunc func) { AllTests[name] = TTest(name, func); } - + TString PrintTests() const { TVector<TString> names; for (const auto& it : AllTests) { names.push_back(it.first); } return JoinSeq(", ", names); - } - + } + void TEST_Clear() { List.Clear(); } - + void TEST_InsertRandom() { for (size_t i = 0; i < Iterations; ++i) { List.Insert(TListItem(Random.GetString(KeyLen), Random.GetString(ValueLen))); } - } - + } + void TEST_InsertSequential() { TString key; for (size_t i = 0; i < Iterations;) { @@ -269,9 +269,9 @@ namespace { key.append((char)j); List.Insert(TListItem(key, Random.GetString(ValueLen))); } - } - } - + } + } + void TEST_InsertSequentialSimple() { for (size_t i = 0; i < Iterations; ++i) { List.Insert(TListItem(Random.GetString(KeyLen), Random.GetString(ValueLen))); @@ -282,11 +282,11 @@ namespace { for (size_t i = 0; i < Iterations; ++i) { List.SeekTo(TListItem(Random.GetString(KeyLen), TStringBuf())); } - } - + } + void TEST_Concurrent() { LogInfo() << "starting producers..." << Endl; - + TVector<TAutoPtr<TWorkerThread>> producers(NumWriters); for (size_t i1 = 0; i1 < producers.size(); ++i1) { producers[i1] = StartThread([&] { @@ -304,9 +304,9 @@ namespace { << Endl; }); } - + LogInfo() << "starting consumers..." << Endl; - + TVector<TAutoPtr<TWorkerThread>> consumers(NumReaders); for (size_t i1 = 0; i1 < consumers.size(); ++i1) { consumers[i1] = StartThread([&] { @@ -321,42 +321,42 @@ namespace { << Endl; }); } - + LogInfo() << "wait for producers..." << Endl; - + TDuration producerTime; for (size_t i = 0; i < producers.size(); ++i) { producers[i]->Join(); producerTime += producers[i]->GetTime(); } - + LogInfo() << "wait for consumers..." << Endl; - + TDuration consumerTime; for (size_t i = 0; i < consumers.size(); ++i) { consumers[i]->Join(); consumerTime += consumers[i]->GetTime(); } - + LogInfo() << "average producer time: " << producerTime.SecondsFloat() / producers.size() << " seconds" << Endl; - + LogInfo() << "average consumer time: " << consumerTime.SecondsFloat() / consumers.size() << " seconds" << Endl; } }; - + } - -//////////////////////////////////////////////////////////////////////////////// - + +//////////////////////////////////////////////////////////////////////////////// + int main(int argc, const char* argv[]) { - TTestSuite suite; - if (!suite.Init(argc, argv)) { - return -1; - } - suite.Run(); - return 0; -} + TTestSuite suite; + if (!suite.Init(argc, argv)) { + return -1; + } + suite.Run(); + return 0; +} diff --git a/library/cpp/threading/skip_list/perf/ya.make b/library/cpp/threading/skip_list/perf/ya.make index 01bfafa404..d64a58a60e 100644 --- a/library/cpp/threading/skip_list/perf/ya.make +++ b/library/cpp/threading/skip_list/perf/ya.make @@ -1,15 +1,15 @@ -PROGRAM(skiplist-perf) - +PROGRAM(skiplist-perf) + OWNER(g:rtmr) - -PEERDIR( + +PEERDIR( library/cpp/charset library/cpp/getopt/small library/cpp/threading/skip_list -) - -SRCS( - main.cpp -) - -END() +) + +SRCS( + main.cpp +) + +END() diff --git a/library/cpp/threading/skip_list/skiplist.cpp b/library/cpp/threading/skip_list/skiplist.cpp index c6e98816fb..386b9546d4 100644 --- a/library/cpp/threading/skip_list/skiplist.cpp +++ b/library/cpp/threading/skip_list/skiplist.cpp @@ -1 +1 @@ -#include "skiplist.h" +#include "skiplist.h" diff --git a/library/cpp/threading/skip_list/skiplist.h b/library/cpp/threading/skip_list/skiplist.h index 914a7c6ee7..054a1b10b9 100644 --- a/library/cpp/threading/skip_list/skiplist.h +++ b/library/cpp/threading/skip_list/skiplist.h @@ -1,69 +1,69 @@ -#pragma once - -#include "compare.h" - -#include <util/generic/algorithm.h> -#include <util/generic/noncopyable.h> -#include <util/generic/typetraits.h> -#include <util/memory/pool.h> -#include <util/random/random.h> -#include <util/system/atomic.h> - -namespace NThreading { +#pragma once + +#include "compare.h" + +#include <util/generic/algorithm.h> +#include <util/generic/noncopyable.h> +#include <util/generic/typetraits.h> +#include <util/memory/pool.h> +#include <util/random/random.h> +#include <util/system/atomic.h> + +namespace NThreading { //////////////////////////////////////////////////////////////////////////////// - + class TNopCounter { protected: template <typename T> void OnInsert(const T&) { } - + template <typename T> void OnUpdate(const T&) { } - + void Reset() { } }; - + //////////////////////////////////////////////////////////////////////////////// - + class TSizeCounter { - private: + private: size_t Size; - - public: + + public: TSizeCounter() : Size(0) - { - } - + { + } + size_t GetSize() const { return Size; - } - + } + protected: template <typename T> void OnInsert(const T&) { ++Size; - } - + } + template <typename T> void OnUpdate(const T&) { - } - + } + void Reset() { Size = 0; - } - }; - + } + }; + //////////////////////////////////////////////////////////////////////////////// // Append-only concurrent skip-list // // Readers do not require any synchronization. // Writers should be externally synchronized. // Nodes will be allocated using TMemoryPool instance. - + template < typename T, typename TComparer = TCompare<T>, @@ -104,41 +104,41 @@ namespace NThreading { } }; - public: + public: class TIterator { private: const TSkipList* List; const TNode* Node; - + public: TIterator() : List(nullptr) , Node(nullptr) { } - + TIterator(const TSkipList* list, const TNode* node) : List(list) , Node(node) { } - + TIterator(const TIterator& other) : List(other.List) , Node(other.Node) { } - + TIterator& operator=(const TIterator& other) { List = other.List; Node = other.Node; return *this; } - + void Next() { Node = Node ? Node->GetNext(0) : nullptr; - } - + } + // much less efficient than Next as our list is single-linked void Prev() { if (Node) { @@ -146,34 +146,34 @@ namespace NThreading { Node = (node != List->Head ? node : nullptr); } } - + void Reset() { Node = nullptr; } - + bool IsValid() const { return Node != nullptr; } - + const T& GetValue() const { Y_ASSERT(IsValid()); return Node->GetValue(); } }; - + private: TAllocator& Allocator; TComparer Comparer; - + TNode* Head; TAtomic Height; TCounter Counter; - + TNode* Prev[MaxHeight]; - + template <typename TValue> using TComparerReturnType = std::invoke_result_t<TComparer, const T&, const TValue&>; - + public: TSkipList(TAllocator& allocator, const TComparer& comparer = TComparer()) : Allocator(allocator) @@ -181,28 +181,28 @@ namespace NThreading { { Init(); } - + ~TSkipList() { CallDtors(); } - + void Clear() { CallDtors(); Allocator.ClearKeepFirstChunk(); Init(); - } - + } + bool Insert(T value) { TNode* node = PrepareInsert(value); if (Y_UNLIKELY(node && Compare(node, value) == 0)) { // we do not allow duplicates return false; - } + } node = DoInsert(std::move(value)); TCounter::OnInsert(node->GetValue()); return true; - } - + } + template <typename TInsertAction, typename TUpdateAction> bool Insert(const T& value, TInsertAction insert, TUpdateAction update) { TNode* node = PrepareInsert(value); @@ -218,27 +218,27 @@ namespace NThreading { TCounter::OnInsert(node->GetValue()); return true; } - + template <typename TValue> bool Contains(const TValue& value) const { TNode* node = FindGreaterThanOrEqual(value); return node && Compare(node, value) == 0; } - + TIterator SeekToFirst() const { return TIterator(this, FindFirst()); } - + TIterator SeekToLast() const { TNode* last = FindLast(); return TIterator(this, last != Head ? last : nullptr); } - + template <typename TValue> TIterator SeekTo(const TValue& value) const { return TIterator(this, FindGreaterThanOrEqual(value)); - } - + } + private: static int RandomHeight() { int height = 1; @@ -247,7 +247,7 @@ namespace NThreading { } return height; } - + void Init() { Head = AllocateRootNode(); Height = 1; @@ -256,8 +256,8 @@ namespace NThreading { for (int i = 0; i < MaxHeight; ++i) { Prev[i] = Head; } - } - + } + void CallDtors() { if (!TTypeTraits<T>::IsPod) { // we should explicitly call destructors for our nodes @@ -267,56 +267,56 @@ namespace NThreading { node->~TNode(); node = next; } - } - } - + } + } + TNode* AllocateRootNode() { size_t size = sizeof(TNode) + sizeof(TNode*) * MaxHeight; void* buffer = Allocator.Allocate(size); memset(buffer, 0, size); return static_cast<TNode*>(buffer); } - + TNode* AllocateNode(T&& value, int height) { size_t size = sizeof(TNode) + sizeof(TNode*) * height; void* buffer = Allocator.Allocate(size); memset(buffer, 0, size); return new (buffer) TNode(std::move(value)); } - + TNode* FindFirst() const { return Head->GetNext(0); } - + TNode* FindLast() const { TNode* node = Head; int height = AtomicGet(Height) - 1; - + while (true) { TNode* next = node->GetNext(height); if (next) { node = next; continue; } - + if (height) { --height; } else { return node; } - } - } - + } + } + template <typename TValue> TComparerReturnType<TValue> Compare(const TNode* node, const TValue& value) const { return Comparer(node->GetValue(), value); } - + template <typename TValue> TNode* FindLessThan(const TValue& value, TNode** links) const { TNode* node = Head; int height = AtomicGet(Height) - 1; - + TNode* prev = nullptr; while (true) { TNode* next = node->GetNext(height); @@ -326,27 +326,27 @@ namespace NThreading { node = next; continue; } - } - + } + if (links) { // collect links from upper levels links[height] = node; } - + if (height) { prev = next; --height; } else { return node; } - } - } - + } + } + template <typename TValue> TNode* FindGreaterThanOrEqual(const TValue& value) const { TNode* node = Head; int height = AtomicGet(Height) - 1; - + TNode* prev = nullptr; while (true) { TNode* next = node->GetNext(height); @@ -359,29 +359,29 @@ namespace NThreading { if (cmp == 0) { return next; } - } + } if (height) { prev = next; --height; } else { - return next; - } - } + return next; + } + } } - + TNode* PrepareInsert(const T& value) { TNode* prev = Prev[0]; TNode* next = prev->GetNext(0); if ((prev == Head || Compare(prev, value) < 0) && (next == nullptr || Compare(next, value) >= 0)) { // avoid seek in case of sequential insert - } else { + } else { prev = FindLessThan(value, Prev); next = prev->GetNext(0); - } + } return next; - } - + } + TNode* DoInsert(T&& value) { // choose level to place new node int currentHeight = AtomicGet(Height); @@ -392,17 +392,17 @@ namespace NThreading { Prev[i] = Head; } AtomicSet(Height, height); - } - + } + TNode* node = AllocateNode(std::move(value), height); node->Link(height, Prev); - + // keep last inserted node to optimize sequential inserts for (int i = 0; i < height; i++) { Prev[i] = node; } return node; - } + } }; - + } diff --git a/library/cpp/threading/skip_list/skiplist_ut.cpp b/library/cpp/threading/skip_list/skiplist_ut.cpp index 52fcffda66..e7d0b62873 100644 --- a/library/cpp/threading/skip_list/skiplist_ut.cpp +++ b/library/cpp/threading/skip_list/skiplist_ut.cpp @@ -1,91 +1,91 @@ -#include "skiplist.h" - +#include "skiplist.h" + #include <library/cpp/testing/unittest/registar.h> - -namespace NThreading { + +namespace NThreading { namespace { struct TTestObject { static size_t Count; int Tag; - + TTestObject(int tag) : Tag(tag) { ++Count; } - + TTestObject(const TTestObject& other) : Tag(other.Tag) { ++Count; } - + ~TTestObject() { --Count; } - + bool operator<(const TTestObject& other) const { return Tag < other.Tag; } }; - + size_t TTestObject::Count = 0; - - } - + + } + //////////////////////////////////////////////////////////////////////////////// - + Y_UNIT_TEST_SUITE(TSkipListTest) { Y_UNIT_TEST(ShouldBeEmptyAfterCreation) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + UNIT_ASSERT_EQUAL(list.GetSize(), 0); } - + Y_UNIT_TEST(ShouldAllowInsertion) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + UNIT_ASSERT(list.Insert(12345678)); UNIT_ASSERT_EQUAL(list.GetSize(), 1); } - + Y_UNIT_TEST(ShouldNotAllowDuplicates) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + UNIT_ASSERT(list.Insert(12345678)); UNIT_ASSERT_EQUAL(list.GetSize(), 1); - + UNIT_ASSERT(!list.Insert(12345678)); UNIT_ASSERT_EQUAL(list.GetSize(), 1); } - + Y_UNIT_TEST(ShouldContainInsertedItem) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + UNIT_ASSERT(list.Insert(12345678)); UNIT_ASSERT(list.Contains(12345678)); } - + Y_UNIT_TEST(ShouldNotContainNotInsertedItem) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + UNIT_ASSERT(list.Insert(12345678)); UNIT_ASSERT(!list.Contains(87654321)); } - + Y_UNIT_TEST(ShouldIterateAllItems) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + for (int i = 8; i > 0; --i) { UNIT_ASSERT(list.Insert(i)); } - + TSkipList<int>::TIterator it = list.SeekToFirst(); for (int i = 1; i <= 8; ++i) { UNIT_ASSERT(it.IsValid()); @@ -94,15 +94,15 @@ namespace NThreading { } UNIT_ASSERT(!it.IsValid()); } - + Y_UNIT_TEST(ShouldIterateAllItemsInReverseDirection) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + for (int i = 8; i > 0; --i) { UNIT_ASSERT(list.Insert(i)); } - + TSkipList<int>::TIterator it = list.SeekToLast(); for (int i = 8; i > 0; --i) { UNIT_ASSERT(it.IsValid()); @@ -111,75 +111,75 @@ namespace NThreading { } UNIT_ASSERT(!it.IsValid()); } - + Y_UNIT_TEST(ShouldSeekToFirstItem) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + for (int i = 1; i < 10; ++i) { UNIT_ASSERT(list.Insert(i)); } - + TSkipList<int>::TIterator it = list.SeekToFirst(); UNIT_ASSERT(it.IsValid()); UNIT_ASSERT_EQUAL(it.GetValue(), 1); } - + Y_UNIT_TEST(ShouldSeekToLastItem) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + for (int i = 1; i < 10; ++i) { UNIT_ASSERT(list.Insert(i)); } - + TSkipList<int>::TIterator it = list.SeekToLast(); UNIT_ASSERT(it.IsValid()); UNIT_ASSERT_EQUAL(it.GetValue(), 9); } - + Y_UNIT_TEST(ShouldSeekToExistingItem) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + UNIT_ASSERT(list.Insert(12345678)); - + TSkipList<int>::TIterator it = list.SeekTo(12345678); UNIT_ASSERT(it.IsValid()); } - + Y_UNIT_TEST(ShouldSeekAfterMissedItem) { TMemoryPool pool(1024); TSkipList<int> list(pool); - + UNIT_ASSERT(list.Insert(100)); UNIT_ASSERT(list.Insert(300)); - + TSkipList<int>::TIterator it = list.SeekTo(200); UNIT_ASSERT(it.IsValid()); UNIT_ASSERT_EQUAL(it.GetValue(), 300); - + it.Prev(); UNIT_ASSERT(it.IsValid()); UNIT_ASSERT_EQUAL(it.GetValue(), 100); } - + Y_UNIT_TEST(ShouldCallDtorsOfNonPodTypes) { UNIT_ASSERT(!TTypeTraits<TTestObject>::IsPod); UNIT_ASSERT_EQUAL(TTestObject::Count, 0); - + { TMemoryPool pool(1024); TSkipList<TTestObject> list(pool); - + UNIT_ASSERT(list.Insert(TTestObject(1))); UNIT_ASSERT(list.Insert(TTestObject(2))); - + UNIT_ASSERT_EQUAL(TTestObject::Count, 2); } UNIT_ASSERT_EQUAL(TTestObject::Count, 0); } - } - + } + } diff --git a/library/cpp/threading/skip_list/ut/ya.make b/library/cpp/threading/skip_list/ut/ya.make index 704a31e9a2..ae07423e71 100644 --- a/library/cpp/threading/skip_list/ut/ya.make +++ b/library/cpp/threading/skip_list/ut/ya.make @@ -1,9 +1,9 @@ UNITTEST_FOR(library/cpp/threading/skip_list) - + OWNER(g:rtmr) - -SRCS( - skiplist_ut.cpp -) - -END() + +SRCS( + skiplist_ut.cpp +) + +END() diff --git a/library/cpp/threading/skip_list/ya.make b/library/cpp/threading/skip_list/ya.make index d338aeae2b..923fcb3566 100644 --- a/library/cpp/threading/skip_list/ya.make +++ b/library/cpp/threading/skip_list/ya.make @@ -1,9 +1,9 @@ -LIBRARY() - +LIBRARY() + OWNER(g:rtmr) - -SRCS( - skiplist.cpp -) - -END() + +SRCS( + skiplist.cpp +) + +END() diff --git a/library/cpp/ytalloc/api/fallback.cpp b/library/cpp/ytalloc/api/fallback.cpp index 5880ede439..7b4e607cb7 100644 --- a/library/cpp/ytalloc/api/fallback.cpp +++ b/library/cpp/ytalloc/api/fallback.cpp @@ -19,13 +19,13 @@ Y_WEAK void* Allocate(size_t size) Y_WEAK void* AllocatePageAligned(size_t size) { -#if defined(_win_) - return ::_aligned_malloc(size, PageSize); +#if defined(_win_) + return ::_aligned_malloc(size, PageSize); #elif defined(_darwin_) || !defined(_musl_) return ::valloc(size); -#else +#else return ::memalign(PageSize, size); -#endif +#endif } Y_WEAK void* AllocateSmall(size_t rank) diff --git a/library/cpp/ytalloc/api/ytalloc.h b/library/cpp/ytalloc/api/ytalloc.h index d942dde638..81684e724e 100644 --- a/library/cpp/ytalloc/api/ytalloc.h +++ b/library/cpp/ytalloc/api/ytalloc.h @@ -15,9 +15,9 @@ namespace NYT::NYTAlloc { //////////////////////////////////////////////////////////////////////////////// // Macros -#if defined(_linux_) && \ - !defined(_asan_enabled_) && \ - !defined(_msan_enabled_) && \ +#if defined(_linux_) && \ + !defined(_asan_enabled_) && \ + !defined(_msan_enabled_) && \ !defined(_tsan_enabled_) #define YT_ALLOC_ENABLED #endif |