diff --git a/Cargo.toml b/Cargo.toml index 85597d7..78d22fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,12 @@ winapi = { version = "0.3.9", features = ["psapi", "processthreadsapi"] } procfs = "0.9.0" libc = "0.2.72" +[target.'cfg(target_os = "freebsd")'.dependencies] +bsd-kvm = "0.1.5" +bsd-kvm-sys = "0.2.0" +sysinfo = "0.35.1" +libc = "0.2.72" + [target.'cfg(target_os = "macos")'.dependencies] darwin-libproc = "0.2.0" libc = "0.2.72" diff --git a/README.md b/README.md index ffdbfcb..172fc43 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ println!("{:?}", process_stats); On Linux, this library reads `/proc/self/stat` and uses the `sysconf` libc function. +On FreeBSD, this library uses getkerninfo(). + On Windows, the library uses `GetCurrentProcess` combined with `GetProcessTimes` and `K32GetProcessMemoryInfo`. On macOS, this library uses `proc_pidinfo` from `libproc` (and current process ID is determined via `libc`). diff --git a/src/freebsd.rs b/src/freebsd.rs new file mode 100644 index 0000000..0c0f2bc --- /dev/null +++ b/src/freebsd.rs @@ -0,0 +1,52 @@ +use crate::{Error, ProcessStats}; +use std::time::Duration; +use sysinfo::{get_current_pid, Pid, System}; + +pub fn get_info() -> Result { + let pid = match get_current_pid() { + Ok(pid) => { pid } + Err(e) => { panic!("failed to get current pid: {}", e) } + }; + + let s = System::new_all(); + if let Some(p) = s.process(Pid::from(pid)) { + let memory_usage_bytes = p.memory(); + let user_mode_seconds = p.run_time(); + let kernel_mode_seconds = p.run_time(); + + Ok(ProcessStats { + cpu_time_user: Duration::from_secs_f64(user_mode_seconds as f64), + cpu_time_kernel: Duration::from_secs_f64(kernel_mode_seconds as f64), + memory_usage_bytes, + }) + } else { + Ok( + ProcessStats { + cpu_time_user: Duration::from_secs_f64(0 as f64), + cpu_time_kernel: Duration::from_secs_f64(0 as f64), + memory_usage_bytes: 0, + } + ) + } +} + +#[cfg(test)] +pub mod tests { + use crate::freebsd; + + #[test] + pub fn test_no_error() { + #[no_mangle] + fn spin_for_a_bit() { + let mut _a = 0; + for _i in 0..9999999 { + _a += 1; + } + } + + // to get some nonzero number for cpu_time_user + spin_for_a_bit(); + + dbg!(freebsd::get_info().unwrap()); + } +} diff --git a/src/lib.rs b/src/lib.rs index 21272a3..6290693 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ //! A small library to get memory usage and elapsed CPU time. //! -//! Supports Windows, Linux and macOS. +//! Supports Windows, Linux, FreeBSD and macOS. //! //! ```rust //! use simple_process_stats::ProcessStats; @@ -31,6 +31,8 @@ mod linux; mod macos; #[cfg(target_os = "windows")] mod windows; +#[cfg(target_os = "freebsd")] +mod freebsd; use std::path::PathBuf; use std::time::Duration; @@ -65,6 +67,12 @@ impl ProcessStats { pub fn get() -> Result { macos::get_info() } + + /// Get the statistics using the OS-specific method. + #[cfg(target_os = "freebsd")] + pub fn get() -> Result { + freebsd::get_info() + } } /// An error that occurred while trying to get the process stats.