Cache PAGE_SIZE

man:sysconf(3) states:
    The values obtained from these functions are system configuration constants.
    They do not change during the lifetime of a process.
This commit is contained in:
Christian Göttsche 2020-10-15 22:37:02 +02:00
parent 0db398d4c3
commit 361877454f
11 changed files with 60 additions and 49 deletions

7
CRT.c
View File

@ -544,6 +544,9 @@ 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;
@ -675,6 +678,10 @@ void CRT_init(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;
}
void CRT_done() {

3
CRT.h
View File

@ -149,6 +149,9 @@ 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

@ -311,8 +311,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 * PAGE_SIZE_KB, coloring); return;
case M_SIZE: Process_humanNumber(str, this->m_size * PAGE_SIZE_KB, coloring); return;
case M_RESIDENT: Process_humanNumber(str, this->m_resident * CRT_pageSizeKB, coloring); return;
case M_SIZE: Process_humanNumber(str, this->m_size * CRT_pageSizeKB, coloring); return;
case NICE: {
xSnprintf(buffer, n, "%3ld ", this->nice);
attr = this->nice < 0 ? CRT_colors[PROCESS_HIGH_PRIORITY]

View File

@ -21,13 +21,6 @@ in the source distribution for its full text.
#define SYS_ioprio_set __NR_ioprio_set
#endif
// On Linux, this works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
#endif
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
#define PROCESS_FLAG_IO 0x0001
typedef enum ProcessFields {

View File

@ -15,6 +15,8 @@ in the source distribution for its full text.
#include <mach/mach.h>
#include "CRT.h"
const ProcessClass DarwinProcess_class = {
.super = {
@ -257,8 +259,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_size = pti.pti_virtual_size / 1024 / PAGE_SIZE_KB;
proc->super.m_resident = pti.pti_resident_size / 1024 / PAGE_SIZE_KB;
proc->super.m_size = pti.pti_virtual_size / CRT_pageSize;
proc->super.m_resident = pti.pti_resident_size / CRT_pageSize;
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

@ -9,7 +9,6 @@ in the source distribution for its full text.
#include "ProcessList.h"
#include "DragonFlyBSDProcessList.h"
#include "DragonFlyBSDProcess.h"
#include "Macros.h"
#include <unistd.h>
#include <stdlib.h>
@ -22,6 +21,9 @@ in the source distribution for its full text.
#include <string.h>
#include <sys/param.h>
#include "CRT.h"
#include "Macros.h"
static int MIB_hw_physmem[2];
static int MIB_vm_stats_vm_v_page_count[4];
@ -54,8 +56,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
len = sizeof(pageSize);
if (sysctlbyname("vm.stats.vm.v_page_size", &pageSize, &len, NULL, 0) == -1) {
pageSize = PAGE_SIZE;
pageSizeKb = PAGE_SIZE_KB;
pageSize = CRT_pageSize;
pageSizeKb = CRT_pageSizeKB;
} else {
pageSizeKb = pageSize / ONE_K;
}
@ -431,12 +433,12 @@ void ProcessList_goThroughEntries(ProcessList* this) {
proc->m_size = kproc->kp_vm_map_size / 1024 / pageSizeKb;
proc->m_resident = kproc->kp_vm_rssize;
proc->percent_mem = (proc->m_resident * PAGE_SIZE_KB) / (double)(this->totalMem) * 100.0;
proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (double)(this->totalMem) * 100.0;
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 * PAGE_SIZE_KB) / (double)(this->totalMem);
proc->percent_mem = 100.0 * (proc->m_resident * pageSizeKb) / (double)(this->totalMem);
if (proc->percent_cpu > 0.1) {
// system idle process should own all CPU time left regardless of CPU count

View File

@ -19,6 +19,7 @@ in the source distribution for its full text.
#include <sys/sysctl.h>
#include <sys/user.h>
#include "CRT.h"
#include "FreeBSDProcess.h"
#include "Macros.h"
#include "ProcessList.h"
@ -60,8 +61,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
len = sizeof(pageSize);
if (sysctlbyname("vm.stats.vm.v_page_size", &pageSize, &len, NULL, 0) == -1) {
pageSize = PAGE_SIZE;
pageSizeKb = PAGE_SIZE_KB;
pageSize = CRT_pageSize;
pageSizeKb = CRT_pageSize;
} else {
pageSizeKb = pageSize / ONE_K;
}
@ -446,12 +447,12 @@ void ProcessList_goThroughEntries(ProcessList* this) {
// from FreeBSD source /src/usr.bin/top/machine.c
proc->m_size = kproc->ki_size / 1024 / pageSizeKb;
proc->m_resident = kproc->ki_rssize;
proc->percent_mem = (proc->m_resident * PAGE_SIZE_KB) / (double)(this->totalMem) * 100.0;
proc->percent_mem = (proc->m_resident * pageSizeKb) / (double)(this->totalMem) * 100.0;
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 * PAGE_SIZE_KB) / (double)(this->totalMem);
proc->percent_mem = 100.0 * (proc->m_resident * pageSizeKb) / (double)(this->totalMem);
/*
* TODO

View File

@ -215,11 +215,11 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
}
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 * PAGE_SIZE_KB, coloring); return;
case M_DT: Process_humanNumber(str, lp->m_dt * PAGE_SIZE_KB, coloring); return;
case M_LRS: Process_humanNumber(str, lp->m_lrs * PAGE_SIZE_KB, coloring); return;
case M_TRS: Process_humanNumber(str, lp->m_trs * PAGE_SIZE_KB, coloring); return;
case M_SHARE: Process_humanNumber(str, lp->m_share * PAGE_SIZE_KB, 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_LRS: Process_humanNumber(str, lp->m_lrs * CRT_pageSizeKB, coloring); return;
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_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

@ -479,14 +479,14 @@ static bool LinuxProcessList_readSmapsFile(LinuxProcess* process, const char* di
//http://elixir.free-electrons.com/linux/v4.10/source/fs/proc/task_mmu.c#L719
//kernel will return data in chunks of size PAGE_SIZE or less.
char buffer[PAGE_SIZE];// 4k
char buffer[CRT_pageSize];// 4k
char *start,*end;
ssize_t nread=0;
int tmp=0;
if(haveSmapsRollup) {// only available in Linux 4.14+
snprintf(buffer, PAGE_SIZE-1, "%s/%s/smaps_rollup", dirname, name);
xSnprintf(buffer, sizeof(buffer), "%s/%s/smaps_rollup", dirname, name);
} else {
snprintf(buffer, PAGE_SIZE-1, "%s/%s/smaps", dirname, name);
xSnprintf(buffer, sizeof(buffer), "%s/%s/smaps", dirname, name);
}
int fd = open(buffer, O_RDONLY);
if (fd == -1)
@ -1020,7 +1020,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, const char*
float percent_cpu = (lp->utime + lp->stime - lasttimes) / period * 100.0;
proc->percent_cpu = CLAMP(percent_cpu, 0.0, cpus * 100.0);
if (isnan(proc->percent_cpu)) proc->percent_cpu = 0.0;
proc->percent_mem = (proc->m_resident * PAGE_SIZE_KB) / (double)(pl->totalMem) * 100.0;
proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (double)(pl->totalMem) * 100.0;
if(!preExisting) {

View File

@ -91,7 +91,7 @@ static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
err(1, "uvmexp sysctl call failed");
}
pl->totalMem = uvmexp.npages * PAGE_SIZE_KB;
pl->totalMem = uvmexp.npages * CRT_pageSizeKB;
// Taken from OpenBSD systat/iostat.c, top/machine.c and uvm_sysctl(9)
static int bcache_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT};
@ -102,9 +102,9 @@ static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
err(1, "cannot get vfs.bcachestat");
}
pl->cachedMem = bcstats.numbufpages * PAGE_SIZE_KB;
pl->freeMem = uvmexp.free * PAGE_SIZE_KB;
pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * PAGE_SIZE_KB;
pl->cachedMem = bcstats.numbufpages * CRT_pageSizeKB;
pl->freeMem = uvmexp.free * CRT_pageSizeKB;
pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * CRT_pageSizeKB;
/*
const OpenBSDProcessList* opl = (OpenBSDProcessList*) pl;
@ -113,10 +113,10 @@ static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
sysctl(MIB_hw_physmem, 2, &(pl->totalMem), &len, NULL, 0);
pl->totalMem /= 1024;
sysctl(MIB_vm_stats_vm_v_wire_count, 4, &(pl->usedMem), &len, NULL, 0);
pl->usedMem *= PAGE_SIZE_KB;
pl->usedMem *= CRT_pageSizeKB;
pl->freeMem = pl->totalMem - pl->usedMem;
sysctl(MIB_vm_stats_vm_v_cache_count, 4, &(pl->cachedMem), &len, NULL, 0);
pl->cachedMem *= PAGE_SIZE_KB;
pl->cachedMem *= CRT_pageSizeKB;
struct kvm_swap swap[16];
int nswap = kvm_getswapinfo(opl->kd, swap, ARRAYSIZE(swap), 0);
@ -126,8 +126,8 @@ static inline void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) {
pl->totalSwap += swap[i].ksw_total;
pl->usedSwap += swap[i].ksw_used;
}
pl->totalSwap *= PAGE_SIZE_KB;
pl->usedSwap *= PAGE_SIZE_KB;
pl->totalSwap *= CRT_pageSizeKB;
pl->usedSwap *= CRT_pageSizeKB;
pl->sharedMem = 0; // currently unused
pl->buffersMem = 0; // not exposed to userspace
@ -231,7 +231,7 @@ static inline void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) {
proc->m_size = kproc->p_vm_dsize;
proc->m_resident = kproc->p_vm_rssize;
proc->percent_mem = (proc->m_resident * PAGE_SIZE_KB) / (double)(this->super.totalMem) * 100.0;
proc->percent_mem = (proc->m_resident * CRT_pageSizeKB) / (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->time = kproc->p_rtime_sec + ((kproc->p_rtime_usec + 500000) / 10);

View File

@ -23,6 +23,9 @@ in the source distribution for its full text.
#include <math.h>
#include <time.h>
#include "CRT.h"
#define MAXCMDLINE 255
char* SolarisProcessList_readZoneName(kstat_ctl_t* kd, SolarisProcess* sproc) {
@ -157,22 +160,22 @@ 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 * PAGE_SIZE_KB;
if (pl->totalMem > freemem_pgs->value.ui64 * PAGE_SIZE_KB)
pl->usedMem = pl->totalMem - freemem_pgs->value.ui64 * PAGE_SIZE_KB;
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;
else
pl->usedMem = 0; // This can happen in non-global zone (in theory)
pl->usedMem = 0; // This can happen in non-global zone (in theory)
// Not sure how to implement this on Solaris - suggestions welcome!
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) * PAGE_SIZE_KB;
pl->buffersMem = (totalmem_pgs->value.ui64 - pages->value.ui64) * CRT_pageSizeKB;
} else {
// Fall back to basic sysconf if kstat isn't working
pl->totalMem = sysconf(_SC_PHYS_PAGES) * PAGE_SIZE;
pl->totalMem = sysconf(_SC_PHYS_PAGES) * CRT_pageSize;
pl->buffersMem = 0;
pl->cachedMem = 0;
pl->usedMem = pl->totalMem - (sysconf(_SC_AVPHYS_PAGES) * PAGE_SIZE);
pl->usedMem = pl->totalMem - (sysconf(_SC_AVPHYS_PAGES) * CRT_pageSize);
}
// Part 2 - swap
@ -198,8 +201,8 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) {
}
free(spathbase);
free(sl);
pl->totalSwap = totalswap * PAGE_SIZE_KB;
pl->usedSwap = pl->totalSwap - (totalfree * PAGE_SIZE_KB);
pl->totalSwap = totalswap * CRT_pageSizeKB;
pl->usedSwap = pl->totalSwap - (totalfree * CRT_pageSizeKB);
}
static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) {
@ -297,8 +300,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/PAGE_SIZE_KB;
proc->m_size = _psinfo->pr_size/PAGE_SIZE_KB;
proc->m_resident = _psinfo->pr_rssize/CRT_pageSizeKB;
proc->m_size = _psinfo->pr_size/CRT_pageSizeKB;
if (!preExisting) {
sproc->realpid = _psinfo->pr_pid;