aboutsummaryrefslogtreecommitdiffstats
path: root/freebsd
diff options
context:
space:
mode:
authorDaniel Lange <DLange@git.local>2021-09-21 08:35:19 +0200
committerDaniel Lange <DLange@git.local>2021-09-21 08:35:19 +0200
commit69f439eff387a6ecb52734e400b297a3c85f2285 (patch)
tree2a988b7868b749654796183ba70b4272965da1bf /freebsd
parentc55320e9e2a8916e911bcd39ab37b79e3a7d03b2 (diff)
downloaddebian_htop-69f439eff387a6ecb52734e400b297a3c85f2285.tar.gz
debian_htop-69f439eff387a6ecb52734e400b297a3c85f2285.tar.bz2
debian_htop-69f439eff387a6ecb52734e400b297a3c85f2285.zip
New upstream version 3.1.0upstream/3.1.0
Diffstat (limited to 'freebsd')
-rw-r--r--freebsd/FreeBSDProcess.c53
-rw-r--r--freebsd/FreeBSDProcess.h16
-rw-r--r--freebsd/FreeBSDProcessList.c332
-rw-r--r--freebsd/FreeBSDProcessList.h15
-rw-r--r--freebsd/Platform.c69
-rw-r--r--freebsd/Platform.h54
-rw-r--r--freebsd/ProcessField.h2
7 files changed, 289 insertions, 252 deletions
diff --git a/freebsd/FreeBSDProcess.c b/freebsd/FreeBSDProcess.c
index 28d482e..9f0386b 100644
--- a/freebsd/FreeBSDProcess.c
+++ b/freebsd/FreeBSDProcess.c
@@ -5,7 +5,7 @@ Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
-#include "FreeBSDProcess.h"
+#include "freebsd/FreeBSDProcess.h"
#include <stdlib.h>
@@ -26,25 +26,27 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = {
[PPID] = { .name = "PPID", .title = "PPID", .description = "Parent process ID", .flags = 0, .pidColumn = true, },
[PGRP] = { .name = "PGRP", .title = "PGRP", .description = "Process group ID", .flags = 0, .pidColumn = true, },
[SESSION] = { .name = "SESSION", .title = "SID", .description = "Process's session ID", .flags = 0, .pidColumn = true, },
- [TTY_NR] = { .name = "TTY_NR", .title = " TTY ", .description = "Controlling terminal", .flags = PROCESS_FLAG_FREEBSD_TTY, },
+ [TTY] = { .name = "TTY", .title = "TTY ", .description = "Controlling terminal", .flags = 0, },
[TPGID] = { .name = "TPGID", .title = "TPGID", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, .pidColumn = true, },
- [MINFLT] = { .name = "MINFLT", .title = " MINFLT ", .description = "Number of minor faults which have not required loading a memory page from disk", .flags = 0, },
- [MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },
+ [MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of copy-on-write faults", .flags = 0, .defaultSortDesc = true, },
[PRIORITY] = { .name = "PRIORITY", .title = "PRI ", .description = "Kernel's internal priority for the process", .flags = 0, },
[NICE] = { .name = "NICE", .title = " NI ", .description = "Nice value (the higher the value, the more it lets other processes take priority)", .flags = 0, },
[STARTTIME] = { .name = "STARTTIME", .title = "START ", .description = "Time the process was started", .flags = 0, },
-
+ [ELAPSED] = { .name = "ELAPSED", .title = "ELAPSED ", .description = "Time since the process was started", .flags = 0, },
[PROCESSOR] = { .name = "PROCESSOR", .title = "CPU ", .description = "Id of the CPU the process last executed on", .flags = 0, },
- [M_VIRT] = { .name = "M_VIRT", .title = " VIRT ", .description = "Total program size in virtual memory", .flags = 0, },
- [M_RESIDENT] = { .name = "M_RESIDENT", .title = " RES ", .description = "Resident set size, size of the text and data sections, plus stack usage", .flags = 0, },
+ [M_VIRT] = { .name = "M_VIRT", .title = " VIRT ", .description = "Total program size in virtual memory", .flags = 0, .defaultSortDesc = true, },
+ [M_RESIDENT] = { .name = "M_RESIDENT", .title = " RES ", .description = "Resident set size, size of the text and data sections, plus stack usage", .flags = 0, .defaultSortDesc = true, },
[ST_UID] = { .name = "ST_UID", .title = " UID ", .description = "User ID of the process owner", .flags = 0, },
- [PERCENT_CPU] = { .name = "PERCENT_CPU", .title = "CPU% ", .description = "Percentage of the CPU time the process used in the last sampling", .flags = 0, },
- [PERCENT_NORM_CPU] = { .name = "PERCENT_NORM_CPU", .title = "NCPU%", .description = "Normalized percentage of the CPU time the process used in the last sampling (normalized by cpu count)", .flags = 0, },
- [PERCENT_MEM] = { .name = "PERCENT_MEM", .title = "MEM% ", .description = "Percentage of the memory the process is using, based on resident memory size", .flags = 0, },
+ [PERCENT_CPU] = { .name = "PERCENT_CPU", .title = "CPU% ", .description = "Percentage of the CPU time the process used in the last sampling", .flags = 0, .defaultSortDesc = true, },
+ [PERCENT_NORM_CPU] = { .name = "PERCENT_NORM_CPU", .title = "NCPU%", .description = "Normalized percentage of the CPU time the process used in the last sampling (normalized by cpu count)", .flags = 0, .defaultSortDesc = true, },
+ [PERCENT_MEM] = { .name = "PERCENT_MEM", .title = "MEM% ", .description = "Percentage of the memory the process is using, based on resident memory size", .flags = 0, .defaultSortDesc = true, },
[USER] = { .name = "USER", .title = "USER ", .description = "Username of the process owner (or user ID if name cannot be determined)", .flags = 0, },
- [TIME] = { .name = "TIME", .title = " TIME+ ", .description = "Total time the process has spent in user and system time", .flags = 0, },
- [NLWP] = { .name = "NLWP", .title = "NLWP ", .description = "Number of threads in the process", .flags = 0, },
+ [TIME] = { .name = "TIME", .title = " TIME+ ", .description = "Total time the process has spent in user and system time", .flags = 0, .defaultSortDesc = true, },
+ [NLWP] = { .name = "NLWP", .title = "NLWP ", .description = "Number of threads in the process", .flags = 0, .defaultSortDesc = true, },
[TGID] = { .name = "TGID", .title = "TGID", .description = "Thread group ID (i.e. process ID)", .flags = 0, .pidColumn = true, },
+ [PROC_COMM] = { .name = "COMM", .title = "COMM ", .description = "comm string of the process", .flags = 0, },
+ [PROC_EXE] = { .name = "EXE", .title = "EXE ", .description = "Basename of exe of the process", .flags = 0, },
+ [CWD] = { .name = "CWD", .title = "CWD ", .description = "The current working directory of the process", .flags = PROCESS_FLAG_CWD, },
[JID] = { .name = "JID", .title = "JID", .description = "Jail prison ID", .flags = 0, .pidColumn = true, },
[JAIL] = { .name = "JAIL", .title = "JAIL ", .description = "Jail prison name", .flags = 0, },
};
@@ -65,25 +67,16 @@ void Process_delete(Object* cast) {
static void FreeBSDProcess_writeField(const Process* this, RichString* str, ProcessField field) {
const FreeBSDProcess* fp = (const FreeBSDProcess*) this;
- char buffer[256]; buffer[255] = '\0';
+ char buffer[256];
+ size_t n = sizeof(buffer);
int attr = CRT_colors[DEFAULT_COLOR];
- int n = sizeof(buffer) - 1;
+
switch (field) {
// add FreeBSD-specific fields here
case JID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, fp->jid); break;
case JAIL:
Process_printLeftAlignedField(str, attr, fp->jname ? fp->jname : "N/A", 11);
return;
- case TTY_NR:
- if (fp->ttyPath) {
- if (fp->ttyPath == nodevStr)
- attr = CRT_colors[PROCESS_SHADOW];
- xSnprintf(buffer, n, "%-8s", fp->ttyPath);
- } else {
- attr = CRT_colors[PROCESS_SHADOW];
- xSnprintf(buffer, n, "? ");
- }
- break;
default:
Process_writeField(this, str, field);
return;
@@ -101,23 +94,11 @@ static int FreeBSDProcess_compareByKey(const Process* v1, const Process* v2, Pro
return SPACESHIP_NUMBER(p1->jid, p2->jid);
case JAIL:
return SPACESHIP_NULLSTR(p1->jname, p2->jname);
- case TTY_NR:
- return SPACESHIP_NULLSTR(p1->ttyPath, p2->ttyPath);
default:
return Process_compareByKey_Base(v1, v2, key);
}
}
-bool Process_isThread(const Process* this) {
- const FreeBSDProcess* fp = (const FreeBSDProcess*) this;
-
- if (fp->kernel == 1 ) {
- return 1;
- } else {
- return Process_isUserlandThread(this);
- }
-}
-
const ProcessClass FreeBSDProcess_class = {
.super = {
.extends = Class(Process),
diff --git a/freebsd/FreeBSDProcess.h b/freebsd/FreeBSDProcess.h
index 6bf2c93..0e0bd59 100644
--- a/freebsd/FreeBSDProcess.h
+++ b/freebsd/FreeBSDProcess.h
@@ -14,26 +14,12 @@ in the source distribution for its full text.
#include "Settings.h"
-#define PROCESS_FLAG_FREEBSD_TTY 0x0100
-
-extern const char* const nodevStr;
-
typedef struct FreeBSDProcess_ {
Process super;
- int kernel;
int jid;
char* jname;
- const char* ttyPath;
} FreeBSDProcess;
-static inline bool Process_isKernelThread(const Process* this) {
- return ((const FreeBSDProcess*)this)->kernel == 1;
-}
-
-static inline bool Process_isUserlandThread(const Process* this) {
- return this->pid != this->tgid;
-}
-
extern const ProcessClass FreeBSDProcess_class;
extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
@@ -42,6 +28,4 @@ Process* FreeBSDProcess_new(const Settings* settings);
void Process_delete(Object* cast);
-bool Process_isThread(const Process* this);
-
#endif
diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c
index 679f640..48c0648 100644
--- a/freebsd/FreeBSDProcessList.c
+++ b/freebsd/FreeBSDProcessList.c
@@ -5,11 +5,13 @@ Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
-#include "FreeBSDProcessList.h"
+#include "config.h" // IWYU pragma: keep
+
+#include "freebsd/FreeBSDProcessList.h"
#include <assert.h>
-#include <dirent.h>
#include <limits.h>
+#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <sys/_iovec.h>
@@ -19,7 +21,6 @@ in the source distribution for its full text.
#include <sys/priority.h>
#include <sys/proc.h>
#include <sys/resource.h>
-#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/types.h>
@@ -34,11 +35,9 @@ in the source distribution for its full text.
#include "ProcessList.h"
#include "Settings.h"
#include "XUtils.h"
+#include "generic/openzfs_sysctl.h"
#include "zfs/ZfsArcStats.h"
-#include "zfs/openzfs_sysctl.h"
-
-char jail_errmsg[JAIL_ERRMSGLEN];
static int MIB_hw_physmem[2];
static int MIB_vm_stats_vm_v_page_count[4];
@@ -57,12 +56,12 @@ static int MIB_kern_cp_time[2];
static int MIB_kern_cp_times[2];
static int kernelFScale;
-ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {
+ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* dynamicMeters, Hashtable* DynamicColumns, Hashtable* pidMatchList, uid_t userId) {
size_t len;
char errbuf[_POSIX2_LINE_MAX];
FreeBSDProcessList* fpl = xCalloc(1, sizeof(FreeBSDProcessList));
ProcessList* pl = (ProcessList*) fpl;
- ProcessList_init(pl, Class(FreeBSDProcess), usersTable, pidMatchList, userId);
+ ProcessList_init(pl, Class(FreeBSDProcess), usersTable, dynamicMeters, DynamicColumns, pidMatchList, userId);
// physical memory in system: hw.physmem
// physical page size: hw.pagesize
@@ -126,13 +125,15 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
sysctl(MIB_kern_cp_times, 2, fpl->cp_times_o, &len, NULL, 0);
}
- pl->cpuCount = MAXIMUM(cpus, 1);
+ pl->existingCPUs = MAXIMUM(cpus, 1);
+ // TODO: support offline CPUs and hot swapping
+ pl->activeCPUs = pl->existingCPUs;
if (cpus == 1 ) {
fpl->cpus = xRealloc(fpl->cpus, sizeof(CPUData));
} else {
// on smp we need CPUs + 1 to store averages too (as kernel kindly provides that as well)
- fpl->cpus = xRealloc(fpl->cpus, (pl->cpuCount + 1) * sizeof(CPUData));
+ fpl->cpus = xRealloc(fpl->cpus, (pl->existingCPUs + 1) * sizeof(CPUData));
}
@@ -147,16 +148,12 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
CRT_fatalError("kvm_openfiles() failed");
}
- fpl->ttys = Hashtable_new(20, true);
-
return pl;
}
void ProcessList_delete(ProcessList* this) {
const FreeBSDProcessList* fpl = (FreeBSDProcessList*) this;
- Hashtable_delete(fpl->ttys);
-
if (fpl->kd) {
kvm_close(fpl->kd);
}
@@ -171,11 +168,11 @@ void ProcessList_delete(ProcessList* this) {
free(this);
}
-static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
+static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) {
const FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl;
- int cpus = pl->cpuCount; // actual CPU count
- int maxcpu = cpus; // max iteration (in case we have average + smp)
+ unsigned int cpus = pl->existingCPUs; // actual CPU count
+ unsigned int maxcpu = cpus; // max iteration (in case we have average + smp)
int cp_times_offset;
assert(cpus > 0);
@@ -202,7 +199,7 @@ static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
sysctl(MIB_kern_cp_times, 2, fpl->cp_times_n, &sizeof_cp_time_array, NULL, 0);
}
- for (int i = 0; i < maxcpu; i++) {
+ for (unsigned int i = 0; i < maxcpu; i++) {
if (cpus == 1) {
// single CPU box
cp_time_n = fpl->cp_time_n;
@@ -248,8 +245,69 @@ static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
cpuData->systemPercent = cp_time_p[CP_SYS];
cpuData->irqPercent = cp_time_p[CP_INTR];
cpuData->systemAllPercent = cp_time_p[CP_SYS] + cp_time_p[CP_INTR];
- // this one is not really used, but we store it anyway
- cpuData->idlePercent = cp_time_p[CP_IDLE];
+ // this one is not really used
+ //cpuData->idlePercent = cp_time_p[CP_IDLE];
+
+ cpuData->temperature = NAN;
+ cpuData->frequency = NAN;
+
+ const int coreId = (cpus == 1) ? 0 : ((int)i - 1);
+ if (coreId < 0)
+ continue;
+
+ // TODO: test with hyperthreading and multi-cpu systems
+ if (pl->settings->showCPUTemperature) {
+ int temperature;
+ size_t len = sizeof(temperature);
+ char mibBuffer[32];
+ xSnprintf(mibBuffer, sizeof(mibBuffer), "dev.cpu.%d.temperature", coreId);
+ int r = sysctlbyname(mibBuffer, &temperature, &len, NULL, 0);
+ if (r == 0)
+ cpuData->temperature = (double)(temperature - 2732) / 10.0; // convert from deci-Kelvin to Celsius
+ }
+
+ // TODO: test with hyperthreading and multi-cpu systems
+ if (pl->settings->showCPUFrequency) {
+ int frequency;
+ size_t len = sizeof(frequency);
+ char mibBuffer[32];
+ xSnprintf(mibBuffer, sizeof(mibBuffer), "dev.cpu.%d.freq", coreId);
+ int r = sysctlbyname(mibBuffer, &frequency, &len, NULL, 0);
+ if (r == 0)
+ cpuData->frequency = frequency; // keep in MHz
+ }
+ }
+
+ // calculate max temperature and avg frequency for average meter and
+ // propagate frequency to all cores if only supplied for CPU 0
+ if (cpus > 1) {
+ if (pl->settings->showCPUTemperature) {
+ double maxTemp = NAN;
+ for (unsigned int i = 1; i < maxcpu; i++) {
+ const double coreTemp = fpl->cpus[i].temperature;
+ if (isnan(coreTemp))
+ continue;
+
+ maxTemp = MAXIMUM(maxTemp, coreTemp);
+ }
+
+ fpl->cpus[0].temperature = maxTemp;
+ }
+
+ if (pl->settings->showCPUFrequency) {
+ const double coreZeroFreq = fpl->cpus[1].frequency;
+ double freqSum = coreZeroFreq;
+ if (!isnan(coreZeroFreq)) {
+ for (unsigned int i = 2; i < maxcpu; i++) {
+ if (isnan(fpl->cpus[i].frequency))
+ fpl->cpus[i].frequency = coreZeroFreq;
+
+ freqSum += fpl->cpus[i].frequency;
+ }
+
+ fpl->cpus[0].frequency = freqSum / (maxcpu - 1);
+ }
+ }
}
}
@@ -321,132 +379,96 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) {
pl->usedSwap *= pageSizeKb;
}
-static void FreeBSDProcessList_scanTTYs(ProcessList* pl) {
- FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl;
-
- // scan /dev/tty*
- {
- DIR* dirPtr = opendir("/dev");
- if (!dirPtr)
- return;
-
- int dirFd = dirfd(dirPtr);
- if (dirFd < 0)
- goto err1;
-
- const struct dirent* entry;
- while ((entry = readdir(dirPtr))) {
- if (!String_startsWith(entry->d_name, "tty"))
- continue;
-
- struct stat info;
- if (Compat_fstatat(dirFd, "/dev", entry->d_name, &info, 0) < 0)
- continue;
+static void FreeBSDProcessList_updateExe(const struct kinfo_proc* kproc, Process* proc) {
+ if (Process_isKernelThread(proc)) {
+ Process_updateExe(proc, NULL);
+ return;
+ }
- if (!S_ISCHR(info.st_mode))
- continue;
+ const int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, kproc->ki_pid };
+ char buffer[2048];
+ size_t size = sizeof(buffer);
+ if (sysctl(mib, 4, buffer, &size, NULL, 0) != 0) {
+ Process_updateExe(proc, NULL);
+ return;
+ }
- if (!Hashtable_get(fpl->ttys, info.st_rdev))
- Hashtable_put(fpl->ttys, info.st_rdev, xStrdup(entry->d_name));
- }
+ Process_updateExe(proc, buffer);
+}
-err1:
- closedir(dirPtr);
+static void FreeBSDProcessList_updateCwd(const struct kinfo_proc* kproc, Process* proc) {
+ const int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_CWD, kproc->ki_pid };
+ char buffer[2048];
+ size_t size = sizeof(buffer);
+ if (sysctl(mib, 4, buffer, &size, NULL, 0) != 0) {
+ free(proc->procCwd);
+ proc->procCwd = NULL;
+ return;
}
- // scan /dev/pts/*
- {
- DIR* dirPtr = opendir("/dev/pts");
- if (!dirPtr)
- return;
-
- int dirFd = dirfd(dirPtr);
- if (dirFd < 0)
- goto err2;
-
- const struct dirent* entry;
- while ((entry = readdir(dirPtr))) {
- struct stat info;
- if (Compat_fstatat(dirFd, "/dev/pts", entry->d_name, &info, 0) < 0)
- continue;
-
- if (!S_ISCHR(info.st_mode))
- continue;
-
- if (!Hashtable_get(fpl->ttys, info.st_rdev)) {
- char* path;
- xAsprintf(&path, "pts/%s", entry->d_name);
- Hashtable_put(fpl->ttys, info.st_rdev, path);
- }
- }
-
-err2:
- closedir(dirPtr);
+ /* Kernel threads return an empty buffer */
+ if (buffer[0] == '\0') {
+ free(proc->procCwd);
+ proc->procCwd = NULL;
+ return;
}
+
+ free_and_xStrdup(&proc->procCwd, buffer);
}
-static char* FreeBSDProcessList_readProcessName(kvm_t* kd, const struct kinfo_proc* kproc, int* basenameEnd) {
+static void FreeBSDProcessList_updateProcessName(kvm_t* kd, const struct kinfo_proc* kproc, Process* proc) {
+ Process_updateComm(proc, kproc->ki_comm);
+
char** argv = kvm_getargv(kd, kproc, 0);
- if (!argv) {
- return xStrdup(kproc->ki_comm);
+ if (!argv || !argv[0]) {
+ Process_updateCmdline(proc, kproc->ki_comm, 0, strlen(kproc->ki_comm));
+ return;
}
- int len = 0;
+
+ size_t len = 0;
for (int i = 0; argv[i]; i++) {
len += strlen(argv[i]) + 1;
}
- char* comm = xMalloc(len);
- char* at = comm;
- *basenameEnd = 0;
+
+ char* cmdline = xMalloc(len);
+ char* at = cmdline;
+ int end = 0;
for (int i = 0; argv[i]; i++) {
at = stpcpy(at, argv[i]);
- if (!*basenameEnd) {
- *basenameEnd = at - comm;
+ if (end == 0) {
+ end = at - cmdline;
}
- *at = ' ';
- at++;
+ *at++ = ' ';
}
at--;
*at = '\0';
- return comm;
+
+ Process_updateCmdline(proc, cmdline, 0, end);
}
static char* FreeBSDProcessList_readJailName(const struct kinfo_proc* kproc) {
- char* jname = NULL;
- char jnamebuf[MAXHOSTNAMELEN];
+ if (kproc->ki_jid == 0)
+ return xStrdup("-");
- if (kproc->ki_jid != 0) {
- struct iovec jiov[6];
+ char jnamebuf[MAXHOSTNAMELEN] = {0};
+ struct iovec jiov[4];
- memset(jnamebuf, 0, sizeof(jnamebuf));
IGNORE_WCASTQUAL_BEGIN
- *(const void**)&jiov[0].iov_base = "jid";
- jiov[0].iov_len = sizeof("jid");
- jiov[1].iov_base = (void*) &kproc->ki_jid;
- jiov[1].iov_len = sizeof(kproc->ki_jid);
- *(const void**)&jiov[2].iov_base = "name";
- jiov[2].iov_len = sizeof("name");
- jiov[3].iov_base = jnamebuf;
- jiov[3].iov_len = sizeof(jnamebuf);
- *(const void**)&jiov[4].iov_base = "errmsg";
- jiov[4].iov_len = sizeof("errmsg");
- jiov[5].iov_base = jail_errmsg;
- jiov[5].iov_len = JAIL_ERRMSGLEN;
+ *(const void**)&jiov[0].iov_base = "jid";
+ jiov[0].iov_len = sizeof("jid");
+ jiov[1].iov_base = (void*) &kproc->ki_jid;
+ jiov[1].iov_len = sizeof(kproc->ki_jid);
+ *(const void**)&jiov[2].iov_base = "name";
+ jiov[2].iov_len = sizeof("name");
+ jiov[3].iov_base = jnamebuf;
+ jiov[3].iov_len = sizeof(jnamebuf);
IGNORE_WCASTQUAL_END
- jail_errmsg[0] = 0;
- int jid = jail_get(jiov, 6, 0);
- if (jid < 0) {
- if (!jail_errmsg[0]) {
- xSnprintf(jail_errmsg, JAIL_ERRMSGLEN, "jail_get: %s", strerror(errno));
- }
- } else if (jid == kproc->ki_jid) {
- jname = xStrdup(jnamebuf);
- }
- } else {
- jname = xStrdup("-");
- }
+ int jid = jail_get(jiov, 4, 0);
+ if (jid == kproc->ki_jid)
+ return xStrdup(jnamebuf);
- return jname;
+ return NULL;
}
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
@@ -457,37 +479,27 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
openzfs_sysctl_updateArcStats(&fpl->zfs);
FreeBSDProcessList_scanMemoryInfo(super);
- FreeBSDProcessList_scanCPUTime(super);
+ FreeBSDProcessList_scanCPU(super);
// in pause mode only gather global data for meters (CPU/memory/...)
if (pauseProcessUpdate) {
return;
}
- if (settings->flags & PROCESS_FLAG_FREEBSD_TTY) {
- FreeBSDProcessList_scanTTYs(super);
- }
-
int count = 0;
- struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_PROC, 0, &count);
+ const struct kinfo_proc* kprocs = kvm_getprocs(fpl->kd, KERN_PROC_PROC, 0, &count);
for (int i = 0; i < count; i++) {
- struct kinfo_proc* kproc = &kprocs[i];
+ const struct kinfo_proc* kproc = &kprocs[i];
bool preExisting = false;
- // TODO: bool isIdleProcess = false;
Process* proc = ProcessList_getProcess(super, kproc->ki_pid, &preExisting, FreeBSDProcess_new);
FreeBSDProcess* fp = (FreeBSDProcess*) proc;
- proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
-
if (!preExisting) {
fp->jid = kproc->ki_jid;
proc->pid = kproc->ki_pid;
- if ( ! ((kproc->ki_pid == 0) || (kproc->ki_pid == 1) ) && kproc->ki_flag & P_SYSTEM) {
- fp->kernel = 1;
- } else {
- fp->kernel = 0;
- }
+ proc->isKernelThread = kproc->ki_pid != 1 && (kproc->ki_flag & P_SYSTEM);
+ proc->isUserlandThread = false;
proc->ppid = kproc->ki_ppid;
proc->tpgid = kproc->ki_tpgid;
proc->tgid = kproc->ki_pid;
@@ -498,8 +510,24 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
Process_fillStarttimeBuffer(proc);
proc->user = UsersTable_getRef(super->usersTable, proc->st_uid);
ProcessList_add(super, proc);
- proc->comm = FreeBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset);
+
+ FreeBSDProcessList_updateExe(kproc, proc);
+ FreeBSDProcessList_updateProcessName(fpl->kd, kproc, proc);
+
+ if (settings->flags & PROCESS_FLAG_CWD) {
+ FreeBSDProcessList_updateCwd(kproc, proc);
+ }
+
fp->jname = FreeBSDProcessList_readJailName(kproc);
+
+ proc->tty_nr = kproc->ki_tdev;
+ const char* name = (kproc->ki_tdev != NODEV) ? devname(kproc->ki_tdev, S_IFCHR) : NULL;
+ if (!name) {
+ free(proc->tty_name);
+ proc->tty_name = NULL;
+ } else {
+ free_and_xStrdup(&proc->tty_name, name);
+ }
} else {
if (fp->jid != kproc->ki_jid) {
// process can enter jail anytime
@@ -515,8 +543,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
proc->user = UsersTable_getRef(super->usersTable, proc->st_uid);
}
if (settings->updateProcessNames) {
- free(proc->comm);
- proc->comm = FreeBSDProcessList_readProcessName(fpl->kd, kproc, &proc->basenameOffset);
+ FreeBSDProcessList_updateProcessName(fpl->kd, kproc, proc);
}
}
@@ -529,19 +556,17 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
proc->percent_cpu = 100.0 * ((double)kproc->ki_pctcpu / (double)kernelFScale);
proc->percent_mem = 100.0 * proc->m_resident / (double)(super->totalMem);
- /*
- * TODO
- * if (proc->percent_cpu > 0.1) {
- * // system idle process should own all CPU time left regardless of CPU count
- * if ( strcmp("idle", kproc->ki_comm) == 0 ) {
- * isIdleProcess = true;
- * }
- * }
- */
+ if (kproc->ki_stat == SRUN && kproc->ki_oncpu != NOCPU) {
+ proc->processor = kproc->ki_oncpu;
+ } else {
+ proc->processor = kproc->ki_lastcpu;
+ }
+
+ proc->majflt = kproc->ki_cow;
proc->priority = kproc->ki_pri.pri_level - PZERO;
- if (strcmp("intr", kproc->ki_comm) == 0 && kproc->ki_flag & P_SYSTEM) {
+ if (String_eq("intr", kproc->ki_comm) && (kproc->ki_flag & P_SYSTEM)) {
proc->nice = 0; //@etosan: intr kernel process (not thread) has weird nice value
} else if (kproc->ki_pri.pri_class == PRI_TIMESHARE) {
proc->nice = kproc->ki_nice - NZERO;
@@ -562,16 +587,23 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
default: proc->state = '?';
}
- if (settings->flags & PROCESS_FLAG_FREEBSD_TTY) {
- fp->ttyPath = (kproc->ki_tdev == NODEV) ? nodevStr : Hashtable_get(fpl->ttys, kproc->ki_tdev);
- }
-
if (Process_isKernelThread(proc))
super->kernelThreads++;
+ proc->show = ! ((hideKernelThreads && Process_isKernelThread(proc)) || (hideUserlandThreads && Process_isUserlandThread(proc)));
+
super->totalTasks++;
if (proc->state == 'R')
super->runningTasks++;
proc->updated = true;
}
}
+
+bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id) {
+ assert(id < super->existingCPUs);
+
+ // TODO: support offline CPUs and hot swapping
+ (void) super; (void) id;
+
+ return true;
+}
diff --git a/freebsd/FreeBSDProcessList.h b/freebsd/FreeBSDProcessList.h
index f18275d..ae82205 100644
--- a/freebsd/FreeBSDProcessList.h
+++ b/freebsd/FreeBSDProcessList.h
@@ -17,16 +17,15 @@ in the source distribution for its full text.
#include "zfs/ZfsArcStats.h"
-#define JAIL_ERRMSGLEN 1024
-extern char jail_errmsg[JAIL_ERRMSGLEN];
-
typedef struct CPUData_ {
double userPercent;
double nicePercent;
double systemPercent;
double irqPercent;
- double idlePercent;
double systemAllPercent;
+
+ double frequency;
+ double temperature;
} CPUData;
typedef struct FreeBSDProcessList_ {
@@ -35,15 +34,11 @@ typedef struct FreeBSDProcessList_ {
unsigned long long int memWire;
unsigned long long int memActive;
- unsigned long long int memInactive;
- unsigned long long int memFree;
ZfsArcStats zfs;
CPUData* cpus;
- Hashtable* ttys;
-
unsigned long* cp_time_o;
unsigned long* cp_time_n;
@@ -52,10 +47,12 @@ typedef struct FreeBSDProcessList_ {
} FreeBSDProcessList;
-ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId);
+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/freebsd/Platform.c b/freebsd/Platform.c
index c74ab6d..527a455 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -5,7 +5,9 @@ Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
-#include "Platform.h"
+#include "config.h" // IWYU pragma: keep
+
+#include "freebsd/Platform.h"
#include <devstat.h>
#include <math.h>
@@ -29,20 +31,22 @@ in the source distribution for its full text.
#include "DateMeter.h"
#include "DateTimeMeter.h"
#include "DiskIOMeter.h"
-#include "FreeBSDProcess.h"
-#include "FreeBSDProcessList.h"
#include "HostnameMeter.h"
#include "LoadAverageMeter.h"
#include "Macros.h"
#include "MemoryMeter.h"
+#include "MemorySwapMeter.h"
#include "Meter.h"
#include "NetworkIOMeter.h"
#include "ProcessList.h"
#include "Settings.h"
#include "SwapMeter.h"
+#include "SysArchMeter.h"
#include "TasksMeter.h"
#include "UptimeMeter.h"
#include "XUtils.h"
+#include "freebsd/FreeBSDProcess.h"
+#include "freebsd/FreeBSDProcessList.h"
#include "zfs/ZfsArcMeter.h"
#include "zfs/ZfsCompressedArcMeter.h"
@@ -97,10 +101,12 @@ const MeterClass* const Platform_meterTypes[] = {
&LoadMeter_class,
&MemoryMeter_class,
&SwapMeter_class,
+ &MemorySwapMeter_class,
&TasksMeter_class,
&UptimeMeter_class,
&BatteryMeter_class,
&HostnameMeter_class,
+ &SysArchMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
&AllCPUs4Meter_class,
@@ -136,7 +142,7 @@ void Platform_setBindings(Htop_Action* keys) {
int Platform_getUptime() {
struct timeval bootTime, currTime;
- int mib[2] = { CTL_KERN, KERN_BOOTTIME };
+ const int mib[2] = { CTL_KERN, KERN_BOOTTIME };
size_t size = sizeof(bootTime);
int err = sysctl(mib, 2, &bootTime, &size, NULL, 0);
@@ -150,7 +156,7 @@ int Platform_getUptime() {
void Platform_getLoadAverage(double* one, double* five, double* fifteen) {
struct loadavg loadAverage;
- int mib[2] = { CTL_VM, VM_LOADAVG };
+ const int mib[2] = { CTL_VM, VM_LOADAVG };
size_t size = sizeof(loadAverage);
int err = sysctl(mib, 2, &loadAverage, &size, NULL, 0);
@@ -175,9 +181,9 @@ int Platform_getMaxPid() {
return maxPid;
}
-double Platform_setCPUValues(Meter* this, int cpu) {
+double Platform_setCPUValues(Meter* this, unsigned int cpu) {
const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl;
- int cpus = this->pl->cpuCount;
+ unsigned int cpus = this->pl->activeCPUs;
const CPUData* cpuData;
if (cpus == 1) {
@@ -205,26 +211,28 @@ double Platform_setCPUValues(Meter* this, int cpu) {
percent = CLAMP(percent, 0.0, 100.0);
- v[CPU_METER_FREQUENCY] = NAN;
- v[CPU_METER_TEMPERATURE] = NAN;
+ v[CPU_METER_FREQUENCY] = cpuData->frequency;
+ v[CPU_METER_TEMPERATURE] = cpuData->temperature;
return percent;
}
void Platform_setMemoryValues(Meter* this) {
- // TODO
const ProcessList* pl = this->pl;
this->total = pl->totalMem;
this->values[0] = pl->usedMem;
this->values[1] = pl->buffersMem;
- this->values[2] = pl->cachedMem;
+ // this->values[2] = "shared memory, like tmpfs and shm"
+ this->values[3] = pl->cachedMem;
+ // this->values[4] = "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;
}
void Platform_setZfsArcValues(Meter* this) {
@@ -240,7 +248,7 @@ void Platform_setZfsCompressedArcValues(Meter* this) {
}
char* Platform_getProcessEnv(pid_t pid) {
- int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ENV, pid };
+ const int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_ENV, pid };
size_t capacity = ARG_MAX;
char* env = xMalloc(capacity);
@@ -261,14 +269,14 @@ char* Platform_getProcessEnv(pid_t pid) {
}
char* Platform_getInodeFilename(pid_t pid, ino_t inode) {
- (void)pid;
- (void)inode;
- return NULL;
+ (void)pid;
+ (void)inode;
+ return NULL;
}
FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid) {
- (void)pid;
- return NULL;
+ (void)pid;
+ return NULL;
}
bool Platform_getDiskIO(DiskIOData* data) {
@@ -285,7 +293,7 @@ bool Platform_getDiskIO(DiskIOData* data) {
int count = current.dinfo->numdevs;
- unsigned long int bytesReadSum = 0, bytesWriteSum = 0, timeSpendSum = 0;
+ unsigned long long int bytesReadSum = 0, bytesWriteSum = 0, timeSpendSum = 0;
// get data
for (int i = 0; i < count; i++) {
@@ -311,24 +319,17 @@ bool Platform_getDiskIO(DiskIOData* data) {
return true;
}
-bool Platform_getNetworkIO(unsigned long int* bytesReceived,
- unsigned long int* packetsReceived,
- unsigned long int* bytesTransmitted,
- unsigned long int* packetsTransmitted) {
- int r;
-
+bool Platform_getNetworkIO(NetworkIOData* data) {
// get number of interfaces
int count;
size_t countLen = sizeof(count);
const int countMib[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT };
- r = sysctl(countMib, ARRAYSIZE(countMib), &count, &countLen, NULL, 0);
+ int r = sysctl(countMib, ARRAYSIZE(countMib), &count, &countLen, NULL, 0);
if (r < 0)
return false;
-
- unsigned long int bytesReceivedSum = 0, packetsReceivedSum = 0, bytesTransmittedSum = 0, packetsTransmittedSum = 0;
-
+ memset(data, 0, sizeof(NetworkIOData));
for (int i = 1; i <= count; i++) {
struct ifmibdata ifmd;
size_t ifmdLen = sizeof(ifmd);
@@ -342,16 +343,12 @@ bool Platform_getNetworkIO(unsigned long int* bytesReceived,
if (ifmd.ifmd_flags & IFF_LOOPBACK)
continue;
- bytesReceivedSum += ifmd.ifmd_data.ifi_ibytes;
- packetsReceivedSum += ifmd.ifmd_data.ifi_ipackets;
- bytesTransmittedSum += ifmd.ifmd_data.ifi_obytes;
- packetsTransmittedSum += ifmd.ifmd_data.ifi_opackets;
+ data->bytesReceived += ifmd.ifmd_data.ifi_ibytes;
+ data->packetsReceived += ifmd.ifmd_data.ifi_ipackets;
+ data->bytesTransmitted += ifmd.ifmd_data.ifi_obytes;
+ data->packetsTransmitted += ifmd.ifmd_data.ifi_opackets;
}
- *bytesReceived = bytesReceivedSum;
- *packetsReceived = packetsReceivedSum;
- *bytesTransmitted = bytesTransmittedSum;
- *packetsTransmitted = packetsTransmittedSum;
return true;
}
diff --git a/freebsd/Platform.h b/freebsd/Platform.h
index 36895b8..e7e274c 100644
--- a/freebsd/Platform.h
+++ b/freebsd/Platform.h
@@ -13,10 +13,15 @@ in the source distribution for its full text.
#include "Action.h"
#include "BatteryMeter.h"
#include "DiskIOMeter.h"
+#include "Hashtable.h"
#include "Meter.h"
+#include "NetworkIOMeter.h"
#include "Process.h"
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
+#include "generic/gettime.h"
+#include "generic/hostname.h"
+#include "generic/uname.h"
extern const ProcessField Platform_defaultFields[];
@@ -39,7 +44,7 @@ void Platform_getLoadAverage(double* one, double* five, double* fifteen);
int Platform_getMaxPid(void);
-double Platform_setCPUValues(Meter* this, int cpu);
+double Platform_setCPUValues(Meter* this, unsigned int cpu);
void Platform_setMemoryValues(Meter* this);
@@ -57,11 +62,50 @@ FileLocks_ProcessData* Platform_getProcessLocks(pid_t pid);
bool Platform_getDiskIO(DiskIOData* data);
-bool Platform_getNetworkIO(unsigned long int* bytesReceived,
- unsigned long int* packetsReceived,
- unsigned long int* bytesTransmitted,
- unsigned long int* packetsTransmitted);
+bool Platform_getNetworkIO(NetworkIOData* data);
void Platform_getBattery(double* percent, ACPresence* isOnAC);
+static inline void Platform_getHostname(char* buffer, size_t size) {
+ Generic_hostname(buffer, size);
+}
+
+static inline void Platform_getRelease(char** string) {
+ *string = Generic_uname();
+}
+
+#define PLATFORM_LONG_OPTIONS
+
+static inline void Platform_longOptionsUsage(ATTR_UNUSED const char* name) { }
+
+static inline bool Platform_getLongOption(ATTR_UNUSED int opt, ATTR_UNUSED int argc, ATTR_UNUSED char** argv) {
+ return false;
+}
+
+static inline void Platform_gettime_realtime(struct timeval* tv, uint64_t* msec) {
+ Generic_gettime_realtime(tv, msec);
+}
+
+static inline void Platform_gettime_monotonic(uint64_t* msec) {
+ Generic_gettime_monotonic(msec);
+}
+
+static inline Hashtable* Platform_dynamicMeters(void) { return NULL; }
+
+static inline void Platform_dynamicMetersDone(ATTR_UNUSED Hashtable* table) { }
+
+static inline void Platform_dynamicMeterInit(ATTR_UNUSED Meter* meter) { }
+
+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 const char* Platform_dynamicColumnInit(ATTR_UNUSED unsigned int key) { return NULL; }
+
+static inline void Platform_dynamicColumnsDone(ATTR_UNUSED Hashtable* table) { }
+
+static inline bool Platform_dynamicColumnWriteField(ATTR_UNUSED const Process* proc, ATTR_UNUSED RichString* str, ATTR_UNUSED unsigned int key) { return false; }
+
#endif
diff --git a/freebsd/ProcessField.h b/freebsd/ProcessField.h
index cc89282..6fba6bc 100644
--- a/freebsd/ProcessField.h
+++ b/freebsd/ProcessField.h
@@ -11,6 +11,8 @@ in the source distribution for its full text.
#define PLATFORM_PROCESS_FIELDS \
JID = 100, \
JAIL = 101, \
+ \
+ DUMMY_BUMP_FIELD = CWD, \
// End of list

© 2014-2024 Faster IT GmbH | imprint | privacy policy