diff --git a/CRT.c b/CRT.c index 68f64054..f932bb2b 100644 --- a/CRT.c +++ b/CRT.c @@ -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(); } diff --git a/CRT.h b/CRT.h index ec3fdafe..c62d4902 100644 --- a/CRT.h +++ b/CRT.h @@ -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); diff --git a/Process.c b/Process.c index 544358ee..0a954d49 100644 --- a/Process.c +++ b/Process.c @@ -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] diff --git a/darwin/DarwinProcess.c b/darwin/DarwinProcess.c index f3c34254..904df0bd 100644 --- a/darwin/DarwinProcess.c +++ b/darwin/DarwinProcess.c @@ -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; diff --git a/dragonflybsd/DragonFlyBSDProcessList.c b/dragonflybsd/DragonFlyBSDProcessList.c index 940ec03d..fd19df30 100644 --- a/dragonflybsd/DragonFlyBSDProcessList.c +++ b/dragonflybsd/DragonFlyBSDProcessList.c @@ -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 { - pageSizeKb = pageSize / ONE_K; - } + 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 diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c index 9aaab5dd..d8fadb33 100644 --- a/freebsd/FreeBSDProcessList.c +++ b/freebsd/FreeBSDProcessList.c @@ -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 { - pageSizeKb = pageSize / ONE_K; - } + 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 diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index ef155af8..44c4b2d9 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -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; diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h index ad396fb2..3c1e7e75 100644 --- a/linux/LinuxProcess.h +++ b/linux/LinuxProcess.h @@ -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[]; diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index b9ba247f..e228220f 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -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) { diff --git a/openbsd/OpenBSDProcessList.c b/openbsd/OpenBSDProcessList.c index 5412030f..3f4abb9f 100644 --- a/openbsd/OpenBSDProcessList.c +++ b/openbsd/OpenBSDProcessList.c @@ -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 @@ -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; diff --git a/solaris/SolarisProcessList.c b/solaris/SolarisProcessList.c index 4249fa60..793b1b3b 100644 --- a/solaris/SolarisProcessList.c +++ b/solaris/SolarisProcessList.c @@ -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;