You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
3.6 KiB
129 lines
3.6 KiB
/* |
|
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 <stdlib.h> |
|
#include <unistd.h> |
|
|
|
#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); |
|
}
|
|
|