From 0bdade1b6cb40c5bd374a93ac0489058a7421bb5 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Tue, 2 May 2023 09:02:22 +1000 Subject: Introduce Machine class for host-specific info (split from ProcessList) First stage in sanitizing the process list structure so that htop can support other types of lists too (cgroups, filesystems, ...), in the not-too-distant future. This introduces struct Machine for system-wide information while keeping process-list information in ProcessList (now much less). Next step is to propogate this separation into each platform, to match these core changes. --- solaris/Platform.c | 27 ++++++++++--------- solaris/SolarisProcess.c | 4 +-- solaris/SolarisProcess.h | 4 +-- solaris/SolarisProcessList.c | 64 +++++++++++++++++++++++++++----------------- solaris/SolarisProcessList.h | 8 ++++-- 5 files changed, 63 insertions(+), 44 deletions(-) (limited to 'solaris') diff --git a/solaris/Platform.c b/solaris/Platform.c index 79b6a9ea..8c88fc85 100644 --- a/solaris/Platform.c +++ b/solaris/Platform.c @@ -194,8 +194,9 @@ int Platform_getMaxPid(void) { } double Platform_setCPUValues(Meter* this, unsigned int cpu) { - const SolarisProcessList* spl = (const SolarisProcessList*) this->pl; - unsigned int cpus = this->pl->existingCPUs; + const Machine* host = this->host; + const SolarisProcessList* spl = (const SolarisProcessList*) host->pl; + unsigned int cpus = host->existingCPUs; const CPUData* cpuData = NULL; if (cpus == 1) { @@ -215,7 +216,7 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { v[CPU_METER_NICE] = cpuData->nicePercent; v[CPU_METER_NORMAL] = cpuData->userPercent; - if (this->pl->settings->detailedCPUTime) { + if (host->settings->detailedCPUTime) { v[CPU_METER_KERNEL] = cpuData->systemPercent; v[CPU_METER_IRQ] = cpuData->irqPercent; this->curItems = 4; @@ -235,32 +236,32 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { } void Platform_setMemoryValues(Meter* this) { - const ProcessList* pl = this->pl; - this->total = pl->totalMem; - this->values[MEMORY_METER_USED] = pl->usedMem; - this->values[MEMORY_METER_BUFFERS] = pl->buffersMem; + const Machine* host = this->host; + this->total = host->totalMem; + this->values[MEMORY_METER_USED] = host->usedMem; + this->values[MEMORY_METER_BUFFERS] = host->buffersMem; // this->values[MEMORY_METER_SHARED] = "shared memory, like tmpfs and shm" // this->values[MEMORY_METER_COMPRESSED] = "compressed memory, like zswap on linux" - this->values[MEMORY_METER_CACHE] = pl->cachedMem; + this->values[MEMORY_METER_CACHE] = host->cachedMem; // this->values[MEMORY_METER_AVAILABLE] = "available memory" } void Platform_setSwapValues(Meter* this) { - const ProcessList* pl = this->pl; - this->total = pl->totalSwap; - this->values[SWAP_METER_USED] = pl->usedSwap; + const Machine* host = this->host; + this->total = host->totalSwap; + this->values[SWAP_METER_USED] = host->usedSwap; // this->values[SWAP_METER_CACHE] = "pages that are both in swap and RAM, like SwapCached on linux" // this->values[SWAP_METER_FRONTSWAP] = "pages that are accounted to swap but stored elsewhere, like frontswap on linux" } void Platform_setZfsArcValues(Meter* this) { - const SolarisProcessList* spl = (const SolarisProcessList*) this->pl; + const SolarisProcessList* spl = (const SolarisProcessList*) this->host->pl; ZfsArcMeter_readStats(this, &(spl->zfs)); } void Platform_setZfsCompressedArcValues(Meter* this) { - const SolarisProcessList* spl = (const SolarisProcessList*) this->pl; + const SolarisProcessList* spl = (const SolarisProcessList*) this->host->pl; ZfsCompressedArcMeter_readStats(this, &(spl->zfs)); } diff --git a/solaris/SolarisProcess.c b/solaris/SolarisProcess.c index 840757e7..3b5ea1ae 100644 --- a/solaris/SolarisProcess.c +++ b/solaris/SolarisProcess.c @@ -59,10 +59,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [LWPID] = { .name = "LWPID", .title = "LWPID", .description = "LWP ID", .flags = 0, .pidColumn = true, }, }; -Process* SolarisProcess_new(const Settings* settings) { +Process* SolarisProcess_new(const Machine* host) { SolarisProcess* this = xCalloc(1, sizeof(SolarisProcess)); Object_setClass(this, Class(SolarisProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, host); return &this->super; } diff --git a/solaris/SolarisProcess.h b/solaris/SolarisProcess.h index 13a2bc1f..6bb3ca1c 100644 --- a/solaris/SolarisProcess.h +++ b/solaris/SolarisProcess.h @@ -21,7 +21,7 @@ in the source distribution for its full text. #undef ERR #define ERR (-1) -#include "Settings.h" +#include "Machine.h" typedef struct SolarisProcess_ { @@ -42,7 +42,7 @@ extern const ProcessClass SolarisProcess_class; extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; -Process* SolarisProcess_new(const Settings* settings); +Process* SolarisProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/solaris/SolarisProcessList.c b/solaris/SolarisProcessList.c index 40907989..84991d6e 100644 --- a/solaris/SolarisProcessList.c +++ b/solaris/SolarisProcessList.c @@ -48,6 +48,7 @@ static char* SolarisProcessList_readZoneName(kstat_ctl_t* kd, SolarisProcess* sp } static void SolarisProcessList_updateCPUcount(ProcessList* super) { + Machine* host = super->host; SolarisProcessList* spl = (SolarisProcessList*) super; long int s; bool change = false; @@ -56,7 +57,7 @@ static void SolarisProcessList_updateCPUcount(ProcessList* super) { if (s < 1) CRT_fatalError("Cannot get existing CPU count by sysconf(_SC_NPROCESSORS_CONF)"); - if (s != super->existingCPUs) { + if (s != host->existingCPUs) { if (s == 1) { spl->cpus = xRealloc(spl->cpus, sizeof(CPUData)); spl->cpus[0].online = true; @@ -69,16 +70,16 @@ static void SolarisProcessList_updateCPUcount(ProcessList* super) { } change = true; - super->existingCPUs = s; + host->existingCPUs = s; } s = sysconf(_SC_NPROCESSORS_ONLN); if (s < 1) CRT_fatalError("Cannot get active CPU count by sysconf(_SC_NPROCESSORS_ONLN)"); - if (s != super->activeCPUs) { + if (s != host->activeCPUs) { change = true; - super->activeCPUs = s; + host->activeCPUs = s; } if (change) { @@ -89,10 +90,10 @@ static void SolarisProcessList_updateCPUcount(ProcessList* super) { } } -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { SolarisProcessList* spl = xCalloc(1, sizeof(SolarisProcessList)); ProcessList* pl = (ProcessList*) spl; - ProcessList_init(pl, Class(SolarisProcess), usersTable, pidMatchList, userId); + ProcessList_init(pl, Class(SolarisProcess), host, pidMatchList); spl->kd = kstat_open(); if (!spl->kd) @@ -110,8 +111,8 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui static inline void SolarisProcessList_scanCPUTime(ProcessList* pl) { const SolarisProcessList* spl = (SolarisProcessList*) pl; - unsigned int activeCPUs = pl->activeCPUs; - unsigned int existingCPUs = pl->existingCPUs; + unsigned int activeCPUs = pl->host->activeCPUs; + unsigned int existingCPUs = pl->host->existingCPUs; kstat_t* cpuinfo = NULL; kstat_named_t* idletime = NULL; kstat_named_t* intrtime = NULL; @@ -203,7 +204,9 @@ static inline void SolarisProcessList_scanCPUTime(ProcessList* pl) { } static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) { + Machine* host = pl->host; SolarisProcessList* spl = (SolarisProcessList*) pl; + static kstat_t *meminfo = NULL; int ksrphyserr = -1; kstat_named_t *totalmem_pgs = NULL; @@ -230,23 +233,23 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) { freemem_pgs = kstat_data_lookup_wrapper(meminfo, "freemem"); pages = kstat_data_lookup_wrapper(meminfo, "pagestotal"); - pl->totalMem = totalmem_pgs->value.ui64 * pageSizeKB; - if (pl->totalMem > freemem_pgs->value.ui64 * pageSizeKB) { - pl->usedMem = pl->totalMem - freemem_pgs->value.ui64 * pageSizeKB; + host->totalMem = totalmem_pgs->value.ui64 * pageSizeKB; + if (host->totalMem > freemem_pgs->value.ui64 * pageSizeKB) { + host->usedMem = host->totalMem - freemem_pgs->value.ui64 * pageSizeKB; } else { - pl->usedMem = 0; // This can happen in non-global zone (in theory) + host->usedMem = 0; // This can happen in non-global zone (in theory) } // Not sure how to implement this on Solaris - suggestions welcome! - pl->cachedMem = 0; + host->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) * pageSizeKB; + host->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) * pageSize; - pl->buffersMem = 0; - pl->cachedMem = 0; - pl->usedMem = pl->totalMem - (sysconf(_SC_AVPHYS_PAGES) * pageSize); + host->totalMem = sysconf(_SC_PHYS_PAGES) * pageSize; + host->buffersMem = 0; + host->cachedMem = 0; + host->usedMem = host->totalMem - (sysconf(_SC_AVPHYS_PAGES) * pageSize); } // Part 2 - swap @@ -276,8 +279,8 @@ static inline void SolarisProcessList_scanMemoryInfo(ProcessList* pl) { } free(spathbase); free(sl); - pl->totalSwap = totalswap * pageSizeKB; - pl->usedSwap = pl->totalSwap - (totalfree * pageSizeKB); + host->totalSwap = totalswap * pageSizeKB; + host->usedSwap = host->totalSwap - (totalfree * pageSizeKB); } static inline void SolarisProcessList_scanZfsArcstats(ProcessList* pl) { @@ -389,6 +392,7 @@ static int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo, // Setup process list ProcessList* pl = (ProcessList*) listptr; SolarisProcessList* spl = (SolarisProcessList*) listptr; + Machine* host = pl->super.host; id_t lwpid_real = _lwpsinfo->pr_lwpid; if (lwpid_real > 1023) { @@ -438,7 +442,7 @@ static int SolarisProcessList_walkproc(psinfo_t* _psinfo, lwpsinfo_t* _lwpsinfo, if (proc->st_uid != _psinfo->pr_euid) { proc->st_uid = _psinfo->pr_euid; - proc->user = UsersTable_getRef(pl->usersTable, proc->st_uid); + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); } if (!preExisting) { @@ -551,10 +555,20 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { proc_walk(&SolarisProcessList_walkproc, super, PR_WALK_LWP); } -bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id) { - assert(id < super->existingCPUs); +Machine* Machine_new(UsersTable* usersTable, uid_t userId) { + Machine* this = xCalloc(1, sizeof(Machine)); + Machine_init(this, usersTable, userId); + return this; +} + +void Machine_delete(Machine* host) { + free(host); +} + +bool Machine_isCPUonline(const Machine* host, unsigned int id) { + assert(id < host->existingCPUs); - const SolarisProcessList* spl = (const SolarisProcessList*) super; + const SolarisProcessList* spl = (const SolarisProcessList*) host->pl; - return (super->existingCPUs == 1) ? true : spl->cpus[id + 1].online; + return (super->host->existingCPUs == 1) ? true : spl->cpus[id + 1].online; } diff --git a/solaris/SolarisProcessList.h b/solaris/SolarisProcessList.h index e2f4f683..7cb64167 100644 --- a/solaris/SolarisProcessList.h +++ b/solaris/SolarisProcessList.h @@ -54,12 +54,16 @@ typedef struct SolarisProcessList_ { ZfsArcStats zfs; } SolarisProcessList; -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList); void ProcessList_delete(ProcessList* pl); void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate); -bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id); +Machine* Machine_new(UsersTable* usersTable, uid_t userId); + +bool Machine_isCPUonline(const Machine* host, unsigned int id); + +void Machine_delete(Machine* host); #endif -- cgit v1.2.3