Skip to content

Commit

Permalink
darwin: Enhance memory metrics support for Apple Silicon (ARM64)
Browse files Browse the repository at this point in the history
  • Loading branch information
SuCicada committed Apr 12, 2024
1 parent 599233f commit ddd3aba
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 4 deletions.
4 changes: 4 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ if test "$my_htop_platform" = darwin; then
AC_CHECK_FUNCS([mach_timebase_info])
AC_CHECK_DECLS([IOMainPort], [], [], [[#include <IOKit/IOKitLib.h>]])
AC_CHECK_DECLS([IOMasterPort], [], [], [[#include <IOKit/IOKitLib.h>]])

AC_CHECK_FUNCS([host_statistics64], [
AC_CHECK_TYPES([struct vm_statistics64], [], [], [[#include <mach/vm_statistics.h>]])
], [])
fi

if test "$my_htop_platform" = pcp; then
Expand Down
16 changes: 12 additions & 4 deletions darwin/DarwinMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_STRUCT_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) {
Expand All @@ -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);
}

Expand All @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions darwin/DarwinMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ typedef struct DarwinMachine_ {
Machine super;

host_basic_info_data_t host_info;
#ifdef HAVE_STRUCT_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;

Expand Down
15 changes: 15 additions & 0 deletions darwin/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_STRUCT_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_STRUCT_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_STRUCT_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"
Expand Down

0 comments on commit ddd3aba

Please sign in to comment.