diff options
author | Daniel Lange <DLange@git.local> | 2021-01-11 20:43:27 +0100 |
---|---|---|
committer | Daniel Lange <DLange@git.local> | 2021-01-11 20:43:27 +0100 |
commit | c55320e9e2a8916e911bcd39ab37b79e3a7d03b2 (patch) | |
tree | d6be9a09fdf7d6dc155de3429a70697ee2bb43b0 /linux/LinuxProcessList.c | |
parent | 65357c8c46154de4e4eca14075bfe5523bb5fc14 (diff) | |
download | debian_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.c | 164 |
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/...) |