From c534f176bc1d0f2d89c90e9e7320e4782eaba833 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 13 May 2021 14:29:15 +0200 Subject: Profiler: Add histogram for sample counts Previously Profiler would use the stack depth to draw the timeline graphs. This is not an accurate representation of whether a thread is "busy" or not. Instead this updates the timelines to use the sample count. --- Userland/DevTools/Profiler/TimelineTrack.cpp | 40 +++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'Userland/DevTools/Profiler/TimelineTrack.cpp') diff --git a/Userland/DevTools/Profiler/TimelineTrack.cpp b/Userland/DevTools/Profiler/TimelineTrack.cpp index 7a09d54db0..cebb1be495 100644 --- a/Userland/DevTools/Profiler/TimelineTrack.cpp +++ b/Userland/DevTools/Profiler/TimelineTrack.cpp @@ -5,6 +5,7 @@ */ #include "TimelineTrack.h" +#include "Histogram.h" #include "Profile.h" #include "TimelineView.h" #include @@ -57,7 +58,11 @@ void TimelineTrack::paint_event(GUI::PaintEvent& event) }; float column_width = (float)frame_inner_rect().width() / (float)m_profile.length_in_ms(); - float frame_height = (float)frame_inner_rect().height() / (float)m_profile.deepest_stack_depth(); + size_t columns = frame_inner_rect().width() / column_width; + + Histogram kernel_histogram { start_of_trace, end_of_trace, columns }; + Histogram usermode_histogram { start_of_trace, end_of_trace, columns }; + auto bucket_count = kernel_histogram.size(); for (auto& event : m_profile.events()) { if (event.pid != m_process.pid) @@ -66,16 +71,37 @@ void TimelineTrack::paint_event(GUI::PaintEvent& event) if (!m_process.valid_at(event.timestamp)) continue; - u64 t = clamp_timestamp(event.timestamp) - start_of_trace; + auto& histogram = event.in_kernel ? kernel_histogram : usermode_histogram; + histogram.insert(clamp_timestamp(event.timestamp), 1); + } + + decltype(kernel_histogram.at(0)) max_value = 0; + for (size_t bucket = 0; bucket < bucket_count; bucket++) { + auto value = kernel_histogram.at(bucket) + usermode_histogram.at(bucket); + if (value > max_value) + max_value = value; + } + + float frame_height = (float)frame_inner_rect().height() / (float)max_value; + + for (size_t bucket = 0; bucket < bucket_count; bucket++) { + auto kernel_value = kernel_histogram.at(bucket); + auto usermode_value = usermode_histogram.at(bucket); + if (kernel_value + usermode_value == 0) + continue; + + auto t = bucket; + int x = (int)((float)t * column_width); int cw = max(1, (int)column_width); - int column_height = frame_inner_rect().height() - (int)((float)event.frames.size() * frame_height); + int kernel_column_height = frame_inner_rect().height() - (int)((float)kernel_value * frame_height); + int usermode_column_height = frame_inner_rect().height() - (int)((float)(kernel_value + usermode_value) * frame_height); - bool in_kernel = event.in_kernel; - Color color = in_kernel ? Color::from_rgb(0xc25e5a) : Color::from_rgb(0x5a65c2); - for (int i = 1; i <= cw; ++i) - painter.draw_line({ x + i, frame_thickness() + column_height }, { x + i, height() - frame_thickness() * 2 }, color); + constexpr auto kernel_color = Color::from_rgb(0xc25e5a); + constexpr auto usermode_color = Color::from_rgb(0x5a65c2); + painter.fill_rect({ x, frame_thickness() + usermode_column_height, cw, height() - frame_thickness() * 2 }, usermode_color); + painter.fill_rect({ x, frame_thickness() + kernel_column_height, cw, height() - frame_thickness() * 2 }, kernel_color); } u64 normalized_start_time = clamp_timestamp(min(m_view.select_start_time(), m_view.select_end_time())); -- cgit v1.2.3