aboutsummaryrefslogtreecommitdiffstats
path: root/vespamalloc
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@yahoo-inc.com>2020-12-17 14:47:45 +0000
committerHenning Baldersheim <balder@yahoo-inc.com>2020-12-17 14:47:45 +0000
commitf04619047cc7da4aa022da9d4de08c2f202aa0bc (patch)
tree1f7351baacafec7d580d7cb90df799e82822df2b /vespamalloc
parentb208f3ba04c121d03517c1f0ddc3af92934ac264 (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.hpp32
-rw-r--r--vespamalloc/src/vespamalloc/malloc/threadlist.hpp2
-rw-r--r--vespamalloc/src/vespamalloc/malloc/threadpool.h2
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: