From ee496b8ace0f807aa5e091629a5ac4b423499890 Mon Sep 17 00:00:00 2001 From: SuCicada Date: Mon, 8 Apr 2024 18:28:32 +0900 Subject: [PATCH] darwin: Enhance memory metrics support for Apple Silicon (ARM64) --- configure.ac | 15 +++++++++++++++ darwin/DarwinMachine.c | 16 ++++++++++++---- darwin/DarwinMachine.h | 4 ++++ darwin/Platform.c | 15 +++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 0a90ca48b..8ba787823 100644 --- a/configure.ac +++ b/configure.ac @@ -330,6 +330,21 @@ if test "$my_htop_platform" = darwin; then AC_CHECK_FUNCS([mach_timebase_info]) AC_CHECK_DECLS([IOMainPort], [], [], [[#include ]]) AC_CHECK_DECLS([IOMasterPort], [], [], [[#include ]]) + + AC_MSG_CHECKING([for vm_statistics64 supported]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include +#include + ]], [[ + mach_msg_type_number_t info_size = HOST_VM_INFO64_COUNT; + vm_statistics64_data_t vm_stat; + host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&vm_stat, &info_size); + ]] + )], + AC_DEFINE([HAVE_VM_STATISTICS64], 1, [The vm_statistics64 features is supported.]) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) fi if test "$my_htop_platform" = pcp; then diff --git a/darwin/DarwinMachine.c b/darwin/DarwinMachine.c index 582d49680..fff738832 100644 --- a/darwin/DarwinMachine.c +++ b/darwin/DarwinMachine.c @@ -59,12 +59,20 @@ static unsigned DarwinMachine_allocateCPULoadInfo(processor_cpu_load_info_t* p) return cpu_count; } -static void DarwinMachine_getVMStats(vm_statistics_t p) { +static void DarwinMachine_getVMStats(DarwinMachine* this) { +#ifdef HAVE_VM_STATISTICS64 + mach_msg_type_number_t info_size = HOST_VM_INFO64_COUNT; + + if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info_t)&this->vm_stats, &info_size) != 0) { + CRT_fatalError("Unable to retrieve VM statistics64"); + } +#else mach_msg_type_number_t info_size = HOST_VM_INFO_COUNT; - if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)p, &info_size) != 0) { + if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&this->vm_stats, &info_size) != 0) { CRT_fatalError("Unable to retrieve VM statistics"); } +#endif } void Machine_scan(Machine* super) { @@ -74,7 +82,7 @@ void Machine_scan(Machine* super) { DarwinMachine_freeCPULoadInfo(&host->prev_load); host->prev_load = host->curr_load; DarwinMachine_allocateCPULoadInfo(&host->curr_load); - DarwinMachine_getVMStats(&host->vm_stats); + DarwinMachine_getVMStats(host); openzfs_sysctl_updateArcStats(&host->zfs); } @@ -91,7 +99,7 @@ Machine* Machine_new(UsersTable* usersTable, uid_t userId) { DarwinMachine_allocateCPULoadInfo(&this->curr_load); /* Initialize the VM statistics */ - DarwinMachine_getVMStats(&this->vm_stats); + DarwinMachine_getVMStats(this); /* Initialize the ZFS kstats, if zfs.kext loaded */ openzfs_sysctl_init(&this->zfs); diff --git a/darwin/DarwinMachine.h b/darwin/DarwinMachine.h index 3135b5895..70cb55528 100644 --- a/darwin/DarwinMachine.h +++ b/darwin/DarwinMachine.h @@ -18,7 +18,11 @@ typedef struct DarwinMachine_ { Machine super; host_basic_info_data_t host_info; +#ifdef HAVE_VM_STATISTICS64 + vm_statistics64_data_t vm_stats; +#else vm_statistics_data_t vm_stats; +#endif processor_cpu_load_info_t prev_load; processor_cpu_load_info_t curr_load; diff --git a/darwin/Platform.c b/darwin/Platform.c index d16156c6e..4b7ff646a 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -292,13 +292,28 @@ double Platform_setCPUValues(Meter* mtr, unsigned int cpu) { void Platform_setMemoryValues(Meter* mtr) { const DarwinMachine* dhost = (const DarwinMachine*) mtr->host; +#ifdef HAVE_VM_STATISTICS64 + const struct vm_statistics64* vm = &dhost->vm_stats; +#else const struct vm_statistics* vm = &dhost->vm_stats; +#endif double page_K = (double)vm_page_size / (double)1024; mtr->total = dhost->host_info.max_mem / 1024; +#ifdef HAVE_VM_STATISTICS64 + natural_t used = vm->active_count + vm->inactive_count + + vm->speculative_count + vm->wire_count + + vm->compressor_page_count - vm->purgeable_count - vm->external_page_count; + mtr->values[MEMORY_METER_USED] = (double)(used - vm->compressor_page_count) * page_K; +#else mtr->values[MEMORY_METER_USED] = (double)(vm->active_count + vm->wire_count) * page_K; +#endif // mtr->values[MEMORY_METER_SHARED] = "shared memory, like tmpfs and shm" +#ifdef HAVE_VM_STATISTICS64 + mtr->values[MEMORY_METER_COMPRESSED] = (double)vm->compressor_page_count * page_K; +#else // mtr->values[MEMORY_METER_COMPRESSED] = "compressed memory, like zswap on linux" +#endif mtr->values[MEMORY_METER_BUFFERS] = (double)vm->purgeable_count * page_K; mtr->values[MEMORY_METER_CACHE] = (double)vm->inactive_count * page_K; // mtr->values[MEMORY_METER_AVAILABLE] = "available memory"