// references: // https://github.com/hdfssk/bubblemon/blob/master/osx/osx-meter.c#L78 // https://stackoverflow.com/questions/6785069/get-cpu-percent-usage-on-macos // https://github.com/apple/darwin-xnu/blob/main/osfmk/kern/host.c#L1125 // licence: MIT use libc; struct CoreSample { load: i32, idle: i32, } struct CpuSample { num_cores: u32, data: libc::processor_info_array_t, size: usize, } impl CpuSample { fn core(&self, core_num: usize) -> CoreSample { unsafe { let arr = std::slice::from_raw_parts(self.data, self.size); return CoreSample { load: arr[libc::CPU_STATE_MAX as usize * core_num + libc::CPU_STATE_USER as usize] + arr[libc::CPU_STATE_MAX as usize * core_num + libc::CPU_STATE_SYSTEM as usize], idle: arr[libc::CPU_STATE_MAX as usize * core_num + libc::CPU_STATE_IDLE as usize] + arr[libc::CPU_STATE_MAX as usize * core_num + libc::CPU_STATE_NICE as usize], }; } } } impl Drop for CpuSample { fn drop(&mut self) { unsafe { libc::vm_deallocate( libc::mach_task_self(), self.data as libc::vm_address_t, self.size * std::mem::size_of::(), ); } } } fn measure_cpu_sample() -> CpuSample { unsafe { let mut num_cores: libc::natural_t = 0; let mut cpu_info: libc::processor_info_array_t = std::ptr::null_mut(); let mut num_cpu_info: libc::mach_msg_type_number_t = 0; libc::host_processor_info( libc::mach_host_self(), libc::PROCESSOR_CPU_LOAD_INFO, &mut num_cores, &mut cpu_info, &mut num_cpu_info, ); return CpuSample{ num_cores, data: cpu_info, size: num_cpu_info as usize }; } } fn main() { let mut prev_sample = measure_cpu_sample(); let num_cores = prev_sample.num_cores; loop { std::thread::sleep(std::time::Duration::from_secs(1)); let this_sample = measure_cpu_sample(); for i in 0..num_cores as usize { let core_now = this_sample.core(i); let core_prev = prev_sample.core(i); let load = core_now.load - core_prev.load; let idle = core_now.idle - core_prev.idle; let total = load + idle; let percent = load as f32 / total as f32 * 100.0; println!("Core {}: {:6.1}", i, percent); } prev_sample = this_sample; println!(""); } }