diff --git a/jcp/jcp-rs/crates/jcp-energy/src/lib.rs b/jcp/jcp-rs/crates/jcp-energy/src/lib.rs index 8c596f58c..a724bdf40 100644 --- a/jcp/jcp-rs/crates/jcp-energy/src/lib.rs +++ b/jcp/jcp-rs/crates/jcp-energy/src/lib.rs @@ -7368,39 +7368,53 @@ mod tests { } } + /// RAPL's probe — its opener on `tree`, its sampler, the CPU-burning tick, + /// the real clock, one budget — with `advance` run after each tick: the + /// fake hardware's rise for that interval. These tests once advanced the + /// zones from another thread on a 2 ms timer instead, which a loaded CI + /// host starved while the tick burned CPU: intervals went flat, and two + /// live packages read Frozen. On the probe's own thread the rise lands in + /// every interval, so the verdict is the rule's, not the scheduler's. + fn rapl_status_ticking(tree: &FakePowercap, mut advance: impl FnMut()) -> CounterStatus { + crate::liveness::status_of( + crate::liveness::probe( + || Rapl::open_in(&tree.root), + Rapl::liveness_sample, + || { + crate::liveness::burn_tick(); + advance(); + }, + std::time::Instant::now, + crate::liveness::BUDGET, + ) + .as_ref(), + ) + } + /// The real RAPL probe — the real reader on files, the CPU-burning tick, /// the real clock, one budget — on fake powercap trees. A tree whose - /// counters hold is Frozen; one whose two packages another thread - /// advances every 2 ms is Live; one where that thread advances package 0 - /// alone, package 1 holding, is Frozen; no tree, or a tree whose - /// `energy_uj` is not a number, is Unavailable, as RAPL was declined - /// before. + /// counters hold is Frozen; one whose two packages advance 4 mJ every tick + /// is Live; one where package 0 advances alone, package 1 holding, is + /// Frozen; no tree, or a tree whose `energy_uj` is not a number, is + /// Unavailable, as RAPL was declined before. #[test] fn the_rapl_probe_on_fake_powercap_trees() { - /// The real probe on `tree` while another thread advances the - /// packages in `advancing` by 4 mJ every 2 ms. + /// The probe on `tree`, the packages in `advancing` rising by 4 mJ at + /// every tick ([`rapl_status_ticking`]). fn probe_while_advancing(tree: &FakePowercap, advancing: &[usize]) -> CounterStatus { - let stop = std::sync::atomic::AtomicBool::new(false); - std::thread::scope(|s| { - s.spawn(|| { - let mut uj: u64 = 1_000; - while !stop.load(std::sync::atomic::Ordering::SeqCst) { - uj += 4_000; - for &k in advancing { - tree.write(k, &uj.to_string()); - } - std::thread::sleep(Duration::from_millis(2)); - } - }); - let started = std::time::Instant::now(); - let status = rapl_status_on(|| Rapl::open_in(&tree.root)); - eprintln!( - "rapl probe: a fake tree with packages {advancing:?} advancing every 2 ms -> {status:?} in {:?}", - started.elapsed() - ); - stop.store(true, std::sync::atomic::Ordering::SeqCst); - status - }) + let mut uj: u64 = 1_000; + let started = std::time::Instant::now(); + let status = rapl_status_ticking(tree, || { + uj += 4_000; + for &k in advancing { + tree.write(k, &uj.to_string()); + } + }); + eprintln!( + "rapl probe: a fake tree with packages {advancing:?} advancing every tick -> {status:?} in {:?}", + started.elapsed() + ); + status } #[cfg(target_os = "macos")] let _hw = ioreport_hw_lock(); @@ -8734,7 +8748,8 @@ mod tests { /// alone, although every other zone rose too; a package wrapping at its own /// range is corrected at that range. And the real probe is Live while the /// two packages advance with `psys` and `dram` holding, Frozen while - /// `psys`, `dram` and one package advance with the other package holding. + /// `psys`, `dram` and one package advance with the other package holding + /// (each advancing at every tick of the probe, [`rapl_status_ticking`]). #[test] fn rapl_sums_and_probes_the_package_zones_only() { #[cfg(target_os = "macos")] @@ -8778,26 +8793,18 @@ mod tests { assert_eq!((e.provenance, e.measured_uj), (Provenance::HwShunt, Some(12_487)), "{e:?}"); drop(meter); - /// The real probe on `tree` while another thread advances the zones - /// in `advancing` by 4 mJ every 2 ms. + /// The probe on `tree`, the zones in `advancing` rising by 4 mJ at + /// every tick ([`rapl_status_ticking`]). fn probe_advancing(tree: &FakePowercap, advancing: &[&str]) -> CounterStatus { - let stop = std::sync::atomic::AtomicBool::new(false); - std::thread::scope(|s| { - s.spawn(|| { - let mut uj: u64 = 100_000; - while !stop.load(std::sync::atomic::Ordering::SeqCst) { - uj += 4_000; - for dir in advancing { - tree.write_zone(dir, &uj.to_string()); - } - std::thread::sleep(Duration::from_millis(2)); - } - }); - let status = rapl_status_on(|| Rapl::open_in(&tree.root)); - eprintln!("rapl probe: zones {advancing:?} advancing, the rest holding -> {status:?}"); - stop.store(true, std::sync::atomic::Ordering::SeqCst); - status - }) + let mut uj: u64 = 100_000; + let status = rapl_status_ticking(tree, || { + uj += 4_000; + for dir in advancing { + tree.write_zone(dir, &uj.to_string()); + } + }); + eprintln!("rapl probe: zones {advancing:?} advancing, the rest holding -> {status:?}"); + status } let tree = two_sockets_with_psys_and_dram(); assert_eq!(