diff options
Diffstat (limited to 'src/energy/trackers/kernel.rs')
-rw-r--r-- | src/energy/trackers/kernel.rs | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/energy/trackers/kernel.rs b/src/energy/trackers/kernel.rs new file mode 100644 index 0000000..050805c --- /dev/null +++ b/src/energy/trackers/kernel.rs @@ -0,0 +1,49 @@ +// energy/trackers/kernel.rs +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<Path>) -> Result<Self, std::io::Error> { + let file = File::open(path)?; + Ok(Self { file }) + } +} + +const PERF_MON: Group = Group::new(b'|'); +const START_TRACE: Ioctl<Write, &u64> = unsafe { PERF_MON.write(0x80) }; +const STOP_TRACE: Ioctl<Write, &u64> = unsafe { PERF_MON.write(0x81) }; +const READ_POWER: Ioctl<WriteRead, &u64> = unsafe { PERF_MON.write_read(0x82) }; + +impl Estimator for KernelDriver { + fn start_trace(&mut self, pid: u64) { + let _ = START_TRACE.ioctl(&mut self.file, &pid); + } + + fn stop_trace(&mut self, pid: u64) { + let _ = STOP_TRACE.ioctl(&mut self.file, &pid); + } + + fn read_consumption(&mut self, pid: u64) -> u64 { + let mut arg = pid; + if let Ok(_) = READ_POWER.ioctl(&mut self.file, &mut arg) { + arg + } else { + 0 + } + } +} |