summaryrefslogtreecommitdiffstats
path: root/library/cpp/lfalloc/alloc_profiler/profiler.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/lfalloc/alloc_profiler/profiler.cpp
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/lfalloc/alloc_profiler/profiler.cpp')
-rw-r--r--library/cpp/lfalloc/alloc_profiler/profiler.cpp81
1 files changed, 81 insertions, 0 deletions
diff --git a/library/cpp/lfalloc/alloc_profiler/profiler.cpp b/library/cpp/lfalloc/alloc_profiler/profiler.cpp
new file mode 100644
index 00000000000..0e30927a5a2
--- /dev/null
+++ b/library/cpp/lfalloc/alloc_profiler/profiler.cpp
@@ -0,0 +1,81 @@
+#include "profiler.h"
+
+#include "stackcollect.h"
+
+#include <util/generic/algorithm.h>
+#include <util/generic/singleton.h>
+#include <util/generic/string.h>
+#include <util/generic/vector.h>
+#include <util/stream/str.h>
+
+namespace NAllocProfiler {
+
+namespace {
+
+static TAllocationStackCollector& AllocationStackCollector()
+{
+ return *Singleton<TAllocationStackCollector>();
+}
+
+int AllocationCallback(int tag, size_t size, int sizeIdx)
+{
+ Y_UNUSED(sizeIdx);
+
+ static const size_t STACK_FRAMES_COUNT = 32;
+ static const size_t STACK_FRAMES_SKIP = 1;
+
+ void* frames[STACK_FRAMES_COUNT];
+ size_t frameCount = BackTrace(frames, Y_ARRAY_SIZE(frames));
+ if (frameCount <= STACK_FRAMES_SKIP) {
+ return -1;
+ }
+
+ void** stack = &frames[STACK_FRAMES_SKIP];
+ frameCount -= STACK_FRAMES_SKIP;
+
+ auto& collector = AllocationStackCollector();
+ return collector.Alloc(stack, frameCount, tag, size);
+}
+
+void DeallocationCallback(int stackId, int tag, size_t size, int sizeIdx)
+{
+ Y_UNUSED(tag);
+ Y_UNUSED(sizeIdx);
+
+ auto& collector = AllocationStackCollector();
+ collector.Free(stackId, size);
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+
+bool StartAllocationSampling(bool profileAllThreads)
+{
+ auto& collector = AllocationStackCollector();
+ collector.Clear();
+
+ NAllocDbg::SetProfileAllThreads(profileAllThreads);
+ NAllocDbg::SetAllocationCallback(AllocationCallback);
+ NAllocDbg::SetDeallocationCallback(DeallocationCallback);
+ NAllocDbg::SetAllocationSamplingEnabled(true);
+ return true;
+}
+
+bool StopAllocationSampling(IAllocationStatsDumper &out, int count)
+{
+ NAllocDbg::SetAllocationCallback(nullptr);
+ NAllocDbg::SetDeallocationCallback(nullptr);
+ NAllocDbg::SetAllocationSamplingEnabled(false);
+
+ auto& collector = AllocationStackCollector();
+ collector.Dump(count, out);
+ return true;
+}
+
+bool StopAllocationSampling(IOutputStream& out, int count) {
+ TAllocationStatsDumper dumper(out);
+ return StopAllocationSampling(dumper, count);
+}
+
+} // namespace NProfiler