aboutsummaryrefslogtreecommitdiffstats
path: root/darwin
diff options
context:
space:
mode:
authorDaniel Lange <DLange@git.local>2024-01-10 11:17:08 +0100
committerDaniel Lange <DLange@git.local>2024-01-10 11:17:08 +0100
commite7372d18a1a661d8c3dba9f51e1f17b5f94171a7 (patch)
treee8270dd60ec096bee8157dbadf029e15ed584592 /darwin
parent937052b231259a47d881d539ad5748245ef55b99 (diff)
downloaddebian_htop-e7372d18a1a661d8c3dba9f51e1f17b5f94171a7.tar.gz
debian_htop-e7372d18a1a661d8c3dba9f51e1f17b5f94171a7.tar.bz2
debian_htop-e7372d18a1a661d8c3dba9f51e1f17b5f94171a7.zip
New upstream version 3.3.0
Diffstat (limited to 'darwin')
-rw-r--r--darwin/DarwinMachine.c119
-rw-r--r--darwin/DarwinMachine.h28
-rw-r--r--darwin/DarwinProcess.c70
-rw-r--r--darwin/DarwinProcess.h8
-rw-r--r--darwin/DarwinProcessList.c202
-rw-r--r--darwin/DarwinProcessList.h39
-rw-r--r--darwin/DarwinProcessTable.c126
-rw-r--r--darwin/DarwinProcessTable.h22
-rw-r--r--darwin/Platform.c232
-rw-r--r--darwin/Platform.h34
-rw-r--r--darwin/PlatformHelpers.c14
-rw-r--r--darwin/PlatformHelpers.h2
12 files changed, 575 insertions, 321 deletions
diff --git a/darwin/DarwinMachine.c b/darwin/DarwinMachine.c
new file mode 100644
index 0000000..582d496
--- /dev/null
+++ b/darwin/DarwinMachine.c
@@ -0,0 +1,119 @@
+/*
+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(vm_statistics_t p) {
+ 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) {
+ CRT_fatalError("Unable to retrieve VM statistics");
+ }
+}
+
+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->vm_stats);
+ 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->vm_stats);
+
+ /* 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;
+}
diff --git a/darwin/DarwinMachine.h b/darwin/DarwinMachine.h
new file mode 100644
index 0000000..3135b58
--- /dev/null
+++ b/darwin/DarwinMachine.h
@@ -0,0 +1,28 @@
+#ifndef HEADER_DarwinMachine
+#define HEADER_DarwinMachine
+/*
+htop - DarwinMachine.h
+(C) 2014 Hisham H. Muhammad
+Released under the GNU GPLv2+, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include <mach/mach_host.h>
+#include <sys/sysctl.h>
+
+#include "Machine.h"
+#include "zfs/ZfsArcStats.h"
+
+
+typedef struct DarwinMachine_ {
+ Machine super;
+
+ host_basic_info_data_t host_info;
+ vm_statistics_data_t vm_stats;
+ processor_cpu_load_info_t prev_load;
+ processor_cpu_load_info_t curr_load;
+
+ ZfsArcStats zfs;
+} DarwinMachine;
+
+#endif
diff --git a/darwin/DarwinProcess.c b/darwin/DarwinProcess.c
index d0204dd..1e315eb 100644
--- a/darwin/DarwinProcess.c
+++ b/darwin/DarwinProcess.c
@@ -16,6 +16,7 @@ in the source distribution for its full text.
#include "CRT.h"
#include "Process.h"
+#include "darwin/DarwinMachine.h"
#include "darwin/Platform.h"
@@ -51,10 +52,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = {
[TRANSLATED] = { .name = "TRANSLATED", .title = "T ", .description = "Translation info (T translated, N native)", .flags = 0, },
};
-Process* DarwinProcess_new(const Settings* settings) {
+Process* DarwinProcess_new(const Machine* host) {
DarwinProcess* this = xCalloc(1, sizeof(DarwinProcess));
Object_setClass(this, Class(DarwinProcess));
- Process_init(&this->super, settings);
+ Process_init(&this->super, host);
this->utime = 0;
this->stime = 0;
@@ -71,18 +72,21 @@ void Process_delete(Object* cast) {
free(this);
}
-static void DarwinProcess_writeField(const Process* this, RichString* str, ProcessField field) {
- const DarwinProcess* dp = (const DarwinProcess*) this;
+static void DarwinProcess_rowWriteField(const Row* super, RichString* str, ProcessField field) {
+ const DarwinProcess* dp = (const DarwinProcess*) super;
+
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
- int n = sizeof(buffer) - 1;
+ size_t n = sizeof(buffer) - 1;
+
switch (field) {
// add Platform-specific fields here
case TRANSLATED: xSnprintf(buffer, n, "%c ", dp->translated ? 'T' : 'N'); break;
default:
- Process_writeField(this, str, field);
+ Process_writeField(&dp->super, str, field);
return;
}
+
RichString_appendWide(str, attr, buffer);
}
@@ -282,7 +286,7 @@ static char* DarwinProcess_getDevname(dev_t dev) {
return NULL;
}
char buf[sizeof("/dev/") + MAXNAMLEN];
- char *name = devname_r(dev, S_IFCHR, buf, MAXNAMLEN);
+ char* name = devname_r(dev, S_IFCHR, buf, MAXNAMLEN);
if (name) {
return xStrdup(name);
}
@@ -291,13 +295,14 @@ static char* DarwinProcess_getDevname(dev_t dev) {
void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists) {
DarwinProcess* dp = (DarwinProcess*)proc;
+ const Settings* settings = proc->super.host->settings;
const struct extern_proc* ep = &ps->kp_proc;
/* UNSET HERE :
*
* processor
- * user (set at ProcessList level)
+ * user (set at ProcessTable level)
* nlwp
* percent_cpu
* percent_mem
@@ -310,12 +315,12 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
/* First, the "immutable" parts */
if (!exists) {
/* Set the PID/PGID/etc. */
- proc->pid = ep->p_pid;
- proc->ppid = ps->kp_eproc.e_ppid;
+ Process_setPid(proc, ep->p_pid);
+ Process_setThreadGroup(proc, ep->p_pid);
+ Process_setParent(proc, ps->kp_eproc.e_ppid);
proc->pgrp = ps->kp_eproc.e_pgid;
proc->session = 0; /* TODO Get the session id */
proc->tpgid = ps->kp_eproc.e_tpgid;
- proc->tgid = proc->pid;
proc->isKernelThread = false;
proc->isUserlandThread = false;
dp->translated = ps->kp_proc.p_flag & P_TRANSLATED;
@@ -328,7 +333,7 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
DarwinProcess_updateExe(ep->p_pid, proc);
DarwinProcess_updateCmdLine(ps, proc);
- if (proc->settings->ss->flags & PROCESS_FLAG_CWD) {
+ if (settings->ss->flags & PROCESS_FLAG_CWD) {
DarwinProcess_updateCwd(ep->p_pid, proc);
}
}
@@ -341,7 +346,7 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
* To mitigate this we only fetch TTY information if the TTY
* field is enabled in the settings.
*/
- if (proc->settings->ss->flags & PROCESS_FLAG_TTY) {
+ if (settings->ss->flags & PROCESS_FLAG_TTY) {
proc->tty_name = DarwinProcess_getDevname(proc->tty_nr);
if (!proc->tty_name) {
/* devname failed: prevent us from calling it again */
@@ -357,13 +362,15 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
proc->state = (ep->p_stat == SZOMB) ? ZOMBIE : UNKNOWN;
/* Make sure the updated flag is set */
- proc->updated = true;
+ proc->super.updated = true;
}
-void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double timeIntervalNS) {
+void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessTable* dpt, double timeIntervalNS) {
struct proc_taskinfo pti;
- if (sizeof(pti) == proc_pidinfo(proc->super.pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) {
+ if (sizeof(pti) == proc_pidinfo(Process_getPid(&proc->super), PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) {
+ const DarwinMachine* dhost = (const DarwinMachine*) proc->super.super.host;
+
uint64_t total_existing_time_ns = proc->stime + proc->utime;
uint64_t user_time_ns = Platform_machTicksToNanoseconds(pti.pti_total_user);
@@ -385,15 +392,15 @@ void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList*
proc->super.m_resident = pti.pti_resident_size / ONE_K;
proc->super.majflt = pti.pti_faults;
proc->super.percent_mem = (double)pti.pti_resident_size * 100.0
- / (double)dpl->host_info.max_mem;
+ / (double)dhost->host_info.max_mem;
proc->stime = system_time_ns;
proc->utime = user_time_ns;
- dpl->super.kernelThreads += 0; /*pti.pti_threads_system;*/
- dpl->super.userlandThreads += pti.pti_threadnum; /*pti.pti_threads_user;*/
- dpl->super.totalTasks += pti.pti_threadnum;
- dpl->super.runningTasks += pti.pti_numrunning;
+ dpt->super.kernelThreads += 0; /*pti.pti_threads_system;*/
+ dpt->super.userlandThreads += pti.pti_threadnum; /*pti.pti_threads_user;*/
+ dpt->super.totalTasks += pti.pti_threadnum;
+ dpt->super.runningTasks += pti.pti_numrunning;
}
}
@@ -415,7 +422,7 @@ void DarwinProcess_scanThreads(DarwinProcess* dp) {
}
task_t port;
- ret = task_for_pid(mach_task_self(), proc->pid, &port);
+ ret = task_for_pid(mach_task_self(), Process_getPid(proc), &port);
if (ret != KERN_SUCCESS) {
dp->taskAccess = false;
return;
@@ -468,11 +475,18 @@ void DarwinProcess_scanThreads(DarwinProcess* dp) {
const ProcessClass DarwinProcess_class = {
.super = {
- .extends = Class(Process),
- .display = Process_display,
- .delete = Process_delete,
- .compare = Process_compare
+ .super = {
+ .extends = Class(Process),
+ .display = Row_display,
+ .delete = Process_delete,
+ .compare = Process_compare
+ },
+ .isHighlighted = Process_rowIsHighlighted,
+ .isVisible = Process_rowIsVisible,
+ .matchesFilter = Process_rowMatchesFilter,
+ .compareByParent = Process_compareByParent,
+ .sortKeyString = Process_rowGetSortKey,
+ .writeField = DarwinProcess_rowWriteField
},
- .writeField = DarwinProcess_writeField,
- .compareByKey = DarwinProcess_compareByKey,
+ .compareByKey = DarwinProcess_compareByKey
};
diff --git a/darwin/DarwinProcess.h b/darwin/DarwinProcess.h
index bd17974..496b179 100644
--- a/darwin/DarwinProcess.h
+++ b/darwin/DarwinProcess.h
@@ -9,8 +9,8 @@ in the source distribution for its full text.
#include <sys/sysctl.h>
-#include "Settings.h"
-#include "darwin/DarwinProcessList.h"
+#include "Machine.h"
+#include "darwin/DarwinProcessTable.h"
#define PROCESS_FLAG_TTY 0x00000100
@@ -28,13 +28,13 @@ extern const ProcessClass DarwinProcess_class;
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
-Process* DarwinProcess_new(const Settings* settings);
+Process* DarwinProcess_new(const Machine* settings);
void Process_delete(Object* cast);
void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists);
-void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList* dpl, double timeIntervalNS);
+void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessTable* dpt, double timeIntervalNS);
/*
* Scan threads for process state information.
diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c
deleted file mode 100644
index bd7821b..0000000
--- a/darwin/DarwinProcessList.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
-htop - DarwinProcessList.c
-(C) 2014 Hisham H. Muhammad
-Released under the GNU GPLv2+, see the COPYING file
-in the source distribution for its full text.
-*/
-
-#include "darwin/DarwinProcessList.h"
-
-#include <errno.h>
-#include <libproc.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <utmpx.h>
-#include <sys/mman.h>
-#include <sys/sysctl.h>
-
-#include "CRT.h"
-#include "ProcessList.h"
-#include "darwin/DarwinProcess.h"
-#include "darwin/Platform.h"
-#include "darwin/PlatformHelpers.h"
-#include "generic/openzfs_sysctl.h"
-#include "zfs/ZfsArcStats.h"
-
-
-static void ProcessList_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 ProcessList_freeCPULoadInfo(processor_cpu_load_info_t* p) {
- if (NULL != p && NULL != *p) {
- if (0 != munmap(*p, vm_page_size)) {
- CRT_fatalError("Unable to free old CPU load information");
- }
- *p = NULL;
- }
-}
-
-static unsigned ProcessList_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 woule 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 ProcessList_getVMStats(vm_statistics_t p) {
- 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) {
- CRT_fatalError("Unable to retrieve VM statistics");
- }
-}
-
-static struct kinfo_proc* ProcessList_getKInfoProcs(size_t* count) {
- int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
- struct kinfo_proc* processes = NULL;
-
- for (int retry = 3; retry > 0; retry--) {
- size_t size = 0;
- if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
- CRT_fatalError("Unable to get size of kproc_infos");
- }
-
- processes = xRealloc(processes, size);
-
- if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
- *count = size / sizeof(struct kinfo_proc);
- return processes;
- }
-
- if (errno != ENOMEM)
- break;
- }
-
- CRT_fatalError("Unable to get kinfo_procs");
-}
-
-ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, Hashtable* dynamicColumns, Hashtable* pidMatchList, uid_t userId) {
- DarwinProcessList* this = xCalloc(1, sizeof(DarwinProcessList));
-
- ProcessList_init(&this->super, Class(DarwinProcess), usersTable, dynamicMeters, dynamicColumns, pidMatchList, userId);
-
- /* Initialize the CPU information */
- this->super.activeCPUs = ProcessList_allocateCPULoadInfo(&this->prev_load);
- // TODO: support offline CPUs and hot swapping
- this->super.existingCPUs = this->super.activeCPUs;
- ProcessList_getHostInfo(&this->host_info);
- ProcessList_allocateCPULoadInfo(&this->curr_load);
-
- /* Initialize the VM statistics */
- ProcessList_getVMStats(&this->vm_stats);
-
- /* Initialize the ZFS kstats, if zfs.kext loaded */
- openzfs_sysctl_init(&this->zfs);
- openzfs_sysctl_updateArcStats(&this->zfs);
-
- this->super.kernelThreads = 0;
- this->super.userlandThreads = 0;
- this->super.totalTasks = 0;
- this->super.runningTasks = 0;
-
- return &this->super;
-}
-
-void ProcessList_delete(ProcessList* this) {
- ProcessList_done(this);
- free(this);
-}
-
-void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
- DarwinProcessList* dpl = (DarwinProcessList*)super;
- bool preExisting = true;
- struct kinfo_proc* ps;
- size_t count;
- DarwinProcess* proc;
-
- /* Update the global data (CPU times and VM stats) */
- ProcessList_freeCPULoadInfo(&dpl->prev_load);
- dpl->prev_load = dpl->curr_load;
- ProcessList_allocateCPULoadInfo(&dpl->curr_load);
- ProcessList_getVMStats(&dpl->vm_stats);
- openzfs_sysctl_updateArcStats(&dpl->zfs);
-
- // in pause mode only gather global data for meters (CPU/memory/...)
- if (pauseProcessUpdate) {
- return;
- }
-
- /* Get the time difference */
- dpl->global_diff = 0;
- for (unsigned int i = 0; i < dpl->super.existingCPUs; ++i) {
- for (size_t j = 0; j < CPU_STATE_MAX; ++j) {
- dpl->global_diff += dpl->curr_load[i].cpu_ticks[j] - dpl->prev_load[i].cpu_ticks[j];
- }
- }
-
- const double time_interval_ns = Platform_schedulerTicksToNanoseconds(dpl->global_diff) / (double) dpl->super.activeCPUs;
-
- /* Clear the thread counts */
- super->kernelThreads = 0;
- super->userlandThreads = 0;
- super->totalTasks = 0;
- super->runningTasks = 0;
-
- /* We use kinfo_procs for initial data since :
- *
- * 1) They always succeed.
- * 2) The contain the basic information.
- *
- * We attempt to fill-in additional information with libproc.
- */
- ps = ProcessList_getKInfoProcs(&count);
-
- for (size_t i = 0; i < count; ++i) {
- proc = (DarwinProcess*)ProcessList_getProcess(super, ps[i].kp_proc.p_pid, &preExisting, DarwinProcess_new);
-
- DarwinProcess_setFromKInfoProc(&proc->super, &ps[i], preExisting);
- DarwinProcess_setFromLibprocPidinfo(proc, dpl, time_interval_ns);
-
- if (proc->super.st_uid != ps[i].kp_eproc.e_ucred.cr_uid) {
- proc->super.st_uid = ps[i].kp_eproc.e_ucred.cr_uid;
- proc->super.user = UsersTable_getRef(super->usersTable, proc->super.st_uid);
- }
-
- // Disabled for High Sierra due to bug in macOS High Sierra
- bool isScanThreadSupported = !Platform_KernelVersionIsBetween((KernelVersion) {17, 0, 0}, (KernelVersion) {17, 5, 0});
-
- if (isScanThreadSupported) {
- DarwinProcess_scanThreads(proc);
- }
-
- super->totalTasks += 1;
-
- if (!preExisting) {
- ProcessList_add(super, &proc->super);
- }
- }
-
- free(ps);
-}
-
-bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id) {
- assert(id < super->existingCPUs);
-
- // TODO: support offline CPUs and hot swapping
- (void) super; (void) id;
-
- return true;
-}
diff --git a/darwin/DarwinProcessList.h b/darwin/DarwinProcessList.h
deleted file mode 100644
index 393e656..0000000
--- a/darwin/DarwinProcessList.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef HEADER_DarwinProcessList
-#define HEADER_DarwinProcessList
-/*
-htop - DarwinProcessList.h
-(C) 2014 Hisham H. Muhammad
-Released under the GNU GPLv2+, see the COPYING file
-in the source distribution for its full text.
-*/
-
-#include <mach/mach_host.h>
-#include <sys/sysctl.h>
-
-#include "ProcessList.h"
-#include "zfs/ZfsArcStats.h"
-
-
-typedef struct DarwinProcessList_ {
- ProcessList super;
-
- host_basic_info_data_t host_info;
- vm_statistics_data_t vm_stats;
- processor_cpu_load_info_t prev_load;
- processor_cpu_load_info_t curr_load;
- uint64_t kernel_threads;
- uint64_t user_threads;
- uint64_t global_diff;
-
- ZfsArcStats zfs;
-} DarwinProcessList;
-
-ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, Hashtable* dynamicColumns, Hashtable* pidMatchList, uid_t userId);
-
-void ProcessList_delete(ProcessList* this);
-
-void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate);
-
-bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id);
-
-#endif
diff --git a/darwin/DarwinProcessTable.c b/darwin/DarwinProcessTable.c
new file mode 100644
index 0000000..850b503
--- /dev/null
+++ b/darwin/DarwinProcessTable.c
@@ -0,0 +1,126 @@
+/*
+htop - DarwinProcessTable.c
+(C) 2014 Hisham H. Muhammad
+Released under the GNU GPLv2+, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include "darwin/DarwinProcessTable.h"
+
+#include <errno.h>
+#include <libproc.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <utmpx.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+
+#include "CRT.h"
+#include "ProcessTable.h"
+#include "darwin/DarwinMachine.h"
+#include "darwin/DarwinProcess.h"
+#include "darwin/Platform.h"
+#include "darwin/PlatformHelpers.h"
+#include "generic/openzfs_sysctl.h"
+#include "zfs/ZfsArcStats.h"
+
+
+static struct kinfo_proc* ProcessTable_getKInfoProcs(size_t* count) {
+ int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
+ struct kinfo_proc* processes = NULL;
+
+ for (unsigned int retry = 0; retry < 4; retry++) {
+ size_t size = 0;
+ if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
+ CRT_fatalError("Unable to get size of kproc_infos");
+ }
+
+ size += 16 * retry * retry * sizeof(struct kinfo_proc);
+ processes = xRealloc(processes, size);
+
+ if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
+ *count = size / sizeof(struct kinfo_proc);
+ return processes;
+ }
+
+ if (errno != ENOMEM)
+ break;
+ }
+
+ CRT_fatalError("Unable to get kinfo_procs");
+}
+
+ProcessTable* ProcessTable_new(Machine* host, Hashtable* pidMatchList) {
+ DarwinProcessTable* this = xCalloc(1, sizeof(DarwinProcessTable));
+ Object_setClass(this, Class(ProcessTable));
+
+ ProcessTable* super = &this->super;
+ ProcessTable_init(super, Class(DarwinProcess), host, pidMatchList);
+
+ return super;
+}
+
+void ProcessTable_delete(Object* cast) {
+ DarwinProcessTable* this = (DarwinProcessTable*) cast;
+ ProcessTable_done(&this->super);
+ free(this);
+}
+
+void ProcessTable_goThroughEntries(ProcessTable* super) {
+ const Machine* host = super->super.host;
+ const DarwinMachine* dhost = (const DarwinMachine*) host;
+ DarwinProcessTable* dpt = (DarwinProcessTable*) super;
+ bool preExisting = true;
+ struct kinfo_proc* ps;
+ size_t count;
+ DarwinProcess* proc;
+
+ /* Get the time difference */
+ dpt->global_diff = 0;
+ for (unsigned int i = 0; i < host->existingCPUs; ++i) {
+ for (size_t j = 0; j < CPU_STATE_MAX; ++j) {
+ dpt->global_diff += dhost->curr_load[i].cpu_ticks[j] - dhost->prev_load[i].cpu_ticks[j];
+ }
+ }
+
+ const double time_interval_ns = Platform_schedulerTicksToNanoseconds(dpt->global_diff) / (double) host->activeCPUs;
+
+ /* We use kinfo_procs for initial data since :
+ *
+ * 1) They always succeed.
+ * 2) They contain the basic information.
+ *
+ * We attempt to fill-in additional information with libproc.
+ */
+ ps = ProcessTable_getKInfoProcs(&count);
+
+ for (size_t i = 0; i < count; ++i) {
+ proc = (DarwinProcess*)ProcessTable_getProcess(super, ps[i].kp_proc.p_pid, &preExisting, DarwinProcess_new);
+
+ DarwinProcess_setFromKInfoProc(&proc->super, &ps[i], preExisting);
+ DarwinProcess_setFromLibprocPidinfo(proc, dpt, time_interval_ns);
+
+ if (proc->super.st_uid != ps[i].kp_eproc.e_ucred.cr_uid) {
+ proc->super.st_uid = ps[i].kp_eproc.e_ucred.cr_uid;
+ proc->super.user = UsersTable_getRef(host->usersTable, proc->super.st_uid);
+ }
+
+ // Disabled for High Sierra due to bug in macOS High Sierra
+ bool isScanThreadSupported = !Platform_KernelVersionIsBetween((KernelVersion) {17, 0, 0}, (KernelVersion) {17, 5, 0});
+
+ if (isScanThreadSupported) {
+ DarwinProcess_scanThreads(proc);
+ }
+
+ super->totalTasks += 1;
+
+ if (!preExisting) {
+ ProcessTable_add(super, &proc->super);
+ }
+ }
+
+ free(ps);
+}
diff --git a/darwin/DarwinProcessTable.h b/darwin/DarwinProcessTable.h
new file mode 100644
index 0000000..7467bfd
--- /dev/null
+++ b/darwin/DarwinProcessTable.h
@@ -0,0 +1,22 @@
+#ifndef HEADER_DarwinProcessTable
+#define HEADER_DarwinProcessTable
+/*
+htop - DarwinProcessTable.h
+(C) 2014 Hisham H. Muhammad
+Released under the GNU GPLv2+, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include <mach/mach_host.h>
+#include <sys/sysctl.h>
+
+#include "ProcessTable.h"
+
+
+typedef struct DarwinProcessTable_ {
+ ProcessTable super;
+
+ uint64_t global_diff;
+} DarwinProcessTable;
+
+#endif
diff --git a/darwin/Platform.c b/darwin/Platform.c
index 4b34d88..387910e 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -14,16 +14,30 @@ in the source distribution for its full text.
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <sys/socket.h>
+#include <sys/_types/_mach_port_t.h>
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFDictionary.h>
+#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CoreFoundation.h>
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOTypes.h>
#include <IOKit/ps/IOPowerSources.h>
#include <IOKit/ps/IOPSKeys.h>
+#include <IOKit/storage/IOBlockStorageDriver.h>
#include "ClockMeter.h"
#include "CPUMeter.h"
#include "CRT.h"
#include "DateMeter.h"
#include "DateTimeMeter.h"
+#include "FileDescriptorMeter.h"
#include "HostnameMeter.h"
#include "LoadAverageMeter.h"
#include "Macros.h"
@@ -34,8 +48,9 @@ in the source distribution for its full text.
#include "SysArchMeter.h"
#include "TasksMeter.h"
#include "UptimeMeter.h"
-#include "darwin/DarwinProcessList.h"
+#include "darwin/DarwinMachine.h"
#include "darwin/PlatformHelpers.h"
+#include "generic/fdstat_sysctl.h"
#include "zfs/ZfsArcMeter.h"
#include "zfs/ZfsCompressedArcMeter.h"
@@ -126,6 +141,9 @@ const MeterClass* const Platform_meterTypes[] = {
&RightCPUs8Meter_class,
&ZfsArcMeter_class,
&ZfsCompressedArcMeter_class,
+ &DiskIOMeter_class,
+ &NetworkIOMeter_class,
+ &FileDescriptorMeter_class,
&BlankMeter_class,
NULL
};
@@ -134,6 +152,9 @@ static double Platform_nanosecondsPerMachTick = 1.0;
static double Platform_nanosecondsPerSchedulerTick = -1;
+static bool iokit_available = false;
+static mach_port_t iokit_port; // the mach port used to initiate communication with IOKit
+
bool Platform_init(void) {
Platform_nanosecondsPerMachTick = Platform_calculateNanosecondsPerMachTick();
@@ -148,6 +169,17 @@ bool Platform_init(void) {
const double nanos_per_sec = 1e9;
Platform_nanosecondsPerSchedulerTick = nanos_per_sec / scheduler_ticks_per_sec;
+ // Since macOS 12.0, IOMasterPort is deprecated, and one should use IOMainPort instead
+ #if defined(HAVE_DECL_IOMAINPORT) && HAVE_DECL_IOMAINPORT
+ if (!IOMainPort(bootstrap_port, &iokit_port)) {
+ iokit_available = true;
+ }
+ #elif defined(HAVE_DECL_IOMASTERPORT) && HAVE_DECL_IOMASTERPORT
+ if (!IOMasterPort(bootstrap_port, &iokit_port)) {
+ iokit_available = true;
+ }
+ #endif
+
return true;
}
@@ -172,7 +204,7 @@ void Platform_setBindings(Htop_Action* keys) {
(void) keys;
}
-int Platform_getUptime() {
+int Platform_getUptime(void) {
struct timeval bootTime, currTime;
int mib[2] = { CTL_KERN, KERN_BOOTTIME };
size_t size = sizeof(bootTime);
@@ -200,19 +232,19 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
}
}
-int Platform_getMaxPid() {
+pid_t Platform_getMaxPid(void) {
/* http://opensource.apple.com/source/xnu/xnu-2782.1.97/bsd/sys/proc_internal.hh */
return 99999;
}
static double Platform_setCPUAverageValues(Meter* mtr) {
- const ProcessList* dpl = mtr->pl;
- unsigned int activeCPUs = dpl->activeCPUs;
+ const Machine* host = mtr->host;
+ unsigned int activeCPUs = host->activeCPUs;
double sumNice = 0.0;
double sumNormal = 0.0;
double sumKernel = 0.0;
double sumPercent = 0.0;
- for (unsigned int i = 1; i <= dpl->existingCPUs; i++) {
+ for (unsigned int i = 1; i <= host->existingCPUs; i++) {
sumPercent += Platform_setCPUValues(mtr, i);
sumNice += mtr->values[CPU_METER_NICE];
sumNormal += mtr->values[CPU_METER_NORMAL];
@@ -230,9 +262,9 @@ double Platform_setCPUValues(Meter* mtr, unsigned int cpu) {
return Platform_setCPUAverageValues(mtr);
}
- const DarwinProcessList* dpl = (const DarwinProcessList*)mtr->pl;
- const processor_cpu_load_info_t prev = &dpl->prev_load[cpu - 1];
- const processor_cpu_load_info_t curr = &dpl->curr_load[cpu - 1];
+ const DarwinMachine* dhost = (const DarwinMachine*) mtr->host;
+ const processor_cpu_load_info_t prev = &dhost->prev_load[cpu - 1];
+ const processor_cpu_load_info_t curr = &dhost->curr_load[cpu - 1];
double total = 0;
/* Take the sums */
@@ -259,16 +291,17 @@ double Platform_setCPUValues(Meter* mtr, unsigned int cpu) {
}
void Platform_setMemoryValues(Meter* mtr) {
- const DarwinProcessList* dpl = (const DarwinProcessList*)mtr->pl;
- const struct vm_statistics* vm = &dpl->vm_stats;
+ const DarwinMachine* dhost = (const DarwinMachine*) mtr->host;
+ const struct vm_statistics* vm = &dhost->vm_stats;
double page_K = (double)vm_page_size / (double)1024;
- mtr->total = dpl->host_info.max_mem / 1024;
- mtr->values[0] = (double)(vm->active_count + vm->wire_count) * page_K;
- mtr->values[1] = (double)vm->purgeable_count * page_K;
- // mtr->values[2] = "shared memory, like tmpfs and shm"
- mtr->values[3] = (double)vm->inactive_count * page_K;
- // mtr->values[4] = "available memory"
+ mtr->total = dhost->host_info.max_mem / 1024;
+ mtr->values[MEMORY_METER_USED] = (double)(vm->active_count + vm->wire_count) * page_K;
+ // mtr->values[MEMORY_METER_SHARED] = "shared memory, like tmpfs and shm"
+ // mtr->values[MEMORY_METER_COMPRESSED] = "compressed memory, like zswap on linux"
+ 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"
}
void Platform_setSwapValues(Meter* mtr) {
@@ -278,19 +311,21 @@ void Platform_setSwapValues(Meter* mtr) {
sysctl(mib, 2, &swapused, &swlen, NULL, 0);
mtr->total = swapused.xsu_total / 1024;
- mtr->values[0] = swapused.xsu_used / 1024;
+ mtr->values[SWAP_METER_USED] = swapused.xsu_used / 1024;
+ // mtr->values[SWAP_METER_CACHE] = "pages that are both in swap and RAM, like SwapCached on linux"
+ // mtr->values[SWAP_METER_FRONTSWAP] = "pages that are accounted to swap but stored elsewhere, like frontswap on linux"
}
void Platform_setZfsArcValues(Meter* this) {
- const DarwinProcessList* dpl = (const DarwinProcessList*) this->pl;
+ const DarwinMachine* dhost = (const DarwinMachine*) this->host;
- ZfsArcMeter_readStats(this, &(dpl->zfs));
+ ZfsArcMeter_readStats(this, &dhost->zfs);
}
void Platform_setZfsCompressedArcValues(Meter* this) {
- const DarwinProcessList* dpl = (const DarwinProcessList*) this->pl;
+ const DarwinMachine* dhost = (const DarwinMachine*) this->host;
- ZfsCompressedArcMeter_readStats(this, &(dpl->zfs));
+ ZfsCompressedArcMeter_readStats(this, &dhost->zfs);
}
char* Platform_getProcessEnv(pid_t pid) {
@@ -344,27 +379,158 @@ char* Platform_getProcessEnv(pid_t pid) {
return env;
}
-char* Platform_getInodeFilename(pid_t pid, ino_t inode) {
+FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) {
(void)pid;
- (void)inode;
return NULL;
}
-FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) {
- (void)pid;
- return NULL;
+void Platform_getFileDescriptors(double* used, double* max) {
+ Generic_getFileDescriptors_sysctl(used, max);
}
bool Platform_getDiskIO(DiskIOData* data) {
- // TODO
- (void)data;
- return false;
+ if (!iokit_available)
+ return false;
+
+ io_iterator_t drive_list;
+
+ /* Get the list of all drives */
+ if (IOServiceGetMatchingServices(iokit_port, IOServiceMatching("IOBlockStorageDriver"), &drive_list))
+ return false;
+
+ unsigned long long int read_sum = 0, write_sum = 0, timeSpend_sum = 0;
+
+ io_registry_entry_t drive;
+ while ((drive = IOIteratorNext(drive_list)) != 0) {
+ CFMutableDictionaryRef properties_tmp = NULL;
+
+ /* Get the properties of this drive */
+ if (IORegistryEntryCreateCFProperties(drive, &properties_tmp, kCFAllocatorDefault, 0)) {
+ IOObjectRelease(drive);
+ IOObjectRelease(drive_list);
+ return false;
+ }
+
+ if (!properties_tmp) {
+ IOObjectRelease(drive);
+ continue;
+ }
+
+ CFDictionaryRef properties = properties_tmp;
+
+ /* Get the statistics of this drive */
+ CFDictionaryRef statistics = (CFDictionaryRef) CFDictionaryGetValue(properties, CFSTR(kIOBlockStorageDriverStatisticsKey));
+
+ if (!statistics) {
+ CFRelease(properties);
+ IOObjectRelease(drive);
+ continue;
+ }
+
+ CFNumberRef number;
+ unsigned long long int value;
+
+ /* Get bytes read */
+ number = (CFNumberRef) CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey));
+ if (number != 0) {
+ CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+ read_sum += value;
+ }
+
+ /* Get bytes written */
+ number = (CFNumberRef) CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey));
+ if (number != 0) {
+ CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+ write_sum += value;
+ }
+
+ /* Get total read time (in ns) */
+ number = (CFNumberRef) CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsTotalReadTimeKey));
+ if (number != 0) {
+ CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+ timeSpend_sum += value;
+ }
+
+ /* Get total write time (in ns) */
+ number = (CFNumberRef) CFDictionaryGetValue(statistics, CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey));
+ if (number != 0) {
+ CFNumberGetValue(number, kCFNumberSInt64Type, &value);
+ timeSpend_sum += value;
+ }
+
+ CFRelease(properties);
+ IOObjectRelease(drive);
+ }
+
+ data->totalBytesRead = read_sum;
+ data->totalBytesWritten = write_sum;
+ data->totalMsTimeSpend = timeSpend_sum / 1e6; /* Convert from ns to ms */
+
+ if (drive_list)
+ IOObjectRelease(drive_list);
+
+ return true;
}
+/* Caution: Given that interfaces are dynamic, and it is not possible to get statistics on interfaces that no longer exist,
+ if some interface disappears between the time of two samples, the values of the second sample may be lower than those of
+ the first one. */
bool Platform_getNetworkIO(NetworkIOData* data) {
- // TODO
- (void)data;
- return false;
+ int mib[6] = {CTL_NET,
+ PF_ROUTE, /* routing messages */
+ 0, /* protocal number, currently always 0 */
+ 0, /* select all address families */
+ NET_RT_IFLIST2, /* interface list with addresses */
+ 0};
+
+ for (size_t retry = 0; retry < 4; retry++) {
+ size_t len = 0;
+
+ /* Determine len */
+ if (sysctl(mib, ARRAYSIZE(mib), NULL, &len, NULL, 0) < 0 || len == 0)
+ return false;
+
+ len += 16 * retry * retry * sizeof(struct if_msghdr2);
+ char *buf = xMalloc(len);
+
+ if (sysctl(mib, ARRAYSIZE(mib), buf, &len, NULL, 0) < 0) {
+ free(buf);
+ if (errno == ENOMEM && retry < 3)
+ continue;
+ else
+ return false;
+ }
+
+ uint64_t bytesReceived_sum = 0, packetsReceived_sum = 0, bytesTransmitted_sum = 0, packetsTransmitted_sum = 0;
+
+ for (char *next = buf; next < buf + len;) {
+ void *tmp = (void*) next;
+ struct if_msghdr *ifm = (struct if_msghdr*) tmp;
+
+ next += ifm->ifm_msglen;
+
+ if (ifm->ifm_type != RTM_IFINFO2)
+ continue;
+
+ struct if_msghdr2 *ifm2 = (struct if_msghdr2*) ifm;
+
+ if (ifm2->ifm_data.ifi_type != IFT_LOOP) { /* do not count loopback traffic */
+ bytesReceived_sum += ifm2->ifm_data.ifi_ibytes;
+ packetsReceived_sum += ifm2->ifm_data.ifi_ipackets;
+ bytesTransmitted_sum += ifm2->ifm_data.ifi_obytes;
+ packetsTransmitted_sum += ifm2->ifm_data.ifi_opackets;
+ }
+ }
+
+ data->bytesReceived = bytesReceived_sum;
+ data->packetsReceived = packetsReceived_sum;
+ data->bytesTransmitted = bytesTransmitted_sum;
+ data->packetsTransmitted = packetsTransmitted_sum;
+
+ free(buf);
+ }
+
+ return true;
}
void Platform_getBattery(double* percent, ACPresence* isOnAC) {
diff --git a/darwin/Platform.h b/darwin/Platform.h
index 4f8e7c9..f67db8f 100644
--- a/darwin/Platform.h
+++ b/darwin/Platform.h
@@ -54,7 +54,7 @@ int Platform_getUptime(void);
void Platform_getLoadAverage(double* one, double* five, double* fifteen);
-int Platform_getMaxPid(void);
+pid_t Platform_getMaxPid(void);
double Platform_setCPUValues(Meter* mtr, unsigned int cpu);
@@ -68,10 +68,10 @@ void Platform_setZfsCompressedArcValues(Meter* this);
char* Platform_getProcessEnv(pid_t pid);
-char* Platform_getInodeFilename(pid_t pid, ino_t inode);
-
FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid);
+void Platform_getFileDescriptors(double* used, double* max);
+
bool Platform_getDiskIO(DiskIOData* data);
bool Platform_getNetworkIO(NetworkIOData* data);
@@ -100,7 +100,9 @@ static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec)
void Platform_gettime_monotonic(uint64_t* msec);
-static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
+static inline Hashtable* Platform_dynamicMeters(void) {
+ return NULL;
+}
static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
@@ -110,12 +112,30 @@ static inline void Platform_dynamicMeterUpdateValues(ATTR_UNUSED Meter* meter) {
static inline void Platform_dynamicMeterDisplay(ATTR_UNUSED const Meter* meter, ATTR_UNUSED RichString* out) { }
-static inline Hashtable* Platform_dynamicColumns(void) { return NULL; }
+static inline Hashtable* Platform_dynamicColumns(void) {
+ return NULL;
+}
static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
-static inline const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
+static inline const char* Platform_dynamicColumnName(ATTR_UNUSED unsigned int key) {
+ return NULL;
+}
+
+static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) {
+ return false;
+}
+
+static inline Hashtable* Platform_dynamicScreens(void) {
+ return NULL;
+}
+
+static inline void Platform_defaultDynamicScreens(ATTR_UNUSED Settings* settings) { }
+
+static inline void Platform_addDynamicScreen(ATTR_UNUSED ScreenSettings* ss) { }
+
+static inline void Platform_addDynamicScreenAvailableColumns(ATTR_UNUSED Panel* availableColumns, ATTR_UNUSED const char* screen) { }
-static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
+static inline void Platform_dynamicScreensDone(ATTR_UNUSED Hashtable* screens) { }
#endif
diff --git a/darwin/PlatformHelpers.c b/darwin/PlatformHelpers.c
index bde9068..a4ea82b 100644
--- a/darwin/PlatformHelpers.c
+++ b/darwin/PlatformHelpers.c
@@ -58,7 +58,7 @@ bool Platform_KernelVersionIsBetween(KernelVersion lowerBound, KernelVersion upp
&& Platform_CompareKernelVersion(upperBound) < 0;
}
-void Platform_getCPUBrandString(char *cpuBrandString, size_t cpuBrandStringSize) {
+void Platform_getCPUBrandString(char* cpuBrandString, size_t cpuBrandStringSize) {
if (sysctlbyname("machdep.cpu.brand_string", cpuBrandString, &cpuBrandStringSize, NULL, 0) == -1) {
fprintf(stderr,
"WARN: Unable to determine the CPU brand string.\n"
@@ -69,12 +69,13 @@ void Platform_getCPUBrandString(char *cpuBrandString, size_t cpuBrandStringSize)
}
// Adapted from https://developer.apple.com/documentation/apple-silicon/about-the-rosetta-translation-environment
-bool Platform_isRunningTranslated() {
+bool Platform_isRunningTranslated(void) {
int ret = 0;
size_t size = sizeof(ret);
errno = 0;
if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) == -1) {
- if (errno == ENOENT) return false;
+ if (errno == ENOENT)
+ return false;
fprintf(stderr,
"WARN: Could not determine if this process was running in a translation environment like Rosetta 2.\n"
@@ -86,7 +87,7 @@ bool Platform_isRunningTranslated() {
return ret;
}
-double Platform_calculateNanosecondsPerMachTick() {
+double Platform_calculateNanosecondsPerMachTick(void) {
// Check if we can determine the timebase used on this system.
// If the API is unavailable assume we get our timebase in nanoseconds.
#ifndef HAVE_MACH_TIMEBASE_INFO
@@ -102,9 +103,8 @@ double Platform_calculateNanosecondsPerMachTick() {
* the "Apple M1" chip specifically when running under Rosetta 2.
*/
- size_t cpuBrandStringSize = 1024;
- char cpuBrandString[cpuBrandStringSize];
- Platform_getCPUBrandString(cpuBrandString, cpuBrandStringSize);
+ char cpuBrandString[1024] = "";
+ Platform_getCPUBrandString(cpuBrandString, sizeof(cpuBrandString));
bool isRunningUnderRosetta2 = Platform_isRunningTranslated();
diff --git a/darwin/PlatformHelpers.h b/darwin/PlatformHelpers.h
index 07f3fe2..45aea1a 100644
--- a/darwin/PlatformHelpers.h
+++ b/darwin/PlatformHelpers.h
@@ -31,7 +31,7 @@ bool Platform_KernelVersionIsBetween(KernelVersion lowerBound, KernelVersion upp
double Platform_calculateNanosecondsPerMachTick(void);
-void Platform_getCPUBrandString(char *cpuBrandString, size_t cpuBrandStringSize);
+void Platform_getCPUBrandString(char* cpuBrandString, size_t cpuBrandStringSize);
bool Platform_isRunningTranslated(void);

© 2014-2024 Faster IT GmbH | imprint | privacy policy