From e4e3f6c390452b4996ece4c92284410e58634052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Fri, 19 Mar 2021 17:34:12 +0100 Subject: OpenBSD: update * Set process data for: - minflt - majflt - processor - nlwp * Drop unimplemented nlwp column * Scan userland threads * Mark a 'Thread is currently on a CPU.' with 'R', and processes 'Currently runnable' with 'P', do confine with man:ps(1) and Linux. See https://man.openbsd.org/ps.1 * Show CPU frequency --- openbsd/OpenBSDProcess.h | 11 +++++++-- openbsd/OpenBSDProcessList.c | 53 ++++++++++++++++++++++++++++++++++---------- openbsd/OpenBSDProcessList.h | 1 + openbsd/Platform.c | 7 ++++-- 4 files changed, 56 insertions(+), 16 deletions(-) (limited to 'openbsd') diff --git a/openbsd/OpenBSDProcess.h b/openbsd/OpenBSDProcess.h index 6aab29a0..79f9b0fe 100644 --- a/openbsd/OpenBSDProcess.h +++ b/openbsd/OpenBSDProcess.h @@ -17,11 +17,18 @@ in the source distribution for its full text. typedef struct OpenBSDProcess_ { Process super; + + /* 'Kernel virtual addr of u-area' to detect main threads */ + uint64_t addr; } OpenBSDProcess; -#define Process_isKernelThread(_process) (_process->pgrp == 0) +static inline bool Process_isKernelThread(const Process* this) { + return this->pgrp == 0; +} -#define Process_isUserlandThread(_process) (_process->pid != _process->tgid) +static inline bool Process_isUserlandThread(const Process* this) { + return this->pid != this->tgid; +} extern const ProcessClass OpenBSDProcess_class; diff --git a/openbsd/OpenBSDProcessList.c b/openbsd/OpenBSDProcessList.c index ff5c9278..bd50d4e1 100644 --- a/openbsd/OpenBSDProcessList.c +++ b/openbsd/OpenBSDProcessList.c @@ -74,6 +74,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui CRT_fatalError("kvm_openfiles() failed"); } + opl->cpuSpeed = -1; + return pl; } @@ -192,18 +194,29 @@ static double getpcpu(const struct kinfo_proc* kp) { static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { const Settings* settings = this->super.settings; - bool hideKernelThreads = settings->hideKernelThreads; - bool hideUserlandThreads = settings->hideUserlandThreads; + 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, 0, sizeof(struct kinfo_proc), &count); + 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_pid, &preExisting, OpenBSDProcess_new); - //OpenBSDProcess* fp = (OpenBSDProcess*) proc; + Process* proc = ProcessList_getProcess(&this->super, (kproc->p_tid == -1) ? kproc->p_pid : kproc->p_tid, &preExisting, OpenBSDProcess_new); + OpenBSDProcess* fp = (OpenBSDProcess*) proc; proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc))); @@ -227,33 +240,38 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { } } + 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 / (double)(this->super.totalMem) * 100.0; - proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0, this->super.cpuCount * 100.0); - //proc->nlwp = kproc->p_numthreads; + proc->percent_mem = proc->m_resident / (float)this->super.totalMem * 100.0F; + proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0F, this->super.cpuCount * 100.0F); 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; switch (kproc->p_stat) { case SIDL: proc->state = 'I'; break; - case SRUN: proc->state = 'R'; break; + case SRUN: proc->state = 'P'; break; case SSLEEP: proc->state = 'S'; break; case SSTOP: proc->state = 'T'; break; case SZOMB: proc->state = 'Z'; break; case SDEAD: proc->state = 'D'; break; - case SONPROC: proc->state = 'P'; break; + case SONPROC: proc->state = 'R'; break; default: proc->state = '?'; } if (Process_isKernelThread(proc)) { this->super.kernelThreads++; + } else if (Process_isUserlandThread(proc)) { + this->super.userlandThreads++; } this->super.totalTasks++; - // SRUN ('R') means runnable, not running - if (proc->state == 'P') { + if (proc->state == 'R') { this->super.runningTasks++; } proc->updated = true; @@ -333,6 +351,17 @@ static void OpenBSDProcessList_scanCPUTime(OpenBSDProcessList* this) { } kernelCPUTimesToHtop(avg, this->cpus); + + { + 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) { diff --git a/openbsd/OpenBSDProcessList.h b/openbsd/OpenBSDProcessList.h index a6195a52..46f53505 100644 --- a/openbsd/OpenBSDProcessList.h +++ b/openbsd/OpenBSDProcessList.h @@ -42,6 +42,7 @@ typedef struct OpenBSDProcessList_ { kvm_t* kd; CPUData* cpus; + int cpuSpeed; } OpenBSDProcessList; diff --git a/openbsd/Platform.c b/openbsd/Platform.c index c57e6cc3..e95419b7 100644 --- a/openbsd/Platform.c +++ b/openbsd/Platform.c @@ -15,6 +15,8 @@ in the source distribution for its full text. #include #include #include +#include // needs to be included before for 'struct sigaltstack' +#include #include #include #include @@ -162,8 +164,7 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen) { } int Platform_getMaxPid() { - // this is hard-coded in sys/proc.h - no sysctl exists - return 99999; + return 2 * THREAD_PID_OFFSET; } double Platform_setCPUValues(Meter* this, int cpu) { @@ -196,6 +197,8 @@ double Platform_setCPUValues(Meter* this, int cpu) { v[CPU_METER_TEMPERATURE] = NAN; + v[CPU_METER_FREQUENCY] = (pl->cpuSpeed != -1) ? pl->cpuSpeed : NAN; + return totalPercent; } -- cgit v1.2.3