From 2eea2ff7cb37c926222f023e6e587d0c5a6fbbc1 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Thu, 17 Dec 2020 12:34:00 +0000 Subject: - Add support for giving out a global callgraph for all threads on level 2. - You need level 3 to get a callgraph per thread. You normally want to see the global callgraph prior to drilling in to each thread. --- vespamalloc/src/vespamalloc/malloc/datasegment.hpp | 12 +++++++----- vespamalloc/src/vespamalloc/malloc/threadlist.hpp | 14 ++++++++++++-- vespamalloc/src/vespamalloc/malloc/threadpool.h | 1 + vespamalloc/src/vespamalloc/malloc/threadpool.hpp | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) (limited to 'vespamalloc/src') diff --git a/vespamalloc/src/vespamalloc/malloc/datasegment.hpp b/vespamalloc/src/vespamalloc/malloc/datasegment.hpp index 366747ef880..6c9c1287ff8 100644 --- a/vespamalloc/src/vespamalloc/malloc/datasegment.hpp +++ b/vespamalloc/src/vespamalloc/malloc/datasegment.hpp @@ -164,14 +164,15 @@ void DataSegment::returnBlock(void *ptr) template size_t DataSegment::infoThread(FILE * os, int level, uint32_t thread, SizeClassT sct) const { - typedef CallGraph CallGraphLT; + using CallGraphLT = CallGraph; + bool allThreads(thread == 0); size_t usedCount(0); size_t checkedCount(0); size_t allocatedCount(0); size_t notAccounted(0); size_t invalidCallStacks(0); - std::unique_ptr callGraph(new CallGraphLT); - for(size_t i=0; i < NELEMS(_blockList); ) { + std::unique_ptr callGraph = std::make_unique(); + for (size_t i=0; i < NELEMS(_blockList); ) { const BlockT & b = _blockList[i]; SizeClassT sc = b.sizeClass(); if (sc == sct) { @@ -182,7 +183,7 @@ size_t DataSegment::infoThread(FILE * os, int level, uint32_t thre checkedCount++; if (mem.allocated()) { allocatedCount++; - if (mem.threadId() == thread) { + if (allThreads || (mem.threadId() == thread)) { usedCount++; if (usedCount < _allocs2Show) { mem.info(os, level); @@ -210,8 +211,9 @@ size_t DataSegment::infoThread(FILE * os, int level, uint32_t thre i++; } } - fprintf(os, "\nCallTree(Checked=%ld, GlobalAlloc=%ld(%ld%%)," "ByMeAlloc=%ld(%2.2f%%) NotAccountedDue2FullGraph=%ld InvalidCallStacks=%ld:\n", + fprintf(os, "\nCallTree(Checked=%ld, GlobalAlloc=%ld(%ld%%)," "By%sAlloc=%ld(%2.2f%%) NotAccountedDue2FullGraph=%ld InvalidCallStacks=%ld:\n", checkedCount, allocatedCount, checkedCount ? allocatedCount*100/checkedCount : 0, + allThreads ? "Us" : "Me", usedCount, checkedCount ? static_cast(usedCount*100)/checkedCount : 0.0, notAccounted, invalidCallStacks); if ( ! callGraph->empty()) { Aggregator agg; diff --git a/vespamalloc/src/vespamalloc/malloc/threadlist.hpp b/vespamalloc/src/vespamalloc/malloc/threadlist.hpp index a9a3a351899..aa514643265 100644 --- a/vespamalloc/src/vespamalloc/malloc/threadlist.hpp +++ b/vespamalloc/src/vespamalloc/malloc/threadlist.hpp @@ -29,16 +29,26 @@ void ThreadListT::info(FILE * os, size_t level) const ThreadPool & thread = _threadVector[i]; if (thread.isActive()) { activeThreads++; + peakThreads = i; + } + } + fprintf(os, "#%ld active threads. Peak threads #%ld\n", activeThreads, peakThreads); + if ((level > 1) && ! ThreadStatT::isDummy()) { + for (SizeClassT sc(0); sc < NUM_SIZE_CLASSES; sc++) { + _allocPool.dataSegment().infoThread(os, level, 0, sc); + } + } + for (size_t i(0); i < getMaxNumThreads(); i++) { + const ThreadPool & thread = _threadVector[i]; + if (thread.isActive()) { if ( ! ThreadStatT::isDummy()) { fprintf(os, "Thread #%ld = pid # %d\n", i, thread.osThreadId()); if (thread.isUsed()) { thread.info(os, level, _allocPool.dataSegment()); } } - peakThreads = i; } } - fprintf(os, "#%ld active threads. Peak threads #%ld\n", activeThreads, peakThreads); } template diff --git a/vespamalloc/src/vespamalloc/malloc/threadpool.h b/vespamalloc/src/vespamalloc/malloc/threadpool.h index 4b3483c45bc..792cf2c8108 100644 --- a/vespamalloc/src/vespamalloc/malloc/threadpool.h +++ b/vespamalloc/src/vespamalloc/malloc/threadpool.h @@ -69,6 +69,7 @@ private: ThreadStatT _stat[NUM_SIZE_CLASSES]; uint32_t _threadId; std::atomic _osThreadId; + static SizeClassT _alwaysReuseSCLimit __attribute__((visibility("hidden"))); static size_t _threadCacheLimit __attribute__((visibility("hidden"))); }; diff --git a/vespamalloc/src/vespamalloc/malloc/threadpool.hpp b/vespamalloc/src/vespamalloc/malloc/threadpool.hpp index 2d3c020578b..4b5277a6396 100644 --- a/vespamalloc/src/vespamalloc/malloc/threadpool.hpp +++ b/vespamalloc/src/vespamalloc/malloc/threadpool.hpp @@ -28,7 +28,7 @@ void ThreadPoolT::info(FILE * os, size_t level, const } } } - if (level > 1) { + if (level > 2) { fprintf(os, "BlockList:%ld,%ld,%ld\n", NELEMS(_stat), sizeof(_stat), sizeof(_stat[0])); size_t sum(0), sumLocal(0); for (size_t i=0; i < NELEMS(_stat); i++) { -- cgit v1.2.3