From adb80c33ec64dd12b65b4655694f56cf385ad45d Mon Sep 17 00:00:00 2001 From: Marcus Nilsson Date: Sat, 26 Jun 2021 21:31:31 +0200 Subject: [PATCH] Utilities/top: Add sort-by and delay-time options Add optional arguments to top so that the user can choose which field to sort by and change the update frequency. --- Userland/Utilities/top.cpp | 91 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 4 deletions(-) diff --git a/Userland/Utilities/top.cpp b/Userland/Utilities/top.cpp index adce57d9b4..7a50fd8255 100644 --- a/Userland/Utilities/top.cpp +++ b/Userland/Utilities/top.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -19,6 +20,23 @@ #include #include +struct TopOption { + enum class SortBy { + Pid, + Tid, + Priority, + UserName, + State, + Virt, + Phys, + Cpu, + Name + }; + + SortBy sort_by { SortBy::Cpu }; + int delay_time { 1 }; +}; + struct ThreadData { int tid; pid_t pid; @@ -114,7 +132,49 @@ static Snapshot get_snapshot() static bool g_window_size_changed = true; static struct winsize g_window_size; -int main(int, char**) +static void parse_args(int argc, char** argv, TopOption& top_option) +{ + Core::ArgsParser::Option sort_by_option { + true, + "Sort by field [pid, tid, pri, user, state, virt, phys, cpu, name]", + "sort-by", + 's', + nullptr, + [&top_option](const char* s) { + StringView sort_by_option { s }; + if (sort_by_option == "pid"sv) + top_option.sort_by = TopOption::SortBy::Pid; + else if (sort_by_option == "tid"sv) + top_option.sort_by = TopOption::SortBy::Tid; + else if (sort_by_option == "pri"sv) + top_option.sort_by = TopOption::SortBy::Priority; + else if (sort_by_option == "user"sv) + top_option.sort_by = TopOption::SortBy::UserName; + else if (sort_by_option == "state"sv) + top_option.sort_by = TopOption::SortBy::State; + else if (sort_by_option == "virt"sv) + top_option.sort_by = TopOption::SortBy::Virt; + else if (sort_by_option == "phys"sv) + top_option.sort_by = TopOption::SortBy::Phys; + else if (sort_by_option == "cpu"sv) + top_option.sort_by = TopOption::SortBy::Cpu; + else if (sort_by_option == "name"sv) + top_option.sort_by = TopOption::SortBy::Name; + else + return false; + return true; + } + }; + + Core::ArgsParser args_parser; + + args_parser.set_general_help("Display information about processes"); + args_parser.add_option(top_option.delay_time, "Delay time interval in seconds", "delay-time", 'd', nullptr); + args_parser.add_option(move(sort_by_option)); + args_parser.parse(argc, argv); +} + +int main(int argc, char** argv) { if (pledge("stdio rpath tty sigaction ", nullptr) < 0) { perror("pledge"); @@ -142,6 +202,9 @@ int main(int, char**) return 1; } + TopOption top_option; + parse_args(argc, argv, top_option); + Vector threads; auto prev = get_snapshot(); usleep(10000); @@ -185,8 +248,28 @@ int main(int, char**) threads.append(&it.value); } - quick_sort(threads, [](auto* p1, auto* p2) { - return p2->times_scheduled_since_prev < p1->times_scheduled_since_prev; + quick_sort(threads, [&top_option](auto* p1, auto* p2) { + switch (top_option.sort_by) { + case TopOption::SortBy::Pid: + return p2->pid > p1->pid; + case TopOption::SortBy::Tid: + return p2->tid > p1->tid; + case TopOption::SortBy::Priority: + return p2->priority > p1->priority; + case TopOption::SortBy::UserName: + return p2->username > p1->username; + case TopOption::SortBy::State: + return p2->state > p1->state; + case TopOption::SortBy::Virt: + return p2->amount_virtual < p1->amount_virtual; + case TopOption::SortBy::Phys: + return p2->amount_resident < p1->amount_resident; + case TopOption::SortBy::Name: + return p2->name > p1->name; + case TopOption::SortBy::Cpu: + default: + return p2->times_scheduled_since_prev < p1->times_scheduled_since_prev; + } }); int row = 0; @@ -211,7 +294,7 @@ int main(int, char**) } threads.clear_with_capacity(); prev = move(current); - sleep(1); + sleep(top_option.delay_time); } return 0; }