Machine.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. htop - Machine.c
  3. (C) 2023 Red Hat, Inc.
  4. (C) 2004,2005 Hisham H. Muhammad
  5. Released under the GNU GPLv2+, see the COPYING file
  6. in the source distribution for its full text.
  7. */
  8. #include "config.h" // IWYU pragma: keep
  9. #include "Machine.h"
  10. #include <stdlib.h>
  11. #include <unistd.h>
  12. #include "Object.h"
  13. #include "Platform.h"
  14. #include "Row.h"
  15. #include "XUtils.h"
  16. void Machine_init(Machine* this, UsersTable* usersTable, uid_t userId) {
  17. this->usersTable = usersTable;
  18. this->userId = userId;
  19. this->htopUserId = getuid();
  20. // discover fixed column width limits
  21. Row_setPidColumnWidth(Platform_getMaxPid());
  22. // always maintain valid realtime timestamps
  23. Platform_gettime_realtime(&this->realtime, &this->realtimeMs);
  24. #ifdef HAVE_LIBHWLOC
  25. this->topologyOk = false;
  26. if (hwloc_topology_init(&this->topology) == 0) {
  27. this->topologyOk =
  28. #if HWLOC_API_VERSION < 0x00020000
  29. /* try to ignore the top-level machine object type */
  30. 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_MACHINE) &&
  31. /* ignore caches, which don't add structure */
  32. 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CORE) &&
  33. 0 == hwloc_topology_ignore_type_keep_structure(this->topology, HWLOC_OBJ_CACHE) &&
  34. 0 == hwloc_topology_set_flags(this->topology, HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) &&
  35. #else
  36. 0 == hwloc_topology_set_all_types_filter(this->topology, HWLOC_TYPE_FILTER_KEEP_STRUCTURE) &&
  37. #endif
  38. 0 == hwloc_topology_load(this->topology);
  39. }
  40. #endif
  41. }
  42. void Machine_done(Machine* this) {
  43. #ifdef HAVE_LIBHWLOC
  44. if (this->topologyOk) {
  45. hwloc_topology_destroy(this->topology);
  46. }
  47. #endif
  48. Object_delete(this->processTable);
  49. free(this->tables);
  50. }
  51. static void Machine_addTable(Machine* this, Table* table) {
  52. /* check that this table has not been seen previously */
  53. for (size_t i = 0; i < this->tableCount; i++)
  54. if (this->tables[i] == table)
  55. return;
  56. size_t nmemb = this->tableCount + 1;
  57. Table** tables = xReallocArray(this->tables, nmemb, sizeof(Table*));
  58. tables[nmemb - 1] = table;
  59. this->tables = tables;
  60. this->tableCount++;
  61. }
  62. void Machine_populateTablesFromSettings(Machine* this, Settings* settings, Table* processTable) {
  63. this->settings = settings;
  64. this->processTable = processTable;
  65. for (size_t i = 0; i < settings->nScreens; i++) {
  66. ScreenSettings* ss = settings->screens[i];
  67. Table* table = ss->table;
  68. if (!table)
  69. table = ss->table = processTable;
  70. if (i == 0)
  71. this->activeTable = table;
  72. Machine_addTable(this, table);
  73. }
  74. }
  75. void Machine_setTablesPanel(Machine* this, Panel* panel) {
  76. for (size_t i = 0; i < this->tableCount; i++) {
  77. Table_setPanel(this->tables[i], panel);
  78. }
  79. }
  80. void Machine_scanTables(Machine* this) {
  81. // set scan timestamp
  82. static bool firstScanDone = false;
  83. if (firstScanDone) {
  84. this->prevMonotonicMs = this->monotonicMs;
  85. Platform_gettime_monotonic(&this->monotonicMs);
  86. } else {
  87. this->prevMonotonicMs = 0;
  88. this->monotonicMs = 1;
  89. firstScanDone = true;
  90. }
  91. assert(this->monotonicMs > this->prevMonotonicMs);
  92. this->maxUserId = 0;
  93. Row_resetFieldWidths();
  94. for (size_t i = 0; i < this->tableCount; i++) {
  95. Table* table = this->tables[i];
  96. // pre-processing of each row
  97. Table_scanPrepare(table);
  98. // scan values for this table
  99. Table_scanIterate(table);
  100. // post-process after scanning
  101. Table_scanCleanup(table);
  102. }
  103. Row_setUidColumnWidth(this->maxUserId);
  104. }