Skip to content

Commit

Permalink
Show cpu usage for processes in Flatpak
Browse files Browse the repository at this point in the history
  • Loading branch information
stsdc committed Dec 25, 2023
1 parent 7ba6821 commit 24f0dc7
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 259 deletions.
119 changes: 95 additions & 24 deletions src/Managers/Process.vala
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ public class Monitor.Process : GLib.Object {


// Whether or not the PID leads to something
public bool exists { get; protected set; }
public bool exists { get; private set; }

// Full command from cmdline file
public string command { get; protected set; }
public string command { get; private set; }

// If process is an installed app, this will contain its name,
// otherwise it is just a trimmed command
Expand Down Expand Up @@ -51,17 +51,17 @@ public class Monitor.Process : GLib.Object {
*
* Will be 0 on first update.
*/
public double cpu_percentage { get; protected set; }
public double cpu_percentage { get; private set; }

protected uint64 cpu_last_used;
private uint64 cpu_last_used;

// Memory usage of the process, measured in KiB.
public uint64 mem_usage { get; protected set; }
public double mem_percentage { get; protected set; }
public uint64 mem_usage { get; private set; }
public double mem_percentage { get; private set; }

protected uint64 last_total;
private uint64 last_total;

protected const int HISTORY_BUFFER_SIZE = 30;
const int HISTORY_BUFFER_SIZE = 30;
public Gee.ArrayList<double ? > cpu_percentage_history = new Gee.ArrayList<double ? > ();
public Gee.ArrayList<double ? > mem_percentage_history = new Gee.ArrayList<double ? > ();

Expand Down Expand Up @@ -95,7 +95,7 @@ public class Monitor.Process : GLib.Object {
get_usage (0, 1);
}

protected int get_uid () {
private int get_uid () {
if (ProcessUtils.is_flatpak_env ()) {
var process_provider = ProcessProvider.get_default ();
string ? status = process_provider.pids_status.get (this.stat.pid);
Expand Down Expand Up @@ -139,7 +139,7 @@ public class Monitor.Process : GLib.Object {
return false;
}

protected bool get_children_pids () {
private bool get_children_pids () {
string ? children_content = ProcessUtils.read_file ("/proc/%d/task/%d/children".printf (stat.pid, stat.pid));
if (children_content == "" || children_content == null) {
return false;
Expand All @@ -152,7 +152,52 @@ public class Monitor.Process : GLib.Object {
return true;
}

protected bool parse_io () {
private bool parse_io_workaround () {
var process_provider = ProcessProvider.get_default ();
string ? io_stats = process_provider.pids_io.get (this.stat.pid);

if (io_stats == "") return false;

foreach (string line in io_stats.split ("\n")) {
if (line == "") continue;
var splitted_line = line.split (":");
switch (splitted_line[0]) {
case "wchar":
io.wchar = uint64.parse (splitted_line[1]);
break;
case "rchar":
io.rchar = uint64.parse (splitted_line[1]);
break;
case "syscr":
io.syscr = uint64.parse (splitted_line[1]);
break;
case "syscw":
io.syscw = uint64.parse (splitted_line[1]);
break;
case "read_bytes":
io.read_bytes = uint64.parse (splitted_line[1]);
break;
case "write_bytes":
io.write_bytes = uint64.parse (splitted_line[1]);
break;
case "cancelled_write_bytes":
io.cancelled_write_bytes = uint64.parse (splitted_line[1]);
break;
default:
warning ("Unknown value in /proc/%d/io", stat.pid);
break;
}
}

return true;
}

private bool parse_io () {

if (ProcessUtils.is_flatpak_env ()) {
return parse_io_workaround ();
}

var io_file = File.new_for_path ("/proc/%d/io".printf (stat.pid));

if (!io_file.query_exists ()) {
Expand Down Expand Up @@ -205,8 +250,14 @@ public class Monitor.Process : GLib.Object {
}

// Reads the /proc/%pid%/stat file and updates the process with the information therein.
protected bool parse_stat () {
string ? stat_contents = ProcessUtils.read_file ("/proc/%d/stat".printf (stat.pid));
private bool parse_stat () {
string ? stat_contents;
if (ProcessUtils.is_flatpak_env ()) {
var process_provider = ProcessProvider.get_default ();
stat_contents = process_provider.pids_stat.get (this.stat.pid);
} else {
stat_contents = ProcessUtils.read_file ("/proc/%d/stat".printf (stat.pid));
}

if (stat_contents == null) return false;

Expand Down Expand Up @@ -238,12 +289,20 @@ public class Monitor.Process : GLib.Object {
stat.priority = int.parse (splitted_stat[17]);
stat.nice = int.parse (splitted_stat[18]);
stat.num_threads = int.parse (splitted_stat[19]);
stat.utime = ulong.parse (splitted_stat[13]);
stat.stime = ulong.parse (splitted_stat[14]);

return true;
}

protected bool parse_statm () {
string ? statm_contents = ProcessUtils.read_file ("/proc/%d/statm".printf (stat.pid));
private bool parse_statm () {
string ? statm_contents;
if (ProcessUtils.is_flatpak_env ()) {
var process_provider = ProcessProvider.get_default ();
statm_contents = process_provider.pids_stat.get (this.stat.pid);
} else {
statm_contents = ProcessUtils.read_file ("/proc/%d/statm".printf (stat.pid));
}

if (statm_contents == null) return false;

Expand All @@ -259,7 +318,7 @@ public class Monitor.Process : GLib.Object {
return true;
}

protected bool get_open_files () {
private bool get_open_files () {
// try {
// string directory = "/proc/%d/fd".printf (stat.pid);
// Dir dir = Dir.open (directory, 0);
Expand All @@ -286,8 +345,14 @@ public class Monitor.Process : GLib.Object {
/**
* Reads the /proc/%pid%/cmdline file and updates from the information contained therein.
*/
protected bool read_cmdline () {
string ? cmdline = process_provider.pids_cmdline.get (this.stat.pid);
private bool read_cmdline () {
string ? cmdline;
if (ProcessUtils.is_flatpak_env ()) {
var process_provider = ProcessProvider.get_default ();
cmdline = process_provider.pids_cmdline.get (this.stat.pid);
} else {
cmdline = ProcessUtils.read_file ("/proc/%d/cmdline".printf (stat.pid));
}

if (cmdline == null) {
return false;
Expand All @@ -305,12 +370,18 @@ public class Monitor.Process : GLib.Object {
return true;
}

protected void get_usage (uint64 cpu_total, uint64 cpu_last_total) {
private void get_usage (uint64 cpu_total, uint64 cpu_last_total) {
// Get CPU usage by process
GTop.ProcTime proc_time;
GTop.get_proc_time (out proc_time, stat.pid);
cpu_percentage = 100 * ((double) (proc_time.rtime - cpu_last_used)) / (cpu_total - cpu_last_total);
cpu_last_used = proc_time.rtime;
if (ProcessUtils.is_flatpak_env ()) {
var rtime = stat.utime + stat.stime;
cpu_percentage = 100 * ((double) (rtime - cpu_last_used)) / (cpu_total - cpu_last_total);
cpu_last_used = rtime;
} else {
GTop.ProcTime proc_time;
GTop.get_proc_time (out proc_time, stat.pid);
cpu_percentage = 100 * ((double) (proc_time.rtime - cpu_last_used)) / (cpu_total - cpu_last_total);
cpu_last_used = proc_time.rtime;
}

// Making CPU history
if (cpu_percentage_history.size == HISTORY_BUFFER_SIZE) {
Expand Down Expand Up @@ -342,4 +413,4 @@ public class Monitor.Process : GLib.Object {
mem_percentage_history.add (mem_percentage);
}

}
}
2 changes: 1 addition & 1 deletion src/Managers/ProcessManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ namespace Monitor {
*/
private Process ? add_process (int pid, bool lazy_signal = false) {
// create the process
var process = ProcessProvider.get_default ().create_process (pid);
var process = new Process (pid);

if (!process.exists) {
return null;
Expand Down
7 changes: 0 additions & 7 deletions src/Managers/ProcessProvider.vala
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,6 @@ namespace Monitor {
return pids;
}

public Process create_process (int pid) {
if (ProcessUtils.is_flatpak_env ()) {
return new ProcessWorkaround (pid);
}
return new Process (pid);
}

private bool process_line (IOChannel channel, IOCondition condition, GLib.List<int> _pids) {
if (condition == IOCondition.HUP) {
// debug ("%s: The fd has been closed.\n", stream_name);
Expand Down
3 changes: 3 additions & 0 deletions src/Managers/ProcessStructs.vala
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,7 @@ public struct Monitor.ProcessStatus {

// The time the process started after system boot.
public uint64 starttime;

public ulong utime;
public ulong stime;
}
Loading

0 comments on commit 24f0dc7

Please sign in to comment.