summaryrefslogtreecommitdiff
path: root/src/energy/trackers/kernel.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/energy/trackers/kernel.rs')
-rw-r--r--src/energy/trackers/kernel.rs49
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
+ }
+ }
+}