1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
/*
htop - DarwinMachine.c
(C) 2014 Hisham H. Muhammad
(C) 2023 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/
#include "darwin/DarwinMachine.h"
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/sysctl.h>
#include "CRT.h"
#include "Machine.h"
#include "darwin/Platform.h"
#include "darwin/PlatformHelpers.h"
#include "generic/openzfs_sysctl.h"
#include "zfs/ZfsArcStats.h"
static void DarwinMachine_getHostInfo(host_basic_info_data_t* p) {
mach_msg_type_number_t info_size = HOST_BASIC_INFO_COUNT;
if (0 != host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)p, &info_size)) {
CRT_fatalError("Unable to retrieve host info");
}
}
static void DarwinMachine_freeCPULoadInfo(processor_cpu_load_info_t* p) {
if (!p)
return;
if (!*p)
return;
if (0 != munmap(*p, vm_page_size)) {
CRT_fatalError("Unable to free old CPU load information");
}
*p = NULL;
}
static unsigned DarwinMachine_allocateCPULoadInfo(processor_cpu_load_info_t* p) {
mach_msg_type_number_t info_size = sizeof(processor_cpu_load_info_t);
unsigned cpu_count;
// TODO Improving the accuracy of the load counts would help a lot.
if (0 != host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &cpu_count, (processor_info_array_t*)p, &info_size)) {
CRT_fatalError("Unable to retrieve CPU info");
}
return cpu_count;
}
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)&this->vm_stats, &info_size) != 0) {
CRT_fatalError("Unable to retrieve VM statistics");
}
#endif
}
void Machine_scan(Machine* super) {
DarwinMachine* host = (DarwinMachine*) super;
/* Update the global data (CPU times and VM stats) */
DarwinMachine_freeCPULoadInfo(&host->prev_load);
host->prev_load = host->curr_load;
DarwinMachine_allocateCPULoadInfo(&host->curr_load);
DarwinMachine_getVMStats(host);
openzfs_sysctl_updateArcStats(&host->zfs);
}
Machine* Machine_new(UsersTable* usersTable, uid_t userId) {
DarwinMachine* this = xCalloc(1, sizeof(DarwinMachine));
Machine* super = &this->super;
Machine_init(super, usersTable, userId);
/* Initialize the CPU information */
super->activeCPUs = DarwinMachine_allocateCPULoadInfo(&this->prev_load);
super->existingCPUs = super->activeCPUs;
DarwinMachine_getHostInfo(&this->host_info);
DarwinMachine_allocateCPULoadInfo(&this->curr_load);
/* Initialize the VM statistics */
DarwinMachine_getVMStats(this);
/* Initialize the ZFS kstats, if zfs.kext loaded */
openzfs_sysctl_init(&this->zfs);
openzfs_sysctl_updateArcStats(&this->zfs);
return super;
}
void Machine_delete(Machine* super) {
DarwinMachine* this = (DarwinMachine*) super;
DarwinMachine_freeCPULoadInfo(&this->prev_load);
Machine_done(super);
free(this);
}
bool Machine_isCPUonline(const Machine* host, unsigned int id) {
assert(id < host->existingCPUs);
// TODO: support offline CPUs and hot swapping
(void) host; (void) id;
return true;
}
|