Explorar o código

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.
Gunnar Beutner %!s(int64=4) %!d(string=hai) anos
pai
achega
d6b3513aab

+ 15 - 0
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)

+ 4 - 0
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<Process>& processes() const { return m_processes; }
 
     template<typename Callback>
@@ -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 };
 };
 
 }

+ 6 - 0
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);
     }

+ 9 - 0
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");