aboutsummaryrefslogtreecommitdiffstats
path: root/linux/LinuxProcessList.c
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/LinuxProcessList.c
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/LinuxProcessList.c')
-rw-r--r--linux/LinuxProcessList.c164
1 files changed, 74 insertions, 90 deletions
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/...)

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