From d6b3513aabbf1f34eb5232517cb612ca0b7cbc9d Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 13 May 2021 22:11:44 +0200 Subject: [PATCH] Profiler: Let the user ignore context switches Now that the profiling timer is independent from the scheduler the user will get quite a few CPU samples from "within" the scheduler. These events are less useful when just profiling a user-mode process rather than the whole system. This patch adds an option to Profiler to hide these events. --- Userland/DevTools/Profiler/Profile.cpp | 15 +++++++++++++++ Userland/DevTools/Profiler/Profile.h | 4 ++++ Userland/DevTools/Profiler/TimelineTrack.cpp | 6 ++++++ Userland/DevTools/Profiler/main.cpp | 9 +++++++++ 4 files changed, 34 insertions(+) diff --git a/Userland/DevTools/Profiler/Profile.cpp b/Userland/DevTools/Profiler/Profile.cpp index fa06bcebe3..35fb6814ff 100644 --- a/Userland/DevTools/Profiler/Profile.cpp +++ b/Userland/DevTools/Profiler/Profile.cpp @@ -99,6 +99,12 @@ void Profile::rebuild_tree() if (!process_filter_contains(event.pid, event.timestamp)) continue; + if (!m_show_scheduler && !event.frames.is_empty()) { + auto top_frame = event.frames[event.frames.size() - 1]; + if (top_frame.symbol == "Kernel::Scheduler::yield()") + continue; + } + m_filtered_event_indices.append(event_index); if (event.type == "malloc" && !live_allocations.contains(event.ptr)) @@ -450,6 +456,15 @@ void Profile::set_show_percentages(bool show_percentages) m_show_percentages = show_percentages; } +void Profile::set_show_scheduler(bool show_scheduler) +{ + if (m_show_scheduler == show_scheduler) + return; + m_show_scheduler = show_scheduler; + // FIXME: This only works when kernel symbols are available + rebuild_tree(); +} + void Profile::set_disassembly_index(const GUI::ModelIndex& index) { if (m_disassembly_index == index) diff --git a/Userland/DevTools/Profiler/Profile.h b/Userland/DevTools/Profiler/Profile.h index cffc5f91f1..3aec06d1e8 100644 --- a/Userland/DevTools/Profiler/Profile.h +++ b/Userland/DevTools/Profiler/Profile.h @@ -196,6 +196,9 @@ public: bool show_percentages() const { return m_show_percentages; } void set_show_percentages(bool); + bool show_scheduler() const { return m_show_scheduler; } + void set_show_scheduler(bool); + const Vector& processes() const { return m_processes; } template @@ -240,6 +243,7 @@ private: bool m_inverted { false }; bool m_show_top_functions { false }; bool m_show_percentages { false }; + bool m_show_scheduler { true }; }; } diff --git a/Userland/DevTools/Profiler/TimelineTrack.cpp b/Userland/DevTools/Profiler/TimelineTrack.cpp index cebb1be495..5b29bd66b0 100644 --- a/Userland/DevTools/Profiler/TimelineTrack.cpp +++ b/Userland/DevTools/Profiler/TimelineTrack.cpp @@ -71,6 +71,12 @@ void TimelineTrack::paint_event(GUI::PaintEvent& event) if (!m_process.valid_at(event.timestamp)) continue; + if (!m_profile.show_scheduler() && !event.frames.is_empty()) { + auto top_frame = event.frames[event.frames.size() - 1]; + if (top_frame.symbol == "Kernel::Scheduler::yield()") + continue; + } + auto& histogram = event.in_kernel ? kernel_histogram : usermode_histogram; histogram.insert(clamp_timestamp(event.timestamp), 1); } diff --git a/Userland/DevTools/Profiler/main.cpp b/Userland/DevTools/Profiler/main.cpp index 83eb37cdcb..d94ee2e18a 100644 --- a/Userland/DevTools/Profiler/main.cpp +++ b/Userland/DevTools/Profiler/main.cpp @@ -209,6 +209,15 @@ int main(int argc, char** argv) percent_action->set_checked(false); view_menu.add_action(percent_action); + auto scheduler_action = GUI::Action::create_checkable("Show &Context Switches", { Mod_Ctrl, Key_C }, [&](auto& action) { + profile->set_show_scheduler(action.is_checked()); + tree_view.update(); + disassembly_view.update(); + timeline_container.update(); + }); + scheduler_action->set_checked(true); + view_menu.add_action(scheduler_action); + auto& help_menu = menubar->add_menu("&Help"); help_menu.add_action(GUI::CommonActions::make_help_action([](auto&) { Desktop::Launcher::open(URL::create_with_file_protocol("/usr/share/man/man1/Profiler.md"), "/bin/Help");