From ea63b353962d29ddfbfcd12a0c0ebe995ef6848c Mon Sep 17 00:00:00 2001 From: cucadmuh <49571317+cucadmuh@users.noreply.github.com> Date: Sun, 31 May 2026 01:12:18 +0300 Subject: [PATCH] fix(perf): use Mach API for macOS host CPU ticks (#931) * fix(perf): use Mach host_processor_info for macOS CPU ticks KERN_CP_TIME and CPUSTATES are not exposed by libc on Darwin; switch read_host_total_cpu_ticks to host_processor_info so aarch64-apple-darwin CI builds succeed. * docs: CHANGELOG and credits for macOS perf CI fix (PR #931) * Revert "docs: CHANGELOG and credits for macOS perf CI fix (PR #931)" This reverts commit a217217c34d71b69034097116fa0aa1048008460. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.com> --- src-tauri/src/lib_commands/app_api/perf.rs | 41 +++++++++++++--------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src-tauri/src/lib_commands/app_api/perf.rs b/src-tauri/src/lib_commands/app_api/perf.rs index df8ba34e..001840d9 100644 --- a/src-tauri/src/lib_commands/app_api/perf.rs +++ b/src-tauri/src/lib_commands/app_api/perf.rs @@ -6,7 +6,7 @@ use serde::Serialize; #[cfg(target_os = "linux")] use std::collections::HashMap; -#[cfg(any(target_os = "linux", target_os = "macos"))] +#[cfg(target_os = "linux")] use std::sync::Mutex; #[cfg(target_os = "linux")] use std::fs; @@ -369,24 +369,33 @@ mod macos { } fn read_host_total_cpu_ticks() -> u64 { - let mut mib = [libc::CTL_KERN, libc::KERN_CP_TIME]; - let mut cp_time = [0_u64; libc::CPUSTATES as usize]; - let mut size = mem::size_of_val(&cp_time); + let mut num_cpus: u32 = 0; + let mut cpu_info: *mut i32 = std::ptr::null_mut(); + let mut num_cpu_info: u32 = 0; let ok = unsafe { - libc::sysctl( - mib.as_mut_ptr(), - mib.len() as _, - cp_time.as_mut_ptr() as *mut _, - &mut size, - std::ptr::null_mut(), - 0, - ) == 0 + libc::host_processor_info( + libc::mach_host_self(), + libc::PROCESSOR_CPU_LOAD_INFO, + &mut num_cpus, + &mut cpu_info, + &mut num_cpu_info, + ) == libc::KERN_SUCCESS }; - if ok { - cp_time.iter().sum() - } else { - 0 + if !ok || cpu_info.is_null() { + return 0; } + let total: u64 = unsafe { + std::slice::from_raw_parts(cpu_info, num_cpu_info as usize) + .iter() + .map(|&ticks| ticks as u64) + .sum() + }; + unsafe { + let size = num_cpu_info as usize * mem::size_of::(); + #[allow(deprecated)] + libc::vm_deallocate(libc::mach_task_self(), cpu_info as _, size); + } + total } fn refresh_target_processes(sys: &mut System, self_pid: Pid) -> Vec {