summaryrefslogtreecommitdiffstats
path: root/src/app/data_harvester/processes/macos.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/data_harvester/processes/macos.rs')
-rw-r--r--src/app/data_harvester/processes/macos.rs96
1 files changed, 51 insertions, 45 deletions
diff --git a/src/app/data_harvester/processes/macos.rs b/src/app/data_harvester/processes/macos.rs
index 95e6fd9a..b895e1ec 100644
--- a/src/app/data_harvester/processes/macos.rs
+++ b/src/app/data_harvester/processes/macos.rs
@@ -1,57 +1,63 @@
//! Process data collection for macOS. Uses sysinfo and custom bindings.
+use std::io;
+use std::process::Command;
+
use hashbrown::HashMap;
-use sysinfo::System;
+use itertools::Itertools;
+use sysinfo::{PidExt, ProcessExt};
+
+use super::UnixProcessExt;
-use super::ProcessHarvest;
-use crate::{data_harvester::processes::UserTable, Pid};
+use crate::Pid;
mod sysctl_bindings;
-pub fn get_process_data(
- sys: &System, use_current_cpu_total: bool, unnormalized_cpu: bool, mem_total: u64,
- user_table: &mut UserTable,
-) -> crate::utils::error::Result<Vec<ProcessHarvest>> {
- super::macos_freebsd::get_process_data(
- sys,
- use_current_cpu_total,
- unnormalized_cpu,
- mem_total,
- user_table,
- get_macos_process_cpu_usage,
- )
+pub(crate) struct MacOSProcessExt;
+
+impl UnixProcessExt for MacOSProcessExt {
+ #[inline]
+ fn has_backup_proc_cpu_fn() -> bool {
+ true
+ }
+
+ fn backup_proc_cpu(pids: &[Pid]) -> io::Result<HashMap<Pid, f64>> {
+ let output = Command::new("ps")
+ .args(["-o", "pid=,pcpu=", "-p"])
+ .arg(
+ // Has to look like this since otherwise, it you hit a `unstable_name_collisions` warning.
+ Itertools::intersperse(pids.iter().map(i32::to_string), ",".to_string())
+ .collect::<String>(),
+ )
+ .output()?;
+ let mut result = HashMap::new();
+ String::from_utf8_lossy(&output.stdout)
+ .split_whitespace()
+ .chunks(2)
+ .into_iter()
+ .for_each(|chunk| {
+ let chunk: Vec<&str> = chunk.collect();
+ if chunk.len() != 2 {
+ panic!("Unexpected `ps` output");
+ }
+ let pid = chunk[0].parse();
+ let usage = chunk[1].parse();
+ if let (Ok(pid), Ok(usage)) = (pid, usage) {
+ result.insert(pid, usage);
+ }
+ });
+ Ok(result)
+ }
+
+ fn parent_pid(process_val: &sysinfo::Process) -> Option<Pid> {
+ process_val
+ .parent()
+ .map(|p| p.as_u32() as _)
+ .or_else(|| fallback_macos_ppid(process_val.pid().as_u32() as _))
+ }
}
-pub(crate) fn fallback_macos_ppid(pid: Pid) -> Option<Pid> {
+fn fallback_macos_ppid(pid: Pid) -> Option<Pid> {
sysctl_bindings::kinfo_process(pid)
.map(|kinfo| kinfo.kp_eproc.e_ppid)
.ok()
}
-
-fn get_macos_process_cpu_usage(pids: &[Pid]) -> std::io::Result<HashMap<i32, f64>> {
- use itertools::Itertools;
- let output = std::process::Command::new("ps")
- .args(["-o", "pid=,pcpu=", "-p"])
- .arg(
- // Has to look like this since otherwise, it you hit a `unstable_name_collisions` warning.
- Itertools::intersperse(pids.iter().map(i32::to_string), ",".to_string())
- .collect::<String>(),
- )
- .output()?;
- let mut result = HashMap::new();
- String::from_utf8_lossy(&output.stdout)
- .split_whitespace()
- .chunks(2)
- .into_iter()
- .for_each(|chunk| {
- let chunk: Vec<&str> = chunk.collect();
- if chunk.len() != 2 {
- panic!("Unexpected `ps` output");
- }
- let pid = chunk[0].parse();
- let usage = chunk[1].parse();
- if let (Ok(pid), Ok(usage)) = (pid, usage) {
- result.insert(pid, usage);
- }
- });
- Ok(result)
-}