| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
use crate::home::Home; |
| 6 |
use flow_core::api::Facts; |
| 7 |
use std::time::Instant; |
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
const REFERENCE_MS: f64 = 225.0; |
| 12 |
|
| 13 |
|
| 14 |
pub fn now(home: &Home, speed: Option<u32>) -> Facts { |
| 15 |
Facts { |
| 16 |
free_disk_mib: free_disk_mib(&home.root), |
| 17 |
load_x100: load_x100(), |
| 18 |
speed, |
| 19 |
speed_class: speed.map(Facts::class_of), |
| 20 |
kernel: std::fs::read_to_string("/proc/sys/kernel/osrelease").ok().map(|s| s.trim().to_string()), |
| 21 |
} |
| 22 |
} |
| 23 |
|
| 24 |
|
| 25 |
pub fn free_disk_mib(path: &std::path::Path) -> Option<u64> { |
| 26 |
use std::os::unix::ffi::OsStrExt; |
| 27 |
let c = std::ffi::CString::new(path.as_os_str().as_bytes()).ok()?; |
| 28 |
let mut s: libc::statvfs = unsafe { std::mem::zeroed() }; |
| 29 |
|
| 30 |
if unsafe { libc::statvfs(c.as_ptr(), &mut s) } != 0 { |
| 31 |
return None; |
| 32 |
} |
| 33 |
Some((s.f_bavail as u64).saturating_mul(s.f_frsize as u64) >> 20) |
| 34 |
} |
| 35 |
|
| 36 |
|
| 37 |
pub fn load_x100() -> Option<u32> { |
| 38 |
let text = std::fs::read_to_string("/proc/loadavg").ok()?; |
| 39 |
let first: f64 = text.split_whitespace().next()?.parse().ok()?; |
| 40 |
Some((first * 100.0).round() as u32) |
| 41 |
} |
| 42 |
|
| 43 |
|
| 44 |
|
| 45 |
|
| 46 |
pub fn bench() -> (u32, u128) { |
| 47 |
let start = Instant::now(); |
| 48 |
let buf: Vec<u8> = (0..32u32 << 20).map(|i| (i.wrapping_mul(2_654_435_761) >> 13) as u8).collect(); |
| 49 |
let mut h = blake3::Hasher::new(); |
| 50 |
for _ in 0..8 { |
| 51 |
h.update(&buf); |
| 52 |
} |
| 53 |
std::hint::black_box(h.finalize()); |
| 54 |
drop(buf); |
| 55 |
let mut x: u64 = 0x9e37_79b9_7f4a_7c15; |
| 56 |
let mut words: Vec<u64> = (0..4u64 << 20) |
| 57 |
.map(|_| { |
| 58 |
x ^= x << 13; |
| 59 |
x ^= x >> 7; |
| 60 |
x ^= x << 17; |
| 61 |
x |
| 62 |
}) |
| 63 |
.collect(); |
| 64 |
words.sort_unstable(); |
| 65 |
std::hint::black_box(&words); |
| 66 |
let ms = start.elapsed().as_millis().max(1); |
| 67 |
((REFERENCE_MS * 100.0 / ms as f64).round() as u32, ms) |
| 68 |
} |
| 69 |
|
| 70 |
#[cfg(test)] |
| 71 |
mod tests { |
| 72 |
use super::*; |
| 73 |
|
| 74 |
#[test] |
| 75 |
fn the_cheap_facts_are_read_and_classes_double() { |
| 76 |
assert!(free_disk_mib(std::path::Path::new("/")).is_some()); |
| 77 |
assert!(load_x100().is_some()); |
| 78 |
assert_eq!(Facts::class_of(100), 3, "the reference machine"); |
| 79 |
assert_eq!((Facts::class_of(50), Facts::class_of(200), Facts::class_of(500), Facts::class_of(10)), (2, 4, 5, 1)); |
| 80 |
} |
| 81 |
} |