aboutsummaryrefslogtreecommitdiffstats
path: root/linux
diff options
context:
space:
mode:
authorDaniel Lange <DLange@git.local>2021-01-11 20:43:27 +0100
committerDaniel Lange <DLange@git.local>2021-01-11 20:43:27 +0100
commitc55320e9e2a8916e911bcd39ab37b79e3a7d03b2 (patch)
treed6be9a09fdf7d6dc155de3429a70697ee2bb43b0 /linux
parent65357c8c46154de4e4eca14075bfe5523bb5fc14 (diff)
downloaddebian_htop-c55320e9e2a8916e911bcd39ab37b79e3a7d03b2.tar.gz
debian_htop-c55320e9e2a8916e911bcd39ab37b79e3a7d03b2.tar.bz2
debian_htop-c55320e9e2a8916e911bcd39ab37b79e3a7d03b2.zip
New upstream version 3.0.5upstream/3.0.5
Diffstat (limited to 'linux')
-rw-r--r--linux/IOPriorityPanel.c2
-rw-r--r--linux/LibSensors.c81
-rw-r--r--linux/LibSensors.h2
-rw-r--r--linux/LinuxProcess.c177
-rw-r--r--linux/LinuxProcess.h97
-rw-r--r--linux/LinuxProcessList.c164
-rw-r--r--linux/Platform.c4
-rw-r--r--linux/Platform.h4
-rw-r--r--linux/PressureStallMeter.c18
-rw-r--r--linux/ProcessField.h53
-rw-r--r--linux/SELinuxMeter.c2
-rw-r--r--linux/SystemdMeter.c20
-rw-r--r--linux/ZramMeter.c14
13 files changed, 331 insertions, 307 deletions
diff --git a/linux/IOPriorityPanel.c b/linux/IOPriorityPanel.c
index c5a4a4c..25d2199 100644
--- a/linux/IOPriorityPanel.c
+++ b/linux/IOPriorityPanel.c
@@ -17,7 +17,7 @@ in the source distribution for its full text.
Panel* IOPriorityPanel_new(IOPriority currPrio) {
- Panel* this = Panel_new(1, 1, 1, 1, true, Class(ListItem), FunctionBar_newEnterEsc("Set ", "Cancel "));
+ Panel* this = Panel_new(1, 1, 1, 1, Class(ListItem), true, FunctionBar_newEnterEsc("Set ", "Cancel "));
Panel_setHeader(this, "IO Priority:");
Panel_add(this, (Object*) ListItem_new("None (based on nice)", IOPriority_None));
diff --git a/linux/LibSensors.c b/linux/LibSensors.c
index a30e21b..158829a 100644
--- a/linux/LibSensors.c
+++ b/linux/LibSensors.c
@@ -4,6 +4,7 @@
#include <dlfcn.h>
#include <errno.h>
+#include <math.h>
#include <sensors/sensors.h>
#include "XUtils.h"
@@ -16,13 +17,20 @@ static int (*sym_sensors_snprintf_chip_name)(char*, size_t, const sensors_chip_n
static const sensors_feature* (*sym_sensors_get_features)(const sensors_chip_name*, int*);
static const sensors_subfeature* (*sym_sensors_get_subfeature)(const sensors_chip_name*, const sensors_feature*, sensors_subfeature_type);
static int (*sym_sensors_get_value)(const sensors_chip_name*, int, double*);
+static char* (*sym_sensors_get_label)(const sensors_chip_name*, const sensors_feature*);
static void* dlopenHandle = NULL;
int LibSensors_init(FILE* input) {
if (!dlopenHandle) {
+ /* Find the unversioned libsensors.so (symlink) and prefer that, but Debian has .so.5 and Fedora .so.4 without
+ matching symlinks (unless people install the -dev packages) */
dlopenHandle = dlopen("libsensors.so", RTLD_LAZY);
if (!dlopenHandle)
+ dlopenHandle = dlopen("libsensors.so.5", RTLD_LAZY);
+ if (!dlopenHandle)
+ dlopenHandle = dlopen("libsensors.so.4", RTLD_LAZY);
+ if (!dlopenHandle)
goto dlfailure;
/* Clear any errors */
@@ -41,6 +49,7 @@ int LibSensors_init(FILE* input) {
resolve(sensors_get_features);
resolve(sensors_get_subfeature);
resolve(sensors_get_value);
+ resolve(sensors_get_label);
#undef resolve
}
@@ -64,17 +73,23 @@ void LibSensors_cleanup(void) {
}
}
-int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) {
+void LibSensors_getCPUTemperatures(CPUData* cpus, unsigned int cpuCount) {
+ for (unsigned int i = 0; i <= cpuCount; i++)
+ cpus[i].temperature = NAN;
+
if (!dlopenHandle)
- return -ENOTSUP;
+ return;
- int tempCount = 0;
+ unsigned int coreTempCount = 0;
int n = 0;
for (const sensors_chip_name *chip = sym_sensors_get_detected_chips(NULL, &n); chip; chip = sym_sensors_get_detected_chips(NULL, &n)) {
char buffer[32];
sym_sensors_snprintf_chip_name(buffer, sizeof(buffer), chip);
- if (!String_startsWith(buffer, "coretemp") && !String_startsWith(buffer, "cpu_thermal"))
+ if (!String_startsWith(buffer, "coretemp") &&
+ !String_startsWith(buffer, "cpu_thermal") &&
+ !String_startsWith(buffer, "k10temp") &&
+ !String_startsWith(buffer, "zenpower"))
continue;
int m = 0;
@@ -82,7 +97,27 @@ int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) {
if (feature->type != SENSORS_FEATURE_TEMP)
continue;
- if (feature->number > cpuCount)
+ char* label = sym_sensors_get_label(chip, feature);
+ if (!label)
+ continue;
+
+ unsigned int tempId;
+ if (String_startsWith(label, "Package ")) {
+ tempId = 0;
+ } else if (String_startsWith(label, "temp")) {
+ /* Raspberry Pi has only temp1 */
+ tempId = 0;
+ } else if (String_startsWith(label, "Tdie")) {
+ tempId = 0;
+ } else if (String_startsWith(label, "Core ")) {
+ tempId = 1 + atoi(label + strlen("Core "));
+ } else {
+ tempId = UINT_MAX;
+ }
+
+ free(label);
+
+ if (tempId > cpuCount)
continue;
const sensors_subfeature *sub_feature = sym_sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
@@ -92,13 +127,43 @@ int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) {
if (r != 0)
continue;
- cpus[feature->number].temperature = temp;
- tempCount++;
+ cpus[tempId].temperature = temp;
+ if (tempId > 0)
+ coreTempCount++;
}
}
}
- return tempCount;
+ const double packageTemp = cpus[0].temperature;
+
+ /* Only package temperature - copy to all cpus */
+ if (coreTempCount == 0 && !isnan(packageTemp)) {
+ for (unsigned int i = 1; i <= cpuCount; i++)
+ cpus[i].temperature = packageTemp;
+
+ return;
+ }
+
+ /* No package temperature - set to max core temperature */
+ if (isnan(packageTemp) && coreTempCount != 0) {
+ double maxTemp = NAN;
+ for (unsigned int i = 1; i <= cpuCount; i++) {
+ const double coreTemp = cpus[i].temperature;
+ if (isnan(coreTemp))
+ continue;
+
+ maxTemp = MAXIMUM(maxTemp, coreTemp);
+ }
+
+ cpus[0].temperature = maxTemp;
+ }
+
+ /* Half the temperatures, probably HT/SMT - copy to second half */
+ const unsigned int delta = cpuCount / 2;
+ if (coreTempCount == delta) {
+ for (unsigned int i = 1; i <= delta; i++)
+ cpus[i + delta].temperature = cpus[i].temperature;
+ }
}
#endif /* HAVE_SENSORS_SENSORS_H */
diff --git a/linux/LibSensors.h b/linux/LibSensors.h
index ed9be7b..cceeedb 100644
--- a/linux/LibSensors.h
+++ b/linux/LibSensors.h
@@ -11,6 +11,6 @@
int LibSensors_init(FILE* input);
void LibSensors_cleanup(void);
-int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount);
+void LibSensors_getCPUTemperatures(CPUData* cpus, unsigned int cpuCount);
#endif /* HEADER_LibSensors */
diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c
index 8298000..ce6d34d 100644
--- a/linux/LinuxProcess.c
+++ b/linux/LinuxProcess.c
@@ -24,22 +24,22 @@ in the source distribution for its full text.
/* semi-global */
-long long btime;
+int pageSize;
+int pageSizeKB;
/* Used to identify kernel threads in Comm and Exe columns */
static const char *const kthreadID = "KTHREAD";
-ProcessFieldData Process_fields[] = {
+const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = {
[0] = { .name = "", .title = NULL, .description = NULL, .flags = 0, },
- [PID] = { .name = "PID", .title = " PID ", .description = "Process/thread ID", .flags = 0, },
+ [PID] = { .name = "PID", .title = "PID", .description = "Process/thread ID", .flags = 0, .pidColumn = true, },
[COMM] = { .name = "Command", .title = "Command ", .description = "Command line", .flags = 0, },
[STATE] = { .name = "STATE", .title = "S ", .description = "Process state (S sleeping, R running, D disk, Z zombie, T traced, W paging, I idle)", .flags = 0, },
- [PPID] = { .name = "PPID", .title = " PPID ", .description = "Parent process ID", .flags = 0, },
- [PGRP] = { .name = "PGRP", .title = " PGRP ", .description = "Process group ID", .flags = 0, },
- [SESSION] = { .name = "SESSION", .title = " SID ", .description = "Process's session ID", .flags = 0, },
+ [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 = 0, },
- [TPGID] = { .name = "TPGID", .title = " TPGID ", .description = "Process ID of the fg process group of the controlling terminal", .flags = 0, },
- [FLAGS] = { .name = "FLAGS", .title = NULL, .description = NULL, .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, },
[CMINFLT] = { .name = "CMINFLT", .title = " CMINFLT ", .description = "Children processes' minor faults", .flags = 0, },
[MAJFLT] = { .name = "MAJFLT", .title = " MAJFLT ", .description = "Number of major faults which have required loading a memory page from disk", .flags = 0, },
@@ -50,24 +50,7 @@ ProcessFieldData Process_fields[] = {
[CSTIME] = { .name = "CSTIME", .title = " CSTIME+ ", .description = "Children processes' system CPU time", .flags = 0, },
[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, },
- [ITREALVALUE] = { .name = "ITREALVALUE", .title = NULL, .description = NULL, .flags = 0, },
[STARTTIME] = { .name = "STARTTIME", .title = "START ", .description = "Time the process was started", .flags = 0, },
- [VSIZE] = { .name = "VSIZE", .title = NULL, .description = NULL, .flags = 0, },
- [RSS] = { .name = "RSS", .title = NULL, .description = NULL, .flags = 0, },
- [RLIM] = { .name = "RLIM", .title = NULL, .description = NULL, .flags = 0, },
- [STARTCODE] = { .name = "STARTCODE", .title = NULL, .description = NULL, .flags = 0, },
- [ENDCODE] = { .name = "ENDCODE", .title = NULL, .description = NULL, .flags = 0, },
- [STARTSTACK] = { .name = "STARTSTACK", .title = NULL, .description = NULL, .flags = 0, },
- [KSTKESP] = { .name = "KSTKESP", .title = NULL, .description = NULL, .flags = 0, },
- [KSTKEIP] = { .name = "KSTKEIP", .title = NULL, .description = NULL, .flags = 0, },
- [SIGNAL] = { .name = "SIGNAL", .title = NULL, .description = NULL, .flags = 0, },
- [BLOCKED] = { .name = "BLOCKED", .title = NULL, .description = NULL, .flags = 0, },
- [SSIGIGNORE] = { .name = "SIGIGNORE", .title = NULL, .description = NULL, .flags = 0, },
- [SIGCATCH] = { .name = "SIGCATCH", .title = NULL, .description = NULL, .flags = 0, },
- [WCHAN] = { .name = "WCHAN", .title = NULL, .description = NULL, .flags = 0, },
- [NSWAP] = { .name = "NSWAP", .title = NULL, .description = NULL, .flags = 0, },
- [CNSWAP] = { .name = "CNSWAP", .title = NULL, .description = NULL, .flags = 0, },
- [EXIT_SIGNAL] = { .name = "EXIT_SIGNAL", .title = NULL, .description = NULL, .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, },
@@ -83,10 +66,10 @@ ProcessFieldData Process_fields[] = {
[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, },
- [TGID] = { .name = "TGID", .title = " TGID ", .description = "Thread group ID (i.e. process ID)", .flags = 0, },
+ [TGID] = { .name = "TGID", .title = "TGID", .description = "Thread group ID (i.e. process ID)", .flags = 0, .pidColumn = true, },
#ifdef HAVE_OPENVZ
[CTID] = { .name = "CTID", .title = " CTID ", .description = "OpenVZ container ID (a.k.a. virtual environment ID)", .flags = PROCESS_FLAG_LINUX_OPENVZ, },
- [VPID] = { .name = "VPID", .title = " VPID ", .description = "OpenVZ process ID", .flags = PROCESS_FLAG_LINUX_OPENVZ, },
+ [VPID] = { .name = "VPID", .title = "VPID", .description = "OpenVZ process ID", .flags = PROCESS_FLAG_LINUX_OPENVZ, .pidColumn = true, },
#endif
#ifdef HAVE_VSERVER
[VXID] = { .name = "VXID", .title = " VXID ", .description = "VServer process ID", .flags = PROCESS_FLAG_LINUX_VSERVER, },
@@ -105,9 +88,9 @@ ProcessFieldData Process_fields[] = {
[OOM] = { .name = "OOM", .title = " OOM ", .description = "OOM (Out-of-Memory) killer score", .flags = PROCESS_FLAG_LINUX_OOM, },
[IO_PRIORITY] = { .name = "IO_PRIORITY", .title = "IO ", .description = "I/O priority", .flags = PROCESS_FLAG_LINUX_IOPRIO, },
#ifdef HAVE_DELAYACCT
- [PERCENT_CPU_DELAY] = { .name = "PERCENT_CPU_DELAY", .title = "CPUD% ", .description = "CPU delay %", .flags = 0, },
- [PERCENT_IO_DELAY] = { .name = "PERCENT_IO_DELAY", .title = "IOD% ", .description = "Block I/O delay %", .flags = 0, },
- [PERCENT_SWAP_DELAY] = { .name = "PERCENT_SWAP_DELAY", .title = "SWAPD% ", .description = "Swapin delay %", .flags = 0, },
+ [PERCENT_CPU_DELAY] = { .name = "PERCENT_CPU_DELAY", .title = "CPUD% ", .description = "CPU delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, },
+ [PERCENT_IO_DELAY] = { .name = "PERCENT_IO_DELAY", .title = "IOD% ", .description = "Block I/O delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, },
+ [PERCENT_SWAP_DELAY] = { .name = "PERCENT_SWAP_DELAY", .title = "SWAPD% ", .description = "Swapin delay %", .flags = PROCESS_FLAG_LINUX_DELAYACCT, },
#endif
[M_PSS] = { .name = "M_PSS", .title = " PSS ", .description = "proportional set size, same as M_RESIDENT but each page is divided by the number of processes sharing it.", .flags = PROCESS_FLAG_LINUX_SMAPS, },
[M_SWAP] = { .name = "M_SWAP", .title = " SWAP ", .description = "Size of the process's swapped pages", .flags = PROCESS_FLAG_LINUX_SMAPS, },
@@ -117,20 +100,6 @@ ProcessFieldData Process_fields[] = {
[PROC_COMM] = { .name = "COMM", .title = "COMM ", .description = "comm string of the process from /proc/[pid]/comm", .flags = 0, },
[PROC_EXE] = { .name = "EXE", .title = "EXE ", .description = "Basename of exe of the process from /proc/[pid]/exe", .flags = 0, },
[CWD] = { .name ="CWD", .title = "CWD ", .description = "The current working directory of the process", .flags = PROCESS_FLAG_LINUX_CWD, },
- [LAST_PROCESSFIELD] = { .name = "*** report bug! ***", .title = NULL, .description = NULL, .flags = 0, },
-};
-
-ProcessPidColumn Process_pidColumns[] = {
- { .id = PID, .label = "PID" },
- { .id = PPID, .label = "PPID" },
- #ifdef HAVE_OPENVZ
- { .id = VPID, .label = "VPID" },
- #endif
- { .id = TPGID, .label = "TPGID" },
- { .id = TGID, .label = "TGID" },
- { .id = PGRP, .label = "PGRP" },
- { .id = SESSION, .label = "SID" },
- { .id = 0, .label = NULL },
};
/* This function returns the string displayed in Command column, so that sorting
@@ -183,6 +152,11 @@ static int LinuxProcess_effectiveIOPriority(const LinuxProcess* this) {
return this->ioPriority;
}
+#ifdef __ANDROID__
+#define SYS_ioprio_get __NR_ioprio_get
+#define SYS_ioprio_set __NR_ioprio_set
+#endif
+
IOPriority LinuxProcess_updateIOPriority(LinuxProcess* this) {
IOPriority ioprio = 0;
// Other OSes masquerading as Linux (NetBSD?) don't have this syscall
@@ -224,12 +198,11 @@ static bool findCommInCmdline(const char *comm, const char *cmdline, int cmdline
/* Try to find procComm in tokenized cmdline - this might in rare cases
* mis-identify a string or fail, if comm or cmdline had been unsuitably
* modified by the process */
- const char *token;
const char *tokenBase;
size_t tokenLen;
const size_t commLen = strlen(comm);
- for (token = cmdline + cmdlineBasenameOffset; *token; ) {
+ for (const char *token = cmdline + cmdlineBasenameOffset; *token; ) {
for (tokenBase = token; *token && *token != '\n'; ++token) {
if (*token == '/') {
tokenBase = token + 1;
@@ -394,6 +367,16 @@ void LinuxProcess_makeCommandStr(Process* this) {
char *str = strStart;
int cmdlineBasenameOffset = lp->procCmdlineBasenameOffset;
+ int cmdlineBasenameEnd = lp->procCmdlineBasenameEnd;
+
+ if (!cmdline) {
+ cmdlineBasenameOffset = 0;
+ cmdlineBasenameEnd = 0;
+ cmdline = "(zombie)";
+ }
+
+ assert(cmdlineBasenameOffset >= 0);
+ assert(cmdlineBasenameOffset <= (int)strlen(cmdline));
if (!showMergedCommand || !procExe || !procComm) { /* fall back to cmdline */
if (showMergedCommand && !procExe && procComm && strlen(procComm)) { /* Prefix column with comm */
@@ -411,11 +394,11 @@ void LinuxProcess_makeCommandStr(Process* this) {
if (showProgramPath) {
(void) stpcpyWithNewlineConversion(str, cmdline);
mc->baseStart = cmdlineBasenameOffset;
- mc->baseEnd = lp->procCmdlineBasenameEnd;
+ mc->baseEnd = cmdlineBasenameEnd;
} else {
(void) stpcpyWithNewlineConversion(str, cmdline + cmdlineBasenameOffset);
mc->baseStart = 0;
- mc->baseEnd = lp->procCmdlineBasenameEnd - cmdlineBasenameOffset;
+ mc->baseEnd = cmdlineBasenameEnd - cmdlineBasenameOffset;
}
if (mc->sep1) {
@@ -430,6 +413,9 @@ void LinuxProcess_makeCommandStr(Process* this) {
int exeBasenameOffset = lp->procExeBasenameOffset;
int exeBasenameLen = exeLen - exeBasenameOffset;
+ assert(exeBasenameOffset >= 0);
+ assert(exeBasenameOffset <= (int)strlen(procExe));
+
/* Start with copying exe */
if (showProgramPath) {
str = stpcpy(str, procExe);
@@ -536,36 +522,36 @@ static void LinuxProcess_writeCommand(const Process* this, int attr, int baseAtt
if(lp->procExeDeleted)
baseAttr = CRT_colors[FAILED_READ];
- RichString_append(str, attr, lp->mergedCommand.str);
+ RichString_appendWide(str, attr, lp->mergedCommand.str);
if (lp->mergedCommand.commEnd) {
if (!lp->mergedCommand.separateComm && commStart == baseStart && highlightBaseName) {
/* If it was matched with procExe's basename, make it bold if needed */
if (commEnd > baseEnd) {
- RichString_setAttrn(str, A_BOLD | baseAttr, baseStart, baseEnd - 1);
- RichString_setAttrn(str, A_BOLD | commAttr, baseEnd, commEnd - 1);
+ RichString_setAttrn(str, A_BOLD | baseAttr, baseStart, baseEnd - baseStart);
+ RichString_setAttrn(str, A_BOLD | commAttr, baseEnd, commEnd - baseEnd);
} else if (commEnd < baseEnd) {
- RichString_setAttrn(str, A_BOLD | commAttr, commStart, commEnd - 1);
- RichString_setAttrn(str, A_BOLD | baseAttr, commEnd, baseEnd - 1);
+ RichString_setAttrn(str, A_BOLD | commAttr, commStart, commEnd - commStart);
+ RichString_setAttrn(str, A_BOLD | baseAttr, commEnd, baseEnd - commEnd);
} else {
// Actually should be highlighted commAttr, but marked baseAttr to reduce visual noise
- RichString_setAttrn(str, A_BOLD | baseAttr, commStart, commEnd - 1);
+ RichString_setAttrn(str, A_BOLD | baseAttr, commStart, commEnd - commStart);
}
baseStart = baseEnd;
} else {
- RichString_setAttrn(str, commAttr, commStart, commEnd - 1);
+ RichString_setAttrn(str, commAttr, commStart, commEnd - commStart);
}
}
if (baseStart < baseEnd && highlightBaseName) {
- RichString_setAttrn(str, baseAttr, baseStart, baseEnd - 1);
+ RichString_setAttrn(str, baseAttr, baseStart, baseEnd - baseStart);
}
if (mc->sep1)
- RichString_setAttrn(str, CRT_colors[FAILED_READ], strStart + mc->sep1, strStart + mc->sep1);
+ RichString_setAttrn(str, CRT_colors[FAILED_READ], strStart + mc->sep1, 1);
if (mc->sep2)
- RichString_setAttrn(str, CRT_colors[FAILED_READ], strStart + mc->sep2, strStart + mc->sep2);
+ RichString_setAttrn(str, CRT_colors[FAILED_READ], strStart + mc->sep2, 1);
}
static void LinuxProcess_writeCommandField(const Process *this, RichString *str, char *buffer, int n, int attr) {
@@ -605,10 +591,11 @@ static void LinuxProcess_writeCommandField(const Process *this, RichString *str,
buf = stpcpy(buf, " ");
}
}
+
n -= (buf - buffer);
- const char* draw = CRT_treeStr[lastItem ? (this->settings->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
+ const char* draw = CRT_treeStr[lastItem ? TREE_STR_BEND : TREE_STR_RTEE];
xSnprintf(buf, n, "%s%s ", draw, this->showChildren ? CRT_treeStr[TREE_STR_SHUT] : CRT_treeStr[TREE_STR_OPEN] );
- RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
+ RichString_appendWide(str, CRT_colors[PROCESS_TREE], buffer);
LinuxProcess_writeCommand(this, attr, baseattr, str);
}
}
@@ -619,7 +606,7 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
char buffer[256]; buffer[255] = '\0';
int attr = CRT_colors[DEFAULT_COLOR];
size_t n = sizeof(buffer) - 1;
- switch ((int)field) {
+ switch (field) {
case TTY_NR: {
if (lp->ttyDevice) {
xSnprintf(buffer, n, "%-9s", lp->ttyDevice + 5 /* skip "/dev/" */);
@@ -631,19 +618,19 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
}
case CMINFLT: Process_colorNumber(str, lp->cminflt, coloring); return;
case CMAJFLT: Process_colorNumber(str, lp->cmajflt, coloring); return;
- case M_DRS: Process_humanNumber(str, lp->m_drs * CRT_pageSizeKB, coloring); return;
- case M_DT: Process_humanNumber(str, lp->m_dt * CRT_pageSizeKB, coloring); return;
+ case M_DRS: Process_humanNumber(str, lp->m_drs * pageSizeKB, coloring); return;
+ case M_DT: Process_humanNumber(str, lp->m_dt * pageSizeKB, coloring); return;
case M_LRS:
if (lp->m_lrs) {
- Process_humanNumber(str, lp->m_lrs * CRT_pageSizeKB, coloring);
+ Process_humanNumber(str, lp->m_lrs * pageSizeKB, coloring);
return;
}
attr = CRT_colors[PROCESS_SHADOW];
xSnprintf(buffer, n, " N/A ");
break;
- case M_TRS: Process_humanNumber(str, lp->m_trs * CRT_pageSizeKB, coloring); return;
- case M_SHARE: Process_humanNumber(str, lp->m_share * CRT_pageSizeKB, coloring); return;
+ case M_TRS: Process_humanNumber(str, lp->m_trs * pageSizeKB, coloring); return;
+ case M_SHARE: Process_humanNumber(str, lp->m_share * pageSizeKB, coloring); return;
case M_PSS: Process_humanNumber(str, lp->m_pss, coloring); return;
case M_SWAP: Process_humanNumber(str, lp->m_swap, coloring); return;
case M_PSSWP: Process_humanNumber(str, lp->m_psswp, coloring); return;
@@ -674,7 +661,7 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
}
#ifdef HAVE_OPENVZ
case CTID: xSnprintf(buffer, n, "%-8s ", lp->ctid ? lp->ctid : ""); break;
- case VPID: xSnprintf(buffer, n, Process_pidFormat, lp->vpid); break;
+ case VPID: xSnprintf(buffer, n, "%*d ", Process_pidDigits, lp->vpid); break;
#endif
#ifdef HAVE_VSERVER
case VXID: xSnprintf(buffer, n, "%5u ", lp->vxid); break;
@@ -720,59 +707,58 @@ static void LinuxProcess_writeField(const Process* this, RichString* str, Proces
return;
}
case PROC_COMM: {
+ const char* procComm;
if (lp->procComm) {
attr = CRT_colors[Process_isUserlandThread(this) ? PROCESS_THREAD_COMM : PROCESS_COMM];
- /* 15 being (TASK_COMM_LEN - 1) */
- xSnprintf(buffer, n, "%-15.15s ", lp->procComm);
+ procComm = lp->procComm;
} else {
attr = CRT_colors[PROCESS_SHADOW];
- xSnprintf(buffer, n, "%-15.15s ", Process_isKernelThread(lp) ? kthreadID : "N/A");
+ procComm = Process_isKernelThread(lp) ? kthreadID : "N/A";
}
- break;
+ /* 15 being (TASK_COMM_LEN - 1) */
+ Process_printLeftAlignedField(str, attr, procComm, 15);
+ return;
}
case PROC_EXE: {
+ const char* procExe;
if (lp->procExe) {
attr = CRT_colors[Process_isUserlandThread(this) ? PROCESS_THREAD_BASENAME : PROCESS_BASENAME];
if (lp->procExeDeleted)
attr = CRT_colors[FAILED_READ];
- xSnprintf(buffer, n, "%-15.15s ", lp->procExe + lp->procExeBasenameOffset);
+ procExe = lp->procExe + lp->procExeBasenameOffset;
} else {
attr = CRT_colors[PROCESS_SHADOW];
- xSnprintf(buffer, n, "%-15.15s ", Process_isKernelThread(lp) ? kthreadID : "N/A");
+ procExe = Process_isKernelThread(lp) ? kthreadID : "N/A";
}
- break;
+ Process_printLeftAlignedField(str, attr, procExe, 15);
+ return;
}
- case CWD:
+ case CWD: {
+ const char* cwd;
if (!lp->cwd) {
- xSnprintf(buffer, n, "%-25s ", "N/A");
attr = CRT_colors[PROCESS_SHADOW];
+ cwd = "N/A";
} else if (String_startsWith(lp->cwd, "/proc/") && strstr(lp->cwd, " (deleted)") != NULL) {
- xSnprintf(buffer, n, "%-25s ", "main thread terminated");
attr = CRT_colors[PROCESS_SHADOW];
+ cwd = "main thread terminated";
} else {
- xSnprintf(buffer, n, "%-25.25s ", lp->cwd);
+ cwd = lp->cwd;
}
- break;
+ Process_printLeftAlignedField(str, attr, cwd, 25);
+ return;
+ }
default:
Process_writeField(this, str, field);
return;
}
- RichString_append(str, attr, buffer);
+ RichString_appendWide(str, attr, buffer);
}
-static long LinuxProcess_compare(const void* v1, const void* v2) {
- const LinuxProcess *p1, *p2;
- const Settings *settings = ((const Process*)v1)->settings;
-
- if (settings->direction == 1) {
- p1 = (const LinuxProcess*)v1;
- p2 = (const LinuxProcess*)v2;
- } else {
- p2 = (const LinuxProcess*)v1;
- p1 = (const LinuxProcess*)v2;
- }
+static int LinuxProcess_compareByKey(const Process* v1, const Process* v2, ProcessField key) {
+ const LinuxProcess* p1 = (const LinuxProcess*)v1;
+ const LinuxProcess* p2 = (const LinuxProcess*)v2;
- switch ((int)settings->sortKey) {
+ switch (key) {
case M_DRS:
return SPACESHIP_NUMBER(p2->m_drs, p1->m_drs);
case M_DT:
@@ -858,7 +844,7 @@ static long LinuxProcess_compare(const void* v1, const void* v2) {
case CWD:
return SPACESHIP_NULLSTR(p1->cwd, p2->cwd);
default:
- return Process_compare(v1, v2);
+ return Process_compareByKey_Base(v1, v2, key);
}
}
@@ -871,8 +857,9 @@ const ProcessClass LinuxProcess_class = {
.extends = Class(Process),
.display = Process_display,
.delete = Process_delete,
- .compare = LinuxProcess_compare
+ .compare = Process_compare
},
.writeField = LinuxProcess_writeField,
- .getCommandStr = LinuxProcess_getCommandStr
+ .getCommandStr = LinuxProcess_getCommandStr,
+ .compareByKey = LinuxProcess_compareByKey
};
diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h
index ad396fb..2e9a9d1 100644
--- a/linux/LinuxProcess.h
+++ b/linux/LinuxProcess.h
@@ -18,85 +18,18 @@ in the source distribution for its full text.
#include "Settings.h"
-#define PROCESS_FLAG_LINUX_IOPRIO 0x00000100
-#define PROCESS_FLAG_LINUX_OPENVZ 0x00000200
-#define PROCESS_FLAG_LINUX_VSERVER 0x00000400
-#define PROCESS_FLAG_LINUX_CGROUP 0x00000800
-#define PROCESS_FLAG_LINUX_OOM 0x00001000
-#define PROCESS_FLAG_LINUX_SMAPS 0x00002000
-#define PROCESS_FLAG_LINUX_CTXT 0x00004000
-#define PROCESS_FLAG_LINUX_SECATTR 0x00008000
-#define PROCESS_FLAG_LINUX_LRS_FIX 0x00010000
-#define PROCESS_FLAG_LINUX_CWD 0x00020000
-
-typedef enum UnsupportedProcessFields {
- FLAGS = 9,
- ITREALVALUE = 20,
- VSIZE = 22,
- RSS = 23,
- RLIM = 24,
- STARTCODE = 25,
- ENDCODE = 26,
- STARTSTACK = 27,
- KSTKESP = 28,
- KSTKEIP = 29,
- SIGNAL = 30,
- BLOCKED = 31,
- SSIGIGNORE = 32,
- SIGCATCH = 33,
- WCHAN = 34,
- NSWAP = 35,
- CNSWAP = 36,
- EXIT_SIGNAL = 37,
-} UnsupportedProcessField;
-
-typedef enum LinuxProcessFields {
- CMINFLT = 11,
- CMAJFLT = 13,
- UTIME = 14,
- STIME = 15,
- CUTIME = 16,
- CSTIME = 17,
- M_SHARE = 41,
- M_TRS = 42,
- M_DRS = 43,
- M_LRS = 44,
- M_DT = 45,
- #ifdef HAVE_OPENVZ
- CTID = 100,
- VPID = 101,
- #endif
- #ifdef HAVE_VSERVER
- VXID = 102,
- #endif
- RCHAR = 103,
- WCHAR = 104,
- SYSCR = 105,
- SYSCW = 106,
- RBYTES = 107,
- WBYTES = 108,
- CNCLWB = 109,
- IO_READ_RATE = 110,
- IO_WRITE_RATE = 111,
- IO_RATE = 112,
- CGROUP = 113,
- OOM = 114,
- IO_PRIORITY = 115,
- #ifdef HAVE_DELAYACCT
- PERCENT_CPU_DELAY = 116,
- PERCENT_IO_DELAY = 117,
- PERCENT_SWAP_DELAY = 118,
- #endif
- M_PSS = 119,
- M_SWAP = 120,
- M_PSSWP = 121,
- CTXT = 122,
- SECATTR = 123,
- PROC_COMM = 124,
- PROC_EXE = 125,
- CWD = 126,
- LAST_PROCESSFIELD = 127,
-} LinuxProcessField;
+#define PROCESS_FLAG_LINUX_IOPRIO 0x00000100
+#define PROCESS_FLAG_LINUX_OPENVZ 0x00000200
+#define PROCESS_FLAG_LINUX_VSERVER 0x00000400
+#define PROCESS_FLAG_LINUX_CGROUP 0x00000800
+#define PROCESS_FLAG_LINUX_OOM 0x00001000
+#define PROCESS_FLAG_LINUX_SMAPS 0x00002000
+#define PROCESS_FLAG_LINUX_CTXT 0x00004000
+#define PROCESS_FLAG_LINUX_SECATTR 0x00008000
+#define PROCESS_FLAG_LINUX_LRS_FIX 0x00010000
+#define PROCESS_FLAG_LINUX_CWD 0x00020000
+#define PROCESS_FLAG_LINUX_DELAYACCT 0x00040000
+
/* LinuxProcessMergedCommand is populated by LinuxProcess_makeCommandStr: It
* contains the merged Command string, and the information needed by
@@ -191,11 +124,11 @@ static inline bool Process_isUserlandThread(const Process* this) {
return this->pid != this->tgid;
}
-extern long long btime;
+extern int pageSize;
-extern ProcessFieldData Process_fields[];
+extern int pageSizeKB;
-extern ProcessPidColumn Process_pidColumns[];
+extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD];
extern const ProcessClass LinuxProcess_class;
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index b9ba247..434d070 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -57,6 +57,16 @@ in the source distribution for its full text.
#endif
+// CentOS 6's kernel doesn't provide a definition of O_PATH
+// based on definition taken from uapi/asm-generic/fcnth.h in Linux kernel tree
+#ifndef O_PATH
+# define O_PATH 010000000
+#endif
+
+static long long btime;
+
+static long jiffy;
+
static FILE* fopenat(openat_arg_t openatArg, const char* pathname, const char* mode) {
assert(String_eq(mode, "r")); /* only currently supported mode */
@@ -92,7 +102,7 @@ static void LinuxProcessList_initTtyDrivers(LinuxProcessList* this) {
int numDrivers = 0;
int allocd = 10;
- ttyDrivers = xMalloc(sizeof(TtyDriver) * allocd);
+ ttyDrivers = xMallocArray(allocd, sizeof(TtyDriver));
char* at = buf;
while (*at != '\0') {
at = strchr(at, ' '); // skip first token
@@ -126,7 +136,7 @@ static void LinuxProcessList_initTtyDrivers(LinuxProcessList* this) {
numDrivers++;
if (numDrivers == allocd) {
allocd += 10;
- ttyDrivers = xRealloc(ttyDrivers, sizeof(TtyDriver) * allocd);
+ ttyDrivers = xReallocArray(ttyDrivers, allocd, sizeof(TtyDriver));
}
}
numDrivers++;
@@ -198,39 +208,39 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
ProcessList_init(pl, Class(LinuxProcess), usersTable, pidMatchList, userId);
LinuxProcessList_initTtyDrivers(this);
- #ifdef HAVE_DELAYACCT
- LinuxProcessList_initNetlinkSocket(this);
- #endif
+ // Initialize page size
+ pageSize = sysconf(_SC_PAGESIZE);
+ if (pageSize == -1)
+ CRT_fatalError("Cannot get pagesize by sysconf(_SC_PAGESIZE)");
+ pageSizeKB = pageSize / ONE_K;
- // Check for /proc/*/smaps_rollup availability (improves smaps parsing speed, Linux 4.14+)
- FILE* file = fopen(PROCDIR "/self/smaps_rollup", "r");
- if (file != NULL) {
- this->haveSmapsRollup = true;
- fclose(file);
- } else {
- this->haveSmapsRollup = false;
- }
+ // Initialize clock ticks
+ jiffy = sysconf(_SC_CLK_TCK);
+ if (jiffy == -1)
+ CRT_fatalError("Cannot get clock ticks by sysconf(_SC_CLK_TCK)");
+
+ // Test /proc/PID/smaps_rollup availability (faster to parse, Linux 4.14+)
+ this->haveSmapsRollup = (access(PROCDIR "/self/smaps_rollup", R_OK) == 0);
- // Read btime
+ // Read btime (the kernel boot time, as number of seconds since the epoch)
{
FILE* statfile = fopen(PROCSTATFILE, "r");
- if (statfile == NULL) {
+ if (statfile == NULL)
CRT_fatalError("Cannot open " PROCSTATFILE);
- }
-
while (true) {
char buffer[PROC_LINE_LENGTH + 1];
- if (fgets(buffer, sizeof(buffer), statfile) == NULL) {
- CRT_fatalError("No btime in " PROCSTATFILE);
- } else if (String_startsWith(buffer, "btime ")) {
- if (sscanf(buffer, "btime %lld\n", &btime) != 1) {
- CRT_fatalError("Failed to parse btime from " PROCSTATFILE);
- }
+ if (fgets(buffer, sizeof(buffer), statfile) == NULL)
break;
- }
+ if (String_startsWith(buffer, "btime ") == false)
+ continue;
+ if (sscanf(buffer, "btime %lld\n", &btime) == 1)
+ break;
+ CRT_fatalError("Failed to parse btime from " PROCSTATFILE);
}
-
fclose(statfile);
+
+ if (!btime)
+ CRT_fatalError("No btime in " PROCSTATFILE);
}
// Initialize CPU count
@@ -267,16 +277,7 @@ void ProcessList_delete(ProcessList* pl) {
free(this);
}
-static inline unsigned long long LinuxProcess_adjustTime(unsigned long long t) {
- static long jiffy = -1;
- if (jiffy == -1) {
- errno = 0;
- jiffy = sysconf(_SC_CLK_TCK);
- if (errno || -1 == jiffy) {
- jiffy = -1;
- return t; // Assume 100Hz clock
- }
- }
+static inline unsigned long long LinuxProcessList_adjustTime(unsigned long long t) {
return t * 100 / jiffy;
}
@@ -329,13 +330,13 @@ static bool LinuxProcessList_readStatFile(Process* process, openat_arg_t procFd,
location += 1;
lp->cmajflt = strtoull(location, &location, 10);
location += 1;
- lp->utime = LinuxProcess_adjustTime(strtoull(location, &location, 10));
+ lp->utime = LinuxProcessList_adjustTime(strtoull(location, &location, 10));
location += 1;
- lp->stime = LinuxProcess_adjustTime(strtoull(location, &location, 10));
+ lp->stime = LinuxProcessList_adjustTime(strtoull(location, &location, 10));
location += 1;
- lp->cutime = LinuxProcess_adjustTime(strtoull(location, &location, 10));
+ lp->cutime = LinuxProcessList_adjustTime(strtoull(location, &location, 10));
location += 1;
- lp->cstime = LinuxProcess_adjustTime(strtoull(location, &location, 10));
+ lp->cstime = LinuxProcessList_adjustTime(strtoull(location, &location, 10));
location += 1;
process->priority = strtol(location, &location, 10);
location += 1;
@@ -345,7 +346,7 @@ static bool LinuxProcessList_readStatFile(Process* process, openat_arg_t procFd,
location += 1;
location = strchr(location, ' ') + 1;
if (process->starttime_ctime == 0) {
- process->starttime_ctime = btime + LinuxProcess_adjustTime(strtoll(location, &location, 10)) / 100;
+ process->starttime_ctime = btime + LinuxProcessList_adjustTime(strtoll(location, &location, 10)) / 100;
} else {
location = strchr(location, ' ') + 1;
}
@@ -483,7 +484,7 @@ static inline uint64_t fast_strtoull_hex(char **str, int maxlen) {
return result;
}
-static void LinuxProcessList_calcLibSize_helper(ATTR_UNUSED hkey_t key, void* value, void* data) {
+static void LinuxProcessList_calcLibSize_helper(ATTR_UNUSED ht_key_t key, void* value, void* data) {
if (!data)
return;
@@ -573,7 +574,7 @@ static uint64_t LinuxProcessList_calcLibSize(openat_arg_t procFd) {
Hashtable_delete(ht);
- return total_size / CRT_pageSize;
+ return total_size / pageSize;
}
static bool LinuxProcessList_readStatmFile(LinuxProcess* process, openat_arg_t procFd, bool performLookup, unsigned long long now) {
@@ -593,6 +594,9 @@ static bool LinuxProcessList_readStatmFile(LinuxProcess* process, openat_arg_t p
fclose(statmfile);
if (r == 7) {
+ process->super.m_virt *= pageSizeKB;
+ process->super.m_resident *= pageSizeKB;
+
if (tmp_m_lrs) {
process->m_lrs = tmp_m_lrs;
} else if (performLookup) {
@@ -947,12 +951,19 @@ static int handleNetlinkMsg(struct nl_msg* nlmsg, void* linuxProcess) {
static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProcess* process) {
struct nl_msg* msg;
+ if (!this->netlink_socket) {
+ LinuxProcessList_initNetlinkSocket(this);
+ if (!this->netlink_socket) {
+ goto delayacct_failure;
+ }
+ }
+
if (nl_socket_modify_cb(this->netlink_socket, NL_CB_VALID, NL_CB_CUSTOM, handleNetlinkMsg, process) < 0) {
- return;
+ goto delayacct_failure;
}
if (! (msg = nlmsg_alloc())) {
- return;
+ goto delayacct_failure;
}
if (! genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, this->netlink_family, 0, NLM_F_REQUEST, TASKSTATS_CMD_GET, TASKSTATS_VERSION)) {
@@ -964,15 +975,19 @@ static void LinuxProcessList_readDelayAcctData(LinuxProcessList* this, LinuxProc
}
if (nl_send_sync(this->netlink_socket, msg) < 0) {
- process->swapin_delay_percent = NAN;
- process->blkio_delay_percent = NAN;
- process->cpu_delay_percent = NAN;
- return;
+ goto delayacct_failure;
}
if (nl_recvmsgs_default(this->netlink_socket) < 0) {
- return;
+ goto delayacct_failure;
}
+
+ return;
+
+delayacct_failure:
+ process->swapin_delay_percent = NAN;
+ process->blkio_delay_percent = NAN;
+ process->cpu_delay_percent = NAN;
}
#endif
@@ -1363,9 +1378,9 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
}
/* period might be 0 after system sleep */
- float percent_cpu = (period < 1e-6) ? 0.0f : ((lp->utime + lp->stime - lasttimes) / period * 100.0);
- proc->percent_cpu = CLAMP(percent_cpu, 0.0f, cpus * 100.0f);
- proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (double)(pl->totalMem) * 100.0;
+ float percent_cpu = (period < 1E-6) ? 0.0F : ((lp->utime + lp->stime - lasttimes) / period * 100.0);
+ proc->percent_cpu = CLAMP(percent_cpu, 0.0F, cpus * 100.0F);
+ proc->percent_mem = proc->m_resident / (double)(pl->totalMem) * 100.0;
if (!preExisting) {
@@ -1411,7 +1426,9 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_
}
#ifdef HAVE_DELAYACCT
- LinuxProcessList_readDelayAcctData(this, lp);
+ if (settings->flags & PROCESS_FLAG_LINUX_DELAYACCT) {
+ LinuxProcessList_readDelayAcctData(this, lp);
+ }
#endif
if (settings->flags & PROCESS_FLAG_LINUX_CGROUP) {
@@ -1785,7 +1802,9 @@ static void scanCPUFreqencyFromCPUinfo(LinuxProcessList* this) {
continue;
} else if (
(sscanf(buffer, "cpu MHz : %lf", &frequency) == 1) ||
- (sscanf(buffer, "cpu MHz: %lf", &frequency) == 1)
+ (sscanf(buffer, "cpu MHz: %lf", &frequency) == 1) ||
+ (sscanf(buffer, "clock : %lfMHz", &frequency) == 1) ||
+ (sscanf(buffer, "clock: %lfMHz", &frequency) == 1)
) {
if (cpuid < 0 || cpuid > (cpus - 1)) {
continue;
@@ -1824,41 +1843,6 @@ static void LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) {
scanCPUFreqencyFromCPUinfo(this);
}
-#ifdef HAVE_SENSORS_SENSORS_H
-static void LinuxProcessList_scanCPUTemperature(LinuxProcessList* this) {
- const int cpuCount = this->super.cpuCount;
-
- for (int i = 0; i <= cpuCount; i++) {
- this->cpus[i].temperature = NAN;
- }
-
- int r = LibSensors_getCPUTemperatures(this->cpus, cpuCount);
-
- /* No temperature - nothing to do */
- if (r <= 0)
- return;
-
- /* Only package temperature - copy to all cpus */
- if (r == 1 && !isnan(this->cpus[0].temperature)) {
- double packageTemp = this->cpus[0].temperature;
- for (int i = 1; i <= cpuCount; i++) {
- this->cpus[i].temperature = packageTemp;
- }
-
- return;
- }
-
- /* Half the temperatures, probably HT/SMT - copy to second half */
- if (r >= 2 && (r - 1) == (cpuCount / 2)) {
- for (int i = cpuCount / 2 + 1; i <= cpuCount; i++) {
- this->cpus[i].temperature = this->cpus[i/2].temperature;
- }
-
- return;
- }
-}
-#endif
-
void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
LinuxProcessList* this = (LinuxProcessList*) super;
const Settings* settings = super->settings;
@@ -1876,7 +1860,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
#ifdef HAVE_SENSORS_SENSORS_H
if (settings->showCPUTemperature)
- LinuxProcessList_scanCPUTemperature(this);
+ LibSensors_getCPUTemperatures(this->cpus, this->super.cpuCount);
#endif
// in pause mode only gather global data for meters (CPU/memory/...)
diff --git a/linux/Platform.c b/linux/Platform.c
index 590fc7a..dd80ded 100644
--- a/linux/Platform.c
+++ b/linux/Platform.c
@@ -65,9 +65,7 @@ in the source distribution for its full text.
#endif
-ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, (int)M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
-
-int Platform_numberOfFields = LAST_PROCESSFIELD;
+const ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
const SignalItem Platform_signals[] = {
{ .name = " 0 Cancel", .number = 0 },
diff --git a/linux/Platform.h b/linux/Platform.h
index 280b997..fe81448 100644
--- a/linux/Platform.h
+++ b/linux/Platform.h
@@ -18,9 +18,7 @@ in the source distribution for its full text.
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
-extern ProcessField Platform_defaultFields[];
-
-extern int Platform_numberOfFields;
+extern const ProcessField Platform_defaultFields[];
extern const SignalItem Platform_signals[];
diff --git a/linux/PressureStallMeter.c b/linux/PressureStallMeter.c
index 745068c..7486968 100644
--- a/linux/PressureStallMeter.c
+++ b/linux/PressureStallMeter.c
@@ -43,18 +43,22 @@ static void PressureStallMeter_updateValues(Meter* this, char* buffer, size_t le
}
Platform_getPressureStall(file, some, &this->values[0], &this->values[1], &this->values[2]);
- xSnprintf(buffer, len, "%s %s %.2lf%% %.2lf%% %.2lf%%", some ? "some" : "full", file, this->values[0], this->values[1], this->values[2]);
+
+ /* only print bar for ten (not sixty and threehundred), cause the sum is meaningless */
+ this->curItems = 1;
+
+ xSnprintf(buffer, len, "%s %s %5.2lf%% %5.2lf%% %5.2lf%%", some ? "some" : "full", file, this->values[0], this->values[1], this->values[2]);
}
static void PressureStallMeter_display(const Object* cast, RichString* out) {
const Meter* this = (const Meter*)cast;
char buffer[20];
- xSnprintf(buffer, sizeof(buffer), "%.2lf%% ", this->values[0]);
- RichString_write(out, CRT_colors[PRESSURE_STALL_TEN], buffer);
- xSnprintf(buffer, sizeof(buffer), "%.2lf%% ", this->values[1]);
- RichString_append(out, CRT_colors[PRESSURE_STALL_SIXTY], buffer);
- xSnprintf(buffer, sizeof(buffer), "%.2lf%% ", this->values[2]);
- RichString_append(out, CRT_colors[PRESSURE_STALL_THREEHUNDRED], buffer);
+ xSnprintf(buffer, sizeof(buffer), "%5.2lf%% ", this->values[0]);
+ RichString_writeAscii(out, CRT_colors[PRESSURE_STALL_TEN], buffer);
+ xSnprintf(buffer, sizeof(buffer), "%5.2lf%% ", this->values[1]);
+ RichString_appendAscii(out, CRT_colors[PRESSURE_STALL_SIXTY], buffer);
+ xSnprintf(buffer, sizeof(buffer), "%5.2lf%% ", this->values[2]);
+ RichString_appendAscii(out, CRT_colors[PRESSURE_STALL_THREEHUNDRED], buffer);
}
const MeterClass PressureStallCPUSomeMeter_class = {
diff --git a/linux/ProcessField.h b/linux/ProcessField.h
new file mode 100644
index 0000000..6e2eff3
--- /dev/null
+++ b/linux/ProcessField.h
@@ -0,0 +1,53 @@
+#ifndef HEADER_LinuxProcessField
+#define HEADER_LinuxProcessField
+/*
+htop - linux/ProcessField.h
+(C) 2020 htop dev team
+Released under the GNU GPLv2, see the COPYING file
+in the source distribution for its full text.
+*/
+
+
+#define PLATFORM_PROCESS_FIELDS \
+ CMINFLT = 11, \
+ CMAJFLT = 13, \
+ UTIME = 14, \
+ STIME = 15, \
+ CUTIME = 16, \
+ CSTIME = 17, \
+ M_SHARE = 41, \
+ M_TRS = 42, \
+ M_DRS = 43, \
+ M_LRS = 44, \
+ M_DT = 45, \
+ CTID = 100, \
+ VPID = 101, \
+ VXID = 102, \
+ RCHAR = 103, \
+ WCHAR = 104, \
+ SYSCR = 105, \
+ SYSCW = 106, \
+ RBYTES = 107, \
+ WBYTES = 108, \
+ CNCLWB = 109, \
+ IO_READ_RATE = 110, \
+ IO_WRITE_RATE = 111, \
+ IO_RATE = 112, \
+ CGROUP = 113, \
+ OOM = 114, \
+ IO_PRIORITY = 115, \
+ PERCENT_CPU_DELAY = 116, \
+ PERCENT_IO_DELAY = 117, \
+ PERCENT_SWAP_DELAY = 118, \
+ M_PSS = 119, \
+ M_SWAP = 120, \
+ M_PSSWP = 121, \
+ CTXT = 122, \
+ SECATTR = 123, \
+ PROC_COMM = 124, \
+ PROC_EXE = 125, \
+ CWD = 126, \
+ // End of list
+
+
+#endif /* HEADER_LinuxProcessField */
diff --git a/linux/SELinuxMeter.c b/linux/SELinuxMeter.c
index 64a3f2a..892f1e8 100644
--- a/linux/SELinuxMeter.c
+++ b/linux/SELinuxMeter.c
@@ -35,7 +35,7 @@ static bool hasSELinuxMount(void) {
return false;
}
- if (sfbuf.f_type != SELINUX_MAGIC) {
+ if ((uint32_t)sfbuf.f_type != (uint32_t)SELINUX_MAGIC) {
return false;
}
diff --git a/linux/SystemdMeter.c b/linux/SystemdMeter.c
index 4350d26..61bb59b 100644
--- a/linux/SystemdMeter.c
+++ b/linux/SystemdMeter.c
@@ -267,9 +267,9 @@ static void SystemdMeter_display(ATTR_UNUSED const Object* cast, RichString* out
char buffer[16];
int color = (systemState && 0 == strcmp(systemState, "running")) ? METER_VALUE_OK : METER_VALUE_ERROR;
- RichString_write(out, CRT_colors[color], systemState ? systemState : "???");
+ RichString_writeAscii(out, CRT_colors[color], systemState ? systemState : "N/A");
- RichString_append(out, CRT_colors[METER_TEXT], " (");
+ RichString_appendAscii(out, CRT_colors[METER_TEXT], " (");
if (nFailedUnits == INVALID_VALUE) {
buffer[0] = '?';
@@ -277,9 +277,9 @@ static void SystemdMeter_display(ATTR_UNUSED const Object* cast, RichString* out
} else {
xSnprintf(buffer, sizeof(buffer), "%u", nFailedUnits);
}
- RichString_append(out, zeroDigitColor(nFailedUnits), buffer);
+ RichString_appendAscii(out, zeroDigitColor(nFailedUnits), buffer);
- RichString_append(out, CRT_colors[METER_TEXT], "/");
+ RichString_appendAscii(out, CRT_colors[METER_TEXT], "/");
if (nNames == INVALID_VALUE) {
buffer[0] = '?';
@@ -287,9 +287,9 @@ static void SystemdMeter_display(ATTR_UNUSED const Object* cast, RichString* out
} else {
xSnprintf(buffer, sizeof(buffer), "%u", nNames);
}
- RichString_append(out, valueDigitColor(nNames), buffer);
+ RichString_appendAscii(out, valueDigitColor(nNames), buffer);
- RichString_append(out, CRT_colors[METER_TEXT], " failed) (");
+ RichString_appendAscii(out, CRT_colors[METER_TEXT], " failed) (");
if (nJobs == INVALID_VALUE) {
buffer[0] = '?';
@@ -297,9 +297,9 @@ static void SystemdMeter_display(ATTR_UNUSED const Object* cast, RichString* out
} else {
xSnprintf(buffer, sizeof(buffer), "%u", nJobs);
}
- RichString_append(out, zeroDigitColor(nJobs), buffer);
+ RichString_appendAscii(out, zeroDigitColor(nJobs), buffer);
- RichString_append(out, CRT_colors[METER_TEXT], "/");
+ RichString_appendAscii(out, CRT_colors[METER_TEXT], "/");
if (nInstalledJobs == INVALID_VALUE) {
buffer[0] = '?';
@@ -307,9 +307,9 @@ static void SystemdMeter_display(ATTR_UNUSED const Object* cast, RichString* out
} else {
xSnprintf(buffer, sizeof(buffer), "%u", nInstalledJobs);
}
- RichString_append(out, valueDigitColor(nInstalledJobs), buffer);
+ RichString_appendAscii(out, valueDigitColor(nInstalledJobs), buffer);
- RichString_append(out, CRT_colors[METER_TEXT], " jobs)");
+ RichString_appendAscii(out, CRT_colors[METER_TEXT], " jobs)");
}
static const int SystemdMeter_attributes[] = {
diff --git a/linux/ZramMeter.c b/linux/ZramMeter.c
index e6b6937..723de0a 100644
--- a/linux/ZramMeter.c
+++ b/linux/ZramMeter.c
@@ -37,17 +37,19 @@ static void ZramMeter_updateValues(Meter* this, char* buffer, size_t size) {
static void ZramMeter_display(const Object* cast, RichString* out) {
char buffer[50];
const Meter* this = (const Meter*)cast;
- RichString_write(out, CRT_colors[METER_TEXT], ":");
+
+ RichString_writeAscii(out, CRT_colors[METER_TEXT], ":");
+
Meter_humanUnit(buffer, this->total, sizeof(buffer));
+ RichString_appendAscii(out, CRT_colors[METER_VALUE], buffer);
- RichString_append(out, CRT_colors[METER_VALUE], buffer);
Meter_humanUnit(buffer, this->values[0], sizeof(buffer));
- RichString_append(out, CRT_colors[METER_TEXT], " used:");
- RichString_append(out, CRT_colors[METER_VALUE], buffer);
+ RichString_appendAscii(out, CRT_colors[METER_TEXT], " used:");
+ RichString_appendAscii(out, CRT_colors[METER_VALUE], buffer);
Meter_humanUnit(buffer, this->values[1], sizeof(buffer));
- RichString_append(out, CRT_colors[METER_TEXT], " uncompressed:");
- RichString_append(out, CRT_colors[METER_VALUE], buffer);
+ RichString_appendAscii(out, CRT_colors[METER_TEXT], " uncompressed:");
+ RichString_appendAscii(out, CRT_colors[METER_VALUE], buffer);
}
const MeterClass ZramMeter_class = {

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