diff options
-rw-r--r-- | Cargo.lock | 20 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/mock.rs | 1 | ||||
-rw-r--r-- | src/mock/perf.rs | 56 |
4 files changed, 78 insertions, 0 deletions
@@ -615,6 +615,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] +name = "perf-event" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4d6393d9238342159080d79b78cb59c67399a8e7ecfa5d410bd614169e4e823" +dependencies = [ + "libc", + "perf-event-open-sys", +] + +[[package]] +name = "perf-event-open-sys" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c44fb1c7651a45a3652c4afc6e754e40b3d6e6556f1487e2b230bfc4f33c2a8" +dependencies = [ + "libc", +] + +[[package]] name = "pkg-config" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -636,6 +655,7 @@ dependencies = [ "iocuddle", "libbpf-rs 0.24.8", "libc", + "perf-event", "plain", "rand", "scx_rustland_core", @@ -14,6 +14,7 @@ scx_rustland_core = "2.2.8" rand = "0.9.0" iocuddle = "0.1.1" clap = { version = "4.5" , features = ["derive"] } +perf-event = "0.4.8" [build-dependencies] scx_rustland_core = "2.2.8" diff --git a/src/mock.rs b/src/mock.rs index 81bc32c..c5f8b34 100644 --- a/src/mock.rs +++ b/src/mock.rs @@ -1,5 +1,6 @@ use iocuddle::*; use rand::Rng; +mod perf; pub trait KernelModule { fn start_trace(&mut self, _pid: u64) {} diff --git a/src/mock/perf.rs b/src/mock/perf.rs new file mode 100644 index 0000000..4bf87c9 --- /dev/null +++ b/src/mock/perf.rs @@ -0,0 +1,56 @@ +use std::collections::HashMap; + +use events::Event; +use perf_event::events::Hardware; +use perf_event::*; + +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 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 + } +} |