use std::io;
use std::mem::MaybeUninit;
use std::process::Child;
use crate::benchmark::measurement::HardwareCounters;
pub fn wait(child: &mut Child) -> io::Result<()> {
drop(child.stdin.take());
let mut info = MaybeUninit::uninit();
loop {
let result = unsafe {
libc::waitid(
libc::P_PID,
child.id(),
info.as_mut_ptr(),
libc::WEXITED | libc::WNOWAIT,
)
};
if result == 0 {
return Ok(());
}
let error = io::Error::last_os_error();
if error.kind() != io::ErrorKind::Interrupted {
return Err(error);
}
}
}
pub fn read(pid: u32) -> HardwareCounters {
let mut usage = MaybeUninit::<libc::rusage_info_v4>::zeroed();
let result = unsafe {
libc::proc_pid_rusage(
pid as libc::pid_t,
libc::RUSAGE_INFO_V4,
usage.as_mut_ptr().cast(),
)
};
if result != 0 {
return HardwareCounters::default();
}
let usage = unsafe { usage.assume_init() };
HardwareCounters {
cpu_cycles: (usage.ri_cycles != 0).then_some(usage.ri_cycles),
instructions: (usage.ri_instructions != 0).then_some(usage.ri_instructions),
..Default::default()
}
}