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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
use iocuddle::*;
use rand::Rng;
pub mod perf;
pub trait KernelModule {
fn start_trace(&mut self, _pid: u64) {}
fn stop_trace(&mut self, _pid: u64) {}
fn read_consumption(&mut self, pid: u64) -> u64;
}
#[derive(Default)]
pub struct MockModule;
impl KernelModule for MockModule {
fn start_trace(&mut self, pid: u64) {
// println!("starting trace of {pid}");
}
fn stop_trace(&mut self, pid: u64) {
// println!("stopping trace of {pid}");
}
fn read_consumption(&mut self, _pid: u64) -> u64 {
// rand::rng().random()
14
}
}
#[derive(Debug)]
pub struct KernelDriver {
file: std::fs::File,
}
impl Default for KernelDriver {
fn default() -> Self {
KernelDriver::new("/dev/rust-pow").unwrap()
}
}
impl KernelDriver {
fn new(path: impl AsRef<std::path::Path>) -> Result<Self, std::io::Error> {
let file = std::fs::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 KernelModule for KernelDriver {
fn start_trace(&mut self, pid: u64) {
START_TRACE.ioctl(&mut self.file, &pid).unwrap();
}
fn stop_trace(&mut self, pid: u64) {
STOP_TRACE.ioctl(&mut self.file, &pid).unwrap();
}
fn read_consumption(&mut self, pid: u64) -> u64 {
let mut arg = pid;
READ_POWER.ioctl(&mut self.file, &mut arg).unwrap();
arg
}
}
|