Skip to content

Instantly share code, notes, and snippets.

@JShorthouse
Last active November 22, 2023 09:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JShorthouse/3d34371637dcbe9e2ef78a35c3dc6c90 to your computer and use it in GitHub Desktop.
Save JShorthouse/3d34371637dcbe9e2ef78a35c3dc6c90 to your computer and use it in GitHub Desktop.
rust - macos CPU usage per core
[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"
// 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!("");
}
}
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