From b74673fe37fd379fc350789e696470556776d815 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Thu, 31 Aug 2023 11:56:43 +1000 Subject: Rename ProcessList to ProcessTable throughout Following up with some discusson from a few months back, where it was proposed that ProcessTable is a better name. This data structure is definitely not a list ... if it was one-dimensional it'd be a set, but in practice it has much more in common with a two-dimensional table. The Process table is a familiar operating system concept for many people too so it resonates a little in that way as well. --- netbsd/NetBSDMachine.c | 8 +- netbsd/NetBSDMachine.h | 2 +- netbsd/NetBSDProcessList.c | 273 -------------------------------------------- netbsd/NetBSDProcessList.h | 24 ---- netbsd/NetBSDProcessTable.c | 273 ++++++++++++++++++++++++++++++++++++++++++++ netbsd/NetBSDProcessTable.h | 24 ++++ 6 files changed, 302 insertions(+), 302 deletions(-) delete mode 100644 netbsd/NetBSDProcessList.c delete mode 100644 netbsd/NetBSDProcessList.h create mode 100644 netbsd/NetBSDProcessTable.c create mode 100644 netbsd/NetBSDProcessTable.h (limited to 'netbsd') diff --git a/netbsd/NetBSDMachine.c b/netbsd/NetBSDMachine.c index c1e6f7ed..245b8231 100644 --- a/netbsd/NetBSDMachine.c +++ b/netbsd/NetBSDMachine.c @@ -129,7 +129,7 @@ Machine* Machine_new(UsersTable* usersTable, uid_t userId) { } void Machine_delete(Machine* super) { - NetBSDMachine* this = (NetBSDProcessList*) super; + NetBSDMachine* this = (NetBSDMachine*) super; Machine_done(super); @@ -266,11 +266,11 @@ static void NetBSDMachine_scanCPUFrequency(NetBSDMachine* this) { void Machine_scan(Machine* super) { NetBSDMachine* this = (NetBSDMachine*) super; - NetBSDProcessList_scanMemoryInfo(this); - NetBSDProcessList_scanCPUTime(this); + NetBSDProcessTable_scanMemoryInfo(this); + NetBSDProcessTable_scanCPUTime(this); if (super->settings->showCPUFrequency) { - NetBSDProcessList_scanCPUFrequency(npl); + NetBSDProcessTable_scanCPUFrequency(npl); } } diff --git a/netbsd/NetBSDMachine.h b/netbsd/NetBSDMachine.h index 9c4e75ed..9d3aa0b2 100644 --- a/netbsd/NetBSDMachine.h +++ b/netbsd/NetBSDMachine.h @@ -15,7 +15,7 @@ in the source distribution for its full text. #include #include "Machine.h" -#include "ProcessList.h" +#include "ProcessTable.h" typedef struct CPUData_ { diff --git a/netbsd/NetBSDProcessList.c b/netbsd/NetBSDProcessList.c deleted file mode 100644 index 1327de70..00000000 --- a/netbsd/NetBSDProcessList.c +++ /dev/null @@ -1,273 +0,0 @@ -/* -htop - NetBSDProcessList.c -(C) 2014 Hisham H. Muhammad -(C) 2015 Michael McConville -(C) 2021 Santhosh Raju -(C) 2021 htop dev team -Released under the GNU GPLv2+, see the COPYING file -in the source distribution for its full text. -*/ - -#include "netbsd/NetBSDProcessList.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "CRT.h" -#include "Macros.h" -#include "Object.h" -#include "Process.h" -#include "ProcessList.h" -#include "Settings.h" -#include "XUtils.h" -#include "netbsd/NetBSDMachine.h" -#include "netbsd/NetBSDProcess.h" - - -ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { - NetBSDProcessList* this = xCalloc(1, sizeof(NetBSDProcessList)); - Object_setClass(this, Class(ProcessList)); - - ProcessList* super = (ProcessList*) this; - ProcessList_init(super, Class(NetBSDProcess), host, pidMatchList); - - return super; -} - -void ProcessList_delete(Object* cast) { - NetBSDProcessList* this = (NetBSDProcessList*) cast; - ProcessList_done(&this->super); - free(this); -} - -static void NetBSDProcessList_updateExe(const struct kinfo_proc2* kproc, Process* proc) { - const int mib[] = { CTL_KERN, KERN_PROC_ARGS, kproc->p_pid, KERN_PROC_PATHNAME }; - char buffer[2048]; - size_t size = sizeof(buffer); - if (sysctl(mib, 4, buffer, &size, NULL, 0) != 0) { - Process_updateExe(proc, NULL); - return; - } - - /* Kernel threads return an empty buffer */ - if (buffer[0] == '\0') { - Process_updateExe(proc, NULL); - return; - } - - Process_updateExe(proc, buffer); -} - -static void NetBSDProcessList_updateCwd(const struct kinfo_proc2* kproc, Process* proc) { - const int mib[] = { CTL_KERN, KERN_PROC_ARGS, kproc->p_pid, KERN_PROC_CWD }; - char buffer[2048]; - size_t size = sizeof(buffer); - if (sysctl(mib, 4, buffer, &size, NULL, 0) != 0) { - free(proc->procCwd); - proc->procCwd = NULL; - return; - } - - /* Kernel threads return an empty buffer */ - if (buffer[0] == '\0') { - free(proc->procCwd); - proc->procCwd = NULL; - return; - } - - free_and_xStrdup(&proc->procCwd, buffer); -} - -static void NetBSDProcessList_updateProcessName(kvm_t* kd, const struct kinfo_proc2* kproc, Process* proc) { - Process_updateComm(proc, kproc->p_comm); - - /* - * Like NetBSD's top(1), we try to fall back to the command name - * (argv[0]) if we fail to construct the full command. - */ - char** arg = kvm_getargv2(kd, kproc, 500); - if (arg == NULL || *arg == NULL) { - Process_updateCmdline(proc, kproc->p_comm, 0, strlen(kproc->p_comm)); - return; - } - - size_t len = 0; - for (int i = 0; arg[i] != NULL; i++) { - len += strlen(arg[i]) + 1; /* room for arg and trailing space or NUL */ - } - - /* don't use xMalloc here - we want to handle huge argv's gracefully */ - char* s; - if ((s = malloc(len)) == NULL) { - Process_updateCmdline(proc, kproc->p_comm, 0, strlen(kproc->p_comm)); - return; - } - - *s = '\0'; - - int start = 0; - int end = 0; - for (int i = 0; arg[i] != NULL; i++) { - size_t n = strlcat(s, arg[i], len); - if (i == 0) { - end = MINIMUM(n, len - 1); - /* check if cmdline ended earlier, e.g 'kdeinit5: Running...' */ - for (int j = end; j > 0; j--) { - if (arg[0][j] == ' ' && arg[0][j - 1] != '\\') { - end = (arg[0][j - 1] == ':') ? (j - 1) : j; - } - } - } - /* the trailing space should get truncated anyway */ - strlcat(s, " ", len); - } - - Process_updateCmdline(proc, s, start, end); - - free(s); -} - -/* - * Borrowed with modifications from NetBSD's top(1). - */ -static double getpcpu(const NetBSDMachine* nhost, const struct kinfo_proc2* kp) { - if (nhost->fscale == 0) - return 0.0; - - return 100.0 * (double)kp->p_pctcpu / nhost->fscale; -} - -static void NetBSDProcessList_scanProcs(NetBSDProcessList* this) { - const Machine* host = this->super.host; - const NetBSDMachine* nhost = (const NetBSDMachine*) host; - const Settings* settings = host->settings; - bool hideKernelThreads = settings->hideKernelThreads; - bool hideUserlandThreads = settings->hideUserlandThreads; - int count = 0; - - const struct kinfo_proc2* kprocs = kvm_getproc2(nhost->kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &count); - - for (int i = 0; i < count; i++) { - const struct kinfo_proc2* kproc = &kprocs[i]; - - bool preExisting = false; - Process* proc = ProcessList_getProcess(&this->super, kproc->p_pid, &preExisting, NetBSDProcess_new); - - proc->super.show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc))); - - if (!preExisting) { - Process_setPid(proc, kproc->p_pid); - Process_setParent(proc, kproc->p_ppid); - Process_setThreadGroup(proc, kproc->p_pid); - proc->tpgid = kproc->p_tpgid; - proc->session = kproc->p_sid; - proc->pgrp = kproc->p__pgid; - proc->isKernelThread = !!(kproc->p_flag & P_SYSTEM); - proc->isUserlandThread = Process_getPid(proc) != Process_getThreadGroup(proc); // eh? - proc->starttime_ctime = kproc->p_ustart_sec; - Process_fillStarttimeBuffer(proc); - ProcessList_add(&this->super, proc); - - proc->tty_nr = kproc->p_tdev; - const char* name = ((dev_t)kproc->p_tdev != KERN_PROC_TTY_NODEV) ? devname(kproc->p_tdev, S_IFCHR) : NULL; - if (!name) { - free(proc->tty_name); - proc->tty_name = NULL; - } else { - free_and_xStrdup(&proc->tty_name, name); - } - - NetBSDProcessList_updateExe(kproc, proc); - NetBSDProcessList_updateProcessName(nhost->kd, kproc, proc); - } else { - if (settings->updateProcessNames) { - NetBSDProcessList_updateProcessName(nhost->kd, kproc, proc); - } - } - - if (settings->ss->flags & PROCESS_FLAG_CWD) { - NetBSDProcessList_updateCwd(kproc, proc); - } - - if (proc->st_uid != kproc->p_uid) { - proc->st_uid = kproc->p_uid; - proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); - } - - proc->m_virt = kproc->p_vm_vsize; - proc->m_resident = kproc->p_vm_rssize; - - proc->percent_mem = (proc->m_resident * nhost->pageSizeKB) / (double)(host->totalMem) * 100.0; - proc->percent_cpu = CLAMP(getpcpu(nhost, kproc), 0.0, host->activeCPUs * 100.0); - Process_updateCPUFieldWidths(proc->percent_cpu); - - proc->nlwp = kproc->p_nlwps; - proc->nice = kproc->p_nice - 20; - proc->time = 100 * (kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000)); - proc->priority = kproc->p_priority - PZERO; - proc->processor = kproc->p_cpuid; - proc->minflt = kproc->p_uru_minflt; - proc->majflt = kproc->p_uru_majflt; - - int nlwps = 0; - const struct kinfo_lwp* klwps = kvm_getlwps(nhost->kd, kproc->p_pid, kproc->p_paddr, sizeof(struct kinfo_lwp), &nlwps); - - /* TODO: According to the link below, SDYING should be a regarded state */ - /* Taken from: https://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/sys/proc.h */ - switch (kproc->p_realstat) { - case SIDL: proc->state = IDLE; break; - case SACTIVE: - // We only consider the first LWP with a one of the below states. - for (int j = 0; j < nlwps; j++) { - if (klwps) { - switch (klwps[j].l_stat) { - case LSONPROC: proc->state = RUNNING; break; - case LSRUN: proc->state = RUNNABLE; break; - case LSSLEEP: proc->state = SLEEPING; break; - case LSSTOP: proc->state = STOPPED; break; - default: proc->state = UNKNOWN; - } - if (proc->state != UNKNOWN) - break; - } else { - proc->state = UNKNOWN; - break; - } - } - break; - case SSTOP: proc->state = STOPPED; break; - case SZOMB: proc->state = ZOMBIE; break; - case SDEAD: proc->state = DEFUNCT; break; - default: proc->state = UNKNOWN; - } - - if (Process_isKernelThread(proc)) { - this->super.kernelThreads++; - } else if (Process_isUserlandThread(proc)) { - this->super.userlandThreads++; - } - - this->super.totalTasks++; - if (proc->state == RUNNING) { - this->super.runningTasks++; - } - proc->super.updated = true; - } -} - -void ProcessList_goThroughEntries(ProcessList* super) { - NetBSDProcessList* npl = (NetBSDProcessList*) super; - - NetBSDProcessList_scanProcs(npl); -} diff --git a/netbsd/NetBSDProcessList.h b/netbsd/NetBSDProcessList.h deleted file mode 100644 index 362d84fc..00000000 --- a/netbsd/NetBSDProcessList.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef HEADER_NetBSDProcessList -#define HEADER_NetBSDProcessList -/* -htop - NetBSDProcessList.h -(C) 2014 Hisham H. Muhammad -(C) 2015 Michael McConville -(C) 2021 Santhosh Raju -(C) 2021 htop dev team -Released under the GNU GPLv2+, see the COPYING file -in the source distribution for its full text. -*/ - -#include -#include - -#include "Hashtable.h" -#include "ProcessList.h" - - -typedef struct NetBSDProcessList_ { - ProcessList super; -} NetBSDProcessList; - -#endif diff --git a/netbsd/NetBSDProcessTable.c b/netbsd/NetBSDProcessTable.c new file mode 100644 index 00000000..885a2edd --- /dev/null +++ b/netbsd/NetBSDProcessTable.c @@ -0,0 +1,273 @@ +/* +htop - NetBSDProcessTable.c +(C) 2014 Hisham H. Muhammad +(C) 2015 Michael McConville +(C) 2021 Santhosh Raju +(C) 2021 htop dev team +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include "netbsd/NetBSDProcessTable.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CRT.h" +#include "Macros.h" +#include "Object.h" +#include "Process.h" +#include "ProcessTable.h" +#include "Settings.h" +#include "XUtils.h" +#include "netbsd/NetBSDMachine.h" +#include "netbsd/NetBSDProcess.h" + + +ProcessTable* ProcessTable_new(Machine* host, Hashtable* pidMatchList) { + NetBSDProcessTable* this = xCalloc(1, sizeof(NetBSDProcessTable)); + Object_setClass(this, Class(ProcessTable)); + + ProcessTable* super = (ProcessTable*) this; + ProcessTable_init(super, Class(NetBSDProcess), host, pidMatchList); + + return super; +} + +void ProcessTable_delete(Object* cast) { + NetBSDProcessTable* this = (NetBSDProcessTable*) cast; + ProcessTable_done(&this->super); + free(this); +} + +static void NetBSDProcessTable_updateExe(const struct kinfo_proc2* kproc, Process* proc) { + const int mib[] = { CTL_KERN, KERN_PROC_ARGS, kproc->p_pid, KERN_PROC_PATHNAME }; + char buffer[2048]; + size_t size = sizeof(buffer); + if (sysctl(mib, 4, buffer, &size, NULL, 0) != 0) { + Process_updateExe(proc, NULL); + return; + } + + /* Kernel threads return an empty buffer */ + if (buffer[0] == '\0') { + Process_updateExe(proc, NULL); + return; + } + + Process_updateExe(proc, buffer); +} + +static void NetBSDProcessTable_updateCwd(const struct kinfo_proc2* kproc, Process* proc) { + const int mib[] = { CTL_KERN, KERN_PROC_ARGS, kproc->p_pid, KERN_PROC_CWD }; + char buffer[2048]; + size_t size = sizeof(buffer); + if (sysctl(mib, 4, buffer, &size, NULL, 0) != 0) { + free(proc->procCwd); + proc->procCwd = NULL; + return; + } + + /* Kernel threads return an empty buffer */ + if (buffer[0] == '\0') { + free(proc->procCwd); + proc->procCwd = NULL; + return; + } + + free_and_xStrdup(&proc->procCwd, buffer); +} + +static void NetBSDProcessTable_updateProcessName(kvm_t* kd, const struct kinfo_proc2* kproc, Process* proc) { + Process_updateComm(proc, kproc->p_comm); + + /* + * Like NetBSD's top(1), we try to fall back to the command name + * (argv[0]) if we fail to construct the full command. + */ + char** arg = kvm_getargv2(kd, kproc, 500); + if (arg == NULL || *arg == NULL) { + Process_updateCmdline(proc, kproc->p_comm, 0, strlen(kproc->p_comm)); + return; + } + + size_t len = 0; + for (int i = 0; arg[i] != NULL; i++) { + len += strlen(arg[i]) + 1; /* room for arg and trailing space or NUL */ + } + + /* don't use xMalloc here - we want to handle huge argv's gracefully */ + char* s; + if ((s = malloc(len)) == NULL) { + Process_updateCmdline(proc, kproc->p_comm, 0, strlen(kproc->p_comm)); + return; + } + + *s = '\0'; + + int start = 0; + int end = 0; + for (int i = 0; arg[i] != NULL; i++) { + size_t n = strlcat(s, arg[i], len); + if (i == 0) { + end = MINIMUM(n, len - 1); + /* check if cmdline ended earlier, e.g 'kdeinit5: Running...' */ + for (int j = end; j > 0; j--) { + if (arg[0][j] == ' ' && arg[0][j - 1] != '\\') { + end = (arg[0][j - 1] == ':') ? (j - 1) : j; + } + } + } + /* the trailing space should get truncated anyway */ + strlcat(s, " ", len); + } + + Process_updateCmdline(proc, s, start, end); + + free(s); +} + +/* + * Borrowed with modifications from NetBSD's top(1). + */ +static double getpcpu(const NetBSDMachine* nhost, const struct kinfo_proc2* kp) { + if (nhost->fscale == 0) + return 0.0; + + return 100.0 * (double)kp->p_pctcpu / nhost->fscale; +} + +static void NetBSDProcessTable_scanProcs(NetBSDProcessTable* this) { + const Machine* host = this->super.host; + const NetBSDMachine* nhost = (const NetBSDMachine*) host; + const Settings* settings = host->settings; + bool hideKernelThreads = settings->hideKernelThreads; + bool hideUserlandThreads = settings->hideUserlandThreads; + int count = 0; + + const struct kinfo_proc2* kprocs = kvm_getproc2(nhost->kd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &count); + + for (int i = 0; i < count; i++) { + const struct kinfo_proc2* kproc = &kprocs[i]; + + bool preExisting = false; + Process* proc = ProcessTable_getProcess(&this->super, kproc->p_pid, &preExisting, NetBSDProcess_new); + + proc->super.show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc))); + + if (!preExisting) { + Process_setPid(proc, kproc->p_pid); + Process_setParent(proc, kproc->p_ppid); + Process_setThreadGroup(proc, kproc->p_pid); + proc->tpgid = kproc->p_tpgid; + proc->session = kproc->p_sid; + proc->pgrp = kproc->p__pgid; + proc->isKernelThread = !!(kproc->p_flag & P_SYSTEM); + proc->isUserlandThread = Process_getPid(proc) != Process_getThreadGroup(proc); // eh? + proc->starttime_ctime = kproc->p_ustart_sec; + Process_fillStarttimeBuffer(proc); + ProcessTable_add(&this->super, proc); + + proc->tty_nr = kproc->p_tdev; + const char* name = ((dev_t)kproc->p_tdev != KERN_PROC_TTY_NODEV) ? devname(kproc->p_tdev, S_IFCHR) : NULL; + if (!name) { + free(proc->tty_name); + proc->tty_name = NULL; + } else { + free_and_xStrdup(&proc->tty_name, name); + } + + NetBSDProcessTable_updateExe(kproc, proc); + NetBSDProcessTable_updateProcessName(nhost->kd, kproc, proc); + } else { + if (settings->updateProcessNames) { + NetBSDProcessTable_updateProcessName(nhost->kd, kproc, proc); + } + } + + if (settings->ss->flags & PROCESS_FLAG_CWD) { + NetBSDProcessTable_updateCwd(kproc, proc); + } + + if (proc->st_uid != kproc->p_uid) { + proc->st_uid = kproc->p_uid; + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); + } + + proc->m_virt = kproc->p_vm_vsize; + proc->m_resident = kproc->p_vm_rssize; + + proc->percent_mem = (proc->m_resident * nhost->pageSizeKB) / (double)(host->totalMem) * 100.0; + proc->percent_cpu = CLAMP(getpcpu(nhost, kproc), 0.0, host->activeCPUs * 100.0); + Process_updateCPUFieldWidths(proc->percent_cpu); + + proc->nlwp = kproc->p_nlwps; + proc->nice = kproc->p_nice - 20; + proc->time = 100 * (kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 1000000)); + proc->priority = kproc->p_priority - PZERO; + proc->processor = kproc->p_cpuid; + proc->minflt = kproc->p_uru_minflt; + proc->majflt = kproc->p_uru_majflt; + + int nlwps = 0; + const struct kinfo_lwp* klwps = kvm_getlwps(nhost->kd, kproc->p_pid, kproc->p_paddr, sizeof(struct kinfo_lwp), &nlwps); + + /* TODO: According to the link below, SDYING should be a regarded state */ + /* Taken from: https://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/sys/proc.h */ + switch (kproc->p_realstat) { + case SIDL: proc->state = IDLE; break; + case SACTIVE: + // We only consider the first LWP with a one of the below states. + for (int j = 0; j < nlwps; j++) { + if (klwps) { + switch (klwps[j].l_stat) { + case LSONPROC: proc->state = RUNNING; break; + case LSRUN: proc->state = RUNNABLE; break; + case LSSLEEP: proc->state = SLEEPING; break; + case LSSTOP: proc->state = STOPPED; break; + default: proc->state = UNKNOWN; + } + if (proc->state != UNKNOWN) + break; + } else { + proc->state = UNKNOWN; + break; + } + } + break; + case SSTOP: proc->state = STOPPED; break; + case SZOMB: proc->state = ZOMBIE; break; + case SDEAD: proc->state = DEFUNCT; break; + default: proc->state = UNKNOWN; + } + + if (Process_isKernelThread(proc)) { + this->super.kernelThreads++; + } else if (Process_isUserlandThread(proc)) { + this->super.userlandThreads++; + } + + this->super.totalTasks++; + if (proc->state == RUNNING) { + this->super.runningTasks++; + } + proc->super.updated = true; + } +} + +void ProcessTable_goThroughEntries(ProcessTable* super) { + NetBSDProcessTable* npt = (NetBSDProcessTable*) super; + + NetBSDProcessTable_scanProcs(npt); +} diff --git a/netbsd/NetBSDProcessTable.h b/netbsd/NetBSDProcessTable.h new file mode 100644 index 00000000..1bcfa985 --- /dev/null +++ b/netbsd/NetBSDProcessTable.h @@ -0,0 +1,24 @@ +#ifndef HEADER_NetBSDProcessTable +#define HEADER_NetBSDProcessTable +/* +htop - NetBSDProcessTable.h +(C) 2014 Hisham H. Muhammad +(C) 2015 Michael McConville +(C) 2021 Santhosh Raju +(C) 2021 htop dev team +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include +#include + +#include "Hashtable.h" +#include "ProcessTable.h" + + +typedef struct NetBSDProcessTable_ { + ProcessTable super; +} NetBSDProcessTable; + +#endif -- cgit v1.2.3