diff --git a/CRT.c b/CRT.c index 150e27b5..e3b1a20a 100644 --- a/CRT.c +++ b/CRT.c @@ -151,6 +151,10 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [MEMORY_BUFFERS] = ColorPair(Blue, Black), [MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Blue, Black), [MEMORY_CACHE] = ColorPair(Yellow, Black), + [HUGEPAGE_1] = ColorPair(Green, Black), + [HUGEPAGE_2] = ColorPair(Yellow, Black), + [HUGEPAGE_3] = ColorPair(Red, Black), + [HUGEPAGE_4] = ColorPair(Blue, Black), [LOAD_AVERAGE_FIFTEEN] = ColorPair(Cyan, Black), [LOAD_AVERAGE_FIVE] = A_BOLD | ColorPair(Cyan, Black), [LOAD_AVERAGE_ONE] = A_BOLD | ColorPair(White, Black), @@ -237,6 +241,10 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [MEMORY_BUFFERS] = A_NORMAL, [MEMORY_BUFFERS_TEXT] = A_NORMAL, [MEMORY_CACHE] = A_NORMAL, + [HUGEPAGE_1] = A_BOLD, + [HUGEPAGE_2] = A_NORMAL, + [HUGEPAGE_3] = A_REVERSE | A_BOLD, + [HUGEPAGE_4] = A_REVERSE, [LOAD_AVERAGE_FIFTEEN] = A_DIM, [LOAD_AVERAGE_FIVE] = A_NORMAL, [LOAD_AVERAGE_ONE] = A_BOLD, @@ -323,6 +331,10 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [MEMORY_BUFFERS] = ColorPair(Cyan, White), [MEMORY_BUFFERS_TEXT] = ColorPair(Cyan, White), [MEMORY_CACHE] = ColorPair(Yellow, White), + [HUGEPAGE_1] = ColorPair(Green, White), + [HUGEPAGE_2] = ColorPair(Yellow, White), + [HUGEPAGE_3] = ColorPair(Red, White), + [HUGEPAGE_4] = ColorPair(Blue, White), [LOAD_AVERAGE_FIFTEEN] = ColorPair(Black, White), [LOAD_AVERAGE_FIVE] = ColorPair(Black, White), [LOAD_AVERAGE_ONE] = ColorPair(Black, White), @@ -409,6 +421,10 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [MEMORY_BUFFERS] = ColorPair(Cyan, Black), [MEMORY_BUFFERS_TEXT] = ColorPair(Cyan, Black), [MEMORY_CACHE] = ColorPair(Yellow, Black), + [HUGEPAGE_1] = ColorPair(Green, Black), + [HUGEPAGE_2] = ColorPair(Yellow, Black), + [HUGEPAGE_3] = ColorPair(Red, Black), + [HUGEPAGE_4] = ColorPair(Blue, Black), [LOAD_AVERAGE_FIFTEEN] = ColorPair(Black, Black), [LOAD_AVERAGE_FIVE] = ColorPair(Black, Black), [LOAD_AVERAGE_ONE] = ColorPair(Black, Black), @@ -495,6 +511,10 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [MEMORY_BUFFERS] = A_BOLD | ColorPair(Cyan, Blue), [MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Cyan, Blue), [MEMORY_CACHE] = A_BOLD | ColorPair(Yellow, Blue), + [HUGEPAGE_1] = A_BOLD | ColorPair(Green, Blue), + [HUGEPAGE_2] = A_BOLD | ColorPair(Yellow, Blue), + [HUGEPAGE_3] = A_BOLD | ColorPair(Red, Blue), + [HUGEPAGE_4] = A_BOLD | ColorPair(White, Blue), [LOAD_AVERAGE_FIFTEEN] = A_BOLD | ColorPair(Black, Blue), [LOAD_AVERAGE_FIVE] = A_NORMAL | ColorPair(White, Blue), [LOAD_AVERAGE_ONE] = A_BOLD | ColorPair(White, Blue), @@ -581,6 +601,10 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = { [MEMORY_BUFFERS] = ColorPair(Blue, Black), [MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Blue, Black), [MEMORY_CACHE] = ColorPair(Yellow, Black), + [HUGEPAGE_1] = ColorPair(Green, Black), + [HUGEPAGE_2] = ColorPair(Yellow, Black), + [HUGEPAGE_3] = ColorPair(Red, Black), + [HUGEPAGE_4] = ColorPair(Blue, Black), [LOAD_AVERAGE_FIFTEEN] = ColorPair(Green, Black), [LOAD_AVERAGE_FIVE] = ColorPair(Green, Black), [LOAD_AVERAGE_ONE] = A_BOLD | ColorPair(Green, Black), diff --git a/CRT.h b/CRT.h index d54ac121..1d2ed32d 100644 --- a/CRT.h +++ b/CRT.h @@ -91,6 +91,10 @@ typedef enum ColorElements_ { MEMORY_BUFFERS, MEMORY_BUFFERS_TEXT, MEMORY_CACHE, + HUGEPAGE_1, + HUGEPAGE_2, + HUGEPAGE_3, + HUGEPAGE_4, LOAD, LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIVE, diff --git a/linux/HugePageMeter.c b/linux/HugePageMeter.c index e546c79a..7222c87a 100644 --- a/linux/HugePageMeter.c +++ b/linux/HugePageMeter.c @@ -9,23 +9,56 @@ in the source distribution for its full text. #include "LinuxProcessList.h" +#include +#include + #include "CRT.h" #include "Object.h" #include "RichString.h" +static const char *HugePageMeter_active_labels[4] = { NULL, NULL, NULL, NULL }; static const int HugePageMeter_attributes[] = { - MEMORY_USED, + HUGEPAGE_1, + HUGEPAGE_2, + HUGEPAGE_3, + HUGEPAGE_4, +}; + +static const char* const HugePageMeter_labels[] = { + " 64K:", " 128K:", " 256K:", " 512K:", + " 1M:", " 2M:", " 4M:", " 8M:", " 16M:", " 32M:", " 64M:", " 128M:", " 256M:", " 512M:", + " 1G:", " 2G:", " 4G:", " 8G:", " 16G:", " 32G:", " 64G:", " 128G:", " 256G:", " 512G:", }; static void HugePageMeter_updateValues(Meter* this, char* buffer, size_t size) { + assert(ARRAYSIZE(HugePageMeter_labels) == HTOP_HUGEPAGE_COUNT); + int written; + unsigned long long int usedTotal = 0; + unsigned nextUsed = 0; const LinuxProcessList* lpl = (const LinuxProcessList*) this->pl; this->total = lpl->totalHugePageMem; - this->values[0] = lpl->totalHugePageMem - lpl->freeHugePageMem; + this->values[0] = 0; + HugePageMeter_active_labels[0] = " used:"; + for (unsigned i = 1; i < ARRAYSIZE(HugePageMeter_active_labels); i++) { + this->values[i] = NAN; + HugePageMeter_active_labels[i] = NULL; + } + for (unsigned i = 0; i < HTOP_HUGEPAGE_COUNT; i++) { + unsigned long long int value = lpl->usedHugePageMem[i]; + if (value != ULLONG_MAX) { + this->values[nextUsed] = value; + usedTotal += value; + HugePageMeter_active_labels[nextUsed] = HugePageMeter_labels[i]; + if (++nextUsed == ARRAYSIZE(HugePageMeter_active_labels)) { + break; + } + } + } - written = Meter_humanUnit(buffer, this->values[0], size); + written = Meter_humanUnit(buffer, usedTotal, size); METER_BUFFER_CHECK(buffer, size, written); METER_BUFFER_APPEND_CHR(buffer, size, '/'); @@ -41,9 +74,14 @@ static void HugePageMeter_display(const Object* cast, RichString* out) { Meter_humanUnit(buffer, this->total, sizeof(buffer)); RichString_appendAscii(out, CRT_colors[METER_VALUE], buffer); - RichString_appendAscii(out, CRT_colors[METER_TEXT], " used:"); - Meter_humanUnit(buffer, this->values[0], sizeof(buffer)); - RichString_appendAscii(out, CRT_colors[MEMORY_USED], buffer); + for (unsigned i = 0; i < ARRAYSIZE(HugePageMeter_active_labels); i++) { + if (isnan(this->values[i])) { + break; + } + RichString_appendAscii(out, CRT_colors[METER_TEXT], HugePageMeter_active_labels[i]); + Meter_humanUnit(buffer, this->values[i], sizeof(buffer)); + RichString_appendAscii(out, CRT_colors[HUGEPAGE_1 + i], buffer); + } } const MeterClass HugePageMeter_class = { @@ -54,7 +92,7 @@ const MeterClass HugePageMeter_class = { }, .updateValues = HugePageMeter_updateValues, .defaultMode = BAR_METERMODE, - .maxItems = 1, + .maxItems = ARRAYSIZE(HugePageMeter_active_labels), .total = 100.0, .attributes = HugePageMeter_attributes, .name = "HugePages", diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 78ae6649..bf11aa15 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -1533,7 +1533,9 @@ static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) { static void LinuxProcessList_scanHugePages(LinuxProcessList* this) { this->totalHugePageMem = 0; - this->freeHugePageMem = 0; + for (unsigned i = 0; i < HTOP_HUGEPAGE_COUNT; i++) { + this->usedHugePageMem[i] = ULLONG_MAX; + } DIR* dir = opendir("/sys/kernel/mm/hugepages"); if (!dir) @@ -1575,8 +1577,11 @@ static void LinuxProcessList_scanHugePages(LinuxProcessList* this) { unsigned long long int free = strtoull(content, NULL, 10); + int shift = ffsl(hugePageSize) - 1 - (HTOP_HUGEPAGE_BASE_SHIFT - 10); + assert(shift >= 0 && shift < HTOP_HUGEPAGE_COUNT); + this->totalHugePageMem += total * hugePageSize; - this->freeHugePageMem += free * hugePageSize; + this->usedHugePageMem[shift] = (total - free) * hugePageSize; } closedir(dir); diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h index b34810bb..d65119e8 100644 --- a/linux/LinuxProcessList.h +++ b/linux/LinuxProcessList.h @@ -18,6 +18,8 @@ in the source distribution for its full text. #include "ZramStats.h" #include "zfs/ZfsArcStats.h" +#define HTOP_HUGEPAGE_BASE_SHIFT 16 +#define HTOP_HUGEPAGE_COUNT 24 typedef struct CPUData_ { unsigned long long int totalTime; @@ -73,7 +75,7 @@ typedef struct LinuxProcessList_ { #endif unsigned long long int totalHugePageMem; - unsigned long long int freeHugePageMem; + unsigned long long int usedHugePageMem[HTOP_HUGEPAGE_COUNT]; ZfsArcStats zfs; ZramStats zram;