1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
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, _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<f64> {
let mut arg = pid;
if READ_POWER.ioctl(&mut self.file, &mut arg).is_ok() {
Some(arg as f64)
} else {
None
}
}
}
|