summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorMarcus Nilsson <brainbomb@gmail.com>2021-06-26 21:31:31 +0200
committerAndreas Kling <kling@serenityos.org>2021-06-28 16:38:44 +0200
commitadb80c33ec64dd12b65b4655694f56cf385ad45d (patch)
treea6c4af0a199ef42e837ec86c02539bbcb71a2a7f /Userland
parent55fa2329de95eec80a8d4484e68562a11bd23524 (diff)
downloadserenity-adb80c33ec64dd12b65b4655694f56cf385ad45d.zip
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.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Utilities/top.cpp91
1 files 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 <AK/QuickSort.h>
#include <AK/String.h>
#include <AK/Vector.h>
+#include <LibCore/ArgsParser.h>
#include <LibCore/ProcessStatisticsReader.h>
#include <fcntl.h>
#include <signal.h>
@@ -19,6 +20,23 @@
#include <sys/ioctl.h>
#include <unistd.h>
+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<ThreadData*> 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;
}