diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2020-12-17 14:47:45 +0000 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2020-12-17 14:47:45 +0000 |
commit | f04619047cc7da4aa022da9d4de08c2f202aa0bc (patch) | |
tree | 1f7351baacafec7d580d7cb90df799e82822df2b /vespamalloc | |
parent | b208f3ba04c121d03517c1f0ddc3af92934ac264 (diff) |
- Dump histogram on single line and order with most active thread first.
- Skip thread and size classes with no allocations.
- Use the unique thread id, instead of index among active threads.
Diffstat (limited to 'vespamalloc')
-rw-r--r-- | vespamalloc/src/vespamalloc/malloc/datasegment.hpp | 32 | ||||
-rw-r--r-- | vespamalloc/src/vespamalloc/malloc/threadlist.hpp | 2 | ||||
-rw-r--r-- | vespamalloc/src/vespamalloc/malloc/threadpool.h | 2 |
3 files changed, 30 insertions, 6 deletions
diff --git a/vespamalloc/src/vespamalloc/malloc/datasegment.hpp b/vespamalloc/src/vespamalloc/malloc/datasegment.hpp index 09c47ec8ae7..355c9e9daad 100644 --- a/vespamalloc/src/vespamalloc/malloc/datasegment.hpp +++ b/vespamalloc/src/vespamalloc/malloc/datasegment.hpp @@ -224,8 +224,12 @@ size_t DataSegment<MemBlockPtrT>::infoThread(FILE * os, int level, uint32_t thre i++; } } - 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, + if (checkedCount == 0) { + return 0; + } + + fprintf(os, "\nCallTree SC %d(Checked=%ld, GlobalAlloc=%ld(%ld%%)," "By%sAlloc=%ld(%2.2f%%) NotAccountedDue2FullGraph=%ld InvalidCallStacks=%ld:\n", + sct, 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()) { @@ -237,12 +241,32 @@ size_t DataSegment<MemBlockPtrT>::infoThread(FILE * os, int level, uint32_t thre fprintf(os, "%s\n", ost.c_str()); } if ( !threadHistogram.empty()) { - fprintf(os, "Histogram"); + uint32_t nonZeroCount(0); for (uint32_t i(0); i < threadHistogram.size(); i++) { if (threadHistogram[i] > 0) { - fprintf(os, "\nThread %u: %u", i, threadHistogram[i]); + nonZeroCount++; + } + } + using Pair = std::pair<uint32_t, uint32_t>; + std::vector<Pair> orderedHisto; + orderedHisto.reserve(nonZeroCount); + for (uint32_t i(0); i < threadHistogram.size(); i++) { + if (threadHistogram[i] > 0) { + orderedHisto.emplace_back(i, threadHistogram[i]); + } + } + std::sort(orderedHisto.begin(), orderedHisto.end(), [](const Pair & a, const Pair & b) { return a.second > b.second;}); + fprintf(os, "ThreadHistogram SC %d: [", sct); + + bool first(true); + for (const Pair & entry : orderedHisto) { + if ( !first) { + fprintf(os, ", "); } + fprintf(os, "{%u, %u}", entry.first, entry.second); + first = false; } + fprintf(os, " ]"); } return usedCount; } diff --git a/vespamalloc/src/vespamalloc/malloc/threadlist.hpp b/vespamalloc/src/vespamalloc/malloc/threadlist.hpp index 12afc8107b3..24f9fc4388c 100644 --- a/vespamalloc/src/vespamalloc/malloc/threadlist.hpp +++ b/vespamalloc/src/vespamalloc/malloc/threadlist.hpp @@ -43,8 +43,8 @@ void ThreadListT<MemBlockPtrT, ThreadStatT>::info(FILE * os, size_t level) const ThreadPool & thread = _threadVector[i]; if (thread.isActive()) { if ( ! ThreadStatT::isDummy()) { - fprintf(os, "Thread #%ld = pid # %d\n", i, thread.osThreadId()); if (thread.isUsed()) { + fprintf(os, "Thread #%u = pid # %d\n", thread.threadId(), thread.osThreadId()); thread.info(os, level, _allocPool.dataSegment()); } } diff --git a/vespamalloc/src/vespamalloc/malloc/threadpool.h b/vespamalloc/src/vespamalloc/malloc/threadpool.h index 792cf2c8108..f719df026fe 100644 --- a/vespamalloc/src/vespamalloc/malloc/threadpool.h +++ b/vespamalloc/src/vespamalloc/malloc/threadpool.h @@ -34,6 +34,7 @@ public: */ bool isUsed() const; int osThreadId() const { return _osThreadId; } + uint32_t threadId() const { return _threadId; } void quit() { _osThreadId = 0; } // Implicit memory barrier void init(int thrId); static void setParams(size_t alwayReuseLimit, size_t threadCacheLimit); @@ -42,7 +43,6 @@ private: bool hasActuallyBeenUsed() const; ThreadPoolT(const ThreadPoolT & rhs); ThreadPoolT & operator =(const ThreadPoolT & rhs); - uint32_t threadId() const { return _threadId; } void setThreadId(uint32_t th) { _threadId = th; } class AllocFree { public: |