/* 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 "config.h" // IWYU pragma: keep #include "Machine.h" #include #include #include "Object.h" #include "Platform.h" #include "Row.h" #include "XUtils.h" void Machine_init(Machine* this, UsersTable* usersTable, uid_t userId) { this->usersTable = usersTable; this->userId = userId; this->htopUserId = getuid(); // discover fixed column width limits Row_setPidColumnWidth(Platform_getMaxPid()); // 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); } #endif Object_delete(this->processTable); free(this->tables); } static void Machine_addTable(Machine* this, Table* table) { /* check that this table has not been seen previously */ for (size_t i = 0; i < this->tableCount; i++) if (this->tables[i] == table) return; size_t nmemb = this->tableCount + 1; Table** tables = xReallocArray(this->tables, nmemb, sizeof(Table*)); tables[nmemb - 1] = table; this->tables = tables; this->tableCount++; } void Machine_populateTablesFromSettings(Machine* this, Settings* settings, Table* processTable) { this->settings = settings; this->processTable = processTable; for (size_t i = 0; i < settings->nScreens; i++) { ScreenSettings* ss = settings->screens[i]; Table* table = ss->table; if (!table) table = ss->table = processTable; if (i == 0) this->activeTable = table; Machine_addTable(this, table); } } void Machine_setTablesPanel(Machine* this, Panel* panel) { for (size_t i = 0; i < this->tableCount; i++) { Table_setPanel(this->tables[i], panel); } } void Machine_scanTables(Machine* this) { // set scan timestamp static bool firstScanDone = false; if (firstScanDone) { this->prevMonotonicMs = this->monotonicMs; Platform_gettime_monotonic(&this->monotonicMs); } else { this->prevMonotonicMs = 0; this->monotonicMs = 1; firstScanDone = true; } assert(this->monotonicMs > this->prevMonotonicMs); this->maxUserId = 0; Row_resetFieldWidths(); for (size_t i = 0; i < this->tableCount; i++) { Table* table = this->tables[i]; // pre-processing of each row Table_scanPrepare(table); // scan values for this table Table_scanIterate(table); // post-process after scanning Table_scanCleanup(table); } Row_setUidColumnWidth(this->maxUserId); }