blob: bf311dc7a6906f4b6fe0460a9a27646ebb308302 [file] [log] [blame]
David Hunt70e7c8d2015-07-12 13:47:43 -05001/*
2htop - DarwinProcessList.c
3(C) 2014 Hisham H. Muhammad
Daniel Lange94ad1112021-09-22 11:33:00 +02004Released under the GNU GPLv2+, see the COPYING file
David Hunt70e7c8d2015-07-12 13:47:43 -05005in the source distribution for its full text.
6*/
7
mayurdahibhate3f86a012021-04-29 23:43:36 +05308#include "darwin/DarwinProcessList.h"
David Hunt70e7c8d2015-07-12 13:47:43 -05009
Christian Göttsche72df9302020-11-17 15:17:19 +010010#include <errno.h>
Christian Göttschee3af8d02020-11-17 15:10:44 +010011#include <libproc.h>
12#include <stdbool.h>
13#include <stdio.h>
David Hunt70e7c8d2015-07-12 13:47:43 -050014#include <stdlib.h>
15#include <string.h>
David Hunt43ef7032015-07-13 01:17:14 -050016#include <unistd.h>
David Hunt57ab3322015-07-13 21:02:40 -050017#include <utmpx.h>
Christian Göttschee3af8d02020-11-17 15:10:44 +010018#include <sys/mman.h>
pmalhaire23f96042018-03-25 22:04:16 +020019#include <sys/sysctl.h>
Christian Göttschee3af8d02020-11-17 15:10:44 +010020
21#include "CRT.h"
Christian Göttschee3af8d02020-11-17 15:10:44 +010022#include "ProcessList.h"
Nathan Scott72235d82023-05-02 16:56:18 +100023#include "darwin/DarwinMachine.h"
mayurdahibhate3f86a012021-04-29 23:43:36 +053024#include "darwin/DarwinProcess.h"
25#include "darwin/Platform.h"
Alexander Momchilovdadcb872021-08-22 12:30:08 -040026#include "darwin/PlatformHelpers.h"
Nathan Scottadaf7482021-03-04 09:00:34 +110027#include "generic/openzfs_sysctl.h"
Christian Göttschee3af8d02020-11-17 15:10:44 +010028#include "zfs/ZfsArcStats.h"
29
pmalhaire23f96042018-03-25 22:04:16 +020030
Christian Göttschee3af8d02020-11-17 15:10:44 +010031static struct kinfo_proc* ProcessList_getKInfoProcs(size_t* count) {
David Hunt43ef7032015-07-13 01:17:14 -050032 int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
Benny Baumann61e14d42020-10-31 23:28:02 +010033 struct kinfo_proc* processes = NULL;
David Hunt43ef7032015-07-13 01:17:14 -050034
Christian Göttschebc22bee2022-09-20 21:40:02 +020035 for (unsigned int retry = 0; retry < 4; retry++) {
Christian Göttsche72df9302020-11-17 15:17:19 +010036 size_t size = 0;
37 if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0 || size == 0) {
38 CRT_fatalError("Unable to get size of kproc_infos");
39 }
40
Christian Göttschebc22bee2022-09-20 21:40:02 +020041 size += 16 * retry * retry * sizeof(struct kinfo_proc);
Christian Göttsche72df9302020-11-17 15:17:19 +010042 processes = xRealloc(processes, size);
43
44 if (sysctl(mib, 4, processes, &size, NULL, 0) == 0) {
45 *count = size / sizeof(struct kinfo_proc);
46 return processes;
47 }
48
49 if (errno != ENOMEM)
50 break;
Benny Baumann45869512020-11-01 01:09:51 +010051 }
David Hunt43ef7032015-07-13 01:17:14 -050052
Christian Göttsche72df9302020-11-17 15:17:19 +010053 CRT_fatalError("Unable to get kinfo_procs");
David Hunt43ef7032015-07-13 01:17:14 -050054}
55
Nathan Scott0bdade12023-05-02 09:02:22 +100056ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) {
Hishamb54d2dd2016-02-02 15:53:02 +010057 DarwinProcessList* this = xCalloc(1, sizeof(DarwinProcessList));
Nathan Scott72235d82023-05-02 16:56:18 +100058 ProcessList* super = &this->super;
David Hunt43ef7032015-07-13 01:17:14 -050059
Nathan Scott72235d82023-05-02 16:56:18 +100060 ProcessList_init(super, Class(DarwinProcess), host, pidMatchList);
David Hunt57ab3322015-07-13 21:02:40 -050061
Nathan Scott72235d82023-05-02 16:56:18 +100062 return super;
David Hunt70e7c8d2015-07-12 13:47:43 -050063}
64
65void ProcessList_delete(ProcessList* this) {
66 ProcessList_done(this);
67 free(this);
68}
69
Nathan Scott72235d82023-05-02 16:56:18 +100070void ProcessList_goThroughEntries(ProcessList* super) {
Nathan Scott0bdade12023-05-02 09:02:22 +100071 const Machine* host = super->host;
Nathan Scott72235d82023-05-02 16:56:18 +100072 const DarwinMachine* dhost = (const DarwinMachine*) host;
73 DarwinProcessList* dpl = (DarwinProcessList*) super;
Benny Baumannb23f8232020-10-31 22:14:27 +010074 bool preExisting = true;
75 struct kinfo_proc* ps;
76 size_t count;
77 DarwinProcess* proc;
David Hunt70e7c8d2015-07-12 13:47:43 -050078
Benny Baumannb23f8232020-10-31 22:14:27 +010079 /* Get the time difference */
80 dpl->global_diff = 0;
Nathan Scott0bdade12023-05-02 09:02:22 +100081 for (unsigned int i = 0; i < host->existingCPUs; ++i) {
Benny Baumannb23f8232020-10-31 22:14:27 +010082 for (size_t j = 0; j < CPU_STATE_MAX; ++j) {
Nathan Scott72235d82023-05-02 16:56:18 +100083 dpl->global_diff += dhost->curr_load[i].cpu_ticks[j] - dhost->prev_load[i].cpu_ticks[j];
Benny Baumannb23f8232020-10-31 22:14:27 +010084 }
85 }
David Hunt907f8292015-07-14 11:46:16 -050086
Nathan Scott0bdade12023-05-02 09:02:22 +100087 const double time_interval_ns = Platform_schedulerTicksToNanoseconds(dpl->global_diff) / (double) host->activeCPUs;
Alexander Momchilov67ccd6b2020-12-08 23:12:44 -050088
Benny Baumannb23f8232020-10-31 22:14:27 +010089 /* Clear the thread counts */
90 super->kernelThreads = 0;
91 super->userlandThreads = 0;
92 super->totalTasks = 0;
93 super->runningTasks = 0;
David Hunt7f3faa22015-07-13 16:53:46 -050094
Benny Baumannb23f8232020-10-31 22:14:27 +010095 /* We use kinfo_procs for initial data since :
96 *
97 * 1) They always succeed.
Guillaume Gomez8a8df712023-05-05 11:28:41 +020098 * 2) They contain the basic information.
Benny Baumannb23f8232020-10-31 22:14:27 +010099 *
100 * We attempt to fill-in additional information with libproc.
101 */
102 ps = ProcessList_getKInfoProcs(&count);
David Hunt70e7c8d2015-07-12 13:47:43 -0500103
Benny Baumannb23f8232020-10-31 22:14:27 +0100104 for (size_t i = 0; i < count; ++i) {
105 proc = (DarwinProcess*)ProcessList_getProcess(super, ps[i].kp_proc.p_pid, &preExisting, DarwinProcess_new);
David Hunt70e7c8d2015-07-12 13:47:43 -0500106
Benny Baumannb23f8232020-10-31 22:14:27 +0100107 DarwinProcess_setFromKInfoProc(&proc->super, &ps[i], preExisting);
Alexander Momchilov5b4d63d2021-08-20 17:52:07 -0400108 DarwinProcess_setFromLibprocPidinfo(proc, dpl, time_interval_ns);
pmalhaire23f96042018-03-25 22:04:16 +0200109
Benny Baumann6a6b09b2021-06-18 20:42:04 +0200110 if (proc->super.st_uid != ps[i].kp_eproc.e_ucred.cr_uid) {
111 proc->super.st_uid = ps[i].kp_eproc.e_ucred.cr_uid;
Nathan Scott0bdade12023-05-02 09:02:22 +1000112 proc->super.user = UsersTable_getRef(host->usersTable, proc->super.st_uid);
Benny Baumann6a6b09b2021-06-18 20:42:04 +0200113 }
114
Benny Baumannb23f8232020-10-31 22:14:27 +0100115 // Disabled for High Sierra due to bug in macOS High Sierra
Nathan Scott72235d82023-05-02 16:56:18 +1000116 bool isScanThreadSupported = !Platform_KernelVersionIsBetween((KernelVersion) {17, 0, 0}, (KernelVersion) {17, 5, 0});
pmalhaire23f96042018-03-25 22:04:16 +0200117
Benny Baumannb23f8232020-10-31 22:14:27 +0100118 if (isScanThreadSupported) {
119 DarwinProcess_scanThreads(proc);
120 }
David Hunt57ab3322015-07-13 21:02:40 -0500121
Benny Baumannb23f8232020-10-31 22:14:27 +0100122 super->totalTasks += 1;
David Hunt70e7c8d2015-07-12 13:47:43 -0500123
Benny Baumannb23f8232020-10-31 22:14:27 +0100124 if (!preExisting) {
Benny Baumannb23f8232020-10-31 22:14:27 +0100125 ProcessList_add(super, &proc->super);
126 }
127 }
David Hunt70e7c8d2015-07-12 13:47:43 -0500128
Benny Baumannb23f8232020-10-31 22:14:27 +0100129 free(ps);
David Hunt70e7c8d2015-07-12 13:47:43 -0500130}