diff options
Diffstat (limited to 'src/app/data_harvester/processes/macos.rs')
-rw-r--r-- | src/app/data_harvester/processes/macos.rs | 96 |
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) -} |