use iocuddle::*; use std::fs::File; use std::path::Path; use crate::energy::Estimator; #[derive(Debug)] pub struct KernelDriver { file: File, } impl Default for KernelDriver { fn default() -> Self { KernelDriver::new("/dev/rust-pow") .unwrap_or_else(|_| panic!("Failed to open kernel driver. Is the module loaded?")) } } impl KernelDriver { pub fn new(path: impl AsRef) -> Result { let file = File::open(path)?; Ok(Self { file }) } } const PERF_MON: Group = Group::new(b'|'); const START_TRACE: Ioctl = unsafe { PERF_MON.write(0x80) }; const STOP_TRACE: Ioctl = unsafe { PERF_MON.write(0x81) }; const READ_POWER: Ioctl = unsafe { PERF_MON.write_read(0x82) }; impl Estimator for KernelDriver { fn start_trace(&mut self, pid: u64, _cpu: i32) -> Result<(), ()> { let _ = START_TRACE.ioctl(&mut self.file, &pid); Ok(()) } fn stop_trace(&mut self, pid: u64) { let _ = STOP_TRACE.ioctl(&mut self.file, &pid); } fn update_information(&mut self, _pid: u64, _cpu: i32) {} fn read_consumption(&mut self, pid: u64) -> Option { let mut arg = pid; if READ_POWER.ioctl(&mut self.file, &mut arg).is_ok() { Some(arg as f64) } else { None } } }