Last active
November 22, 2023 09:33
-
-
Save JShorthouse/3d34371637dcbe9e2ef78a35c3dc6c90 to your computer and use it in GitHub Desktop.
rust - macos CPU usage per core
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "cpu_usage" | |
version = "0.1.0" | |
edition = "2021" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[dependencies] | |
libc = "0.2.125" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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::<libc::integer_t>(), | |
); | |
} | |
} | |
} | |
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!(""); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Core 0: 5.0 | |
Core 1: 5.9 | |
Core 2: 3.0 | |
Core 3: 2.0 | |
Core 4: 72.3 | |
Core 5: 29.7 | |
Core 6: 67.7 | |
Core 7: 46.5 | |
Core 0: 9.0 | |
Core 1: 9.1 | |
Core 2: 8.0 | |
Core 3: 8.8 | |
Core 4: 79.0 | |
Core 5: 59.6 | |
Core 6: 93.0 | |
Core 7: 72.5 | |
Core 0: 6.9 | |
Core 1: 5.9 | |
Core 2: 4.0 | |
Core 3: 1.0 | |
Core 4: 98.0 | |
Core 5: 56.4 | |
Core 6: 100.0 | |
Core 7: 46.5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment