jcp-energy: the RAPL probe tests advance their fake zones on the probe's own tick #272
1 changed files with 55 additions and 48 deletions
|
|
@ -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!(
|
||||
|
|
|
|||
Loading…
Reference in a new issue