diff options
author | Gunnar Beutner <gbeutner@serenityos.org> | 2021-05-08 01:33:43 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-08 09:53:53 +0200 |
commit | 210d2d270d3a71e215350b1c78b1e9f0f614d8cf (patch) | |
tree | 1d96afb0214d03a019e75a523c15bc2765da7ba6 | |
parent | 325d9445fdf3f0239abca2fecac7e7ee6a973762 (diff) | |
download | serenity-210d2d270d3a71e215350b1c78b1e9f0f614d8cf.zip |
Profiler: Let the user select more than one process
-rw-r--r-- | Userland/DevTools/Profiler/Profile.cpp | 35 | ||||
-rw-r--r-- | Userland/DevTools/Profiler/Profile.h | 21 | ||||
-rw-r--r-- | Userland/DevTools/Profiler/main.cpp | 10 |
3 files changed, 46 insertions, 20 deletions
diff --git a/Userland/DevTools/Profiler/Profile.cpp b/Userland/DevTools/Profiler/Profile.cpp index 948ac92bf4..bd49eade17 100644 --- a/Userland/DevTools/Profiler/Profile.cpp +++ b/Userland/DevTools/Profiler/Profile.cpp @@ -376,26 +376,39 @@ void Profile::clear_timestamp_filter_range() m_samples_model->update(); } -void Profile::set_process_filter(pid_t pid, u64 start_valid, u64 end_valid) +void Profile::add_process_filter(pid_t pid, u64 start_valid, u64 end_valid) { - if (m_has_process_filter && m_process_filter_pid == pid && m_process_filter_start_valid == start_valid && m_process_filter_end_valid == end_valid) + auto filter = ProcessFilter { pid, start_valid, end_valid }; + if (m_process_filters.contains_slow(filter)) return; - m_has_process_filter = true; + m_process_filters.append(move(filter)); - m_process_filter_pid = pid; - m_process_filter_start_valid = start_valid; - m_process_filter_end_valid = end_valid; + rebuild_tree(); + if (m_disassembly_model) + m_disassembly_model->update(); + m_samples_model->update(); +} + +void Profile::remove_process_filter(pid_t pid, u64 start_valid, u64 end_valid) +{ + auto filter = ProcessFilter { pid, start_valid, end_valid }; + if (!m_process_filters.contains_slow(filter)) + return; + m_process_filters.remove_first_matching([&filter](ProcessFilter const& other_filter) { + return other_filter == filter; + }); rebuild_tree(); if (m_disassembly_model) m_disassembly_model->update(); m_samples_model->update(); } + void Profile::clear_process_filter() { - if (!m_has_process_filter) + if (m_process_filters.is_empty()) return; - m_has_process_filter = false; + m_process_filters.clear(); rebuild_tree(); if (m_disassembly_model) m_disassembly_model->update(); @@ -407,7 +420,11 @@ bool Profile::process_filter_contains(pid_t pid, u32 timestamp) if (!has_process_filter()) return true; - return (pid == m_process_filter_pid && timestamp >= m_process_filter_start_valid && timestamp <= m_process_filter_end_valid); + for (auto const& process_filter : m_process_filters) + if (pid == process_filter.pid && timestamp >= process_filter.start_valid && timestamp <= process_filter.end_valid) + return true; + + return false; } void Profile::set_inverted(bool inverted) diff --git a/Userland/DevTools/Profiler/Profile.h b/Userland/DevTools/Profiler/Profile.h index 4008884b92..cffc5f91f1 100644 --- a/Userland/DevTools/Profiler/Profile.h +++ b/Userland/DevTools/Profiler/Profile.h @@ -116,6 +116,17 @@ private: Bitmap m_seen_events; }; +struct ProcessFilter { + pid_t pid { 0 }; + u64 start_valid { 0 }; + u64 end_valid { 0 }; + + bool operator==(ProcessFilter const& rhs) const + { + return pid == rhs.pid && start_valid == rhs.start_valid && end_valid == rhs.end_valid; + } +}; + class Profile { public: static Result<NonnullOwnPtr<Profile>, String> load_from_perfcore_file(const StringView& path); @@ -171,9 +182,10 @@ public: void clear_timestamp_filter_range(); bool has_timestamp_filter_range() const { return m_has_timestamp_filter_range; } - void set_process_filter(pid_t pid, u64 start_valid, u64 end_valid); + void add_process_filter(pid_t pid, u64 start_valid, u64 end_valid); + void remove_process_filter(pid_t pid, u64 start_valid, u64 end_valid); void clear_process_filter(); - bool has_process_filter() const { return m_has_process_filter; } + bool has_process_filter() const { return !m_process_filters.is_empty(); } bool process_filter_contains(pid_t pid, u32 timestamp); bool is_inverted() const { return m_inverted; } @@ -222,10 +234,7 @@ private: u64 m_timestamp_filter_range_start { 0 }; u64 m_timestamp_filter_range_end { 0 }; - bool m_has_process_filter { false }; - pid_t m_process_filter_pid { 0 }; - u64 m_process_filter_start_valid { 0 }; - u64 m_process_filter_end_valid { 0 }; + Vector<ProcessFilter> m_process_filters; u32 m_deepest_stack_depth { 0 }; bool m_inverted { false }; diff --git a/Userland/DevTools/Profiler/main.cpp b/Userland/DevTools/Profiler/main.cpp index 3b322f008a..83eb37cdcb 100644 --- a/Userland/DevTools/Profiler/main.cpp +++ b/Userland/DevTools/Profiler/main.cpp @@ -110,11 +110,11 @@ int main(int argc, char** argv) auto& timeline_header = timeline_header_container->add<TimelineHeader>(*profile, process); timeline_header.set_shrink_to_fit(true); timeline_header.on_selection_change = [&](bool selected) { - if (selected) { - auto end_valid = process.end_valid == 0 ? profile->last_timestamp() : process.end_valid; - profile->set_process_filter(process.pid, process.start_valid, end_valid); - } else - profile->clear_process_filter(); + auto end_valid = process.end_valid == 0 ? profile->last_timestamp() : process.end_valid; + if (selected) + profile->add_process_filter(process.pid, process.start_valid, end_valid); + else + profile->remove_process_filter(process.pid, process.start_valid, end_valid); timeline_header_container->for_each_child_widget([](auto& other_timeline_header) { static_cast<TimelineHeader&>(other_timeline_header).update_selection(); |