Skip to content

Commit 33f442d

Browse files
committed
Add pidrusage
1 parent bb31235 commit 33f442d

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

src/libproc/proc_pid.rs

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,15 @@ pub enum PidFDInfoFlavor {
206206
ATalkInfo = 8
207207
}
208208

209+
// From https://opensource.apple.com/source/xnu/xnu-4903.221.2/bsd/sys/resource.h
210+
pub enum PidRUsageFlavor {
211+
V0 = 0,
212+
V1 = 1,
213+
V2 = 2,
214+
V3 = 3,
215+
V4 = 4,
216+
}
217+
209218
// this extern block links to the libproc library
210219
// Original signatures of functions can be found at http://opensource.apple.com/source/Libc/Libc-594.9.4/darwin/libproc.c
211220
#[link(name = "proc", kind = "dylib")]
@@ -223,6 +232,8 @@ extern {
223232
fn proc_pidpath(pid: c_int, buffer: *mut c_void, buffersize: uint32_t) -> c_int;
224233

225234
fn proc_libversion(major: *mut c_int, minor: *mut c_int) -> c_int;
235+
236+
fn proc_pid_rusage(pid: c_int, flavor: c_int, buffer: *mut c_void) -> c_int;
226237
}
227238

228239

@@ -1076,3 +1087,208 @@ impl Default for KernCtlInfo {
10761087
}
10771088
}
10781089

1090+
// This trait is needed for polymorphism on pidrusage types, also abstracting flavor in order to provide
1091+
// type-guaranteed flavor correctness
1092+
pub trait PIDRUsage: Default {
1093+
fn flavor() -> PidRUsageFlavor;
1094+
}
1095+
1096+
/// Returns the information about resources of the process that match pid passed in.
1097+
///
1098+
/// # Examples
1099+
///
1100+
/// ```
1101+
/// use std::io::Write;
1102+
/// use libproc::libproc::proc_pid::{pidrusage, RUsageInfoV2};
1103+
///
1104+
/// fn pidrusage_test() {
1105+
/// use std::process;
1106+
/// let pid = process::id() as i32;
1107+
///
1108+
/// if let Ok(res) = pidrusage::<RUsageInfoV2>(pid) {
1109+
/// println!("UUID: {:?}, Disk Read: {}, Disk Write: {}", res.ri_uuid, res.ri_diskio_bytesread, res.ri_diskio_byteswritten);
1110+
/// }
1111+
/// }
1112+
/// ```
1113+
///
1114+
pub fn pidrusage<T: PIDRUsage>(pid : i32) -> Result<T, String> {
1115+
let flavor = T::flavor() as i32;
1116+
let mut pidrusage = T::default();
1117+
let buffer_ptr = &mut pidrusage as *mut _ as *mut c_void;
1118+
let ret: i32;
1119+
1120+
unsafe {
1121+
ret = proc_pid_rusage(pid, flavor, buffer_ptr);
1122+
};
1123+
1124+
if ret < 0 {
1125+
Err(get_errno_with_message(ret))
1126+
} else {
1127+
Ok(pidrusage)
1128+
}
1129+
}
1130+
1131+
#[test]
1132+
fn pidrusage_test() {
1133+
use std::process;
1134+
let pid = process::id() as i32;
1135+
1136+
let res = pidrusage::<RUsageInfoV2>(pid).unwrap();
1137+
println!("UUID: {:?}, Disk Read: {}, Disk Write: {}", res.ri_uuid, res.ri_diskio_bytesread, res.ri_diskio_byteswritten);
1138+
}
1139+
1140+
#[repr(C)]
1141+
#[derive(Default)]
1142+
pub struct RUsageInfoV0 {
1143+
pub ri_uuid : [uint8_t; 16],
1144+
pub ri_user_time : uint64_t,
1145+
pub ri_system_time : uint64_t,
1146+
pub ri_pkg_idle_wkups : uint64_t,
1147+
pub ri_interrupt_wkups : uint64_t,
1148+
pub ri_pageins : uint64_t,
1149+
pub ri_wired_size : uint64_t,
1150+
pub ri_resident_size : uint64_t,
1151+
pub ri_phys_footprint : uint64_t,
1152+
pub ri_proc_start_abstime: uint64_t,
1153+
pub ri_proc_exit_abstime : uint64_t,
1154+
}
1155+
1156+
impl PIDRUsage for RUsageInfoV0 {
1157+
fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V0 }
1158+
}
1159+
1160+
#[repr(C)]
1161+
#[derive(Default)]
1162+
pub struct RUsageInfoV1 {
1163+
pub ri_uuid : [uint8_t; 16],
1164+
pub ri_user_time : uint64_t,
1165+
pub ri_system_time : uint64_t,
1166+
pub ri_pkg_idle_wkups : uint64_t,
1167+
pub ri_interrupt_wkups : uint64_t,
1168+
pub ri_pageins : uint64_t,
1169+
pub ri_wired_size : uint64_t,
1170+
pub ri_resident_size : uint64_t,
1171+
pub ri_phys_footprint : uint64_t,
1172+
pub ri_proc_start_abstime : uint64_t,
1173+
pub ri_proc_exit_abstime : uint64_t,
1174+
pub ri_child_user_time : uint64_t,
1175+
pub ri_child_system_time : uint64_t,
1176+
pub ri_child_pkg_idle_wkups : uint64_t,
1177+
pub ri_child_interrupt_wkups: uint64_t,
1178+
pub ri_child_pageins : uint64_t,
1179+
pub ri_child_elapsed_abstime: uint64_t,
1180+
}
1181+
1182+
impl PIDRUsage for RUsageInfoV1 {
1183+
fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V1 }
1184+
}
1185+
1186+
#[repr(C)]
1187+
#[derive(Debug, Default)]
1188+
pub struct RUsageInfoV2 {
1189+
pub ri_uuid : [uint8_t; 16],
1190+
pub ri_user_time : uint64_t,
1191+
pub ri_system_time : uint64_t,
1192+
pub ri_pkg_idle_wkups : uint64_t,
1193+
pub ri_interrupt_wkups : uint64_t,
1194+
pub ri_pageins : uint64_t,
1195+
pub ri_wired_size : uint64_t,
1196+
pub ri_resident_size : uint64_t,
1197+
pub ri_phys_footprint : uint64_t,
1198+
pub ri_proc_start_abstime : uint64_t,
1199+
pub ri_proc_exit_abstime : uint64_t,
1200+
pub ri_child_user_time : uint64_t,
1201+
pub ri_child_system_time : uint64_t,
1202+
pub ri_child_pkg_idle_wkups : uint64_t,
1203+
pub ri_child_interrupt_wkups: uint64_t,
1204+
pub ri_child_pageins : uint64_t,
1205+
pub ri_child_elapsed_abstime: uint64_t,
1206+
pub ri_diskio_bytesread : uint64_t,
1207+
pub ri_diskio_byteswritten : uint64_t,
1208+
}
1209+
1210+
impl PIDRUsage for RUsageInfoV2 {
1211+
fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V2 }
1212+
}
1213+
1214+
#[repr(C)]
1215+
#[derive(Default)]
1216+
pub struct RUsageInfoV3 {
1217+
pub ri_uuid : [uint8_t; 16],
1218+
pub ri_user_time : uint64_t,
1219+
pub ri_system_time : uint64_t,
1220+
pub ri_pkg_idle_wkups : uint64_t,
1221+
pub ri_interrupt_wkups : uint64_t,
1222+
pub ri_pageins : uint64_t,
1223+
pub ri_wired_size : uint64_t,
1224+
pub ri_resident_size : uint64_t,
1225+
pub ri_phys_footprint : uint64_t,
1226+
pub ri_proc_start_abstime : uint64_t,
1227+
pub ri_proc_exit_abstime : uint64_t,
1228+
pub ri_child_user_time : uint64_t,
1229+
pub ri_child_system_time : uint64_t,
1230+
pub ri_child_pkg_idle_wkups : uint64_t,
1231+
pub ri_child_interrupt_wkups : uint64_t,
1232+
pub ri_child_pageins : uint64_t,
1233+
pub ri_child_elapsed_abstime : uint64_t,
1234+
pub ri_diskio_bytesread : uint64_t,
1235+
pub ri_diskio_byteswritten : uint64_t,
1236+
pub ri_cpu_time_qos_default : uint64_t,
1237+
pub ri_cpu_time_qos_maintenance : uint64_t,
1238+
pub ri_cpu_time_qos_background : uint64_t,
1239+
pub ri_cpu_time_qos_utility : uint64_t,
1240+
pub ri_cpu_time_qos_legacy : uint64_t,
1241+
pub ri_cpu_time_qos_user_initiated : uint64_t,
1242+
pub ri_cpu_time_qos_user_interactive: uint64_t,
1243+
pub ri_billed_system_time : uint64_t,
1244+
pub ri_serviced_system_time : uint64_t,
1245+
}
1246+
1247+
impl PIDRUsage for RUsageInfoV3 {
1248+
fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V3 }
1249+
}
1250+
1251+
#[repr(C)]
1252+
#[derive(Default)]
1253+
pub struct RUsageInfoV4 {
1254+
pub ri_uuid : [uint8_t; 16],
1255+
pub ri_user_time : uint64_t,
1256+
pub ri_system_time : uint64_t,
1257+
pub ri_pkg_idle_wkups : uint64_t,
1258+
pub ri_interrupt_wkups : uint64_t,
1259+
pub ri_pageins : uint64_t,
1260+
pub ri_wired_size : uint64_t,
1261+
pub ri_resident_size : uint64_t,
1262+
pub ri_phys_footprint : uint64_t,
1263+
pub ri_proc_start_abstime : uint64_t,
1264+
pub ri_proc_exit_abstime : uint64_t,
1265+
pub ri_child_user_time : uint64_t,
1266+
pub ri_child_system_time : uint64_t,
1267+
pub ri_child_pkg_idle_wkups : uint64_t,
1268+
pub ri_child_interrupt_wkups : uint64_t,
1269+
pub ri_child_pageins : uint64_t,
1270+
pub ri_child_elapsed_abstime : uint64_t,
1271+
pub ri_diskio_bytesread : uint64_t,
1272+
pub ri_diskio_byteswritten : uint64_t,
1273+
pub ri_cpu_time_qos_default : uint64_t,
1274+
pub ri_cpu_time_qos_maintenance : uint64_t,
1275+
pub ri_cpu_time_qos_background : uint64_t,
1276+
pub ri_cpu_time_qos_utility : uint64_t,
1277+
pub ri_cpu_time_qos_legacy : uint64_t,
1278+
pub ri_cpu_time_qos_user_initiated : uint64_t,
1279+
pub ri_cpu_time_qos_user_interactive: uint64_t,
1280+
pub ri_billed_system_time : uint64_t,
1281+
pub ri_serviced_system_time : uint64_t,
1282+
pub ri_logical_writes : uint64_t,
1283+
pub ri_lifetime_max_phys_footprint : uint64_t,
1284+
pub ri_instructions : uint64_t,
1285+
pub ri_cycles : uint64_t,
1286+
pub ri_billed_energy : uint64_t,
1287+
pub ri_serviced_energy : uint64_t,
1288+
pub ri_interval_max_phys_footprint : uint64_t,
1289+
pub ri_unused : [uint64_t; 1],
1290+
}
1291+
1292+
impl PIDRUsage for RUsageInfoV4 {
1293+
fn flavor() -> PidRUsageFlavor { PidRUsageFlavor::V4 }
1294+
}

0 commit comments

Comments
 (0)