use std::hint::black_box; use std::time::{Duration, Instant}; #[derive(Debug, PartialEq)] struct Fault { message: String, locations: Vec<&'static str>, causes: Vec, } impl Fault { fn overflow(location: &'static str) -> Self { Self { message: "Int overflow".into(), locations: vec![location], causes: Vec::new(), } } fn at(mut self, location: &'static str) -> Self { self.locations.push(location); self } } struct Record { first: i64, second: i64, third: i64, } struct OwnedRecord { name: String, tags: Vec, count: i64, } fn inspect_owned(row: &OwnedRecord) -> Result { let partial = row .count .checked_add(row.name.chars().count() as i64) .ok_or_else(|| Fault::overflow("inspect_owned"))?; partial .checked_add(row.tags.len() as i64) .ok_or_else(|| Fault::overflow("inspect_owned")) } fn forward_owned(row: &OwnedRecord) -> Result { inspect_owned(row).map_err(|error| error.at("forward_owned")) } fn owned_sum(rows: &[OwnedRecord]) -> Result { let mut total = 0_i64; for row in rows { let projected = forward_owned(row).map_err(|error| error.at("call_read"))?; total = total .checked_add(projected) .ok_or_else(|| Fault::overflow("call_read"))?; } Ok(total) } fn add(total: i64, value: i64) -> Result { total .checked_add(value) .ok_or_else(|| Fault::overflow("add")) } fn record_value(row: &Record) -> Result { let partial = row .first .checked_add(row.second) .ok_or_else(|| Fault::overflow("record_value"))?; partial .checked_add(row.third) .ok_or_else(|| Fault::overflow("record_value")) } fn record_sum(values: &[Record]) -> Result { let mut total = 0i64; for row in values { let projected = record_value(row).map_err(|error| error.at("record_sum"))?; total = total .checked_add(projected) .ok_or_else(|| Fault::overflow("record_sum"))?; } Ok(total) } fn measure(operation: &str, ticks: &str) -> Result<(i64, Duration), Fault> { let source = black_box(ticks.as_bytes()); match operation { "call_read" => { let rows = source .iter() .map(|value| { let name = format!("row-value-{value}"); OwnedRecord { count: i64::from(*value) - name.chars().count() as i64 - 1, tags: vec![name.clone()], name, } }) .collect::>(); let borrowed = black_box(&rows); let begin = Instant::now(); let total = owned_sum(borrowed)?; black_box(total); let elapsed = begin.elapsed(); black_box(&rows); Ok((total, elapsed)) } "integer" => { let begin = Instant::now(); let mut total = 0; for value in source { total = add(total, i64::from(*value)).map_err(|error| error.at("integer"))?; } Ok((black_box(total), begin.elapsed())) } "list_record_read" => { let mut values = Vec::new(); for value in source { values.push(Record { first: i64::from(*value), second: 0, third: 0, }); } let borrowed = black_box(&values); let begin = Instant::now(); let total = record_sum(borrowed)?; black_box(total); drop(values); Ok((total, begin.elapsed())) } _ => panic!("unknown checked kernel"), } } fn verify_errors() { let fault = owned_sum(&[OwnedRecord { name: "overflow".into(), tags: vec!["preserved".into()], count: i64::MAX, }]) .unwrap_err(); assert_eq!(fault.message, "Int overflow"); assert_eq!( fault.locations, ["inspect_owned", "forward_owned", "call_read"] ); assert!(fault.causes.is_empty()); assert_eq!(add(i64::MAX, 0).unwrap(), i64::MAX); assert_eq!(add(i64::MIN, 0).unwrap(), i64::MIN); for (left, right) in [(i64::MAX, 1), (i64::MIN, -1)] { let fault = add(left, right).unwrap_err().at("integer"); assert_eq!(fault.message, "Int overflow"); assert_eq!(fault.locations, ["add", "integer"]); assert!(fault.causes.is_empty()); } let fault = record_sum(&[Record { first: i64::MAX, second: 1, third: 0, }]) .unwrap_err(); assert_eq!(fault.locations, ["record_value", "record_sum"]); let fault = record_sum(&[ Record { first: i64::MAX, second: 0, third: 0, }, Record { first: 1, second: 0, third: 0, }, ]) .unwrap_err(); assert_eq!(fault.locations, ["record_sum"]); } fn main() { let arguments = std::env::args().collect::>(); if arguments[1] == "--verify-errors" { verify_errors(); println!("checked overflow and error frames verified"); return; } let input: serde_json::Value = serde_json::from_str(&arguments[2]).expect("input object"); let ticks = input["ticks"].as_str().expect("ticks string"); let (operation, count) = arguments[1] .strip_prefix("continuous_") .map_or((arguments[1].as_str(), 1), |operation| (operation, 10)); let mut samples = Vec::new(); for _ in 0..count { match measure(operation, ticks) { Ok((checksum, elapsed)) => samples .push(serde_json::json!({"checksum": checksum, "elapsed_ns": elapsed.as_nanos()})), Err(error) => { eprintln!("{error:?}"); std::process::exit(1); } } } let output = if count == 1 { samples.pop().unwrap() } else { serde_json::Value::Array(samples) }; println!("{output}"); }