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. --- Action.c | 111 +++++++++++++++++++-------------- Action.h | 11 ++-- Affinity.c | 20 +++--- Affinity.h | 10 +-- AffinityPanel.c | 24 +++---- AffinityPanel.h | 6 +- AvailableMetersPanel.c | 21 ++++--- AvailableMetersPanel.h | 8 +-- CPUMeter.c | 34 +++++----- CategoriesPanel.c | 24 ++++--- CategoriesPanel.h | 9 +-- ClockMeter.c | 4 +- CommandLine.c | 26 ++++---- DateMeter.c | 4 +- DateTimeMeter.c | 4 +- DiskIOMeter.c | 6 +- DynamicMeter.c | 4 +- Header.c | 24 +++---- Header.h | 8 +-- LoadAverageMeter.c | 12 ++-- Machine.c | 60 ++++++++++++++++++ Machine.h | 89 ++++++++++++++++++++++++++ MainPanel.c | 23 ++++--- Makefile.am | 2 + MemorySwapMeter.c | 4 +- Meter.c | 12 ++-- Meter.h | 6 +- NetworkIOMeter.c | 6 +- Process.c | 52 ++++++++------- Process.h | 11 ++-- ProcessList.c | 74 ++++++---------------- ProcessList.h | 49 ++------------- ScreenManager.c | 33 +++++----- ScreenManager.h | 6 +- TasksMeter.c | 9 +-- darwin/DarwinProcess.c | 9 +-- darwin/DarwinProcess.h | 4 +- darwin/DarwinProcessList.c | 31 ++++++--- darwin/DarwinProcessList.h | 8 ++- darwin/Platform.c | 15 ++--- dragonflybsd/DragonFlyBSDProcess.c | 4 +- dragonflybsd/DragonFlyBSDProcess.h | 4 +- dragonflybsd/DragonFlyBSDProcessList.c | 33 ++++++---- dragonflybsd/DragonFlyBSDProcessList.h | 8 ++- dragonflybsd/Platform.c | 11 ++-- freebsd/FreeBSDProcess.c | 4 +- freebsd/FreeBSDProcess.h | 4 +- freebsd/FreeBSDProcessList.c | 75 +++++++++++++--------- freebsd/FreeBSDProcessList.h | 8 ++- freebsd/Platform.c | 31 ++++----- linux/HugePageMeter.c | 2 +- linux/LinuxProcess.c | 6 +- linux/LinuxProcess.h | 4 +- linux/LinuxProcessList.c | 106 ++++++++++++++++++------------- linux/LinuxProcessList.h | 8 ++- linux/Platform.c | 39 ++++++------ netbsd/NetBSDProcess.c | 4 +- netbsd/NetBSDProcess.h | 4 +- netbsd/NetBSDProcessList.c | 64 +++++++++++-------- netbsd/NetBSDProcessList.h | 8 ++- netbsd/Platform.c | 21 ++++--- openbsd/OpenBSDProcess.c | 4 +- openbsd/OpenBSDProcess.h | 4 +- openbsd/OpenBSDProcessList.c | 60 +++++++++++------- openbsd/OpenBSDProcessList.h | 8 ++- openbsd/Platform.c | 21 ++++--- pcp/PCPDynamicColumn.c | 2 +- pcp/PCPProcess.c | 6 +- pcp/PCPProcess.h | 4 +- pcp/PCPProcessList.c | 86 ++++++++++++++----------- pcp/PCPProcessList.h | 8 ++- pcp/Platform.c | 34 +++++----- solaris/Platform.c | 27 ++++---- solaris/SolarisProcess.c | 4 +- solaris/SolarisProcess.h | 4 +- solaris/SolarisProcessList.c | 64 +++++++++++-------- solaris/SolarisProcessList.h | 8 ++- unsupported/UnsupportedProcess.c | 6 +- unsupported/UnsupportedProcess.h | 4 +- unsupported/UnsupportedProcessList.c | 24 ++++--- unsupported/UnsupportedProcessList.h | 8 ++- 81 files changed, 989 insertions(+), 718 deletions(-) create mode 100644 Machine.c create mode 100644 Machine.h diff --git a/Action.c b/Action.c index 73b86062..d6b2a1ce 100644 --- a/Action.c +++ b/Action.c @@ -27,6 +27,7 @@ in the source distribution for its full text. #include "MainPanel.h" #include "OpenFilesScreen.h" #include "Process.h" +#include "ProcessList.h" #include "ProcessLocksScreen.h" #include "ProvideCurses.h" #include "Scheduling.h" @@ -45,9 +46,10 @@ in the source distribution for its full text. Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess) { MainPanel* mainPanel = st->mainPanel; Header* header = st->header; + Machine* host = st->host; int y = ((Panel*)mainPanel)->y; - ScreenManager* scr = ScreenManager_new(header, st->settings, st, false); + ScreenManager* scr = ScreenManager_new(header, host, st, false); scr->allowFocusChange = false; ScreenManager_add(scr, list, x); ScreenManager_add(scr, (Panel*)mainPanel, -1); @@ -55,13 +57,13 @@ Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess) int ch; bool unfollow = false; int pid = followProcess ? MainPanel_selectedPid(mainPanel) : -1; - if (followProcess && header->pl->following == -1) { - header->pl->following = pid; + if (followProcess && host->pl->following == -1) { + host->pl->following = pid; unfollow = true; } ScreenManager_run(scr, &panelFocus, &ch, NULL); if (unfollow) { - header->pl->following = -1; + host->pl->following = -1; } ScreenManager_delete(scr); Panel_move((Panel*)mainPanel, 0, y); @@ -84,12 +86,13 @@ Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess) // ---------------------------------------- static void Action_runSetup(State* st) { - ScreenManager* scr = ScreenManager_new(st->header, st->settings, st, true); - CategoriesPanel_new(scr, st->settings, st->header, st->pl); + const Settings* settings = st->host->settings; + ScreenManager* scr = ScreenManager_new(st->header, st->host, st, true); + CategoriesPanel_new(scr, st->header, st->host); ScreenManager_run(scr, NULL, NULL, "Setup"); ScreenManager_delete(scr); - if (st->settings->changed) { - CRT_setMouse(st->settings->enableMouse); + if (settings->changed) { + CRT_setMouse(settings->enableMouse); Header_writeBackToSettings(st->header); } } @@ -166,7 +169,8 @@ static Htop_Reaction actionSetSortColumn(State* st) { Htop_Reaction reaction = HTOP_OK; Panel* sortPanel = Panel_new(0, 0, 0, 0, Class(ListItem), true, FunctionBar_newEnterEsc("Sort ", "Cancel ")); Panel_setHeader(sortPanel, "Sort by"); - const Settings* settings = st->settings; + Machine* host = st->host; + Settings* settings = host->settings; const ProcessField* fields = settings->ss->fields; Hashtable* dynamicColumns = settings->dynamicColumns; for (int i = 0; fields[i]; i++) { @@ -187,74 +191,80 @@ static Htop_Reaction actionSetSortColumn(State* st) { } const ListItem* field = (const ListItem*) Action_pickFromVector(st, sortPanel, 14, false); if (field) { - reaction |= Action_setSortKey(st->settings, field->key); + reaction |= Action_setSortKey(settings, field->key); } Object_delete(sortPanel); - st->pl->needsSort = true; + host->pl->needsSort = true; return reaction | HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR; } static Htop_Reaction actionSortByPID(State* st) { - return Action_setSortKey(st->settings, PID); + return Action_setSortKey(st->host->settings, PID); } static Htop_Reaction actionSortByMemory(State* st) { - return Action_setSortKey(st->settings, PERCENT_MEM); + return Action_setSortKey(st->host->settings, PERCENT_MEM); } static Htop_Reaction actionSortByCPU(State* st) { - return Action_setSortKey(st->settings, PERCENT_CPU); + return Action_setSortKey(st->host->settings, PERCENT_CPU); } static Htop_Reaction actionSortByTime(State* st) { - return Action_setSortKey(st->settings, TIME); + return Action_setSortKey(st->host->settings, TIME); } static Htop_Reaction actionToggleKernelThreads(State* st) { - st->settings->hideKernelThreads = !st->settings->hideKernelThreads; - st->settings->lastUpdate++; + Settings* settings = st->host->settings; + settings->hideKernelThreads = !settings->hideKernelThreads; + settings->lastUpdate++; return HTOP_RECALCULATE | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING; } static Htop_Reaction actionToggleUserlandThreads(State* st) { - st->settings->hideUserlandThreads = !st->settings->hideUserlandThreads; - st->settings->lastUpdate++; + Settings* settings = st->host->settings; + settings->hideUserlandThreads = !settings->hideUserlandThreads; + settings->lastUpdate++; return HTOP_RECALCULATE | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING; } static Htop_Reaction actionToggleRunningInContainer(State* st) { - st->settings->hideRunningInContainer = !st->settings->hideRunningInContainer; - st->settings->lastUpdate++; + Settings* settings = st->host->settings; + settings->hideRunningInContainer = !settings->hideRunningInContainer; + settings->lastUpdate++; return HTOP_RECALCULATE | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING; } static Htop_Reaction actionToggleProgramPath(State* st) { - st->settings->showProgramPath = !st->settings->showProgramPath; - st->settings->lastUpdate++; + Settings* settings = st->host->settings; + settings->showProgramPath = !settings->showProgramPath; + settings->lastUpdate++; return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING; } static Htop_Reaction actionToggleMergedCommand(State* st) { - st->settings->showMergedCommand = !st->settings->showMergedCommand; - st->settings->lastUpdate++; + Settings* settings = st->host->settings; + settings->showMergedCommand = !settings->showMergedCommand; + settings->lastUpdate++; return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING | HTOP_UPDATE_PANELHDR; } static Htop_Reaction actionToggleTreeView(State* st) { - ScreenSettings* ss = st->settings->ss; + Machine* host = st->host; + ScreenSettings* ss = host->settings->ss; ss->treeView = !ss->treeView; if (!ss->allBranchesCollapsed) - ProcessList_expandTree(st->pl); + ProcessList_expandTree(host->pl); - st->pl->needsSort = true; + host->pl->needsSort = true; return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING | HTOP_REDRAW_BAR | HTOP_UPDATE_PANELHDR; } @@ -265,22 +275,24 @@ static Htop_Reaction actionToggleHideMeters(State* st) { } static Htop_Reaction actionExpandOrCollapseAllBranches(State* st) { - ScreenSettings* ss = st->settings->ss; + Machine* host = st->host; + ScreenSettings* ss = host->settings->ss; if (!ss->treeView) { return HTOP_OK; } ss->allBranchesCollapsed = !ss->allBranchesCollapsed; if (ss->allBranchesCollapsed) - ProcessList_collapseAllBranches(st->pl); + ProcessList_collapseAllBranches(host->pl); else - ProcessList_expandTree(st->pl); + ProcessList_expandTree(host->pl); return HTOP_REFRESH | HTOP_SAVE_SETTINGS; } static Htop_Reaction actionIncFilter(State* st) { + Machine* host = st->host; IncSet* inc = (st->mainPanel)->inc; IncSet_activate(inc, INC_FILTER, (Panel*)st->mainPanel); - st->pl->incFilter = IncSet_filter(inc); + host->pl->incFilter = IncSet_filter(inc); return HTOP_REFRESH | HTOP_KEEP_FOLLOWING; } @@ -307,13 +319,14 @@ static Htop_Reaction actionLowerPriority(State* st) { } static Htop_Reaction actionInvertSortOrder(State* st) { - ScreenSettings_invertSortOrder(st->settings->ss); - st->pl->needsSort = true; + Machine* host = st->host; + ScreenSettings_invertSortOrder(host->settings->ss); + host->pl->needsSort = true; return HTOP_REFRESH | HTOP_SAVE_SETTINGS | HTOP_KEEP_FOLLOWING | HTOP_UPDATE_PANELHDR; } static Htop_Reaction actionExpandOrCollapse(State* st) { - if (!st->settings->ss->treeView) + if (!st->host->settings->ss->treeView) return HTOP_OK; bool changed = expandCollapse((Panel*)st->mainPanel); @@ -321,7 +334,7 @@ static Htop_Reaction actionExpandOrCollapse(State* st) { } static Htop_Reaction actionCollapseIntoParent(State* st) { - if (!st->settings->ss->treeView) { + if (!st->host->settings->ss->treeView) { return HTOP_OK; } bool changed = collapseIntoParent((Panel*)st->mainPanel); @@ -329,11 +342,11 @@ static Htop_Reaction actionCollapseIntoParent(State* st) { } static Htop_Reaction actionExpandCollapseOrSortColumn(State* st) { - return st->settings->ss->treeView ? actionExpandOrCollapse(st) : actionSetSortColumn(st); + return st->host->settings->ss->treeView ? actionExpandOrCollapse(st) : actionSetSortColumn(st); } static Htop_Reaction actionNextScreen(State* st) { - Settings* settings = st->settings; + Settings* settings = st->host->settings; settings->ssIndex++; if (settings->ssIndex == settings->nScreens) { settings->ssIndex = 0; @@ -343,7 +356,7 @@ static Htop_Reaction actionNextScreen(State* st) { } static Htop_Reaction actionPrevScreen(State* st) { - Settings* settings = st->settings; + Settings* settings = st->host->settings; if (settings->ssIndex == 0) { settings->ssIndex = settings->nScreens - 1; } else { @@ -379,7 +392,8 @@ static Htop_Reaction actionSetAffinity(State* st) { if (Settings_isReadonly()) return HTOP_OK; - if (st->pl->activeCPUs == 1) + Machine* host = st->host; + if (host->activeCPUs == 1) return HTOP_OK; #if (defined(HAVE_LIBHWLOC) || defined(HAVE_AFFINITY)) @@ -387,17 +401,17 @@ static Htop_Reaction actionSetAffinity(State* st) { if (!p) return HTOP_OK; - Affinity* affinity1 = Affinity_get(p, st->pl); + Affinity* affinity1 = Affinity_get(p, host); if (!affinity1) return HTOP_OK; int width; - Panel* affinityPanel = AffinityPanel_new(st->pl, affinity1, &width); + Panel* affinityPanel = AffinityPanel_new(host, affinity1, &width); Affinity_delete(affinity1); const void* set = Action_pickFromVector(st, affinityPanel, width, true); if (set) { - Affinity* affinity2 = AffinityPanel_getAffinity(affinityPanel, st->pl); + Affinity* affinity2 = AffinityPanel_getAffinity(affinityPanel, host); bool ok = MainPanel_foreachProcess(st->mainPanel, Affinity_set, (Arg) { .v = affinity2 }, NULL); if (!ok) beep(); @@ -479,16 +493,17 @@ static Htop_Reaction actionKill(State* st) { static Htop_Reaction actionFilterByUser(State* st) { Panel* usersPanel = Panel_new(0, 0, 0, 0, Class(ListItem), true, FunctionBar_newEnterEsc("Show ", "Cancel ")); Panel_setHeader(usersPanel, "Show processes of:"); - UsersTable_foreach(st->ut, addUserToVector, usersPanel); + Machine* host = st->host; + UsersTable_foreach(host->usersTable, addUserToVector, usersPanel); Vector_insertionSort(usersPanel->items); ListItem* allUsers = ListItem_new("All users", -1); Panel_insert(usersPanel, 0, (Object*) allUsers); const ListItem* picked = (ListItem*) Action_pickFromVector(st, usersPanel, 19, false); if (picked) { if (picked == allUsers) { - st->pl->userId = (uid_t)-1; + host->userId = (uid_t)-1; } else { - Action_setUserOnly(ListItem_getRef(picked), &(st->pl->userId)); + Action_setUserOnly(ListItem_getRef(picked), &host->userId); } } Panel_delete((Object*)usersPanel); @@ -496,7 +511,7 @@ static Htop_Reaction actionFilterByUser(State* st) { } Htop_Reaction Action_follow(State* st) { - st->pl->following = MainPanel_selectedPid(st->mainPanel); + st->host->pl->following = MainPanel_selectedPid(st->mainPanel); Panel_setSelectionColor((Panel*)st->mainPanel, PANEL_SELECTION_FOLLOW); return HTOP_KEEP_FOLLOWING; } @@ -660,7 +675,7 @@ static Htop_Reaction actionHelp(State* st) { addbartext(CRT_colors[CPU_NICE_TEXT], "", "low"); addbartext(CRT_colors[CPU_NORMAL], "/", "normal"); addbartext(CRT_colors[CPU_SYSTEM], "/", "kernel"); - if (st->settings->detailedCPUTime) { + if (st->host->settings->detailedCPUTime) { addbartext(CRT_colors[CPU_IRQ], "/", "irq"); addbartext(CRT_colors[CPU_SOFTIRQ], "/", "soft-irq"); addbartext(CRT_colors[CPU_STEAL], "/", "steal"); diff --git a/Action.h b/Action.h index 04d090f8..3540e93e 100644 --- a/Action.h +++ b/Action.h @@ -13,10 +13,10 @@ in the source distribution for its full text. #include #include "Header.h" +#include "Machine.h" #include "Object.h" #include "Panel.h" #include "Process.h" -#include "ProcessList.h" #include "Settings.h" #include "UsersTable.h" @@ -36,9 +36,7 @@ typedef enum { struct MainPanel_; // IWYU pragma: keep typedef struct State_ { - Settings* settings; - UsersTable* ut; - ProcessList* pl; + Machine* host; struct MainPanel_* mainPanel; Header* header; bool pauseUpdate; @@ -47,12 +45,13 @@ typedef struct State_ { } State; static inline bool State_hideFunctionBar(const State* st) { - return st->settings->hideFunctionBar == 2 || (st->settings->hideFunctionBar == 1 && st->hideSelection); + const Settings* settings = st->host->settings; + return settings->hideFunctionBar == 2 || (settings->hideFunctionBar == 1 && st->hideSelection); } typedef Htop_Reaction (*Htop_Action)(State* st); -Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess); +Object* Action_pickFromVector(State* st, Panel* list, int x, bool follow); bool Action_setUserOnly(const char* userName, uid_t* userId); diff --git a/Affinity.c b/Affinity.c index dc6a7fba..f7c597bf 100644 --- a/Affinity.c +++ b/Affinity.c @@ -27,11 +27,11 @@ in the source distribution for its full text. #endif -Affinity* Affinity_new(ProcessList* pl) { +Affinity* Affinity_new(Machine* host) { Affinity* this = xCalloc(1, sizeof(Affinity)); this->size = 8; this->cpus = xCalloc(this->size, sizeof(unsigned int)); - this->pl = pl; + this->host = host; return this; } @@ -52,14 +52,14 @@ void Affinity_add(Affinity* this, unsigned int id) { #if defined(HAVE_LIBHWLOC) -Affinity* Affinity_get(const Process* proc, ProcessList* pl) { +Affinity* Affinity_get(const Process* proc, Machine* host) { hwloc_cpuset_t cpuset = hwloc_bitmap_alloc(); - bool ok = (hwloc_get_proc_cpubind(pl->topology, proc->pid, cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0); + bool ok = (hwloc_get_proc_cpubind(host->topology, proc->pid, cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0); Affinity* affinity = NULL; if (ok) { - affinity = Affinity_new(pl); + affinity = Affinity_new(host); if (hwloc_bitmap_last(cpuset) == -1) { - for (unsigned int i = 0; i < pl->existingCPUs; i++) { + for (unsigned int i = 0; i < host->existingCPUs; i++) { Affinity_add(affinity, i); } } else { @@ -79,21 +79,21 @@ bool Affinity_set(Process* proc, Arg arg) { for (unsigned int i = 0; i < this->used; i++) { hwloc_bitmap_set(cpuset, this->cpus[i]); } - bool ok = (hwloc_set_proc_cpubind(this->pl->topology, proc->pid, cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0); + bool ok = (hwloc_set_proc_cpubind(this->host->topology, proc->pid, cpuset, HTOP_HWLOC_CPUBIND_FLAG) == 0); hwloc_bitmap_free(cpuset); return ok; } #elif defined(HAVE_AFFINITY) -Affinity* Affinity_get(const Process* proc, ProcessList* pl) { +Affinity* Affinity_get(const Process* proc, Machine* host) { cpu_set_t cpuset; bool ok = (sched_getaffinity(proc->pid, sizeof(cpu_set_t), &cpuset) == 0); if (!ok) return NULL; - Affinity* affinity = Affinity_new(pl); - for (unsigned int i = 0; i < pl->existingCPUs; i++) { + Affinity* affinity = Affinity_new(host); + for (unsigned int i = 0; i < host->existingCPUs; i++) { if (CPU_ISSET(i, &cpuset)) { Affinity_add(affinity, i); } diff --git a/Affinity.h b/Affinity.h index 5e7bfe2e..58d9bd73 100644 --- a/Affinity.h +++ b/Affinity.h @@ -3,14 +3,14 @@ /* htop - Affinity.h (C) 2004-2011 Hisham H. Muhammad -(C) 2020 Red Hat, Inc. All Rights Reserved. +(C) 2020,2023 Red Hat, Inc. All Rights Reserved. Released under the GNU GPLv2+, see the COPYING file in the source distribution for its full text. */ #include "config.h" // IWYU pragma: keep -#include "ProcessList.h" +#include "Machine.h" #if defined(HAVE_LIBHWLOC) || defined(HAVE_AFFINITY) #include @@ -26,13 +26,13 @@ in the source distribution for its full text. typedef struct Affinity_ { - ProcessList* pl; + Machine* host; unsigned int size; unsigned int used; unsigned int* cpus; } Affinity; -Affinity* Affinity_new(ProcessList* pl); +Affinity* Affinity_new(Machine* host); void Affinity_delete(Affinity* this); @@ -40,7 +40,7 @@ void Affinity_add(Affinity* this, unsigned int id); #if defined(HAVE_LIBHWLOC) || defined(HAVE_AFFINITY) -Affinity* Affinity_get(const Process* proc, ProcessList* pl); +Affinity* Affinity_get(const Process* proc, Machine* host); bool Affinity_set(Process* proc, Arg arg); diff --git a/AffinityPanel.c b/AffinityPanel.c index b7243971..1214a84f 100644 --- a/AffinityPanel.c +++ b/AffinityPanel.c @@ -122,7 +122,7 @@ static MaskItem* MaskItem_newSingleton(const char* text, int cpu, bool isSet) { typedef struct AffinityPanel_ { Panel super; - ProcessList* pl; + Machine* host; bool topoView; Vector* cpuids; unsigned width; @@ -272,7 +272,7 @@ static MaskItem* AffinityPanel_addObject(AffinityPanel* this, hwloc_obj_t obj, u char buf[64], indent_buf[left + 1]; if (obj->type == HWLOC_OBJ_PU) { - index = Settings_cpuId(this->pl->settings, obj->os_index); + index = Settings_cpuId(this->host->settings, obj->os_index); type_name = "CPU"; index_prefix = ""; } @@ -357,12 +357,12 @@ static const char* const AffinityPanelFunctions[] = { static const char* const AffinityPanelKeys[] = {"Enter", "Esc", "F1", "F2", "F3"}; static const int AffinityPanelEvents[] = {13, 27, KEY_F(1), KEY_F(2), KEY_F(3)}; -Panel* AffinityPanel_new(ProcessList* pl, const Affinity* affinity, int* width) { +Panel* AffinityPanel_new(Machine* host, const Affinity* affinity, int* width) { AffinityPanel* this = AllocThis(AffinityPanel); Panel* super = (Panel*) this; Panel_init(super, 1, 1, 1, 1, Class(MaskItem), false, FunctionBar_new(AffinityPanelFunctions, AffinityPanelKeys, AffinityPanelEvents)); - this->pl = pl; + this->host = host; /* defaults to 15, this also includes the gap between the panels, * but this will be added by the caller */ this->width = 14; @@ -370,25 +370,25 @@ Panel* AffinityPanel_new(ProcessList* pl, const Affinity* affinity, int* width) this->cpuids = Vector_new(Class(MaskItem), true, DEFAULT_SIZE); #ifdef HAVE_LIBHWLOC - this->topoView = pl->settings->topologyAffinity; + this->topoView = host->settings->topologyAffinity; #else this->topoView = false; #endif #ifdef HAVE_LIBHWLOC - this->allCpuset = hwloc_topology_get_complete_cpuset(pl->topology); + this->allCpuset = hwloc_topology_get_complete_cpuset(host->topology); this->workCpuset = hwloc_bitmap_alloc(); #endif Panel_setHeader(super, "Use CPUs:"); unsigned int curCpu = 0; - for (unsigned int i = 0; i < pl->existingCPUs; i++) { - if (!ProcessList_isCPUonline(this->pl, i)) + for (unsigned int i = 0; i < host->existingCPUs; i++) { + if (!Machine_isCPUonline(host, i)) continue; char number[16]; - xSnprintf(number, 9, "CPU %d", Settings_cpuId(pl->settings, i)); + xSnprintf(number, 9, "CPU %d", Settings_cpuId(host->settings, i)); unsigned cpu_width = 4 + strlen(number); if (cpu_width > this->width) { this->width = cpu_width; @@ -408,7 +408,7 @@ Panel* AffinityPanel_new(ProcessList* pl, const Affinity* affinity, int* width) } #ifdef HAVE_LIBHWLOC - this->topoRoot = AffinityPanel_buildTopology(this, hwloc_get_root_obj(pl->topology), 0, NULL); + this->topoRoot = AffinityPanel_buildTopology(this, hwloc_get_root_obj(host->topology), 0, NULL); #endif if (width) { @@ -420,9 +420,9 @@ Panel* AffinityPanel_new(ProcessList* pl, const Affinity* affinity, int* width) return super; } -Affinity* AffinityPanel_getAffinity(Panel* super, ProcessList* pl) { +Affinity* AffinityPanel_getAffinity(Panel* super, Machine* host) { const AffinityPanel* this = (AffinityPanel*) super; - Affinity* affinity = Affinity_new(pl); + Affinity* affinity = Affinity_new(host); #ifdef HAVE_LIBHWLOC int i; diff --git a/AffinityPanel.h b/AffinityPanel.h index 87b1b850..f5b97b93 100644 --- a/AffinityPanel.h +++ b/AffinityPanel.h @@ -8,14 +8,14 @@ in the source distribution for its full text. */ #include "Affinity.h" +#include "Machine.h" #include "Panel.h" -#include "ProcessList.h" extern const PanelClass AffinityPanel_class; -Panel* AffinityPanel_new(ProcessList* pl, const Affinity* affinity, int* width); +Panel* AffinityPanel_new(Machine* host, const Affinity* affinity, int* width); -Affinity* AffinityPanel_getAffinity(Panel* super, ProcessList* pl); +Affinity* AffinityPanel_getAffinity(Panel* super, Machine* host); #endif diff --git a/AvailableMetersPanel.c b/AvailableMetersPanel.c index aa6d7795..de1dd211 100644 --- a/AvailableMetersPanel.c +++ b/AvailableMetersPanel.c @@ -78,8 +78,9 @@ static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) { } } if (update) { - this->settings->changed = true; - this->settings->lastUpdate++; + Settings* settings = this->host->settings; + settings->changed = true; + settings->lastUpdate++; Header_calculateHeight(header); Header_updateData(header); Header_draw(header); @@ -97,12 +98,12 @@ const PanelClass AvailableMetersPanel_class = { }; // Handle (&CPUMeter_class) entries in the AvailableMetersPanel -static void AvailableMetersPanel_addCPUMeters(Panel* super, const MeterClass* type, const ProcessList* pl) { - if (pl->existingCPUs > 1) { +static void AvailableMetersPanel_addCPUMeters(Panel* super, const MeterClass* type, const Machine* host) { + if (host->existingCPUs > 1) { Panel_add(super, (Object*) ListItem_new("CPU average", 0)); - for (unsigned int i = 1; i <= pl->existingCPUs; i++) { + for (unsigned int i = 1; i <= host->existingCPUs; i++) { char buffer[50]; - xSnprintf(buffer, sizeof(buffer), "%s %d", type->uiName, Settings_cpuId(pl->settings, i - 1)); + xSnprintf(buffer, sizeof(buffer), "%s %d", type->uiName, Settings_cpuId(host->settings, i - 1)); Panel_add(super, (Object*) ListItem_new(buffer, i)); } } else { @@ -141,13 +142,13 @@ static void AvailableMetersPanel_addPlatformMeter(Panel* super, const MeterClass Panel_add(super, (Object*) ListItem_new(label, offset << 16)); } -AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* header, size_t columns, MetersPanel** meterPanels, ScreenManager* scr, const ProcessList* pl) { +AvailableMetersPanel* AvailableMetersPanel_new(Machine* host, Header* header, size_t columns, MetersPanel** meterPanels, ScreenManager* scr) { AvailableMetersPanel* this = AllocThis(AvailableMetersPanel); Panel* super = (Panel*) this; FunctionBar* fuBar = FunctionBar_newEnterEsc("Add ", "Done "); Panel_init(super, 1, 1, 1, 1, Class(ListItem), true, fuBar); - this->settings = settings; + this->host = host; this->header = header; this->columns = columns; this->meterPanels = meterPanels; @@ -162,11 +163,11 @@ AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* heade const MeterClass* type = Platform_meterTypes[i]; assert(type != &CPUMeter_class); if (type == &DynamicMeter_class) - AvailableMetersPanel_addDynamicMeters(super, settings, i); + AvailableMetersPanel_addDynamicMeters(super, host->settings, i); else AvailableMetersPanel_addPlatformMeter(super, type, i); } - AvailableMetersPanel_addCPUMeters(super, &CPUMeter_class, pl); + AvailableMetersPanel_addCPUMeters(super, &CPUMeter_class, host); return this; } diff --git a/AvailableMetersPanel.h b/AvailableMetersPanel.h index 1c0555af..fad1e6e8 100644 --- a/AvailableMetersPanel.h +++ b/AvailableMetersPanel.h @@ -10,18 +10,16 @@ in the source distribution for its full text. #include #include "Header.h" +#include "Machine.h" #include "MetersPanel.h" #include "Panel.h" -#include "ProcessList.h" #include "ScreenManager.h" -#include "Settings.h" typedef struct AvailableMetersPanel_ { Panel super; ScreenManager* scr; - - Settings* settings; + Machine* host; Header* header; size_t columns; MetersPanel** meterPanels; @@ -29,6 +27,6 @@ typedef struct AvailableMetersPanel_ { extern const PanelClass AvailableMetersPanel_class; -AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* header, size_t columns, MetersPanel** meterPanels, ScreenManager* scr, const ProcessList* pl); +AvailableMetersPanel* AvailableMetersPanel_new(Machine* host, Header* header, size_t columns, MetersPanel** meterPanels, ScreenManager* scr); #endif diff --git a/CPUMeter.c b/CPUMeter.c index ba005956..a946aa7d 100644 --- a/CPUMeter.c +++ b/CPUMeter.c @@ -40,11 +40,12 @@ typedef struct CPUMeterData_ { static void CPUMeter_init(Meter* this) { unsigned int cpu = this->param; + const Machine* host = this->host; if (cpu == 0) { Meter_setCaption(this, "Avg"); - } else if (this->pl->activeCPUs > 1) { + } else if (host->activeCPUs > 1) { char caption[10]; - xSnprintf(caption, sizeof(caption), "%3u", Settings_cpuId(this->pl->settings, cpu - 1)); + xSnprintf(caption, sizeof(caption), "%3u", Settings_cpuId(host->settings, cpu - 1)); Meter_setCaption(this, caption); } } @@ -60,8 +61,11 @@ static void CPUMeter_getUiName(const Meter* this, char* buffer, size_t length) { static void CPUMeter_updateValues(Meter* this) { memset(this->values, 0, sizeof(double) * CPU_METER_ITEMCOUNT); + const Machine* host = this->host; + const Settings* settings = host->settings; + unsigned int cpu = this->param; - if (cpu > this->pl->existingCPUs) { + if (cpu > host->existingCPUs) { xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "absent"); return; } @@ -76,11 +80,11 @@ static void CPUMeter_updateValues(Meter* this) { char cpuFrequencyBuffer[16] = { 0 }; char cpuTemperatureBuffer[16] = { 0 }; - if (this->pl->settings->showCPUUsage) { + if (settings->showCPUUsage) { xSnprintf(cpuUsageBuffer, sizeof(cpuUsageBuffer), "%.1f%%", percent); } - if (this->pl->settings->showCPUFrequency) { + if (settings->showCPUFrequency) { double cpuFrequency = this->values[CPU_METER_FREQUENCY]; if (isnan(cpuFrequency)) { xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "N/A"); @@ -90,11 +94,11 @@ static void CPUMeter_updateValues(Meter* this) { } #ifdef BUILD_WITH_CPU_TEMP - if (this->pl->settings->showCPUTemperature) { + if (settings->showCPUTemperature) { double cpuTemperature = this->values[CPU_METER_TEMPERATURE]; if (isnan(cpuTemperature)) xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "N/A"); - else if (this->pl->settings->degreeFahrenheit) + else if (settings->degreeFahrenheit) xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%3d%sF", (int)(cpuTemperature * 9 / 5 + 32), CRT_degreeSign); else xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%d%sC", (int)cpuTemperature, CRT_degreeSign); @@ -113,8 +117,10 @@ static void CPUMeter_display(const Object* cast, RichString* out) { char buffer[50]; int len; const Meter* this = (const Meter*)cast; + const Machine* host = this->host; + const Settings* settings = host->settings; - if (this->param > this->pl->existingCPUs) { + if (this->param > host->existingCPUs) { RichString_appendAscii(out, CRT_colors[METER_SHADOW], " absent"); return; } @@ -127,7 +133,7 @@ static void CPUMeter_display(const Object* cast, RichString* out) { len = xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_NORMAL]); RichString_appendAscii(out, CRT_colors[METER_TEXT], ":"); RichString_appendnAscii(out, CRT_colors[CPU_NORMAL], buffer, len); - if (this->pl->settings->detailedCPUTime) { + if (settings->detailedCPUTime) { len = xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_KERNEL]); RichString_appendAscii(out, CRT_colors[METER_TEXT], "sy:"); RichString_appendnAscii(out, CRT_colors[CPU_SYSTEM], buffer, len); @@ -167,7 +173,7 @@ static void CPUMeter_display(const Object* cast, RichString* out) { } } - if (this->pl->settings->showCPUFrequency) { + if (settings->showCPUFrequency) { char cpuFrequencyBuffer[10]; double cpuFrequency = this->values[CPU_METER_FREQUENCY]; if (isnan(cpuFrequency)) { @@ -180,12 +186,12 @@ static void CPUMeter_display(const Object* cast, RichString* out) { } #ifdef BUILD_WITH_CPU_TEMP - if (this->pl->settings->showCPUTemperature) { + if (settings->showCPUTemperature) { char cpuTemperatureBuffer[10]; double cpuTemperature = this->values[CPU_METER_TEMPERATURE]; if (isnan(cpuTemperature)) { len = xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "N/A"); - } else if (this->pl->settings->degreeFahrenheit) { + } else if (settings->degreeFahrenheit) { len = xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%5.1f%sF", cpuTemperature * 9 / 5 + 32, CRT_degreeSign); } else { len = xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%5.1f%sC", cpuTemperature, CRT_degreeSign); @@ -226,7 +232,7 @@ static void AllCPUsMeter_updateValues(Meter* this) { } static void CPUMeterCommonInit(Meter* this, int ncol) { - unsigned int cpus = this->pl->existingCPUs; + unsigned int cpus = this->host->existingCPUs; CPUMeterData* data = this->meterData; if (!data) { data = this->meterData = xMalloc(sizeof(CPUMeterData)); @@ -238,7 +244,7 @@ static void CPUMeterCommonInit(Meter* this, int ncol) { AllCPUsMeter_getRange(this, &start, &count); for (int i = 0; i < count; i++) { if (!meters[i]) - meters[i] = Meter_new(this->pl, start + i + 1, (const MeterClass*) Class(CPUMeter)); + meters[i] = Meter_new(this->host, start + i + 1, (const MeterClass*) Class(CPUMeter)); Meter_init(meters[i]); } diff --git a/CategoriesPanel.c b/CategoriesPanel.c index 6e905ce9..ba7ee503 100644 --- a/CategoriesPanel.c +++ b/CategoriesPanel.c @@ -41,11 +41,12 @@ static void CategoriesPanel_delete(Object* object) { static void CategoriesPanel_makeMetersPage(CategoriesPanel* this) { size_t columns = HeaderLayout_getColumns(this->scr->header->headerLayout); MetersPanel** meterPanels = xMallocArray(columns, sizeof(MetersPanel*)); + Settings* settings = this->host->settings; for (size_t i = 0; i < columns; i++) { char titleBuffer[32]; xSnprintf(titleBuffer, sizeof(titleBuffer), "Column %zu", i + 1); - meterPanels[i] = MetersPanel_new(this->settings, titleBuffer, this->header->columns[i], this->scr); + meterPanels[i] = MetersPanel_new(settings, titleBuffer, this->header->columns[i], this->scr); if (i != 0) { meterPanels[i]->leftNeighbor = meterPanels[i - 1]; @@ -55,31 +56,35 @@ static void CategoriesPanel_makeMetersPage(CategoriesPanel* this) { ScreenManager_add(this->scr, (Panel*) meterPanels[i], 20); } - Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->settings, this->header, columns, meterPanels, this->scr, this->pl); + Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->host, this->header, columns, meterPanels, this->scr); ScreenManager_add(this->scr, availableMeters, -1); } static void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) { - Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(this->settings, this->scr); + Settings* settings = this->host->settings; + Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(settings, this->scr); ScreenManager_add(this->scr, displayOptions, -1); } static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) { - Panel* colors = (Panel*) ColorsPanel_new(this->settings); + Settings* settings = this->host->settings; + Panel* colors = (Panel*) ColorsPanel_new(settings); ScreenManager_add(this->scr, colors, -1); } static void CategoriesPanel_makeScreensPage(CategoriesPanel* this) { - Panel* screens = (Panel*) ScreensPanel_new(this->settings); + Settings* settings = this->host->settings; + Panel* screens = (Panel*) ScreensPanel_new(settings); Panel* columns = (Panel*) ((ScreensPanel*)screens)->columns; - Panel* availableColumns = (Panel*) AvailableColumnsPanel_new(columns, this->settings->dynamicColumns); + Panel* availableColumns = (Panel*) AvailableColumnsPanel_new(columns, settings->dynamicColumns); ScreenManager_add(this->scr, screens, 20); ScreenManager_add(this->scr, columns, 20); ScreenManager_add(this->scr, availableColumns, -1); } static void CategoriesPanel_makeHeaderOptionsPage(CategoriesPanel* this) { - Panel* colors = (Panel*) HeaderOptionsPanel_new(this->settings, this->scr); + Settings* settings = this->host->settings; + Panel* colors = (Panel*) HeaderOptionsPanel_new(settings, this->scr); ScreenManager_add(this->scr, colors, -1); } @@ -149,16 +154,15 @@ const PanelClass CategoriesPanel_class = { .eventHandler = CategoriesPanel_eventHandler }; -CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Settings* settings, Header* header, ProcessList* pl) { +CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Header* header, Machine* host) { CategoriesPanel* this = AllocThis(CategoriesPanel); Panel* super = (Panel*) this; FunctionBar* fuBar = FunctionBar_new(CategoriesFunctions, NULL, NULL); Panel_init(super, 1, 1, 1, 1, Class(ListItem), true, fuBar); this->scr = scr; - this->settings = settings; + this->host = host; this->header = header; - this->pl = pl; Panel_setHeader(super, "Categories"); for (size_t i = 0; i < ARRAYSIZE(categoriesPanelPages); i++) Panel_add(super, (Object*) ListItem_new(categoriesPanelPages[i].name, 0)); diff --git a/CategoriesPanel.h b/CategoriesPanel.h index 825cd069..1f50b8a0 100644 --- a/CategoriesPanel.h +++ b/CategoriesPanel.h @@ -8,23 +8,20 @@ in the source distribution for its full text. */ #include "Header.h" +#include "Machine.h" #include "Panel.h" -#include "ProcessList.h" #include "ScreenManager.h" -#include "Settings.h" typedef struct CategoriesPanel_ { Panel super; ScreenManager* scr; - - Settings* settings; + Machine* host; Header* header; - ProcessList* pl; } CategoriesPanel; extern const PanelClass CategoriesPanel_class; -CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Settings* settings, Header* header, ProcessList* pl); +CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Header* header, Machine* host); #endif diff --git a/ClockMeter.c b/ClockMeter.c index 8e3b66e6..ee712ae2 100644 --- a/ClockMeter.c +++ b/ClockMeter.c @@ -22,10 +22,10 @@ static const int ClockMeter_attributes[] = { }; static void ClockMeter_updateValues(Meter* this) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; struct tm result; - const struct tm* lt = localtime_r(&pl->realtime.tv_sec, &result); + const struct tm* lt = localtime_r(&host->realtime.tv_sec, &result); this->values[0] = lt->tm_hour * 60 + lt->tm_min; strftime(this->txtBuffer, sizeof(this->txtBuffer), "%H:%M:%S", lt); } diff --git a/CommandLine.c b/CommandLine.c index 9dd02dfc..9e2018ef 100644 --- a/CommandLine.c +++ b/CommandLine.c @@ -277,18 +277,18 @@ static CommandLineStatus parseArguments(int argc, char** argv, CommandLineSettin return STATUS_OK; } -static void CommandLine_delay(ProcessList* pl, unsigned long millisec) { +static void CommandLine_delay(Machine* host, unsigned long millisec) { struct timespec req = { .tv_sec = 0, .tv_nsec = millisec * 1000000L }; while (nanosleep(&req, &req) == -1) continue; - Platform_gettime_realtime(&pl->realtime, &pl->realtimeMs); + Platform_gettime_realtime(&host->realtime, &host->realtimeMs); } static void setCommFilter(State* state, char** commFilter) { - ProcessList* pl = state->pl; + ProcessList* pl = state->host->pl; IncSet* inc = state->mainPanel->inc; IncSet_setFilter(inc, *commFilter); @@ -327,13 +327,14 @@ int CommandLine_run(int argc, char** argv) { if (!dc) dc = Hashtable_new(0, true); - ProcessList* pl = ProcessList_new(ut, flags.pidMatchList, flags.userId); + Machine* host = Machine_new(ut, flags.userId); + ProcessList* pl = ProcessList_new(host, flags.pidMatchList); + Settings* settings = Settings_new(host->activeCPUs, dm, dc); - Settings* settings = Settings_new(pl->activeCPUs, dm, dc); - pl->settings = settings; - - Header* header = Header_new(pl, settings, 2); + host->settings = settings; + Machine_addList(host, pl); + Header* header = Header_new(host, 2); Header_populateFromSettings(header); if (flags.delay != -1) @@ -367,9 +368,7 @@ int CommandLine_run(int argc, char** argv) { MainPanel_updateLabels(panel, settings->ss->treeView, flags.commFilter); State state = { - .settings = settings, - .ut = ut, - .pl = pl, + .host = host, .mainPanel = panel, .header = header, .pauseUpdate = false, @@ -381,11 +380,11 @@ int CommandLine_run(int argc, char** argv) { if (flags.commFilter) setCommFilter(&state, &(flags.commFilter)); - ScreenManager* scr = ScreenManager_new(header, settings, &state, true); + ScreenManager* scr = ScreenManager_new(header, host, &state, true); ScreenManager_add(scr, (Panel*) panel, -1); ProcessList_scan(pl, false); - CommandLine_delay(pl, 75); + CommandLine_delay(host, 75); ProcessList_scan(pl, false); if (settings->ss->allBranchesCollapsed) @@ -405,6 +404,7 @@ int CommandLine_run(int argc, char** argv) { Header_delete(header); ProcessList_delete(pl); + Machine_delete(host); ScreenManager_delete(scr); MetersPanel_cleanup(); diff --git a/DateMeter.c b/DateMeter.c index 96285963..b38f43b0 100644 --- a/DateMeter.c +++ b/DateMeter.c @@ -22,10 +22,10 @@ static const int DateMeter_attributes[] = { }; static void DateMeter_updateValues(Meter* this) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; struct tm result; - const struct tm* lt = localtime_r(&pl->realtime.tv_sec, &result); + const struct tm* lt = localtime_r(&host->realtime.tv_sec, &result); this->values[0] = lt->tm_yday; int year = lt->tm_year + 1900; if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) { diff --git a/DateTimeMeter.c b/DateTimeMeter.c index 1044ff39..d46f3cb2 100644 --- a/DateTimeMeter.c +++ b/DateTimeMeter.c @@ -22,10 +22,10 @@ static const int DateTimeMeter_attributes[] = { }; static void DateTimeMeter_updateValues(Meter* this) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; struct tm result; - const struct tm* lt = localtime_r(&pl->realtime.tv_sec, &result); + const struct tm* lt = localtime_r(&host->realtime.tv_sec, &result); int year = lt->tm_year + 1900; if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) { this->total = 366; diff --git a/DiskIOMeter.c b/DiskIOMeter.c index adab8f73..545ec008 100644 --- a/DiskIOMeter.c +++ b/DiskIOMeter.c @@ -32,10 +32,10 @@ static uint32_t cached_write_diff; static double cached_utilisation_diff; static void DiskIOMeter_updateValues(Meter* this) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; static uint64_t cached_last_update; - uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update; + uint64_t passedTimeInMs = host->realtimeMs - cached_last_update; /* update only every 500ms to have a sane span for rate calculation */ if (passedTimeInMs > 500) { @@ -55,7 +55,7 @@ static void DiskIOMeter_updateValues(Meter* this) { status = RATESTATUS_DATA; } - cached_last_update = pl->realtimeMs; + cached_last_update = host->realtimeMs; if (status == RATESTATUS_NODATA) { xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "no data"); diff --git a/DynamicMeter.c b/DynamicMeter.c index 40c06bb6..82e73a92 100644 --- a/DynamicMeter.c +++ b/DynamicMeter.c @@ -88,7 +88,7 @@ static void DynamicMeter_display(const Object* cast, RichString* out) { } static const char* DynamicMeter_getCaption(const Meter* this) { - const Settings* settings = this->pl->settings; + const Settings* settings = this->host->settings; const DynamicMeter* meter = Hashtable_get(settings->dynamicMeters, this->param); if (meter) return meter->caption ? meter->caption : meter->name; @@ -96,7 +96,7 @@ static const char* DynamicMeter_getCaption(const Meter* this) { } static void DynamicMeter_getUiName(const Meter* this, char* name, size_t length) { - const Settings* settings = this->pl->settings; + const Settings* settings = this->host->settings; const DynamicMeter* meter = Hashtable_get(settings->dynamicMeters, this->param); if (meter) { const char* uiName = meter->caption; diff --git a/Header.c b/Header.c index b2fc56cc..3fafc70a 100644 --- a/Header.c +++ b/Header.c @@ -25,12 +25,11 @@ in the source distribution for its full text. #include "XUtils.h" -Header* Header_new(ProcessList* pl, Settings* settings, HeaderLayout hLayout) { +Header* Header_new(Machine* host, HeaderLayout hLayout) { Header* this = xCalloc(1, sizeof(Header)); this->columns = xMallocArray(HeaderLayout_getColumns(hLayout), sizeof(Vector*)); - this->settings = settings; - this->pl = pl; this->headerLayout = hLayout; + this->host = host; Header_forEachColumn(this, i) { this->columns[i] = Vector_new(Class(Meter), true, DEFAULT_SIZE); @@ -92,7 +91,8 @@ static void Header_addMeterByName(Header* this, const char* name, MeterModeId mo if ((end = strrchr(dynamic, ')')) == NULL) return; // htoprc parse failure *end = '\0'; - if (!DynamicMeter_search(this->settings->dynamicMeters, dynamic, ¶m)) + const Settings* settings = this->host->settings; + if (!DynamicMeter_search(settings->dynamicMeters, dynamic, ¶m)) return; // name lookup failure } else { param = 0; @@ -105,7 +105,7 @@ static void Header_addMeterByName(Header* this, const char* name, MeterModeId mo for (const MeterClass* const* type = Platform_meterTypes; *type; type++) { if (0 == strncmp(name, (*type)->name, nameLen) && (*type)->name[nameLen] == '\0') { - Meter* meter = Meter_new(this->pl, param, *type); + Meter* meter = Meter_new(this->host, param, *type); if (mode != 0) { Meter_setMode(meter, mode); } @@ -116,10 +116,11 @@ static void Header_addMeterByName(Header* this, const char* name, MeterModeId mo } void Header_populateFromSettings(Header* this) { - Header_setLayout(this, this->settings->hLayout); + const Settings* settings = this->host->settings; + Header_setLayout(this, settings->hLayout); Header_forEachColumn(this, col) { - const MeterColumnSetting* colSettings = &this->settings->hColumns[col]; + const MeterColumnSetting* colSettings = &settings->hColumns[col]; Vector_prune(this->columns[col]); for (size_t i = 0; i < colSettings->len; i++) { Header_addMeterByName(this, colSettings->names[i], colSettings->modes[i], col); @@ -130,7 +131,7 @@ void Header_populateFromSettings(Header* this) { } void Header_writeBackToSettings(const Header* this) { - Settings* settings = this->settings; + Settings* settings = this->host->settings; Settings_setHeaderLayout(settings, this->headerLayout); Header_forEachColumn(this, col) { @@ -172,7 +173,7 @@ Meter* Header_addMeterByClass(Header* this, const MeterClass* type, unsigned int Vector* meters = this->columns[column]; - Meter* meter = Meter_new(this->pl, param, type); + Meter* meter = Meter_new(this->host, param, type); Vector_add(meters, meter); return meter; } @@ -274,7 +275,8 @@ static int calcColumnWidthCount(const Header* this, const Meter* curMeter, const } int Header_calculateHeight(Header* this) { - const int pad = this->settings->headerMargin ? 2 : 0; + const Settings* settings = this->host->settings; + const int pad = settings->headerMargin ? 2 : 0; int maxHeight = pad; Header_forEachColumn(this, col) { @@ -295,7 +297,7 @@ int Header_calculateHeight(Header* this) { this->pad = pad; } - if (this->settings->screenTabs) { + if (settings->screenTabs) { maxHeight++; } diff --git a/Header.h b/Header.h index 954d434c..add4d76b 100644 --- a/Header.h +++ b/Header.h @@ -8,16 +8,14 @@ in the source distribution for its full text. */ #include "HeaderLayout.h" +#include "Machine.h" #include "Meter.h" -#include "ProcessList.h" -#include "Settings.h" #include "Vector.h" typedef struct Header_ { Vector** columns; - Settings* settings; - ProcessList* pl; + Machine* host; HeaderLayout headerLayout; int pad; int height; @@ -25,7 +23,7 @@ typedef struct Header_ { #define Header_forEachColumn(this_, i_) for (size_t (i_)=0, H_fEC_numColumns_ = HeaderLayout_getColumns((this_)->headerLayout); (i_) < H_fEC_numColumns_; ++(i_)) -Header* Header_new(ProcessList* pl, Settings* settings, HeaderLayout hLayout); +Header* Header_new(Machine *host, HeaderLayout hLayout); void Header_delete(Header* this); diff --git a/LoadAverageMeter.c b/LoadAverageMeter.c index 3fe3d900..0beae04b 100644 --- a/LoadAverageMeter.c +++ b/LoadAverageMeter.c @@ -47,12 +47,12 @@ static void LoadAverageMeter_updateValues(Meter* this) { if (this->values[0] < 1.0) { this->curAttributes = OK_attributes; this->total = 1.0; - } else if (this->values[0] < this->pl->activeCPUs) { + } else if (this->values[0] < this->host->activeCPUs) { this->curAttributes = Medium_attributes; - this->total = this->pl->activeCPUs; + this->total = this->host->activeCPUs; } else { this->curAttributes = High_attributes; - this->total = 2 * this->pl->activeCPUs; + this->total = 2 * this->host->activeCPUs; } xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.2f/%.2f/%.2f", this->values[0], this->values[1], this->values[2]); @@ -79,12 +79,12 @@ static void LoadMeter_updateValues(Meter* this) { if (this->values[0] < 1.0) { this->curAttributes = OK_attributes; this->total = 1.0; - } else if (this->values[0] < this->pl->activeCPUs) { + } else if (this->values[0] < this->host->activeCPUs) { this->curAttributes = Medium_attributes; - this->total = this->pl->activeCPUs; + this->total = this->host->activeCPUs; } else { this->curAttributes = High_attributes; - this->total = 2 * this->pl->activeCPUs; + this->total = 2 * this->host->activeCPUs; } xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%.2f", this->values[0]); diff --git a/Machine.c b/Machine.c new file mode 100644 index 00000000..63a996ef --- /dev/null +++ b/Machine.c @@ -0,0 +1,60 @@ +/* +htop - Machine.c +(C) 2023 Red Hat, Inc. +(C) 2004,2005 Hisham H. Muhammad +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include "Machine.h" + +#include +#include + +#include "CRT.h" +#include "Hashtable.h" +#include "Macros.h" +#include "Platform.h" +#include "XUtils.h" + + +void Machine_init(Machine* this, UsersTable* usersTable, uid_t userId) { + this->usersTable = usersTable; + this->userId = userId; + + // always maintain valid realtime timestamps + Platform_gettime_realtime(&this->realtime, &this->realtimeMs); + +#ifdef HAVE_LIBHWLOC + this->topologyOk = false; + if (hwloc_topology_init(&this->topology) == 0) { + this->topologyOk = + #if HWLOC_API_VERSION < 0x00020000 + /* try to ignore the top-level machine object type */ + 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_MACHINE) && + /* ignore caches, which don't add structure */ + 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CORE) && + 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CACHE) && + 0 == hwloc_topology_set_flags(this->topology, HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) && + #else + 0 == hwloc_topology_set_all_types_filter(this->topology, HWLOC_TYPE_FILTER_KEEP_STRUCTURE) && + #endif + 0 == hwloc_topology_load(this->topology); + } +#endif +} + +void Machine_done(Machine* this) { +#ifdef HAVE_LIBHWLOC + if (this->topologyOk) { + hwloc_topology_destroy(this->topology); + } +#else + (void)this; +#endif +} + +void Machine_addList(Machine* this, struct ProcessList_ *pl) { + // currently only process lists are supported + this->pl = pl; +} diff --git a/Machine.h b/Machine.h new file mode 100644 index 00000000..3683701a --- /dev/null +++ b/Machine.h @@ -0,0 +1,89 @@ +#ifndef HEADER_Machine +#define HEADER_Machine +/* +htop - Machine.h +(C) 2023 Red Hat, Inc. +(C) 2004,2005 Hisham H. Muhammad +Released under the GNU GPLv2+, see the COPYING file +in the source distribution for its full text. +*/ + +#include "config.h" // IWYU pragma: keep + +#include +#include +#include +#include +#include + +#include "Hashtable.h" +#include "Settings.h" +#include "UsersTable.h" +#include "Vector.h" + +#ifdef HAVE_LIBHWLOC +#include +#endif + + +#ifndef MAX_NAME +#define MAX_NAME 128 +#endif + +#ifndef MAX_READ +#define MAX_READ 2048 +#endif + +typedef unsigned long long int memory_t; +#define MEMORY_MAX ULLONG_MAX + +struct ProcessList_; + +typedef struct Machine_ { + Settings* settings; + + struct timeval realtime; /* time of the current sample */ + uint64_t realtimeMs; /* current time in milliseconds */ + uint64_t monotonicMs; /* same, but from monotonic clock */ + + #ifdef HAVE_LIBHWLOC + hwloc_topology_t topology; + bool topologyOk; + #endif + + memory_t totalMem; + memory_t usedMem; + memory_t buffersMem; + memory_t cachedMem; + memory_t sharedMem; + memory_t availableMem; + + memory_t totalSwap; + memory_t usedSwap; + memory_t cachedSwap; + + unsigned int activeCPUs; + unsigned int existingCPUs; + + UsersTable* usersTable; + uid_t userId; + + /* To become an array of lists - processes, cgroups, filesystems,... etc */ + /* for now though, just point back to the one list we have at the moment */ + struct ProcessList_ *pl; +} Machine; + + +Machine* Machine_new(UsersTable* usersTable, uid_t userId); + +void Machine_init(Machine* this, UsersTable* usersTable, uid_t userId); + +void Machine_delete(Machine* this); + +void Machine_done(Machine* this); + +bool Machine_isCPUonline(const Machine* this, unsigned int id); + +void Machine_addList(Machine* this, struct ProcessList_ *pl); + +#endif diff --git a/MainPanel.c b/MainPanel.c index 0889a5c2..14bd3bbd 100644 --- a/MainPanel.c +++ b/MainPanel.c @@ -53,10 +53,9 @@ static const char* MainPanel_getValue(Panel* this, int i) { static HandlerResult MainPanel_eventHandler(Panel* super, int ch) { MainPanel* this = (MainPanel*) super; - - HandlerResult result = IGNORED; - + Machine* host = this->state->host; Htop_Reaction reaction = HTOP_OK; + HandlerResult result = IGNORED; /* Let supervising ScreenManager handle resize */ if (ch == KEY_RESIZE) @@ -66,20 +65,19 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) { bool needReset = ch != ERR; #ifdef HAVE_GETMOUSE /* except mouse events while mouse support is disabled */ - if (!(ch != KEY_MOUSE || this->state->settings->enableMouse)) + if (!(ch != KEY_MOUSE || host->settings->enableMouse)) needReset = false; #endif if (needReset) this->state->hideSelection = false; - Settings* settings = this->state->settings; + Settings* settings = host->settings; ScreenSettings* ss = settings->ss; if (EVENT_IS_HEADER_CLICK(ch)) { int x = EVENT_HEADER_CLICK_GET_X(ch); - const ProcessList* pl = this->state->pl; int hx = super->scrollH + x + 1; - ProcessField field = ProcessList_keyAt(pl, hx); + ProcessField field = ProcessList_keyAt(host->pl, hx); if (ss->treeView && ss->treeViewAlwaysByPID) { ss->treeView = false; ss->direction = 1; @@ -98,7 +96,7 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) { } else if (ch != ERR && this->inc->active) { bool filterChanged = IncSet_handleKey(this->inc, ch, super, MainPanel_getValue, NULL); if (filterChanged) { - this->state->pl->incFilter = IncSet_filter(this->inc); + host->pl->incFilter = IncSet_filter(this->inc); reaction = HTOP_REFRESH | HTOP_REDRAW_BAR; } if (this->inc->found) { @@ -123,7 +121,7 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) { } if ((reaction & HTOP_REDRAW_BAR) == HTOP_REDRAW_BAR) { - MainPanel_updateLabels(this, settings->ss->treeView, this->state->pl->incFilter); + MainPanel_updateLabels(this, settings->ss->treeView, host->pl->incFilter); } if ((reaction & HTOP_RESIZE) == HTOP_RESIZE) { result |= RESIZE; @@ -138,13 +136,13 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) { result |= RESCAN; } if ((reaction & HTOP_SAVE_SETTINGS) == HTOP_SAVE_SETTINGS) { - this->state->settings->changed = true; + host->settings->changed = true; } if ((reaction & HTOP_QUIT) == HTOP_QUIT) { return BREAK_LOOP; } if ((reaction & HTOP_KEEP_FOLLOWING) != HTOP_KEEP_FOLLOWING) { - this->state->pl->following = -1; + host->pl->following = -1; Panel_setSelectionColor(super, PANEL_SELECTION_FOCUS); } return result; @@ -197,7 +195,8 @@ static void MainPanel_drawFunctionBar(Panel* super, bool hideFunctionBar) { static void MainPanel_printHeader(Panel* super) { MainPanel* this = (MainPanel*) super; - ProcessList_printHeader(this->state->pl, &super->header); + Machine* host = this->state->host; + ProcessList_printHeader(host->pl, &super->header); } const PanelClass MainPanel_class = { diff --git a/Makefile.am b/Makefile.am index 42734201..94db4d77 100644 --- a/Makefile.am +++ b/Makefile.am @@ -60,6 +60,7 @@ myhtopsources = \ InfoScreen.c \ ListItem.c \ LoadAverageMeter.c \ + Machine.c \ MainPanel.c \ MemoryMeter.c \ MemorySwapMeter.c \ @@ -122,6 +123,7 @@ myhtopheaders = \ InfoScreen.h \ ListItem.h \ LoadAverageMeter.h \ + Machine.h \ Macros.h \ MainPanel.h \ MemoryMeter.h \ diff --git a/MemorySwapMeter.c b/MemorySwapMeter.c index 46b2a6b7..814841f7 100644 --- a/MemorySwapMeter.c +++ b/MemorySwapMeter.c @@ -53,9 +53,9 @@ static void MemorySwapMeter_init(Meter* this) { } if (!data->memoryMeter) - data->memoryMeter = Meter_new(this->pl, 0, (const MeterClass*) Class(MemoryMeter)); + data->memoryMeter = Meter_new(this->host, 0, (const MeterClass*) Class(MemoryMeter)); if (!data->swapMeter) - data->swapMeter = Meter_new(this->pl, 0, (const MeterClass*) Class(SwapMeter)); + data->swapMeter = Meter_new(this->host, 0, (const MeterClass*) Class(SwapMeter)); if (Meter_initFn(data->memoryMeter)) Meter_init(data->memoryMeter); diff --git a/Meter.c b/Meter.c index a88de04a..cf0fe36a 100644 --- a/Meter.c +++ b/Meter.c @@ -32,12 +32,12 @@ const MeterClass Meter_class = { } }; -Meter* Meter_new(const struct ProcessList_* pl, unsigned int param, const MeterClass* type) { +Meter* Meter_new(const Machine* host, unsigned int param, const MeterClass* type) { Meter* this = xCalloc(1, sizeof(Meter)); Object_setClass(this, type); this->h = 1; this->param = param; - this->pl = pl; + this->host = host; this->curItems = type->maxItems; this->curAttributes = NULL; this->values = type->maxItems ? xCalloc(type->maxItems, sizeof(double)) : NULL; @@ -294,7 +294,7 @@ static const char* const GraphMeterMode_dotsAscii[] = { }; static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; if (!this->drawData) { this->drawData = xCalloc(1, sizeof(GraphData)); @@ -322,10 +322,10 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { x += captionLen; w -= captionLen; - if (!timercmp(&pl->realtime, &(data->time), <)) { - int globalDelay = this->pl->settings->delay; + if (!timercmp(&host->realtime, &(data->time), <)) { + int globalDelay = this->host->settings->delay; struct timeval delay = { .tv_sec = globalDelay / 10, .tv_usec = (globalDelay % 10) * 100000L }; - timeradd(&pl->realtime, &delay, &(data->time)); + timeradd(&host->realtime, &delay, &(data->time)); for (int i = 0; i < nValues - 1; i++) data->values[i] = data->values[i + 1]; diff --git a/Meter.h b/Meter.h index 8e8618d6..db93e4c0 100644 --- a/Meter.h +++ b/Meter.h @@ -15,8 +15,8 @@ in the source distribution for its full text. #include #include "ListItem.h" +#include "Machine.h" #include "Object.h" -#include "ProcessList.h" #define METER_TXTBUFFER_LEN 256 @@ -105,6 +105,7 @@ typedef struct GraphData_ { struct Meter_ { Object super; Meter_Draw draw; + const Machine* host; char* caption; int mode; @@ -112,7 +113,6 @@ struct Meter_ { GraphData* drawData; int h; int columnWidthCount; /**< only used internally by the Header */ - const ProcessList* pl; uint8_t curItems; const int* curAttributes; char txtBuffer[METER_TXTBUFFER_LEN]; @@ -145,7 +145,7 @@ typedef enum { extern const MeterClass Meter_class; -Meter* Meter_new(const ProcessList* pl, unsigned int param, const MeterClass* type); +Meter* Meter_new(const Machine* host, unsigned int param, const MeterClass* type); int Meter_humanUnit(char* buffer, unsigned long int value, size_t size); diff --git a/NetworkIOMeter.c b/NetworkIOMeter.c index d41eafa8..5945bae7 100644 --- a/NetworkIOMeter.c +++ b/NetworkIOMeter.c @@ -26,10 +26,10 @@ static uint32_t cached_txb_diff; static uint32_t cached_txp_diff; static void NetworkIOMeter_updateValues(Meter* this) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; static uint64_t cached_last_update = 0; - uint64_t passedTimeInMs = pl->realtimeMs - cached_last_update; + uint64_t passedTimeInMs = host->realtimeMs - cached_last_update; /* update only every 500ms to have a sane span for rate calculation */ if (passedTimeInMs > 500) { @@ -50,7 +50,7 @@ static void NetworkIOMeter_updateValues(Meter* this) { status = RATESTATUS_DATA; } - cached_last_update = pl->realtimeMs; + cached_last_update = host->realtimeMs; if (status == RATESTATUS_NODATA) { xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "no data"); diff --git a/Process.c b/Process.c index c92d01b9..43f7f70d 100644 --- a/Process.c +++ b/Process.c @@ -407,7 +407,7 @@ static inline char* stpcpyWithNewlineConversion(char* dstStr, const char* srcStr */ void Process_makeCommandStr(Process* this) { ProcessMergedCommand* mc = &this->mergedCommand; - const Settings* settings = this->settings; + const Settings* settings = this->host->settings; bool showMergedCommand = settings->showMergedCommand; bool showProgramPath = settings->showProgramPath; @@ -675,15 +675,16 @@ void Process_writeCommand(const Process* this, int attr, int baseAttr, RichStrin int strStart = RichString_size(str); - const bool highlightBaseName = this->settings->highlightBaseName; + const Settings* settings = this->host->settings; + const bool highlightBaseName = settings->highlightBaseName; const bool highlightSeparator = true; - const bool highlightDeleted = this->settings->highlightDeletedExe; + const bool highlightDeleted = settings->highlightDeletedExe; if (!mergedCommand) { int len = 0; const char* cmdline = this->cmdline; - if (highlightBaseName || !this->settings->showProgramPath) { + if (highlightBaseName || !settings->showProgramPath) { int basename = 0; for (int i = 0; i < this->cmdlineBasenameEnd; i++) { if (cmdline[i] == '/') { @@ -694,7 +695,7 @@ void Process_writeCommand(const Process* this, int attr, int baseAttr, RichStrin } } if (len == 0) { - if (this->settings->showProgramPath) { + if (settings->showProgramPath) { strStart += basename; } else { cmdline += basename; @@ -705,7 +706,7 @@ void Process_writeCommand(const Process* this, int attr, int baseAttr, RichStrin RichString_appendWide(str, attr, cmdline); - if (this->settings->highlightBaseName) { + if (settings->highlightBaseName) { RichString_setAttrn(str, baseAttr, strStart, len); } @@ -833,16 +834,17 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field char buffer[256]; size_t n = sizeof(buffer); int attr = CRT_colors[DEFAULT_COLOR]; - bool coloring = this->settings->highlightMegabytes; + const Settings* settings = this->host->settings; + bool coloring = settings->highlightMegabytes; switch (field) { case COMM: { int baseattr = CRT_colors[PROCESS_BASENAME]; - if (this->settings->highlightThreads && Process_isThread(this)) { + if (settings->highlightThreads && Process_isThread(this)) { attr = CRT_colors[PROCESS_THREAD]; baseattr = CRT_colors[PROCESS_THREAD_BASENAME]; } - const ScreenSettings* ss = this->settings->ss; + const ScreenSettings* ss = settings->ss; if (!ss->treeView || this->indent == 0) { Process_writeCommand(this, attr, baseattr, str); return; @@ -890,7 +892,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field const char* procExe; if (this->procExe) { attr = CRT_colors[Process_isUserlandThread(this) ? PROCESS_THREAD_BASENAME : PROCESS_BASENAME]; - if (this->settings->highlightDeletedExe) { + if (settings->highlightDeletedExe) { if (this->procExeDeleted) attr = CRT_colors[FAILED_READ]; else if (this->usesDeletedLib) @@ -920,7 +922,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field return; } case ELAPSED: { - const uint64_t rt = this->processList->realtimeMs; + const uint64_t rt = this->host->realtimeMs; const uint64_t st = this->starttime_ctime * 1000; const uint64_t dt = rt < st ? 0 : @@ -946,7 +948,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field break; case PERCENT_CPU: Process_printPercentage(this->percent_cpu, buffer, n, Process_fieldWidths[PERCENT_CPU], &attr); break; case PERCENT_NORM_CPU: { - float cpuPercentage = this->percent_cpu / this->processList->activeCPUs; + float cpuPercentage = this->percent_cpu / this->host->activeCPUs; Process_printPercentage(cpuPercentage, buffer, n, Process_fieldWidths[PERCENT_CPU], &attr); break; } @@ -960,7 +962,7 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field else xSnprintf(buffer, n, "%3ld ", this->priority); break; - case PROCESSOR: xSnprintf(buffer, n, "%3d ", Settings_cpuId(this->settings, this->processor)); break; + case PROCESSOR: xSnprintf(buffer, n, "%3d ", Settings_cpuId(settings, this->processor)); break; case SCHEDULERPOLICY: { const char* schedPolStr = "N/A"; #ifdef SCHEDULER_SUPPORT @@ -1044,11 +1046,12 @@ void Process_writeField(const Process* this, RichString* str, ProcessField field void Process_display(const Object* cast, RichString* out) { const Process* this = (const Process*) cast; - const ProcessField* fields = this->settings->ss->fields; + const Settings* settings = this->host->settings; + const ProcessField* fields = settings->ss->fields; for (int i = 0; fields[i]; i++) As_Process(this)->writeField(this, out, fields[i]); - if (this->settings->shadowOtherUsers && this->st_uid != Process_getuid) { + if (settings->shadowOtherUsers && this->st_uid != Process_getuid) { RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]); } @@ -1056,7 +1059,7 @@ void Process_display(const Object* cast, RichString* out) { RichString_setAttr(out, CRT_colors[PROCESS_TAG]); } - if (this->settings->highlightChanges) { + if (settings->highlightChanges) { if (Process_isTomb(this)) { out->highlightAttr = CRT_colors[PROCESS_TOMB]; } else if (Process_isNew(this)) { @@ -1081,7 +1084,8 @@ void Process_done(Process* this) { * happens on what is displayed - whether comm, full path, basename, etc.. So * this follows Process_writeField(COMM) and Process_writeCommand */ const char* Process_getCommand(const Process* this) { - if ((Process_isUserlandThread(this) && this->settings->showThreadNames) || !this->mergedCommand.str) { + const Settings* settings = this->host->settings; + if ((Process_isUserlandThread(this) && settings->showThreadNames) || !this->mergedCommand.str) { return this->cmdline; } @@ -1098,8 +1102,8 @@ const ProcessClass Process_class = { .writeField = Process_writeField, }; -void Process_init(Process* this, const Settings* settings) { - this->settings = settings; +void Process_init(Process* this, const Machine* host) { + this->host = host; this->tag = false; this->showChildren = true; this->show = true; @@ -1117,9 +1121,11 @@ void Process_toggleTag(Process* this) { } bool Process_isNew(const Process* this) { - assert(this->processList); - if (this->processList->monotonicMs >= this->seenStampMs) { - return this->processList->monotonicMs - this->seenStampMs <= 1000 * (uint64_t)this->processList->settings->highlightDelaySecs; + assert(this->host); + const Machine* host = this->host; + if (host->monotonicMs >= this->seenStampMs) { + const Settings* settings = host->settings; + return host->monotonicMs - this->seenStampMs <= 1000 * (uint64_t)settings->highlightDelaySecs; } return false; } @@ -1153,7 +1159,7 @@ int Process_compare(const void* v1, const void* v2) { const Process* p1 = (const Process*)v1; const Process* p2 = (const Process*)v2; - const Settings* settings = p1->settings; + const Settings* settings = p1->host->settings; const ScreenSettings* ss = settings->ss; ProcessField key = ScreenSettings_getActiveSortKey(ss); diff --git a/Process.h b/Process.h index db32ecc1..ad89fd45 100644 --- a/Process.h +++ b/Process.h @@ -82,7 +82,7 @@ typedef enum ProcessState_ { SLEEPING } ProcessState; -struct Settings_; +struct Machine_; /* Holds information about regions of the cmdline that should be * highlighted (e.g. program basename, delimiter, comm). */ @@ -108,9 +108,8 @@ typedef struct Process_ { /* Super object for emulated OOP */ Object super; - /* Pointer to quasi-global data structures */ - const struct ProcessList_* processList; - const struct Settings_* settings; + /* Pointer to quasi-global data */ + const struct Machine_* host; /* Process identifier */ pid_t pid; @@ -305,7 +304,7 @@ extern uint8_t Process_fieldWidths[LAST_PROCESSFIELD]; extern int Process_pidDigits; extern int Process_uidDigits; -typedef Process* (*Process_New)(const struct Settings_*); +typedef Process* (*Process_New)(const struct Machine_*); typedef void (*Process_WriteField)(const Process*, RichString*, ProcessField); typedef int (*Process_CompareByKey)(const Process*, const Process*, ProcessField); @@ -389,7 +388,7 @@ void Process_done(Process* this); extern const ProcessClass Process_class; -void Process_init(Process* this, const struct Settings_* settings); +void Process_init(Process* this, const struct Machine_* host); void Process_toggleTag(Process* this); diff --git a/ProcessList.c b/ProcessList.c index 8e989d02..49217b8c 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -20,58 +20,18 @@ in the source distribution for its full text. #include "XUtils.h" -ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +void ProcessList_init(ProcessList* this, const ObjectClass* klass, Machine* host, Hashtable* pidMatchList) { this->processes = Vector_new(klass, true, DEFAULT_SIZE); this->displayList = Vector_new(klass, false, DEFAULT_SIZE); - this->processTable = Hashtable_new(200, false); - this->needsSort = true; - - this->usersTable = usersTable; this->pidMatchList = pidMatchList; - - this->userId = userId; - - // set later by platform-specific code - this->activeCPUs = 0; - this->existingCPUs = 0; - this->monotonicMs = 0; - - // always maintain valid realtime timestamps - Platform_gettime_realtime(&this->realtime, &this->realtimeMs); - -#ifdef HAVE_LIBHWLOC - this->topologyOk = false; - if (hwloc_topology_init(&this->topology) == 0) { - this->topologyOk = - #if HWLOC_API_VERSION < 0x00020000 - /* try to ignore the top-level machine object type */ - 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_MACHINE) && - /* ignore caches, which don't add structure */ - 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CORE) && - 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CACHE) && - 0 == hwloc_topology_set_flags(this->topology, HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) && - #else - 0 == hwloc_topology_set_all_types_filter(this->topology, HWLOC_TYPE_FILTER_KEEP_STRUCTURE) && - #endif - 0 == hwloc_topology_load(this->topology); - } -#endif - + this->needsSort = true; this->following = -1; - - return this; + this->host = host; } void ProcessList_done(ProcessList* this) { -#ifdef HAVE_LIBHWLOC - if (this->topologyOk) { - hwloc_topology_destroy(this->topology); - } -#endif - Hashtable_delete(this->processTable); - Vector_delete(this->displayList); Vector_delete(this->processes); } @@ -134,7 +94,7 @@ static const char* ProcessField_alignedTitle(const Settings* settings, ProcessFi void ProcessList_printHeader(const ProcessList* this, RichString* header) { RichString_rewind(header, RichString_size(header)); - const Settings* settings = this->settings; + const Settings* settings = this->host->settings; const ScreenSettings* ss = settings->ss; const ProcessField* fields = ss->fields; @@ -168,10 +128,9 @@ void ProcessList_printHeader(const ProcessList* this, RichString* header) { void ProcessList_add(ProcessList* this, Process* p) { assert(Vector_indexOf(this->processes, p, Process_pidEqualCompare) == -1); assert(Hashtable_get(this->processTable, p->pid) == NULL); - p->processList = this; // highlighting processes found in first scan by first scan marked "far in the past" - p->seenStampMs = this->monotonicMs; + p->seenStampMs = this->host->monotonicMs; Vector_add(this->processes, p); Hashtable_put(this->processTable, p->pid, p); @@ -325,7 +284,7 @@ static void ProcessList_buildTree(ProcessList* this) { } void ProcessList_updateDisplayList(ProcessList* this) { - if (this->settings->ss->treeView) { + if (this->host->settings->ss->treeView) { if (this->needsSort) ProcessList_buildTree(this); } else { @@ -341,7 +300,7 @@ void ProcessList_updateDisplayList(ProcessList* this) { ProcessField ProcessList_keyAt(const ProcessList* this, int at) { int x = 0; - const Settings* settings = this->settings; + const Settings* settings = this->host->settings; const ProcessField* fields = settings->ss->fields; ProcessField field; for (int i = 0; (field = fields[i]); i++) { @@ -387,7 +346,8 @@ void ProcessList_rebuildPanel(ProcessList* this) { Panel_prune(this->panel); /* Follow main process if followed a userland thread and threads are now hidden */ - const Settings* settings = this->settings; + const Machine* host= this->host; + const Settings* settings = host->settings; if (this->following != -1 && settings->hideUserlandThreads) { const Process* followedProcess = (const Process*) Hashtable_get(this->processTable, this->following); if (followedProcess && Process_isThread(followedProcess) && Hashtable_get(this->processTable, followedProcess->tgid) != NULL) { @@ -403,7 +363,7 @@ void ProcessList_rebuildPanel(ProcessList* this) { Process* p = (Process*) Vector_get(this->displayList, i); if ( (!p->show) - || (this->userId != (uid_t) -1 && (p->st_uid != this->userId)) + || (host->userId != (uid_t) -1 && (p->st_uid != host->userId)) || (incFilter && !(String_contains_i(Process_getCommand(p), incFilter, true))) || (this->pidMatchList && !Hashtable_get(this->pidMatchList, p->tgid)) ) continue; @@ -443,7 +403,7 @@ Process* ProcessList_getProcess(ProcessList* this, pid_t pid, bool* preExisting, assert(Vector_indexOf(this->processes, proc, Process_pidEqualCompare) != -1); assert(proc->pid == pid); } else { - proc = constructor(this->settings); + proc = constructor(this->host); assert(proc->cmdline == NULL); proc->pid = pid; } @@ -474,16 +434,18 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) { // set scan timestamp static bool firstScanDone = false; + Machine* host = this->host; if (firstScanDone) { - Platform_gettime_monotonic(&this->monotonicMs); + Platform_gettime_monotonic(&host->monotonicMs); } else { - this->monotonicMs = 0; + host->monotonicMs = 0; firstScanDone = true; } ProcessList_goThroughEntries(this, false); uid_t maxUid = 0; + const Settings* settings = host->settings; for (int i = Vector_size(this->processes) - 1; i >= 0; i--) { Process* p = (Process*) Vector_get(this->processes, i); Process_makeCommandStr(p); @@ -494,14 +456,14 @@ void ProcessList_scan(ProcessList* this, bool pauseProcessUpdate) { if (p->tombStampMs > 0) { // remove tombed process - if (this->monotonicMs >= p->tombStampMs) { + if (host->monotonicMs >= p->tombStampMs) { ProcessList_removeIndex(this, p, i); } } else if (p->updated == false) { // process no longer exists - if (this->settings->highlightChanges && p->wasShown) { + if (settings->highlightChanges && p->wasShown) { // mark tombed - p->tombStampMs = this->monotonicMs + 1000 * this->settings->highlightDelaySecs; + p->tombStampMs = host->monotonicMs + 1000 * settings->highlightDelaySecs; } else { // immediately remove ProcessList_removeIndex(this, p, i); diff --git a/ProcessList.h b/ProcessList.h index eab122a3..d09cc072 100644 --- a/ProcessList.h +++ b/ProcessList.h @@ -16,6 +16,7 @@ in the source distribution for its full text. #include #include "Hashtable.h" +#include "Machine.h" #include "Object.h" #include "Panel.h" #include "Process.h" @@ -24,76 +25,34 @@ in the source distribution for its full text. #include "UsersTable.h" #include "Vector.h" -#ifdef HAVE_LIBHWLOC -#include -#endif - - -#ifndef MAX_NAME -#define MAX_NAME 128 -#endif - -#ifndef MAX_READ -#define MAX_READ 2048 -#endif - -typedef unsigned long long int memory_t; -#define MEMORY_MAX ULLONG_MAX typedef struct ProcessList_ { - const Settings* settings; + struct Machine_* host; Vector* processes; /* all known processes; sort order can vary and differ from display order */ Vector* displayList; /* process tree flattened in display order (borrowed); updated in ProcessList_updateDisplayList when rebuilding panel */ Hashtable* processTable; /* fast known process lookup by PID */ - UsersTable* usersTable; bool needsSort; - struct timeval realtime; /* time of the current sample */ - uint64_t realtimeMs; /* current time in milliseconds */ - uint64_t monotonicMs; /* same, but from monotonic clock */ - Panel* panel; int following; - uid_t userId; const char* incFilter; Hashtable* pidMatchList; - #ifdef HAVE_LIBHWLOC - hwloc_topology_t topology; - bool topologyOk; - #endif - unsigned int totalTasks; unsigned int runningTasks; unsigned int userlandThreads; unsigned int kernelThreads; - - memory_t totalMem; - memory_t usedMem; - memory_t buffersMem; - memory_t cachedMem; - memory_t sharedMem; - memory_t availableMem; - - memory_t totalSwap; - memory_t usedSwap; - memory_t cachedSwap; - - unsigned int activeCPUs; - unsigned int existingCPUs; } ProcessList; /* Implemented by platforms */ -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); - -ProcessList* ProcessList_init(ProcessList* this, const ObjectClass* klass, UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); +void ProcessList_init(ProcessList* this, const ObjectClass* klass, Machine* host, Hashtable* pidMatchList); void ProcessList_done(ProcessList* this); diff --git a/ScreenManager.c b/ScreenManager.c index 6b9fada5..f1897893 100644 --- a/ScreenManager.c +++ b/ScreenManager.c @@ -24,7 +24,7 @@ in the source distribution for its full text. #include "XUtils.h" -ScreenManager* ScreenManager_new(Header* header, const Settings* settings, State* state, bool owner) { +ScreenManager* ScreenManager_new(Header* header, Machine* host, State* state, bool owner) { ScreenManager* this; this = xMalloc(sizeof(ScreenManager)); this->x1 = 0; @@ -34,7 +34,7 @@ ScreenManager* ScreenManager_new(Header* header, const Settings* settings, State this->panels = Vector_new(Class(Panel), owner, DEFAULT_SIZE); this->panelCount = 0; this->header = header; - this->settings = settings; + this->host = host; this->state = state; this->allowFocusChange = true; return this; @@ -116,12 +116,12 @@ void ScreenManager_resize(ScreenManager* this) { } static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTimeout, bool* redraw, bool* rescan, bool* timedOut, bool* force_redraw) { - ProcessList* pl = this->header->pl; + Machine* host = this->host; - Platform_gettime_realtime(&pl->realtime, &pl->realtimeMs); - double newTime = ((double)pl->realtime.tv_sec * 10) + ((double)pl->realtime.tv_usec / 100000); + Platform_gettime_realtime(&host->realtime, &host->realtimeMs); + double newTime = ((double)host->realtime.tv_sec * 10) + ((double)host->realtime.tv_usec / 100000); - *timedOut = (newTime - *oldTime > this->settings->delay); + *timedOut = (newTime - *oldTime > host->settings->delay); *rescan |= *timedOut; if (newTime < *oldTime) { @@ -131,12 +131,12 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi if (*rescan) { *oldTime = newTime; int oldUidDigits = Process_uidDigits; - if (!this->state->pauseUpdate && (*sortTimeout == 0 || this->settings->ss->treeView)) { - pl->needsSort = true; + if (!this->state->pauseUpdate && (*sortTimeout == 0 || host->settings->ss->treeView)) { + host->pl->needsSort = true; *sortTimeout = 1; } // scan processes first - some header values are calculated there - ProcessList_scan(pl, this->state->pauseUpdate); + ProcessList_scan(host->pl, this->state->pauseUpdate); // always update header, especially to avoid gaps in graph meters Header_updateData(this->header); // force redraw if the number of UID digits was changed @@ -146,7 +146,7 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi *redraw = true; } if (*redraw) { - ProcessList_rebuildPanel(pl); + ProcessList_rebuildPanel(host->pl); if (!this->state->hideMeters) Header_draw(this->header); } @@ -175,8 +175,9 @@ static inline bool drawTab(const int* y, int* x, int l, const char* name, bool c } static void ScreenManager_drawScreenTabs(ScreenManager* this) { - ScreenSettings** screens = this->settings->screens; - int cur = this->settings->ssIndex; + Settings* settings = this->host->settings; + ScreenSettings** screens = settings->screens; + int cur = settings->ssIndex; int l = COLS; Panel* panel = (Panel*) Vector_get(this->panels, 0); int y = panel->y - 1; @@ -197,7 +198,8 @@ static void ScreenManager_drawScreenTabs(ScreenManager* this) { } static void ScreenManager_drawPanels(ScreenManager* this, int focus, bool force_redraw) { - if (this->settings->screenTabs) { + Settings* settings = this->host->settings; + if (settings->screenTabs) { ScreenManager_drawScreenTabs(this); } const int nPanels = this->panelCount; @@ -217,6 +219,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey, con int focus = 0; Panel* panelFocus = (Panel*) Vector_get(this->panels, focus); + Settings* settings = this->host->settings; double oldTime = 0.0; @@ -247,7 +250,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey, con HandlerResult result = IGNORED; #ifdef HAVE_GETMOUSE - if (ch == KEY_MOUSE && this->settings->enableMouse) { + if (ch == KEY_MOUSE && settings->enableMouse) { ch = ERR; MEVENT mevent; int ok = getmouse(&mevent); @@ -262,7 +265,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey, con if (mevent.y == panel->y) { ch = EVENT_HEADER_CLICK(mevent.x - panel->x); break; - } else if (this->settings->screenTabs && mevent.y == panel->y - 1) { + } else if (settings->screenTabs && mevent.y == panel->y - 1) { ch = EVENT_SCREEN_TAB_CLICK(mevent.x); break; } else if (mevent.y > panel->y && mevent.y <= panel->y + panel->h) { diff --git a/ScreenManager.h b/ScreenManager.h index d08a9413..37821bb4 100644 --- a/ScreenManager.h +++ b/ScreenManager.h @@ -11,8 +11,8 @@ in the source distribution for its full text. #include "Action.h" #include "Header.h" +#include "Machine.h" #include "Panel.h" -#include "Settings.h" #include "Vector.h" @@ -25,12 +25,12 @@ typedef struct ScreenManager_ { const char* name; int panelCount; Header* header; - const Settings* settings; + Machine* host; State* state; bool allowFocusChange; } ScreenManager; -ScreenManager* ScreenManager_new(Header* header, const Settings* settings, State* state, bool owner); +ScreenManager* ScreenManager_new(Header* header, Machine* host, State* state, bool owner); void ScreenManager_delete(ScreenManager* this); diff --git a/TasksMeter.c b/TasksMeter.c index 64c9837c..b5563fca 100644 --- a/TasksMeter.c +++ b/TasksMeter.c @@ -24,19 +24,20 @@ static const int TasksMeter_attributes[] = { }; static void TasksMeter_updateValues(Meter* this) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; + const ProcessList* pl = host->pl; this->values[0] = pl->kernelThreads; this->values[1] = pl->userlandThreads; this->values[2] = pl->totalTasks - pl->kernelThreads - pl->userlandThreads; - this->values[3] = MINIMUM(pl->runningTasks, pl->activeCPUs); + this->values[3] = MINIMUM(pl->runningTasks, host->activeCPUs); this->total = pl->totalTasks; - xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%u/%u", MINIMUM(pl->runningTasks, pl->activeCPUs), pl->totalTasks); + xSnprintf(this->txtBuffer, sizeof(this->txtBuffer), "%u/%u", MINIMUM(pl->runningTasks, host->activeCPUs), pl->totalTasks); } static void TasksMeter_display(const Object* cast, RichString* out) { const Meter* this = (const Meter*)cast; - const Settings* settings = this->pl->settings; + const Settings* settings = this->host->settings; char buffer[20]; int len; diff --git a/darwin/DarwinProcess.c b/darwin/DarwinProcess.c index 6027c25b..22004e36 100644 --- a/darwin/DarwinProcess.c +++ b/darwin/DarwinProcess.c @@ -51,10 +51,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [TRANSLATED] = { .name = "TRANSLATED", .title = "T ", .description = "Translation info (T translated, N native)", .flags = 0, }, }; -Process* DarwinProcess_new(const Settings* settings) { +Process* DarwinProcess_new(const Machine* host) { DarwinProcess* this = xCalloc(1, sizeof(DarwinProcess)); Object_setClass(this, Class(DarwinProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, host); this->utime = 0; this->stime = 0; @@ -291,6 +291,7 @@ static char* DarwinProcess_getDevname(dev_t dev) { void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, bool exists) { DarwinProcess* dp = (DarwinProcess*)proc; + const Settings* settings = proc->host->settings; const struct extern_proc* ep = &ps->kp_proc; @@ -328,7 +329,7 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, DarwinProcess_updateExe(ep->p_pid, proc); DarwinProcess_updateCmdLine(ps, proc); - if (proc->settings->ss->flags & PROCESS_FLAG_CWD) { + if (settings->ss->flags & PROCESS_FLAG_CWD) { DarwinProcess_updateCwd(ep->p_pid, proc); } } @@ -341,7 +342,7 @@ void DarwinProcess_setFromKInfoProc(Process* proc, const struct kinfo_proc* ps, * To mitigate this we only fetch TTY information if the TTY * field is enabled in the settings. */ - if (proc->settings->ss->flags & PROCESS_FLAG_TTY) { + if (settings->ss->flags & PROCESS_FLAG_TTY) { proc->tty_name = DarwinProcess_getDevname(proc->tty_nr); if (!proc->tty_name) { /* devname failed: prevent us from calling it again */ diff --git a/darwin/DarwinProcess.h b/darwin/DarwinProcess.h index bd179746..89a0576d 100644 --- a/darwin/DarwinProcess.h +++ b/darwin/DarwinProcess.h @@ -9,7 +9,7 @@ in the source distribution for its full text. #include -#include "Settings.h" +#include "Machine.h" #include "darwin/DarwinProcessList.h" @@ -28,7 +28,7 @@ extern const ProcessClass DarwinProcess_class; extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; -Process* DarwinProcess_new(const Settings* settings); +Process* DarwinProcess_new(const Machine* settings); void Process_delete(Object* cast); diff --git a/darwin/DarwinProcessList.c b/darwin/DarwinProcessList.c index 6e9eecf7..16c44d2c 100644 --- a/darwin/DarwinProcessList.c +++ b/darwin/DarwinProcessList.c @@ -89,15 +89,15 @@ static struct kinfo_proc* ProcessList_getKInfoProcs(size_t* count) { CRT_fatalError("Unable to get kinfo_procs"); } -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { DarwinProcessList* this = xCalloc(1, sizeof(DarwinProcessList)); - ProcessList_init(&this->super, Class(DarwinProcess), usersTable, pidMatchList, userId); + ProcessList_init(&this->super, Class(DarwinProcess), host, pidMatchList); /* Initialize the CPU information */ - this->super.activeCPUs = ProcessList_allocateCPULoadInfo(&this->prev_load); + host->activeCPUs = ProcessList_allocateCPULoadInfo(&this->prev_load); // TODO: support offline CPUs and hot swapping - this->super.existingCPUs = this->super.activeCPUs; + host->existingCPUs = host->activeCPUs; ProcessList_getHostInfo(&this->host_info); ProcessList_allocateCPULoadInfo(&this->curr_load); @@ -123,6 +123,7 @@ void ProcessList_delete(ProcessList* this) { void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { DarwinProcessList* dpl = (DarwinProcessList*)super; + const Machine* host = super->host; bool preExisting = true; struct kinfo_proc* ps; size_t count; @@ -142,13 +143,13 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { /* Get the time difference */ dpl->global_diff = 0; - for (unsigned int i = 0; i < dpl->super.existingCPUs; ++i) { + for (unsigned int i = 0; i < host->existingCPUs; ++i) { for (size_t j = 0; j < CPU_STATE_MAX; ++j) { dpl->global_diff += dpl->curr_load[i].cpu_ticks[j] - dpl->prev_load[i].cpu_ticks[j]; } } - const double time_interval_ns = Platform_schedulerTicksToNanoseconds(dpl->global_diff) / (double) dpl->super.activeCPUs; + const double time_interval_ns = Platform_schedulerTicksToNanoseconds(dpl->global_diff) / (double) host->activeCPUs; /* Clear the thread counts */ super->kernelThreads = 0; @@ -173,7 +174,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { if (proc->super.st_uid != ps[i].kp_eproc.e_ucred.cr_uid) { proc->super.st_uid = ps[i].kp_eproc.e_ucred.cr_uid; - proc->super.user = UsersTable_getRef(super->usersTable, proc->super.st_uid); + proc->super.user = UsersTable_getRef(host->usersTable, proc->super.st_uid); } // Disabled for High Sierra due to bug in macOS High Sierra @@ -193,11 +194,21 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { free(ps); } -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); // TODO: support offline CPUs and hot swapping - (void) super; (void) id; + (void) host; (void) id; return true; } diff --git a/darwin/DarwinProcessList.h b/darwin/DarwinProcessList.h index ec504bcf..128896ae 100644 --- a/darwin/DarwinProcessList.h +++ b/darwin/DarwinProcessList.h @@ -28,12 +28,16 @@ typedef struct DarwinProcessList_ { ZfsArcStats zfs; } DarwinProcessList; -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList); void ProcessList_delete(ProcessList* this); 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 diff --git a/darwin/Platform.c b/darwin/Platform.c index 20bfec26..71d08247 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -233,13 +233,13 @@ int Platform_getMaxPid(void) { } static double Platform_setCPUAverageValues(Meter* mtr) { - const ProcessList* dpl = mtr->pl; - unsigned int activeCPUs = dpl->activeCPUs; + const Machine* host = mtr->host; + unsigned int activeCPUs = host->activeCPUs; double sumNice = 0.0; double sumNormal = 0.0; double sumKernel = 0.0; double sumPercent = 0.0; - for (unsigned int i = 1; i <= dpl->existingCPUs; i++) { + for (unsigned int i = 1; i <= host->existingCPUs; i++) { sumPercent += Platform_setCPUValues(mtr, i); sumNice += mtr->values[CPU_METER_NICE]; sumNormal += mtr->values[CPU_METER_NORMAL]; @@ -257,7 +257,7 @@ double Platform_setCPUValues(Meter* mtr, unsigned int cpu) { return Platform_setCPUAverageValues(mtr); } - const DarwinProcessList* dpl = (const DarwinProcessList*)mtr->pl; + const DarwinProcessList* dpl = (const DarwinProcessList*)mtr->host->pl; const processor_cpu_load_info_t prev = &dpl->prev_load[cpu - 1]; const processor_cpu_load_info_t curr = &dpl->curr_load[cpu - 1]; double total = 0; @@ -286,7 +286,8 @@ double Platform_setCPUValues(Meter* mtr, unsigned int cpu) { } void Platform_setMemoryValues(Meter* mtr) { - const DarwinProcessList* dpl = (const DarwinProcessList*)mtr->pl; + const Machine* host = mtr->host; + const DarwinProcessList* dpl = (const DarwinProcessList*) host->pl; const struct vm_statistics* vm = &dpl->vm_stats; double page_K = (double)vm_page_size / (double)1024; @@ -312,13 +313,13 @@ void Platform_setSwapValues(Meter* mtr) { } void Platform_setZfsArcValues(Meter* this) { - const DarwinProcessList* dpl = (const DarwinProcessList*) this->pl; + const DarwinProcessList* dpl = (const DarwinProcessList*) this->host->pl; ZfsArcMeter_readStats(this, &(dpl->zfs)); } void Platform_setZfsCompressedArcValues(Meter* this) { - const DarwinProcessList* dpl = (const DarwinProcessList*) this->pl; + const DarwinProcessList* dpl = (const DarwinProcessList*) this->host->pl; ZfsCompressedArcMeter_readStats(this, &(dpl->zfs)); } diff --git a/dragonflybsd/DragonFlyBSDProcess.c b/dragonflybsd/DragonFlyBSDProcess.c index 7ff92451..7cfc71be 100644 --- a/dragonflybsd/DragonFlyBSDProcess.c +++ b/dragonflybsd/DragonFlyBSDProcess.c @@ -52,10 +52,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [JAIL] = { .name = "JAIL", .title = "JAIL ", .description = "Jail prison name", .flags = 0, }, }; -Process* DragonFlyBSDProcess_new(const Settings* settings) { +Process* DragonFlyBSDProcess_new(const Machine* host) { DragonFlyBSDProcess* this = xCalloc(1, sizeof(DragonFlyBSDProcess)); Object_setClass(this, Class(DragonFlyBSDProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, host); return &this->super; } diff --git a/dragonflybsd/DragonFlyBSDProcess.h b/dragonflybsd/DragonFlyBSDProcess.h index e0a77ef1..92747b1a 100644 --- a/dragonflybsd/DragonFlyBSDProcess.h +++ b/dragonflybsd/DragonFlyBSDProcess.h @@ -12,7 +12,7 @@ in the source distribution for its full text. #include "Object.h" #include "Process.h" -#include "Settings.h" +#include "Machine.h" typedef struct DragonFlyBSDProcess_ { @@ -25,7 +25,7 @@ extern const ProcessClass DragonFlyBSDProcess_class; extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; -Process* DragonFlyBSDProcess_new(const Settings* settings); +Process* DragonFlyBSDProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/dragonflybsd/DragonFlyBSDProcessList.c b/dragonflybsd/DragonFlyBSDProcessList.c index 39b05250..c66917fb 100644 --- a/dragonflybsd/DragonFlyBSDProcessList.c +++ b/dragonflybsd/DragonFlyBSDProcessList.c @@ -42,12 +42,12 @@ static int MIB_kern_cp_time[2]; static int MIB_kern_cp_times[2]; static int kernelFScale; -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { size_t len; char errbuf[_POSIX2_LINE_MAX]; DragonFlyBSDProcessList* dfpl = xCalloc(1, sizeof(DragonFlyBSDProcessList)); ProcessList* pl = (ProcessList*) dfpl; - ProcessList_init(pl, Class(DragonFlyBSDProcess), usersTable, pidMatchList, userId); + ProcessList_init(pl, Class(DragonFlyBSDProcess), host, pidMatchList); // physical memory in system: hw.physmem // physical page size: hw.pagesize @@ -95,15 +95,15 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui sysctl(MIB_kern_cp_times, 2, dfpl->cp_times_o, &len, NULL, 0); } - pl->existingCPUs = MAXIMUM(cpus, 1); + host->existingCPUs = MAXIMUM(cpus, 1); // TODO: support offline CPUs and hot swapping - pl->activeCPUs = pl->existingCPUs; + host->activeCPUs = host->existingCPUs; if (cpus == 1 ) { dfpl->cpus = xRealloc(dfpl->cpus, sizeof(CPUData)); } else { // on smp we need CPUs + 1 to store averages too (as kernel kindly provides that as well) - dfpl->cpus = xRealloc(dfpl->cpus, (pl->existingCPUs + 1) * sizeof(CPUData)); + dfpl->cpus = xRealloc(dfpl->cpus, (host->existingCPUs + 1) * sizeof(CPUData)); } len = sizeof(kernelFScale); @@ -420,7 +420,8 @@ static char* DragonFlyBSDProcessList_readJailName(DragonFlyBSDProcessList* dfpl, void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { DragonFlyBSDProcessList* dfpl = (DragonFlyBSDProcessList*) super; - const Settings* settings = super->settings; + const Machine* host = super->host; + const Settings* settings = host->settings; bool hideKernelThreads = settings->hideKernelThreads; bool hideUserlandThreads = settings->hideUserlandThreads; @@ -467,7 +468,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { proc->processor = kproc->kp_lwp.kl_origcpu; proc->starttime_ctime = kproc->kp_start.tv_sec; Process_fillStarttimeBuffer(proc); - proc->user = UsersTable_getRef(super->usersTable, proc->st_uid); + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); proc->tty_nr = kproc->kp_tdev; // control terminal device number const char* name = (kproc->kp_tdev != NODEV) ? devname(kproc->kp_tdev, S_IFCHR) : NULL; @@ -499,7 +500,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { proc->ppid = kproc->kp_ppid; if (proc->st_uid != kproc->kp_uid) { // some processes change users (eg. to lower privs) proc->st_uid = kproc->kp_uid; - proc->user = UsersTable_getRef(super->usersTable, proc->st_uid); + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); } if (settings->updateProcessNames) { DragonFlyBSDProcessList_updateProcessName(dfpl->kd, kproc, proc); @@ -605,11 +606,21 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { } } -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); // TODO: support offline CPUs and hot swapping - (void) super; (void) id; + (void) host; (void) id; return true; } diff --git a/dragonflybsd/DragonFlyBSDProcessList.h b/dragonflybsd/DragonFlyBSDProcessList.h index 2cc40054..406722e0 100644 --- a/dragonflybsd/DragonFlyBSDProcessList.h +++ b/dragonflybsd/DragonFlyBSDProcessList.h @@ -53,12 +53,16 @@ typedef struct DragonFlyBSDProcessList_ { Hashtable* jails; } DragonFlyBSDProcessList; -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList); void ProcessList_delete(ProcessList* this); 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 diff --git a/dragonflybsd/Platform.c b/dragonflybsd/Platform.c index 99527642..1c0ef0a4 100644 --- a/dragonflybsd/Platform.c +++ b/dragonflybsd/Platform.c @@ -172,8 +172,9 @@ int Platform_getMaxPid(void) { } double Platform_setCPUValues(Meter* this, unsigned int cpu) { - const DragonFlyBSDProcessList* fpl = (const DragonFlyBSDProcessList*) this->pl; - unsigned int cpus = this->pl->activeCPUs; + const Machine* host = this->host; + const DragonFlyBSDProcessList* fpl = (const DragonFlyBSDProcessList*) host->pl; + unsigned int cpus = this->host->activeCPUs; const CPUData* cpuData; if (cpus == 1) { @@ -188,7 +189,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; @@ -209,7 +210,7 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { void Platform_setMemoryValues(Meter* this) { // TODO - const ProcessList* pl = this->pl; + const ProcessList* pl = this->host->pl; this->total = pl->totalMem; this->values[MEMORY_METER_USED] = pl->usedMem; @@ -221,7 +222,7 @@ void Platform_setMemoryValues(Meter* this) { } void Platform_setSwapValues(Meter* this) { - const ProcessList* pl = this->pl; + const ProcessList* pl = this->host->pl; this->total = pl->totalSwap; this->values[SWAP_METER_USED] = pl->usedSwap; // mtr->values[SWAP_METER_CACHE] = "pages that are both in swap and RAM, like SwapCached on linux" diff --git a/freebsd/FreeBSDProcess.c b/freebsd/FreeBSDProcess.c index 90bc1f2c..4970ff2c 100644 --- a/freebsd/FreeBSDProcess.c +++ b/freebsd/FreeBSDProcess.c @@ -56,10 +56,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [EMULATION] = { .name = "EMULATION", .title = "EMULATION ", .description = "System call emulation environment (ABI)", .flags = 0, }, }; -Process* FreeBSDProcess_new(const Settings* settings) { +Process* FreeBSDProcess_new(const Machine* machine) { FreeBSDProcess* this = xCalloc(1, sizeof(FreeBSDProcess)); Object_setClass(this, Class(FreeBSDProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, machine); return &this->super; } diff --git a/freebsd/FreeBSDProcess.h b/freebsd/FreeBSDProcess.h index 654f9cfa..012cfa27 100644 --- a/freebsd/FreeBSDProcess.h +++ b/freebsd/FreeBSDProcess.h @@ -11,7 +11,7 @@ in the source distribution for its full text. #include "Object.h" #include "Process.h" -#include "Settings.h" +#include "Machine.h" typedef struct FreeBSDProcess_ { @@ -25,7 +25,7 @@ extern const ProcessClass FreeBSDProcess_class; extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; -Process* FreeBSDProcess_new(const Settings* settings); +Process* FreeBSDProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c index f545a3ee..bd6e3aac 100644 --- a/freebsd/FreeBSDProcessList.c +++ b/freebsd/FreeBSDProcessList.c @@ -59,12 +59,12 @@ static int MIB_kern_cp_time[2]; static int MIB_kern_cp_times[2]; static int kernelFScale; -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { size_t len; char errbuf[_POSIX2_LINE_MAX]; FreeBSDProcessList* fpl = xCalloc(1, sizeof(FreeBSDProcessList)); ProcessList* pl = (ProcessList*) fpl; - ProcessList_init(pl, Class(FreeBSDProcess), usersTable, pidMatchList, userId); + ProcessList_init(pl, Class(FreeBSDProcess), host, pidMatchList); // physical memory in system: hw.physmem // physical page size: hw.pagesize @@ -129,15 +129,15 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui sysctl(MIB_kern_cp_times, 2, fpl->cp_times_o, &len, NULL, 0); } - pl->existingCPUs = MAXIMUM(cpus, 1); + host->existingCPUs = MAXIMUM(cpus, 1); // TODO: support offline CPUs and hot swapping - pl->activeCPUs = pl->existingCPUs; + host->activeCPUs = host->existingCPUs; if (cpus == 1 ) { fpl->cpus = xRealloc(fpl->cpus, sizeof(CPUData)); } else { // on smp we need CPUs + 1 to store averages too (as kernel kindly provides that as well) - fpl->cpus = xRealloc(fpl->cpus, (pl->existingCPUs + 1) * sizeof(CPUData)); + fpl->cpus = xRealloc(fpl->cpus, (host->existingCPUs + 1) * sizeof(CPUData)); } @@ -174,8 +174,9 @@ void ProcessList_delete(ProcessList* this) { static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) { const FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl; + const Machine* host = pl->host; - unsigned int cpus = pl->existingCPUs; // actual CPU count + unsigned int cpus = host->existingCPUs; // actual CPU count unsigned int maxcpu = cpus; // max iteration (in case we have average + smp) int cp_times_offset; @@ -260,7 +261,7 @@ static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) { continue; // TODO: test with hyperthreading and multi-cpu systems - if (pl->settings->showCPUTemperature) { + if (host->settings->showCPUTemperature) { int temperature; size_t len = sizeof(temperature); char mibBuffer[32]; @@ -271,7 +272,7 @@ static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) { } // TODO: test with hyperthreading and multi-cpu systems - if (pl->settings->showCPUFrequency) { + if (host->settings->showCPUFrequency) { int frequency; size_t len = sizeof(frequency); char mibBuffer[32]; @@ -285,7 +286,7 @@ static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) { // calculate max temperature and avg frequency for average meter and // propagate frequency to all cores if only supplied for CPU 0 if (cpus > 1) { - if (pl->settings->showCPUTemperature) { + if (host->settings->showCPUTemperature) { double maxTemp = NAN; for (unsigned int i = 1; i < maxcpu; i++) { const double coreTemp = fpl->cpus[i].temperature; @@ -298,7 +299,7 @@ static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) { fpl->cpus[0].temperature = maxTemp; } - if (pl->settings->showCPUFrequency) { + if (host->settings->showCPUFrequency) { const double coreZeroFreq = fpl->cpus[1].frequency; double freqSum = coreZeroFreq; if (!isnan(coreZeroFreq)) { @@ -317,6 +318,7 @@ static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) { static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) { FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl; + Machine* host = pl->host; // @etosan: // memory counter relationships seem to be these: @@ -338,12 +340,12 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) { //disabled for now, as it is always smaller than phycal amount of memory... //...to avoid "where is my memory?" questions - //sysctl(MIB_vm_stats_vm_v_page_count, 4, &(pl->totalMem), &len, NULL, 0); - //pl->totalMem *= pageSizeKb; + //sysctl(MIB_vm_stats_vm_v_page_count, 4, &(host->totalMem), &len, NULL, 0); + //host->totalMem *= pageSizeKb; len = sizeof(totalMem); sysctl(MIB_hw_physmem, 2, &(totalMem), &len, NULL, 0); totalMem /= 1024; - pl->totalMem = totalMem; + host->totalMem = totalMem; len = sizeof(memActive); sysctl(MIB_vm_stats_vm_v_active_count, 4, &(memActive), &len, NULL, 0); @@ -358,29 +360,29 @@ static inline void FreeBSDProcessList_scanMemoryInfo(ProcessList* pl) { len = sizeof(buffersMem); sysctl(MIB_vfs_bufspace, 2, &(buffersMem), &len, NULL, 0); buffersMem /= 1024; - pl->buffersMem = buffersMem; + host->buffersMem = buffersMem; len = sizeof(cachedMem); sysctl(MIB_vm_stats_vm_v_cache_count, 4, &(cachedMem), &len, NULL, 0); cachedMem *= pageSizeKb; - pl->cachedMem = cachedMem; + host->cachedMem = cachedMem; len = sizeof(vmtotal); sysctl(MIB_vm_vmtotal, 2, &(vmtotal), &len, NULL, 0); - pl->sharedMem = vmtotal.t_rmshr * pageSizeKb; + host->sharedMem = vmtotal.t_rmshr * pageSizeKb; - pl->usedMem = fpl->memActive + fpl->memWire; + host->usedMem = fpl->memActive + fpl->memWire; struct kvm_swap swap[16]; int nswap = kvm_getswapinfo(fpl->kd, swap, ARRAYSIZE(swap), 0); - pl->totalSwap = 0; - pl->usedSwap = 0; + host->totalSwap = 0; + host->usedSwap = 0; for (int i = 0; i < nswap; i++) { - pl->totalSwap += swap[i].ksw_total; - pl->usedSwap += swap[i].ksw_used; + host->totalSwap += swap[i].ksw_total; + host->usedSwap += swap[i].ksw_used; } - pl->totalSwap *= pageSizeKb; - pl->usedSwap *= pageSizeKb; + host->totalSwap *= pageSizeKb; + host->usedSwap *= pageSizeKb; } static void FreeBSDProcessList_updateExe(const struct kinfo_proc* kproc, Process* proc) { @@ -483,7 +485,8 @@ IGNORE_WCASTQUAL_END void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { FreeBSDProcessList* fpl = (FreeBSDProcessList*) super; - const Settings* settings = super->settings; + const Machine* host = super->host; + const Settings* settings = host->settings; bool hideKernelThreads = settings->hideKernelThreads; bool hideUserlandThreads = settings->hideUserlandThreads; @@ -518,10 +521,10 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { proc->st_uid = kproc->ki_uid; proc->starttime_ctime = kproc->ki_start.tv_sec; if (proc->starttime_ctime < 0) { - proc->starttime_ctime = super->realtimeMs / 1000; + proc->starttime_ctime = super->host.realtimeMs / 1000; } Process_fillStarttimeBuffer(proc); - proc->user = UsersTable_getRef(super->usersTable, proc->st_uid); + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); ProcessList_add(super, proc); FreeBSDProcessList_updateExe(kproc, proc); @@ -553,7 +556,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { if (proc->st_uid != kproc->ki_uid) { // some processes change users (eg. to lower privs) proc->st_uid = kproc->ki_uid; - proc->user = UsersTable_getRef(super->usersTable, proc->st_uid); + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); } if (settings->updateProcessNames) { FreeBSDProcessList_updateProcessName(fpl->kd, kproc, proc); @@ -569,7 +572,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { 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 / (double)(super->totalMem); + proc->percent_mem = 100.0 * proc->m_resident / (double)(host->totalMem); Process_updateCPUFieldWidths(proc->percent_cpu); if (kproc->ki_stat == SRUN && kproc->ki_oncpu != NOCPU) { @@ -621,11 +624,21 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { } } -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); // TODO: support offline CPUs and hot swapping - (void) super; (void) id; + (void) host; (void) id; return true; } diff --git a/freebsd/FreeBSDProcessList.h b/freebsd/FreeBSDProcessList.h index 98510fad..b7e29f8b 100644 --- a/freebsd/FreeBSDProcessList.h +++ b/freebsd/FreeBSDProcessList.h @@ -47,12 +47,16 @@ typedef struct FreeBSDProcessList_ { } FreeBSDProcessList; -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList); void ProcessList_delete(ProcessList* this); 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 diff --git a/freebsd/Platform.c b/freebsd/Platform.c index cab80929..3ba2778e 100644 --- a/freebsd/Platform.c +++ b/freebsd/Platform.c @@ -193,8 +193,9 @@ int Platform_getMaxPid(void) { } double Platform_setCPUValues(Meter* this, unsigned int cpu) { - const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl; - unsigned int cpus = this->pl->activeCPUs; + const Machine* host = this->host; + const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) host->pl; + unsigned int cpus = host->activeCPUs; const CPUData* cpuData; if (cpus == 1) { @@ -209,7 +210,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; @@ -229,15 +230,16 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { } void Platform_setMemoryValues(Meter* this) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; + const ProcessList* pl = host->pl; const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) pl; - this->total = pl->totalMem; - this->values[MEMORY_METER_USED] = pl->usedMem; - this->values[MEMORY_METER_BUFFERS] = pl->buffersMem; - this->values[MEMORY_METER_SHARED] = pl->sharedMem; + this->total = host->totalMem; + this->values[MEMORY_METER_USED] = host->usedMem; + this->values[MEMORY_METER_BUFFERS] = host->buffersMem; + this->values[MEMORY_METER_SHARED] = host->sharedMem; // 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" if (fpl->zfs.enabled) { @@ -252,21 +254,22 @@ void Platform_setMemoryValues(Meter* this) { } 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 FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl; + const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->host->pl; ZfsArcMeter_readStats(this, &(fpl->zfs)); } void Platform_setZfsCompressedArcValues(Meter* this) { - const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->pl; + const FreeBSDProcessList* fpl = (const FreeBSDProcessList*) this->host->pl; ZfsCompressedArcMeter_readStats(this, &(fpl->zfs)); } diff --git a/linux/HugePageMeter.c b/linux/HugePageMeter.c index 1efde2f2..0e429444 100644 --- a/linux/HugePageMeter.c +++ b/linux/HugePageMeter.c @@ -43,7 +43,7 @@ static void HugePageMeter_updateValues(Meter* this) { memory_t usedTotal = 0; unsigned nextUsed = 0; - const LinuxProcessList* lpl = (const LinuxProcessList*) this->pl; + const LinuxProcessList* lpl = (const LinuxProcessList*) this->host->pl; this->total = lpl->totalHugePageMem; this->values[0] = 0; HugePageMeter_active_labels[0] = " used:"; diff --git a/linux/LinuxProcess.c b/linux/LinuxProcess.c index 8f9c3462..a3a4c821 100644 --- a/linux/LinuxProcess.c +++ b/linux/LinuxProcess.c @@ -106,10 +106,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { #endif }; -Process* LinuxProcess_new(const Settings* settings) { +Process* LinuxProcess_new(const Machine* host) { LinuxProcess* this = xCalloc(1, sizeof(LinuxProcess)); Object_setClass(this, Class(LinuxProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, host); return &this->super; } @@ -197,7 +197,7 @@ bool LinuxProcess_changeAutogroupPriorityBy(Process* this, Arg delta) { static void LinuxProcess_writeField(const Process* this, RichString* str, ProcessField field) { const LinuxProcess* lp = (const LinuxProcess*) this; - bool coloring = this->settings->highlightMegabytes; + bool coloring = this->host->settings->highlightMegabytes; char buffer[256]; buffer[255] = '\0'; int attr = CRT_colors[DEFAULT_COLOR]; size_t n = sizeof(buffer) - 1; diff --git a/linux/LinuxProcess.h b/linux/LinuxProcess.h index 3e5d3804..6c309893 100644 --- a/linux/LinuxProcess.h +++ b/linux/LinuxProcess.h @@ -14,9 +14,9 @@ in the source distribution for its full text. #include #include "linux/IOPriority.h" +#include "Machine.h" #include "Object.h" #include "Process.h" -#include "Settings.h" #define PROCESS_FLAG_LINUX_IOPRIO 0x00000100 @@ -118,7 +118,7 @@ extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; extern const ProcessClass LinuxProcess_class; -Process* LinuxProcess_new(const Settings* settings); +Process* LinuxProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 2ecdefc3..911fc3e1 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -216,6 +216,7 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) { * https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/getsysstats.c;hb=HEAD */ + Machine* host = super->host; LinuxProcessList* this = (LinuxProcessList*) super; unsigned int existing = 0, active = 0; @@ -224,15 +225,15 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) { this->cpuData = xCalloc(2, sizeof(CPUData)); this->cpuData[0].online = true; /* average is always "online" */ this->cpuData[1].online = true; - super->activeCPUs = 1; - super->existingCPUs = 1; + host->activeCPUs = 1; + host->existingCPUs = 1; } DIR* dir = opendir("/sys/devices/system/cpu"); if (!dir) return; - unsigned int currExisting = super->existingCPUs; + unsigned int currExisting = host->existingCPUs; const struct dirent* entry; while ((entry = readdir(dir)) != NULL) { @@ -288,20 +289,20 @@ static void LinuxProcessList_updateCPUcount(ProcessList* super) { #ifdef HAVE_SENSORS_SENSORS_H /* When started with offline CPUs, libsensors does not monitor those, * even when they become online. */ - if (super->existingCPUs != 0 && (active > super->activeCPUs || currExisting > super->existingCPUs)) + if (host->existingCPUs != 0 && (active > host->activeCPUs || currExisting > host->existingCPUs)) LibSensors_reload(); #endif - super->activeCPUs = active; + host->activeCPUs = active; assert(existing == currExisting); - super->existingCPUs = currExisting; + host->existingCPUs = currExisting; } -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { LinuxProcessList* this = xCalloc(1, sizeof(LinuxProcessList)); ProcessList* pl = &(this->super); - ProcessList_init(pl, Class(LinuxProcess), usersTable, pidMatchList, userId); + ProcessList_init(pl, Class(LinuxProcess), host, pidMatchList); LinuxProcessList_initTtyDrivers(this); // Initialize page size @@ -594,7 +595,7 @@ static bool LinuxProcessList_readStatusFile(Process* process, openat_arg_t procF return true; } -static bool LinuxProcessList_updateUser(ProcessList* processList, Process* process, openat_arg_t procFd) { +static bool LinuxProcessList_updateUser(const Machine* host, Process* process, openat_arg_t procFd) { struct stat sstat; #ifdef HAVE_OPENAT int statok = fstat(procFd, &sstat); @@ -606,7 +607,7 @@ static bool LinuxProcessList_updateUser(ProcessList* processList, Process* proce if (process->st_uid != sstat.st_uid) { process->st_uid = sstat.st_uid; - process->user = UsersTable_getRef(processList->usersTable, sstat.st_uid); + process->user = UsersTable_getRef(host->usersTable, sstat.st_uid); } return true; @@ -1421,14 +1422,14 @@ static char* LinuxProcessList_updateTtyDevice(TtyDriver* ttyDrivers, unsigned lo return out; } -static bool isOlderThan(const ProcessList* pl, const Process* proc, unsigned int seconds) { - assert(pl->realtimeMs > 0); +static bool isOlderThan(const Machine* host, const Process* proc, unsigned int seconds) { + assert(host->realtimeMs > 0); /* Starttime might not yet be parsed */ if (proc->starttime_ctime <= 0) return false; - uint64_t realtime = pl->realtimeMs / 1000; + uint64_t realtime = host->realtimeMs / 1000; if (realtime < (uint64_t)proc->starttime_ctime) return false; @@ -1438,9 +1439,10 @@ static bool isOlderThan(const ProcessList* pl, const Process* proc, unsigned int static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_t parentFd, const char* dirname, const Process* parent, double period) { ProcessList* pl = (ProcessList*) this; - const struct dirent* entry; - const Settings* settings = pl->settings; + const Machine* host = pl->host; + const Settings* settings = host->settings; const ScreenSettings* ss = settings->ss; + const struct dirent* entry; #ifdef HAVE_OPENAT int dirFd = openat(parentFd, dirname, O_RDONLY | O_DIRECTORY | O_NOFOLLOW); @@ -1457,7 +1459,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ return false; } - const unsigned int activeCPUs = pl->activeCPUs; + const unsigned int activeCPUs = host->activeCPUs; const bool hideKernelThreads = settings->hideKernelThreads; const bool hideUserlandThreads = settings->hideUserlandThreads; const bool hideRunningInContainer = settings->hideRunningInContainer; @@ -1543,7 +1545,7 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ bool scanMainThread = !hideUserlandThreads && !Process_isKernelThread(proc) && !parent; if (ss->flags & PROCESS_FLAG_IO) - LinuxProcessList_readIoFile(lp, procFd, scanMainThread, pl->realtimeMs); + LinuxProcessList_readIoFile(lp, procFd, scanMainThread, host->realtimeMs); if (!LinuxProcessList_readStatmFile(lp, procFd)) goto errorReadingProcess; @@ -1552,15 +1554,15 @@ static bool LinuxProcessList_recurseProcTree(LinuxProcessList* this, openat_arg_ bool prev = proc->usesDeletedLib; if (!proc->isKernelThread && !proc->isUserlandThread && - ((ss->flags & PROCESS_FLAG_LINUX_LRS_FIX) || (settings->highlightDeletedExe && !proc->procExeDeleted && isOlderThan(pl, proc, 10)))) { + ((ss->flags & PROCESS_FLAG_LINUX_LRS_FIX) || (settings->highlightDeletedExe && !proc->procExeDeleted && isOlderThan(host, proc, 10)))) { // Check if we really should recalculate the M_LRS value for this process - uint64_t passedTimeInMs = pl->realtimeMs - lp->last_mlrs_calctime; + uint64_t passedTimeInMs = host->realtimeMs - lp->last_mlrs_calctime; uint64_t recheck = ((uint64_t)rand()) % 2048; if (passedTimeInMs > recheck) { - lp->last_mlrs_calctime = pl->realtimeMs; + lp->last_mlrs_calctime = host->realtimeMs; LinuxProcessList_readMaps(lp, procFd, ss->flags & PROCESS_FLAG_LINUX_LRS_FIX, settings->highlightDeletedExe); } } else { @@ -1610,10 +1612,10 @@ 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, activeCPUs * 100.0F); - proc->percent_mem = proc->m_resident / (double)(pl->totalMem) * 100.0; + proc->percent_mem = proc->m_resident / (double)(host->totalMem) * 100.0; Process_updateCPUFieldWidths(proc->percent_cpu); - if (! LinuxProcessList_updateUser(pl, proc, procFd)) + if (! LinuxProcessList_updateUser(host, proc, procFd)) goto errorReadingProcess; if (!LinuxProcessList_readStatusFile(proc, procFd)) @@ -1733,6 +1735,7 @@ errorReadingProcess: } static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { + Machine* host = this->host; LinuxProcessList *lpl = (LinuxProcessList *)this; memory_t availableMem = 0; memory_t freeMem = 0; @@ -1809,16 +1812,16 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { * - Shmem in part of Cached (see https://lore.kernel.org/patchwork/patch/648763/), * do not show twice by subtracting from Cached and do not subtract twice from used. */ - this->totalMem = totalMem; - this->cachedMem = cachedMem + sreclaimableMem - sharedMem; - this->sharedMem = sharedMem; + host->totalMem = totalMem; + host->cachedMem = cachedMem + sreclaimableMem - sharedMem; + host->sharedMem = sharedMem; const memory_t usedDiff = freeMem + cachedMem + sreclaimableMem + buffersMem; - this->usedMem = (totalMem >= usedDiff) ? totalMem - usedDiff : totalMem - freeMem; - this->buffersMem = buffersMem; - this->availableMem = availableMem != 0 ? MINIMUM(availableMem, totalMem) : freeMem; - this->totalSwap = swapTotalMem; - this->usedSwap = swapTotalMem - swapFreeMem - swapCacheMem; - this->cachedSwap = swapCacheMem; + host->usedMem = (totalMem >= usedDiff) ? totalMem - usedDiff : totalMem - freeMem; + host->buffersMem = buffersMem; + host->availableMem = availableMem != 0 ? MINIMUM(availableMem, totalMem) : freeMem; + host->totalSwap = swapTotalMem; + host->usedSwap = swapTotalMem - swapFreeMem - swapCacheMem; + host->cachedSwap = swapCacheMem; lpl->zswap.usedZswapComp = zswapCompMem; lpl->zswap.usedZswapOrig = zswapOrigMem; } @@ -1880,6 +1883,7 @@ static void LinuxProcessList_scanHugePages(LinuxProcessList* this) { } static inline void LinuxProcessList_scanZswapInfo(LinuxProcessList *this) { + const Machine* host = this->super.host; long max_pool_percent = 0; int r; char buf[256]; @@ -1893,7 +1897,7 @@ static inline void LinuxProcessList_scanZswapInfo(LinuxProcessList *this) { return; } - this->zswap.totalZswapPool = this->super.totalMem * max_pool_percent / 100; + this->zswap.totalZswapPool = host->totalMem * max_pool_percent / 100; /* the rest of the metrics are set in LinuxProcessList_scanMemoryInfo() */ } @@ -2027,7 +2031,8 @@ static inline double LinuxProcessList_scanCPUTime(ProcessList* super) { if (!file) CRT_fatalError("Cannot open " PROCSTATFILE); - unsigned int existingCPUs = super->existingCPUs; + Machine* host = super->host; + unsigned int existingCPUs = host->existingCPUs; unsigned int lastAdjCpuId = 0; for (unsigned int i = 0; i <= existingCPUs; i++) { @@ -2056,7 +2061,7 @@ static inline double LinuxProcessList_scanCPUTime(ProcessList* super) { adjCpuId = cpuid + 1; } - if (adjCpuId > super->existingCPUs) + if (adjCpuId > host->existingCPUs) break; for (unsigned int j = lastAdjCpuId + 1; j < adjCpuId; j++) { @@ -2104,7 +2109,7 @@ static inline double LinuxProcessList_scanCPUTime(ProcessList* super) { cpuData->totalTime = totaltime; } - double period = (double)this->cpuData[0].totalPeriod / super->activeCPUs; + double period = (double)this->cpuData[0].totalPeriod / host->activeCPUs; char buffer[PROC_LINE_LENGTH + 1]; while (fgets(buffer, sizeof(buffer), file)) { @@ -2120,7 +2125,8 @@ static inline double LinuxProcessList_scanCPUTime(ProcessList* super) { } static int scanCPUFrequencyFromSysCPUFreq(LinuxProcessList* this) { - unsigned int existingCPUs = this->super.existingCPUs; + const Machine* host = this->super.host; + unsigned int existingCPUs = host->existingCPUs; int numCPUsWithFrequency = 0; unsigned long totalFrequency = 0; @@ -2139,7 +2145,7 @@ static int scanCPUFrequencyFromSysCPUFreq(LinuxProcessList* this) { } for (unsigned int i = 0; i < existingCPUs; ++i) { - if (!ProcessList_isCPUonline(&this->super, i)) + if (!Machine_isCPUonline(host, i)) continue; char pathBuffer[64]; @@ -2187,7 +2193,7 @@ static void scanCPUFrequencyFromCPUinfo(LinuxProcessList* this) { if (file == NULL) return; - unsigned int existingCPUs = this->super.existingCPUs; + unsigned int existingCPUs = this->super.host->existingCPUs; int numCPUsWithFrequency = 0; double totalFrequency = 0; int cpuid = -1; @@ -2228,7 +2234,7 @@ static void scanCPUFrequencyFromCPUinfo(LinuxProcessList* this) { } static void LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) { - unsigned int existingCPUs = this->super.existingCPUs; + unsigned int existingCPUs = this->super.host->existingCPUs; for (unsigned int i = 0; i <= existingCPUs; i++) { this->cpuData[i].frequency = NAN; @@ -2243,7 +2249,9 @@ static void LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) { void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { LinuxProcessList* this = (LinuxProcessList*) super; - const Settings* settings = super->settings; + + const Machine* host = super->host; + const Settings* settings = host->settings; LinuxProcessList_scanMemoryInfo(super); LinuxProcessList_scanHugePages(this); @@ -2259,7 +2267,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { #ifdef HAVE_SENSORS_SENSORS_H if (settings->showCPUTemperature) - LibSensors_getCPUTemperatures(this->cpuData, this->super.existingCPUs, this->super.activeCPUs); + LibSensors_getCPUTemperatures(this->cpuData, host->existingCPUs, host->activeCPUs); #endif // in pause mode only gather global data for meters (CPU/memory/...) @@ -2288,9 +2296,19 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { LinuxProcessList_recurseProcTree(this, rootFd, PROCDIR, NULL, period); } -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 LinuxProcessList* this = (const LinuxProcessList*) super; + const LinuxProcessList* this = (const LinuxProcessList*) host->pl; return this->cpuData[id + 1].online; } diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h index 9cfdf24a..69bae5c0 100644 --- a/linux/LinuxProcessList.h +++ b/linux/LinuxProcessList.h @@ -117,12 +117,16 @@ typedef struct LinuxProcessList_ { #define PROC_LINE_LENGTH 4096 #endif -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 diff --git a/linux/Platform.c b/linux/Platform.c index 782f1546..68cefce9 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -304,7 +304,8 @@ int Platform_getMaxPid(void) { } double Platform_setCPUValues(Meter* this, unsigned int cpu) { - const LinuxProcessList* pl = (const LinuxProcessList*) this->pl; + const Machine* host = this->host; + const LinuxProcessList* pl = (const LinuxProcessList*) host->pl; const CPUData* cpuData = &(pl->cpuData[cpu]); double total = (double) ( cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod); double percent; @@ -317,7 +318,7 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { v[CPU_METER_NICE] = cpuData->nicePeriod / total * 100.0; v[CPU_METER_NORMAL] = cpuData->userPeriod / total * 100.0; - if (this->pl->settings->detailedCPUTime) { + if (host->settings->detailedCPUTime) { v[CPU_METER_KERNEL] = cpuData->systemPeriod / total * 100.0; v[CPU_METER_IRQ] = cpuData->irqPeriod / total * 100.0; v[CPU_METER_SOFTIRQ] = cpuData->softIrqPeriod / total * 100.0; @@ -326,7 +327,7 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { v[CPU_METER_IOWAIT] = cpuData->ioWaitPeriod / total * 100.0; this->curItems = 8; percent = v[CPU_METER_NICE] + v[CPU_METER_NORMAL] + v[CPU_METER_KERNEL] + v[CPU_METER_IRQ] + v[CPU_METER_SOFTIRQ]; - if (this->pl->settings->accountGuestInCPUMeter) { + if (host->settings->accountGuestInCPUMeter) { percent += v[CPU_METER_STEAL] + v[CPU_METER_GUEST]; } } else { @@ -352,16 +353,16 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { } void Platform_setMemoryValues(Meter* this) { - const ProcessList* pl = this->pl; - const LinuxProcessList* lpl = (const LinuxProcessList*) pl; + const Machine* host = this->host; + const LinuxProcessList* lpl = (const LinuxProcessList*) host->pl; - this->total = pl->totalMem; - this->values[MEMORY_METER_USED] = pl->usedMem; - this->values[MEMORY_METER_BUFFERS] = pl->buffersMem; - this->values[MEMORY_METER_SHARED] = pl->sharedMem; + this->total = host->totalMem; + this->values[MEMORY_METER_USED] = host->usedMem; + this->values[MEMORY_METER_BUFFERS] = host->buffersMem; + this->values[MEMORY_METER_SHARED] = host->sharedMem; this->values[MEMORY_METER_COMPRESSED] = 0; /* compressed */ - this->values[MEMORY_METER_CACHE] = pl->cachedMem; - this->values[MEMORY_METER_AVAILABLE] = pl->availableMem; + this->values[MEMORY_METER_CACHE] = host->cachedMem; + this->values[MEMORY_METER_AVAILABLE] = host->availableMem; if (lpl->zfs.enabled != 0 && !Running_containerized) { // ZFS does not shrink below the value of zfs_arc_min. @@ -380,12 +381,12 @@ void Platform_setMemoryValues(Meter* this) { } void Platform_setSwapValues(Meter* this) { - const ProcessList* pl = this->pl; - const LinuxProcessList* lpl = (const LinuxProcessList*) pl; + const Machine* host = this->host; + const LinuxProcessList* lpl = (const LinuxProcessList*) host->pl; - this->total = pl->totalSwap; - this->values[SWAP_METER_USED] = pl->usedSwap; - this->values[SWAP_METER_CACHE] = pl->cachedSwap; + this->total = host->totalSwap; + this->values[SWAP_METER_USED] = host->usedSwap; + this->values[SWAP_METER_CACHE] = host->cachedSwap; this->values[SWAP_METER_FRONTSWAP] = 0; /* frontswap -- memory that is accounted to swap but resides elsewhere */ if (lpl->zswap.usedZswapOrig > 0 || lpl->zswap.usedZswapComp > 0) { @@ -410,20 +411,20 @@ void Platform_setSwapValues(Meter* this) { } void Platform_setZramValues(Meter* this) { - const LinuxProcessList* lpl = (const LinuxProcessList*) this->pl; + const LinuxProcessList* lpl = (const LinuxProcessList*) this->host->pl; this->total = lpl->zram.totalZram; this->values[ZRAM_METER_COMPRESSED] = lpl->zram.usedZramComp; this->values[ZRAM_METER_UNCOMPRESSED] = lpl->zram.usedZramOrig; } void Platform_setZfsArcValues(Meter* this) { - const LinuxProcessList* lpl = (const LinuxProcessList*) this->pl; + const LinuxProcessList* lpl = (const LinuxProcessList*) this->host->pl; ZfsArcMeter_readStats(this, &(lpl->zfs)); } void Platform_setZfsCompressedArcValues(Meter* this) { - const LinuxProcessList* lpl = (const LinuxProcessList*) this->pl; + const LinuxProcessList* lpl = (const LinuxProcessList*) this->host->pl; ZfsCompressedArcMeter_readStats(this, &(lpl->zfs)); } diff --git a/netbsd/NetBSDProcess.c b/netbsd/NetBSDProcess.c index 4d4ac4ee..bdb0f50c 100644 --- a/netbsd/NetBSDProcess.c +++ b/netbsd/NetBSDProcess.c @@ -212,10 +212,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { }; -Process* NetBSDProcess_new(const Settings* settings) { +Process* NetBSDProcess_new(const Machine* host) { NetBSDProcess* this = xCalloc(1, sizeof(NetBSDProcess)); Object_setClass(this, Class(NetBSDProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, host); return &this->super; } diff --git a/netbsd/NetBSDProcess.h b/netbsd/NetBSDProcess.h index b9e6b26a..1c068a4a 100644 --- a/netbsd/NetBSDProcess.h +++ b/netbsd/NetBSDProcess.h @@ -12,9 +12,9 @@ in the source distribution for its full text. #include +#include "Machine.h" #include "Object.h" #include "Process.h" -#include "Settings.h" typedef struct NetBSDProcess_ { @@ -25,7 +25,7 @@ extern const ProcessClass NetBSDProcess_class; extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; -Process* NetBSDProcess_new(const Settings* settings); +Process* NetBSDProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/netbsd/NetBSDProcessList.c b/netbsd/NetBSDProcessList.c index 381672d6..b7b6915a 100644 --- a/netbsd/NetBSDProcessList.c +++ b/netbsd/NetBSDProcessList.c @@ -54,6 +54,7 @@ static const struct { static void NetBSDProcessList_updateCPUcount(ProcessList* super) { NetBSDProcessList* opl = (NetBSDProcessList*) super; + Machine* host = super->host; // Definitions for sysctl(3), cf. https://nxr.netbsd.org/xref/src/sys/sys/sysctl.h#813 const int mib_ncpu_existing[] = { CTL_HW, HW_NCPU }; // Number of existing CPUs @@ -72,8 +73,8 @@ static void NetBSDProcessList_updateCPUcount(ProcessList* super) { value = 1; } - if (value != super->activeCPUs) { - super->activeCPUs = value; + if (value != host->activeCPUs) { + host->activeCPUs = value; change = true; } @@ -81,12 +82,12 @@ static void NetBSDProcessList_updateCPUcount(ProcessList* super) { size = sizeof(value); r = sysctl(mib_ncpu_existing, 2, &value, &size, NULL, 0); if (r < 0 || value < 1) { - value = super->activeCPUs; + value = host->activeCPUs; } - if (value != super->existingCPUs) { + if (value != host->existingCPUs) { opl->cpuData = xReallocArray(opl->cpuData, value + 1, sizeof(CPUData)); - super->existingCPUs = value; + host->existingCPUs = value; change = true; } @@ -97,7 +98,7 @@ static void NetBSDProcessList_updateCPUcount(ProcessList* super) { dAvg->totalTime = 1; dAvg->totalPeriod = 1; - for (unsigned int i = 0; i < super->existingCPUs; i++) { + for (unsigned int i = 0; i < host->existingCPUs; i++) { CPUData* d = &opl->cpuData[i + 1]; memset(d, '\0', sizeof(CPUData)); d->totalTime = 1; @@ -106,14 +107,14 @@ static void NetBSDProcessList_updateCPUcount(ProcessList* super) { } } -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { const int fmib[] = { CTL_KERN, KERN_FSCALE }; size_t size; char errbuf[_POSIX2_LINE_MAX]; NetBSDProcessList* npl = xCalloc(1, sizeof(NetBSDProcessList)); ProcessList* pl = (ProcessList*) npl; - ProcessList_init(pl, Class(NetBSDProcess), usersTable, pidMatchList, userId); + ProcessList_init(pl, Class(NetBSDProcess), host, pidMatchList); NetBSDProcessList_updateCPUcount(pl); @@ -147,7 +148,7 @@ void ProcessList_delete(ProcessList* this) { free(this); } -static void NetBSDProcessList_scanMemoryInfo(ProcessList* pl) { +static void NetBSDProcessList_scanMemoryInfo(Machine* host) { static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP2}; struct uvmexp_sysctl uvmexp; size_t size_uvmexp = sizeof(uvmexp); @@ -156,12 +157,12 @@ static void NetBSDProcessList_scanMemoryInfo(ProcessList* pl) { CRT_fatalError("uvmexp sysctl call failed"); } - pl->totalMem = uvmexp.npages * pageSizeKB; - pl->buffersMem = 0; - pl->cachedMem = (uvmexp.filepages + uvmexp.execpages) * pageSizeKB; - pl->usedMem = (uvmexp.active + uvmexp.wired) * pageSizeKB; - pl->totalSwap = uvmexp.swpages * pageSizeKB; - pl->usedSwap = uvmexp.swpginuse * pageSizeKB; + host->totalMem = uvmexp.npages * pageSizeKB; + host->buffersMem = 0; + host->cachedMem = (uvmexp.filepages + uvmexp.execpages) * pageSizeKB; + host->usedMem = (uvmexp.active + uvmexp.wired) * pageSizeKB; + host->totalSwap = uvmexp.swpages * pageSizeKB; + host->usedSwap = uvmexp.swpginuse * pageSizeKB; } static void NetBSDProcessList_updateExe(const struct kinfo_proc2* kproc, Process* proc) { @@ -262,7 +263,8 @@ static double getpcpu(const struct kinfo_proc2* kp) { } static void NetBSDProcessList_scanProcs(NetBSDProcessList* this) { - const Settings* settings = this->super.settings; + const Machine* host = this->super.host; + const Settings* settings = host->settings; bool hideKernelThreads = settings->hideKernelThreads; bool hideUserlandThreads = settings->hideUserlandThreads; int count = 0; @@ -313,14 +315,14 @@ static void NetBSDProcessList_scanProcs(NetBSDProcessList* this) { if (proc->st_uid != kproc->p_uid) { proc->st_uid = kproc->p_uid; - proc->user = UsersTable_getRef(this->super.usersTable, proc->st_uid); + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); } proc->m_virt = kproc->p_vm_vsize; proc->m_resident = kproc->p_vm_rssize; - proc->percent_mem = (proc->m_resident * pageSizeKB) / (double)(this->super.totalMem) * 100.0; - proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0, this->super.activeCPUs * 100.0); + proc->percent_mem = (proc->m_resident * pageSizeKB) / (double)(host->totalMem) * 100.0; + proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0, host->activeCPUs * 100.0); Process_updateCPUFieldWidths(proc->percent_cpu); proc->nlwp = kproc->p_nlwps; @@ -411,10 +413,11 @@ static void kernelCPUTimesToHtop(const u_int64_t* times, CPUData* cpu) { } static void NetBSDProcessList_scanCPUTime(NetBSDProcessList* this) { + const Machine* host = this->super.host; u_int64_t kernelTimes[CPUSTATES] = {0}; u_int64_t avg[CPUSTATES] = {0}; - for (unsigned int i = 0; i < this->super.existingCPUs; i++) { + for (unsigned int i = 0; i < host->existingCPUs; i++) { getKernelCPUTimes(i, kernelTimes); CPUData* cpu = &this->cpuData[i + 1]; kernelCPUTimesToHtop(kernelTimes, cpu); @@ -427,14 +430,15 @@ static void NetBSDProcessList_scanCPUTime(NetBSDProcessList* this) { } for (int i = 0; i < CPUSTATES; i++) { - avg[i] /= this->super.activeCPUs; + avg[i] /= host->activeCPUs; } kernelCPUTimesToHtop(avg, &this->cpuData[0]); } static void NetBSDProcessList_scanCPUFrequency(NetBSDProcessList* this) { - unsigned int cpus = this->super.existingCPUs; + const Machine* host = this->super.host; + unsigned int cpus = host->existingCPUs; bool match = false; char name[64]; long int freq = 0; @@ -481,7 +485,7 @@ static void NetBSDProcessList_scanCPUFrequency(NetBSDProcessList* this) { void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { NetBSDProcessList* npl = (NetBSDProcessList*) super; - NetBSDProcessList_scanMemoryInfo(super); + NetBSDProcessList_scanMemoryInfo(super->host); NetBSDProcessList_scanCPUTime(npl); if (super->settings->showCPUFrequency) { @@ -496,8 +500,18 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { NetBSDProcessList_scanProcs(npl); } -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); // TODO: Support detecting online / offline CPUs. return true; diff --git a/netbsd/NetBSDProcessList.h b/netbsd/NetBSDProcessList.h index d5a757fe..0fe18b03 100644 --- a/netbsd/NetBSDProcessList.h +++ b/netbsd/NetBSDProcessList.h @@ -49,10 +49,16 @@ typedef struct NetBSDProcessList_ { } NetBSDProcessList; -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList); void ProcessList_delete(ProcessList* this); void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate); +Machine* Machine_new(UsersTable* usersTable, uid_t userId); + +bool Machine_isCPUonline(const Machine* host, unsigned int id); + +void Machine_delete(Machine* host); + #endif diff --git a/netbsd/Platform.c b/netbsd/Platform.c index 1cf16067..ea81a26a 100644 --- a/netbsd/Platform.c +++ b/netbsd/Platform.c @@ -237,7 +237,8 @@ int Platform_getMaxPid(void) { } double Platform_setCPUValues(Meter* this, int cpu) { - const NetBSDProcessList* npl = (const NetBSDProcessList*) this->pl; + const Machine* host = this->host; + const NetBSDProcessList* npl = (const NetBSDProcessList*) host->pl; const CPUData* cpuData = &npl->cpuData[cpu]; double total = cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod; double totalPercent; @@ -245,7 +246,7 @@ double Platform_setCPUValues(Meter* this, int cpu) { v[CPU_METER_NICE] = cpuData->nicePeriod / total * 100.0; v[CPU_METER_NORMAL] = cpuData->userPeriod / total * 100.0; - if (this->pl->settings->detailedCPUTime) { + if (host->settings->detailedCPUTime) { v[CPU_METER_KERNEL] = cpuData->sysPeriod / total * 100.0; v[CPU_METER_IRQ] = cpuData->intrPeriod / total * 100.0; v[CPU_METER_SOFTIRQ] = 0.0; @@ -269,20 +270,20 @@ double Platform_setCPUValues(Meter* this, 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" } diff --git a/openbsd/OpenBSDProcess.c b/openbsd/OpenBSDProcess.c index c2f2ed4c..0875dc00 100644 --- a/openbsd/OpenBSDProcess.c +++ b/openbsd/OpenBSDProcess.c @@ -204,10 +204,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { }; -Process* OpenBSDProcess_new(const Settings* settings) { +Process* OpenBSDProcess_new(const Machine* host) { OpenBSDProcess* this = xCalloc(1, sizeof(OpenBSDProcess)); Object_setClass(this, Class(OpenBSDProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, host); return &this->super; } diff --git a/openbsd/OpenBSDProcess.h b/openbsd/OpenBSDProcess.h index 898c5377..aac4b318 100644 --- a/openbsd/OpenBSDProcess.h +++ b/openbsd/OpenBSDProcess.h @@ -10,9 +10,9 @@ in the source distribution for its full text. #include +#include "Machine.h" #include "Object.h" #include "Process.h" -#include "Settings.h" typedef struct OpenBSDProcess_ { @@ -26,7 +26,7 @@ extern const ProcessClass OpenBSDProcess_class; extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; -Process* OpenBSDProcess_new(const Settings* settings); +Process* OpenBSDProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/openbsd/OpenBSDProcessList.c b/openbsd/OpenBSDProcessList.c index 6ad3a760..c83eb543 100644 --- a/openbsd/OpenBSDProcessList.c +++ b/openbsd/OpenBSDProcessList.c @@ -38,6 +38,7 @@ static int pageSizeKB; static void OpenBSDProcessList_updateCPUcount(ProcessList* super) { OpenBSDProcessList* opl = (OpenBSDProcessList*) super; + Machine* host = super->host; const int nmib[] = { CTL_HW, HW_NCPU }; const int mib[] = { CTL_HW, HW_NCPUONLINE }; int r; @@ -51,20 +52,20 @@ static void OpenBSDProcessList_updateCPUcount(ProcessList* super) { value = 1; } - if (value != super->activeCPUs) { - super->activeCPUs = value; + if (value != host->activeCPUs) { + host->activeCPUs = value; change = true; } size = sizeof(value); r = sysctl(nmib, 2, &value, &size, NULL, 0); if (r < 0 || value < 1) { - value = super->activeCPUs; + value = host->activeCPUs; } - if (value != super->existingCPUs) { + if (value != host->existingCPUs) { opl->cpuData = xReallocArray(opl->cpuData, value + 1, sizeof(CPUData)); - super->existingCPUs = value; + host->existingCPUs = value; change = true; } @@ -75,7 +76,7 @@ static void OpenBSDProcessList_updateCPUcount(ProcessList* super) { dAvg->totalPeriod = 1; dAvg->online = true; - for (unsigned int i = 0; i < super->existingCPUs; i++) { + for (unsigned int i = 0; i < host->existingCPUs; i++) { CPUData* d = &opl->cpuData[i + 1]; memset(d, '\0', sizeof(CPUData)); d->totalTime = 1; @@ -94,14 +95,14 @@ static void OpenBSDProcessList_updateCPUcount(ProcessList* super) { } -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { const int fmib[] = { CTL_KERN, KERN_FSCALE }; size_t size; char errbuf[_POSIX2_LINE_MAX]; OpenBSDProcessList* opl = xCalloc(1, sizeof(OpenBSDProcessList)); ProcessList* pl = (ProcessList*) opl; - ProcessList_init(pl, Class(OpenBSDProcess), usersTable, pidMatchList, userId); + ProcessList_init(pl, Class(OpenBSDProcess), host, pidMatchList); OpenBSDProcessList_updateCPUcount(pl); @@ -138,6 +139,7 @@ void ProcessList_delete(ProcessList* this) { } static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) { + Machine* host = pl->host; const int uvmexp_mib[] = { CTL_VM, VM_UVMEXP }; struct uvmexp uvmexp; size_t size_uvmexp = sizeof(uvmexp); @@ -146,8 +148,8 @@ static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) { CRT_fatalError("uvmexp sysctl call failed"); } - pl->totalMem = uvmexp.npages * pageSizeKB; - pl->usedMem = (uvmexp.npages - uvmexp.free - uvmexp.paging) * pageSizeKB; + host->totalMem = uvmexp.npages * pageSizeKB; + host->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 }; @@ -158,7 +160,7 @@ static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) { CRT_fatalError("cannot get vfs.bcachestat"); } - pl->cachedMem = bcstats.numbufpages * pageSizeKB; + host->cachedMem = bcstats.numbufpages * pageSizeKB; /* * Copyright (c) 1994 Thorsten Lockert @@ -183,10 +185,10 @@ static void OpenBSDProcessList_scanMemoryInfo(ProcessList* pl) { } } - pl->totalSwap = total; - pl->usedSwap = used; + host->totalSwap = total; + host->usedSwap = used; } else { - pl->totalSwap = pl->usedSwap = 0; + host->totalSwap = host->usedSwap = 0; } } @@ -270,7 +272,8 @@ static double getpcpu(const struct kinfo_proc* kp) { } static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { - const Settings* settings = this->super.settings; + Machine* host = this->super.host; + const Settings* settings = host->settings; const bool hideKernelThreads = settings->hideKernelThreads; const bool hideUserlandThreads = settings->hideUserlandThreads; int count = 0; @@ -331,8 +334,8 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { proc->m_virt = kproc->p_vm_dsize * pageSizeKB; proc->m_resident = kproc->p_vm_rssize * pageSizeKB; - proc->percent_mem = proc->m_resident / (float)this->super.totalMem * 100.0F; - proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0F, this->super.activeCPUs * 100.0F); + proc->percent_mem = proc->m_resident / (float)host->totalMem * 100.0F; + proc->percent_cpu = CLAMP(getpcpu(kproc), 0.0F, host->activeCPUs * 100.0F); Process_updateCPUFieldWidths(proc->percent_cpu); proc->nice = kproc->p_nice - 20; @@ -345,7 +348,7 @@ static void OpenBSDProcessList_scanProcs(OpenBSDProcessList* this) { if (proc->st_uid != kproc->p_uid) { proc->st_uid = kproc->p_uid; - proc->user = UsersTable_getRef(this->super.usersTable, proc->st_uid); + proc->user = UsersTable_getRef(host->usersTable, proc->st_uid); } /* Taken from: https://github.com/openbsd/src/blob/6a38af0976a6870911f4b2de19d8da28723a5778/sys/sys/proc.h#L420 */ @@ -422,10 +425,11 @@ static void kernelCPUTimesToHtop(const u_int64_t* times, CPUData* cpu) { } static void OpenBSDProcessList_scanCPUTime(OpenBSDProcessList* this) { + Machine* host = this->super.host; u_int64_t kernelTimes[CPUSTATES] = {0}; u_int64_t avg[CPUSTATES] = {0}; - for (unsigned int i = 0; i < this->super.existingCPUs; i++) { + for (unsigned int i = 0; i < host->existingCPUs; i++) { CPUData* cpu = &this->cpuData[i + 1]; if (!cpu->online) { @@ -446,7 +450,7 @@ static void OpenBSDProcessList_scanCPUTime(OpenBSDProcessList* this) { } for (int i = 0; i < CPUSTATES; i++) { - avg[i] /= this->super.activeCPUs; + avg[i] /= host->activeCPUs; } kernelCPUTimesToHtop(avg, &this->cpuData[0]); @@ -478,9 +482,19 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { OpenBSDProcessList_scanProcs(opl); } -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 OpenBSDProcessList* opl = (const OpenBSDProcessList*) super; + const OpenBSDProcessList* opl = (const OpenBSDProcessList*) host->pl; return opl->cpuData[id + 1].online; } diff --git a/openbsd/OpenBSDProcessList.h b/openbsd/OpenBSDProcessList.h index 99de96cd..6ca2ba2c 100644 --- a/openbsd/OpenBSDProcessList.h +++ b/openbsd/OpenBSDProcessList.h @@ -49,12 +49,16 @@ typedef struct OpenBSDProcessList_ { } OpenBSDProcessList; -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList); void ProcessList_delete(ProcessList* this); 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 diff --git a/openbsd/Platform.c b/openbsd/Platform.c index 707d2106..03c36856 100644 --- a/openbsd/Platform.c +++ b/openbsd/Platform.c @@ -181,7 +181,8 @@ int Platform_getMaxPid(void) { } double Platform_setCPUValues(Meter* this, unsigned int cpu) { - const OpenBSDProcessList* pl = (const OpenBSDProcessList*) this->pl; + const Machine* host = this->host; + const OpenBSDProcessList* pl = (const OpenBSDProcessList*) host->pl; const CPUData* cpuData = &(pl->cpuData[cpu]); double total; double totalPercent; @@ -196,7 +197,7 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { v[CPU_METER_NICE] = cpuData->nicePeriod / total * 100.0; v[CPU_METER_NORMAL] = cpuData->userPeriod / total * 100.0; - if (this->pl->settings->detailedCPUTime) { + if (host->settings->detailedCPUTime) { v[CPU_METER_KERNEL] = cpuData->sysPeriod / total * 100.0; v[CPU_METER_IRQ] = cpuData->intrPeriod / total * 100.0; v[CPU_METER_SOFTIRQ] = 0.0; @@ -222,12 +223,12 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) { } void Platform_setMemoryValues(Meter* this) { - const ProcessList* pl = this->pl; - long int usedMem = pl->usedMem; - long int buffersMem = pl->buffersMem; - long int cachedMem = pl->cachedMem; + const Machine* host = this->host; + long int usedMem = host->usedMem; + long int buffersMem = host->buffersMem; + long int cachedMem = host->cachedMem; usedMem -= buffersMem + cachedMem; - this->total = pl->totalMem; + this->total = host->totalMem; this->values[MEMORY_METER_USED] = usedMem; this->values[MEMORY_METER_BUFFERS] = buffersMem; // this->values[MEMORY_METER_SHARED] = "shared memory, like tmpfs and shm" @@ -237,9 +238,9 @@ void Platform_setMemoryValues(Meter* this) { } 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" } diff --git a/pcp/PCPDynamicColumn.c b/pcp/PCPDynamicColumn.c index 8c35fc10..23b896e6 100644 --- a/pcp/PCPDynamicColumn.c +++ b/pcp/PCPDynamicColumn.c @@ -304,7 +304,7 @@ void PCPDynamicColumn_writeField(PCPDynamicColumn* this, const Process* proc, Ri } int PCPDynamicColumn_compareByKey(const PCPProcess* p1, const PCPProcess* p2, ProcessField key) { - const PCPDynamicColumn* column = Hashtable_get(p1->super.settings->dynamicColumns, key); + const PCPDynamicColumn* column = Hashtable_get(p1->super.host->settings->dynamicColumns, key); if (!column) return -1; diff --git a/pcp/PCPProcess.c b/pcp/PCPProcess.c index b8b87cab..cefd0ac3 100644 --- a/pcp/PCPProcess.c +++ b/pcp/PCPProcess.c @@ -88,10 +88,10 @@ const ProcessFieldData Process_fields[] = { [AUTOGROUP_NICE] = { .name = "AUTOGROUP_NICE", .title = " ANI", .description = "Nice value (the higher the value, the more other processes take priority) associated with the process autogroup", .flags = PROCESS_FLAG_LINUX_AUTOGROUP, }, }; -Process* PCPProcess_new(const Settings* settings) { +Process* PCPProcess_new(const Machine* host) { PCPProcess* this = xCalloc(1, sizeof(PCPProcess)); Object_setClass(this, Class(PCPProcess)); - Process_init(&this->super, settings); + Process_init(&this->super, host); return &this->super; } @@ -113,7 +113,7 @@ static void PCPProcess_printDelay(float delay_percent, char* buffer, int n) { static void PCPProcess_writeField(const Process* this, RichString* str, ProcessField field) { const PCPProcess* pp = (const PCPProcess*) this; - bool coloring = this->settings->highlightMegabytes; + bool coloring = this->host->settings->highlightMegabytes; char buffer[256]; buffer[255] = '\0'; int attr = CRT_colors[DEFAULT_COLOR]; int n = sizeof(buffer) - 1; diff --git a/pcp/PCPProcess.h b/pcp/PCPProcess.h index 46ba07fe..be33111e 100644 --- a/pcp/PCPProcess.h +++ b/pcp/PCPProcess.h @@ -13,9 +13,9 @@ in the source distribution for its full text. #include +#include "Machine.h" #include "Object.h" #include "Process.h" -#include "Settings.h" #define PROCESS_FLAG_LINUX_CGROUP 0x00000800 @@ -93,7 +93,7 @@ extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; extern const ProcessClass PCPProcess_class; -Process* PCPProcess_new(const Settings* settings); +Process* PCPProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/pcp/PCPProcessList.c b/pcp/PCPProcessList.c index a5eb64d6..0e345fc0 100644 --- a/pcp/PCPProcessList.c +++ b/pcp/PCPProcessList.c @@ -19,6 +19,7 @@ in the source distribution for its full text. #include #include "Macros.h" +#include "Machine.h" #include "Object.h" #include "Platform.h" #include "Process.h" @@ -30,16 +31,16 @@ in the source distribution for its full text. static void PCPProcessList_updateCPUcount(PCPProcessList* this) { - ProcessList* pl = &(this->super); - pl->activeCPUs = PCPMetric_instanceCount(PCP_PERCPU_SYSTEM); + Machine* host = this->super.host; + host->activeCPUs = PCPMetric_instanceCount(PCP_PERCPU_SYSTEM); unsigned int cpus = Platform_getMaxCPU(); - if (cpus == pl->existingCPUs) + if (cpus == host->existingCPUs) return; if (cpus == 0) - cpus = pl->activeCPUs; + cpus = host->activeCPUs; if (cpus <= 1) - cpus = pl->activeCPUs = 1; - pl->existingCPUs = cpus; + cpus = host->activeCPUs = 1; + host->existingCPUs = cpus; free(this->percpu); free(this->values); @@ -63,11 +64,11 @@ static char* setUser(UsersTable* this, unsigned int uid, int pid, int offset) { return name; } -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { PCPProcessList* this = xCalloc(1, sizeof(PCPProcessList)); ProcessList* super = &(this->super); - ProcessList_init(super, Class(PCPProcess), usersTable, pidMatchList, userId); + ProcessList_init(super, Class(PCPProcess), host, pidMatchList); struct timeval timestamp; gettimeofday(×tamp, NULL); @@ -83,7 +84,7 @@ void ProcessList_delete(ProcessList* pl) { PCPProcessList* this = (PCPProcessList*) pl; ProcessList_done(pl); free(this->values); - for (unsigned int i = 0; i < pl->existingCPUs; i++) + for (unsigned int i = 0; i < pl->host->existingCPUs; i++) free(this->percpu[i]); free(this->percpu); free(this->cpu); @@ -341,7 +342,9 @@ static void PCPProcessList_updateCmdline(Process* process, int pid, int offset, static bool PCPProcessList_updateProcesses(PCPProcessList* this, double period, struct timeval* tv) { ProcessList* pl = (ProcessList*) this; - const Settings* settings = pl->settings; + + Machine* host = pl->host; + const Settings* settings = host->settings; bool hideKernelThreads = settings->hideKernelThreads; bool hideUserlandThreads = settings->hideUserlandThreads; @@ -406,11 +409,11 @@ static bool PCPProcessList_updateProcesses(PCPProcessList* this, double period, float percent_cpu = (pp->utime + pp->stime - lasttimes) / period * 100.0; proc->percent_cpu = isnan(percent_cpu) ? - 0.0 : CLAMP(percent_cpu, 0.0, pl->activeCPUs * 100.0); - proc->percent_mem = proc->m_resident / (double)pl->totalMem * 100.0; + 0.0 : CLAMP(percent_cpu, 0.0, host->activeCPUs * 100.0); + proc->percent_mem = proc->m_resident / (double)host->totalMem * 100.0; Process_updateCPUFieldWidths(proc->percent_cpu); - PCPProcessList_updateUsername(proc, pid, offset, pl->usersTable); + PCPProcessList_updateUsername(proc, pid, offset, host->usersTable); if (!preExisting) { PCPProcessList_updateCmdline(proc, pid, offset, command); @@ -465,39 +468,40 @@ static bool PCPProcessList_updateProcesses(PCPProcessList* this, double period, } static void PCPProcessList_updateMemoryInfo(ProcessList* super) { + Machine* host = super->host; unsigned long long int freeMem = 0; unsigned long long int swapFreeMem = 0; unsigned long long int sreclaimableMem = 0; - super->totalMem = super->usedMem = super->cachedMem = 0; - super->usedSwap = super->totalSwap = super->sharedMem = 0; + host->totalMem = host->usedMem = host->cachedMem = 0; + host->usedSwap = host->totalSwap = host->sharedMem = 0; pmAtomValue value; if (PCPMetric_values(PCP_MEM_TOTAL, &value, 1, PM_TYPE_U64) != NULL) - super->totalMem = value.ull; + host->totalMem = value.ull; if (PCPMetric_values(PCP_MEM_FREE, &value, 1, PM_TYPE_U64) != NULL) freeMem = value.ull; if (PCPMetric_values(PCP_MEM_BUFFERS, &value, 1, PM_TYPE_U64) != NULL) - super->buffersMem = value.ull; + host->buffersMem = value.ull; if (PCPMetric_values(PCP_MEM_SRECLAIM, &value, 1, PM_TYPE_U64) != NULL) sreclaimableMem = value.ull; if (PCPMetric_values(PCP_MEM_SHARED, &value, 1, PM_TYPE_U64) != NULL) - super->sharedMem = value.ull; + host->sharedMem = value.ull; if (PCPMetric_values(PCP_MEM_CACHED, &value, 1, PM_TYPE_U64) != NULL) - super->cachedMem = value.ull + sreclaimableMem - super->sharedMem; - const memory_t usedDiff = freeMem + super->cachedMem + sreclaimableMem + super->buffersMem; - super->usedMem = (super->totalMem >= usedDiff) ? - super->totalMem - usedDiff : super->totalMem - freeMem; + host->cachedMem = value.ull + sreclaimableMem - host->sharedMem; + const memory_t usedDiff = freeMem + host->cachedMem + sreclaimableMem + host->buffersMem; + host->usedMem = (host->totalMem >= usedDiff) ? + host->totalMem - usedDiff : host->totalMem - freeMem; if (PCPMetric_values(PCP_MEM_AVAILABLE, &value, 1, PM_TYPE_U64) != NULL) - super->availableMem = MINIMUM(value.ull, super->totalMem); + host->availableMem = MINIMUM(value.ull, host->totalMem); else - super->availableMem = freeMem; + host->availableMem = freeMem; if (PCPMetric_values(PCP_MEM_SWAPFREE, &value, 1, PM_TYPE_U64) != NULL) swapFreeMem = value.ull; if (PCPMetric_values(PCP_MEM_SWAPTOTAL, &value, 1, PM_TYPE_U64) != NULL) - super->totalSwap = value.ull; + host->totalSwap = value.ull; if (PCPMetric_values(PCP_MEM_SWAPCACHED, &value, 1, PM_TYPE_U64) != NULL) - super->cachedSwap = value.ull; - super->usedSwap = super->totalSwap - swapFreeMem - super->cachedSwap; + host->cachedSwap = value.ull; + host->usedSwap = host->totalSwap - swapFreeMem - host->cachedSwap; } /* make copies of previously sampled values to avoid overwrite */ @@ -576,7 +580,7 @@ static void PCPProcessList_updateAllCPUTime(PCPProcessList* this, PCPMetric metr static void PCPProcessList_updatePerCPUTime(PCPProcessList* this, PCPMetric metric, CPUMetric cpumetric) { - int cpus = this->super.existingCPUs; + int cpus = this->super.host->existingCPUs; if (PCPMetric_values(metric, this->values, cpus, PM_TYPE_U64) == NULL) memset(this->values, 0, cpus * sizeof(pmAtomValue)); for (int i = 0; i < cpus; i++) @@ -585,7 +589,7 @@ static void PCPProcessList_updatePerCPUTime(PCPProcessList* this, PCPMetric metr static void PCPProcessList_updatePerCPUReal(PCPProcessList* this, PCPMetric metric, CPUMetric cpumetric) { - int cpus = this->super.existingCPUs; + int cpus = this->super.host->existingCPUs; if (PCPMetric_values(metric, this->values, cpus, PM_TYPE_DOUBLE) == NULL) memset(this->values, 0, cpus * sizeof(pmAtomValue)); for (int i = 0; i < cpus; i++) @@ -630,6 +634,7 @@ static inline void PCPProcessList_scanZfsArcstats(PCPProcessList* this) { } static void PCPProcessList_updateHeader(ProcessList* super, const Settings* settings) { + Machine* host = super->host; PCPProcessList_updateMemoryInfo(super); PCPProcessList* this = (PCPProcessList*) super; @@ -647,7 +652,7 @@ static void PCPProcessList_updateHeader(ProcessList* super, const Settings* sett PCPProcessList_updateAllCPUTime(this, PCP_CPU_GUEST, CPU_GUEST_TIME); PCPProcessList_deriveCPUTime(this->cpu); - for (unsigned int i = 0; i < super->existingCPUs; i++) + for (unsigned int i = 0; i < host->existingCPUs; i++) PCPProcessList_backupCPUTime(this->percpu[i]); PCPProcessList_updatePerCPUTime(this, PCP_PERCPU_USER, CPU_USER_TIME); PCPProcessList_updatePerCPUTime(this, PCP_PERCPU_NICE, CPU_NICE_TIME); @@ -658,7 +663,7 @@ static void PCPProcessList_updateHeader(ProcessList* super, const Settings* sett PCPProcessList_updatePerCPUTime(this, PCP_PERCPU_SOFTIRQ, CPU_SOFTIRQ_TIME); PCPProcessList_updatePerCPUTime(this, PCP_PERCPU_STEAL, CPU_STEAL_TIME); PCPProcessList_updatePerCPUTime(this, PCP_PERCPU_GUEST, CPU_GUEST_TIME); - for (unsigned int i = 0; i < super->existingCPUs; i++) + for (unsigned int i = 0; i < host->existingCPUs; i++) PCPProcessList_deriveCPUTime(this->percpu[i]); if (settings->showCPUFrequency) @@ -669,7 +674,8 @@ static void PCPProcessList_updateHeader(ProcessList* super, const Settings* sett void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { PCPProcessList* this = (PCPProcessList*) super; - const Settings* settings = super->settings; + Machine* host = super->host; + const Settings* settings = host->settings; bool enabled = !pauseProcessUpdate; bool flagged = settings->showCPUFrequency; @@ -716,9 +722,19 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { PCPProcessList_updateProcesses(this, period, ×tamp); } -bool ProcessList_isCPUonline(const ProcessList* super, unsigned int id) { - assert(id < super->existingCPUs); - (void) super; +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); + (void) host; pmAtomValue value; if (PCPMetric_instance(PCP_PERCPU_SYSTEM, id, id, &value, PM_TYPE_U32)) diff --git a/pcp/PCPProcessList.h b/pcp/PCPProcessList.h index 90e9939c..9bce9cd7 100644 --- a/pcp/PCPProcessList.h +++ b/pcp/PCPProcessList.h @@ -63,12 +63,16 @@ typedef struct PCPProcessList_ { ZfsArcStats zfs; } PCPProcessList; -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 diff --git a/pcp/Platform.c b/pcp/Platform.c index 87de2c2f..181898aa 100644 --- a/pcp/Platform.c +++ b/pcp/Platform.c @@ -485,6 +485,7 @@ long long Platform_getBootTime(void) { } static double Platform_setOneCPUValues(Meter* this, pmAtomValue* values) { + Settings* settings = this->host->settings; unsigned long long value = values[CPU_TOTAL_PERIOD].ull; double total = (double) (value == 0 ? 1 : value); @@ -493,7 +494,7 @@ static double Platform_setOneCPUValues(Meter* this, pmAtomValue* values) { double* v = this->values; v[CPU_METER_NICE] = values[CPU_NICE_PERIOD].ull / total * 100.0; v[CPU_METER_NORMAL] = values[CPU_USER_PERIOD].ull / total * 100.0; - if (this->pl->settings->detailedCPUTime) { + if (settings->detailedCPUTime) { v[CPU_METER_KERNEL] = values[CPU_SYSTEM_PERIOD].ull / total * 100.0; v[CPU_METER_IRQ] = values[CPU_IRQ_PERIOD].ull / total * 100.0; v[CPU_METER_SOFTIRQ] = values[CPU_SOFTIRQ_PERIOD].ull / total * 100.0; @@ -502,7 +503,7 @@ static double Platform_setOneCPUValues(Meter* this, pmAtomValue* values) { v[CPU_METER_IOWAIT] = values[CPU_IOWAIT_PERIOD].ull / total * 100.0; this->curItems = 8; percent = v[CPU_METER_NICE] + v[CPU_METER_NORMAL] + v[CPU_METER_KERNEL] + v[CPU_METER_IRQ] + v[CPU_METER_SOFTIRQ]; - if (this->pl->settings->accountGuestInCPUMeter) { + if (settings->accountGuestInCPUMeter) { percent += v[CPU_METER_STEAL] + v[CPU_METER_GUEST]; } } else { @@ -523,23 +524,24 @@ static double Platform_setOneCPUValues(Meter* this, pmAtomValue* values) { } double Platform_setCPUValues(Meter* this, int cpu) { - const PCPProcessList* pl = (const PCPProcessList*) this->pl; + const PCPProcessList* pl = (const PCPProcessList*) this->host->pl; if (cpu <= 0) /* use aggregate values */ return Platform_setOneCPUValues(this, pl->cpu); return Platform_setOneCPUValues(this, pl->percpu[cpu - 1]); } void Platform_setMemoryValues(Meter* this) { - const ProcessList* pl = this->pl; + const Machine* host = this->host; + const ProcessList* pl = host->pl; const PCPProcessList* ppl = (const PCPProcessList*) pl; - this->total = pl->totalMem; - this->values[MEMORY_METER_USED] = pl->usedMem; - this->values[MEMORY_METER_BUFFERS] = pl->buffersMem; - this->values[MEMORY_METER_SHARED] = pl->sharedMem; + this->total = host->totalMem; + this->values[MEMORY_METER_USED] = host->usedMem; + this->values[MEMORY_METER_BUFFERS] = host->buffersMem; + this->values[MEMORY_METER_SHARED] = host->sharedMem; // this->values[MEMORY_METER_COMPRESSED] = "compressed memory, like zswap on linux" - this->values[MEMORY_METER_CACHE] = pl->cachedMem; - this->values[MEMORY_METER_AVAILABLE] = pl->availableMem; + this->values[MEMORY_METER_CACHE] = host->cachedMem; + this->values[MEMORY_METER_AVAILABLE] = host->availableMem; if (ppl->zfs.enabled != 0) { // ZFS does not shrink below the value of zfs_arc_min. @@ -553,10 +555,10 @@ void Platform_setMemoryValues(Meter* this) { } void Platform_setSwapValues(Meter* this) { - const ProcessList* pl = this->pl; - this->total = pl->totalSwap; - this->values[SWAP_METER_USED] = pl->usedSwap; - this->values[SWAP_METER_CACHE] = pl->cachedSwap; + const Machine* host = this->host; + this->total = host->totalSwap; + this->values[SWAP_METER_USED] = host->usedSwap; + this->values[SWAP_METER_CACHE] = host->cachedSwap; // this->values[SWAP_METER_FRONTSWAP] = "pages that are accounted to swap but stored elsewhere, like frontswap on linux" } @@ -593,13 +595,13 @@ void Platform_setZramValues(Meter* this) { } void Platform_setZfsArcValues(Meter* this) { - const PCPProcessList* ppl = (const PCPProcessList*) this->pl; + const PCPProcessList* ppl = (const PCPProcessList*) this->host->pl; ZfsArcMeter_readStats(this, &(ppl->zfs)); } void Platform_setZfsCompressedArcValues(Meter* this) { - const PCPProcessList* ppl = (const PCPProcessList*) this->pl; + const PCPProcessList* ppl = (const PCPProcessList*) this->host->pl; ZfsCompressedArcMeter_readStats(this, &(ppl->zfs)); } 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 diff --git a/unsupported/UnsupportedProcess.c b/unsupported/UnsupportedProcess.c index 2aca0488..4d8cb080 100644 --- a/unsupported/UnsupportedProcess.c +++ b/unsupported/UnsupportedProcess.c @@ -44,10 +44,10 @@ const ProcessFieldData Process_fields[LAST_PROCESSFIELD] = { [TGID] = { .name = "TGID", .title = "TGID", .description = "Thread group ID (i.e. process ID)", .flags = 0, .pidColumn = true, }, }; -Process* UnsupportedProcess_new(const Settings* settings) { +Process* UnsupportedProcess_new(const Machine* host) { Process* this = xCalloc(1, sizeof(UnsupportedProcess)); Object_setClass(this, Class(UnsupportedProcess)); - Process_init(this, settings); + Process_init(this, host); return this; } @@ -60,7 +60,7 @@ void Process_delete(Object* cast) { static void UnsupportedProcess_writeField(const Process* this, RichString* str, ProcessField field) { const UnsupportedProcess* up = (const UnsupportedProcess*) this; - bool coloring = this->settings->highlightMegabytes; + bool coloring = this->host->settings->highlightMegabytes; char buffer[256]; buffer[255] = '\0'; int attr = CRT_colors[DEFAULT_COLOR]; size_t n = sizeof(buffer) - 1; diff --git a/unsupported/UnsupportedProcess.h b/unsupported/UnsupportedProcess.h index e30169c5..21956ddd 100644 --- a/unsupported/UnsupportedProcess.h +++ b/unsupported/UnsupportedProcess.h @@ -7,7 +7,7 @@ Released under the GNU GPLv2+, see the COPYING file in the source distribution for its full text. */ -#include "Settings.h" +#include "Machine.h" typedef struct UnsupportedProcess_ { @@ -19,7 +19,7 @@ typedef struct UnsupportedProcess_ { extern const ProcessFieldData Process_fields[LAST_PROCESSFIELD]; -Process* UnsupportedProcess_new(const Settings* settings); +Process* UnsupportedProcess_new(const Machine* host); void Process_delete(Object* cast); diff --git a/unsupported/UnsupportedProcessList.c b/unsupported/UnsupportedProcessList.c index fc226f76..e5b7af6d 100644 --- a/unsupported/UnsupportedProcessList.c +++ b/unsupported/UnsupportedProcessList.c @@ -14,12 +14,12 @@ in the source distribution for its full text. #include "UnsupportedProcess.h" -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList) { ProcessList* this = xCalloc(1, sizeof(ProcessList)); - ProcessList_init(this, Class(Process), usersTable, pidMatchList, userId); + ProcessList_init(this, Class(Process), host, pidMatchList); - this->existingCPUs = 1; - this->activeCPUs = 1; + host->existingCPUs = 1; + host->activeCPUs = 1; return this; } @@ -91,10 +91,20 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { ProcessList_add(super, proc); } -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); - (void) super; (void) id; + (void) host; (void) id; return true; } diff --git a/unsupported/UnsupportedProcessList.h b/unsupported/UnsupportedProcessList.h index 9f4d23aa..cdb0b601 100644 --- a/unsupported/UnsupportedProcessList.h +++ b/unsupported/UnsupportedProcessList.h @@ -10,12 +10,16 @@ in the source distribution for its full text. #include "ProcessList.h" -ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId); +ProcessList* ProcessList_new(Machine* host, Hashtable* pidMatchList); void ProcessList_delete(ProcessList* this); 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