mod clock;
#[cfg(target_os = "macos")]
mod macos;
pub mod procfs;
pub use clock::{monotonic_ns, thread_cpu_ns, tid};
#[cfg(not(target_os = "macos"))]
use std::path::Path;
#[derive(Clone, Debug, Default)]
pub struct ProcessObservation {
pub pid: u32,
pub ppid: u32,
pub start_ticks: u64,
pub name: String,
pub user_ns: u64,
pub system_ns: u64,
pub waited_user_ns: u64,
pub waited_system_ns: u64,
pub rss_bytes: u64,
pub pss_bytes: Option<u64>,
pub read_bytes: Option<u64>,
pub write_bytes: Option<u64>,
pub minor_faults: u64,
pub major_faults: u64,
pub threads: u64,
}
#[must_use]
pub fn basic_process(pid: u32) -> Option<ProcessObservation> {
#[cfg(target_os = "macos")]
return macos::process(pid);
#[cfg(not(target_os = "macos"))]
procfs::basic_process(Path::new("/proc"), pid)
}
#[must_use]
pub fn process_identity(pid: u32) -> Option<u64> {
#[cfg(target_os = "macos")]
return macos::identity(pid);
#[cfg(not(target_os = "macos"))]
procfs::process_identity(Path::new("/proc"), pid)
}
#[must_use]
pub fn process(pid: u32, memory_detail: bool) -> Option<ProcessObservation> {
#[cfg(target_os = "macos")]
{
let _ = memory_detail;
basic_process(pid)
}
#[cfg(not(target_os = "macos"))]
{
let mut result = basic_process(pid)?;
procfs::read_details(Path::new("/proc"), &mut result, memory_detail);
Some(result)
}
}
#[derive(Debug, Default)]
pub struct ChildProcesses {
pub pids: Vec<u32>,
pub unavailable: bool,
pub incomplete: bool,
pub truncated: bool,
}
#[must_use]
pub fn children(pid: u32, capacity: usize) -> ChildProcesses {
#[cfg(target_os = "macos")]
return macos::children(pid, capacity);
#[cfg(not(target_os = "macos"))]
{
let _ = capacity;
procfs::children(Path::new("/proc"), pid)
}
}
#[must_use]
#[cfg_attr(
not(target_os = "linux"),
expect(
clippy::missing_const_for_fn,
reason = "the Linux implementation queries live scheduler state and cannot be const"
)
)]
pub fn affinity_cpus(pid: u32) -> Option<u32> {
#[cfg(target_os = "linux")]
{
let pid = rustix::thread::Pid::from_raw(i32::try_from(pid).ok()?);
rustix::thread::sched_getaffinity(pid)
.ok()
.map(|set| set.count())
}
#[cfg(not(target_os = "linux"))]
{
let _ = pid;
None
}
}
#[cfg(test)]
mod tests;