use std::collections::HashMap; use events::Event; use perf_event::events::Hardware; use perf_event::*; struct PerfEstimator { registry: HashMap, } struct Counters { group: Group, counters: Vec, } 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 mut group = Group::new().expect("failed to create Group"); 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; } sum } }