diff options
author | Alexander Gololobov <davenger@yandex-team.com> | 2022-02-10 16:47:38 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:38 +0300 |
commit | fccc62e9bfdce9be2fe7e0f23479da3a5512211a (patch) | |
tree | c0748b5dcbade83af788c0abfa89c0383d6b779c /library/cpp | |
parent | 39608cdb86363c75ce55b2b9a69841c3b71f22cf (diff) | |
download | ydb-fccc62e9bfdce9be2fe7e0f23479da3a5512211a.tar.gz |
Restoring authorship annotation for Alexander Gololobov <davenger@yandex-team.com>. Commit 2 of 2.
Diffstat (limited to 'library/cpp')
86 files changed, 1867 insertions, 1867 deletions
diff --git a/library/cpp/actors/core/actor.h b/library/cpp/actors/core/actor.h index 7eabe6fbd1..ed29bd14b9 100644 --- a/library/cpp/actors/core/actor.h +++ b/library/cpp/actors/core/actor.h @@ -218,7 +218,7 @@ namespace NActors { TActorIdentity SelfActorId; i64 ElapsedTicks; ui64 HandledEvents; - + friend void DoActorInit(TActorSystem*, IActor*, const TActorId&, const TActorId&); friend class TDecorator; @@ -235,10 +235,10 @@ namespace NActors { INTERCONNECT_COMMON = 171, SELF_PING_ACTOR = 207, TEST_ACTOR_RUNTIME = 283, - INTERCONNECT_HANDSHAKE = 284, - INTERCONNECT_POLLER = 285, - INTERCONNECT_SESSION_KILLER = 286, - ACTOR_SYSTEM_SCHEDULER_ACTOR = 312, + INTERCONNECT_HANDSHAKE = 284, + INTERCONNECT_POLLER = 285, + INTERCONNECT_SESSION_KILLER = 286, + ACTOR_SYSTEM_SCHEDULER_ACTOR = 312, ACTOR_FUTURE_CALLBACK = 337, INTERCONNECT_MONACTOR = 362, INTERCONNECT_LOAD_ACTOR = 376, @@ -418,10 +418,10 @@ namespace NActors { } protected: - //* Comment this function to find unmarked activities + //* Comment this function to find unmarked activities static constexpr IActor::EActivityType ActorActivityType() { return EActorActivity::OTHER; - } //*/ + } //*/ // static constexpr char ActorName[] = "UNNAMED"; diff --git a/library/cpp/actors/core/actorsystem.h b/library/cpp/actors/core/actorsystem.h index 242794ac6f..40499d7586 100644 --- a/library/cpp/actors/core/actorsystem.h +++ b/library/cpp/actors/core/actorsystem.h @@ -8,7 +8,7 @@ #include "event.h" #include "log_settings.h" #include "scheduler_cookie.h" -#include "mon_stats.h" +#include "mon_stats.h" #include <library/cpp/threading/future/future.h> #include <library/cpp/actors/util/ticket_lock.h> @@ -58,7 +58,7 @@ namespace NActors { , DestroyedActors(0) { } - + virtual ~IExecutorPool() { } @@ -348,7 +348,7 @@ namespace NActors { T* AppData() const { return (T*)AppData0; } - + NLog::TSettings* LoggerSettings() const { return LoggerSettings0.Get(); } diff --git a/library/cpp/actors/core/defs.h b/library/cpp/actors/core/defs.h index 6c50ab677c..980b7d767b 100644 --- a/library/cpp/actors/core/defs.h +++ b/library/cpp/actors/core/defs.h @@ -6,12 +6,12 @@ #include <util/generic/hash.h> #include <util/string/printf.h> -// Enables collection of -// event send/receive counts -// activation time histograms -// event processing time histograms -#define ACTORSLIB_COLLECT_EXEC_STATS - +// Enables collection of +// event send/receive counts +// activation time histograms +// event processing time histograms +#define ACTORSLIB_COLLECT_EXEC_STATS + namespace NActors { using TPoolId = ui8; using TPoolsMask = ui64; diff --git a/library/cpp/actors/core/event.h b/library/cpp/actors/core/event.h index 9d2b694cb2..6ff02aaf94 100644 --- a/library/cpp/actors/core/event.h +++ b/library/cpp/actors/core/event.h @@ -7,9 +7,9 @@ #include <library/cpp/actors/wilson/wilson_trace.h> -#include <util/system/hp_timer.h> +#include <util/system/hp_timer.h> #include <util/generic/maybe.h> - + namespace NActors { class TChunkSerializer; @@ -110,10 +110,10 @@ namespace NActors { // filled if feeded by interconnect session const TActorId InterconnectSession; -#ifdef ACTORSLIB_COLLECT_EXEC_STATS +#ifdef ACTORSLIB_COLLECT_EXEC_STATS ::NHPTimer::STime SendTime; -#endif - +#endif + static const size_t ChannelBits = 12; static const size_t ChannelShift = (sizeof(ui32) << 3) - ChannelBits; @@ -174,9 +174,9 @@ namespace NActors { , Sender(sender) , Cookie(cookie) , TraceId(std::move(traceId)) -#ifdef ACTORSLIB_COLLECT_EXEC_STATS +#ifdef ACTORSLIB_COLLECT_EXEC_STATS , SendTime(0) -#endif +#endif , Event(ev) , RewriteRecipient(Recipient) , RewriteType(Type) @@ -199,9 +199,9 @@ namespace NActors { , Sender(sender) , Cookie(cookie) , TraceId(std::move(traceId)) -#ifdef ACTORSLIB_COLLECT_EXEC_STATS +#ifdef ACTORSLIB_COLLECT_EXEC_STATS , SendTime(0) -#endif +#endif , Buffer(std::move(buffer)) , RewriteRecipient(Recipient) , RewriteType(Type) @@ -228,9 +228,9 @@ namespace NActors { , OriginScopeId(originScopeId) , TraceId(std::move(traceId)) , InterconnectSession(session) -#ifdef ACTORSLIB_COLLECT_EXEC_STATS +#ifdef ACTORSLIB_COLLECT_EXEC_STATS , SendTime(0) -#endif +#endif , Buffer(std::move(buffer)) , RewriteRecipient(Recipient) , RewriteType(Type) diff --git a/library/cpp/actors/core/event_pb.h b/library/cpp/actors/core/event_pb.h index d7ff4a3cbe..d7546b901a 100644 --- a/library/cpp/actors/core/event_pb.h +++ b/library/cpp/actors/core/event_pb.h @@ -127,27 +127,27 @@ namespace NActors { static const size_t EventMaxByteSize = 67108000; #endif - template <typename TEv, typename TRecord /*protobuf record*/, ui32 TEventType, typename TRecHolder> - class TEventPBBase: public TEventBase<TEv, TEventType> , public TRecHolder { + template <typename TEv, typename TRecord /*protobuf record*/, ui32 TEventType, typename TRecHolder> + class TEventPBBase: public TEventBase<TEv, TEventType> , public TRecHolder { // a vector of data buffers referenced by record; if filled, then extended serialization mechanism applies TVector<TRope> Payload; public: - using TRecHolder::Record; - - public: + using TRecHolder::Record; + + public: using ProtoRecordType = TRecord; - TEventPBBase() = default; + TEventPBBase() = default; - explicit TEventPBBase(const TRecord& rec) + explicit TEventPBBase(const TRecord& rec) { - Record = rec; + Record = rec; } - explicit TEventPBBase(TRecord&& rec) + explicit TEventPBBase(TRecord&& rec) { - Record = std::move(rec); + Record = std::move(rec); } TString ToStringHeader() const override { @@ -231,7 +231,7 @@ namespace NActors { } static IEventBase* Load(TIntrusivePtr<TEventSerializedData> input) { - THolder<TEventPBBase> ev(new TEv()); + THolder<TEventPBBase> ev(new TEv()); if (!input->GetSize()) { Y_PROTOBUF_SUPPRESS_NODISCARD ev->Record.ParseFromString(TString()); } else { @@ -273,7 +273,7 @@ namespace NActors { } ev->CachedByteSize = input->GetSize(); return ev.Release(); - } + } size_t GetCachedByteSize() const { if (CachedByteSize == 0) { @@ -369,43 +369,43 @@ namespace NActors { } }; - // Protobuf record not using arena - template <typename TRecord> - struct TRecordHolder { - TRecord Record; - }; - - // Protobuf arena and a record allocated on it - template <typename TRecord, size_t InitialBlockSize, size_t MaxBlockSize> - struct TArenaRecordHolder { - google::protobuf::Arena PbArena; - TRecord& Record; - - static const google::protobuf::ArenaOptions GetArenaOptions() { - google::protobuf::ArenaOptions opts; - opts.initial_block_size = InitialBlockSize; - opts.max_block_size = MaxBlockSize; - return opts; - } - - TArenaRecordHolder() - : PbArena(GetArenaOptions()) - , Record(*google::protobuf::Arena::CreateMessage<TRecord>(&PbArena)) - {} - }; - + // Protobuf record not using arena + template <typename TRecord> + struct TRecordHolder { + TRecord Record; + }; + + // Protobuf arena and a record allocated on it + template <typename TRecord, size_t InitialBlockSize, size_t MaxBlockSize> + struct TArenaRecordHolder { + google::protobuf::Arena PbArena; + TRecord& Record; + + static const google::protobuf::ArenaOptions GetArenaOptions() { + google::protobuf::ArenaOptions opts; + opts.initial_block_size = InitialBlockSize; + opts.max_block_size = MaxBlockSize; + return opts; + } + + TArenaRecordHolder() + : PbArena(GetArenaOptions()) + , Record(*google::protobuf::Arena::CreateMessage<TRecord>(&PbArena)) + {} + }; + + template <typename TEv, typename TRecord, ui32 TEventType> + class TEventPB : public TEventPBBase<TEv, TRecord, TEventType, TRecordHolder<TRecord> > { + typedef TEventPBBase<TEv, TRecord, TEventType, TRecordHolder<TRecord> > TPbBase; + // NOTE: No extra fields allowed: TEventPB must be a "template typedef" + public: + using TPbBase::TPbBase; + }; + + template <typename TEv, typename TRecord, ui32 TEventType, size_t InitialBlockSize = 512, size_t MaxBlockSize = 16*1024> + using TEventPBWithArena = TEventPBBase<TEv, TRecord, TEventType, TArenaRecordHolder<TRecord, InitialBlockSize, MaxBlockSize> >; + template <typename TEv, typename TRecord, ui32 TEventType> - class TEventPB : public TEventPBBase<TEv, TRecord, TEventType, TRecordHolder<TRecord> > { - typedef TEventPBBase<TEv, TRecord, TEventType, TRecordHolder<TRecord> > TPbBase; - // NOTE: No extra fields allowed: TEventPB must be a "template typedef" - public: - using TPbBase::TPbBase; - }; - - template <typename TEv, typename TRecord, ui32 TEventType, size_t InitialBlockSize = 512, size_t MaxBlockSize = 16*1024> - using TEventPBWithArena = TEventPBBase<TEv, TRecord, TEventType, TArenaRecordHolder<TRecord, InitialBlockSize, MaxBlockSize> >; - - template <typename TEv, typename TRecord, ui32 TEventType> class TEventShortDebugPB: public TEventPB<TEv, TRecord, TEventType> { public: using TBase = TEventPB<TEv, TRecord, TEventType>; @@ -455,7 +455,7 @@ namespace NActors { base.Swap(©); PreSerializedData.clear(); } - return TBase::Record; + return TBase::Record; } const TRecord& GetRecord() const { @@ -463,7 +463,7 @@ namespace NActors { } TRecord* MutableRecord() { - GetRecord(); // Make sure PreSerializedData is parsed + GetRecord(); // Make sure PreSerializedData is parsed return &(TBase::Record); } diff --git a/library/cpp/actors/core/event_pb_payload_ut.cpp b/library/cpp/actors/core/event_pb_payload_ut.cpp index 4dcc958bb1..eab007bc15 100644 --- a/library/cpp/actors/core/event_pb_payload_ut.cpp +++ b/library/cpp/actors/core/event_pb_payload_ut.cpp @@ -8,7 +8,7 @@ using namespace NActors; enum { EvMessageWithPayload = EventSpaceBegin(TEvents::ES_PRIVATE), - EvArenaMessage, + EvArenaMessage, EvArenaMessageBig, EvMessageWithPayloadPreSerialized }; @@ -38,81 +38,81 @@ TString MakeString(size_t len) { Y_UNIT_TEST_SUITE(TEventProtoWithPayload) { - template <class TEventFrom, class TEventTo> - void TestSerializeDeserialize(size_t size1, size_t size2) { - static_assert(TEventFrom::EventType == TEventTo::EventType, "Must be same event type"); + template <class TEventFrom, class TEventTo> + void TestSerializeDeserialize(size_t size1, size_t size2) { + static_assert(TEventFrom::EventType == TEventTo::EventType, "Must be same event type"); - TEventFrom msg; - msg.Record.SetMeta("hello, world!"); - msg.Record.AddPayloadId(msg.AddPayload(MakeStringRope(MakeString(size1)))); - msg.Record.AddPayloadId(msg.AddPayload(MakeStringRope(MakeString(size2)))); - msg.Record.AddSomeData(MakeString((size1 + size2) % 50 + 11)); + TEventFrom msg; + msg.Record.SetMeta("hello, world!"); + msg.Record.AddPayloadId(msg.AddPayload(MakeStringRope(MakeString(size1)))); + msg.Record.AddPayloadId(msg.AddPayload(MakeStringRope(MakeString(size2)))); + msg.Record.AddSomeData(MakeString((size1 + size2) % 50 + 11)); - auto serializer = MakeHolder<TAllocChunkSerializer>(); + auto serializer = MakeHolder<TAllocChunkSerializer>(); msg.SerializeToArcadiaStream(serializer.Get()); - auto buffers = serializer->Release(msg.IsExtendedFormat()); - UNIT_ASSERT_VALUES_EQUAL(buffers->GetSize(), msg.CalculateSerializedSize()); - TString ser = buffers->GetString(); - - TString chunkerRes; - TCoroutineChunkSerializer chunker; - chunker.SetSerializingEvent(&msg); - while (!chunker.IsComplete()) { - char buffer[4096]; + auto buffers = serializer->Release(msg.IsExtendedFormat()); + UNIT_ASSERT_VALUES_EQUAL(buffers->GetSize(), msg.CalculateSerializedSize()); + TString ser = buffers->GetString(); + + TString chunkerRes; + TCoroutineChunkSerializer chunker; + chunker.SetSerializingEvent(&msg); + while (!chunker.IsComplete()) { + char buffer[4096]; auto range = chunker.FeedBuf(buffer, sizeof(buffer)); for (auto p = range.first; p != range.second; ++p) { chunkerRes += TString(p->first, p->second); } } - UNIT_ASSERT_VALUES_EQUAL(chunkerRes, ser); - + UNIT_ASSERT_VALUES_EQUAL(chunkerRes, ser); + THolder<IEventBase> ev2 = THolder(TEventTo::Load(buffers)); - TEventTo& msg2 = static_cast<TEventTo&>(*ev2); - UNIT_ASSERT_VALUES_EQUAL(msg2.Record.GetMeta(), msg.Record.GetMeta()); - UNIT_ASSERT_EQUAL(msg2.GetPayload(msg2.Record.GetPayloadId(0)), msg.GetPayload(msg.Record.GetPayloadId(0))); - UNIT_ASSERT_EQUAL(msg2.GetPayload(msg2.Record.GetPayloadId(1)), msg.GetPayload(msg.Record.GetPayloadId(1))); + TEventTo& msg2 = static_cast<TEventTo&>(*ev2); + UNIT_ASSERT_VALUES_EQUAL(msg2.Record.GetMeta(), msg.Record.GetMeta()); + UNIT_ASSERT_EQUAL(msg2.GetPayload(msg2.Record.GetPayloadId(0)), msg.GetPayload(msg.Record.GetPayloadId(0))); + UNIT_ASSERT_EQUAL(msg2.GetPayload(msg2.Record.GetPayloadId(1)), msg.GetPayload(msg.Record.GetPayloadId(1))); + } + + template <class TEvent> + void TestAllSizes(size_t step1 = 100, size_t step2 = 111) { + for (size_t size1 = 0; size1 < 10000; size1 += step1) { + for (size_t size2 = 0; size2 < 10000; size2 += step2) { + TestSerializeDeserialize<TEvent, TEvent>(size1, size2); + } + } } - - template <class TEvent> - void TestAllSizes(size_t step1 = 100, size_t step2 = 111) { - for (size_t size1 = 0; size1 < 10000; size1 += step1) { - for (size_t size2 = 0; size2 < 10000; size2 += step2) { - TestSerializeDeserialize<TEvent, TEvent>(size1, size2); - } - } - } - + #if (!defined(_tsan_enabled_)) - Y_UNIT_TEST(SerializeDeserialize) { - TestAllSizes<TEvMessageWithPayload>(); - } + Y_UNIT_TEST(SerializeDeserialize) { + TestAllSizes<TEvMessageWithPayload>(); + } #endif - - - struct TEvArenaMessage : TEventPBWithArena<TEvArenaMessage, TMessageWithPayload, EvArenaMessage> { - }; - - Y_UNIT_TEST(SerializeDeserializeArena) { - TestAllSizes<TEvArenaMessage>(500, 111); - } - - - struct TEvArenaMessageBig : TEventPBWithArena<TEvArenaMessageBig, TMessageWithPayload, EvArenaMessageBig, 4000, 32000> { - }; - - Y_UNIT_TEST(SerializeDeserializeArenaBig) { - TestAllSizes<TEvArenaMessageBig>(111, 500); - } - - - // Compatible with TEvArenaMessage but doesn't use arenas - struct TEvArenaMessageWithoutArena : TEventPB<TEvArenaMessageWithoutArena, TMessageWithPayload, EvArenaMessage> { - }; - - Y_UNIT_TEST(Compatibility) { - TestSerializeDeserialize<TEvArenaMessage, TEvArenaMessageWithoutArena>(200, 14010); - TestSerializeDeserialize<TEvArenaMessageWithoutArena, TEvArenaMessage>(2000, 4010); - } + + + struct TEvArenaMessage : TEventPBWithArena<TEvArenaMessage, TMessageWithPayload, EvArenaMessage> { + }; + + Y_UNIT_TEST(SerializeDeserializeArena) { + TestAllSizes<TEvArenaMessage>(500, 111); + } + + + struct TEvArenaMessageBig : TEventPBWithArena<TEvArenaMessageBig, TMessageWithPayload, EvArenaMessageBig, 4000, 32000> { + }; + + Y_UNIT_TEST(SerializeDeserializeArenaBig) { + TestAllSizes<TEvArenaMessageBig>(111, 500); + } + + + // Compatible with TEvArenaMessage but doesn't use arenas + struct TEvArenaMessageWithoutArena : TEventPB<TEvArenaMessageWithoutArena, TMessageWithPayload, EvArenaMessage> { + }; + + Y_UNIT_TEST(Compatibility) { + TestSerializeDeserialize<TEvArenaMessage, TEvArenaMessageWithoutArena>(200, 14010); + TestSerializeDeserialize<TEvArenaMessageWithoutArena, TEvArenaMessage>(2000, 4010); + } Y_UNIT_TEST(PreSerializedCompatibility) { // ensure TEventPreSerializedPB and TEventPB are interchangable with no compatibility issues diff --git a/library/cpp/actors/core/executelater.h b/library/cpp/actors/core/executelater.h index a2e380e466..e7a13c1005 100644 --- a/library/cpp/actors/core/executelater.h +++ b/library/cpp/actors/core/executelater.h @@ -8,10 +8,10 @@ namespace NActors { template <typename TCallback> class TExecuteLater: public TActorBootstrapped<TExecuteLater<TCallback>> { public: - static constexpr IActor::EActivityType ActorActivityType() { - return IActor::ACTORLIB_COMMON; - } - + static constexpr IActor::EActivityType ActorActivityType() { + return IActor::ACTORLIB_COMMON; + } + TExecuteLater( TCallback&& callback, IActor::EActivityType activityType, diff --git a/library/cpp/actors/core/executor_pool_base.cpp b/library/cpp/actors/core/executor_pool_base.cpp index e3852eaf8d..c3b9999168 100644 --- a/library/cpp/actors/core/executor_pool_base.cpp +++ b/library/cpp/actors/core/executor_pool_base.cpp @@ -16,9 +16,9 @@ namespace NActors { : IExecutorPool(poolId) , ActorSystem(nullptr) , MailboxTable(new TMailboxTable) -#ifdef ACTORSLIB_COLLECT_EXEC_STATS - , Stats(maxActivityType) -#endif +#ifdef ACTORSLIB_COLLECT_EXEC_STATS + , Stats(maxActivityType) +#endif {} TExecutorPoolBaseMailboxed::~TExecutorPoolBaseMailboxed() { @@ -47,9 +47,9 @@ namespace NActors { bool TExecutorPoolBaseMailboxed::Send(TAutoPtr<IEventHandle>& ev) { Y_VERIFY_DEBUG(ev->GetRecipientRewrite().PoolID() == PoolId); -#ifdef ACTORSLIB_COLLECT_EXEC_STATS +#ifdef ACTORSLIB_COLLECT_EXEC_STATS RelaxedStore(&ev->SendTime, (::NHPTimer::STime)GetCycleCountFast()); -#endif +#endif return MailboxTable->SendTo(ev, this); } @@ -59,21 +59,21 @@ namespace NActors { TActorId TExecutorPoolBaseMailboxed::Register(IActor* actor, TMailboxType::EType mailboxType, ui64 revolvingWriteCounter, const TActorId& parentId) { NHPTimer::STime hpstart = GetCycleCountFast(); -#ifdef ACTORSLIB_COLLECT_EXEC_STATS +#ifdef ACTORSLIB_COLLECT_EXEC_STATS ui32 at = actor->GetActivityType(); if (at >= Stats.MaxActivityType()) at = 0; AtomicIncrement(Stats.ActorsAliveByActivity[at]); -#endif +#endif AtomicIncrement(ActorRegistrations); - + // first step - find good enough mailbox ui32 hint = 0; TMailboxHeader* mailbox = nullptr; if (revolvingWriteCounter == 0) revolvingWriteCounter = AtomicIncrement(RegisterRevolvingCounter); - + { ui32 hintBackoff = 0; @@ -122,7 +122,7 @@ namespace NActors { default: Y_FAIL(); } - + NHPTimer::STime elapsed = GetCycleCountFast() - hpstart; if (elapsed > 1000000) { LWPROBE(SlowRegisterNew, PoolId, NHPTimer::GetSeconds(elapsed) * 1000.0); @@ -133,14 +133,14 @@ namespace NActors { TActorId TExecutorPoolBaseMailboxed::Register(IActor* actor, TMailboxHeader* mailbox, ui32 hint, const TActorId& parentId) { NHPTimer::STime hpstart = GetCycleCountFast(); -#ifdef ACTORSLIB_COLLECT_EXEC_STATS +#ifdef ACTORSLIB_COLLECT_EXEC_STATS ui32 at = actor->GetActivityType(); if (at >= Stats.MaxActivityType()) at = 0; AtomicIncrement(Stats.ActorsAliveByActivity[at]); -#endif +#endif AtomicIncrement(ActorRegistrations); - + const ui64 localActorId = AllocateID(); mailbox->AttachActor(localActorId, actor); diff --git a/library/cpp/actors/core/executor_pool_base.h b/library/cpp/actors/core/executor_pool_base.h index 49129e8a8d..c84ce1af77 100644 --- a/library/cpp/actors/core/executor_pool_base.h +++ b/library/cpp/actors/core/executor_pool_base.h @@ -12,11 +12,11 @@ namespace NActors { protected: TActorSystem* ActorSystem; THolder<TMailboxTable> MailboxTable; -#ifdef ACTORSLIB_COLLECT_EXEC_STATS +#ifdef ACTORSLIB_COLLECT_EXEC_STATS // Need to have per pool object to collect stats like actor registrations (because // registrations might be done in threads from other pools) TExecutorThreadStats Stats; -#endif +#endif TAtomic RegisterRevolvingCounter = 0; ui64 AllocateID(); public: diff --git a/library/cpp/actors/core/executor_pool_basic.cpp b/library/cpp/actors/core/executor_pool_basic.cpp index fdd07ef84f..4dce16939a 100644 --- a/library/cpp/actors/core/executor_pool_basic.cpp +++ b/library/cpp/actors/core/executor_pool_basic.cpp @@ -21,8 +21,8 @@ namespace NActors { TAffinity* affinity, TDuration timePerMailbox, ui32 eventsPerMailbox, - int realtimePriority, - ui32 maxActivityType) + int realtimePriority, + ui32 maxActivityType) : TExecutorPoolBase(poolId, threads, affinity, maxActivityType) , SpinThreshold(spinThreshold) , SpinThresholdCycles(spinThreshold * NHPTimer::GetCyclesPerSecond() * 0.000001) // convert microseconds to cycles @@ -195,7 +195,7 @@ namespace NActors { return activation; } SpinLockPause(); - } + } // stopping, die! return 0; @@ -245,8 +245,8 @@ namespace NActors { for (size_t i = 0; i < PoolThreads; ++i) { Threads[i].Thread->GetCurrentStats(statsCopy[i + 1]); } - } - + } + void TBasicExecutorPool::Prepare(TActorSystem* actorSystem, NSchedulerQueue::TReader** scheduleReaders, ui32* scheduleSz) { TAffinityGuard affinityGuard(Affinity()); diff --git a/library/cpp/actors/core/executor_pool_basic.h b/library/cpp/actors/core/executor_pool_basic.h index 2a663ab3ca..023190f7fe 100644 --- a/library/cpp/actors/core/executor_pool_basic.h +++ b/library/cpp/actors/core/executor_pool_basic.h @@ -77,8 +77,8 @@ namespace NActors { TAffinity* affinity = nullptr, TDuration timePerMailbox = DEFAULT_TIME_PER_MAILBOX, ui32 eventsPerMailbox = DEFAULT_EVENTS_PER_MAILBOX, - int realtimePriority = 0, - ui32 maxActivityType = 1); + int realtimePriority = 0, + ui32 maxActivityType = 1); explicit TBasicExecutorPool(const TBasicExecutorPoolConfig& cfg); ~TBasicExecutorPool(); diff --git a/library/cpp/actors/core/executor_pool_io.h b/library/cpp/actors/core/executor_pool_io.h index b4f1472731..e576d642a1 100644 --- a/library/cpp/actors/core/executor_pool_io.h +++ b/library/cpp/actors/core/executor_pool_io.h @@ -26,7 +26,7 @@ namespace NActors { public: TIOExecutorPool(ui32 poolId, ui32 threads, const TString& poolName = "", TAffinity* affinity = nullptr, - ui32 maxActivityType = 1); + ui32 maxActivityType = 1); explicit TIOExecutorPool(const TIOExecutorPoolConfig& cfg); ~TIOExecutorPool(); diff --git a/library/cpp/actors/core/executor_pool_united.cpp b/library/cpp/actors/core/executor_pool_united.cpp index c8c2b3af54..dac6245635 100644 --- a/library/cpp/actors/core/executor_pool_united.cpp +++ b/library/cpp/actors/core/executor_pool_united.cpp @@ -741,7 +741,7 @@ namespace NActors { #endif } } - } + } void WakeFastWorker() { #ifdef _linux_ diff --git a/library/cpp/actors/core/executor_thread.cpp b/library/cpp/actors/core/executor_thread.cpp index 437f1d04b9..446b651efd 100644 --- a/library/cpp/actors/core/executor_thread.cpp +++ b/library/cpp/actors/core/executor_thread.cpp @@ -21,9 +21,9 @@ #include <util/system/type_name.h> #include <util/system/datetime.h> - -LWTRACE_USING(ACTORLIB_PROVIDER) - + +LWTRACE_USING(ACTORLIB_PROVIDER) + namespace NActors { constexpr TDuration TExecutorThread::DEFAULT_TIME_PER_MAILBOX; @@ -98,10 +98,10 @@ namespace NActors { } } - inline TString ActorTypeName(const IActor* actor, ui32 activityType) { - return actor ? SafeTypeName(actor) : ("activityType_" + ToString(activityType) + " (destroyed)"); - } - + inline TString ActorTypeName(const IActor* actor, ui32 activityType) { + return actor ? SafeTypeName(actor) : ("activityType_" + ToString(activityType) + " (destroyed)"); + } + inline void LwTraceSlowDelivery(IEventHandle* ev, const IActor* actor, ui32 poolId, const TActorId& currentRecipient, double delivMs, double sinceActivationMs, ui32 eventsExecutedBefore) { const auto baseEv = (ev && ev->HasEvent()) ? ev->GetBase() : nullptr; @@ -124,13 +124,13 @@ namespace NActors { eventMs, baseEv ? SafeTypeName(baseEv) : ToString(evTypeForTracing), currentRecipient.ToString(), - ActorTypeName(actor, activityType)); + ActorTypeName(actor, activityType)); } template <typename TMailbox> void TExecutorThread::Execute(TMailbox* mailbox, ui32 hint) { Y_VERIFY_DEBUG(DyingActors.empty()); - + bool reclaimAsFree = false; NHPTimer::STime hpstart = GetCycleCountFast(); @@ -167,9 +167,9 @@ namespace NActors { double sinceActivationMs = NHPTimer::GetSeconds(hpprev - hpstart) * 1000.0; LwTraceSlowDelivery(ev.Get(), actor, Ctx.PoolId, CurrentRecipient, NHPTimer::GetSeconds(hpprev - ev->SendTime) * 1000.0, sinceActivationMs, executed); } - + ui32 evTypeForTracing = ev->Type; - + ui32 activityType = actor->GetActivityType(); if (activityType != prevActivityType) { prevActivityType = activityType; @@ -184,10 +184,10 @@ namespace NActors { DropUnregistered(); actor = nullptr; } - + if (mailbox->IsEmpty()) // was not-free and become free, we must reclaim mailbox reclaimAsFree = true; - + hpnow = GetCycleCountFast(); NHPTimer::STime elapsed = Ctx.AddEventProcessingStats(hpprev, hpnow, activityType, CurrentActorScheduledEventsCounter); if (elapsed > 1000000) { @@ -197,9 +197,9 @@ namespace NActors { // The actor might have been destroyed if (actor) actor->AddElapsedTicks(elapsed); - + CurrentRecipient = TActorId(); - } else { + } else { TAutoPtr<IEventHandle> nonDelivered = ev->ForwardOnNondelivery(TEvents::TEvUndelivered::ReasonActorUnknown); if (nonDelivered.Get()) { ActorSystem->Send(nonDelivered); @@ -207,7 +207,7 @@ namespace NActors { Ctx.IncrementNonDeliveredEvents(); } hpnow = GetCycleCountFast(); - } + } hpprev = hpnow; @@ -241,8 +241,8 @@ namespace NActors { recipient.ToString(), SafeTypeName(actor)); break; - } - + } + if (executed + 1 == Ctx.EventsPerMailbox) { AtomicStore(&mailbox->ScheduleMoment, hpnow); Ctx.IncrementMailboxPushedOutByEventCount(); @@ -255,8 +255,8 @@ namespace NActors { Ctx.WorkerId, recipient.ToString(), SafeTypeName(actor)); - break; - } + break; + } } else { if (executed == 0) Ctx.IncrementEmptyMailboxActivation(); @@ -271,7 +271,7 @@ namespace NActors { SafeTypeName(actor)); break; // empty queue, leave } - } + } NProfiling::TMemoryTagScope::Reset(0); TlsActivationContext = nullptr; diff --git a/library/cpp/actors/core/executor_thread.h b/library/cpp/actors/core/executor_thread.h index 6d6e527f9e..9d3c573f0d 100644 --- a/library/cpp/actors/core/executor_thread.h +++ b/library/cpp/actors/core/executor_thread.h @@ -54,15 +54,15 @@ namespace NActors { #ifdef USE_ACTOR_CALLSTACK ev->Callstack = TCallstack::GetTlsCallstack(); ev->Callstack.Trace(); -#endif +#endif Ctx.IncrementSentEvents(); return ActorSystem->Send(ev); } - + void GetCurrentStats(TExecutorThreadStats& statsCopy) const { Ctx.GetCurrentStats(statsCopy); } - + TThreadId GetThreadId() const; // blocks, must be called after Start() TWorkerId GetWorkerId() const { return Ctx.WorkerId; } diff --git a/library/cpp/actors/core/log.cpp b/library/cpp/actors/core/log.cpp index 3edc42012c..5f63b5af58 100644 --- a/library/cpp/actors/core/log.cpp +++ b/library/cpp/actors/core/log.cpp @@ -164,8 +164,8 @@ namespace NActors { std::shared_ptr<NMonitoring::TMetricRegistry> Metrics; }; - TAtomic TLoggerActor::IsOverflow = 0; - + TAtomic TLoggerActor::IsOverflow = 0; + TLoggerActor::TLoggerActor(TIntrusivePtr<NLog::TSettings> settings, TAutoPtr<TLogBackend> logBackend, TIntrusivePtr<NMonitoring::TDynamicCounters> counters) @@ -224,10 +224,10 @@ namespace NActors { } void TLoggerActor::Throttle(const NLog::TSettings& settings) { - if (AtomicGet(IsOverflow)) + if (AtomicGet(IsOverflow)) Sleep(settings.ThrottleDelay); - } - + } + void TLoggerActor::LogIgnoredCount(TInstant now) { TString message = Sprintf("Ignored IgnoredCount# %" PRIu64 " log records due to logger overflow!", IgnoredCount); if (!OutputRecord(now, NActors::NLog::EPrio::Error, Settings->LoggerComponent, message)) { @@ -250,7 +250,7 @@ namespace NActors { Metrics->IncActorMsgs(); const auto prio = ev.Level.ToPrio(); - + switch (prio) { case ::NActors::NLog::EPrio::Alert: Metrics->IncAlertMsgs(); @@ -267,28 +267,28 @@ namespace NActors { void TLoggerActor::HandleLogEvent(NLog::TEvLog::TPtr& ev, const NActors::TActorContext& ctx) { i64 delayMillisec = (ctx.Now() - ev->Get()->Stamp).MilliSeconds(); WriteMessageStat(*ev->Get()); - if (Settings->AllowDrop) { - // Disable throttling if it was enabled previously - if (AtomicGet(IsOverflow)) - AtomicSet(IsOverflow, 0); - - // Check if some records have to be dropped + if (Settings->AllowDrop) { + // Disable throttling if it was enabled previously + if (AtomicGet(IsOverflow)) + AtomicSet(IsOverflow, 0); + + // Check if some records have to be dropped if ((PassedCount > 10 && delayMillisec > (i64)Settings->TimeThresholdMs) || IgnoredCount > 0) { Metrics->IncIgnoredMsgs(); - if (IgnoredCount == 0) { - ctx.Send(ctx.SelfID, new TLogIgnored()); - } - ++IgnoredCount; - PassedCount = 0; - return; + if (IgnoredCount == 0) { + ctx.Send(ctx.SelfID, new TLogIgnored()); + } + ++IgnoredCount; + PassedCount = 0; + return; } - PassedCount++; - } else { - // Enable of disable throttling depending on the load - if (delayMillisec > (i64)Settings->TimeThresholdMs && !AtomicGet(IsOverflow)) - AtomicSet(IsOverflow, 1); - else if (delayMillisec <= (i64)Settings->TimeThresholdMs && AtomicGet(IsOverflow)) - AtomicSet(IsOverflow, 0); + PassedCount++; + } else { + // Enable of disable throttling depending on the load + if (delayMillisec > (i64)Settings->TimeThresholdMs && !AtomicGet(IsOverflow)) + AtomicSet(IsOverflow, 1); + else if (delayMillisec <= (i64)Settings->TimeThresholdMs && AtomicGet(IsOverflow)) + AtomicSet(IsOverflow, 0); } const auto prio = ev->Get()->Level.ToPrio(); @@ -376,8 +376,8 @@ namespace NActors { bool hasPriority = false; bool hasSamplingPriority = false; bool hasSamplingRate = false; - bool hasAllowDrop = false; - int allowDrop = 0; + bool hasAllowDrop = false; + int allowDrop = 0; if (params.Has("c")) { if (TryFromString(params.Get("c"), component) && (component == NLog::InvalidComponent || Settings->IsValidComponent(component))) { hasComponent = true; @@ -402,11 +402,11 @@ namespace NActors { } } } - if (params.Has("allowdrop")) { - if (TryFromString(params.Get("allowdrop"), allowDrop)) { - hasAllowDrop = true; - } - } + if (params.Has("allowdrop")) { + if (TryFromString(params.Get("allowdrop"), allowDrop)) { + hasAllowDrop = true; + } + } TStringStream str; if (hasComponent && !hasPriority && !hasSamplingPriority && !hasSamplingRate) { @@ -485,9 +485,9 @@ namespace NActors { if (hasComponent && hasSamplingRate) { Settings->SetSamplingRate(samplingRate, component, explanation); } - if (hasAllowDrop) { - Settings->SetAllowDrop(allowDrop); - } + if (hasAllowDrop) { + Settings->SetAllowDrop(allowDrop); + } HTML(str) { if (!explanation.empty()) { @@ -559,10 +559,10 @@ namespace NActors { str << "Drop log entries in case of overflow: " << (Settings->AllowDrop ? "Enabled" : "Disabled"); } - str << "<form method=\"GET\">" << Endl; + str << "<form method=\"GET\">" << Endl; str << "<input type=\"hidden\" name=\"allowdrop\" value=\"" << (Settings->AllowDrop ? "0" : "1") << "\"/>" << Endl; str << "<input class=\"btn btn-primary\" type=\"submit\" value=\"" << (Settings->AllowDrop ? "Disable" : "Enable") << "\"/>" << Endl; - str << "</form>" << Endl; + str << "</form>" << Endl; } } Metrics->GetOutputHtml(str); @@ -588,7 +588,7 @@ namespace NActors { logRecord << time; } logRecord - << Settings->MessagePrefix + << Settings->MessagePrefix << " :" << Settings->ComponentName(component) << " " << PriorityToString(priority) << ": " << formatted; diff --git a/library/cpp/actors/core/log.h b/library/cpp/actors/core/log.h index 4219194faa..c11a7cf3c1 100644 --- a/library/cpp/actors/core/log.h +++ b/library/cpp/actors/core/log.h @@ -233,13 +233,13 @@ namespace NActors { void Log(TInstant time, NLog::EPriority priority, NLog::EComponent component, const char* c, ...); static void Throttle(const NLog::TSettings& settings); - + private: TIntrusivePtr<NLog::TSettings> Settings; std::shared_ptr<TLogBackend> LogBackend; ui64 IgnoredCount = 0; ui64 PassedCount = 0; - static TAtomic IsOverflow; + static TAtomic IsOverflow; TDuration WakeupInterval{TDuration::Seconds(5)}; std::unique_ptr<ILoggerMetrics> Metrics; diff --git a/library/cpp/actors/core/log_settings.cpp b/library/cpp/actors/core/log_settings.cpp index e22760d149..f52f2fc5d2 100644 --- a/library/cpp/actors/core/log_settings.cpp +++ b/library/cpp/actors/core/log_settings.cpp @@ -11,7 +11,7 @@ namespace NActors { : LoggerActorId(loggerActorId) , LoggerComponent(loggerComponent) , TimeThresholdMs(timeThresholdMs) - , AllowDrop(true) + , AllowDrop(true) , ThrottleDelay(TDuration::MilliSeconds(100)) , MinVal(0) , MaxVal(0) @@ -33,7 +33,7 @@ namespace NActors { : LoggerActorId(loggerActorId) , LoggerComponent(loggerComponent) , TimeThresholdMs(timeThresholdMs) - , AllowDrop(true) + , AllowDrop(true) , ThrottleDelay(TDuration::MilliSeconds(100)) , MinVal(0) , MaxVal(0) @@ -201,10 +201,10 @@ namespace NActors { return (MinVal <= component) && (component <= MaxVal) && !ComponentNames[component].empty(); } - void TSettings::SetAllowDrop(bool val) { - AllowDrop = val; - } - + void TSettings::SetAllowDrop(bool val) { + AllowDrop = val; + } + void TSettings::SetThrottleDelay(TDuration value) { ThrottleDelay = value; } diff --git a/library/cpp/actors/core/log_settings.h b/library/cpp/actors/core/log_settings.h index acab6bb93e..7fe4504edd 100644 --- a/library/cpp/actors/core/log_settings.h +++ b/library/cpp/actors/core/log_settings.h @@ -72,7 +72,7 @@ namespace NActors { TActorId LoggerActorId; EComponent LoggerComponent; ui64 TimeThresholdMs; - bool AllowDrop; + bool AllowDrop; TDuration ThrottleDelay; TArrayHolder<TAtomic> ComponentInfo; TVector<TString> ComponentNames; @@ -92,7 +92,7 @@ namespace NActors { ELogFormat Format; TString ShortHostName; TString ClusterName; - TString MessagePrefix; + TString MessagePrefix; // The best way to provide minVal, maxVal and func is to have // protobuf enumeration of components. In this case protoc @@ -161,7 +161,7 @@ namespace NActors { static int PowerOf2Mask(int val); static bool IsValidPriority(EPriority priority); bool IsValidComponent(EComponent component); - void SetAllowDrop(bool val); + void SetAllowDrop(bool val); void SetThrottleDelay(TDuration value); void SetUseLocalTimestamps(bool value); diff --git a/library/cpp/actors/core/mailbox.cpp b/library/cpp/actors/core/mailbox.cpp index 87337bfa9e..d84b4f9e46 100644 --- a/library/cpp/actors/core/mailbox.cpp +++ b/library/cpp/actors/core/mailbox.cpp @@ -180,7 +180,7 @@ namespace NActors { TSimpleMailbox* const mailbox = TSimpleMailbox::Get(lineHint, x); #if (!defined(_tsan_enabled_)) Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); -#endif +#endif mailbox->Queue.Push(ev.Release()); if (mailbox->MarkForSchedule()) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); @@ -200,11 +200,11 @@ namespace NActors { "We expect that one line can store more simple mailboxes than revolving mailboxes"); if (lineHint > TRevolvingMailbox::MaxMailboxesInLine()) return false; - + TRevolvingMailbox* const mailbox = TRevolvingMailbox::Get(lineHint, x); #if (!defined(_tsan_enabled_)) Y_VERIFY_DEBUG(mailbox->Type == (ui32)x->MailboxType); -#endif +#endif mailbox->QueueWriter.Push(ev.Release()); if (mailbox->MarkForSchedule()) { RelaxedStore<NHPTimer::STime>(&mailbox->ScheduleMoment, GetCycleCountFast()); diff --git a/library/cpp/actors/core/mailbox.h b/library/cpp/actors/core/mailbox.h index 1879a8aea6..0bd9c4d314 100644 --- a/library/cpp/actors/core/mailbox.h +++ b/library/cpp/actors/core/mailbox.h @@ -370,7 +370,7 @@ namespace NActors { TRevolvingMailbox(); ~TRevolvingMailbox(); - + IEventHandle* Pop() { return QueueReader.Pop(); } diff --git a/library/cpp/actors/core/mon_stats.h b/library/cpp/actors/core/mon_stats.h index 2415537e71..d55552af0c 100644 --- a/library/cpp/actors/core/mon_stats.h +++ b/library/cpp/actors/core/mon_stats.h @@ -1,16 +1,16 @@ -#pragma once - -#include "defs.h" -#include "actor.h" +#pragma once + +#include "defs.h" +#include "actor.h" #include <library/cpp/monlib/metrics/histogram_snapshot.h> -#include <util/system/hp_timer.h> - -namespace NActors { +#include <util/system/hp_timer.h> + +namespace NActors { struct TLogHistogram : public NMonitoring::IHistogramSnapshot { TLogHistogram() { memset(Buckets, 0, sizeof(Buckets)); } - + inline void Add(ui64 val, ui64 inc = 1) { size_t ind = 0; #if defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 7 @@ -27,15 +27,15 @@ namespace NActors { RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc); RelaxedStore(&Buckets[ind], RelaxedLoad(&Buckets[ind]) + inc); } - + void Aggregate(const TLogHistogram& other) { const ui64 inc = RelaxedLoad(&other.TotalSamples); RelaxedStore(&TotalSamples, RelaxedLoad(&TotalSamples) + inc); for (size_t i = 0; i < Y_ARRAY_SIZE(Buckets); ++i) { Buckets[i] += RelaxedLoad(&other.Buckets[i]); } - } - + } + // IHistogramSnapshot ui32 Count() const override { return Y_ARRAY_SIZE(Buckets); @@ -57,7 +57,7 @@ namespace NActors { ui64 TotalSamples = 0; ui64 Buckets[65]; }; - + struct TExecutorPoolStats { ui64 MaxUtilizationTime = 0; }; @@ -86,7 +86,7 @@ namespace NActors { ui64 MailboxPushedOutBySoftPreemption = 0; ui64 MailboxPushedOutByTime = 0; ui64 MailboxPushedOutByEventCount = 0; - + TExecutorThreadStats(size_t activityVecSize = 1) // must be not empty as 0 used as default : ElapsedTicksByActivity(activityVecSize) , ReceivedEventsByActivity(activityVecSize) @@ -103,7 +103,7 @@ namespace NActors { for (size_t at = 0; at < otherSize; ++at) self[at] += RelaxedLoad(&other[at]); } - + void Aggregate(const TExecutorThreadStats& other) { SentEvents += RelaxedLoad(&other.SentEvents); ReceivedEvents += RelaxedLoad(&other.ReceivedEvents); @@ -115,9 +115,9 @@ namespace NActors { ParkedTicks += RelaxedLoad(&other.ParkedTicks); BlockedTicks += RelaxedLoad(&other.BlockedTicks); MailboxPushedOutBySoftPreemption += RelaxedLoad(&other.MailboxPushedOutBySoftPreemption); - MailboxPushedOutByTime += RelaxedLoad(&other.MailboxPushedOutByTime); - MailboxPushedOutByEventCount += RelaxedLoad(&other.MailboxPushedOutByEventCount); - + MailboxPushedOutByTime += RelaxedLoad(&other.MailboxPushedOutByTime); + MailboxPushedOutByEventCount += RelaxedLoad(&other.MailboxPushedOutByEventCount); + ActivationTimeHistogram.Aggregate(other.ActivationTimeHistogram); EventDeliveryTimeHistogram.Aggregate(other.EventDeliveryTimeHistogram); EventProcessingCountHistogram.Aggregate(other.EventProcessingCountHistogram); @@ -143,5 +143,5 @@ namespace NActors { return ActorsAliveByActivity.size(); } }; - + } diff --git a/library/cpp/actors/core/probes.cpp b/library/cpp/actors/core/probes.cpp index ae475bb59f..7ace83e102 100644 --- a/library/cpp/actors/core/probes.cpp +++ b/library/cpp/actors/core/probes.cpp @@ -1,10 +1,10 @@ -#include "probes.h" - +#include "probes.h" + #include "actorsystem.h" #include <util/string/builder.h> -LWTRACE_DEFINE_PROVIDER(ACTORLIB_PROVIDER); +LWTRACE_DEFINE_PROVIDER(ACTORLIB_PROVIDER); namespace NActors { TVector<NLWTrace::TDashboard> LWTraceDashboards(TActorSystemSetup* setup) { diff --git a/library/cpp/actors/core/probes.h b/library/cpp/actors/core/probes.h index 536200b977..4912d6dd26 100644 --- a/library/cpp/actors/core/probes.h +++ b/library/cpp/actors/core/probes.h @@ -1,8 +1,8 @@ -#pragma once - +#pragma once + #include <library/cpp/lwtrace/all.h> #include <util/generic/vector.h> - + #define LWACTORID(x) (x).RawX1(), (x).RawX2(), (x).NodeId(), (x).PoolID() #define LWTYPE_ACTORID ui64, ui64, ui32, ui32 #define LWNAME_ACTORID(n) n "Raw1", n "Raw2", n "NodeId", n "PoolId" @@ -167,8 +167,8 @@ TYPES(ui32, ui64, TString, TString, ui32), \ NAMES("fromPoolId", "toPoolId", "fromPool", "toPool", "cpu")) \ /**/ - -LWTRACE_DECLARE_PROVIDER(ACTORLIB_PROVIDER) + +LWTRACE_DECLARE_PROVIDER(ACTORLIB_PROVIDER) namespace NActors { struct TActorSystemSetup; diff --git a/library/cpp/actors/core/process_stats.cpp b/library/cpp/actors/core/process_stats.cpp index f3a7341980..0e1dbd0031 100644 --- a/library/cpp/actors/core/process_stats.cpp +++ b/library/cpp/actors/core/process_stats.cpp @@ -1,25 +1,25 @@ -#include "actorsystem.h" -#include "actor_bootstrapped.h" -#include "hfunc.h" +#include "actorsystem.h" +#include "actor_bootstrapped.h" +#include "hfunc.h" #include "process_stats.h" - + #include <library/cpp/monlib/dynamic_counters/counters.h> #include <library/cpp/monlib/metrics/metric_registry.h> - + #include <util/datetime/uptime.h> -#include <util/system/defaults.h> -#include <util/stream/file.h> -#include <util/string/vector.h> -#include <util/string/split.h> - -#ifndef _win_ +#include <util/system/defaults.h> +#include <util/stream/file.h> +#include <util/string/vector.h> +#include <util/string/split.h> + +#ifndef _win_ #include <sys/user.h> #include <sys/sysctl.h> -#endif - -namespace NActors { -#ifdef _linux_ - +#endif + +namespace NActors { +#ifdef _linux_ + namespace { template <typename TVal> static bool ExtractVal(const TString& str, const TString& name, TVal& res) { @@ -32,16 +32,16 @@ namespace NActors { res = atol(str.data() + pos); return true; } - + float TicksPerMillisec() { -#ifdef _SC_CLK_TCK +#ifdef _SC_CLK_TCK return sysconf(_SC_CLK_TCK) / 1000.0; -#else +#else return 1.f; -#endif - } +#endif + } } - + bool TProcStat::Fill(pid_t pid) { try { TString strPid(ToString(pid)); @@ -57,9 +57,9 @@ namespace NActors { } // Convert from kB to bytes Rss *= 1024; - + float tickPerMillisec = TicksPerMillisec(); - + TFileInput procStat("/proc/" + strPid + "/stat"); procStat.ReadLine(str); if (!str.empty()) { @@ -114,28 +114,28 @@ namespace NActors { } catch (...) { return false; - } + } return true; - } - + } + long TProcStat::ObtainPageSize() { long sz = sysconf(_SC_PAGESIZE); return sz; } -#else - +#else + bool TProcStat::Fill(pid_t pid) { Y_UNUSED(pid); return false; } - + long TProcStat::ObtainPageSize() { return 0; } -#endif - +#endif + namespace { // Periodically collects process stats and exposes them as mon counters template <typename TDerived> @@ -144,7 +144,7 @@ namespace { static constexpr IActor::EActivityType ActorActivityType() { return IActor::ACTORLIB_STATS; } - + TProcStatCollectingActor(TDuration interval) : Interval(interval) { @@ -154,19 +154,19 @@ namespace { ctx.Schedule(Interval, new TEvents::TEvWakeup()); Self()->Become(&TDerived::StateWork); } - + STFUNC(StateWork) { switch (ev->GetTypeRewrite()) { CFunc(TEvents::TSystem::Wakeup, Wakeup); } } - + private: void Wakeup(const TActorContext& ctx) { Self()->UpdateCounters(ProcStat); ctx.Schedule(Interval, new TEvents::TEvWakeup()); - } - + } + TDerived* Self() { ProcStat.Fill(getpid()); return static_cast<TDerived*>(this); @@ -176,7 +176,7 @@ namespace { const TDuration Interval; TProcStat ProcStat; }; - + // Periodically collects process stats and exposes them as mon counters class TDynamicCounterCollector: public TProcStatCollectingActor<TDynamicCounterCollector> { using TBase = TProcStatCollectingActor<TDynamicCounterCollector>; @@ -295,8 +295,8 @@ namespace { IActor* CreateProcStatCollector(ui32 intervalSec, NMonitoring::TDynamicCounterPtr counters) { return new TDynamicCounterCollector(intervalSec, counters); - } - + } + IActor* CreateProcStatCollector(TDuration interval, NMonitoring::TMetricRegistry& registry) { return new TRegistryCollector(interval, registry); } diff --git a/library/cpp/actors/core/process_stats.h b/library/cpp/actors/core/process_stats.h index 454c04e6f3..66346d0b5a 100644 --- a/library/cpp/actors/core/process_stats.h +++ b/library/cpp/actors/core/process_stats.h @@ -1,15 +1,15 @@ -#pragma once - -#include "defs.h" -#include "actor.h" - +#pragma once + +#include "defs.h" +#include "actor.h" + #include <library/cpp/monlib/dynamic_counters/counters.h> - + namespace NMonitoring { class TMetricRegistry; } -namespace NActors { +namespace NActors { struct TProcStat { ui64 Rss; ui64 VolCtxSwtch; diff --git a/library/cpp/actors/core/scheduler_actor.cpp b/library/cpp/actors/core/scheduler_actor.cpp index 60d972d9aa..febc5e40dd 100644 --- a/library/cpp/actors/core/scheduler_actor.cpp +++ b/library/cpp/actors/core/scheduler_actor.cpp @@ -61,7 +61,7 @@ namespace NActors { public: static constexpr IActor::EActivityType ActorActivityType() { - return IActor::ACTOR_SYSTEM_SCHEDULER_ACTOR; + return IActor::ACTOR_SYSTEM_SCHEDULER_ACTOR; } TSchedulerActor(const TSchedulerConfig& cfg) diff --git a/library/cpp/actors/core/ya.make b/library/cpp/actors/core/ya.make index 5a3a6c7a35..880a9d00db 100644 --- a/library/cpp/actors/core/ya.make +++ b/library/cpp/actors/core/ya.make @@ -80,15 +80,15 @@ SRCS( memory_tracker.cpp memory_tracker.h mon.h - mon_stats.h + mon_stats.h monotonic.cpp monotonic.h worker_context.cpp worker_context.h probes.cpp - probes.h - process_stats.cpp - process_stats.h + probes.h + process_stats.cpp + process_stats.h scheduler_actor.cpp scheduler_actor.h scheduler_basic.cpp diff --git a/library/cpp/actors/helpers/selfping_actor.cpp b/library/cpp/actors/helpers/selfping_actor.cpp index 2fa2ce3a45..f9bfaf8dc0 100644 --- a/library/cpp/actors/helpers/selfping_actor.cpp +++ b/library/cpp/actors/helpers/selfping_actor.cpp @@ -72,8 +72,8 @@ private: public: static constexpr auto ActorActivityType() { return SELF_PING_ACTOR; - } - + } + TSelfPingActor(TDuration sendInterval, const NMonitoring::TDynamicCounters::TCounterPtr& counter, const NMonitoring::TDynamicCounters::TCounterPtr& calculationTimeCounter) : SendInterval(sendInterval) diff --git a/library/cpp/actors/helpers/selfping_actor_ut.cpp b/library/cpp/actors/helpers/selfping_actor_ut.cpp index 9df99d1949..459635fa24 100644 --- a/library/cpp/actors/helpers/selfping_actor_ut.cpp +++ b/library/cpp/actors/helpers/selfping_actor_ut.cpp @@ -27,9 +27,9 @@ Y_UNIT_TEST_SUITE(TSelfPingTest) { TDuration::MilliSeconds(100), // sendInterval (unused in test) counter, counter2); - UNIT_ASSERT_VALUES_EQUAL(counter->Val(), 0); + UNIT_ASSERT_VALUES_EQUAL(counter->Val(), 0); UNIT_ASSERT_VALUES_EQUAL(counter2->Val(), 0); - + const TActorId actorId = runtime->Register(actor); Y_UNUSED(actorId); diff --git a/library/cpp/actors/interconnect/interconnect_handshake.cpp b/library/cpp/actors/interconnect/interconnect_handshake.cpp index ea09913bdd..9ede998d8e 100644 --- a/library/cpp/actors/interconnect/interconnect_handshake.cpp +++ b/library/cpp/actors/interconnect/interconnect_handshake.cpp @@ -98,10 +98,10 @@ namespace NActors { TInstant Deadline; public: - static constexpr IActor::EActivityType ActorActivityType() { - return IActor::INTERCONNECT_HANDSHAKE; - } - + static constexpr IActor::EActivityType ActorActivityType() { + return IActor::INTERCONNECT_HANDSHAKE; + } + THandshakeActor(TInterconnectProxyCommon::TPtr common, const TActorId& self, const TActorId& peer, ui32 nodeId, ui64 nextPacket, TString peerHostName, TSessionParams params) : TActorCoroImpl(StackSize, true, true) // allow unhandled poison pills and dtors diff --git a/library/cpp/actors/interconnect/interconnect_tcp_session.h b/library/cpp/actors/interconnect/interconnect_tcp_session.h index 846388edfc..7fc00dbcc5 100644 --- a/library/cpp/actors/interconnect/interconnect_tcp_session.h +++ b/library/cpp/actors/interconnect/interconnect_tcp_session.h @@ -518,10 +518,10 @@ namespace NActors { TInterconnectProxyCommon::TPtr Common; public: - static constexpr EActivityType ActorActivityType() { - return INTERCONNECT_SESSION_KILLER; - } - + static constexpr EActivityType ActorActivityType() { + return INTERCONNECT_SESSION_KILLER; + } + TInterconnectSessionKiller(TInterconnectProxyCommon::TPtr common) : Common(common) { diff --git a/library/cpp/actors/interconnect/load.cpp b/library/cpp/actors/interconnect/load.cpp index b40a01b3e8..2a8443da71 100644 --- a/library/cpp/actors/interconnect/load.cpp +++ b/library/cpp/actors/interconnect/load.cpp @@ -100,10 +100,10 @@ namespace NInterconnect { } public: - static constexpr IActor::EActivityType ActorActivityType() { + static constexpr IActor::EActivityType ActorActivityType() { return IActor::INTERCONNECT_LOAD_RESPONDER; - } - + } + TLoadResponderMasterActor() {} @@ -150,10 +150,10 @@ namespace NInterconnect { std::shared_ptr<std::atomic_uint64_t> Traffic; public: - static constexpr IActor::EActivityType ActorActivityType() { + static constexpr IActor::EActivityType ActorActivityType() { return IActor::INTERCONNECT_LOAD_ACTOR; - } - + } + TLoadActor(const TLoadParams& params) : Params(params) {} diff --git a/library/cpp/actors/interconnect/poller_actor.cpp b/library/cpp/actors/interconnect/poller_actor.cpp index 9bf3bd1d8d..e75cbcaef4 100644 --- a/library/cpp/actors/interconnect/poller_actor.cpp +++ b/library/cpp/actors/interconnect/poller_actor.cpp @@ -246,10 +246,10 @@ namespace NActors { std::shared_ptr<TPollerThread> PollerThread; public: - static constexpr IActor::EActivityType ActorActivityType() { - return IActor::INTERCONNECT_POLLER; - } - + static constexpr IActor::EActivityType ActorActivityType() { + return IActor::INTERCONNECT_POLLER; + } + void Bootstrap() { PollerThread = std::make_shared<TPollerThread>(TlsActivationContext->ExecutorThread.ActorSystem); Become(&TPollerActor::StateFunc); diff --git a/library/cpp/actors/interconnect/ut/lib/node.h b/library/cpp/actors/interconnect/ut/lib/node.h index 95666d3f7a..ff30b1445e 100644 --- a/library/cpp/actors/interconnect/ut/lib/node.h +++ b/library/cpp/actors/interconnect/ut/lib/node.h @@ -21,10 +21,10 @@ public: TChannelsConfig channelsSettings = TChannelsConfig(), ui32 numDynamicNodes = 0, ui32 numThreads = 1) { TActorSystemSetup setup; - setup.NodeId = nodeId; - setup.ExecutorsCount = 1; + setup.NodeId = nodeId; + setup.ExecutorsCount = 1; setup.Executors.Reset(new TAutoPtr<IExecutorPool>[setup.ExecutorsCount]); - for (ui32 i = 0; i < setup.ExecutorsCount; ++i) { + for (ui32 i = 0; i < setup.ExecutorsCount; ++i) { setup.Executors[i].Reset(new TBasicExecutorPool(i, numThreads, 20 /* magic number */)); } setup.Scheduler.Reset(new TBasicSchedulerThread()); diff --git a/library/cpp/actors/protos/unittests.proto b/library/cpp/actors/protos/unittests.proto index 64503bc1c1..a856b0942a 100644 --- a/library/cpp/actors/protos/unittests.proto +++ b/library/cpp/actors/protos/unittests.proto @@ -1,5 +1,5 @@ -option cc_enable_arenas = true; - +option cc_enable_arenas = true; + message TSimple { required string Str1 = 1; optional string Str2 = 2; @@ -16,5 +16,5 @@ message TBigMessage { message TMessageWithPayload { optional string Meta = 1; repeated uint32 PayloadId = 2; - repeated string SomeData = 3; + repeated string SomeData = 3; } diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp index fd61e4c720..6fa25b9965 100644 --- a/library/cpp/actors/testlib/test_runtime.cpp +++ b/library/cpp/actors/testlib/test_runtime.cpp @@ -19,7 +19,7 @@ #include <util/string/printf.h> #include <typeinfo> -bool VERBOSE = false; +bool VERBOSE = false; const bool PRINT_EVENT_BODY = false; namespace { @@ -86,8 +86,8 @@ namespace NActors { public: static constexpr EActivityType ActorActivityType() { return TEST_ACTOR_RUNTIME; - } - + } + TEdgeActor(TTestActorRuntimeBase* runtime) : TActor(&TEdgeActor::StateFunc) , Runtime(runtime) @@ -722,9 +722,9 @@ namespace NActors { } void TTestActorRuntimeBase::SetVerbose(bool verbose) { - VERBOSE = verbose; - } - + VERBOSE = verbose; + } + void TTestActorRuntimeBase::AddLocalService(const TActorId& actorId, const TActorSetupCmd& cmd, ui32 nodeIndex) { Y_VERIFY(!IsInitialized); Y_VERIFY(nodeIndex < NodeCount); @@ -1038,10 +1038,10 @@ namespace NActors { bool TTestActorRuntimeBase::DispatchEvents(const TDispatchOptions& options, TInstant simDeadline) { TGuard<TMutex> guard(Mutex); - return DispatchEventsInternal(options, simDeadline); - } - - // Mutex must be locked by caller! + return DispatchEventsInternal(options, simDeadline); + } + + // Mutex must be locked by caller! bool TTestActorRuntimeBase::DispatchEventsInternal(const TDispatchOptions& options, TInstant simDeadline) { TDispatchContext localContext; localContext.Options = &options; @@ -1253,9 +1253,9 @@ namespace NActors { if (!localContext.FoundNonEmptyMailboxes.empty()) return true; - if (options.CustomFinalCondition && options.CustomFinalCondition()) - return true; - + if (options.CustomFinalCondition && options.CustomFinalCondition()) + return true; + if (options.FinalEvents.empty()) { for (auto& mbox : currentMailboxes) { if (!mbox.second->IsActive(TInstant::MicroSeconds(CurrentTimestamp))) @@ -1755,8 +1755,8 @@ namespace NActors { public: static constexpr EActivityType ActorActivityType() { return TEST_ACTOR_RUNTIME; - } - + } + TReplyActor(TStrandingActorDecorator* owner) : TActor(&TReplyActor::StateFunc) , Owner(owner) @@ -1771,8 +1771,8 @@ namespace NActors { static constexpr EActivityType ActorActivityType() { return TEST_ACTOR_RUNTIME; - } - + } + TStrandingActorDecorator(const TActorId& delegatee, bool isSync, const TVector<TActorId>& additionalActors, TSimpleSharedPtr<TStrandingActorDecoratorContext> context, TTestActorRuntimeBase* runtime, TReplyCheckerCreator createReplyChecker) diff --git a/library/cpp/actors/testlib/test_runtime.h b/library/cpp/actors/testlib/test_runtime.h index 90de87b5ac..26e3b45c98 100644 --- a/library/cpp/actors/testlib/test_runtime.h +++ b/library/cpp/actors/testlib/test_runtime.h @@ -93,7 +93,7 @@ namespace NActors { TVector<TFinalEventCondition> FinalEvents; TVector<TEventMailboxId> NonEmptyMailboxes; TVector<TEventMailboxId> OnlyMailboxes; - std::function<bool()> CustomFinalCondition; + std::function<bool()> CustomFinalCondition; bool Quiet = false; }; @@ -219,8 +219,8 @@ namespace NActors { TEventFilter SetEventFilter(TEventFilter filterFunc); TScheduledEventFilter SetScheduledEventFilter(TScheduledEventFilter filterFunc); TRegistrationObserver SetRegistrationObserverFunc(TRegistrationObserver observerFunc); - static bool IsVerbose(); - static void SetVerbose(bool verbose); + static bool IsVerbose(); + static void SetVerbose(bool verbose); TDuration SetDispatchTimeout(TDuration timeout); void SetDispatchedEventsLimit(ui64 limit) { DispatchedEventsLimit = limit; @@ -499,7 +499,7 @@ namespace NActors { void ClearMailbox(ui32 nodeId, ui32 hint); void HandleNonEmptyMailboxesForEachContext(TEventMailboxId mboxId); void UpdateFinalEventsStatsForEachContext(IEventHandle& ev); - bool DispatchEventsInternal(const TDispatchOptions& options, TInstant simDeadline); + bool DispatchEventsInternal(const TDispatchOptions& options, TInstant simDeadline); private: ui64 ScheduledCount; diff --git a/library/cpp/execprofile/annotate_profile.pl b/library/cpp/execprofile/annotate_profile.pl index c6923c8e94..1a8c5d65a1 100644 --- a/library/cpp/execprofile/annotate_profile.pl +++ b/library/cpp/execprofile/annotate_profile.pl @@ -1,360 +1,360 @@ -#!/usr/bin/env perl - -# -# Takes profile file as an input and prints out annotated disassmebly -# Usage: -# ./annotate_profile.pl <binary_name> <profile_name> -# - - -# Function to draw bar of the specified length filled up to specified length -sub DRAW_BAR($$) { - my ($length, $filled) = @_; - my $bar = ""; - --$filled; - while ($filled > 0) { - $bar = $bar . "X"; - $length--; - $filled--; - } - while ($length > 0) { - $bar = $bar . " "; - $length--; - } - return $bar; -} - -my $curFunc = ""; -my $curModule = ""; -my $allHits = 0; -my %moduleHits; -my %funcModule; -my %funcHits; -my %funcHottestCount; -my %funcStart; -my %funcEnd; -my %funcNames; -my %funcBaseAddrs; -my %funcSizes; -my %addrHits; -my %addrFunc; -my %moduleBaseAddr; -my @funcSortByAddr; -my %demangledNames; -my %srcLineHits; -my %srcFileHits; - -# Demagles C++ function name -sub DEMANGLE($) { - my ($name) = @_; - if (exists $demangledNames{$name}) { - return $demangledNames{$name}; - } - if ($name =~ /^_Z/) { - my $cmd = "c++filt -p \'$name\' |"; - open(my $RES, $cmd ) || die "No c++filt"; - my $demangled_name = <$RES>; - chomp($demangled_name); - close $RES; - if (length($demangled_name) !=0) { - $name = $demangled_name; - } - } - return $name; -} - -# Saves function info -sub AddFunc($$$$$) -{ - my ($func, $bin_file, $baseAddr, $size, $name) = @_; - $funcModule{$func} = $bin_file; - $funcBaseAddrs{$func} = $baseAddr; - # A function with the same base address can be mentioned multiple times with different sizes (0, and non-0, WTF??) - if ((! exists $funcSizes{$func}) || ($funcSizes{$func} < $size)) { - $funcSizes{$func} = $size; - } - $funcNames{$func} = $name; - $funcStart{$func} = $func; -# printf "%08x\t%08x\t%016x\t%s\t%s\n", -# $funcBaseAddrs{$func}, $funcSizes{$func}, $moduleBaseAddr, $funcModule{$func}, $funcNames{$func}; -} - -# Reads list of all functions in a module -sub ReadFunctionList($$) { - my ($bin_file, $moduleBaseAddr) = @_; - if (! -e $bin_file) { - return; - } - my $readelf_cmd = "readelf -W -s $bin_file |"; -# print "$readelf_cmd\n"; - my $IN_FILE; - open($IN_FILE, $readelf_cmd) || die "couldn't open the file!"; - while (my $line = <$IN_FILE>) { - chomp($line); - # " 33: 00000000000a0fc0 433 FUNC GLOBAL DEFAULT 10 getipnodebyaddr@@FBSD_1.0" - if ($line =~ m/^\s*\d+:\s+([0-9a-fA-F]+)\s+(\d+)\s+FUNC\s+\w+\s+DEFAULT\s+\d+\s+(.*)$/) { - # Read function info - my $name = $3; - my $baseAddr = hex($1) + $moduleBaseAddr; - my $func = $baseAddr; - my $size = $2; - AddFunc($func, $bin_file, $baseAddr, $size, $name); - } - } - close($IN_FILE); - @funcSortByAddr = sort {$funcBaseAddrs{$a} <=> $funcBaseAddrs{$b} } keys %funcBaseAddrs; -# printf "%016x\t%s\t%d\n", $moduleBaseAddr, $bin_file, $#funcSortByAddr+1; -} - -# Reads the profile and attributes address hits to the functions -sub ReadSamples() { - # First pass saves all samples in a hash-table - my $samples_file = $ARGV[1]; - my $IN_FILE; - open($IN_FILE, $samples_file)|| die "couldn't open the file!"; - my $curFuncInd = 0; - my $curFunc = 0; - my $curFuncBegin = 0; - my $curFuncEnd = 0; - my $curModule = ""; - my $curModuleBase = 0; - my $read_samples = 0; - my $samplesStarted = 0; - while (my $line = <$IN_FILE>) { - chomp($line); - - if ($line =~ m/^samples:\s+(\d+)\s+unique:\s+(\d+)\s+dropped:\s+(\d+)\s+searchskips:\s+(\d+)$/) { - $total_samples = $1; - $unique_samples = $2; - $dropped_samples = $3; - $search_skips = $4; - next; - } - - if ($line =~ m/^Samples:$/) { - $samplesStarted = 1; - next; - } elsif (!$samplesStarted) { - print "$line\n"; - next; - } - -# print "$line\n"; - if ($line =~ m/^Func\t\d+/) { - # "Func 2073 0x803323000 0x803332fd0 /lib/libthr.so.3 pthread_cond_init" - my @cols = split(/\t/, $line); - $curModule = $cols[4]; - $curModuleBase = hex($cols[2]); - if (0x400000 == $curModuleBase) { - $curModuleBase = 0; - } - $curFunc = hex($cols[3]); - if (! exists $moduleBaseAddr{$curModule}) { - $moduleBaseAddr{$curModule} = $curModuleBase; - ReadFunctionList($curModule, $curModuleBase); - } - if (! exists $funcNames{$curFunc}) { - my $name = sprintf("unknown_0x%08x", $curFunc); - AddFunc($curFunc, $curModule, $curFunc, 0, $name); - } - } elsif ($line =~ m/^\d+\t0x([0-9,a-f,A-F]+)\t(\d+)/) { - # Read one sample for the current function - $read_samples++; - my $addr = hex($1); -# print "$addr\n"; - if ($addr >= $curFuncEnd) { - # Find the function the current address belongs to - while ($curFuncInd <= $#funcSortByAddr) { - my $f = $funcSortByAddr[$curFuncInd]; - my $begin = $funcBaseAddrs{$f}; - my $end = $funcBaseAddrs{$f} + $funcSizes{$f}; - if ($begin <= $addr and $addr < $end) { - $curFunc = $f; - $funcStart{$curFunc} = $addr; - $curFuncBegin = $begin; - $curFuncEnd = $end; - last; - } elsif ($addr < $begin) { -# printf "X3: func:%08x\tname:%s\tbase:%08x\tsize:%08x\t%s\nline:%s\n", -# $curFunc, $funcNames{$curFunc}, $funcBaseAddrs{$curFunc}, $funcSizes{$curFunc}, $curModule, $line; - last; - } - ++$curFuncInd; - } - } - - $funcHits{$curFunc} += $2; - if ($funcHottestCount{$curFunc} < $2) { - $funcHottestCount{$curFunc} = $2; - } - $addrHits{$addr} = $2; - $addrFunc{$addr} = $curFunc; - $funcEnd{$curFunc} = $addr; - $allHits += $2; - $moduleHits{$curModule} += $2; - -# printf "%08x\t%08x\t%08x\t%08x\t%s\n", $addr, $curFunc, $curFuncBegin, $curFuncEnd, $funcNames{$curFunc}; - } - } - close($IN_FILE); - - printf "\nsamples: %d unique: %d dropped: %d searchskips: %d\n", $total_samples, $unique_samples, $dropped_samples, $search_skips; - if ($read_samples != $unique_samples) { - printf "\n-----------------------------------------------------------------------------------------------------\n"; - printf "!!!!WARNING: read %d samples, expected %d samples, profiling results might be not acqurate!!!!", $read_samples, $unique_samples; - printf "\n-----------------------------------------------------------------------------------------------------\n"; - } -} - -# Dumps module stats -sub DumpModules() { - # Sort functions by hit counts and dump the list - my @modules = sort {$a <=> $b } keys %moduleHits; - for (my $i = 0; $i <= $#modules; ++$i) { - my $m = $modules[$i]; - my $cnt = $moduleHits{$m}; - my $perc = 100.0 * $cnt / $allHits; - printf "%12d\t%6.2f%% |%s %s\n", $cnt, $perc, DRAW_BAR(20, 20*$cnt/$allHits), $m; - } -} - -# Dumps top N hot functions -sub DumpHotFunc($) { - my ($maxCnt) = @_; - # Sort functions by hit counts and dump the list - my @hotFunc = sort {$funcHits{$b} <=> $funcHits{$a} } keys %funcHits; -# print $#hotFunc; - for (my $i = 0; $i <= $#hotFunc && $i < $maxCnt; ++$i) { - my $f = $hotFunc[$i]; - my $cnt = $funcHits{$f}; - my $perc = 100.0 * $cnt / $allHits; - printf "%12d\t%6.2f%% |%s %s\n", $cnt, $perc, DRAW_BAR(20, 20*$cnt/$allHits), DEMANGLE($funcNames{$f}); - } -} - -# Dumps top N hotspots (hot addresses) -sub DumpHotSpots($) { - my ($maxCnt) = @_; - # Sort addresses by hit counts and dump the list - my @hotSpots = sort {$addrHits{$b} <=> $addrHits{$a} } keys %addrHits; - for (my $i = 0; $i <= $#hotSpots && $i < $maxCnt; ++$i) { - my $s = $hotSpots[$i]; - my $cnt = $addrHits{$s}; - my $perc = 100.0 * $cnt / $allHits; - my $f = $addrFunc{$s}; - my $fname = $funcNames{$f}; - printf "%12d\t%6.2f%% |%s 0x%016x\t%s + 0x%x\n", - $cnt, $perc, DRAW_BAR(20, 20*$cnt/$allHits), $s, DEMANGLE($fname), $s - $funcBaseAddrs{$f}; - } -} - -# Adds hit informations to a disassembly line -sub ANNOTATE_DISASSM($$$$) { - my ($address, $disassm, $max_hit_count, $func_hit_count) = @_; - my $hit_count = $addrHits{$address}; - my $perc = sprintf("% 7.2f%%", 100*$hit_count/$func_hit_count); - $address = sprintf("% 8x", $address); - print $address . " " . $hit_count . "\t" . $perc . " |" . - DRAW_BAR(20, 20*$hit_count/$max_hit_count) . "\t" . $disassm . "\n"; -} - -# Dumps annotated disassembly of the specified function (actually not the whole function but -# just the addresses between the first and last hit) -sub DumpDisasm($) { - my ($name) = @_; - if (exists $funcStart{$name} && exists $funcEnd{$name} && $funcStart{$name}!=0) { - my $module = $funcModule{$name}; - my $modBase = $moduleBaseAddr{$module}; - my $start_address = $funcStart{$name} - $modBase; - my $stop_address = $funcEnd{$name} - $modBase + 1; -# print " " . $funcStart{$name} . " " . $funcEnd{$name} . " $modBase ---"; - my $max_hit_count = $funcHits{$name}; - my $objdump_cmd = "objdump -C -d -l --start-address=" . $start_address . - " --stop-address=" . $stop_address . " " . $module . " |"; - if ($stop_address - $start_address < 10000000) { # don't try to disaassemble more than 10MB, because most likely it's a bug -# print STDERR $objdump_cmd . "\n"; - open(my $OBJDUMP, $objdump_cmd) || die "No objdump"; - my $srcLine = "func# ". $name; - my $srcFile = $module; - while (my $objdump_line = <$OBJDUMP>) { - # filter disassembly lines - if ($objdump_line =~ /^Disassembly of section/) { - } elsif ($objdump_line =~ m/^\s*([0-9,a-f,A-F]+):\s*(.*)/) { - my $addr = hex($1); - my $hit_count = $addrHits{$addr}; - if ($hit_count > 0) { - $srcLineHits{$srcLine} += $hit_count; - $srcFileHits{$srcFile} += $hit_count; - } - ANNOTATE_DISASSM($addr + $modBase, $2, $funcHottestCount{$name}, $max_hit_count); - } elsif ($objdump_line =~ m/^(\/.*):(\d+)$/) { - $srcLine = $objdump_line; - $srcFile = $1; - chomp($srcLine); - print $objdump_line; - } else { - print $objdump_line; - } - } - close $OBJDUMP; - } - } -} - -# Dumps disassemlby for top N hot functions -sub DumpFuncDissasm($) { - (my $maxCnt) = @_; - my @funcs = sort {$funcHits{$b} <=> $funcHits{$a} } keys %funcHits; - print $#funcs . "\n"; - for (my $i = 0; $i <= $#funcs && $i < $maxCnt; ++$i) { - my $f = $funcs[$i]; - print "\n--------------------------------------------------------------------------------------------------------------\n"; - printf "hits:%d\t%7.2f%%\tbase:%08x\tstart:%08x\tend:%08x\t%s\n", - $funcHits{$f}, 100*$funcHits{$f}/$allHits, $funcBaseAddrs{$f}, $funcStart{$f}, $funcEnd{$f}, DEMANGLE($funcNames{$f}); - print "--------------------------------------------------------------------------------------------------------------\n"; - DumpDisasm($f); - } -} - -sub DumpSrcFiles($) { - (my $maxCnt) = @_; - my @srcFiles = sort {$srcFileHits{$b} <=> $srcFileHits{$a} } keys %srcFileHits; - for (my $i = 0; $i <= $#srcFiles && $i < $maxCnt; ++$i) { - my $f = $srcFiles[$i]; - my $cnt = $srcFileHits{$f}; - printf "%12d\t%6.2f%% |%s %s\n", $cnt, 100*$cnt/$allHits, DRAW_BAR(20, 20*$cnt/$allHits), $f; - } -} - -sub DumpSrcLines($) { - (my $maxCnt) = @_; - my @srcLines = sort {$srcLineHits{$b} <=> $srcLineHits{$a} } keys %srcLineHits; - for (my $i = 0; $i <= $#srcLines && $i < $maxCnt; ++$i) { - my $l = $srcLines[$i]; - my $cnt = $srcLineHits{$l}; - printf "%12d\t%6.2f%% |%s %s\n", $cnt, 100*$cnt/$allHits, DRAW_BAR(20, 20*$cnt/$allHits), $l; - } -} - -ReadFunctionList($ARGV[0], 0); -ReadSamples(); -print "\nModules:\n"; -DumpModules(); -print "\nHot functions:\n"; -DumpHotFunc(100); -print "\nHotspots:\n"; -DumpHotSpots(100); -DumpFuncDissasm(100); -print "\nHot src files:\n"; -DumpSrcFiles(100); -print "\nHot src lines:\n"; -DumpSrcLines(100); - -# my @funcs = sort {$funcBaseAddrs{$a} <=> $funcBaseAddrs{$b} } keys %funcHits; -# printf "%d\n", $#funcs; -# for (my $i = 0; $i <= $#funcs; ++$i) { -# my $f = $funcs[$i]; -# printf "%s\t%d\tbase:%08x\tstart:%08x\tend:%08x\t%s\n", -# $funcNames{$f}, $funcHits{$f}, $funcBaseAddrs{$f}, $funcStart{$f}, $funcEnd{$f}, $funcModule{$f}; -# #DumpDisasm($f); -# } +#!/usr/bin/env perl + +# +# Takes profile file as an input and prints out annotated disassmebly +# Usage: +# ./annotate_profile.pl <binary_name> <profile_name> +# + + +# Function to draw bar of the specified length filled up to specified length +sub DRAW_BAR($$) { + my ($length, $filled) = @_; + my $bar = ""; + --$filled; + while ($filled > 0) { + $bar = $bar . "X"; + $length--; + $filled--; + } + while ($length > 0) { + $bar = $bar . " "; + $length--; + } + return $bar; +} + +my $curFunc = ""; +my $curModule = ""; +my $allHits = 0; +my %moduleHits; +my %funcModule; +my %funcHits; +my %funcHottestCount; +my %funcStart; +my %funcEnd; +my %funcNames; +my %funcBaseAddrs; +my %funcSizes; +my %addrHits; +my %addrFunc; +my %moduleBaseAddr; +my @funcSortByAddr; +my %demangledNames; +my %srcLineHits; +my %srcFileHits; + +# Demagles C++ function name +sub DEMANGLE($) { + my ($name) = @_; + if (exists $demangledNames{$name}) { + return $demangledNames{$name}; + } + if ($name =~ /^_Z/) { + my $cmd = "c++filt -p \'$name\' |"; + open(my $RES, $cmd ) || die "No c++filt"; + my $demangled_name = <$RES>; + chomp($demangled_name); + close $RES; + if (length($demangled_name) !=0) { + $name = $demangled_name; + } + } + return $name; +} + +# Saves function info +sub AddFunc($$$$$) +{ + my ($func, $bin_file, $baseAddr, $size, $name) = @_; + $funcModule{$func} = $bin_file; + $funcBaseAddrs{$func} = $baseAddr; + # A function with the same base address can be mentioned multiple times with different sizes (0, and non-0, WTF??) + if ((! exists $funcSizes{$func}) || ($funcSizes{$func} < $size)) { + $funcSizes{$func} = $size; + } + $funcNames{$func} = $name; + $funcStart{$func} = $func; +# printf "%08x\t%08x\t%016x\t%s\t%s\n", +# $funcBaseAddrs{$func}, $funcSizes{$func}, $moduleBaseAddr, $funcModule{$func}, $funcNames{$func}; +} + +# Reads list of all functions in a module +sub ReadFunctionList($$) { + my ($bin_file, $moduleBaseAddr) = @_; + if (! -e $bin_file) { + return; + } + my $readelf_cmd = "readelf -W -s $bin_file |"; +# print "$readelf_cmd\n"; + my $IN_FILE; + open($IN_FILE, $readelf_cmd) || die "couldn't open the file!"; + while (my $line = <$IN_FILE>) { + chomp($line); + # " 33: 00000000000a0fc0 433 FUNC GLOBAL DEFAULT 10 getipnodebyaddr@@FBSD_1.0" + if ($line =~ m/^\s*\d+:\s+([0-9a-fA-F]+)\s+(\d+)\s+FUNC\s+\w+\s+DEFAULT\s+\d+\s+(.*)$/) { + # Read function info + my $name = $3; + my $baseAddr = hex($1) + $moduleBaseAddr; + my $func = $baseAddr; + my $size = $2; + AddFunc($func, $bin_file, $baseAddr, $size, $name); + } + } + close($IN_FILE); + @funcSortByAddr = sort {$funcBaseAddrs{$a} <=> $funcBaseAddrs{$b} } keys %funcBaseAddrs; +# printf "%016x\t%s\t%d\n", $moduleBaseAddr, $bin_file, $#funcSortByAddr+1; +} + +# Reads the profile and attributes address hits to the functions +sub ReadSamples() { + # First pass saves all samples in a hash-table + my $samples_file = $ARGV[1]; + my $IN_FILE; + open($IN_FILE, $samples_file)|| die "couldn't open the file!"; + my $curFuncInd = 0; + my $curFunc = 0; + my $curFuncBegin = 0; + my $curFuncEnd = 0; + my $curModule = ""; + my $curModuleBase = 0; + my $read_samples = 0; + my $samplesStarted = 0; + while (my $line = <$IN_FILE>) { + chomp($line); + + if ($line =~ m/^samples:\s+(\d+)\s+unique:\s+(\d+)\s+dropped:\s+(\d+)\s+searchskips:\s+(\d+)$/) { + $total_samples = $1; + $unique_samples = $2; + $dropped_samples = $3; + $search_skips = $4; + next; + } + + if ($line =~ m/^Samples:$/) { + $samplesStarted = 1; + next; + } elsif (!$samplesStarted) { + print "$line\n"; + next; + } + +# print "$line\n"; + if ($line =~ m/^Func\t\d+/) { + # "Func 2073 0x803323000 0x803332fd0 /lib/libthr.so.3 pthread_cond_init" + my @cols = split(/\t/, $line); + $curModule = $cols[4]; + $curModuleBase = hex($cols[2]); + if (0x400000 == $curModuleBase) { + $curModuleBase = 0; + } + $curFunc = hex($cols[3]); + if (! exists $moduleBaseAddr{$curModule}) { + $moduleBaseAddr{$curModule} = $curModuleBase; + ReadFunctionList($curModule, $curModuleBase); + } + if (! exists $funcNames{$curFunc}) { + my $name = sprintf("unknown_0x%08x", $curFunc); + AddFunc($curFunc, $curModule, $curFunc, 0, $name); + } + } elsif ($line =~ m/^\d+\t0x([0-9,a-f,A-F]+)\t(\d+)/) { + # Read one sample for the current function + $read_samples++; + my $addr = hex($1); +# print "$addr\n"; + if ($addr >= $curFuncEnd) { + # Find the function the current address belongs to + while ($curFuncInd <= $#funcSortByAddr) { + my $f = $funcSortByAddr[$curFuncInd]; + my $begin = $funcBaseAddrs{$f}; + my $end = $funcBaseAddrs{$f} + $funcSizes{$f}; + if ($begin <= $addr and $addr < $end) { + $curFunc = $f; + $funcStart{$curFunc} = $addr; + $curFuncBegin = $begin; + $curFuncEnd = $end; + last; + } elsif ($addr < $begin) { +# printf "X3: func:%08x\tname:%s\tbase:%08x\tsize:%08x\t%s\nline:%s\n", +# $curFunc, $funcNames{$curFunc}, $funcBaseAddrs{$curFunc}, $funcSizes{$curFunc}, $curModule, $line; + last; + } + ++$curFuncInd; + } + } + + $funcHits{$curFunc} += $2; + if ($funcHottestCount{$curFunc} < $2) { + $funcHottestCount{$curFunc} = $2; + } + $addrHits{$addr} = $2; + $addrFunc{$addr} = $curFunc; + $funcEnd{$curFunc} = $addr; + $allHits += $2; + $moduleHits{$curModule} += $2; + +# printf "%08x\t%08x\t%08x\t%08x\t%s\n", $addr, $curFunc, $curFuncBegin, $curFuncEnd, $funcNames{$curFunc}; + } + } + close($IN_FILE); + + printf "\nsamples: %d unique: %d dropped: %d searchskips: %d\n", $total_samples, $unique_samples, $dropped_samples, $search_skips; + if ($read_samples != $unique_samples) { + printf "\n-----------------------------------------------------------------------------------------------------\n"; + printf "!!!!WARNING: read %d samples, expected %d samples, profiling results might be not acqurate!!!!", $read_samples, $unique_samples; + printf "\n-----------------------------------------------------------------------------------------------------\n"; + } +} + +# Dumps module stats +sub DumpModules() { + # Sort functions by hit counts and dump the list + my @modules = sort {$a <=> $b } keys %moduleHits; + for (my $i = 0; $i <= $#modules; ++$i) { + my $m = $modules[$i]; + my $cnt = $moduleHits{$m}; + my $perc = 100.0 * $cnt / $allHits; + printf "%12d\t%6.2f%% |%s %s\n", $cnt, $perc, DRAW_BAR(20, 20*$cnt/$allHits), $m; + } +} + +# Dumps top N hot functions +sub DumpHotFunc($) { + my ($maxCnt) = @_; + # Sort functions by hit counts and dump the list + my @hotFunc = sort {$funcHits{$b} <=> $funcHits{$a} } keys %funcHits; +# print $#hotFunc; + for (my $i = 0; $i <= $#hotFunc && $i < $maxCnt; ++$i) { + my $f = $hotFunc[$i]; + my $cnt = $funcHits{$f}; + my $perc = 100.0 * $cnt / $allHits; + printf "%12d\t%6.2f%% |%s %s\n", $cnt, $perc, DRAW_BAR(20, 20*$cnt/$allHits), DEMANGLE($funcNames{$f}); + } +} + +# Dumps top N hotspots (hot addresses) +sub DumpHotSpots($) { + my ($maxCnt) = @_; + # Sort addresses by hit counts and dump the list + my @hotSpots = sort {$addrHits{$b} <=> $addrHits{$a} } keys %addrHits; + for (my $i = 0; $i <= $#hotSpots && $i < $maxCnt; ++$i) { + my $s = $hotSpots[$i]; + my $cnt = $addrHits{$s}; + my $perc = 100.0 * $cnt / $allHits; + my $f = $addrFunc{$s}; + my $fname = $funcNames{$f}; + printf "%12d\t%6.2f%% |%s 0x%016x\t%s + 0x%x\n", + $cnt, $perc, DRAW_BAR(20, 20*$cnt/$allHits), $s, DEMANGLE($fname), $s - $funcBaseAddrs{$f}; + } +} + +# Adds hit informations to a disassembly line +sub ANNOTATE_DISASSM($$$$) { + my ($address, $disassm, $max_hit_count, $func_hit_count) = @_; + my $hit_count = $addrHits{$address}; + my $perc = sprintf("% 7.2f%%", 100*$hit_count/$func_hit_count); + $address = sprintf("% 8x", $address); + print $address . " " . $hit_count . "\t" . $perc . " |" . + DRAW_BAR(20, 20*$hit_count/$max_hit_count) . "\t" . $disassm . "\n"; +} + +# Dumps annotated disassembly of the specified function (actually not the whole function but +# just the addresses between the first and last hit) +sub DumpDisasm($) { + my ($name) = @_; + if (exists $funcStart{$name} && exists $funcEnd{$name} && $funcStart{$name}!=0) { + my $module = $funcModule{$name}; + my $modBase = $moduleBaseAddr{$module}; + my $start_address = $funcStart{$name} - $modBase; + my $stop_address = $funcEnd{$name} - $modBase + 1; +# print " " . $funcStart{$name} . " " . $funcEnd{$name} . " $modBase ---"; + my $max_hit_count = $funcHits{$name}; + my $objdump_cmd = "objdump -C -d -l --start-address=" . $start_address . + " --stop-address=" . $stop_address . " " . $module . " |"; + if ($stop_address - $start_address < 10000000) { # don't try to disaassemble more than 10MB, because most likely it's a bug +# print STDERR $objdump_cmd . "\n"; + open(my $OBJDUMP, $objdump_cmd) || die "No objdump"; + my $srcLine = "func# ". $name; + my $srcFile = $module; + while (my $objdump_line = <$OBJDUMP>) { + # filter disassembly lines + if ($objdump_line =~ /^Disassembly of section/) { + } elsif ($objdump_line =~ m/^\s*([0-9,a-f,A-F]+):\s*(.*)/) { + my $addr = hex($1); + my $hit_count = $addrHits{$addr}; + if ($hit_count > 0) { + $srcLineHits{$srcLine} += $hit_count; + $srcFileHits{$srcFile} += $hit_count; + } + ANNOTATE_DISASSM($addr + $modBase, $2, $funcHottestCount{$name}, $max_hit_count); + } elsif ($objdump_line =~ m/^(\/.*):(\d+)$/) { + $srcLine = $objdump_line; + $srcFile = $1; + chomp($srcLine); + print $objdump_line; + } else { + print $objdump_line; + } + } + close $OBJDUMP; + } + } +} + +# Dumps disassemlby for top N hot functions +sub DumpFuncDissasm($) { + (my $maxCnt) = @_; + my @funcs = sort {$funcHits{$b} <=> $funcHits{$a} } keys %funcHits; + print $#funcs . "\n"; + for (my $i = 0; $i <= $#funcs && $i < $maxCnt; ++$i) { + my $f = $funcs[$i]; + print "\n--------------------------------------------------------------------------------------------------------------\n"; + printf "hits:%d\t%7.2f%%\tbase:%08x\tstart:%08x\tend:%08x\t%s\n", + $funcHits{$f}, 100*$funcHits{$f}/$allHits, $funcBaseAddrs{$f}, $funcStart{$f}, $funcEnd{$f}, DEMANGLE($funcNames{$f}); + print "--------------------------------------------------------------------------------------------------------------\n"; + DumpDisasm($f); + } +} + +sub DumpSrcFiles($) { + (my $maxCnt) = @_; + my @srcFiles = sort {$srcFileHits{$b} <=> $srcFileHits{$a} } keys %srcFileHits; + for (my $i = 0; $i <= $#srcFiles && $i < $maxCnt; ++$i) { + my $f = $srcFiles[$i]; + my $cnt = $srcFileHits{$f}; + printf "%12d\t%6.2f%% |%s %s\n", $cnt, 100*$cnt/$allHits, DRAW_BAR(20, 20*$cnt/$allHits), $f; + } +} + +sub DumpSrcLines($) { + (my $maxCnt) = @_; + my @srcLines = sort {$srcLineHits{$b} <=> $srcLineHits{$a} } keys %srcLineHits; + for (my $i = 0; $i <= $#srcLines && $i < $maxCnt; ++$i) { + my $l = $srcLines[$i]; + my $cnt = $srcLineHits{$l}; + printf "%12d\t%6.2f%% |%s %s\n", $cnt, 100*$cnt/$allHits, DRAW_BAR(20, 20*$cnt/$allHits), $l; + } +} + +ReadFunctionList($ARGV[0], 0); +ReadSamples(); +print "\nModules:\n"; +DumpModules(); +print "\nHot functions:\n"; +DumpHotFunc(100); +print "\nHotspots:\n"; +DumpHotSpots(100); +DumpFuncDissasm(100); +print "\nHot src files:\n"; +DumpSrcFiles(100); +print "\nHot src lines:\n"; +DumpSrcLines(100); + +# my @funcs = sort {$funcBaseAddrs{$a} <=> $funcBaseAddrs{$b} } keys %funcHits; +# printf "%d\n", $#funcs; +# for (my $i = 0; $i <= $#funcs; ++$i) { +# my $f = $funcs[$i]; +# printf "%s\t%d\tbase:%08x\tstart:%08x\tend:%08x\t%s\n", +# $funcNames{$f}, $funcHits{$f}, $funcBaseAddrs{$f}, $funcStart{$f}, $funcEnd{$f}, $funcModule{$f}; +# #DumpDisasm($f); +# } diff --git a/library/cpp/execprofile/profile.cpp b/library/cpp/execprofile/profile.cpp index 19003a9a51..d05de20203 100644 --- a/library/cpp/execprofile/profile.cpp +++ b/library/cpp/execprofile/profile.cpp @@ -1,190 +1,190 @@ #include <util/system/defaults.h> -#include "profile.h" - +#include "profile.h" + #if defined(_unix_) && !defined(_bionic_) && !defined(_cygwin_) - -#include <signal.h> -#include <sys/time.h> -#include <sys/resource.h> + +#include <signal.h> +#include <sys/time.h> +#include <sys/resource.h> #if defined(_darwin_) #include <sys/ucontext.h> #else -#include <ucontext.h> +#include <ucontext.h> #endif #include <dlfcn.h> -#include <util/system/platform.h> +#include <util/system/platform.h> #include <util/generic/hash.h> #include <util/generic/map.h> #include <util/generic/noncopyable.h> #include <util/generic/algorithm.h> #include <util/generic/vector.h> -#include <util/stream/file.h> -#include <util/string/util.h> -#include <util/system/datetime.h> - -// This class sets SIGPROF handler and captures instruction pointer in it. +#include <util/stream/file.h> +#include <util/string/util.h> +#include <util/system/datetime.h> + +// This class sets SIGPROF handler and captures instruction pointer in it. class TExecutionSampler : TNonCopyable { -public: +public: typedef TVector<std::pair<void*, size_t>> TSampleVector; - - struct TStats { - ui64 SavedSamples; - ui64 DroppedSamples; - ui64 SearchSkipCount; - }; - - // NOTE: There is no synchronization here as the instance is supposed to be - // created on the main thread. + + struct TStats { + ui64 SavedSamples; + ui64 DroppedSamples; + ui64 SearchSkipCount; + }; + + // NOTE: There is no synchronization here as the instance is supposed to be + // created on the main thread. static TExecutionSampler* Instance() { if (SInstance == nullptr) { - SInstance = new TExecutionSampler(); - } - - return SInstance; - } - + SInstance = new TExecutionSampler(); + } + + return SInstance; + } + void Start() { - // Set signal handler - struct sigaction sa; - sa.sa_sigaction = ProfilerSignalHandler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO; - if (sigaction(SIGPROF, &sa, &OldSignalHandler) != 0) - return; - - // Set interval timer - itimerval tv; - tv.it_interval.tv_sec = tv.it_value.tv_sec = 0; - tv.it_interval.tv_usec = tv.it_value.tv_usec = SAMPLE_INTERVAL; - setitimer(ITIMER_PROF, &tv, &OldTimerValue); - - Started = true; - } - + // Set signal handler + struct sigaction sa; + sa.sa_sigaction = ProfilerSignalHandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGPROF, &sa, &OldSignalHandler) != 0) + return; + + // Set interval timer + itimerval tv; + tv.it_interval.tv_sec = tv.it_value.tv_sec = 0; + tv.it_interval.tv_usec = tv.it_value.tv_usec = SAMPLE_INTERVAL; + setitimer(ITIMER_PROF, &tv, &OldTimerValue); + + Started = true; + } + void Stop(TSampleVector& sampleVector, TStats& stats) { - // Reset signal handler and timer - if (Started) { + // Reset signal handler and timer + if (Started) { setitimer(ITIMER_PROF, &OldTimerValue, nullptr); - sleep(1); - } - - WaitForWriteFlag(); - - if (Started) { + sleep(1); + } + + WaitForWriteFlag(); + + if (Started) { sigaction(SIGPROF, &OldSignalHandler, nullptr); - Started = false; - } - - TExecutionSampler::TSampleVector hits; - hits.reserve(Samples); - for (size_t i = 0; i < SZ; ++i) { + Started = false; + } + + TExecutionSampler::TSampleVector hits; + hits.reserve(Samples); + for (size_t i = 0; i < SZ; ++i) { if (Ips[i].first != nullptr) { - hits.push_back(Ips[i]); - } - } - stats.SavedSamples = Samples; - stats.DroppedSamples = AtomicGet(DroppedSamples); - stats.SearchSkipCount = SearchSkipCount; - AtomicUnlock(&WriteFlag); - + hits.push_back(Ips[i]); + } + } + stats.SavedSamples = Samples; + stats.DroppedSamples = AtomicGet(DroppedSamples); + stats.SearchSkipCount = SearchSkipCount; + AtomicUnlock(&WriteFlag); + Sort(hits.begin(), hits.end(), TCompareFirst()); - - sampleVector.swap(hits); - } - + + sampleVector.swap(hits); + } + void ResetStats() { - WaitForWriteFlag(); - Clear(); - AtomicUnlock(&WriteFlag); - } - -private: + WaitForWriteFlag(); + Clear(); + AtomicUnlock(&WriteFlag); + } + +private: static const size_t SZ = 2 * 1024 * 1024; // size of the hash table // inserts work faster if it's a power of 2 static const int SAMPLE_INTERVAL = 1000; // in microseconds - - struct TCompareFirst { + + struct TCompareFirst { bool operator()(const std::pair<void*, size_t>& a, const std::pair<void*, size_t>& b) const { - return a.first < b.first; - } - }; - - TExecutionSampler() - : Started(false) - , Ips(SZ) - , WriteFlag(0) - , DroppedSamples(0) - , Samples(0) - , UniqueSamples(0) - , SearchSkipCount(0) - { - } - + return a.first < b.first; + } + }; + + TExecutionSampler() + : Started(false) + , Ips(SZ) + , WriteFlag(0) + , DroppedSamples(0) + , Samples(0) + , UniqueSamples(0) + , SearchSkipCount(0) + { + } + ~TExecutionSampler() = default; - - // Signal handler is not allowed to do anything that can deadlock with activity - // on the thread to which the signal is delivered or corrupt data structures that - // were in process of update. - // One such thing is memory allocation. That's why a fixed size vector is - // preallocated at start. + + // Signal handler is not allowed to do anything that can deadlock with activity + // on the thread to which the signal is delivered or corrupt data structures that + // were in process of update. + // One such thing is memory allocation. That's why a fixed size vector is + // preallocated at start. static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { - (void)info; - if (signal != SIGPROF) { - return; - } - - ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); + (void)info; + if (signal != SIGPROF) { + return; + } + + ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); Y_ASSERT(SInstance != nullptr); - - SInstance->CaptureIP(GetIp(&ucontext->uc_mcontext)); - } - + + SInstance->CaptureIP(GetIp(&ucontext->uc_mcontext)); + } + void WaitForWriteFlag() { - // Wait for write flag to be reset - ui32 delay = 100; - while (!AtomicTryLock(&WriteFlag)) { - usleep(delay); - delay += delay; + // Wait for write flag to be reset + ui32 delay = 100; + while (!AtomicTryLock(&WriteFlag)) { + usleep(delay); + delay += delay; delay = Min(delay, (ui32)5000); - } - } - + } + } + void CaptureIP(void* rip) { - // Check if the handler on another thread is in the process of adding a sample - // If this is the case, we just drop the current sample as this should happen - // rarely. - if (AtomicTryLock(&WriteFlag)) { - AddSample(rip); - AtomicUnlock(&WriteFlag); - } else { + // Check if the handler on another thread is in the process of adding a sample + // If this is the case, we just drop the current sample as this should happen + // rarely. + if (AtomicTryLock(&WriteFlag)) { + AddSample(rip); + AtomicUnlock(&WriteFlag); + } else { AtomicIncrement(DroppedSamples); - } - } - - // Hash function applied to the addresses + } + } + + // Hash function applied to the addresses static inline ui32 Hash(void* key) { - return ((size_t)key + (size_t)key / SZ) % SZ; - } - - // Get instruction pointer from the context + return ((size_t)key + (size_t)key / SZ) % SZ; + } + + // Get instruction pointer from the context static inline void* GetIp(const mcontext_t* mctx) { -#if defined _freebsd_ +#if defined _freebsd_ #if defined _64_ - return (void*)mctx->mc_rip; + return (void*)mctx->mc_rip; #else - return (void*)mctx->mc_eip; + return (void*)mctx->mc_eip; #endif -#elif defined _linux_ +#elif defined _linux_ #if defined _64_ #if defined(_arm_) return (void*)mctx->pc; #else - return (void*)mctx->gregs[REG_RIP]; + return (void*)mctx->gregs[REG_RIP]; #endif #else - return (void*)mctx->gregs[REG_EIP]; + return (void*)mctx->gregs[REG_EIP]; #endif #elif defined _darwin_ #if defined _64_ @@ -199,67 +199,67 @@ private: #else return (void*)(*mctx)->__ss.__eip; #endif -#endif #endif - } - +#endif + } + inline bool AddSample(void* key) { - ui32 slot = Hash(key); - ui32 prevSlot = (slot - 1) % SZ; - - while (key != Ips[slot].first && !IsSlotEmpty(slot) && slot != prevSlot) { - slot = (slot + 1) % SZ; - SearchSkipCount++; - } - - if (key == Ips[slot].first) { - // increment the count - Ips[slot].second++; - ++Samples; - } else if (InsertsAllowed()) { - // add new sample and set the count to 1 - Ips[slot].first = key; - Ips[slot].second = 1; - ++UniqueSamples; - ++Samples; - } else { - // don't insert new sample if the search is becoming too slow + ui32 slot = Hash(key); + ui32 prevSlot = (slot - 1) % SZ; + + while (key != Ips[slot].first && !IsSlotEmpty(slot) && slot != prevSlot) { + slot = (slot + 1) % SZ; + SearchSkipCount++; + } + + if (key == Ips[slot].first) { + // increment the count + Ips[slot].second++; + ++Samples; + } else if (InsertsAllowed()) { + // add new sample and set the count to 1 + Ips[slot].first = key; + Ips[slot].second = 1; + ++UniqueSamples; + ++Samples; + } else { + // don't insert new sample if the search is becoming too slow AtomicIncrement(DroppedSamples); - return false; - } - - return true; - } - + return false; + } + + return true; + } + inline bool IsSlotEmpty(ui32 slot) const { return Ips[slot].first == nullptr; - } - + } + inline bool InsertsAllowed() const { - return UniqueSamples < SZ / 2; - } - - void + return UniqueSamples < SZ / 2; + } + + void Clear() { Y_ASSERT(WriteFlag == 1); - - for (size_t i = 0; i < SZ; ++i) { + + for (size_t i = 0; i < SZ; ++i) { Ips[i] = std::make_pair((void*)nullptr, (size_t)0); - } - Samples = 0; - AtomicSet(DroppedSamples, 0); - UniqueSamples = 0; - SearchSkipCount = 0; - } - + } + Samples = 0; + AtomicSet(DroppedSamples, 0); + UniqueSamples = 0; + SearchSkipCount = 0; + } + bool Started; struct sigaction OldSignalHandler; itimerval OldTimerValue; - + TVector<std::pair<void*, size_t>> Ips; // The hash table storing addresses and their hitcounts - - // TODO: on a big multiproc cache line false sharing by the flag and count might become an issue + + // TODO: on a big multiproc cache line false sharing by the flag and count might become an issue TAtomic WriteFlag; // Is used to syncronize access to the hash table TAtomic DroppedSamples; // "dropped sample" count will show how many times // a sample was dropped either because of write conflict @@ -267,87 +267,87 @@ private: ui64 Samples; // Saved samples count ui64 UniqueSamples; // Number of unique addresses ui64 SearchSkipCount; // Total number of linear hash table probes due to collisions - - static TExecutionSampler* SInstance; -}; - -// Performs analysis of samples captured by TExecutionSampler -class TSampleAnalyser : TNonCopyable { -public: - TSampleAnalyser(TExecutionSampler::TSampleVector& samples, const TExecutionSampler::TStats& stats, bool putTimeStamps = false) - : Samples() - , Stats(stats) - , PutTimestamps(putTimeStamps) - { - Samples.swap(samples); - } - + + static TExecutionSampler* SInstance; +}; + +// Performs analysis of samples captured by TExecutionSampler +class TSampleAnalyser : TNonCopyable { +public: + TSampleAnalyser(TExecutionSampler::TSampleVector& samples, const TExecutionSampler::TStats& stats, bool putTimeStamps = false) + : Samples() + , Stats(stats) + , PutTimestamps(putTimeStamps) + { + Samples.swap(samples); + } + ~TSampleAnalyser() = default; - - void Analyze(FILE* out) const; - -private: - TExecutionSampler::TSampleVector Samples; + + void Analyze(FILE* out) const; + +private: + TExecutionSampler::TSampleVector Samples; TExecutionSampler::TStats Stats; - bool PutTimestamps; -}; - + bool PutTimestamps; +}; + void TSampleAnalyser::Analyze(FILE* out) const { fprintf(out, "samples: %" PRIu64 " unique: %" PRIu64 " dropped: %" PRIu64 " searchskips: %" PRIu64 "\n", (ui64)Stats.SavedSamples, (ui64)Samples.size(), (ui64)Stats.DroppedSamples, (ui64)Stats.SearchSkipCount); - - fprintf(out, "\nSamples:\n"); - size_t funcCnt = 0; - void* prevModBase = (void*)-1; - void* prevFunc = (void*)-1; - for (size_t i = 0; i < Samples.size(); ++i) { - // print cycle count once in a while to estimate time consumed by - // dumping the samples - if (PutTimestamps && (i % 1000 == 0)) { - ui64 tm = GetCycleCount(); + + fprintf(out, "\nSamples:\n"); + size_t funcCnt = 0; + void* prevModBase = (void*)-1; + void* prevFunc = (void*)-1; + for (size_t i = 0; i < Samples.size(); ++i) { + // print cycle count once in a while to estimate time consumed by + // dumping the samples + if (PutTimestamps && (i % 1000 == 0)) { + ui64 tm = GetCycleCount(); fprintf(out, "TM: %" PRIu64 "\n", tm); - } - - Dl_info addrInfo; - if (dladdr(Samples[i].first, &addrInfo)) { - if (addrInfo.dli_fbase != prevModBase || addrInfo.dli_saddr != prevFunc) { + } + + Dl_info addrInfo; + if (dladdr(Samples[i].first, &addrInfo)) { + if (addrInfo.dli_fbase != prevModBase || addrInfo.dli_saddr != prevFunc) { fprintf(out, "Func\t%" PRISZT "\t%p\t%p\t%s\t%s\n", funcCnt, addrInfo.dli_fbase, addrInfo.dli_saddr, addrInfo.dli_fname, addrInfo.dli_sname); - prevModBase = addrInfo.dli_fbase; - prevFunc = addrInfo.dli_saddr; - ++funcCnt; - } - } else { - fprintf(out, "[dladdr failed]\n"); - } + prevModBase = addrInfo.dli_fbase; + prevFunc = addrInfo.dli_saddr; + ++funcCnt; + } + } else { + fprintf(out, "[dladdr failed]\n"); + } fprintf(out, "%" PRISZT "\t%p\t%lu\n", i, Samples[i].first, Samples[i].second); - } -} - + } +} + TExecutionSampler* TExecutionSampler::SInstance = nullptr; - -// Starts capturing execution samples -void BeginProfiling() { - TExecutionSampler::Instance()->Start(); -} - -// Resets captured execution samples -void ResetProfile() { - TExecutionSampler::Instance()->ResetStats(); -} - -void DumpRUsage(FILE* out) { - rusage ru; - int e = getrusage(RUSAGE_SELF, &ru); - if (e != 0) - return; - - fprintf(out, + +// Starts capturing execution samples +void BeginProfiling() { + TExecutionSampler::Instance()->Start(); +} + +// Resets captured execution samples +void ResetProfile() { + TExecutionSampler::Instance()->ResetStats(); +} + +void DumpRUsage(FILE* out) { + rusage ru; + int e = getrusage(RUSAGE_SELF, &ru); + if (e != 0) + return; + + fprintf(out, "user time: %lf\n" "system time: %lf\n" "max RSS: %ld\n" @@ -372,46 +372,46 @@ void DumpRUsage(FILE* out) { ru.ru_msgsnd, ru.ru_msgrcv, ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw); -} - -// Pauses capturing execution samples and dumps them to the file -// Samples are not cleared so that profiling can be continued by calling BeginProfiling() -// or it can be started from scratch by calling ResetProfile() and then BeginProfiling() -void EndProfiling(FILE* out) { - DumpRUsage(out); - - TExecutionSampler::TSampleVector samples; - TExecutionSampler::TStats stats; - TExecutionSampler::Instance()->Stop(samples, stats); - - TSampleAnalyser analyzer(samples, stats); - analyzer.Analyze(out); -} - -void EndProfiling() { - static unsigned cnt = 0; - char nameBuf[256]; - snprintf(nameBuf, sizeof(nameBuf), "./%s.%d.%u.profile", getprogname(), (int)getpid(), cnt); - FILE* out = fopen(nameBuf, "a"); - EndProfiling(out); - fclose(out); - ++cnt; -} - +} + +// Pauses capturing execution samples and dumps them to the file +// Samples are not cleared so that profiling can be continued by calling BeginProfiling() +// or it can be started from scratch by calling ResetProfile() and then BeginProfiling() +void EndProfiling(FILE* out) { + DumpRUsage(out); + + TExecutionSampler::TSampleVector samples; + TExecutionSampler::TStats stats; + TExecutionSampler::Instance()->Stop(samples, stats); + + TSampleAnalyser analyzer(samples, stats); + analyzer.Analyze(out); +} + +void EndProfiling() { + static unsigned cnt = 0; + char nameBuf[256]; + snprintf(nameBuf, sizeof(nameBuf), "./%s.%d.%u.profile", getprogname(), (int)getpid(), cnt); + FILE* out = fopen(nameBuf, "a"); + EndProfiling(out); + fclose(out); + ++cnt; +} + #else - -// NOTE: not supported on Windows - -void BeginProfiling() { -} - -void ResetProfile() { -} - + +// NOTE: not supported on Windows + +void BeginProfiling() { +} + +void ResetProfile() { +} + void EndProfiling(FILE*) { -} - -void EndProfiling() { -} - +} + +void EndProfiling() { +} + #endif diff --git a/library/cpp/execprofile/profile.h b/library/cpp/execprofile/profile.h index bd90aad3aa..ccb8866656 100644 --- a/library/cpp/execprofile/profile.h +++ b/library/cpp/execprofile/profile.h @@ -1,17 +1,17 @@ #pragma once - -#include <stdio.h> - -// Starts capturing execution samples -void BeginProfiling(); - -// Resets captured execution samples -void ResetProfile(); - -// Pauses capturing execution samples and dumps them to the file -// Samples are not cleared so that profiling can be continued by calling BeginProfiling() -// or it can be started from scratch by calling ResetProfile() and then BeginProfiling() -void EndProfiling(FILE* out); - -// Dumps the profile to default file (basename.pid.N.profile) -void EndProfiling(); + +#include <stdio.h> + +// Starts capturing execution samples +void BeginProfiling(); + +// Resets captured execution samples +void ResetProfile(); + +// Pauses capturing execution samples and dumps them to the file +// Samples are not cleared so that profiling can be continued by calling BeginProfiling() +// or it can be started from scratch by calling ResetProfile() and then BeginProfiling() +void EndProfiling(FILE* out); + +// Dumps the profile to default file (basename.pid.N.profile) +void EndProfiling(); diff --git a/library/cpp/execprofile/ya.make b/library/cpp/execprofile/ya.make index ef002f1552..9d202ac4eb 100644 --- a/library/cpp/execprofile/ya.make +++ b/library/cpp/execprofile/ya.make @@ -1,9 +1,9 @@ OWNER(g:cpp-contrib) LIBRARY() - + SRCS( - profile.cpp -) - -END() + profile.cpp +) + +END() diff --git a/library/cpp/grpc/server/grpc_request.h b/library/cpp/grpc/server/grpc_request.h index d034f8e2b7..5bd8d3902b 100644 --- a/library/cpp/grpc/server/grpc_request.h +++ b/library/cpp/grpc/server/grpc_request.h @@ -59,8 +59,8 @@ public: TRequestCallback requestCallback, const char* name, TLoggerPtr logger, - ICounterBlockPtr counters, - IGRpcRequestLimiterPtr limiter) + ICounterBlockPtr counters, + IGRpcRequestLimiterPtr limiter) : TBaseAsyncContext<TService>(service, cq) , Server_(server) , Cb_(cb) @@ -69,7 +69,7 @@ public: , Name_(name) , Logger_(std::move(logger)) , Counters_(std::move(counters)) - , RequestLimiter_(std::move(limiter)) + , RequestLimiter_(std::move(limiter)) , Writer_(new grpc::ServerAsyncResponseWriter<TUniversalResponseRef<TOut>>(&this->Context)) , StateFunc_(&TThis::SetRequestDone) { @@ -87,8 +87,8 @@ public: TStreamRequestCallback requestCallback, const char* name, TLoggerPtr logger, - ICounterBlockPtr counters, - IGRpcRequestLimiterPtr limiter) + ICounterBlockPtr counters, + IGRpcRequestLimiterPtr limiter) : TBaseAsyncContext<TService>(service, cq) , Server_(server) , Cb_(cb) @@ -97,7 +97,7 @@ public: , Name_(name) , Logger_(std::move(logger)) , Counters_(std::move(counters)) - , RequestLimiter_(std::move(limiter)) + , RequestLimiter_(std::move(limiter)) , StreamWriter_(new grpc::ServerAsyncWriter<TUniversalResponse<TOut>>(&this->Context)) , StateFunc_(&TThis::SetRequestDone) { @@ -363,7 +363,7 @@ private: return false; } - if (IncRequest()) { + if (IncRequest()) { // Adjust counters. RequestSize = Request_->ByteSize(); Counters_->StartProcessing(RequestSize); @@ -405,7 +405,7 @@ private: if (!ok) { logCb(-1); - DecRequest(); + DecRequest(); Counters_->FinishProcessing(RequestSize, ResponseSize, ok, ResponseStatus, TDuration::Seconds(RequestTimer.Passed())); return false; @@ -426,7 +426,7 @@ private: GRPC_LOG_DEBUG(Logger_, "[%p] finished request Name# %s ok# %s peer# %s", this, Name_, ok ? "true" : "false", this->Context.peer().c_str()); //PrintBackTrace(); - DecRequest(); + DecRequest(); Counters_->FinishProcessing(RequestSize, ResponseSize, ok, ResponseStatus, TDuration::Seconds(RequestTimer.Passed())); return false; @@ -436,7 +436,7 @@ private: GRPC_LOG_DEBUG(Logger_, "[%p] finished request with error Name# %s ok# %s peer# %s", this, Name_, ok ? "true" : "false", this->Context.peer().c_str()); if (!SkipUpdateCountersOnError) { - DecRequest(); + DecRequest(); Counters_->FinishProcessing(RequestSize, ResponseSize, ok, ResponseStatus, TDuration::Seconds(RequestTimer.Passed())); } @@ -457,28 +457,28 @@ private: } } - bool IncRequest() { - if (!Server_->IncRequest()) - return false; - - if (!RequestLimiter_) - return true; - - if (!RequestLimiter_->IncRequest()) { - Server_->DecRequest(); - return false; - } - - return true; - } - - void DecRequest() { - if (RequestLimiter_) { - RequestLimiter_->DecRequest(); - } - Server_->DecRequest(); - } - + bool IncRequest() { + if (!Server_->IncRequest()) + return false; + + if (!RequestLimiter_) + return true; + + if (!RequestLimiter_->IncRequest()) { + Server_->DecRequest(); + return false; + } + + return true; + } + + void DecRequest() { + if (RequestLimiter_) { + RequestLimiter_->DecRequest(); + } + Server_->DecRequest(); + } + using TStateFunc = bool (TThis::*)(bool); TService* Server_; TOnRequest Cb_; @@ -487,7 +487,7 @@ private: const char* const Name_; TLoggerPtr Logger_; ICounterBlockPtr Counters_; - IGRpcRequestLimiterPtr RequestLimiter_; + IGRpcRequestLimiterPtr RequestLimiter_; THolder<grpc::ServerAsyncResponseWriter<TUniversalResponseRef<TOut>>> Writer_; THolder<grpc::ServerAsyncWriterInterface<TUniversalResponse<TOut>>> StreamWriter_; @@ -521,8 +521,8 @@ public: typename TBase::TRequestCallback requestCallback, const char* name, TLoggerPtr logger, - ICounterBlockPtr counters, - IGRpcRequestLimiterPtr limiter = nullptr) + ICounterBlockPtr counters, + IGRpcRequestLimiterPtr limiter = nullptr) : TBase{server, service, cq, std::move(cb), std::move(requestCallback), name, std::move(logger), std::move(counters), std::move(limiter)} { } diff --git a/library/cpp/grpc/server/grpc_request_base.h b/library/cpp/grpc/server/grpc_request_base.h index 2be84158c7..fcfce1c181 100644 --- a/library/cpp/grpc/server/grpc_request_base.h +++ b/library/cpp/grpc/server/grpc_request_base.h @@ -28,16 +28,16 @@ struct TAuthState { EAuthState State; }; - -//! An interface that may be used to limit concurrency of requests + +//! An interface that may be used to limit concurrency of requests class IGRpcRequestLimiter: public TThrRefBase { -public: - virtual bool IncRequest() = 0; - virtual void DecRequest() = 0; -}; - -using IGRpcRequestLimiterPtr = TIntrusivePtr<IGRpcRequestLimiter>; - +public: + virtual bool IncRequest() = 0; + virtual void DecRequest() = 0; +}; + +using IGRpcRequestLimiterPtr = TIntrusivePtr<IGRpcRequestLimiter>; + //! State of current request class IRequestContextBase: public TThrRefBase { public: diff --git a/library/cpp/grpc/server/grpc_server.h b/library/cpp/grpc/server/grpc_server.h index 4ce67a1b68..d6814a90a0 100644 --- a/library/cpp/grpc/server/grpc_server.h +++ b/library/cpp/grpc/server/grpc_server.h @@ -1,8 +1,8 @@ #pragma once -#include "grpc_request_base.h" +#include "grpc_request_base.h" #include "logger.h" - + #include <library/cpp/threading/future/future.h> #include <util/generic/ptr.h> @@ -123,10 +123,10 @@ public: virtual ~ICancelableContext() = default; }; -template <class TLimit> -class TInFlightLimiterImpl { +template <class TLimit> +class TInFlightLimiterImpl { public: - explicit TInFlightLimiterImpl(const TLimit& limit) + explicit TInFlightLimiterImpl(const TLimit& limit) : Limit_(limit) {} @@ -154,13 +154,13 @@ public: } private: - const TLimit Limit_; + const TLimit Limit_; TAtomic CurInFlightReqs_ = 0; }; -using TGlobalLimiter = TInFlightLimiterImpl<i64>; - - +using TGlobalLimiter = TInFlightLimiterImpl<i64>; + + class IGRpcService: public TThrRefBase { public: virtual grpc::Service* GetService() = 0; diff --git a/library/cpp/lfalloc/alloc_profiler/profiler.cpp b/library/cpp/lfalloc/alloc_profiler/profiler.cpp index beb0ffb289..0e30927a5a 100644 --- a/library/cpp/lfalloc/alloc_profiler/profiler.cpp +++ b/library/cpp/lfalloc/alloc_profiler/profiler.cpp @@ -8,7 +8,7 @@ #include <util/generic/vector.h> #include <util/stream/str.h> -namespace NAllocProfiler { +namespace NAllocProfiler { namespace { @@ -50,32 +50,32 @@ void DeallocationCallback(int stackId, int tag, size_t size, int sizeIdx) //////////////////////////////////////////////////////////////////////////////// -bool StartAllocationSampling(bool profileAllThreads) +bool StartAllocationSampling(bool profileAllThreads) { auto& collector = AllocationStackCollector(); collector.Clear(); - NAllocDbg::SetProfileAllThreads(profileAllThreads); + NAllocDbg::SetProfileAllThreads(profileAllThreads); NAllocDbg::SetAllocationCallback(AllocationCallback); NAllocDbg::SetDeallocationCallback(DeallocationCallback); NAllocDbg::SetAllocationSamplingEnabled(true); return true; } -bool StopAllocationSampling(IAllocationStatsDumper &out, int count) +bool StopAllocationSampling(IAllocationStatsDumper &out, int count) { NAllocDbg::SetAllocationCallback(nullptr); NAllocDbg::SetDeallocationCallback(nullptr); NAllocDbg::SetAllocationSamplingEnabled(false); auto& collector = AllocationStackCollector(); - collector.Dump(count, out); + collector.Dump(count, out); return true; } -bool StopAllocationSampling(IOutputStream& out, int count) { - TAllocationStatsDumper dumper(out); - return StopAllocationSampling(dumper, count); +bool StopAllocationSampling(IOutputStream& out, int count) { + TAllocationStatsDumper dumper(out); + return StopAllocationSampling(dumper, count); } } // namespace NProfiler diff --git a/library/cpp/lfalloc/alloc_profiler/profiler.h b/library/cpp/lfalloc/alloc_profiler/profiler.h index 592849b460..4ea49b9dcc 100644 --- a/library/cpp/lfalloc/alloc_profiler/profiler.h +++ b/library/cpp/lfalloc/alloc_profiler/profiler.h @@ -1,13 +1,13 @@ #pragma once -#include "stackcollect.h" +#include "stackcollect.h" #include <library/cpp/lfalloc/dbg_info/dbg_info.h> #include <util/generic/noncopyable.h> #include <util/stream/output.h> -namespace NAllocProfiler { +namespace NAllocProfiler { //////////////////////////////////////////////////////////////////////////////// @@ -21,9 +21,9 @@ 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); +bool StartAllocationSampling(bool profileAllThreads = false); +bool StopAllocationSampling(IAllocationStatsDumper& out, int count = 100); +bool StopAllocationSampling(IOutputStream& out, int count = 100); //////////////////////////////////////////////////////////////////////////////// @@ -42,4 +42,4 @@ public: } }; -} // namespace NAllocProfiler +} // namespace NAllocProfiler diff --git a/library/cpp/lfalloc/alloc_profiler/profiler_ut.cpp b/library/cpp/lfalloc/alloc_profiler/profiler_ut.cpp index 21b667e730..4341dda6ed 100644 --- a/library/cpp/lfalloc/alloc_profiler/profiler_ut.cpp +++ b/library/cpp/lfalloc/alloc_profiler/profiler_ut.cpp @@ -1,76 +1,76 @@ -#include "profiler.h" - +#include "profiler.h" + #include <library/cpp/testing/unittest/registar.h> - -namespace NAllocProfiler { - -//////////////////////////////////////////////////////////////////////////////// - -Y_UNIT_TEST_SUITE(Profiler) { - Y_UNIT_TEST(StackCollection) - { - TStringStream str; - - NAllocProfiler::StartAllocationSampling(true); - TVector<TAutoPtr<int>> test; - // Do many allocations and no deallocations - for (int i = 0; i < 10000; ++i) { - test.push_back(new int); - } - NAllocProfiler::StopAllocationSampling(str); - //Cout << str.Str() << Endl; - -#if !defined(ARCH_AARCH64) - /* Check that output resembles this: - - STACK #2: 0 Allocs: 10 Frees: 0 CurrentSize: 40 - 0000000000492353 ?? - 000000000048781F operator new(unsigned long) +1807 - 00000000003733FA NAllocProfiler::NTestSuiteProfiler::TTestCaseStackCollection::Execute_(NUnitTest::TTestContext&) +218 - 00000000004A1938 NUnitTest::TTestBase::Run(std::__y1::function<void ()>, TString, char const*, bool) +120 - 0000000000375656 NAllocProfiler::NTestSuiteProfiler::TCurrentTest::Execute() +342 - 00000000004A20CF NUnitTest::TTestFactory::Execute() +847 - 000000000049922D NUnitTest::RunMain(int, char**) +1965 - 00007FF665778F45 __libc_start_main +245 - */ - - UNIT_ASSERT_STRING_CONTAINS(str.Str(), "StackCollection"); - UNIT_ASSERT_STRING_CONTAINS(str.Str(), "NUnitTest::TTestBase::Run"); - UNIT_ASSERT_STRING_CONTAINS(str.Str(), "NAllocProfiler::NTestSuiteProfiler::TCurrentTest::Execute"); - UNIT_ASSERT_STRING_CONTAINS(str.Str(), "NUnitTest::TTestFactory::Execute"); - UNIT_ASSERT_STRING_CONTAINS(str.Str(), "NUnitTest::RunMain"); -#endif - } - - class TAllocDumper : public NAllocProfiler::TAllocationStatsDumper { - public: - explicit TAllocDumper(IOutputStream& out) : NAllocProfiler::TAllocationStatsDumper(out) {} - - TString FormatTag(int tag) override { - UNIT_ASSERT_VALUES_EQUAL(tag, 42); - return "TAG_NAME_42"; - } - }; - - Y_UNIT_TEST(TagNames) - { - TStringStream str; - - NAllocProfiler::StartAllocationSampling(true); - TVector<TAutoPtr<int>> test; - NAllocProfiler::TProfilingScope scope(42); - // Do many allocations and no deallocations - for (int i = 0; i < 10000; ++i) { - test.push_back(new int); - } - - TAllocDumper dumper(str); - NAllocProfiler::StopAllocationSampling(dumper); - -#if !defined(ARCH_AARCH64) - UNIT_ASSERT_STRING_CONTAINS(str.Str(), "TAG_NAME_42"); -#endif - } -} - -} + +namespace NAllocProfiler { + +//////////////////////////////////////////////////////////////////////////////// + +Y_UNIT_TEST_SUITE(Profiler) { + Y_UNIT_TEST(StackCollection) + { + TStringStream str; + + NAllocProfiler::StartAllocationSampling(true); + TVector<TAutoPtr<int>> test; + // Do many allocations and no deallocations + for (int i = 0; i < 10000; ++i) { + test.push_back(new int); + } + NAllocProfiler::StopAllocationSampling(str); + //Cout << str.Str() << Endl; + +#if !defined(ARCH_AARCH64) + /* Check that output resembles this: + + STACK #2: 0 Allocs: 10 Frees: 0 CurrentSize: 40 + 0000000000492353 ?? + 000000000048781F operator new(unsigned long) +1807 + 00000000003733FA NAllocProfiler::NTestSuiteProfiler::TTestCaseStackCollection::Execute_(NUnitTest::TTestContext&) +218 + 00000000004A1938 NUnitTest::TTestBase::Run(std::__y1::function<void ()>, TString, char const*, bool) +120 + 0000000000375656 NAllocProfiler::NTestSuiteProfiler::TCurrentTest::Execute() +342 + 00000000004A20CF NUnitTest::TTestFactory::Execute() +847 + 000000000049922D NUnitTest::RunMain(int, char**) +1965 + 00007FF665778F45 __libc_start_main +245 + */ + + UNIT_ASSERT_STRING_CONTAINS(str.Str(), "StackCollection"); + UNIT_ASSERT_STRING_CONTAINS(str.Str(), "NUnitTest::TTestBase::Run"); + UNIT_ASSERT_STRING_CONTAINS(str.Str(), "NAllocProfiler::NTestSuiteProfiler::TCurrentTest::Execute"); + UNIT_ASSERT_STRING_CONTAINS(str.Str(), "NUnitTest::TTestFactory::Execute"); + UNIT_ASSERT_STRING_CONTAINS(str.Str(), "NUnitTest::RunMain"); +#endif + } + + class TAllocDumper : public NAllocProfiler::TAllocationStatsDumper { + public: + explicit TAllocDumper(IOutputStream& out) : NAllocProfiler::TAllocationStatsDumper(out) {} + + TString FormatTag(int tag) override { + UNIT_ASSERT_VALUES_EQUAL(tag, 42); + return "TAG_NAME_42"; + } + }; + + Y_UNIT_TEST(TagNames) + { + TStringStream str; + + NAllocProfiler::StartAllocationSampling(true); + TVector<TAutoPtr<int>> test; + NAllocProfiler::TProfilingScope scope(42); + // Do many allocations and no deallocations + for (int i = 0; i < 10000; ++i) { + test.push_back(new int); + } + + TAllocDumper dumper(str); + NAllocProfiler::StopAllocationSampling(dumper); + +#if !defined(ARCH_AARCH64) + UNIT_ASSERT_STRING_CONTAINS(str.Str(), "TAG_NAME_42"); +#endif + } +} + +} diff --git a/library/cpp/lfalloc/alloc_profiler/stackcollect.cpp b/library/cpp/lfalloc/alloc_profiler/stackcollect.cpp index d608803e84..fded4e2fd1 100644 --- a/library/cpp/lfalloc/alloc_profiler/stackcollect.cpp +++ b/library/cpp/lfalloc/alloc_profiler/stackcollect.cpp @@ -5,16 +5,16 @@ #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/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> -namespace NAllocProfiler { - +namespace NAllocProfiler { + //////////////////////////////////////////////////////////////////////////////// template <typename T> @@ -87,11 +87,11 @@ public: return Y_ARRAY_SIZE(Frames); } - void BackTrace(const TFrameInfo* stack, TStackVec<void*, 64>& frames) const + void BackTrace(const TFrameInfo* stack, TStackVec<void*, 64>& frames) const { - frames.clear(); + frames.clear(); for (size_t i = 0; i < 100; ++i) { - frames.push_back(stack->Addr); + frames.push_back(stack->Addr); int prevInd = stack->PrevInd; if (prevInd == -1) { break; @@ -174,11 +174,11 @@ private: //////////////////////////////////////////////////////////////////////////////// -class TAllocationStackCollector::TImpl: public TStackCollector<TStats> { - using TBase = TStackCollector<TStats>; +class TAllocationStackCollector::TImpl: public TStackCollector<TStats> { + using TBase = TStackCollector<TStats>; private: - TStats Total; + TStats Total; public: int Alloc(void** stack, size_t frameCount, int tag, size_t size) @@ -203,7 +203,7 @@ public: Total.Clear(); } - void Dump(int count, IAllocationStatsDumper& out) const + void Dump(int count, IAllocationStatsDumper& out) const { const TFrameInfo* frames = TBase::GetFrames(); size_t framesCount = TBase::GetFramesCount(); @@ -225,18 +225,18 @@ public: : ls.Frees > rs.Frees; }); - out.DumpTotal(Total); + out.DumpTotal(Total); - TAllocationInfo allocInfo; + TAllocationInfo allocInfo; int printedCount = 0; for (const TFrameInfo* stack: stacks) { - allocInfo.Clear(); - allocInfo.Tag = stack->Tag; - allocInfo.Stats = stack->Stats; - TBase::BackTrace(stack, allocInfo.Stack); + allocInfo.Clear(); + allocInfo.Tag = stack->Tag; + allocInfo.Stats = stack->Stats; + TBase::BackTrace(stack, allocInfo.Stack); + + out.DumpEntry(allocInfo); - out.DumpEntry(allocInfo); - if (++printedCount >= count) { break; } @@ -268,65 +268,65 @@ void TAllocationStackCollector::Clear() Impl->Clear(); } -void TAllocationStackCollector::Dump(int count, IAllocationStatsDumper &out) const +void TAllocationStackCollector::Dump(int count, IAllocationStatsDumper &out) const { Impl->Dump(count, out); } - -TString IAllocationStatsDumper::FormatTag(int tag) { - return ToString(tag); -} - -TString IAllocationStatsDumper::FormatSize(intptr_t sz) { - return ToString(sz); -} - - -TAllocationStatsDumper::TAllocationStatsDumper(IOutputStream& out) - : PrintedCount(0) - , Out(out) - , SymbolCache(2048) -{} - -void TAllocationStatsDumper::DumpTotal(const TStats& total) { - Out << "TOTAL" - << "\tAllocs: " << total.Allocs - << "\tFrees: " << total.Frees - << "\tCurrentSize: " << FormatSize(total.CurrentSize) - << Endl; -} - -void TAllocationStatsDumper::DumpEntry(const TAllocationInfo& allocInfo) { - Out << Endl - << "STACK #" << PrintedCount+1 << ": " << FormatTag(allocInfo.Tag) - << "\tAllocs: " << allocInfo.Stats.Allocs - << "\tFrees: " << allocInfo.Stats.Frees - << "\tCurrentSize: " << FormatSize(allocInfo.Stats.CurrentSize) - << Endl; - FormatBackTrace(allocInfo.Stack.data(), allocInfo.Stack.size()); - PrintedCount++; -} - -void TAllocationStatsDumper::FormatBackTrace(void* const* stack, size_t sz) { - char name[1024]; - for (size_t i = 0; i < sz; ++i) { - TSymbol symbol; - auto it = SymbolCache.Find(stack[i]); - if (it != SymbolCache.End()) { - symbol = it.Value(); - } else { - TResolvedSymbol rs = ResolveSymbol(stack[i], name, sizeof(name)); - symbol = {rs.NearestSymbol, rs.Name}; - SymbolCache.Insert(stack[i], symbol); - } - - Out << Hex((intptr_t)stack[i], HF_FULL) << "\t" << symbol.Name; - intptr_t offset = (intptr_t)stack[i] - (intptr_t)symbol.Address; - if (offset) - Out << " +" << offset; - Out << Endl; - } -} - -} // namespace NAllocProfiler + +TString IAllocationStatsDumper::FormatTag(int tag) { + return ToString(tag); +} + +TString IAllocationStatsDumper::FormatSize(intptr_t sz) { + return ToString(sz); +} + + +TAllocationStatsDumper::TAllocationStatsDumper(IOutputStream& out) + : PrintedCount(0) + , Out(out) + , SymbolCache(2048) +{} + +void TAllocationStatsDumper::DumpTotal(const TStats& total) { + Out << "TOTAL" + << "\tAllocs: " << total.Allocs + << "\tFrees: " << total.Frees + << "\tCurrentSize: " << FormatSize(total.CurrentSize) + << Endl; +} + +void TAllocationStatsDumper::DumpEntry(const TAllocationInfo& allocInfo) { + Out << Endl + << "STACK #" << PrintedCount+1 << ": " << FormatTag(allocInfo.Tag) + << "\tAllocs: " << allocInfo.Stats.Allocs + << "\tFrees: " << allocInfo.Stats.Frees + << "\tCurrentSize: " << FormatSize(allocInfo.Stats.CurrentSize) + << Endl; + FormatBackTrace(allocInfo.Stack.data(), allocInfo.Stack.size()); + PrintedCount++; +} + +void TAllocationStatsDumper::FormatBackTrace(void* const* stack, size_t sz) { + char name[1024]; + for (size_t i = 0; i < sz; ++i) { + TSymbol symbol; + auto it = SymbolCache.Find(stack[i]); + if (it != SymbolCache.End()) { + symbol = it.Value(); + } else { + TResolvedSymbol rs = ResolveSymbol(stack[i], name, sizeof(name)); + symbol = {rs.NearestSymbol, rs.Name}; + SymbolCache.Insert(stack[i], symbol); + } + + Out << Hex((intptr_t)stack[i], HF_FULL) << "\t" << symbol.Name; + intptr_t offset = (intptr_t)stack[i] - (intptr_t)symbol.Address; + if (offset) + Out << " +" << offset; + Out << Endl; + } +} + +} // namespace NAllocProfiler diff --git a/library/cpp/lfalloc/alloc_profiler/stackcollect.h b/library/cpp/lfalloc/alloc_profiler/stackcollect.h index 7c10cd2ffd..80715ed7cb 100644 --- a/library/cpp/lfalloc/alloc_profiler/stackcollect.h +++ b/library/cpp/lfalloc/alloc_profiler/stackcollect.h @@ -2,89 +2,89 @@ #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/stream/output.h> -namespace NAllocProfiler { - -struct TStats { - intptr_t Allocs = 0; - intptr_t Frees = 0; - intptr_t CurrentSize = 0; - - void Clear() - { - Allocs = 0; - Frees = 0; - CurrentSize = 0; - } - - void Alloc(size_t size) - { - AtomicIncrement(Allocs); - AtomicAdd(CurrentSize, size); - } - - void Free(size_t size) - { - AtomicIncrement(Frees); - AtomicSub(CurrentSize, size); - } -}; - -struct TAllocationInfo { - int Tag; - TStats Stats; - TStackVec<void*, 64> Stack; - - void Clear() { - Tag = 0; - Stats.Clear(); - Stack.clear(); - } -}; - - -class IAllocationStatsDumper { -public: - virtual ~IAllocationStatsDumper() = default; - - // Total stats - virtual void DumpTotal(const TStats& total) = 0; - - // Stats for individual stack - virtual void DumpEntry(const TAllocationInfo& allocInfo) = 0; - - // App-specific tag printer - virtual TString FormatTag(int tag); - - // Size printer (e.g. "10KB", "100MB", "over 9000") - virtual TString FormatSize(intptr_t sz); -}; - -// Default implementation -class TAllocationStatsDumper: public IAllocationStatsDumper { -public: - explicit TAllocationStatsDumper(IOutputStream& out); - void DumpTotal(const TStats& total) override; - void DumpEntry(const TAllocationInfo& allocInfo) override; - -private: - void FormatBackTrace(void* const* stack, size_t sz); - -private: - struct TSymbol { - const void* Address; - TString Name; - }; - - size_t PrintedCount; - IOutputStream& Out; - TLFUCache<void*, TSymbol> SymbolCache; -}; - +namespace NAllocProfiler { + +struct TStats { + intptr_t Allocs = 0; + intptr_t Frees = 0; + intptr_t CurrentSize = 0; + + void Clear() + { + Allocs = 0; + Frees = 0; + CurrentSize = 0; + } + + void Alloc(size_t size) + { + AtomicIncrement(Allocs); + AtomicAdd(CurrentSize, size); + } + + void Free(size_t size) + { + AtomicIncrement(Frees); + AtomicSub(CurrentSize, size); + } +}; + +struct TAllocationInfo { + int Tag; + TStats Stats; + TStackVec<void*, 64> Stack; + + void Clear() { + Tag = 0; + Stats.Clear(); + Stack.clear(); + } +}; + + +class IAllocationStatsDumper { +public: + virtual ~IAllocationStatsDumper() = default; + + // Total stats + virtual void DumpTotal(const TStats& total) = 0; + + // Stats for individual stack + virtual void DumpEntry(const TAllocationInfo& allocInfo) = 0; + + // App-specific tag printer + virtual TString FormatTag(int tag); + + // Size printer (e.g. "10KB", "100MB", "over 9000") + virtual TString FormatSize(intptr_t sz); +}; + +// Default implementation +class TAllocationStatsDumper: public IAllocationStatsDumper { +public: + explicit TAllocationStatsDumper(IOutputStream& out); + void DumpTotal(const TStats& total) override; + void DumpEntry(const TAllocationInfo& allocInfo) override; + +private: + void FormatBackTrace(void* const* stack, size_t sz); + +private: + struct TSymbol { + const void* Address; + TString Name; + }; + + size_t PrintedCount; + IOutputStream& Out; + TLFUCache<void*, TSymbol> SymbolCache; +}; + //////////////////////////////////////////////////////////////////////////////// class TAllocationStackCollector: private TNonCopyable { @@ -101,7 +101,7 @@ public: void Clear(); - void Dump(int count, IAllocationStatsDumper& out) const; + void Dump(int count, IAllocationStatsDumper& out) const; }; -} // namespace NAllocProfiler +} // namespace NAllocProfiler diff --git a/library/cpp/lfalloc/alloc_profiler/ut/ya.make b/library/cpp/lfalloc/alloc_profiler/ut/ya.make index c90a1278d5..8a7daa74af 100644 --- a/library/cpp/lfalloc/alloc_profiler/ut/ya.make +++ b/library/cpp/lfalloc/alloc_profiler/ut/ya.make @@ -1,22 +1,22 @@ UNITTEST_FOR(library/cpp/lfalloc/alloc_profiler) - -OWNER(g:rtmr g:kikimr) - -PEERDIR( + +OWNER(g:rtmr g:kikimr) + +PEERDIR( library/cpp/testing/unittest -) - -IF (ARCH_AARCH64) - PEERDIR( - contrib/libs/jemalloc - ) -ELSE() - ALLOCATOR(LF_DBG) -ENDIF() - -SRCS( - profiler_ut.cpp +) + +IF (ARCH_AARCH64) + PEERDIR( + contrib/libs/jemalloc + ) +ELSE() + ALLOCATOR(LF_DBG) +ENDIF() + +SRCS( + profiler_ut.cpp align_ut.cpp -) - -END() +) + +END() diff --git a/library/cpp/lfalloc/alloc_profiler/ya.make b/library/cpp/lfalloc/alloc_profiler/ya.make index dd1bfb0918..0f58d91767 100644 --- a/library/cpp/lfalloc/alloc_profiler/ya.make +++ b/library/cpp/lfalloc/alloc_profiler/ya.make @@ -1,17 +1,17 @@ -LIBRARY() - -OWNER(g:rtmr g:kikimr) - -SRCS( - profiler.cpp - stackcollect.cpp -) - -PEERDIR( +LIBRARY() + +OWNER(g:rtmr g:kikimr) + +SRCS( + profiler.cpp + stackcollect.cpp +) + +PEERDIR( library/cpp/lfalloc/dbg_info library/cpp/cache -) - -END() - -RECURSE(ut) +) + +END() + +RECURSE(ut) diff --git a/library/cpp/lfalloc/dbg_info/dbg_info.cpp b/library/cpp/lfalloc/dbg_info/dbg_info.cpp index 7667e444a2..1fb9f7ad93 100644 --- a/library/cpp/lfalloc/dbg_info/dbg_info.cpp +++ b/library/cpp/lfalloc/dbg_info/dbg_info.cpp @@ -15,7 +15,7 @@ namespace NAllocDbg { int& numSizes); using TSetProfileCurrentThread = bool(bool newVal); - using TSetProfileAllThreads = bool(bool newVal); + using TSetProfileAllThreads = bool(bool newVal); using TSetAllocationSamplingEnabled = bool(bool newVal); using TSetAllocationSampleRate = size_t(size_t newVal); @@ -32,7 +32,7 @@ namespace NAllocDbg { TGetPerTagAllocInfo* GetPerTagAllocInfo = nullptr; TSetProfileCurrentThread* SetProfileCurrentThread = nullptr; - TSetProfileAllThreads* SetProfileAllThreads = nullptr; + TSetProfileAllThreads* SetProfileAllThreads = nullptr; TSetAllocationSamplingEnabled* SetAllocationSamplingEnabled = nullptr; TSetAllocationSampleRate* SetAllocationSampleRate = nullptr; @@ -51,7 +51,7 @@ namespace NAllocDbg { GetPerTagAllocInfo = (TGetPerTagAllocInfo*)mallocInfo.GetParam("GetPerTagAllocInfo"); SetProfileCurrentThread = (TSetProfileCurrentThread*)mallocInfo.GetParam("SetProfileCurrentThread"); - SetProfileAllThreads = (TSetProfileAllThreads*)mallocInfo.GetParam("SetProfileAllThreads"); + SetProfileAllThreads = (TSetProfileAllThreads*)mallocInfo.GetParam("SetProfileAllThreads"); SetAllocationSamplingEnabled = (TSetAllocationSamplingEnabled*)mallocInfo.GetParam("SetAllocationSamplingEnabled"); SetAllocationSampleRate = (TSetAllocationSampleRate*)mallocInfo.GetParam("SetAllocationSampleRate"); @@ -97,10 +97,10 @@ namespace NAllocDbg { return AllocFn.SetProfileCurrentThread ? AllocFn.SetProfileCurrentThread(newVal) : false; } - bool SetProfileAllThreads(bool newVal) { - return AllocFn.SetProfileAllThreads ? AllocFn.SetProfileAllThreads(newVal) : false; - } - + bool SetProfileAllThreads(bool newVal) { + return AllocFn.SetProfileAllThreads ? AllocFn.SetProfileAllThreads(newVal) : false; + } + bool SetAllocationSamplingEnabled(bool newVal) { return AllocFn.SetAllocationSamplingEnabled ? AllocFn.SetAllocationSamplingEnabled(newVal) : false; } diff --git a/library/cpp/lfalloc/dbg_info/dbg_info.h b/library/cpp/lfalloc/dbg_info/dbg_info.h index 8c6ead7180..071562a81a 100644 --- a/library/cpp/lfalloc/dbg_info/dbg_info.h +++ b/library/cpp/lfalloc/dbg_info/dbg_info.h @@ -1,6 +1,6 @@ #pragma once -#include <util/generic/ptr.h> +#include <util/generic/ptr.h> #include <util/system/types.h> namespace NAllocDbg { @@ -60,7 +60,7 @@ namespace NAllocDbg { // Allocation sampling could be used to collect detailed information bool SetProfileCurrentThread(bool newVal); - bool SetProfileAllThreads(bool newVal); + bool SetProfileAllThreads(bool newVal); bool SetAllocationSamplingEnabled(bool newVal); size_t SetAllocationSampleRate(size_t newVal); diff --git a/library/cpp/lfalloc/lf_allocX64.h b/library/cpp/lfalloc/lf_allocX64.h index 161d42243e..fd2a906d6f 100644 --- a/library/cpp/lfalloc/lf_allocX64.h +++ b/library/cpp/lfalloc/lf_allocX64.h @@ -128,11 +128,11 @@ static bool TransparentHugePages = false; // force MADV_HUGEPAGE for large alloc static bool MapHugeTLB = false; // force MAP_HUGETLB for small allocs static bool EnableDefrag = true; -// Buffers that are larger than this size will not be filled with 0xcf -#ifndef DBG_FILL_MAX_SIZE -#define DBG_FILL_MAX_SIZE 0x01000000000000ULL -#endif - +// Buffers that are larger than this size will not be filled with 0xcf +#ifndef DBG_FILL_MAX_SIZE +#define DBG_FILL_MAX_SIZE 0x01000000000000ULL +#endif + template <class T> inline T* DoCas(T* volatile* target, T* exchange, T* compare) { #if defined(__has_builtin) && __has_builtin(__sync_val_compare_and_swap) @@ -304,7 +304,7 @@ enum EMMapMode { #ifndef _MSC_VER inline void VerifyMmapResult(void* result) { if (Y_UNLIKELY(result == MAP_FAILED)) - NMalloc::AbortFromCorruptedAllocator("negative size requested? or just out of mem"); + NMalloc::AbortFromCorruptedAllocator("negative size requested? or just out of mem"); } #endif @@ -337,7 +337,7 @@ static char* AllocWithMMapLinuxImpl(uintptr_t sz, EMMapMode mode) { char* nextAllocPtr = prevAllocPtr + sz; if (uintptr_t(nextAllocPtr - (char*)nullptr) >= areaFinish) { if (Y_UNLIKELY(wrapped)) { - NMalloc::AbortFromCorruptedAllocator("virtual memory is over fragmented"); + NMalloc::AbortFromCorruptedAllocator("virtual memory is over fragmented"); } // wrap after all area is used DoCas(areaPtr, areaStart, prevAllocPtr); @@ -368,15 +368,15 @@ static char* AllocWithMMap(uintptr_t sz, EMMapMode mode) { #ifdef _MSC_VER char* largeBlock = (char*)VirtualAlloc(0, sz, MEM_RESERVE, PAGE_READWRITE); if (Y_UNLIKELY(largeBlock == nullptr)) - NMalloc::AbortFromCorruptedAllocator("out of memory"); + 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"); + 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); if (Y_UNLIKELY(uintptr_t(((char*)largeBlock - ALLOC_START) + sz) >= N_MAX_WORKSET_SIZE)) - NMalloc::AbortFromCorruptedAllocator("out of working set, something has broken"); + NMalloc::AbortFromCorruptedAllocator("out of working set, something has broken"); #else char* largeBlock = AllocWithMMapLinuxImpl(sz, mode); if (TransparentHugePages) { @@ -453,7 +453,7 @@ static void* LargeBlockAlloc(size_t _nSize, ELFAllocCounter counter) { #ifdef _MSC_VER char* pRes = (char*)VirtualAlloc(0, (pgCount + 1) * 4096ll, MEM_COMMIT, PAGE_READWRITE); if (Y_UNLIKELY(pRes == 0)) { - NMalloc::AbortFromCorruptedAllocator("out of memory"); + NMalloc::AbortFromCorruptedAllocator("out of memory"); } #else @@ -784,7 +784,7 @@ static bool DefragmentMem() { int* nFreeCount = (int*)SystemAlloc(N_CHUNKS * sizeof(int)); if (Y_UNLIKELY(!nFreeCount)) { //__debugbreak(); - NMalloc::AbortFromCorruptedAllocator("debugbreak"); + NMalloc::AbortFromCorruptedAllocator("debugbreak"); } memset(nFreeCount, 0, N_CHUNKS * sizeof(int)); @@ -1004,7 +1004,7 @@ static Y_FORCE_INLINE void PutBlocksToGlobalFreeList(ptrdiff_t nSizeIdx, char** ////////////////////////////////////////////////////////////////////////// static TAtomic GlobalCounters[CT_MAX]; const int MAX_LOCAL_UPDATES = 100; -const intptr_t MAX_LOCAL_DELTA = 1*1024*1024; +const intptr_t MAX_LOCAL_DELTA = 1*1024*1024; struct TLocalCounter { intptr_t Value; @@ -1019,7 +1019,7 @@ struct TLocalCounter { Y_FORCE_INLINE void Increment(size_t value) { Value += value; - if (++Updates > MAX_LOCAL_UPDATES || Value > MAX_LOCAL_DELTA) { + if (++Updates > MAX_LOCAL_UPDATES || Value > MAX_LOCAL_DELTA) { Flush(); } } @@ -1344,13 +1344,13 @@ extern "C" bool SetProfileCurrentThread(bool newVal) { return prevVal; } -static volatile bool ProfileAllThreads; -extern "C" bool SetProfileAllThreads(bool newVal) { - bool prevVal = ProfileAllThreads; - ProfileAllThreads = newVal; - return prevVal; -} - +static volatile bool ProfileAllThreads; +extern "C" bool SetProfileAllThreads(bool newVal) { + bool prevVal = ProfileAllThreads; + ProfileAllThreads = newVal; + return prevVal; +} + static volatile bool AllocationSamplingEnabled; extern "C" bool SetAllocationSamplingEnabled(bool newVal) { bool prevVal = AllocationSamplingEnabled; @@ -1394,7 +1394,7 @@ 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; - if (AllocationSamplingEnabled && (ProfileCurrentThread || ProfileAllThreads) && !InAllocationCallback) { + if (AllocationSamplingEnabled && (ProfileCurrentThread || ProfileAllThreads) && !InAllocationCallback) { if (p->Size > AllocationSampleMaxSize || ++AllocationsCount % AllocationSampleRate == 0) { if (AllocationCallback) { InAllocationCallback = true; @@ -1556,7 +1556,7 @@ static Y_FORCE_INLINE void* LFAllocImpl(size_t _nSize) { if (count == 0) { count = LFAllocNoCacheMultiple(nSizeIdx, buf); if (count == 0) { - NMalloc::AbortFromCorruptedAllocator("no way LFAllocNoCacheMultiple() can fail"); + NMalloc::AbortFromCorruptedAllocator("no way LFAllocNoCacheMultiple() can fail"); } } char** dstBuf = thr->FreePtrs[nSizeIdx] + freePtrIdx - 1; @@ -1773,7 +1773,7 @@ static void DumpMemoryBlockUtilizationLocked() { nBadPages += page == 3; nTotalPages += page != 1; } - DebugTraceMMgr("entry = %lld; size = %lld; free = %lld; system %lld; utilisation = %g%%, fragmentation = %g%%\n", + DebugTraceMMgr("entry = %lld; size = %lld; free = %lld; system %lld; utilisation = %g%%, fragmentation = %g%%\n", k, nSize, cs.FreeCount * nSize, csGB.FreeCount * nSize, (N_CHUNK_SIZE - cs.FreeCount * nSize) * 100.0f / N_CHUNK_SIZE, 100.0f * nBadPages / Y_ARRAY_SIZE(pages)); nTotalAllocated += N_CHUNK_SIZE; @@ -1781,10 +1781,10 @@ static void DumpMemoryBlockUtilizationLocked() { nTotalBadPages += nBadPages; } SystemFree(entries); - DebugTraceMMgr("Total allocated = %llu, free = %lld, system = %lld, locked for future use %lld, utilisation = %g, fragmentation = %g\n", + DebugTraceMMgr("Total allocated = %llu, free = %lld, system = %lld, locked for future use %lld, utilisation = %g, fragmentation = %g\n", nTotalAllocated, nTotalFree, nTotalGroupBlocks, nTotalLocked, 100.0f * (nTotalAllocated - nTotalFree) / nTotalAllocated, 100.0f * nTotalBadPages / nTotalPages); - DebugTraceMMgr("Total %lld bytes used, %lld bytes in used pages\n", nTotalUsed, nTotalPages * N_PAGE_SIZE); + DebugTraceMMgr("Total %lld bytes used, %lld bytes in used pages\n", nTotalUsed, nTotalPages * N_PAGE_SIZE); for (int nSizeIdx = 0; nSizeIdx < N_SIZES; ++nSizeIdx) globalFreeLists[nSizeIdx].ReturnWholeList(wholeLists[nSizeIdx]); @@ -1850,7 +1850,7 @@ static const char* LFAlloc_GetParam(const char* param) { #if defined(LFALLOC_DBG) {"SetThreadAllocTag", (const char*)&SetThreadAllocTag}, {"SetProfileCurrentThread", (const char*)&SetProfileCurrentThread}, - {"SetProfileAllThreads", (const char*)&SetProfileAllThreads}, + {"SetProfileAllThreads", (const char*)&SetProfileAllThreads}, {"SetAllocationSamplingEnabled", (const char*)&SetAllocationSamplingEnabled}, {"SetAllocationSampleRate", (const char*)&SetAllocationSampleRate}, {"SetAllocationSampleMaxSize", (const char*)&SetAllocationSampleMaxSize}, @@ -1870,11 +1870,11 @@ static const char* LFAlloc_GetParam(const char* param) { static Y_FORCE_INLINE int LFPosixMemalign(void** memptr, size_t alignment, size_t size) { if (Y_UNLIKELY(alignment > 4096)) { - const char* error = "Larger alignment are not guaranteed with this implementation\n"; + const char* error = "Larger alignment are not guaranteed with this implementation\n"; #ifdef _win_ - OutputDebugStringA(error); + OutputDebugStringA(error); #endif - NMalloc::AbortFromCorruptedAllocator(error); + NMalloc::AbortFromCorruptedAllocator(error); } size_t bigsize = size; if (bigsize <= alignment) { diff --git a/library/cpp/lwtrace/mon/mon_lwtrace.cpp b/library/cpp/lwtrace/mon/mon_lwtrace.cpp index e9b8bb11a2..a61ee9ce22 100644 --- a/library/cpp/lwtrace/mon/mon_lwtrace.cpp +++ b/library/cpp/lwtrace/mon/mon_lwtrace.cpp @@ -1,5 +1,5 @@ -#include "mon_lwtrace.h" - +#include "mon_lwtrace.h" + #include <algorithm> #include <iterator> @@ -15,21 +15,21 @@ #include <util/string/escape.h> #include <util/system/condvar.h> #include <util/system/execpath.h> -#include <util/system/hostname.h> - -using namespace NMonitoring; - +#include <util/system/hostname.h> + +using namespace NMonitoring; + #define WWW_CHECK(cond, ...) \ - do { \ - if (!(cond)) { \ - ythrow yexception() << Sprintf(__VA_ARGS__); \ - } \ - } while (false) \ - /**/ - + do { \ + if (!(cond)) { \ + ythrow yexception() << Sprintf(__VA_ARGS__); \ + } \ + } while (false) \ + /**/ + #define WWW_HTML_INNER(out) HTML(out) WITH_SCOPED(tmp, TScopedHtmlInner(out)) #define WWW_HTML(out) out << NMonitoring::HTTPOKHTML; WWW_HTML_INNER(out) - + namespace NLwTraceMonPage { struct TTrackLogRefs { @@ -1537,35 +1537,35 @@ void SeriesSelectors(TStringStream& ss, const TCgiParameters& e, } } -class TProbesHtmlPrinter { -private: +class TProbesHtmlPrinter { +private: TVector<TVector<TString>> TableData; static constexpr int TimeoutSec = 15 * 60; // default timeout -public: - void Push(const NLWTrace::TProbe* probe) - { +public: + void Push(const NLWTrace::TProbe* probe) + { TableData.emplace_back(); auto& row = TableData.back(); row.emplace_back(); TString& groups = row.back(); - bool first = true; + bool first = true; for (const char* const* i = probe->Event.Groups; *i != nullptr; ++i, first = false) { groups.append(TString(first? "": ", ") + GroupHtml(*i)); - } + } row.push_back(ProbeHtml(probe->Event.GetProvider(), probe->Event.Name)); row.emplace_back(); TString& params = row.back(); - first = true; - for (size_t i = 0; i < probe->Event.Signature.ParamCount; i++, first = false) { + first = true; + for (size_t i = 0; i < probe->Event.Signature.ParamCount; i++, first = false) { params.append(TString(first? "": ", ") + probe->Event.Signature.ParamTypes[i] + " " + probe->Event.Signature.ParamNames[i]); - } + } row.emplace_back(ToString(probe->GetExecutorsCount())); - } + } void Output(IOutputStream& os) { @@ -1647,8 +1647,8 @@ private: "</div>"; return ss.Str(); } -}; - +}; + void TDashboardRegistry::Register(const NLWTrace::TDashboard& dashboard) { TGuard<TMutex> g(Mutex); Dashboards[dashboard.GetName()] = dashboard; @@ -1835,27 +1835,27 @@ public: } }; -class TTracesHtmlPrinter { -private: +class TTracesHtmlPrinter { +private: IOutputStream& Os; TInstant Now; -public: +public: explicit TTracesHtmlPrinter(IOutputStream& os) - : Os(os) + : Os(os) , Now(TInstant::Now()) - {} - + {} + void Push(ILogSource* src) - { + { TString id = src->GetId(); - Os << "<tr>"; - Os << "<td>"; - try { + Os << "<tr>"; + Os << "<td>"; + try { Os << src->GetStartTime().ToStringUpToSeconds(); - } catch (...) { - Os << "error: " << CurrentExceptionMessage(); - } - Os << "</td>" + } catch (...) { + Os << "error: " << CurrentExceptionMessage(); + } + Os << "</td>" << "<td><div class=\"dropdown\">" "<a href=\"#\" data-toggle=\"dropdown\">" << TimeoutToString(src->GetTimeout(Now)) << "</a>" "<ul class=\"dropdown-menu\">" @@ -1867,12 +1867,12 @@ public: "<li><a href=\"#\" onClick=\"$.redirectPost('?mode=settimeout&ui=y', {id:'" << id << "'});\">no timeout</a></li>" "</ul>" "</div></td>" - << "<td>" << EncodeHtmlPcdata(id) << "</td>" + << "<td>" << EncodeHtmlPcdata(id) << "</td>" << "<td>" << src->GetEventsCount() << "</td>" << "<td>" << src->GetThreadsCount() << "</td>" - << "<td><a href=\"?mode=log&id=" << id << "\">Text</a></td>" - << "<td><a href=\"?mode=log&format=json&id=" << id << "\">Json</a></td>" - << "<td><a href=\"?mode=query&id=" << id << "\">Query</a></td>" + << "<td><a href=\"?mode=log&id=" << id << "\">Text</a></td>" + << "<td><a href=\"?mode=log&format=json&id=" << id << "\">Json</a></td>" + << "<td><a href=\"?mode=query&id=" << id << "\">Query</a></td>" << "<td><a href=\"?mode=analytics&id=" << id << "\">Analytics</a></td>" << "<td><div class=\"dropdown navbar-right\">" // navbar-right is hack to drop left "<a href=\"#\" data-toggle=\"dropdown\">Modify</a>" @@ -1881,8 +1881,8 @@ public: "<li><a href=\"#\" onClick=\"$.redirectPost('?mode=delete&ui=y', {id:'" << id << "'});\">Delete</a></li>" "</ul>" "</div></td>" - << "</tr>\n"; - } + << "</tr>\n"; + } private: static TString TimeoutToString(TDuration d) { @@ -1916,8 +1916,8 @@ private: } return ss.Str(); } -}; - +}; + class TTracesLister { private: TVariants& Variants; @@ -2004,8 +2004,8 @@ private: } }; -class TLogFilter { -private: +class TLogFilter { +private: struct TFilter { TString ParamName; TString ParamValue; @@ -2042,31 +2042,31 @@ private: THashSet<const NLWTrace::TSignature*> Signatures; // Just to list param names TVariants ParamNames; THashMap<TString, THashSet<TString>> FilteredParamValues; // paramName -> { paramValue } -public: +public: explicit TLogFilter(const TVector<TString>& filters) - { + { for (const TString& subvalue : filters) { TFilter filter(subvalue); FilteredParamValues[filter.ParamName]; // just create empty set to gather values later if (filter.Parsed) { Filters.push_back(filter); } - } - } - + } + } + virtual ~TLogFilter() {} template <class TLog> bool Filter(const TLog& log) - { + { Gather(log); for (const TFilter& filter : Filters) { if (filter.Query.ExecuteQuery(log) != filter.Value) { return false; - } - } + } + } return true; - } + } void FilterSelectors(TStringStream& ss, const TCgiParameters& e, const TString& fparam) { @@ -2155,8 +2155,8 @@ private: Sort(result.begin(), result.end()); return result; } -}; - +}; + static void EscapeJSONString(IOutputStream& os, const TString& s) { for (TString::const_iterator i = s.begin(), e = s.end(); i != e; ++i) { @@ -2180,72 +2180,72 @@ static TString EscapeJSONString(const TString& s) return ss.Str(); } -class TLogJsonPrinter { -private: +class TLogJsonPrinter { +private: IOutputStream& Os; - bool FirstThread; - bool FirstItem; -public: + bool FirstThread; + bool FirstItem; +public: explicit TLogJsonPrinter(IOutputStream& os) - : Os(os) - , FirstThread(true) - , FirstItem(true) - {} - - void OutputHeader() - { - Os << "{\n\t\"source\": \"" << HostName() << "\"" - "\n\t, \"items\": [" - ; - } - + : Os(os) + , FirstThread(true) + , FirstItem(true) + {} + + void OutputHeader() + { + Os << "{\n\t\"source\": \"" << HostName() << "\"" + "\n\t, \"items\": [" + ; + } + void OutputFooter(const NLWTrace::TSession* trace) - { - Os << "\n\t\t]" - "\n\t, \"threads\": [" - ; + { + Os << "\n\t\t]" + "\n\t, \"threads\": [" + ; trace->ReadThreads(*this); - Os << "]" + Os << "]" "\n\t, \"events_count\": " << trace->GetEventsCount() << "\n\t, \"threads_count\": " << trace->GetThreadsCount() << - "\n\t, \"timestamp\": " << Now().GetValue() << - "\n}" - ; - } - - void PushThread(TThread::TId tid) - { - Os << (FirstThread? "": ", ") << tid; - FirstThread = false; - } - + "\n\t, \"timestamp\": " << Now().GetValue() << + "\n}" + ; + } + + void PushThread(TThread::TId tid) + { + Os << (FirstThread? "": ", ") << tid; + FirstThread = false; + } + void Push(TThread::TId tid, const NLWTrace::TLogItem& item) - { - Os << "\n\t\t" << (FirstItem? "": ", "); - FirstItem = false; - - Os << "[" << tid << - ", " << item.Timestamp.GetValue() << - ", \"" << item.Probe->Event.GetProvider() << "\"" - ", \"" << item.Probe->Event.Name << "\"" - ", {" - ; - if (item.SavedParamsCount > 0) { + { + Os << "\n\t\t" << (FirstItem? "": ", "); + FirstItem = false; + + Os << "[" << tid << + ", " << item.Timestamp.GetValue() << + ", \"" << item.Probe->Event.GetProvider() << "\"" + ", \"" << item.Probe->Event.Name << "\"" + ", {" + ; + if (item.SavedParamsCount > 0) { TString ParamValues[LWTRACE_MAX_PARAMS]; - item.Probe->Event.Signature.SerializeParams(item.Params, ParamValues); - bool first = true; - for (size_t i = 0; i < item.SavedParamsCount; i++, first = false) { - Os << (first? "": ", ") << "\"" << item.Probe->Event.Signature.ParamNames[i] << "\": \""; - EscapeJSONString(Os, ParamValues[i]); - Os << "\""; - } - } - Os << "}]"; - } -}; - -class TLogTextPrinter : public TLogFilter { -private: + item.Probe->Event.Signature.SerializeParams(item.Params, ParamValues); + bool first = true; + for (size_t i = 0; i < item.SavedParamsCount; i++, first = false) { + Os << (first? "": ", ") << "\"" << item.Probe->Event.Signature.ParamNames[i] << "\": \""; + EscapeJSONString(Os, ParamValues[i]); + Os << "\""; + } + } + Os << "}]"; + } +}; + +class TLogTextPrinter : public TLogFilter { +private: TMultiMap<NLWTrace::TTypedParam, std::pair<TThread::TId, NLWTrace::TLogItem> > Items; TMultiMap<NLWTrace::TTypedParam, NLWTrace::TTrackLog> Depot; THashMap<NLWTrace::TProbe*, size_t> ProbeId; @@ -2256,7 +2256,7 @@ private: ui64 Head = 0; ui64 Tail = 0; bool ShowTs = false; -public: +public: TLogTextPrinter(const TVector<TString>& filters, ui64 head, ui64 tail, const TString& order, bool reverseOrder, bool cutTs, bool showTs) : TLogFilter(filters) , CutTs(cutTs) @@ -2284,11 +2284,11 @@ public: }; void Output(IOutputStream& os) const - { + { OutputItems<Text>(os); OutputDepot<Text>(os); - } - + } + void OutputJson(IOutputStream& os) const { os << "{\"depot\":[\n"; @@ -2315,13 +2315,13 @@ public: } void Push(TThread::TId tid, const NLWTrace::TLogItem& item) - { + { CutTs.Push(tid, item); - if (Filter(item)) { + if (Filter(item)) { AddId(item); Items.emplace(GetKey(item), std::make_pair(tid, item)); - } - } + } + } void Push(TThread::TId tid, const NLWTrace::TTrackLog& tl) { @@ -2332,7 +2332,7 @@ public: } } -private: +private: void AddId(const NLWTrace::TLogItem& item) { if (ProbeId.find(item.Probe) == ProbeId.end()) { @@ -2412,7 +2412,7 @@ private: template <EFormat Format, bool AsTrack = false> void OutputItem(IOutputStream& os, TThread::TId tid, const NLWTrace::TLogItem& item, ui64 startTs, ui64 prevTs, bool& first) const - { + { if (CutTs.Skip(item)) { return; } @@ -2427,7 +2427,7 @@ private: } if (tid) { os << "<" << tid << "> "; - } + } if (item.Timestamp != TInstant::Zero()) { os << "[" << item.Timestamp << "] "; } else { @@ -2464,9 +2464,9 @@ private: } os << "}]" << (AsTrack? "]":""); } - } + } first = false; - } + } template <EFormat Format> void OutputTrackLog(IOutputStream& os, const NLWTrace::TTrackLog& tl, bool& first) const @@ -2486,8 +2486,8 @@ private: } os << "\n"; } -}; - +}; + class TLogAnalyzer: public TLogFilter { private: TMultiMap<ui64, std::pair<TThread::TId, NLWTrace::TLogItem>> Items; @@ -3773,52 +3773,52 @@ NLWTrace::TManager g_UnsafeManager(g_Probes, true); TDashboardRegistry g_DashboardRegistry; class TLWTraceMonPage : public NMonitoring::IMonPage { -private: +private: NLWTrace::TManager* TraceMngr; TString StartTime; TTraceCleaner Cleaner; TMutex SnapshotsMtx; THashMap<TString, TAtomicSharedPtr<NLWTrace::TLogPb>> Snapshots; -public: +public: explicit TLWTraceMonPage(bool allowUnsafe = false) - : NMonitoring::IMonPage("trace", "Tracing") + : NMonitoring::IMonPage("trace", "Tracing") , TraceMngr(&TraceManager(allowUnsafe)) , Cleaner(TraceMngr) { time_t stime = TInstant::Now().TimeT(); StartTime = CTimeR(&stime); } - + virtual void Output(NMonitoring::IMonHttpRequest& request) { TStringStream out; - try { + try { if (request.GetParams().Get("mode") == "") { OutputTracesAndSnapshots(request, out); - } else if (request.GetParams().Get("mode") == "probes") { + } else if (request.GetParams().Get("mode") == "probes") { OutputProbes(request, out); } else if (request.GetParams().Get("mode") == "dashboards") { OutputDashboards(request, out); } else if (request.GetParams().Get("mode") == "dashboard") { OutputDashboard(request, out); - } else if (request.GetParams().Get("mode") == "log") { + } else if (request.GetParams().Get("mode") == "log") { OutputLog(request, out); - } else if (request.GetParams().Get("mode") == "query") { + } else if (request.GetParams().Get("mode") == "query") { OutputQuery(request, out); } else if (request.GetParams().Get("mode") == "builder") { OutputBuilder(request, out); } else if (request.GetParams().Get("mode") == "analytics") { OutputAnalytics(request, out); - } else if (request.GetParams().Get("mode") == "new") { + } else if (request.GetParams().Get("mode") == "new") { PostNew(request, out); - } else if (request.GetParams().Get("mode") == "delete") { + } else if (request.GetParams().Get("mode") == "delete") { PostDelete(request, out); } else if (request.GetParams().Get("mode") == "make_snapshot") { PostSnapshot(request, out); } else if (request.GetParams().Get("mode") == "settimeout") { PostSetTimeout(request, out); - } else { - ythrow yexception() << "Bad request"; - } + } else { + ythrow yexception() << "Bad request"; + } } catch (TPageGenBase& gen) { out.Clear(); out << gen.what(); @@ -4063,8 +4063,8 @@ private: WWW_HTML(out) { out << "<h2>Trace Query: " << id << "</h2><pre>" << queryStr; } - } - } + } + } void OutputBuilder(const NMonitoring::IMonHttpRequest& request, IOutputStream& out) { @@ -4669,8 +4669,8 @@ private: } return false; } -}; - +}; + void RegisterPages(NMonitoring::TMonService2* mon, bool allowUnsafe) { THolder<NLwTraceMonPage::TLWTraceMonPage> p = MakeHolder<NLwTraceMonPage::TLWTraceMonPage>(allowUnsafe); mon->Register(p.Release()); @@ -4706,7 +4706,7 @@ void RegisterPages(NMonitoring::TMonService2* mon, bool allowUnsafe) { WWW_STATIC_FILE("lwtrace/mon/static/js/jquery.treegrid.min.js", JAVASCRIPT); WWW_STATIC_FILE("lwtrace/mon/static/js/jquery.url.min.js", JAVASCRIPT); #undef WWW_STATIC_FILE -} +} NLWTrace::TProbeRegistry& ProbeRegistry() { return g_Probes; diff --git a/library/cpp/lwtrace/mon/mon_lwtrace.h b/library/cpp/lwtrace/mon/mon_lwtrace.h index 2d5c4d3854..8030f6ea61 100644 --- a/library/cpp/lwtrace/mon/mon_lwtrace.h +++ b/library/cpp/lwtrace/mon/mon_lwtrace.h @@ -1,9 +1,9 @@ -#pragma once +#pragma once #include <library/cpp/lwtrace/protos/lwtrace.pb.h> #include <library/cpp/monlib/service/monservice.h> #include <library/cpp/lwtrace/control.h> - + #include <util/generic/vector.h> namespace NLwTraceMonPage { diff --git a/library/cpp/lwtrace/protos/ya.make b/library/cpp/lwtrace/protos/ya.make index 9262af6154..503d5e515f 100644 --- a/library/cpp/lwtrace/protos/ya.make +++ b/library/cpp/lwtrace/protos/ya.make @@ -1,11 +1,11 @@ PROTO_LIBRARY() - + OWNER(serxa) INCLUDE_TAGS(GO_PROTO) -SRCS( +SRCS( lwtrace.proto -) - -END() +) + +END() diff --git a/library/cpp/lwtrace/ya.make b/library/cpp/lwtrace/ya.make index 746c1314fd..d9accb3006 100644 --- a/library/cpp/lwtrace/ya.make +++ b/library/cpp/lwtrace/ya.make @@ -1,12 +1,12 @@ -LIBRARY() - +LIBRARY() + OWNER(serxa) PEERDIR( library/cpp/lwtrace/protos ) -SRCS( +SRCS( check.cpp control.cpp custom_action.cpp @@ -20,9 +20,9 @@ SRCS( stderr_writer.cpp symbol.cpp trace.cpp -) - -END() +) + +END() RECURSE(mon) diff --git a/library/cpp/malloc/api/malloc.cpp b/library/cpp/malloc/api/malloc.cpp index 9bda35814f..eed1c58a38 100644 --- a/library/cpp/malloc/api/malloc.cpp +++ b/library/cpp/malloc/api/malloc.cpp @@ -1,5 +1,5 @@ #include <stdlib.h> -#include <stdio.h> +#include <stdio.h> #include "malloc.h" @@ -28,9 +28,9 @@ namespace NMalloc { { } - void AbortFromCorruptedAllocator(const char* errorMessage) { - errorMessage = errorMessage ? errorMessage : "<unspecified>"; - fprintf(stderr, "Allocator error: %s\n", errorMessage); + void AbortFromCorruptedAllocator(const char* errorMessage) { + errorMessage = errorMessage ? errorMessage : "<unspecified>"; + fprintf(stderr, "Allocator error: %s\n", errorMessage); IsAllocatorCorrupted = true; abort(); } diff --git a/library/cpp/malloc/api/malloc.h b/library/cpp/malloc/api/malloc.h index d0d6e0c8d4..ebd545d6dd 100644 --- a/library/cpp/malloc/api/malloc.h +++ b/library/cpp/malloc/api/malloc.h @@ -16,7 +16,7 @@ namespace NMalloc { }; extern volatile bool IsAllocatorCorrupted; - void AbortFromCorruptedAllocator(const char* errorMessage = nullptr); + void AbortFromCorruptedAllocator(const char* errorMessage = nullptr); // this function should be implemented by malloc implementations TMallocInfo MallocInfo(); diff --git a/library/cpp/messagebus/actor/executor.cpp b/library/cpp/messagebus/actor/executor.cpp index b58e07f4bd..7a2227a458 100644 --- a/library/cpp/messagebus/actor/executor.cpp +++ b/library/cpp/messagebus/actor/executor.cpp @@ -18,7 +18,7 @@ using namespace NActor::NPrivate; namespace { struct THistoryInternal { struct TRecord { - TAtomic MaxQueueSize; + TAtomic MaxQueueSize; TRecord() : MaxQueueSize() @@ -27,7 +27,7 @@ namespace { TExecutorHistory::THistoryRecord Capture() { TExecutorHistory::THistoryRecord r; - r.MaxQueueSize = AtomicGet(MaxQueueSize); + r.MaxQueueSize = AtomicGet(MaxQueueSize); return r; } }; @@ -237,14 +237,14 @@ size_t TExecutor::GetWorkQueueSize() const { return WorkItems.Size(); } -using namespace NTSAN; - +using namespace NTSAN; + ui32 TExecutor::GetMaxQueueSizeAndClear() const { ui32 max = 0; for (unsigned i = 0; i < WorkerThreads.size(); ++i) { - TExecutorWorkerThreadLocalData* wtls = RelaxedLoad(&WorkerThreads[i]->ThreadLocalData); - max = Max<ui32>(max, RelaxedLoad(&wtls->MaxQueueSize)); - RelaxedStore<ui32>(&wtls->MaxQueueSize, 0); + TExecutorWorkerThreadLocalData* wtls = RelaxedLoad(&WorkerThreads[i]->ThreadLocalData); + max = Max<ui32>(max, RelaxedLoad(&wtls->MaxQueueSize)); + RelaxedStore<ui32>(&wtls->MaxQueueSize, 0); } return max; } @@ -269,7 +269,7 @@ TExecutorStatus TExecutor::GetStatusRecordInternal() const { ss << "work items: " << GetWorkQueueSize() << "\n"; ss << "workers:\n"; for (unsigned i = 0; i < WorkerThreads.size(); ++i) { - ss << "-- " << AtomicGet(*AtomicGet(WorkerThreads[i]->WhatThreadDoesLocation)) << "\n"; + ss << "-- " << AtomicGet(*AtomicGet(WorkerThreads[i]->WhatThreadDoesLocation)) << "\n"; } r.Status = ss.Str(); } @@ -299,8 +299,8 @@ TAutoPtr<IWorkItem> TExecutor::DequeueWork() { auto& wtls = TlsRef(WorkerThreadLocalData); - if (queueSize > RelaxedLoad(&wtls.MaxQueueSize)) { - RelaxedStore<ui32>(&wtls.MaxQueueSize, queueSize); + if (queueSize > RelaxedLoad(&wtls.MaxQueueSize)) { + RelaxedStore<ui32>(&wtls.MaxQueueSize, queueSize); } return wi; diff --git a/library/cpp/messagebus/actor/thread_extra.h b/library/cpp/messagebus/actor/thread_extra.h index e4f37a9760..b5aa151618 100644 --- a/library/cpp/messagebus/actor/thread_extra.h +++ b/library/cpp/messagebus/actor/thread_extra.h @@ -2,28 +2,28 @@ #include <util/thread/singleton.h> -namespace NTSAN { +namespace NTSAN { template <typename T> inline void RelaxedStore(volatile T* a, T x) { static_assert(std::is_integral<T>::value || std::is_pointer<T>::value, "expect std::is_integral<T>::value || std::is_pointer<T>::value"); -#ifdef _win_ +#ifdef _win_ *a = x; -#else +#else __atomic_store_n(a, x, __ATOMIC_RELAXED); -#endif +#endif } - + template <typename T> inline T RelaxedLoad(volatile T* a) { -#ifdef _win_ +#ifdef _win_ return *a; -#else +#else return __atomic_load_n(a, __ATOMIC_RELAXED); -#endif +#endif } - -} - + +} + void SetCurrentThreadName(const char* name); namespace NThreadExtra { diff --git a/library/cpp/messagebus/actor/what_thread_does.cpp b/library/cpp/messagebus/actor/what_thread_does.cpp index bce5ccd15e..bebb6a888c 100644 --- a/library/cpp/messagebus/actor/what_thread_does.cpp +++ b/library/cpp/messagebus/actor/what_thread_does.cpp @@ -1,6 +1,6 @@ #include "what_thread_does.h" -#include "thread_extra.h" +#include "thread_extra.h" #include <util/system/tls.h> @@ -8,13 +8,13 @@ Y_POD_STATIC_THREAD(const char*) WhatThreadDoes; const char* PushWhatThreadDoes(const char* what) { - const char* r = NTSAN::RelaxedLoad(&WhatThreadDoes); - NTSAN::RelaxedStore(&WhatThreadDoes, what); + const char* r = NTSAN::RelaxedLoad(&WhatThreadDoes); + NTSAN::RelaxedStore(&WhatThreadDoes, what); return r; } void PopWhatThreadDoes(const char* prev) { - NTSAN::RelaxedStore(&WhatThreadDoes, prev); + NTSAN::RelaxedStore(&WhatThreadDoes, prev); } const char** WhatThreadDoesLocation() { diff --git a/library/cpp/messagebus/config/defs.h b/library/cpp/messagebus/config/defs.h index 5db4ef4dae..92b1df9969 100644 --- a/library/cpp/messagebus/config/defs.h +++ b/library/cpp/messagebus/config/defs.h @@ -70,7 +70,7 @@ namespace NBus { inline bool IsBusKeyValid(TBusKey key) { return key != YBUS_KEYINVALID && key != YBUS_KEYMAX && key > YBUS_KEYLOCAL; } - + #define YBUS_VERSION 0 #define YBUS_INFINITE (1u << 30u) diff --git a/library/cpp/messagebus/latch.h b/library/cpp/messagebus/latch.h index 3677ee7c29..373f4c0e13 100644 --- a/library/cpp/messagebus/latch.h +++ b/library/cpp/messagebus/latch.h @@ -23,7 +23,7 @@ public: } TGuard<TMutex> guard(Mutex); - while (AtomicGet(Locked) == 1) { + while (AtomicGet(Locked) == 1) { CondVar.WaitI(Mutex); } } @@ -39,7 +39,7 @@ public: } TGuard<TMutex> guard(Mutex); - AtomicSet(Locked, 0); + AtomicSet(Locked, 0); CondVar.BroadCast(); } diff --git a/library/cpp/messagebus/local_tasks.h b/library/cpp/messagebus/local_tasks.h index c92d197ca5..d8e801a457 100644 --- a/library/cpp/messagebus/local_tasks.h +++ b/library/cpp/messagebus/local_tasks.h @@ -1,23 +1,23 @@ #pragma once -#include <util/system/atomic.h> - +#include <util/system/atomic.h> + class TLocalTasks { private: - TAtomic GotTasks; + TAtomic GotTasks; public: TLocalTasks() - : GotTasks(0) + : GotTasks(0) { } void AddTask() { - AtomicSet(GotTasks, 1); + AtomicSet(GotTasks, 1); } bool FetchTask() { - bool gotTasks = AtomicCas(&GotTasks, 0, 1); + bool gotTasks = AtomicCas(&GotTasks, 0, 1); return gotTasks; } }; diff --git a/library/cpp/messagebus/message.h b/library/cpp/messagebus/message.h index bf57f13dde..005ca10c65 100644 --- a/library/cpp/messagebus/message.h +++ b/library/cpp/messagebus/message.h @@ -155,7 +155,7 @@ namespace NBus { inline bool IsVersionNegotiation(const NBus::TBusHeader& header) { return header.Id == 0 && header.Size == sizeof(TBusHeader); } - + ////////////////////////////////////////////////////////// /// \brief Base class for all messages passed in the system diff --git a/library/cpp/messagebus/oldmodule/module.cpp b/library/cpp/messagebus/oldmodule/module.cpp index a322a2366f..24bd778799 100644 --- a/library/cpp/messagebus/oldmodule/module.cpp +++ b/library/cpp/messagebus/oldmodule/module.cpp @@ -777,7 +777,7 @@ void TBusModuleImpl::DestroyJob(TJobRunner* job) { Y_VERIFY(jobCount >= 0, "decremented too much"); Jobs.erase(job->JobStorageIterator); - if (AtomicGet(State) == STOPPED) { + if (AtomicGet(State) == STOPPED) { if (jobCount == 0) { ShutdownCondVar.BroadCast(); } @@ -804,11 +804,11 @@ void TBusModuleImpl::OnMessageReceived(TAutoPtr<TBusMessage> msg0, TOnMessageCon } void TBusModuleImpl::Shutdown() { - if (AtomicGet(State) != TBusModuleImpl::RUNNING) { - AtomicSet(State, TBusModuleImpl::STOPPED); + if (AtomicGet(State) != TBusModuleImpl::RUNNING) { + AtomicSet(State, TBusModuleImpl::STOPPED); return; } - AtomicSet(State, TBusModuleImpl::STOPPED); + AtomicSet(State, TBusModuleImpl::STOPPED); for (auto& clientSession : ClientSessions) { clientSession->Shutdown(); diff --git a/library/cpp/messagebus/protobuf/ybusbuf.cpp b/library/cpp/messagebus/protobuf/ybusbuf.cpp index 90ff132942..63415b3737 100644 --- a/library/cpp/messagebus/protobuf/ybusbuf.cpp +++ b/library/cpp/messagebus/protobuf/ybusbuf.cpp @@ -75,12 +75,12 @@ TAutoPtr<TBusMessage> TBusBufferProtocol::Deserialize(ui16 messageType, TArrayRe // clone the base TAutoPtr<TBusBufferBase> bmess = messageTemplate->New(); - // Need to override protobuf message size limit - // NOTE: the payload size has already been checked against session MaxMessageSize - google::protobuf::io::CodedInputStream input(reinterpret_cast<const ui8*>(payload.data()), payload.size()); + // Need to override protobuf message size limit + // NOTE: the payload size has already been checked against session MaxMessageSize + google::protobuf::io::CodedInputStream input(reinterpret_cast<const ui8*>(payload.data()), payload.size()); input.SetTotalBytesLimit(payload.size()); - - bool ok = bmess->GetRecord()->ParseFromCodedStream(&input) && input.ConsumedEntireMessage(); + + bool ok = bmess->GetRecord()->ParseFromCodedStream(&input) && input.ConsumedEntireMessage(); if (!ok) { return nullptr; } diff --git a/library/cpp/messagebus/remote_connection.cpp b/library/cpp/messagebus/remote_connection.cpp index 2113b5622f..22932569db 100644 --- a/library/cpp/messagebus/remote_connection.cpp +++ b/library/cpp/messagebus/remote_connection.cpp @@ -186,7 +186,7 @@ namespace NBus { } ReaderData.DropChannel(); - + ReaderData.Status.Fd = readSocket.Socket; ReaderData.SocketVersion = readSocket.SocketVersion; @@ -393,8 +393,8 @@ namespace NBus { } return true; - } - + } + bool TRemoteConnection::ReaderFillBuffer() { if (!ReaderData.BufferMore()) return true; diff --git a/library/cpp/messagebus/remote_connection_status.cpp b/library/cpp/messagebus/remote_connection_status.cpp index c34c875536..2c48b2a287 100644 --- a/library/cpp/messagebus/remote_connection_status.cpp +++ b/library/cpp/messagebus/remote_connection_status.cpp @@ -202,7 +202,7 @@ TString TRemoteConnectionStatus::PrintToString() const { p.AddRow("write buffer cap", LeftPad(WriterStatus.BufferSize, 12)); p.AddRow("read buffer cap", LeftPad(ReaderStatus.BufferSize, 12)); - + p.AddRow("write buffer drops", LeftPad(WriterStatus.Incremental.BufferDrops, 10)); p.AddRow("read buffer drops", LeftPad(ReaderStatus.Incremental.BufferDrops, 10)); diff --git a/library/cpp/messagebus/test/ut/messagebus_ut.cpp b/library/cpp/messagebus/test/ut/messagebus_ut.cpp index e771a933ca..040f9b7702 100644 --- a/library/cpp/messagebus/test/ut/messagebus_ut.cpp +++ b/library/cpp/messagebus/test/ut/messagebus_ut.cpp @@ -313,9 +313,9 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { TMutex Lock_; TDeque<TAutoPtr<TOnMessageContext>> DelayedMessages; - TDelayReplyServer() - : MessageReceivedEvent(TEventResetType::rAuto) - { + TDelayReplyServer() + : MessageReceivedEvent(TEventResetType::rAuto) + { Bus = CreateMessageQueue("TDelayReplyServer"); TBusServerSessionConfig sessionConfig; sessionConfig.SendTimeout = 1000; @@ -617,30 +617,30 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { } Y_UNIT_TEST(ServerMessageReservedIds) { - TObjectCountCheck objectCountCheck; - - TExampleServer server; - TNetAddr serverAddr = server.GetActualListenAddr(); - - TExampleClient client; - - client.SendMessagesWaitReplies(2, serverAddr); - - // This test doens't check 0, 1, YBUS_KEYINVALID because there are asserts() on sending side - - TAutoPtr<TBusMessage> req(new TExampleRequest(&client.Proto.RequestCount)); - req->GetHeader()->Id = 2; - client.Session->SendMessageAutoPtr(req, &serverAddr); - client.MessageCount = 1; - client.WaitForError(MESSAGE_DELIVERY_FAILED); - - req.Reset(new TExampleRequest(&client.Proto.RequestCount)); - req->GetHeader()->Id = YBUS_KEYLOCAL; - client.Session->SendMessageAutoPtr(req, &serverAddr); - client.MessageCount = 1; - client.WaitForError(MESSAGE_DELIVERY_FAILED); - } - + TObjectCountCheck objectCountCheck; + + TExampleServer server; + TNetAddr serverAddr = server.GetActualListenAddr(); + + TExampleClient client; + + client.SendMessagesWaitReplies(2, serverAddr); + + // This test doens't check 0, 1, YBUS_KEYINVALID because there are asserts() on sending side + + TAutoPtr<TBusMessage> req(new TExampleRequest(&client.Proto.RequestCount)); + req->GetHeader()->Id = 2; + client.Session->SendMessageAutoPtr(req, &serverAddr); + client.MessageCount = 1; + client.WaitForError(MESSAGE_DELIVERY_FAILED); + + req.Reset(new TExampleRequest(&client.Proto.RequestCount)); + req->GetHeader()->Id = YBUS_KEYLOCAL; + client.Session->SendMessageAutoPtr(req, &serverAddr); + client.MessageCount = 1; + client.WaitForError(MESSAGE_DELIVERY_FAILED); + } + Y_UNIT_TEST(TestGetInFlightForDestination) { TObjectCountCheck objectCountCheck; @@ -661,7 +661,7 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { break; } } - UNIT_ASSERT_VALUES_EQUAL(server.GetDelayedMessageCount(), 2); + UNIT_ASSERT_VALUES_EQUAL(server.GetDelayedMessageCount(), 2); size_t inFlight = client.Session->GetInFlight(addr); // 4 is for messagebus1 that adds inFlight counter twice for some reason @@ -731,10 +731,10 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { // check reset is possible here message->Reset(); - // intentionally don't destroy the message - // we will try to resend it + // intentionally don't destroy the message + // we will try to resend it Y_UNUSED(message.Release()); - + TestSync.CheckAndIncrement(1); } }; @@ -760,8 +760,8 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { // check reset is possible here message->Reset(); client.TestSync.CheckAndIncrement(3); - - delete message; + + delete message; } Y_UNIT_TEST(ResetAfterSendOneWayErrorInReturn) { @@ -865,8 +865,8 @@ Y_UNIT_TEST_SUITE(TMessageBusTests) { request.SetVersionInternal(0xF); // max output.Write(&request, sizeof(request)); - UNIT_ASSERT_VALUES_EQUAL(IsVersionNegotiation(request), true); - + UNIT_ASSERT_VALUES_EQUAL(IsVersionNegotiation(request), true); + TStreamSocketInput input(&socket); TBusHeader response; diff --git a/library/cpp/messagebus/test/ut/one_way_ut.cpp b/library/cpp/messagebus/test/ut/one_way_ut.cpp index bc78c5238a..9c21227e2b 100644 --- a/library/cpp/messagebus/test/ut/one_way_ut.cpp +++ b/library/cpp/messagebus/test/ut/one_way_ut.cpp @@ -93,7 +93,7 @@ public: TExampleProtocol Proto; public: - TAtomic NumMessages; + TAtomic NumMessages; NullServer() { NumMessages = 0; @@ -119,7 +119,7 @@ public: /// tell session to forget this message and never expect any reply mess.ForgetRequest(); - AtomicIncrement(NumMessages); + AtomicIncrement(NumMessages); } /// this handler should not be called because this server does not send replies @@ -139,10 +139,10 @@ Y_UNIT_TEST_SUITE(TMessageBusTests_OneWay) { client.Work(); // wait until all client message are delivered - UNIT_WAIT_FOR(AtomicGet(server.NumMessages) == 10); + UNIT_WAIT_FOR(AtomicGet(server.NumMessages) == 10); // assert correct number of messages - UNIT_ASSERT_VALUES_EQUAL(AtomicGet(server.NumMessages), 10); + UNIT_ASSERT_VALUES_EQUAL(AtomicGet(server.NumMessages), 10); UNIT_ASSERT_VALUES_EQUAL(server.Session->GetInFlight(), 0); UNIT_ASSERT_VALUES_EQUAL(client.Session->GetInFlight(), 0); } @@ -196,7 +196,7 @@ Y_UNIT_TEST_SUITE(TMessageBusTests_OneWay) { TBusClientSessionConfig sessionConfig; sessionConfig.SendTimeout = 1; sessionConfig.ConnectTimeout = 1; - sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(10); + sessionConfig.Secret.TimeoutPeriod = TDuration::MilliSeconds(10); return sessionConfig; } @@ -245,11 +245,11 @@ Y_UNIT_TEST_SUITE(TMessageBusTests_OneWay) { first = false; } - // BUGBUG: The test is buggy: the client might not get any error when sending one-way messages. - // All the messages that the client has sent before he gets first MESSAGE_BUSY error might get - // serailized and written to the socket buffer, so the write queue gets drained and there are - // no messages to timeout when periodic timeout check happens. - + // BUGBUG: The test is buggy: the client might not get any error when sending one-way messages. + // All the messages that the client has sent before he gets first MESSAGE_BUSY error might get + // serailized and written to the socket buffer, so the write queue gets drained and there are + // no messages to timeout when periodic timeout check happens. + client.GotError.WaitI(); } } diff --git a/library/cpp/monlib/counters/counters.cpp b/library/cpp/monlib/counters/counters.cpp index 2781b8ab4e..50dca4c577 100644 --- a/library/cpp/monlib/counters/counters.cpp +++ b/library/cpp/monlib/counters/counters.cpp @@ -7,18 +7,18 @@ namespace NMonitoring { unsigned i = 0; i64 major = val; i64 minor = 0; - const unsigned imax = sizeof(shorts) / sizeof(char); - for (i = 0; i < imax; i++) { + const unsigned imax = sizeof(shorts) / sizeof(char); + for (i = 0; i < imax; i++) { if (major >> 10 == 0) break; else { - minor = major - (major >> 10 << 10); + minor = major - (major >> 10 << 10); major = major >> 10; } } - minor = (minor * 10) >> 10; + minor = (minor * 10) >> 10; - if (i == 0 || i >= imax) + if (i == 0 || i >= imax) *buf = '\0'; else snprintf(buf, size, "%" PRId64 ".%" PRId64 "%c", major, minor, shorts[i]); @@ -28,15 +28,15 @@ namespace NMonitoring { char* PrettyNum(i64 val, char* buf, size_t size) { Y_ASSERT(buf); - if (size < 4) { - buf[0] = 0; - return buf; - } + if (size < 4) { + buf[0] = 0; + return buf; + } PrettyNumShort(val, buf + 2, size - 3); if (buf[2] == 0) { *buf = '\0'; } else { - size_t len = 2 + strnlen(buf + 2, size - 4); + size_t len = 2 + strnlen(buf + 2, size - 4); Y_ASSERT(len < size); buf[0] = ' '; buf[1] = '('; diff --git a/library/cpp/monlib/dynamic_counters/counters.h b/library/cpp/monlib/dynamic_counters/counters.h index 5b0db006ae..dc178cfbe0 100644 --- a/library/cpp/monlib/dynamic_counters/counters.h +++ b/library/cpp/monlib/dynamic_counters/counters.h @@ -195,7 +195,7 @@ namespace NMonitoring { private: TRWMutex Lock; - TCounterPtr LookupCounter; // Counts lookups by name + TCounterPtr LookupCounter; // Counts lookups by name TOnLookupPtr OnLookup = nullptr; // Called on each lookup if not nullptr, intended for lightweight tracing. typedef TIntrusivePtr<TCountableBase> TCountablePtr; @@ -241,12 +241,12 @@ namespace NMonitoring { ~TDynamicCounters() override; - // This counter allows to track lookups by name within the whole subtree - void SetLookupCounter(TCounterPtr lookupCounter) { + // This counter allows to track lookups by name within the whole subtree + void SetLookupCounter(TCounterPtr lookupCounter) { TWriteGuard g(Lock); - LookupCounter = lookupCounter; - } - + LookupCounter = lookupCounter; + } + void SetOnLookup(TOnLookupPtr onLookup) { TWriteGuard g(Lock); OnLookup = onLookup; diff --git a/library/cpp/monlib/dynamic_counters/counters_ut.cpp b/library/cpp/monlib/dynamic_counters/counters_ut.cpp index f3d87930f9..3591037e0a 100644 --- a/library/cpp/monlib/dynamic_counters/counters_ut.cpp +++ b/library/cpp/monlib/dynamic_counters/counters_ut.cpp @@ -284,33 +284,33 @@ Y_UNIT_TEST_SUITE(TDynamicCountersTest) { " sensor:timeMillis = {1: 1, 2: 1, 4: 2, inf: 95}\n" "}\n"); } - - Y_UNIT_TEST(CounterLookupCounter) { - TDynamicCounterPtr rootGroup(new TDynamicCounters()); - TDynamicCounters::TCounterPtr lookups = rootGroup->GetCounter("Lookups", true); - rootGroup->SetLookupCounter(lookups); - - // Create subtree and check that counter is inherited - TDynamicCounterPtr serviceGroup = rootGroup->GetSubgroup("service", "MyService"); - UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 1); - - TDynamicCounterPtr subGroup = serviceGroup->GetSubgroup("component", "MyComponent"); - UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 2); - - auto counter = subGroup->GetNamedCounter("range", "20 msec", true); - UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 3); - - auto hist = subGroup->GetHistogram("timeMsec", ExponentialHistogram(4, 2)); - UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 4); - - // Replace the counter for subGroup - auto subGroupLookups = rootGroup->GetCounter("LookupsInMyComponent", true); - UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 5); - subGroup->SetLookupCounter(subGroupLookups); - auto counter2 = subGroup->GetNamedCounter("range", "30 msec", true); - UNIT_ASSERT_VALUES_EQUAL(subGroupLookups->Val(), 1); - UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 5); - } + + Y_UNIT_TEST(CounterLookupCounter) { + TDynamicCounterPtr rootGroup(new TDynamicCounters()); + TDynamicCounters::TCounterPtr lookups = rootGroup->GetCounter("Lookups", true); + rootGroup->SetLookupCounter(lookups); + + // Create subtree and check that counter is inherited + TDynamicCounterPtr serviceGroup = rootGroup->GetSubgroup("service", "MyService"); + UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 1); + + TDynamicCounterPtr subGroup = serviceGroup->GetSubgroup("component", "MyComponent"); + UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 2); + + auto counter = subGroup->GetNamedCounter("range", "20 msec", true); + UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 3); + + auto hist = subGroup->GetHistogram("timeMsec", ExponentialHistogram(4, 2)); + UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 4); + + // Replace the counter for subGroup + auto subGroupLookups = rootGroup->GetCounter("LookupsInMyComponent", true); + UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 5); + subGroup->SetLookupCounter(subGroupLookups); + auto counter2 = subGroup->GetNamedCounter("range", "30 msec", true); + UNIT_ASSERT_VALUES_EQUAL(subGroupLookups->Val(), 1); + UNIT_ASSERT_VALUES_EQUAL(lookups->Val(), 5); + } Y_UNIT_TEST(FindCounters) { TDynamicCounterPtr rootGroup(new TDynamicCounters()); diff --git a/library/cpp/monlib/service/pages/templates.h b/library/cpp/monlib/service/pages/templates.h index a4de362845..b4656f059f 100644 --- a/library/cpp/monlib/service/pages/templates.h +++ b/library/cpp/monlib/service/pages/templates.h @@ -150,8 +150,8 @@ namespace NMonitoring { } ~TTag() { - try { - Str << "</" << tag << ">"; + try { + Str << "</" << tag << ">"; } catch (...) { } } diff --git a/library/cpp/monlib/service/pages/version_mon_page.cpp b/library/cpp/monlib/service/pages/version_mon_page.cpp index 50e6288809..41e29417da 100644 --- a/library/cpp/monlib/service/pages/version_mon_page.cpp +++ b/library/cpp/monlib/service/pages/version_mon_page.cpp @@ -11,6 +11,6 @@ void TVersionMonPage::OutputText(IOutputStream& out, NMonitoring::IMonHttpReques out << version; if (!TString(version).EndsWith("\n")) out << "\n"; - out << GetBuildInfo() << "\n\n"; + out << GetBuildInfo() << "\n\n"; out << "linked with malloc: " << NMalloc::MallocInfo().Name << "\n"; } diff --git a/library/cpp/regex/pire/extraencodings.cpp b/library/cpp/regex/pire/extraencodings.cpp index 965a0c77de..2e507e4b67 100644 --- a/library/cpp/regex/pire/extraencodings.cpp +++ b/library/cpp/regex/pire/extraencodings.cpp @@ -1,13 +1,13 @@ -#include <util/system/defaults.h> -#include <util/system/yassert.h> +#include <util/system/defaults.h> +#include <util/system/yassert.h> #include <library/cpp/charset/codepage.h> -#include <util/generic/singleton.h> -#include <util/generic/yexception.h> +#include <util/generic/singleton.h> +#include <util/generic/yexception.h> #include <library/cpp/charset/doccodes.h> -#include "pire.h" - -namespace NPire { +#include "pire.h" + +namespace NPire { namespace { // A one-byte encoding which is capable of transforming upper half of the character // table to/from Unicode chars. @@ -18,14 +18,14 @@ namespace NPire { for (size_t i = 0; i < 256; ++i) Reverse_.insert(std::make_pair(Table_[i], static_cast<char>(i))); } - + wchar32 FromLocal(const char*& begin, const char* end) const override { if (begin != end) return Table_[static_cast<unsigned char>(*begin++)]; else ythrow yexception() << "EOF reached in Pire::OneByte::fromLocal()"; } - + TString ToLocal(wchar32 c) const override { THashMap<wchar32, char>::const_iterator i = Reverse_.find(c); if (i != Reverse_.end()) @@ -33,16 +33,16 @@ namespace NPire { else return TString(); } - + void AppendDot(TFsm& fsm) const override { fsm.AppendDot(); } - + private: const wchar32* Table_; THashMap<wchar32, char> Reverse_; }; - + template <unsigned N> struct TOneByteHelper: public TOneByte { inline TOneByteHelper() @@ -51,16 +51,16 @@ namespace NPire { } }; } - + namespace NEncodings { const NPire::TEncoding& Koi8r() { return *Singleton<TOneByteHelper<CODES_KOI8>>(); } - + const NPire::TEncoding& Cp1251() { return *Singleton<TOneByteHelper<CODES_WIN>>(); - } - + } + const NPire::TEncoding& Get(ECharset encoding) { switch (encoding) { case CODES_WIN: @@ -75,7 +75,7 @@ namespace NPire { ythrow yexception() << "Pire::Encodings::get(ECharset): unknown encoding " << (int)encoding; } } - - } - -} + + } + +} diff --git a/library/cpp/regex/pire/inline/ya.make b/library/cpp/regex/pire/inline/ya.make index 78a44d80d7..d4850f7b45 100644 --- a/library/cpp/regex/pire/inline/ya.make +++ b/library/cpp/regex/pire/inline/ya.make @@ -1,5 +1,5 @@ PROGRAM(pire_inline) - + CFLAGS(-DPIRE_NO_CONFIG) OWNER( @@ -9,14 +9,14 @@ OWNER( PEERDIR( ADDINCL library/cpp/regex/pire -) - +) + SRCDIR( contrib/libs/pire/pire ) - -SRCS( + +SRCS( inline.l -) - -END() +) + +END() diff --git a/library/cpp/regex/pire/pire.h b/library/cpp/regex/pire/pire.h index e8f6f7cfd1..286fecd693 100644 --- a/library/cpp/regex/pire/pire.h +++ b/library/cpp/regex/pire/pire.h @@ -1,19 +1,19 @@ -#pragma once - -#ifndef PIRE_NO_CONFIG -#define PIRE_NO_CONFIG -#endif - -#include <contrib/libs/pire/pire/pire.h> -#include <contrib/libs/pire/pire/extra.h> - +#pragma once + +#ifndef PIRE_NO_CONFIG +#define PIRE_NO_CONFIG +#endif + +#include <contrib/libs/pire/pire/pire.h> +#include <contrib/libs/pire/pire/extra.h> + #include <library/cpp/charset/doccodes.h> -namespace NPire { +namespace NPire { using TChar = Pire::Char; using Pire::MaxChar; - - // Scanner classes + + // Scanner classes using TScanner = Pire::Scanner; using TNonrelocScanner = Pire::NonrelocScanner; using TScannerNoMask = Pire::ScannerNoMask; @@ -27,11 +27,11 @@ namespace NPire { using TCapturingScanner = Pire::CapturingScanner; using TSlowCapturingScanner = Pire::SlowCapturingScanner; using TCountingScanner = Pire::CountingScanner; - + template <typename T1, typename T2> using TScannerPair = Pire::ScannerPair<T1, T2>; - // Helper classes + // Helper classes using TFsm = Pire::Fsm; using TLexer = Pire::Lexer; using TTerm = Pire::Term; @@ -39,38 +39,38 @@ namespace NPire { using TFeature = Pire::Feature; using TFeaturePtr = Pire::Feature::Ptr; using TError = Pire::Error; - - // Helper functions + + // Helper functions using Pire::LongestPrefix; using Pire::LongestSuffix; using Pire::Matches; - using Pire::MmappedScanner; - using Pire::Run; + using Pire::MmappedScanner; + using Pire::Run; using Pire::Runner; - using Pire::ShortestPrefix; - using Pire::ShortestSuffix; - using Pire::Step; - - using namespace Pire::SpecialChar; - using namespace Pire::Consts; - - namespace NFeatures { + using Pire::ShortestPrefix; + using Pire::ShortestSuffix; + using Pire::Step; + + using namespace Pire::SpecialChar; + using namespace Pire::Consts; + + namespace NFeatures { using Pire::Features::AndNotSupport; using Pire::Features::Capture; - using Pire::Features::CaseInsensitive; - using Pire::Features::GlueSimilarGlyphs; - } - - namespace NEncodings { - using Pire::Encodings::Latin1; - using Pire::Encodings::Utf8; - + using Pire::Features::CaseInsensitive; + using Pire::Features::GlueSimilarGlyphs; + } + + namespace NEncodings { + using Pire::Encodings::Latin1; + using Pire::Encodings::Utf8; + const NPire::TEncoding& Koi8r(); const NPire::TEncoding& Cp1251(); const NPire::TEncoding& Get(ECharset encoding); - } - - namespace NTokenTypes { - using namespace Pire::TokenTypes; - } -} + } + + namespace NTokenTypes { + using namespace Pire::TokenTypes; + } +} diff --git a/library/cpp/regex/pire/regexp.h b/library/cpp/regex/pire/regexp.h index aeb66a8a64..94bba4064b 100644 --- a/library/cpp/regex/pire/regexp.h +++ b/library/cpp/regex/pire/regexp.h @@ -54,13 +54,13 @@ namespace NRegExp { lexer.Assign(regexp.data(), regexp.data() + regexp.size()); } else { TVector<wchar32> ucs4(regexp.size() + 1); - size_t inRead = 0; - size_t outWritten = 0; + size_t inRead = 0; + size_t outWritten = 0; int recodeRes = RecodeToUnicode(opts.Charset, regexp.data(), ucs4.data(), regexp.size(), regexp.size(), inRead, outWritten); Y_ASSERT(recodeRes == RECODE_OK); Y_ASSERT(outWritten < ucs4.size()); - ucs4[outWritten] = 0; + ucs4[outWritten] = 0; lexer.Assign(ucs4.begin(), ucs4.begin() + std::char_traits<wchar32>::length(ucs4.data())); @@ -207,12 +207,12 @@ namespace NRegExp { } protected: - inline void Run(const char* data, size_t len, bool addBegin, bool addEnd) noexcept { - if (addBegin) { + inline void Run(const char* data, size_t len, bool addBegin, bool addEnd) noexcept { + if (addBegin) { NPire::Step(GetScanner(), State, NPire::BeginMark); } NPire::Run(GetScanner(), State, data, data + len); - if (addEnd) { + if (addEnd) { NPire::Step(GetScanner(), State, NPire::EndMark); } } @@ -236,8 +236,8 @@ namespace NRegExp { { } - inline TMatcher& Match(const char* data, size_t len, bool addBegin = false, bool addEnd = false) noexcept { - Run(data, len, addBegin, addEnd); + inline TMatcher& Match(const char* data, size_t len, bool addBegin = false, bool addEnd = false) noexcept { + Run(data, len, addBegin, addEnd); return *this; } @@ -267,9 +267,9 @@ namespace NRegExp { return GetState().Captured(); } - inline TSearcher& Search(const char* data, size_t len, bool addBegin = true, bool addEnd = true) noexcept { + inline TSearcher& Search(const char* data, size_t len, bool addBegin = true, bool addEnd = true) noexcept { Data = TStringBuf(data, len); - Run(data, len, addBegin, addEnd); + Run(data, len, addBegin, addEnd); return *this; } diff --git a/library/cpp/regex/pire/ut/regexp_ut.cpp b/library/cpp/regex/pire/ut/regexp_ut.cpp index 7c517bc583..e7206de9ad 100644 --- a/library/cpp/regex/pire/ut/regexp_ut.cpp +++ b/library/cpp/regex/pire/ut/regexp_ut.cpp @@ -17,41 +17,41 @@ Y_UNIT_TEST_SUITE(TRegExp) { } Y_UNIT_TEST(Boundaries) { - UNIT_ASSERT(!TMatcher(TFsm("qwb$", TFsm::TOptions().SetSurround(true))).Match("aqwb").Final()); - UNIT_ASSERT(!TMatcher(TFsm("^aqw", TFsm::TOptions().SetSurround(true))).Match("aqwb").Final()); + UNIT_ASSERT(!TMatcher(TFsm("qwb$", TFsm::TOptions().SetSurround(true))).Match("aqwb").Final()); + UNIT_ASSERT(!TMatcher(TFsm("^aqw", TFsm::TOptions().SetSurround(true))).Match("aqwb").Final()); UNIT_ASSERT(TMatcher(TFsm("qwb$", TFsm::TOptions().SetSurround(true))).Match(TStringBuf("aqwb"), true, true).Final()); UNIT_ASSERT(TMatcher(TFsm("^aqw", TFsm::TOptions().SetSurround(true))).Match(TStringBuf("aqwb"), true, true).Final()); UNIT_ASSERT(!TMatcher(TFsm("qw$", TFsm::TOptions().SetSurround(true))).Match(TStringBuf("aqwb"), true, true).Final()); UNIT_ASSERT(!TMatcher(TFsm("^qw", TFsm::TOptions().SetSurround(true))).Match(TStringBuf("aqwb"), true, true).Final()); - - UNIT_ASSERT(TMatcher(TFsm("^aqwb$", TFsm::TOptions().SetSurround(true))) + + UNIT_ASSERT(TMatcher(TFsm("^aqwb$", TFsm::TOptions().SetSurround(true))) .Match(TStringBuf("a"), true, false) .Match(TStringBuf("q"), false, false) .Match(TStringBuf("w"), false, false) .Match(TStringBuf("b"), false, true) .Final()); - } - + } + Y_UNIT_TEST(Case) { UNIT_ASSERT(TMatcher(TFsm("qw", TFsm::TOptions().SetCaseInsensitive(true))).Match("Qw").Final()); UNIT_ASSERT(!TMatcher(TFsm("qw", TFsm::TOptions().SetCaseInsensitive(false))).Match("Qw").Final()); } - + Y_UNIT_TEST(UnicodeCase) { UNIT_ASSERT(TMatcher(TFsm("\\x{61}\\x{62}", TFsm::TOptions().SetCaseInsensitive(true))).Match("Ab").Final()); UNIT_ASSERT(!TMatcher(TFsm("\\x{61}\\x{62}", TFsm::TOptions().SetCaseInsensitive(false))).Match("Ab").Final()); } Y_UNIT_TEST(Utf) { - NRegExp::TFsmBase::TOptions opts; - opts.Charset = CODES_UTF8; - opts.Surround = true; - UNIT_ASSERT(TMatcher(TFsm(".*", opts)).Match("wtf").Final()); - UNIT_ASSERT(TMatcher(TFsm(".*", opts)).Match("чзн").Final()); - UNIT_ASSERT(TMatcher(TFsm("ч.*", opts)).Match("чзн").Final()); - UNIT_ASSERT(!TMatcher(TFsm("чзн", opts)).Match("чзх").Final()); - } - + NRegExp::TFsmBase::TOptions opts; + opts.Charset = CODES_UTF8; + opts.Surround = true; + UNIT_ASSERT(TMatcher(TFsm(".*", opts)).Match("wtf").Final()); + UNIT_ASSERT(TMatcher(TFsm(".*", opts)).Match("чзн").Final()); + UNIT_ASSERT(TMatcher(TFsm("ч.*", opts)).Match("чзн").Final()); + UNIT_ASSERT(!TMatcher(TFsm("чзн", opts)).Match("чзх").Final()); + } + Y_UNIT_TEST(AndNot) { NRegExp::TFsmBase::TOptions opts; opts.AndNotSupport = true; @@ -84,15 +84,15 @@ Y_UNIT_TEST_SUITE(TRegExp) { } Y_UNIT_TEST(Glue) { - TFsm glued = - TFsm("qw", TFsm::TOptions().SetCaseInsensitive(true)) | - TFsm("qw", TFsm::TOptions().SetCaseInsensitive(false)) | - TFsm("abc", TFsm::TOptions().SetCaseInsensitive(false)); - UNIT_ASSERT(TMatcher(glued).Match("Qw").Final()); - UNIT_ASSERT(TMatcher(glued).Match("Qw").Final()); - UNIT_ASSERT(TMatcher(glued).Match("abc").Final()); - UNIT_ASSERT(!TMatcher(glued).Match("Abc").Final()); - } + TFsm glued = + TFsm("qw", TFsm::TOptions().SetCaseInsensitive(true)) | + TFsm("qw", TFsm::TOptions().SetCaseInsensitive(false)) | + TFsm("abc", TFsm::TOptions().SetCaseInsensitive(false)); + UNIT_ASSERT(TMatcher(glued).Match("Qw").Final()); + UNIT_ASSERT(TMatcher(glued).Match("Qw").Final()); + UNIT_ASSERT(TMatcher(glued).Match("abc").Final()); + UNIT_ASSERT(!TMatcher(glued).Match("Abc").Final()); + } Y_UNIT_TEST(Capture1) { TCapturingFsm fsm("here we have user_id=([a-z0-9]+);"); diff --git a/library/cpp/regex/pire/ut/ya.make b/library/cpp/regex/pire/ut/ya.make index d0a2301816..8776695f40 100644 --- a/library/cpp/regex/pire/ut/ya.make +++ b/library/cpp/regex/pire/ut/ya.make @@ -1,20 +1,20 @@ # this test in not linked into build tree with ReCURSE and is built by unittest/library UNITTEST() - + OWNER( g:util davenger ) SET(PIRETESTSDIR contrib/libs/pire/ut) - + CFLAGS(-DPIRE_NO_CONFIG) - + PEERDIR( library/cpp/regex/pire ) - + SRCDIR( ${PIRETESTSDIR} ) @@ -23,22 +23,22 @@ ADDINCL( contrib/libs/pire/pire contrib/libs/pire/ut ) - -SRCS( - pire_ut.cpp - capture_ut.cpp - count_ut.cpp + +SRCS( + pire_ut.cpp + capture_ut.cpp + count_ut.cpp glyph_ut.cpp - easy_ut.cpp + easy_ut.cpp read_unicode_ut.cpp - regexp_ut.cpp + regexp_ut.cpp approx_matching_ut.cpp -) - +) + SIZE(MEDIUM) TIMEOUT(600) PIRE_INLINE(inline_ut.cpp) -END() +END() diff --git a/library/cpp/regex/pire/ya.make b/library/cpp/regex/pire/ya.make index 0f788b35b5..c857e6d18b 100644 --- a/library/cpp/regex/pire/ya.make +++ b/library/cpp/regex/pire/ya.make @@ -1,5 +1,5 @@ -LIBRARY() - +LIBRARY() + OWNER( g:util g:antiinfra @@ -8,33 +8,33 @@ OWNER( ) CFLAGS(-DPIRE_NO_CONFIG) - + SRCDIR(contrib/libs/pire/pire) - -SRCS( + +SRCS( pcre2pire.cpp - classes.cpp - encoding.cpp - fsm.cpp - scanner_io.cpp - easy.cpp - scanners/null.cpp - extra/capture.cpp - extra/count.cpp - extra/glyphs.cpp - re_lexer.cpp + classes.cpp + encoding.cpp + fsm.cpp + scanner_io.cpp + easy.cpp + scanners/null.cpp + extra/capture.cpp + extra/count.cpp + extra/glyphs.cpp + re_lexer.cpp re_parser.y read_unicode.cpp - extraencodings.cpp + extraencodings.cpp approx_matching.cpp half_final_fsm.cpp minimize.h -) - +) + PEERDIR( library/cpp/charset ) -END() +END() RECURSE_FOR_TESTS(ut) |