aboutsummaryrefslogtreecommitdiffstats
path: root/vespamalloc
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-12-17 12:34:00 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-12-17 12:34:00 +0000
commit2eea2ff7cb37c926222f023e6e587d0c5a6fbbc1 (patch)
tree5f62207e0719e265275a1641febc8eb7c840d2ff /vespamalloc
parent8c379d0f7b7f670666abae9ee9e3b9516a091835 (diff)
- 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.
Diffstat (limited to 'vespamalloc')
-rw-r--r--vespamalloc/src/vespamalloc/malloc/datasegment.hpp12
-rw-r--r--vespamalloc/src/vespamalloc/malloc/threadlist.hpp14
-rw-r--r--vespamalloc/src/vespamalloc/malloc/threadpool.h1
-rw-r--r--vespamalloc/src/vespamalloc/malloc/threadpool.hpp2
4 files changed, 21 insertions, 8 deletions
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<MemBlockPtrT>::returnBlock(void *ptr)
template<typename MemBlockPtrT>
size_t DataSegment<MemBlockPtrT>::infoThread(FILE * os, int level, uint32_t thread, SizeClassT sct) const
{
- typedef CallGraph<typename MemBlockPtrT::Stack, 0x10000, Index> CallGraphLT;
+ using CallGraphLT = CallGraph<typename MemBlockPtrT::Stack, 0x10000, Index>;
+ 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<CallGraphLT> callGraph(new CallGraphLT);
- for(size_t i=0; i < NELEMS(_blockList); ) {
+ std::unique_ptr<CallGraphLT> callGraph = std::make_unique<CallGraphLT>();
+ 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<MemBlockPtrT>::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<MemBlockPtrT>::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<double>(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<MemBlockPtrT, ThreadStatT>::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 <typename MemBlockPtrT, typename ThreadStatT>
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<ssize_t> _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<MemBlockPtrT, ThreadStatT>::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++) {