Cull the definitions of pageSize and pageSizeKB from CRT.c

By storing the per-process m_resident and m_virt values in the form
htop wants to display them in (KB, not pages), we no longer need to
have definitions of pageSize and pageSizeKB in the common CRT code.

These variables were never really CRT (i.e. display) related in the
first place.  It turns out the darwin platform code doesn't need to
use these at all (the process values are extracted from the kernel
in bytes not pages) and the other platforms can each use their own
local pagesize variables, in more appropriate locations.

Some platforms were actually already doing this, so this change is
removing duplication of logic and variables there.
This commit is contained in:
Nathan Scott 2020-12-10 11:57:48 +11:00
parent db5687a355
commit 75e9f9a8d9
11 changed files with 72 additions and 61 deletions

8
CRT.c
View File

@ -608,9 +608,6 @@ const char* CRT_termType;
int CRT_colorScheme = 0;
long CRT_pageSize = -1;
long CRT_pageSizeKB = -1;
ATTR_NORETURN
static void CRT_handleSIGTERM(int sgn) {
(void) sgn;
@ -746,11 +743,6 @@ void CRT_init(const int* delay, int colorScheme, bool allowUnicode) {
mousemask(BUTTON1_RELEASED, NULL);
#endif
CRT_pageSize = sysconf(_SC_PAGESIZE);
if (CRT_pageSize == -1)
CRT_fatalError("Fatal error: Can not get PAGE_SIZE by sysconf(_SC_PAGESIZE)");
CRT_pageSizeKB = CRT_pageSize / 1024;
CRT_degreeSign = initDegreeSign();
}

3
CRT.h
View File

@ -156,9 +156,6 @@ extern const char* CRT_termType;
extern int CRT_colorScheme;
extern long CRT_pageSize;
extern long CRT_pageSizeKB;
#ifdef HAVE_SETUID_ENABLED
void CRT_dropPrivileges(void);

View File

@ -328,8 +328,8 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field
}
case MAJFLT: Process_colorNumber(str, this->majflt, coloring); return;
case MINFLT: Process_colorNumber(str, this->minflt, coloring); return;
case M_RESIDENT: Process_humanNumber(str, this->m_resident * CRT_pageSizeKB, coloring); return;
case M_VIRT: Process_humanNumber(str, this->m_virt * CRT_pageSizeKB, coloring); return;
case M_RESIDENT: Process_humanNumber(str, this->m_resident, coloring); return;
case M_VIRT: Process_humanNumber(str, this->m_virt, coloring); return;
case NICE: {
xSnprintf(buffer, n, "%3ld ", this->nice);
attr = this->nice < 0 ? CRT_colors[PROCESS_HIGH_PRIORITY]

View File

@ -258,8 +258,8 @@ void DarwinProcess_setFromLibprocPidinfo(DarwinProcess* proc, DarwinProcessList*
proc->super.time = (pti.pti_total_system + pti.pti_total_user) / 10000000;
proc->super.nlwp = pti.pti_threadnum;
proc->super.m_virt = pti.pti_virtual_size / CRT_pageSize;
proc->super.m_resident = pti.pti_resident_size / CRT_pageSize;
proc->super.m_virt = pti.pti_virtual_size / ONE_K;
proc->super.m_resident = pti.pti_resident_size / ONE_K;
proc->super.majflt = pti.pti_faults;
proc->super.percent_mem = (double)pti.pti_resident_size * 100.0
/ (double)dpl->host_info.max_mem;

View File

@ -55,12 +55,9 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
len = 2; sysctlnametomib("hw.physmem", MIB_hw_physmem, &len);
len = sizeof(pageSize);
if (sysctlbyname("vm.stats.vm.v_page_size", &pageSize, &len, NULL, 0) == -1) {
pageSize = CRT_pageSize;
pageSizeKb = CRT_pageSizeKB;
} else {
if (sysctlbyname("vm.stats.vm.v_page_size", &pageSize, &len, NULL, 0) == -1)
CRT_fatalError("Cannot get pagesize by sysctl");
pageSizeKb = pageSize / ONE_K;
}
// usable page count vm.stats.vm.v_page_count
// actually usable memory : vm.stats.vm.v_page_count * vm.stats.vm.v_page_size
@ -433,13 +430,13 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
}
}
proc->m_virt = kproc->kp_vm_map_size / pageSize;
proc->m_resident = kproc->kp_vm_rssize;
proc->m_virt = kproc->kp_vm_map_size / ONE_K;
proc->m_resident = kproc->kp_vm_rssize * pageSizeKB;
proc->nlwp = kproc->kp_nthreads; // number of lwp thread
proc->time = (kproc->kp_swtime + 5000) / 10000;
proc->percent_cpu = 100.0 * ((double)kproc->kp_lwp.kl_pctcpu / (double)kernelFScale);
proc->percent_mem = 100.0 * (proc->m_resident * pageSizeKb) / (double)(super->totalMem);
proc->percent_mem = 100.0 * proc->m_resident / (double)(super->totalMem);
if (proc->percent_cpu > 0.1) {
// system idle process should own all CPU time left regardless of CPU count

View File

@ -72,12 +72,9 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
len = 2; sysctlnametomib("hw.physmem", MIB_hw_physmem, &len);
len = sizeof(pageSize);
if (sysctlbyname("vm.stats.vm.v_page_size", &pageSize, &len, NULL, 0) == -1) {
pageSize = CRT_pageSize;
pageSizeKb = CRT_pageSize;
} else {
if (sysctlbyname("vm.stats.vm.v_page_size", &pageSize, &len, NULL, 0) == -1)
CRT_fatalError("Cannot get pagesize by sysctl");
pageSizeKb = pageSize / ONE_K;
}
// usable page count vm.stats.vm.v_page_count
// actually usable memory : vm.stats.vm.v_page_count * vm.stats.vm.v_page_size
@ -526,13 +523,13 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
}
// from FreeBSD source /src/usr.bin/top/machine.c
proc->m_virt = kproc->ki_size / pageSize;
proc->m_resident = kproc->ki_rssize;
proc->m_virt = kproc->ki_size / ONE_K;
proc->m_resident = kproc->ki_rssize * pageSizeKb;
proc->nlwp = kproc->ki_numthreads;
proc->time = (kproc->ki_runtime + 5000) / 10000;
proc->percent_cpu = 100.0 * ((double)kproc->ki_pctcpu / (double)kernelFScale);
proc->percent_mem = 100.0 * (proc->m_resident * pageSizeKb) / (double)(super->totalMem);
proc->percent_mem = 100.0 * proc->m_resident / (double)(super->totalMem);
/*
* TODO

View File

@ -25,6 +25,8 @@ 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";
@ -632,19 +634,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;

View File

@ -193,6 +193,10 @@ static inline bool Process_isUserlandThread(const Process* this) {
extern long long btime;
extern int pageSize;
extern int pageSizeKB;
extern ProcessFieldData Process_fields[];
extern ProcessPidColumn Process_pidColumns[];

View File

@ -202,6 +202,12 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
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) {
@ -573,7 +579,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 +599,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) {
@ -1365,7 +1374,7 @@ 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;
proc->percent_mem = proc->m_resident / (double)(pl->totalMem) * 100.0;
if (!preExisting) {

View File

@ -34,6 +34,8 @@ in the source distribution for its full text.
static long fscale;
static int pageSize;
static int pageSizeKB;
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {
const int mib[] = { CTL_HW, HW_NCPU };
@ -58,6 +60,10 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
err(1, "fscale sysctl call failed");
}
if ((pageSize = sysconf(_SC_PAGESIZE)) == -1)
err(1, "pagesize sysconf call failed");
pageSizeKB = pageSize / ONE_K;
for (int i = 0; i <= pl->cpuCount; i++) {
CPUData* d = opl->cpus + i;
d->totalTime = 1;
@ -94,8 +100,8 @@ static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
err(1, "uvmexp sysctl call failed");
}
pl->totalMem = uvmexp.npages * CRT_pageSizeKB;
pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * CRT_pageSizeKB;
pl->totalMem = uvmexp.npages * pageSizeKB;
pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * pageSizeKB;
// Taken from OpenBSD systat/iostat.c, top/machine.c and uvm_sysctl(9)
const int bcache_mib[] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT };
@ -106,7 +112,7 @@ static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
err(1, "cannot get vfs.bcachestat");
}
pl->cachedMem = bcstats.numbufpages * CRT_pageSizeKB;
pl->cachedMem = bcstats.numbufpages * pageSizeKB;
/*
* Copyright (c) 1994 Thorsten Lockert <tholo@sigmasoft.com>
@ -222,9 +228,9 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
}
}
proc->m_virt = kproc->p_vm_dsize;
proc->m_resident = kproc->p_vm_rssize;
proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (double)(this->super.totalMem) * 100.0;
proc->m_virt = kproc->p_vm_dsize * pageSizeKB;
proc->m_resident = kproc->p_vm_rssize * pageSizeKB;
proc->percent_mem = proc->m_resident / (double)(this->super.totalMem) * 100.0;
proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0, this->super.cpuCount * 100.0);
//proc->nlwp = kproc->p_numthreads;
proc->nice = kproc->p_nice - 20;

View File

@ -25,9 +25,11 @@ in the source distribution for its full text.
#include "CRT.h"
#define MAXCMDLINE 255
static int pageSize;
static int pageSizeKB;
char* SolarisProcessList_readZoneName(kstat_ctl_t* kd, SolarisProcess* sproc) {
char* zname;
@ -50,13 +52,18 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
spl->kd = kstat_open();
pl->cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
pageSize = sysconf(_SC_PAGESIZE);
if (pageSize == -1)
CRT_fatalError("Cannot get pagesize by sysconf(_SC_PAGESIZE)");
pageSizeKB = pageSize / 1024;
if (pl->cpuCount == 1 ) {
pl->cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
if (pl->cpuCount == -1)
CRT_fatalError("Cannot get CPU count by sysconf(_SC_NPROCESSORS_ONLN)");
else if (pl->cpuCount == 1)
spl->cpus = xRealloc(spl->cpus, sizeof(CPUData));
} else {
else
spl->cpus = xRealloc(spl->cpus, (pl->cpuCount + 1) * sizeof(CPUData));
}
return pl;
}
@ -169,9 +176,9 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) {
freemem_pgs = kstat_data_lookup(meminfo, "freemem");
pages = kstat_data_lookup(meminfo, "pagestotal");
pl->totalMem = totalmem_pgs->value.ui64 * CRT_pageSizeKB;
if (pl->totalMem > freemem_pgs->value.ui64 * CRT_pageSizeKB) {
pl->usedMem = pl->totalMem - freemem_pgs->value.ui64 * CRT_pageSizeKB;
pl->totalMem = totalmem_pgs->value.ui64 * pageSizeKB;
if (pl->totalMem > freemem_pgs->value.ui64 * pageSizeKB) {
pl->usedMem = pl->totalMem - freemem_pgs->value.ui64 * pageSizeKB;
} else {
pl->usedMem = 0; // This can happen in non-global zone (in theory)
}
@ -179,13 +186,13 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) {
pl->cachedMem = 0;
// Not really "buffers" but the best Solaris analogue that I can find to
// "memory in use but not by programs or the kernel itself"
pl->buffersMem = (totalmem_pgs->value.ui64 - pages->value.ui64) * CRT_pageSizeKB;
pl->buffersMem = (totalmem_pgs->value.ui64 - pages->value.ui64) * pageSizeKB;
} else {
// Fall back to basic sysconf if kstat isn't working
pl->totalMem = sysconf(_SC_PHYS_PAGES) * CRT_pageSize;
pl->totalMem = sysconf(_SC_PHYS_PAGES) * pageSize;
pl->buffersMem = 0;
pl->cachedMem = 0;
pl->usedMem = pl->totalMem - (sysconf(_SC_AVPHYS_PAGES) * CRT_pageSize);
pl->usedMem = pl->totalMem - (sysconf(_SC_AVPHYS_PAGES) * pageSize);
}
// Part 2 - swap
@ -215,8 +222,8 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) {
}
free(spathbase);
free(sl);
pl->totalSwap = totalswap * CRT_pageSizeKB;
pl->usedSwap = pl->totalSwap - (totalfree * CRT_pageSizeKB);
pl->totalSwap = totalswap * pageSizeKB;
pl->usedSwap = pl->totalSwap - (totalfree * pageSizeKB);
}
static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) {
@ -323,8 +330,8 @@ int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo, void*
proc->pgrp = _psinfo->pr_pgid;
proc->nlwp = _psinfo->pr_nlwp;
proc->tty_nr = _psinfo->pr_ttydev;
proc->m_resident = _psinfo->pr_rssize / CRT_pageSizeKB;
proc->m_virt = _psinfo->pr_size / CRT_pageSizeKB;
proc->m_resident = _psinfo->pr_rssize; // KB
proc->m_virt = _psinfo->pr_size; // KB
if (!preExisting) {
sproc->realpid = _psinfo->pr_pid;