pub const QUIET_LOAD: f64 = 2.0;
pub fn load_average() -> Option<f64> {
if let Ok(s) = std::fs::read_to_string("/proc/loadavg") {
return s.split_whitespace().next()?.parse().ok();
}
sysctl_load()
}
#[cfg(unix)]
fn sysctl_load() -> Option<f64> {
let out = std::process::Command::new("sysctl").args(["-n", "vm.loadavg"]).output().ok()?;
let text = String::from_utf8_lossy(&out.stdout);
text.split_whitespace().find_map(|t| t.parse::<f64>().ok())
}
#[cfg(not(unix))]
fn sysctl_load() -> Option<f64> {
None
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Timing {
pub seconds: f64,
pub load1: Option<f64>,
}
impl Timing {
pub fn around<T>(f: impl FnOnce() -> T) -> (T, Timing) {
let before = load_average();
let t0 = std::time::Instant::now();
let out = f();
let seconds = t0.elapsed().as_secs_f64();
let after = load_average();
let load1 = match (before, after) {
(Some(a), Some(b)) => Some(a.max(b)),
(Some(a), None) | (None, Some(a)) => Some(a),
(None, None) => None,
};
(out, Timing { seconds, load1 })
}
pub fn new(seconds: f64, load1: Option<f64>) -> Timing {
Timing { seconds, load1 }
}
pub fn trustworthy(&self) -> bool {
!matches!(self.load1, Some(l) if l > QUIET_LOAD)
}
pub fn as_measurement(&self) -> Option<f64> {
self.trustworthy().then_some(self.seconds)
}
pub fn caveat(&self) -> Option<String> {
match self.load1 {
Some(l) if l > QUIET_LOAD => Some(format!(
"the 1-minute load average reached {l:.1} during the run, so every time above is \
the run queue's number rather than this code's. A load average counts runnable \
threads; above {QUIET_LOAD:.0}, at least that many never slept. The results are \
unaffected -- a cut or a bound is the same number whoever else is on the CPU -- \
but the seconds are not a measurement. Re-run on a quiet machine for those."
)),
_ => None,
}
}
}
impl core::fmt::Display for Timing {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self.load1 {
Some(l) if l > QUIET_LOAD => {
write!(f, "{:.1} s -- NOT A MEASUREMENT, load {l:.1}", self.seconds)
}
Some(l) => write!(f, "{:.1} s, load {l:.2}", self.seconds),
None => write!(f, "{:.1} s, load unknown on this platform", self.seconds),
}
}
}
pub const ALLOW_BUSY: &str = "FERROTHERM_ALLOW_BUSY";
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Quiet {
Yes { load1: Option<f64> },
Overridden { load1: f64 },
}
impl Quiet {
pub fn caveat(&self) -> Option<String> {
match self {
Quiet::Yes { .. } => None,
Quiet::Overridden { load1 } => Some(format!(
"** {ALLOW_BUSY} is set and the 1-minute load average is {load1:.1}. Every rate \
below is therefore a lower bound on this machine's throughput, spoiled by an \
unknown amount. Do not quote it. **"
)),
}
}
}
pub fn require_quiet(what: &str) -> Result<Quiet, String> {
let allow = match std::env::var(ALLOW_BUSY) {
Ok(v) => !v.is_empty() && v != "0",
Err(_) => false,
};
decide(load_average(), allow, what)
}
fn decide(load1: Option<f64>, allow: bool, what: &str) -> Result<Quiet, String> {
match load1 {
Some(l) if l > QUIET_LOAD => {
if allow {
Ok(Quiet::Overridden { load1: l })
} else {
Err(format!(
"refusing to report {what}: the 1-minute load average is {l:.1}, and every \
number here is a wall-clock time divided into something, so what would be \
printed is this machine's contention rather than this code's speed. A load \
average counts runnable threads; above {QUIET_LOAD:.0}, at least that many \
never slept. Wait for the machine to go quiet, or set {ALLOW_BUSY}=1 to get \
the numbers anyway with that caveat attached to them."
))
}
}
_ => Ok(Quiet::Yes { load1 }),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_threshold_is_where_it_says_it_is() {
assert!(Timing::new(1.0, Some(0.0)).trustworthy());
assert!(Timing::new(1.0, Some(QUIET_LOAD)).trustworthy(), "the threshold itself is allowed");
assert!(!Timing::new(1.0, Some(QUIET_LOAD + 0.01)).trustworthy());
assert!(!Timing::new(1.0, Some(189.0)).trustworthy());
}
#[test]
fn an_unreadable_load_average_does_not_block_the_timing() {
let t = Timing::new(1.0, None);
assert!(t.trustworthy());
assert_eq!(t.as_measurement(), Some(1.0));
assert!(t.to_string().contains("unknown"), "but it says so: {t}");
}
#[test]
fn a_contaminated_timing_keeps_its_seconds_and_loses_its_status() {
let t = Timing::new(85.7, Some(189.4));
assert_eq!(t.seconds, 85.7, "the number is context, not a secret");
assert_eq!(t.as_measurement(), None, "but it is not a measurement");
let s = t.to_string();
assert!(s.contains("NOT A MEASUREMENT"), "{s}");
assert!(s.contains("189.4"), "the reader is told how busy: {s}");
assert!(s.len() < 60, "the inline form stays on one line: {s}");
let c = t.caveat().expect("a contaminated timing owes the reader an explanation");
assert!(c.contains("189.4") && c.contains("run queue"), "{c}");
assert!(
Timing::new(1.0, Some(0.5)).caveat().is_none(),
"a clean timing must not carry a warning"
);
}
#[test]
fn the_worse_of_the_two_samples_is_the_one_kept() {
assert_eq!(Timing::new(1.0, Some(0.1).map(|a: f64| a.max(9.0))).load1, Some(9.0));
let (_, t) = Timing::around(|| ());
if let Some(l) = t.load1 {
assert!(l >= 0.0 && l.is_finite(), "load {l}");
}
assert!(t.seconds >= 0.0);
}
#[test]
fn a_rate_is_refused_when_the_machine_is_busy() {
let e = decide(Some(157.0), false, "flips per second").unwrap_err();
assert!(e.contains("flips per second"), "names what it refused: {e}");
assert!(e.contains("157"), "says how busy: {e}");
assert!(e.contains(ALLOW_BUSY), "says how to override: {e}");
}
#[test]
fn a_quiet_machine_is_waved_through_with_its_reading() {
assert_eq!(decide(Some(0.4), false, "x"), Ok(Quiet::Yes { load1: Some(0.4) }));
assert_eq!(decide(Some(QUIET_LOAD), false, "x"), Ok(Quiet::Yes { load1: Some(QUIET_LOAD) }));
assert_eq!(decide(None, false, "x"), Ok(Quiet::Yes { load1: None }));
assert!(decide(Some(0.4), false, "x").unwrap().caveat().is_none());
}
#[test]
fn the_override_hands_back_a_caveat_rather_than_hiding_the_load() {
let q = decide(Some(157.0), true, "flips per second").unwrap();
assert_eq!(q, Quiet::Overridden { load1: 157.0 });
let c = q.caveat().expect("an overridden run must carry a caveat");
assert!(c.contains("157"), "{c}");
assert!(c.contains("lower bound"), "and says which way it is wrong: {c}");
}
#[test]
fn the_platform_reading_is_sane_or_absent() {
if let Some(l) = load_average() {
assert!(l.is_finite() && l >= 0.0, "load average {l}");
}
}
}