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
|
use std::collections::HashMap;
use events::Event;
use perf_event::events::Hardware;
use perf_event::*;
#[derive(Default)]
pub struct PerfEstimator {
registry: HashMap<u64, Counters>,
}
struct Counters {
group: Group,
counters: Vec<Counter>,
}
static EVENT_TYPES: &[(f32, Event)] = &[
(1.0, Event::Hardware(Hardware::CPU_CYCLES)),
(2.0, Event::Hardware(Hardware::INSTRUCTIONS)),
];
impl super::KernelModule for PerfEstimator {
fn start_trace(&mut self, pid: u64) {
let Ok(mut group) = Group::new() else {
println!("failed to create Group");
return;
};
let counters = EVENT_TYPES
.iter()
.map(|(_, kind)| {
Builder::new()
.group(&mut group)
.kind(kind.clone())
.build()
.unwrap()
})
.collect();
group.enable().unwrap();
let counters = Counters { counters, group };
self.registry.insert(pid, counters);
}
fn stop_trace(&mut self, pid: u64) {
self.registry.remove(&pid);
}
fn read_consumption(&mut self, pid: u64) -> u64 {
let Some(counters) = self.registry.get_mut(&pid) else {
return 0;
};
let mut sum = 0;
let counts = counters.group.read().unwrap();
for ((factor, _ty), count) in EVENT_TYPES.iter().zip(counts.iter()) {
sum += *factor as u64 * count.1;
}
// dbg!(sum);
sum
}
}
|