Skip to content

Commit

Permalink
Merge branch 'darwin-ps' of aestriplex/htop
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Lange authored and Daniel Lange committed Feb 25, 2025
2 parents 899c6b6 + 847547c commit b4ab345
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 59 deletions.
73 changes: 32 additions & 41 deletions darwin/DarwinProcess.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,40 +369,43 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps,
void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessTable* dpt, double timeIntervalNS) {
struct proc_taskinfo 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;
if (PROC_PIDTASKINFO_SIZE != proc_pidinfo(Process_getPid(&proc->super), PROC_PIDTASKINFO, 0, &pti, PROC_PIDTASKINFO_SIZE)) {
proc->taskAccess = false;
return;
}

uint64_t total_existing_time_ns = proc->stime + proc->utime;
const DarwinMachine* dhost = (const DarwinMachine*) proc->super.super.host;

uint64_t user_time_ns = Platform_machTicksToNanoseconds(pti.pti_total_user);
uint64_t system_time_ns = Platform_machTicksToNanoseconds(pti.pti_total_system);
uint64_t total_existing_time_ns = proc->stime + proc->utime;

uint64_t total_current_time_ns = user_time_ns + system_time_ns;
uint64_t user_time_ns = Platform_machTicksToNanoseconds(pti.pti_total_user);
uint64_t system_time_ns = Platform_machTicksToNanoseconds(pti.pti_total_system);

if (total_existing_time_ns && 1E-6 < timeIntervalNS) {
uint64_t total_time_diff_ns = total_current_time_ns - total_existing_time_ns;
proc->super.percent_cpu = ((double)total_time_diff_ns / timeIntervalNS) * 100.0;
} else {
proc->super.percent_cpu = 0.0;
}
Process_updateCPUFieldWidths(proc->super.percent_cpu);

proc->super.time = nanosecondsToCentiseconds(total_current_time_ns);
proc->super.nlwp = pti.pti_threadnum;
proc->super.m_virt = pti.pti_virtual_size / ONE_K;
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)dhost->host_info.max_mem;

proc->stime = system_time_ns;
proc->utime = user_time_ns;

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;
uint64_t total_current_time_ns = user_time_ns + system_time_ns;

if (total_existing_time_ns && 1E-6 < timeIntervalNS) {
uint64_t total_time_diff_ns = total_current_time_ns - total_existing_time_ns;
proc->super.percent_cpu = ((double)total_time_diff_ns / timeIntervalNS) * 100.0;
} else {
proc->super.percent_cpu = 0.0;
}
Process_updateCPUFieldWidths(proc->super.percent_cpu);

proc->super.state = pti.pti_numrunning > 0 ? RUNNING : SLEEPING;
proc->super.time = nanosecondsToCentiseconds(total_current_time_ns);
proc->super.nlwp = pti.pti_threadnum;
proc->super.m_virt = pti.pti_virtual_size / ONE_K;
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)dhost->host_info.max_mem;

proc->stime = system_time_ns;
proc->utime = user_time_ns;

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;
}

/*
Expand Down Expand Up @@ -434,18 +437,6 @@ void DarwinProcess_scanThreads(DarwinProcess* dp, DarwinProcessTable* dpt) {
return;
}

{
task_info_data_t tinfo;
mach_msg_type_number_t task_info_count = TASK_INFO_MAX;
ret = task_info(task, TASK_BASIC_INFO, (task_info_t) &tinfo, &task_info_count);
if (ret != KERN_SUCCESS) {
CRT_debug("task_info(%d) failed: %s", pid, mach_error_string(ret));
dp->taskAccess = false;
mach_port_deallocate(mach_task_self(), task);
return;
}
}

thread_array_t thread_list;
mach_msg_type_number_t thread_count;
ret = task_threads(task, &thread_list, &thread_count);
Expand Down
25 changes: 7 additions & 18 deletions darwin/DarwinProcessTable.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,6 @@ in the source distribution for its full text.
#include "zfs/ZfsArcStats.h"


static ProcessState ProcessTable_mapDarwinProcessState(int kinfo_proc_state) {
switch(kinfo_proc_state) {
case SRUN:
return RUNNING;
case SSLEEP:
return SLEEPING;
case SSTOP:
return STOPPED;
case SZOMB:
return ZOMBIE;
case SIDL:
return IDLE;
default:
return UNKNOWN;
}
}

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;
Expand Down Expand Up @@ -120,11 +103,17 @@ void ProcessTable_goThroughEntries(ProcessTable* super) {
DarwinProcess_setFromKInfoProc(&proc->super, &ps[i], preExisting);
DarwinProcess_setFromLibprocPidinfo(proc, dpt, time_interval_ns);

// Deduce further process states not covered in the libproc call above
if (ps[i].kp_proc.p_stat == SZOMB) {
proc->super.state = ZOMBIE;
} else if (ps[i].kp_proc.p_stat == SSTOP) {
proc->super.state = STOPPED;
}

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);
}
proc->super.state = ProcessTable_mapDarwinProcessState(ps[i].kp_proc.p_stat);

// Disabled for High Sierra due to bug in macOS High Sierra
bool isScanThreadSupported = !Platform_KernelVersionIsBetween((KernelVersion) {17, 0, 0}, (KernelVersion) {17, 5, 0});
Expand Down

0 comments on commit b4ab345

Please sign in to comment.