//! The RAPL liveness probe behind `rapl_status()` runs once per PROCESS, //! however many threads ask at once: a probe per call would burn about a //! second of CPU on each caller's thread where the counters are readable, and //! could flip the verdict mid-process. //! //! This file holds this one test, so that it runs in a process of its own and //! IS the first use of the RAPL meter in that process. The counter it reads, //! `real_rapl_probe_runs()`, counts runs of the production probe //! (`rapl_host_status`, whose first statement it is), not lookups of the cache. //! Off Linux there is no RAPL: the status is `Unavailable` and no probe runs. use proof_cascade::meter::{rapl_status, real_rapl_probe_runs, CounterStatus}; use std::sync::{Arc, Barrier}; #[test] fn the_rapl_liveness_probe_runs_once_per_process() { assert_eq!(real_rapl_probe_runs(), 0, "the RAPL meter was used in this process before this test"); const THREADS: usize = 8; let gate = Arc::new(Barrier::new(THREADS)); let handles: Vec<_> = (0..THREADS) .map(|_| { let gate = gate.clone(); std::thread::spawn(move || { gate.wait(); (rapl_status(), rapl_status()) }) }) .collect(); let seen: Vec<_> = handles.into_iter().map(|h| h.join().expect("a probing thread panicked")).collect(); let runs = real_rapl_probe_runs(); eprintln!("rapl cache: {THREADS} threads saw {:?}; real RAPL probe runs in this process: {runs}", seen[0].0); for (i, (status, again)) in seen.iter().enumerate() { assert_eq!((*status, *again), (seen[0].0, seen[0].0), "thread {i} was given a different status"); } if cfg!(target_os = "linux") { assert_eq!(runs, 1, "the RAPL liveness probe ran {runs} times in this process ({THREADS} threads asked at once)"); } else { assert_eq!(seen[0].0, CounterStatus::Unavailable, "RAPL off Linux"); assert_eq!(runs, 0, "a RAPL liveness probe ran off Linux"); } }