1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:07:35 +00:00

LibCore: Make ProcessStatisticsReader return results in a Vector

The HashMap API was overkill and made using this less ergonomic than
it should be.
This commit is contained in:
Andreas Kling 2021-05-23 11:08:32 +02:00
parent a345a1f4a1
commit a1e133cc6b
12 changed files with 79 additions and 83 deletions

View file

@ -130,8 +130,8 @@ private:
return false; return false;
for (auto& it : all_processes.value()) { for (auto& it : all_processes.value()) {
for (auto& jt : it.value.threads) { for (auto& jt : it.threads) {
if (it.value.pid == 0) if (it.pid == 0)
idle += jt.ticks_user + jt.ticks_kernel; idle += jt.ticks_user + jt.ticks_kernel;
else else
busy += jt.ticks_user + jt.ticks_kernel; busy += jt.ticks_user + jt.ticks_kernel;

View file

@ -328,14 +328,14 @@ void ProcessModel::update()
HashTable<int> live_tids; HashTable<int> live_tids;
u64 sum_ticks_scheduled = 0, sum_ticks_scheduled_kernel = 0; u64 sum_ticks_scheduled = 0, sum_ticks_scheduled_kernel = 0;
if (all_processes.has_value()) { if (all_processes.has_value()) {
for (auto& it : all_processes.value()) { for (auto& process : all_processes.value()) {
for (auto& thread : it.value.threads) { for (auto& thread : process.threads) {
ThreadState state; ThreadState state;
state.kernel = it.value.kernel; state.kernel = process.kernel;
state.pid = it.value.pid; state.pid = process.pid;
state.user = it.value.username; state.user = process.username;
state.pledge = it.value.pledge; state.pledge = process.pledge;
state.veil = it.value.veil; state.veil = process.veil;
state.syscall_count = thread.syscall_count; state.syscall_count = thread.syscall_count;
state.inode_faults = thread.inode_faults; state.inode_faults = thread.inode_faults;
state.zero_faults = thread.zero_faults; state.zero_faults = thread.zero_faults;
@ -346,20 +346,20 @@ void ProcessModel::update()
state.ipv4_socket_write_bytes = thread.ipv4_socket_write_bytes; state.ipv4_socket_write_bytes = thread.ipv4_socket_write_bytes;
state.file_read_bytes = thread.file_read_bytes; state.file_read_bytes = thread.file_read_bytes;
state.file_write_bytes = thread.file_write_bytes; state.file_write_bytes = thread.file_write_bytes;
state.amount_virtual = it.value.amount_virtual; state.amount_virtual = process.amount_virtual;
state.amount_resident = it.value.amount_resident; state.amount_resident = process.amount_resident;
state.amount_dirty_private = it.value.amount_dirty_private; state.amount_dirty_private = process.amount_dirty_private;
state.amount_clean_inode = it.value.amount_clean_inode; state.amount_clean_inode = process.amount_clean_inode;
state.amount_purgeable_volatile = it.value.amount_purgeable_volatile; state.amount_purgeable_volatile = process.amount_purgeable_volatile;
state.amount_purgeable_nonvolatile = it.value.amount_purgeable_nonvolatile; state.amount_purgeable_nonvolatile = process.amount_purgeable_nonvolatile;
state.name = thread.name; state.name = thread.name;
state.executable = it.value.executable; state.executable = process.executable;
state.ppid = it.value.ppid; state.ppid = process.ppid;
state.tid = thread.tid; state.tid = thread.tid;
state.pgid = it.value.pgid; state.pgid = process.pgid;
state.sid = it.value.sid; state.sid = process.sid;
state.ticks_user = thread.ticks_user; state.ticks_user = thread.ticks_user;
state.ticks_kernel = thread.ticks_kernel; state.ticks_kernel = thread.ticks_kernel;
state.cpu = thread.cpu; state.cpu = thread.cpu;

View file

@ -270,8 +270,8 @@ bool generate_profile(pid_t& pid)
auto all_processes = Core::ProcessStatisticsReader::get_all(); auto all_processes = Core::ProcessStatisticsReader::get_all();
if (all_processes.has_value()) { if (all_processes.has_value()) {
if (auto it = all_processes.value().find(pid); it != all_processes.value().end()) if (auto it = all_processes.value().find_if([&](auto& entry) { return entry.pid == pid; }); it != all_processes.value().end())
process_name = it->value.name; process_name = it->name;
else else
process_name = "(unknown)"; process_name = "(unknown)";
} else { } else {

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -17,7 +17,7 @@ namespace Core {
HashMap<uid_t, String> ProcessStatisticsReader::s_usernames; HashMap<uid_t, String> ProcessStatisticsReader::s_usernames;
Optional<HashMap<pid_t, Core::ProcessStatistics>> ProcessStatisticsReader::get_all(RefPtr<Core::File>& proc_all_file) Optional<Vector<Core::ProcessStatistics>> ProcessStatisticsReader::get_all(RefPtr<Core::File>& proc_all_file)
{ {
if (proc_all_file) { if (proc_all_file) {
if (!proc_all_file->seek(0, Core::SeekMode::SetPosition)) { if (!proc_all_file->seek(0, Core::SeekMode::SetPosition)) {
@ -32,7 +32,7 @@ Optional<HashMap<pid_t, Core::ProcessStatistics>> ProcessStatisticsReader::get_a
} }
} }
HashMap<pid_t, Core::ProcessStatistics> map; Vector<Core::ProcessStatistics> processes;
auto file_contents = proc_all_file->read_all(); auto file_contents = proc_all_file->read_all();
auto json = JsonValue::from_string(file_contents); auto json = JsonValue::from_string(file_contents);
@ -93,13 +93,13 @@ Optional<HashMap<pid_t, Core::ProcessStatistics>> ProcessStatisticsReader::get_a
// and synthetic data last // and synthetic data last
process.username = username_from_uid(process.uid); process.username = username_from_uid(process.uid);
map.set(process.pid, process); processes.append(move(process));
}); });
return map; return processes;
} }
Optional<HashMap<pid_t, Core::ProcessStatistics>> ProcessStatisticsReader::get_all() Optional<Vector<Core::ProcessStatistics>> ProcessStatisticsReader::get_all()
{ {
RefPtr<Core::File> proc_all_file; RefPtr<Core::File> proc_all_file;
return get_all(proc_all_file); return get_all(proc_all_file);

View file

@ -1,12 +1,11 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#pragma once #pragma once
#include <AK/HashMap.h>
#include <AK/String.h> #include <AK/String.h>
#include <LibCore/File.h> #include <LibCore/File.h>
#include <unistd.h> #include <unistd.h>
@ -67,8 +66,8 @@ struct ProcessStatistics {
class ProcessStatisticsReader { class ProcessStatisticsReader {
public: public:
static Optional<HashMap<pid_t, Core::ProcessStatistics>> get_all(RefPtr<Core::File>&); static Optional<Vector<Core::ProcessStatistics>> get_all(RefPtr<Core::File>&);
static Optional<HashMap<pid_t, Core::ProcessStatistics>> get_all(); static Optional<Vector<Core::ProcessStatistics>> get_all();
private: private:
static String username_from_uid(uid_t); static String username_from_uid(uid_t);

View file

@ -27,15 +27,14 @@ void RunningProcessesModel::update()
{ {
m_processes.clear(); m_processes.clear();
Core::ProcessStatisticsReader reader; auto processes = Core::ProcessStatisticsReader::get_all();
auto processes = reader.get_all();
if (processes.has_value()) { if (processes.has_value()) {
for (auto& it : processes.value()) { for (auto& it : processes.value()) {
Process process; Process process;
process.pid = it.value.pid; process.pid = it.pid;
process.uid = it.value.uid; process.uid = it.uid;
process.icon = FileIconProvider::icon_for_executable(it.value.executable).bitmap_for_size(16); process.icon = FileIconProvider::icon_for_executable(it.executable).bitmap_for_size(16);
process.name = it.value.name; process.name = it.name;
m_processes.append(move(process)); m_processes.append(move(process));
} }
} }

View file

@ -20,13 +20,13 @@ static void print_usage_and_exit()
static int kill_all(const String& process_name, const unsigned signum) static int kill_all(const String& process_name, const unsigned signum)
{ {
auto processes = Core::ProcessStatisticsReader().get_all(); auto processes = Core::ProcessStatisticsReader::get_all();
if (!processes.has_value()) if (!processes.has_value())
return 1; return 1;
for (auto& it : processes.value()) { for (auto& process : processes.value()) {
if (it.value.name == process_name) { if (process.name == process_name) {
int ret = kill(it.value.pid, signum); int ret = kill(process.pid, signum);
if (ret < 0) if (ret < 0)
perror("kill"); perror("kill");
} }

View file

@ -150,22 +150,22 @@ int main(int argc, char* argv[])
if (!processes.has_value()) if (!processes.has_value())
return 1; return 1;
if (arg_pid == -1) { if (arg_pid == -1) {
for (auto process : processes.value()) { for (auto& process : processes.value()) {
if (process.key == 0) if (process.pid == 0)
continue; continue;
auto open_files = get_open_files_by_pid(process.key); auto open_files = get_open_files_by_pid(process.pid);
if (open_files.is_empty()) if (open_files.is_empty())
continue; continue;
for (auto file : open_files) { for (auto& file : open_files) {
if ((arg_all_processes) if ((arg_all_processes)
|| (arg_fd != -1 && file.fd == arg_fd) || (arg_fd != -1 && file.fd == arg_fd)
|| (arg_uid_int != -1 && (int)process.value.uid == arg_uid_int) || (arg_uid_int != -1 && (int)process.uid == arg_uid_int)
|| (arg_uid != nullptr && process.value.username == arg_uid) || (arg_uid != nullptr && process.username == arg_uid)
|| (arg_pgid != -1 && (int)process.value.pgid == arg_pgid) || (arg_pgid != -1 && (int)process.pgid == arg_pgid)
|| (arg_filename != nullptr && file.name == arg_filename)) || (arg_filename != nullptr && file.name == arg_filename))
display_entry(file, process.value); display_entry(file, process);
} }
} }
} else { } else {
@ -175,7 +175,7 @@ int main(int argc, char* argv[])
return 0; return 0;
for (auto file : open_files) { for (auto file : open_files) {
display_entry(file, processes.value().get(arg_pid).value()); display_entry(file, *processes->find_if([&](auto& entry) { return entry.pid == arg_pid; }));
} }
} }

View file

@ -19,14 +19,14 @@ static int pid_of(const String& process_name, bool single_shot, bool omit_pid, p
{ {
bool displayed_at_least_one = false; bool displayed_at_least_one = false;
auto processes = Core::ProcessStatisticsReader().get_all(); auto processes = Core::ProcessStatisticsReader::get_all();
if (!processes.has_value()) if (!processes.has_value())
return 1; return 1;
for (auto& it : processes.value()) { for (auto& it : processes.value()) {
if (it.value.name == process_name) { if (it.name == process_name) {
if (!omit_pid || it.value.pid != pid) { if (!omit_pid || it.pid != pid) {
printf(" %d" + (displayed_at_least_one ? 0 : 1), it.value.pid); printf(" %d" + (displayed_at_least_one ? 0 : 1), it.pid);
displayed_at_least_one = true; displayed_at_least_one = true;
if (single_shot) if (single_shot)

View file

@ -103,9 +103,8 @@ int main(int argc, char** argv)
if (!all_processes.has_value()) if (!all_processes.has_value())
return 1; return 1;
for (const auto& it : all_processes.value()) { for (auto const& process : all_processes.value()) {
const auto& proc = it.value; auto tty = process.tty;
auto tty = proc.tty;
if (!every_process_flag && tty != this_tty) if (!every_process_flag && tty != this_tty)
continue; continue;
@ -115,20 +114,20 @@ int main(int argc, char** argv)
else else
tty = "n/a"; tty = "n/a";
auto* state = proc.threads.is_empty() ? "Zombie" : proc.threads.first().state.characters(); auto* state = process.threads.is_empty() ? "Zombie" : process.threads.first().state.characters();
if (uid_column != -1) if (uid_column != -1)
columns[uid_column].buffer = proc.username; columns[uid_column].buffer = process.username;
if (pid_column != -1) if (pid_column != -1)
columns[pid_column].buffer = String::number(proc.pid); columns[pid_column].buffer = String::number(process.pid);
if (ppid_column != -1) if (ppid_column != -1)
columns[ppid_column].buffer = String::number(proc.ppid); columns[ppid_column].buffer = String::number(process.ppid);
if (tty_column != -1) if (tty_column != -1)
columns[tty_column].buffer = tty; columns[tty_column].buffer = tty;
if (state_column != -1) if (state_column != -1)
columns[state_column].buffer = state; columns[state_column].buffer = state;
if (cmd_column != -1) if (cmd_column != -1)
columns[cmd_column].buffer = proc.name; columns[cmd_column].buffer = process.name;
for (auto& column : columns) for (auto& column : columns)
print_column(column, column.buffer); print_column(column, column.buffer);

View file

@ -77,25 +77,24 @@ static Snapshot get_snapshot()
return {}; return {};
Snapshot snapshot; Snapshot snapshot;
for (auto& it : all_processes.value()) { for (auto& process : all_processes.value()) {
auto& stats = it.value; for (auto& thread : process.threads) {
for (auto& thread : stats.threads) {
snapshot.sum_times_scheduled += thread.times_scheduled; snapshot.sum_times_scheduled += thread.times_scheduled;
ThreadData thread_data; ThreadData thread_data;
thread_data.tid = thread.tid; thread_data.tid = thread.tid;
thread_data.pid = stats.pid; thread_data.pid = process.pid;
thread_data.pgid = stats.pgid; thread_data.pgid = process.pgid;
thread_data.pgp = stats.pgp; thread_data.pgp = process.pgp;
thread_data.sid = stats.sid; thread_data.sid = process.sid;
thread_data.uid = stats.uid; thread_data.uid = process.uid;
thread_data.gid = stats.gid; thread_data.gid = process.gid;
thread_data.ppid = stats.ppid; thread_data.ppid = process.ppid;
thread_data.nfds = stats.nfds; thread_data.nfds = process.nfds;
thread_data.name = stats.name; thread_data.name = process.name;
thread_data.tty = stats.tty; thread_data.tty = process.tty;
thread_data.amount_virtual = stats.amount_virtual; thread_data.amount_virtual = process.amount_virtual;
thread_data.amount_resident = stats.amount_resident; thread_data.amount_resident = process.amount_resident;
thread_data.amount_shared = stats.amount_shared; thread_data.amount_shared = process.amount_shared;
thread_data.syscall_count = thread.syscall_count; thread_data.syscall_count = thread.syscall_count;
thread_data.inode_faults = thread.inode_faults; thread_data.inode_faults = thread.inode_faults;
thread_data.zero_faults = thread.zero_faults; thread_data.zero_faults = thread.zero_faults;
@ -103,9 +102,9 @@ static Snapshot get_snapshot()
thread_data.times_scheduled = thread.times_scheduled; thread_data.times_scheduled = thread.times_scheduled;
thread_data.priority = thread.priority; thread_data.priority = thread.priority;
thread_data.state = thread.state; thread_data.state = thread.state;
thread_data.username = stats.username; thread_data.username = process.username;
snapshot.map.set({ stats.pid, thread.tid }, move(thread_data)); snapshot.map.set({ process.pid, thread.tid }, move(thread_data));
} }
} }

View file

@ -95,9 +95,9 @@ int main()
String what = "n/a"; String what = "n/a";
for (auto& it : process_statistics.value()) { for (auto& process : process_statistics.value()) {
if (it.value.tty == tty && it.value.pid == it.value.pgid) if (process.tty == tty && process.pid == process.pgid)
what = it.value.name; what = process.name;
} }
printf("%-10s %-12s %-16s %-6s %s\n", printf("%-10s %-12s %-16s %-6s %s\n",