//! `sysinfo`: how many CPUs there are, how busy each one is, and how many //! threads, processes and memory frames are in use. //! //! The load is measured, not guessed: each CPU counts its ~10 ms timer //! ticks, and how many of them interrupted real work rather than its idle //! thread. We read those counters twice, a quarter of a second apart; busy ticks //! divided by all ticks in between is that CPU's load. #![no_std] #![no_main] #[macro_use] #[path = "../../../rbrt/ulib.rs"] mod ulib; fn main() -> i64 { let before = ulib::sysinfo(); ulib::sleep_ms(250); // sleeping, not spinning: we don't count as load let after = ulib::sysinfo(); let seconds = after.uptime_ticks * 10 / 182; // the PIT ticks ~18.2 times a second println!( "{} CPU{} online (this program ran on CPU {}), up {} s", after.cpus, if after.cpus == 1 { "" } else { "s" }, after.this_cpu, seconds ); println!( "{} threads, {} processes, {} KiB of memory frames in use", after.threads, after.processes, after.frames_in_use * 4 ); println!("CPU load over the last quarter second:"); for cpu in 0..(after.cpus as usize).min(16) { let ticks = after.ticks[cpu] - before.ticks[cpu]; let busy = after.busy_ticks[cpu] - before.busy_ticks[cpu]; let percent = if ticks == 0 { 0 } else { busy * 100 / ticks }; // A 20-character bar: one '#' per 5%. let mut bar = [b'.'; 20]; for c in bar.iter_mut().take((percent / 5) as usize) { *c = b'#'; } let bar = core::str::from_utf8(&bar).unwrap_or(""); println!(" CPU{} [{}] {:3}%", cpu, bar, percent); } 0 }