From e7372d18a1a661d8c3dba9f51e1f17b5f94171a7 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Wed, 10 Jan 2024 11:17:08 +0100 Subject: New upstream version 3.3.0 --- openbsd/OpenBSDMachine.c | 290 +++++++++++++++++++++++++ openbsd/OpenBSDMachine.h | 53 +++++ openbsd/OpenBSDProcess.c | 34 ++- openbsd/OpenBSDProcess.h | 4 +- openbsd/OpenBSDProcessList.c | 486 ------------------------------------------ openbsd/OpenBSDProcessList.h | 60 ------ openbsd/OpenBSDProcessTable.c | 245 +++++++++++++++++++++ openbsd/OpenBSDProcessTable.h | 21 ++ openbsd/Platform.c | 85 +++++--- openbsd/Platform.h | 34 ++- 10 files changed, 715 insertions(+), 597 deletions(-) create mode 100644 openbsd/OpenBSDMachine.c create mode 100644 openbsd/OpenBSDMachine.h 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 new file mode 100644 index 0000000..0ff893b --- /dev/null +++ b/openbsd/OpenBSDMachine.c @@ -0,0 +1,290 @@ +/* +htop - OpenBSDMachine.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 "config.h" // IWYU pragma: keep + +#include "openbsd/OpenBSDMachine.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CRT.h" +#include "Macros.h" +#include "Object.h" +#include "Settings.h" +#include "XUtils.h" + + +static void OpenBSDMachine_updateCPUcount(OpenBSDMachine* this) { + Machine* super = &this->super; + const int nmib[] = { CTL_HW, HW_NCPU }; + const int mib[] = { CTL_HW, HW_NCPUONLINE }; + int r; + unsigned int value; + size_t size; + bool change = false; + + size = sizeof(value); + r = sysctl(mib, 2, &value, &size, NULL, 0); + if (r < 0 || value < 1) { + value = 1; + } + + if (value != super->activeCPUs) { + super->activeCPUs = value; + change = true; + } + + size = sizeof(value); + r = sysctl(nmib, 2, &value, &size, NULL, 0); + if (r < 0 || value < 1) { + value = super->activeCPUs; + } + + if (value != super->existingCPUs) { + this->cpuData = xReallocArray(this->cpuData, value + 1, sizeof(CPUData)); + super->existingCPUs = value; + change = true; + } + + if (change) { + CPUData* dAvg = &this->cpuData[0]; + memset(dAvg, '\0', sizeof(CPUData)); + dAvg->totalTime = 1; + dAvg->totalPeriod = 1; + dAvg->online = true; + + for (unsigned int i = 0; i < super->existingCPUs; i++) { + CPUData* d = &this->cpuData[i + 1]; + memset(d, '\0', sizeof(CPUData)); + d->totalTime = 1; + d->totalPeriod = 1; + + const int ncmib[] = { CTL_KERN, KERN_CPUSTATS, i }; + struct cpustats cpu_stats; + + size = sizeof(cpu_stats); + if (sysctl(ncmib, 3, &cpu_stats, &size, NULL, 0) < 0) { + CRT_fatalError("ncmib sysctl call failed"); + } + d->online = (cpu_stats.cs_flags & CPUSTATS_ONLINE); + } + } +} + +Machine* Machine_new(UsersTable* usersTable, uid_t userId) { + const int fmib[] = { CTL_KERN, KERN_FSCALE }; + size_t size; + char errbuf[_POSIX2_LINE_MAX]; + + OpenBSDMachine* this = xCalloc(1, sizeof(OpenBSDMachine)); + Machine* super = &this->super; + + Machine_init(super, usersTable, userId); + + OpenBSDMachine_updateCPUcount(this); + + size = sizeof(this->fscale); + if (sysctl(fmib, 2, &this->fscale, &size, NULL, 0) < 0 || this->fscale <= 0) { + CRT_fatalError("fscale sysctl call failed"); + } + + if ((this->pageSize = sysconf(_SC_PAGESIZE)) == -1) + CRT_fatalError("pagesize sysconf call failed"); + this->pageSizeKB = this->pageSize / ONE_K; + + this->kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + if (this->kd == NULL) { + CRT_fatalError("kvm_openfiles() failed"); + } + + this->cpuSpeed = -1; + + return super; +} + +void Machine_delete(Machine* super) { + OpenBSDMachine* this = (OpenBSDMachine*) super; + + if (this->kd) { + kvm_close(this->kd); + } + free(this->cpuData); + Machine_done(super); + free(this); +} + +static void OpenBSDMachine_scanMemoryInfo(OpenBSDMachine* this) { + Machine* super = &this->super; + const int uvmexp_mib[] = { CTL_VM, VM_UVMEXP }; + struct uvmexp uvmexp; + size_t size_uvmexp = sizeof(uvmexp); + + if (sysctl(uvmexp_mib, 2, &uvmexp, &size_uvmexp, NULL, 0) < 0) { + CRT_fatalError("uvmexp sysctl call failed"); + } + + super->totalMem = uvmexp.npages * this->pageSizeKB; + super->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * this->pageSizeKB; + + // Taken from OpenBSD systat/iostat.c, top/machine.c and uvm_sysctl(9) + const int bcache_mib[] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT }; + struct bcachestats bcstats; + size_t size_bcstats = sizeof(bcstats); + + if (sysctl(bcache_mib, 3, &bcstats, &size_bcstats, NULL, 0) < 0) { + CRT_fatalError("cannot get vfs.bcachestat"); + } + + super->cachedMem = bcstats.numbufpages * this->pageSizeKB; + + /* + * Copyright (c) 1994 Thorsten Lockert + * All rights reserved. + * + * Taken almost directly from OpenBSD's top(1) + * + * Originally released under a BSD-3 license + * Modified through htop developers applying GPL-2 + */ + int nswap = swapctl(SWAP_NSWAP, 0, 0); + if (nswap > 0) { + struct swapent* swdev = xMallocArray(nswap, sizeof(struct swapent)); + int rnswap = swapctl(SWAP_STATS, swdev, nswap); + + /* Total things up */ + unsigned long long int total = 0, used = 0; + for (int i = 0; i < rnswap; i++) { + if (swdev[i].se_flags & SWF_ENABLE) { + used += (swdev[i].se_inuse / (1024 / DEV_BSIZE)); + total += (swdev[i].se_nblks / (1024 / DEV_BSIZE)); + } + } + + super->totalSwap = total; + super->usedSwap = used; + + free(swdev); + } else { + super->totalSwap = super->usedSwap = 0; + } +} + +static void getKernelCPUTimes(unsigned int cpuId, u_int64_t* times) { + const int mib[] = { CTL_KERN, KERN_CPTIME2, cpuId }; + size_t length = sizeof(*times) * CPUSTATES; + if (sysctl(mib, 3, times, &length, NULL, 0) == -1 || length != sizeof(*times) * CPUSTATES) { + CRT_fatalError("sysctl kern.cp_time2 failed"); + } +} + +static void kernelCPUTimesToHtop(const u_int64_t* times, CPUData* cpu) { + unsigned long long totalTime = 0; + for (int i = 0; i < CPUSTATES; i++) { + totalTime += times[i]; + } + + unsigned long long sysAllTime = times[CP_INTR] + times[CP_SYS]; + + // XXX Not sure if CP_SPIN should be added to sysAllTime. + // See https://github.com/openbsd/src/commit/531d8034253fb82282f0f353c086e9ad827e031c + #ifdef CP_SPIN + sysAllTime += times[CP_SPIN]; + #endif + + cpu->totalPeriod = saturatingSub(totalTime, cpu->totalTime); + cpu->userPeriod = saturatingSub(times[CP_USER], cpu->userTime); + cpu->nicePeriod = saturatingSub(times[CP_NICE], cpu->niceTime); + cpu->sysPeriod = saturatingSub(times[CP_SYS], cpu->sysTime); + cpu->sysAllPeriod = saturatingSub(sysAllTime, cpu->sysAllTime); + #ifdef CP_SPIN + cpu->spinPeriod = saturatingSub(times[CP_SPIN], cpu->spinTime); + #endif + cpu->intrPeriod = saturatingSub(times[CP_INTR], cpu->intrTime); + cpu->idlePeriod = saturatingSub(times[CP_IDLE], cpu->idleTime); + + cpu->totalTime = totalTime; + cpu->userTime = times[CP_USER]; + cpu->niceTime = times[CP_NICE]; + cpu->sysTime = times[CP_SYS]; + cpu->sysAllTime = sysAllTime; + #ifdef CP_SPIN + cpu->spinTime = times[CP_SPIN]; + #endif + cpu->intrTime = times[CP_INTR]; + cpu->idleTime = times[CP_IDLE]; +} + +static void OpenBSDMachine_scanCPUTime(OpenBSDMachine* this) { + Machine* super = &this->super; + u_int64_t kernelTimes[CPUSTATES] = {0}; + u_int64_t avg[CPUSTATES] = {0}; + + for (unsigned int i = 0; i < super->existingCPUs; i++) { + CPUData* cpu = &this->cpuData[i + 1]; + + if (!cpu->online) { + continue; + } + + getKernelCPUTimes(i, kernelTimes); + kernelCPUTimesToHtop(kernelTimes, cpu); + + avg[CP_USER] += cpu->userTime; + avg[CP_NICE] += cpu->niceTime; + avg[CP_SYS] += cpu->sysTime; + #ifdef CP_SPIN + avg[CP_SPIN] += cpu->spinTime; + #endif + avg[CP_INTR] += cpu->intrTime; + avg[CP_IDLE] += cpu->idleTime; + } + + for (int i = 0; i < CPUSTATES; i++) { + avg[i] /= super->activeCPUs; + } + + kernelCPUTimesToHtop(avg, &this->cpuData[0]); + + { + const int mib[] = { CTL_HW, HW_CPUSPEED }; + int cpuSpeed; + size_t size = sizeof(cpuSpeed); + if (sysctl(mib, 2, &cpuSpeed, &size, NULL, 0) == -1) { + this->cpuSpeed = -1; + } else { + this->cpuSpeed = cpuSpeed; + } + } +} + +void Machine_scan(Machine* super) { + OpenBSDMachine* this = (OpenBSDMachine*) super; + + OpenBSDMachine_updateCPUcount(this); + OpenBSDMachine_scanMemoryInfo(this); + OpenBSDMachine_scanCPUTime(this); +} + +bool Machine_isCPUonline(const Machine* super, unsigned int id) { + assert(id < super->existingCPUs); + + const OpenBSDMachine* this = (const OpenBSDMachine*) super; + return this->cpuData[id + 1].online; +} diff --git a/openbsd/OpenBSDMachine.h b/openbsd/OpenBSDMachine.h new file mode 100644 index 0000000..51d6a75 --- /dev/null +++ b/openbsd/OpenBSDMachine.h @@ -0,0 +1,53 @@ +#ifndef HEADER_OpenBSDMachine +#define HEADER_OpenBSDMachine +/* +htop - OpenBSDMachine.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 + +#include "Machine.h" + + +typedef struct CPUData_ { + unsigned long long int totalTime; + unsigned long long int userTime; + unsigned long long int niceTime; + unsigned long long int sysTime; + unsigned long long int sysAllTime; + unsigned long long int spinTime; + unsigned long long int intrTime; + unsigned long long int idleTime; + + unsigned long long int totalPeriod; + unsigned long long int userPeriod; + unsigned long long int nicePeriod; + unsigned long long int sysPeriod; + unsigned long long int sysAllPeriod; + unsigned long long int spinPeriod; + unsigned long long int intrPeriod; + unsigned long long int idlePeriod; + + bool online; +} CPUData; + +typedef struct OpenBSDMachine_ { + Machine super; + kvm_t* kd; + + CPUData* cpuData; + + long fscale; + int cpuSpeed; + int pageSize; + int pageSizeKB; + +} OpenBSDMachine; + +#endif diff --git a/openbsd/OpenBSDProcess.c b/openbsd/OpenBSDProcess.c index c2f2ed4..681d516 100644 --- a/openbsd/OpenBSDProcess.c +++ b/openbsd/OpenBSDProcess.c @@ -6,6 +6,8 @@ Released under the GNU GPLv2+, see the COPYING file in the source distribution for its full text. */ +#include "config.h" // IWYU pragma: keep + #include "openbsd/OpenBSDProcess.h" #include @@ -204,10 +206,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { }; -Process* OpenBSDProcess_new(const Settings* settings) { +Process* OpenBSDProcess_new(const Machine* host) { OpenBSDProcess* this = xCalloc(1, sizeof(OpenBSDProcess)); Object_setClass(this, Class(OpenBSDProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, host); return &this->super; } @@ -217,17 +219,20 @@ void Process_delete(Object* cast) { free(this); } -static void OpenBSDProcess_writeField(const Process* this, RichString* str, ProcessField field) { - //const OpenBSDProcess* op = (const OpenBSDProcess*) this; +static void OpenBSDProcess_rowWriteField(const Row* super, RichString* str, ProcessField field) { + const OpenBSDProcess* op = (const OpenBSDProcess*) 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 OpenBSD-specific fields here default: - Process_writeField(this, str, field); + Process_writeField(&op->super, str, field); return; } + RichString_appendWide(str, attr, buffer); } @@ -247,11 +252,18 @@ static int OpenBSDProcess_compareByKey(const Process* v1, const Process* v2, Pro const ProcessClass OpenBSDProcess_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 = OpenBSDProcess_rowWriteField }, - .writeField = OpenBSDProcess_writeField, .compareByKey = OpenBSDProcess_compareByKey }; diff --git a/openbsd/OpenBSDProcess.h b/openbsd/OpenBSDProcess.h index 898c537..aac4b31 100644 --- a/openbsd/OpenBSDProcess.h +++ b/openbsd/OpenBSDProcess.h @@ -10,9 +10,9 @@ in the source distribution for its full text. #include +#include "Machine.h" #include "Object.h" #include "Process.h" -#include "Settings.h" typedef struct OpenBSDProcess_ { @@ -26,7 +26,7 @@ extern const ProcessClass OpenBSDProcess_class; extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; -Process* OpenBSDProcess_new(const Settings* settings); +Process* OpenBSDProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/openbsd/OpenBSDProcessList.c b/openbsd/OpenBSDProcessList.c deleted file mode 100644 index d070e5e..0000000 --- a/openbsd/OpenBSDProcessList.c +++ /dev/null @@ -1,486 +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 - -#include "CRT.h" -#include "Macros.h" -#include "Object.h" -#include "Process.h" -#include "ProcessList.h" -#include "Settings.h" -#include "XUtils.h" -#include "openbsd/OpenBSDProcess.h" - - -static long fscale; -static int pageSize; -static int pageSizeKB; - -static void OpenBSDProcessList_updateCPUcount(ProcessList* super) { - OpenBSDProcessList* opl = (OpenBSDProcessList*) super; - const int nmib[] = { CTL_HW, HW_NCPU }; - const int mib[] = { CTL_HW, HW_NCPUONLINE }; - int r; - unsigned int value; - size_t size; - bool change = false; - - size = sizeof(value); - r = sysctl(mib, 2, &value, &size, NULL, 0); - if (r < 0 || value < 1) { - value = 1; - } - - if (value != super->activeCPUs) { - super->activeCPUs = value; - change = true; - } - - size = sizeof(value); - r = sysctl(nmib, 2, &value, &size, NULL, 0); - if (r < 0 || value < 1) { - value = super->activeCPUs; - } - - if (value != super->existingCPUs) { - opl->cpuData = xReallocArray(opl->cpuData, value + 1, sizeof(CPUData)); - super->existingCPUs = value; - change = true; - } - - if (change) { - CPUData* dAvg = &opl->cpuData[0]; - memset(dAvg, '\0', sizeof(CPUData)); - dAvg->totalTime = 1; - dAvg->totalPeriod = 1; - dAvg->online = true; - - for (unsigned int i = 0; i < super->existingCPUs; i++) { - CPUData* d = &opl->cpuData[i + 1]; - memset(d, '\0', sizeof(CPUData)); - d->totalTime = 1; - d->totalPeriod = 1; - - const int ncmib[] = { CTL_KERN, KERN_CPUSTATS, i }; - struct cpustats cpu_stats; - - size = sizeof(cpu_stats); - if (sysctl(ncmib, 3, &cpu_stats, &size, NULL, 0) < 0) { - CRT_fatalError("ncmib sysctl call failed"); - } - d->online = (cpu_stats.cs_flags & CPUSTATS_ONLINE); - } - } -} - - -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, Hashtable* dynamicColumns, Hashtable* pidMatchList, uid_t userId) { - const int fmib[] = { CTL_KERN, KERN_FSCALE }; - size_t size; - char errbuf[_POSIX2_LINE_MAX]; - - OpenBSDProcessList* opl = xCalloc(1, sizeof(OpenBSDProcessList)); - ProcessList* pl = (ProcessList*) opl; - ProcessList_init(pl, Class(OpenBSDProcess), usersTable, dynamicMeters, dynamicColumns, pidMatchList, userId); - - OpenBSDProcessList_updateCPUcount(pl); - - size = sizeof(fscale); - if (sysctl(fmib, 2, &fscale, &size, NULL, 0) < 0) { - CRT_fatalError("fscale sysctl call failed"); - } - - if ((pageSize = sysconf(_SC_PAGESIZE)) == -1) - CRT_fatalError("pagesize sysconf call failed"); - pageSizeKB = pageSize / ONE_K; - - opl->kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); - if (opl->kd == NULL) { - CRT_fatalError("kvm_openfiles() failed"); - } - - opl->cpuSpeed = -1; - - return pl; -} - -void ProcessList_delete(ProcessList* this) { - OpenBSDProcessList* opl = (OpenBSDProcessList*) this; - - if (opl->kd) { - kvm_close(opl->kd); - } - - free(opl->cpuData); - - ProcessList_done(this); - free(this); -} - -static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) { - const int uvmexp_mib[] = { CTL_VM, VM_UVMEXP }; - struct uvmexp uvmexp; - size_t size_uvmexp = sizeof(uvmexp); - - if (sysctl(uvmexp_mib, 2, &uvmexp, &size_uvmexp, NULL, 0) < 0) { - CRT_fatalError("uvmexp sysctl call failed"); - } - - pl->totalMem = uvmexp.npages * pageSizeKB; - pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * pageSizeKB; - - // Taken from OpenBSD systat/iostat.c, top/machine.c and uvm_sysctl(9) - const int bcache_mib[] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT }; - struct bcachestats bcstats; - size_t size_bcstats = sizeof(bcstats); - - if (sysctl(bcache_mib, 3, &bcstats, &size_bcstats, NULL, 0) < 0) { - CRT_fatalError("cannot get vfs.bcachestat"); - } - - pl->cachedMem = bcstats.numbufpages * pageSizeKB; - - /* - * Copyright (c) 1994 Thorsten Lockert - * All rights reserved. - * - * Taken almost directly from OpenBSD's top(1) - * - * Originally released under a BSD-3 license - * Modified through htop developers applying GPL-2 - */ - int nswap = swapctl(SWAP_NSWAP, 0, 0); - if (nswap > 0) { - struct swapent swdev[nswap]; - int rnswap = swapctl(SWAP_STATS, swdev, nswap); - - /* Total things up */ - unsigned long long int total = 0, used = 0; - for (int i = 0; i < rnswap; i++) { - if (swdev[i].se_flags & SWF_ENABLE) { - used += (swdev[i].se_inuse / (1024 / DEV_BSIZE)); - total += (swdev[i].se_nblks / (1024 / DEV_BSIZE)); - } - } - - pl->totalSwap = total; - pl->usedSwap = used; - } else { - pl->totalSwap = pl->usedSwap = 0; - } -} - -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 struct kinfo_proc* kp) { - if (fscale == 0) - return 0.0; - - return 100.0 * (double)kp->p_pctcpu / fscale; -} - -static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { - const Settings* settings = this->super.settings; - const bool hideKernelThreads = settings->hideKernelThreads; - const bool hideUserlandThreads = settings->hideUserlandThreads; - int count = 0; - - const struct kinfo_proc* kprocs = kvm_getprocs(this->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* fp = (OpenBSDProcess*) proc; - - if (!preExisting) { - proc->ppid = kproc->p_ppid; - proc->tpgid = kproc->p_tpgid; - proc->tgid = kproc->p_pid; - 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(this->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(this->kd, kproc, proc); - } - } - - fp->addr = kproc->p_addr; - proc->m_virt = kproc->p_vm_dsize * pageSizeKB; - proc->m_resident = kproc->p_vm_rssize * pageSizeKB; - - proc->percent_mem = proc->m_resident / (float)this->super.totalMem * 100.0F; - proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0F, this->super.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(this->super.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->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc))); - proc->updated = true; - } -} - -static void getKernelCPUTimes(unsigned int cpuId, u_int64_t* times) { - const int mib[] = { CTL_KERN, KERN_CPTIME2, cpuId }; - size_t length = sizeof(*times) * CPUSTATES; - if (sysctl(mib, 3, times, &length, NULL, 0) == -1 || length != sizeof(*times) * CPUSTATES) { - CRT_fatalError("sysctl kern.cp_time2 failed"); - } -} - -static void kernelCPUTimesToHtop(const u_int64_t* times, CPUData* cpu) { - unsigned long long totalTime = 0; - for (int i = 0; i < CPUSTATES; i++) { - totalTime += times[i]; - } - - unsigned long long sysAllTime = times[CP_INTR] + times[CP_SYS]; - - // XXX Not sure if CP_SPIN should be added to sysAllTime. - // See https://github.com/openbsd/src/commit/531d8034253fb82282f0f353c086e9ad827e031c - #ifdef CP_SPIN - sysAllTime += times[CP_SPIN]; - #endif - - cpu->totalPeriod = saturatingSub(totalTime, cpu->totalTime); - cpu->userPeriod = saturatingSub(times[CP_USER], cpu->userTime); - cpu->nicePeriod = saturatingSub(times[CP_NICE], cpu->niceTime); - cpu->sysPeriod = saturatingSub(times[CP_SYS], cpu->sysTime); - cpu->sysAllPeriod = saturatingSub(sysAllTime, cpu->sysAllTime); - #ifdef CP_SPIN - cpu->spinPeriod = saturatingSub(times[CP_SPIN], cpu->spinTime); - #endif - cpu->intrPeriod = saturatingSub(times[CP_INTR], cpu->intrTime); - cpu->idlePeriod = saturatingSub(times[CP_IDLE], cpu->idleTime); - - cpu->totalTime = totalTime; - cpu->userTime = times[CP_USER]; - cpu->niceTime = times[CP_NICE]; - cpu->sysTime = times[CP_SYS]; - cpu->sysAllTime = sysAllTime; - #ifdef CP_SPIN - cpu->spinTime = times[CP_SPIN]; - #endif - cpu->intrTime = times[CP_INTR]; - cpu->idleTime = times[CP_IDLE]; -} - -static void OpenBSDProcessList_scanCPUTime(OpenBSDProcessList* this) { - u_int64_t kernelTimes[CPUSTATES] = {0}; - u_int64_t avg[CPUSTATES] = {0}; - - for (unsigned int i = 0; i < this->super.existingCPUs; i++) { - CPUData* cpu = &this->cpuData[i + 1]; - - if (!cpu->online) { - continue; - } - - getKernelCPUTimes(i, kernelTimes); - kernelCPUTimesToHtop(kernelTimes, cpu); - - avg[CP_USER] += cpu->userTime; - avg[CP_NICE] += cpu->niceTime; - avg[CP_SYS] += cpu->sysTime; - #ifdef CP_SPIN - avg[CP_SPIN] += cpu->spinTime; - #endif - avg[CP_INTR] += cpu->intrTime; - avg[CP_IDLE] += cpu->idleTime; - } - - for (int i = 0; i < CPUSTATES; i++) { - avg[i] /= this->super.activeCPUs; - } - - kernelCPUTimesToHtop(avg, &this->cpuData[0]); - - { - const int mib[] = { CTL_HW, HW_CPUSPEED }; - int cpuSpeed; - size_t size = sizeof(cpuSpeed); - if (sysctl(mib, 2, &cpuSpeed, &size, NULL, 0) == -1) { - this->cpuSpeed = -1; - } else { - this->cpuSpeed = cpuSpeed; - } - } -} - -void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { - OpenBSDProcessList* opl = (OpenBSDProcessList*) super; - - OpenBSDProcessList_updateCPUcount(super); - OpenBSDProcessList_scanMemoryInfo(super); - OpenBSDProcessList_scanCPUTime(opl); - - // in pause mode only gather global data for meters (CPU/memory/...) - if (pauseProcessUpdate) { - return; - } - - OpenBSDProcessList_scanProcs(opl); -} - -bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id) { - assert(id < super->existingCPUs); - - const OpenBSDProcessList* opl = (const OpenBSDProcessList*) super; - return opl->cpuData[id + 1].online; -} diff --git a/openbsd/OpenBSDProcessList.h b/openbsd/OpenBSDProcessList.h deleted file mode 100644 index 89fdb09..0000000 --- a/openbsd/OpenBSDProcessList.h +++ /dev/null @@ -1,60 +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 - -#include "Hashtable.h" -#include "ProcessList.h" -#include "UsersTable.h" - - -typedef struct CPUData_ { - unsigned long long int totalTime; - unsigned long long int userTime; - unsigned long long int niceTime; - unsigned long long int sysTime; - unsigned long long int sysAllTime; - unsigned long long int spinTime; - unsigned long long int intrTime; - unsigned long long int idleTime; - - unsigned long long int totalPeriod; - unsigned long long int userPeriod; - unsigned long long int nicePeriod; - unsigned long long int sysPeriod; - unsigned long long int sysAllPeriod; - unsigned long long int spinPeriod; - unsigned long long int intrPeriod; - unsigned long long int idlePeriod; - - bool online; -} CPUData; - -typedef struct OpenBSDProcessList_ { - ProcessList super; - kvm_t* kd; - - CPUData* cpuData; - int cpuSpeed; - -} OpenBSDProcessList; - - -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/openbsd/OpenBSDProcessTable.c b/openbsd/OpenBSDProcessTable.c new file mode 100644 index 0000000..f2980a4 --- /dev/null +++ b/openbsd/OpenBSDProcessTable.c @@ -0,0 +1,245 @@ +/* +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 "config.h" // IWYU pragma: keep + +#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*) cast; + 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.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 0000000..f911a10 --- /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 diff --git a/openbsd/Platform.c b/openbsd/Platform.c index b222bee..a8b5d21 100644 --- a/openbsd/Platform.c +++ b/openbsd/Platform.c @@ -6,6 +6,8 @@ Released under the GNU GPLv2+, see the COPYING file in the source distribution for its full text. */ +#include "config.h" // IWYU pragma: keep + #include "openbsd/Platform.h" #include @@ -28,13 +30,13 @@ in the source distribution for its full text. #include "ClockMeter.h" #include "DateMeter.h" #include "DateTimeMeter.h" +#include "FileDescriptorMeter.h" #include "HostnameMeter.h" #include "LoadAverageMeter.h" #include "Macros.h" #include "MemoryMeter.h" #include "MemorySwapMeter.h" #include "Meter.h" -#include "ProcessList.h" #include "Settings.h" #include "SignalsPanel.h" #include "SwapMeter.h" @@ -42,8 +44,8 @@ in the source distribution for its full text. #include "TasksMeter.h" #include "UptimeMeter.h" #include "XUtils.h" +#include "openbsd/OpenBSDMachine.h" #include "openbsd/OpenBSDProcess.h" -#include "openbsd/OpenBSDProcessList.h" const ScreenDefaults Platform_defaultScreens[] = { @@ -125,6 +127,7 @@ const MeterClass* const Platform_meterTypes[] = { &RightCPUs4Meter_class, &LeftCPUs8Meter_class, &RightCPUs8Meter_class, + &FileDescriptorMeter_class, &BlankMeter_class, NULL }; @@ -143,7 +146,7 @@ void Platform_setBindings(Htop_Action* keys) { (void) keys; } -int Platform_getUptime() { +int Platform_getUptime(void) { struct timeval bootTime, currTime; const int mib[2] = { CTL_KERN, KERN_BOOTTIME }; size_t size = sizeof(bootTime); @@ -174,13 +177,14 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen) { *fifteen = (double) loadAverage.ldavg[2] / loadAverage.fscale; } -int Platform_getMaxPid() { +pid_t Platform_getMaxPid(void) { return 2 * THREAD_PID_OFFSET; } double Platform_setCPUValues(Meter* this, unsigned int cpu) { - const OpenBSDProcessList* pl = (const OpenBSDProcessList*) this->pl; - const CPUData* cpuData = &(pl->cpuData[cpu]); + const Machine* host = this->host; + const OpenBSDMachine* ohost = (const OpenBSDMachine*) host; + const CPUData* cpuData = &ohost->cpuData[cpu]; double total; double totalPercent; double* v = this->values; @@ -194,7 +198,7 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { v[CPU_METER_NICE] = cpuData->nicePeriod / total * 100.0; v[CPU_METER_NORMAL] = cpuData->userPeriod / total * 100.0; - if (this->pl->settings->detailedCPUTime) { + if (host->settings->detailedCPUTime) { v[CPU_METER_KERNEL] = cpuData->sysPeriod / total * 100.0; v[CPU_METER_IRQ] = cpuData->intrPeriod / total * 100.0; v[CPU_METER_SOFTIRQ] = 0.0; @@ -203,42 +207,43 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { v[CPU_METER_IOWAIT] = 0.0; v[CPU_METER_FREQUENCY] = NAN; this->curItems = 8; - totalPercent = v[0] + v[1] + v[2] + v[3]; } else { - v[2] = cpuData->sysAllPeriod / total * 100.0; - v[3] = 0.0; // No steal nor guest on OpenBSD - totalPercent = v[0] + v[1] + v[2]; + v[CPU_METER_KERNEL] = cpuData->sysAllPeriod / total * 100.0; + v[CPU_METER_IRQ] = 0.0; // No steal nor guest on OpenBSD this->curItems = 4; } + totalPercent = v[CPU_METER_NICE] + v[CPU_METER_NORMAL] + v[CPU_METER_KERNEL] + v[CPU_METER_IRQ]; totalPercent = CLAMP(totalPercent, 0.0, 100.0); v[CPU_METER_TEMPERATURE] = NAN; - v[CPU_METER_FREQUENCY] = (pl->cpuSpeed != -1) ? pl->cpuSpeed : NAN; + v[CPU_METER_FREQUENCY] = (ohost->cpuSpeed != -1) ? ohost->cpuSpeed : NAN; return totalPercent; } void Platform_setMemoryValues(Meter* this) { - const ProcessList* pl = this->pl; - long int usedMem = pl->usedMem; - long int buffersMem = pl->buffersMem; - long int cachedMem = pl->cachedMem; + const Machine* host = this->host; + long int usedMem = host->usedMem; + long int buffersMem = host->buffersMem; + long int cachedMem = host->cachedMem; usedMem -= buffersMem + cachedMem; - this->total = pl->totalMem; - this->values[0] = usedMem; - this->values[1] = buffersMem; - // this->values[2] = "shared memory, like tmpfs and shm" - this->values[3] = cachedMem; - // this->values[4] = "available memory" + this->total = host->totalMem; + this->values[MEMORY_METER_USED] = usedMem; + // this->values[MEMORY_METER_SHARED] = "shared memory, like tmpfs and shm" + // this->values[MEMORY_METER_COMPRESSED] = "compressed memory, like zswap on linux" + this->values[MEMORY_METER_BUFFERS] = buffersMem; + this->values[MEMORY_METER_CACHE] = cachedMem; + // this->values[MEMORY_METER_AVAILABLE] = "available memory" } void Platform_setSwapValues(Meter* this) { - const ProcessList* pl = this->pl; - this->total = pl->totalSwap; - this->values[0] = pl->usedSwap; - this->values[1] = NAN; + const Machine* host = this->host; + this->total = host->totalSwap; + this->values[SWAP_METER_USED] = host->usedSwap; + // this->values[SWAP_METER_CACHE] = "pages that are both in swap and RAM, like SwapCached on linux" + // this->values[SWAP_METER_FRONTSWAP] = "pages that are accounted to swap but stored elsewhere, like frontswap on linux" } char* Platform_getProcessEnv(pid_t pid) { @@ -296,15 +301,33 @@ end: 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) { + static const int mib_kern_maxfile[] = { CTL_KERN, KERN_MAXFILES }; + int sysctl_maxfile = 0; + size_t size_maxfile = sizeof(int); + if (sysctl(mib_kern_maxfile, ARRAYSIZE(mib_kern_maxfile), &sysctl_maxfile, &size_maxfile, NULL, 0) < 0) { + *max = NAN; + } else if (size_maxfile != sizeof(int) || sysctl_maxfile < 1) { + *max = NAN; + } else { + *max = sysctl_maxfile; + } + + static const int mib_kern_nfiles[] = { CTL_KERN, KERN_NFILES }; + int sysctl_nfiles = 0; + size_t size_nfiles = sizeof(int); + if (sysctl(mib_kern_nfiles, ARRAYSIZE(mib_kern_nfiles), &sysctl_nfiles, &size_nfiles, NULL, 0) < 0) { + *used = NAN; + } else if (size_nfiles != sizeof(int) || sysctl_nfiles < 0) { + *used = NAN; + } else { + *used = sysctl_nfiles; + } } bool Platform_getDiskIO(DiskIOData* data) { diff --git a/openbsd/Platform.h b/openbsd/Platform.h index e3d6116..339616c 100644 --- a/openbsd/Platform.h +++ b/openbsd/Platform.h @@ -47,7 +47,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* this, unsigned int cpu); @@ -57,10 +57,10 @@ void Platform_setSwapValues(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); @@ -91,7 +91,9 @@ static inline void Platform_gettime_monotonic(uint64_t* msec) { Generic_gettime_monotonic(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) { } @@ -101,12 +103,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 -- cgit v1.2.3