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. --- openbsd/OpenBSDMachine.c | 2 +- openbsd/OpenBSDProcessList.c | 243 ------------------------------------------ openbsd/OpenBSDProcessList.h | 21 ---- openbsd/OpenBSDProcessTable.c | 243 ++++++++++++++++++++++++++++++++++++++++++ openbsd/OpenBSDProcessTable.h | 21 ++++ 5 files changed, 265 insertions(+), 265 deletions(-) delete mode 100644 openbsd/OpenBSDProcessList.c delete mode 100644 openbsd/OpenBSDProcessList.h create mode 100644 openbsd/OpenBSDProcessTable.c create mode 100644 openbsd/OpenBSDProcessTable.h (limited to 'openbsd') diff --git a/openbsd/OpenBSDMachine.c b/openbsd/OpenBSDMachine.c index 8b86dfab..c4b6e47e 100644 --- a/openbsd/OpenBSDMachine.c +++ b/openbsd/OpenBSDMachine.c @@ -96,7 +96,7 @@ Machine* Machine_new(UsersTable* usersTable, uid_t userId) { Machine_init(super, usersTable, userId); - OpenBSDProcessList_updateCPUcount(this); + OpenBSDProcessTable_updateCPUcount(this); size = sizeof(this->fscale); if (sysctl(fmib, 2, &this->fscale, &size, NULL, 0) < 0 || this->fscale <= 0) { diff --git a/openbsd/OpenBSDProcessList.c b/openbsd/OpenBSDProcessList.c deleted file mode 100644 index 17066397..00000000 --- a/openbsd/OpenBSDProcessList.c +++ /dev/null @@ -1,243 +0,0 @@ -/* -htop - OpenBSDProcessList.c -(C) 2014 Hisham H. Muhammad -(C) 2015 Michael McConville -Released under the GNU GPLv2+, see the COPYING file -in the source distribution for its full text. -*/ - -#include "openbsd/OpenBSDProcessList.h" - -#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 "openbsd/OpenBSDMachine.h" -#include "openbsd/OpenBSDProcess.h" - - -ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { - OpenBSDProcessList* this = xCalloc(1, sizeof(OpenBSDProcessList)); - Object_setClass(this, Class(ProcessList)); - - ProcessList* super = &this->super; - ProcessList_init(super, Class(OpenBSDProcess), host, pidMatchList); - - return this; -} - -void ProcessList_delete(Object* cast) { - OpenBSDProcessList* this = (OpenBSDProcessList*) super; - ProcessList_done(&this->super); - free(this); -} - -static void OpenBSDProcessList_updateCwd(const struct kinfo_proc* kproc, Process* proc) { - const int mib[] = { CTL_KERN, KERN_PROC_CWD, kproc->p_pid }; - char buffer[2048]; - size_t size = sizeof(buffer); - if (sysctl(mib, 3, 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 OpenBSDProcessList_updateProcessName(kvm_t* kd, const struct kinfo_proc* kproc, Process* proc) { - Process_updateComm(proc, kproc->p_comm); - - /* - * Like OpenBSD'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_getargv(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); -} - -/* - * Taken from OpenBSD's ps(1). - */ -static double getpcpu(const OpenBSDMachine* ohost, const struct kinfo_proc* kp) { - if (ohost->fscale == 0) - return 0.0; - - return 100.0 * (double)kp->p_pctcpu / ohost->fscale; -} - -static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { - Machine* host = this->super.host; - OpenBSDMachine* ohost = (OpenBSDMachine*) host; - const Settings* settings = host->settings; - const bool hideKernelThreads = settings->hideKernelThreads; - const bool hideUserlandThreads = settings->hideUserlandThreads; - int count = 0; - - const struct kinfo_proc* kprocs = kvm_getprocs(ohost->kd, KERN_PROC_KTHREAD | KERN_PROC_SHOW_THREADS, 0, sizeof(struct kinfo_proc), &count); - - for (int i = 0; i < count; i++) { - const struct kinfo_proc* kproc = &kprocs[i]; - - /* Ignore main threads */ - if (kproc->p_tid != -1) { - Process* containingProcess = ProcessList_findProcess(&this->super, kproc->p_pid); - if (containingProcess) { - if (((OpenBSDProcess*)containingProcess)->addr == kproc->p_addr) - continue; - - containingProcess->nlwp++; - } - } - - bool preExisting = false; - Process* proc = ProcessList_getProcess(&this->super, (kproc->p_tid == -1) ? kproc->p_pid : kproc->p_tid, &preExisting, OpenBSDProcess_new); - OpenBSDProcess* op = (OpenBSDProcess*) proc; - - if (!preExisting) { - 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 = proc->pgrp == 0; - proc->isUserlandThread = kproc->p_tid != -1; - proc->starttime_ctime = kproc->p_ustart_sec; - Process_fillStarttimeBuffer(proc); - ProcessList_add(&this->super, proc); - - OpenBSDProcessList_updateProcessName(ohost->kd, kproc, proc); - - if (settings->ss->flags & PROCESS_FLAG_CWD) { - OpenBSDProcessList_updateCwd(kproc, proc); - } - - proc->tty_nr = kproc->p_tdev; - const char* name = ((dev_t)kproc->p_tdev != NODEV) ? devname(kproc->p_tdev, S_IFCHR) : NULL; - if (!name || String_eq(name, "??")) { - free(proc->tty_name); - proc->tty_name = NULL; - } else { - free_and_xStrdup(&proc->tty_name, name); - } - } else { - if (settings->updateProcessNames) { - OpenBSDProcessList_updateProcessName(ohost->kd, kproc, proc); - } - } - - op->addr = kproc->p_addr; - proc->m_virt = kproc->p_vm_dsize * ohost->pageSizeKB; - proc->m_resident = kproc->p_vm_rssize * ohost->pageSizeKB; - - proc->percent_mem = proc->m_resident / (float)host->totalMem * 100.0F; - proc->percent_cpu = CLAMP(getpcpu(ohost, kproc), 0.0F, host->activeCPUs * 100.0F); - Process_updateCPUFieldWidths(proc->percent_cpu); - - 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; - proc->nlwp = 1; - - if (proc->st_uid != kproc->p_uid) { - proc->st_uid = kproc->p_uid; - proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); - } - - /* Taken from: https://github.com/openbsd/src/blob/6a38af0976a6870911f4b2de19d8da28723a5778/sys/sys/proc.h#L420 */ - switch (kproc->p_stat) { - case SIDL: proc->state = IDLE; break; - case SRUN: proc->state = RUNNABLE; break; - case SSLEEP: proc->state = SLEEPING; break; - case SSTOP: proc->state = STOPPED; break; - case SZOMB: proc->state = ZOMBIE; break; - case SDEAD: proc->state = DEFUNCT; break; - case SONPROC: proc->state = RUNNING; 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.show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc))); - proc->super.updated = true; - } -} - -void ProcessList_goThroughEntries(ProcessList* super) { - OpenBSDProcessList* this = (OpenBSDProcessList*) super; - - OpenBSDProcessList_scanProcs(this); -} diff --git a/openbsd/OpenBSDProcessList.h b/openbsd/OpenBSDProcessList.h deleted file mode 100644 index 8a03fecb..00000000 --- a/openbsd/OpenBSDProcessList.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef HEADER_OpenBSDProcessList -#define HEADER_OpenBSDProcessList -/* -htop - OpenBSDProcessList.h -(C) 2014 Hisham H. Muhammad -(C) 2015 Michael McConville -Released under the GNU GPLv2+, see the COPYING file -in the source distribution for its full text. -*/ - -#include -#include - -#include "ProcessList.h" - - -typedef struct OpenBSDProcessList_ { - ProcessList super; -} OpenBSDProcessList; - -#endif diff --git a/openbsd/OpenBSDProcessTable.c b/openbsd/OpenBSDProcessTable.c new file mode 100644 index 00000000..0b016fbb --- /dev/null +++ b/openbsd/OpenBSDProcessTable.c @@ -0,0 +1,243 @@ +/* +htop - OpenBSDProcessTable.c +(C) 2014 Hisham H. Muhammad +(C) 2015 Michael McConville +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include "openbsd/OpenBSDProcessTable.h" + +#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 "openbsd/OpenBSDMachine.h" +#include "openbsd/OpenBSDProcess.h" + + +ProcessTable* ProcessTable_new(Machine* host, Hashtable* pidMatchList) { + OpenBSDProcessTable* this = xCalloc(1, sizeof(OpenBSDProcessTable)); + Object_setClass(this, Class(ProcessTable)); + + ProcessTable* super = &this->super; + ProcessTable_init(super, Class(OpenBSDProcess), host, pidMatchList); + + return this; +} + +void ProcessTable_delete(Object* cast) { + OpenBSDProcessTable* this = (OpenBSDProcessTable*) super; + ProcessTable_done(&this->super); + free(this); +} + +static void OpenBSDProcessTable_updateCwd(const struct kinfo_proc* kproc, Process* proc) { + const int mib[] = { CTL_KERN, KERN_PROC_CWD, kproc->p_pid }; + char buffer[2048]; + size_t size = sizeof(buffer); + if (sysctl(mib, 3, 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 OpenBSDProcessTable_updateProcessName(kvm_t* kd, const struct kinfo_proc* kproc, Process* proc) { + Process_updateComm(proc, kproc->p_comm); + + /* + * Like OpenBSD'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_getargv(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); +} + +/* + * Taken from OpenBSD's ps(1). + */ +static double getpcpu(const OpenBSDMachine* ohost, const struct kinfo_proc* kp) { + if (ohost->fscale == 0) + return 0.0; + + return 100.0 * (double)kp->p_pctcpu / ohost->fscale; +} + +static void OpenBSDProcessTable_scanProcs(OpenBSDProcessTable* this) { + Machine* host = this->super.host; + OpenBSDMachine* ohost = (OpenBSDMachine*) host; + const Settings* settings = host->settings; + const bool hideKernelThreads = settings->hideKernelThreads; + const bool hideUserlandThreads = settings->hideUserlandThreads; + int count = 0; + + const struct kinfo_proc* kprocs = kvm_getprocs(ohost->kd, KERN_PROC_KTHREAD | KERN_PROC_SHOW_THREADS, 0, sizeof(struct kinfo_proc), &count); + + for (int i = 0; i < count; i++) { + const struct kinfo_proc* kproc = &kprocs[i]; + + /* Ignore main threads */ + if (kproc->p_tid != -1) { + Process* containingProcess = ProcessTable_findProcess(&this->super, kproc->p_pid); + if (containingProcess) { + if (((OpenBSDProcess*)containingProcess)->addr == kproc->p_addr) + continue; + + containingProcess->nlwp++; + } + } + + bool preExisting = false; + Process* proc = ProcessTable_getProcess(&this->super, (kproc->p_tid == -1) ? kproc->p_pid : kproc->p_tid, &preExisting, OpenBSDProcess_new); + OpenBSDProcess* op = (OpenBSDProcess*) proc; + + if (!preExisting) { + 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 = proc->pgrp == 0; + proc->isUserlandThread = kproc->p_tid != -1; + proc->starttime_ctime = kproc->p_ustart_sec; + Process_fillStarttimeBuffer(proc); + ProcessTable_add(&this->super, proc); + + OpenBSDProcessTable_updateProcessName(ohost->kd, kproc, proc); + + if (settings->ss->flags & PROCESS_FLAG_CWD) { + OpenBSDProcessTable_updateCwd(kproc, proc); + } + + proc->tty_nr = kproc->p_tdev; + const char* name = ((dev_t)kproc->p_tdev != NODEV) ? devname(kproc->p_tdev, S_IFCHR) : NULL; + if (!name || String_eq(name, "??")) { + free(proc->tty_name); + proc->tty_name = NULL; + } else { + free_and_xStrdup(&proc->tty_name, name); + } + } else { + if (settings->updateProcessNames) { + OpenBSDProcessTable_updateProcessName(ohost->kd, kproc, proc); + } + } + + op->addr = kproc->p_addr; + proc->m_virt = kproc->p_vm_dsize * ohost->pageSizeKB; + proc->m_resident = kproc->p_vm_rssize * ohost->pageSizeKB; + + proc->percent_mem = proc->m_resident / (float)host->totalMem * 100.0F; + proc->percent_cpu = CLAMP(getpcpu(ohost, kproc), 0.0F, host->activeCPUs * 100.0F); + Process_updateCPUFieldWidths(proc->percent_cpu); + + 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; + proc->nlwp = 1; + + if (proc->st_uid != kproc->p_uid) { + proc->st_uid = kproc->p_uid; + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); + } + + /* Taken from: https://github.com/openbsd/src/blob/6a38af0976a6870911f4b2de19d8da28723a5778/sys/sys/proc.h#L420 */ + switch (kproc->p_stat) { + case SIDL: proc->state = IDLE; break; + case SRUN: proc->state = RUNNABLE; break; + case SSLEEP: proc->state = SLEEPING; break; + case SSTOP: proc->state = STOPPED; break; + case SZOMB: proc->state = ZOMBIE; break; + case SDEAD: proc->state = DEFUNCT; break; + case SONPROC: proc->state = RUNNING; 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.show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc))); + proc->super.updated = true; + } +} + +void ProcessTable_goThroughEntries(ProcessTable* super) { + OpenBSDProcessTable* this = (OpenBSDProcessTable*) super; + + OpenBSDProcessTable_scanProcs(this); +} diff --git a/openbsd/OpenBSDProcessTable.h b/openbsd/OpenBSDProcessTable.h new file mode 100644 index 00000000..f911a10b --- /dev/null +++ b/openbsd/OpenBSDProcessTable.h @@ -0,0 +1,21 @@ +#ifndef HEADER_OpenBSDProcessTable +#define HEADER_OpenBSDProcessTable +/* +htop - OpenBSDProcessTable.h +(C) 2014 Hisham H. Muhammad +(C) 2015 Michael McConville +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include +#include + +#include "ProcessTable.h" + + +typedef struct OpenBSDProcessTable_ { + ProcessTable super; +} OpenBSDProcessTable; + +#endif -- cgit v1.2.3