From 3e4f06d1010e5048ffb8e3efdc6bb94b204a2144 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Wed, 4 Oct 2006 14:21:27 +0000 Subject: [PATCH] Contribution by Philipp Richter: Display IO-Wait, IRQ and Soft-IRQ values in status bar (minor modifications: default to false, add help) --- CPUMeter.c | 50 +++++++++++++++++++++++++++++++-------- CRT.c | 21 +++++++++++++++++ CRT.h | 3 +++ DisplayOptionsPanel.c | 1 + ProcessList.c | 55 ++++++++++++++++++++++++++++++++++++++++--- ProcessList.h | 11 +++++++++ Settings.c | 3 +++ htop.c | 28 +++++++++++++++------- 8 files changed, 150 insertions(+), 22 deletions(-) diff --git a/CPUMeter.c b/CPUMeter.c index 363da6ac..a252d5a5 100644 --- a/CPUMeter.c +++ b/CPUMeter.c @@ -19,14 +19,14 @@ in the source distribution for its full text. #include int CPUMeter_attributes[] = { - CPU_NICE, CPU_NORMAL, CPU_KERNEL + CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IOWAIT, CPU_IRQ, CPU_SOFTIRQ }; MeterType CPUMeter = { .setValues = CPUMeter_setValues, .display = CPUMeter_display, .mode = BAR_METERMODE, - .items = 3, + .items = 6, .total = 100.0, .attributes = CPUMeter_attributes, .name = "CPU", @@ -71,10 +71,22 @@ void CPUMeter_setValues(Meter* this, char* buffer, int size) { ProcessList* pl = this->pl; int processor = this->param; double total = (double) pl->totalPeriod[processor]; + double cpu; this->values[0] = pl->nicePeriod[processor] / total * 100.0; this->values[1] = pl->userPeriod[processor] / total * 100.0; - this->values[2] = pl->systemPeriod[processor] / total * 100.0; - double cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]))); + if (pl->expandSystemTime) { + this->values[2] = pl->systemPeriod[processor] / total * 100.0; + this->values[3] = pl->ioWaitPeriod[processor] / total * 100.0; + this->values[4] = pl->irqPeriod[processor] / total * 100.0; + this->values[5] = pl->softIrqPeriod[processor] / total * 100.0; + this->type->items = 6; + cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+ + this->values[3]+this->values[4]+this->values[5]))); + } else { + this->values[2] = pl->systemAllPeriod[processor] / total * 100.0; + this->type->items = 3; + cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]))); + } snprintf(buffer, size, "%5.1f%%", cpu ); } @@ -85,12 +97,30 @@ void CPUMeter_display(Object* cast, RichString* out) { sprintf(buffer, "%5.1f%% ", this->values[1]); RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[CPU_NORMAL], buffer); - sprintf(buffer, "%5.1f%% ", this->values[2]); - RichString_append(out, CRT_colors[METER_TEXT], "sys:"); - RichString_append(out, CRT_colors[CPU_KERNEL], buffer); - sprintf(buffer, "%5.1f%% ", this->values[0]); - RichString_append(out, CRT_colors[METER_TEXT], "low:"); - RichString_append(out, CRT_colors[CPU_NICE], buffer); + if (this->pl->expandSystemTime) { + sprintf(buffer, "%5.1f%% ", this->values[2]); + RichString_append(out, CRT_colors[METER_TEXT], "sy:"); + RichString_append(out, CRT_colors[CPU_KERNEL], buffer); + sprintf(buffer, "%5.1f%% ", this->values[0]); + RichString_append(out, CRT_colors[METER_TEXT], "ni:"); + RichString_append(out, CRT_colors[CPU_NICE], buffer); + sprintf(buffer, "%5.1f%% ", this->values[3]); + RichString_append(out, CRT_colors[METER_TEXT], "wa:"); + RichString_append(out, CRT_colors[CPU_IOWAIT], buffer); + sprintf(buffer, "%5.1f%% ", this->values[4]); + RichString_append(out, CRT_colors[METER_TEXT], "hi:"); + RichString_append(out, CRT_colors[CPU_IRQ], buffer); + sprintf(buffer, "%5.1f%% ", this->values[4]); + RichString_append(out, CRT_colors[METER_TEXT], "si:"); + RichString_append(out, CRT_colors[CPU_SOFTIRQ], buffer); + } else { + sprintf(buffer, "%5.1f%% ", this->values[2]); + RichString_append(out, CRT_colors[METER_TEXT], "sys:"); + RichString_append(out, CRT_colors[CPU_KERNEL], buffer); + sprintf(buffer, "%5.1f%% ", this->values[0]); + RichString_append(out, CRT_colors[METER_TEXT], "low:"); + RichString_append(out, CRT_colors[CPU_NICE], buffer); + } } void AllCPUsMeter_init(Meter* this) { diff --git a/CRT.c b/CRT.c index 8bd29f08..97104522 100644 --- a/CRT.c +++ b/CRT.c @@ -93,6 +93,9 @@ typedef enum ColorElements_ { CPU_NORMAL, CPU_KERNEL, HELP_BOLD, + CPU_IOWAIT, + CPU_IRQ, + CPU_SOFTIRQ, LAST_COLORELEMENT } ColorElements; @@ -251,6 +254,9 @@ void CRT_setColors(int colorScheme) { CRT_colors[CHECK_BOX] = A_BOLD; CRT_colors[CHECK_MARK] = A_NORMAL; CRT_colors[CHECK_TEXT] = A_NORMAL; + CRT_colors[CPU_IOWAIT] = A_BOLD; + CRT_colors[CPU_IRQ] = A_BOLD; + CRT_colors[CPU_SOFTIRQ] = A_BOLD; } else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) { CRT_colors[RESET_COLOR] = ColorPair(Black,White); CRT_colors[DEFAULT_COLOR] = ColorPair(Black,White); @@ -303,6 +309,9 @@ void CRT_setColors(int colorScheme) { CRT_colors[CHECK_BOX] = ColorPair(Blue,White); CRT_colors[CHECK_MARK] = ColorPair(Black,White); CRT_colors[CHECK_TEXT] = ColorPair(Black,White); + CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,White); + CRT_colors[CPU_IRQ] = ColorPair(Blue,White); + CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,White); } else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) { CRT_colors[RESET_COLOR] = ColorPair(Black,Black); CRT_colors[DEFAULT_COLOR] = ColorPair(Black,Black); @@ -355,6 +364,9 @@ void CRT_setColors(int colorScheme) { CRT_colors[CHECK_BOX] = ColorPair(Blue,Black); CRT_colors[CHECK_MARK] = ColorPair(Black,Black); CRT_colors[CHECK_TEXT] = ColorPair(Black,Black); + CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black); + CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black); + CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black); } else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) { CRT_colors[RESET_COLOR] = ColorPair(White,Blue); CRT_colors[DEFAULT_COLOR] = ColorPair(White,Blue); @@ -407,6 +419,9 @@ void CRT_setColors(int colorScheme) { CRT_colors[CHECK_BOX] = ColorPair(Cyan,Blue); CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(White,Blue); CRT_colors[CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue); + CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Yellow,Blue); + CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Black,Blue); + CRT_colors[CPU_SOFTIRQ] = ColorPair(Black,Blue); } else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) { CRT_colors[RESET_COLOR] = ColorPair(Cyan,Black); CRT_colors[DEFAULT_COLOR] = ColorPair(Cyan,Black); @@ -459,6 +474,9 @@ void CRT_setColors(int colorScheme) { CRT_colors[CHECK_BOX] = ColorPair(Green,Black); CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(Green,Black); CRT_colors[CHECK_TEXT] = ColorPair(Cyan,Black); + CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black); + CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black); + CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black); } else { /* Default */ CRT_colors[RESET_COLOR] = ColorPair(White,Black); @@ -512,5 +530,8 @@ void CRT_setColors(int colorScheme) { CRT_colors[CHECK_BOX] = ColorPair(Cyan,Black); CRT_colors[CHECK_MARK] = A_BOLD; CRT_colors[CHECK_TEXT] = A_NORMAL; + CRT_colors[CPU_IOWAIT] = ColorPair(Cyan,Black); + CRT_colors[CPU_IRQ] = ColorPair(Yellow,Black); + CRT_colors[CPU_SOFTIRQ] = ColorPair(Magenta,Black); } } diff --git a/CRT.h b/CRT.h index 1f6020bd..76a3b08c 100644 --- a/CRT.h +++ b/CRT.h @@ -95,6 +95,9 @@ typedef enum ColorElements_ { CPU_NORMAL, CPU_KERNEL, HELP_BOLD, + CPU_IOWAIT, + CPU_IRQ, + CPU_SOFTIRQ, LAST_COLORELEMENT } ColorElements; diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c index c2b7f5e6..119b4e64 100644 --- a/DisplayOptionsPanel.c +++ b/DisplayOptionsPanel.c @@ -38,6 +38,7 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight program \"basename\""), &(settings->pl->highlightBaseName))); Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight megabytes in memory counters"), &(settings->pl->highlightMegabytes))); Panel_add(super, (Object*) CheckItem_new(String_copy("Leave a margin around header"), &(settings->header->margin))); + Panel_add(super, (Object*) CheckItem_new(String_copy("Split System Time into System/IO-Wait/Hard-IRQ/Soft-IRQ"), &(settings->pl->expandSystemTime))); return this; } diff --git a/ProcessList.c b/ProcessList.c index 87db785c..a031d461 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -74,13 +74,23 @@ typedef struct ProcessList_ { unsigned long long int* totalTime; unsigned long long int* userTime; unsigned long long int* systemTime; + unsigned long long int* systemAllTime; unsigned long long int* idleTime; unsigned long long int* niceTime; + unsigned long long int* ioWaitTime; + unsigned long long int* irqTime; + unsigned long long int* softIrqTime; + unsigned long long int* stealTime; unsigned long long int* totalPeriod; unsigned long long int* userPeriod; unsigned long long int* systemPeriod; + unsigned long long int* systemAllPeriod; unsigned long long int* idlePeriod; unsigned long long int* nicePeriod; + unsigned long long int* ioWaitPeriod; + unsigned long long int* irqPeriod; + unsigned long long int* softIrqPeriod; + unsigned long long int* stealPeriod; unsigned long long int totalMem; unsigned long long int usedMem; @@ -198,16 +208,29 @@ ProcessList* ProcessList_new(UsersTable* usersTable) { } while (String_startsWith(buffer, "cpu")); fclose(status); this->processorCount = procs - 1; + this->totalTime = calloc(procs * FIELDS, sizeof(long long int)); + this->userTime = + this->totalTime = calloc(procs, sizeof(long long int)); this->userTime = calloc(procs, sizeof(long long int)); this->systemTime = calloc(procs, sizeof(long long int)); + this->systemAllTime = calloc(procs, sizeof(long long int)); this->niceTime = calloc(procs, sizeof(long long int)); this->idleTime = calloc(procs, sizeof(long long int)); + this->ioWaitTime = calloc(procs, sizeof(long long int)); + this->irqTime = calloc(procs, sizeof(long long int)); + this->softIrqTime = calloc(procs, sizeof(long long int)); + this->stealTime = calloc(procs, sizeof(long long int)); this->totalPeriod = calloc(procs, sizeof(long long int)); this->userPeriod = calloc(procs, sizeof(long long int)); this->systemPeriod = calloc(procs, sizeof(long long int)); + this->systemAllPeriod = calloc(procs, sizeof(long long int)); this->nicePeriod = calloc(procs, sizeof(long long int)); this->idlePeriod = calloc(procs, sizeof(long long int)); + this->ioWaitPeriod = calloc(procs, sizeof(long long int)); + this->irqPeriod = calloc(procs, sizeof(long long int)); + this->softIrqPeriod = calloc(procs, sizeof(long long int)); + this->stealPeriod = calloc(procs, sizeof(long long int)); for (int i = 0; i < procs; i++) { this->totalTime[i] = 1; this->totalPeriod[i] = 1; @@ -228,6 +251,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) { this->treeView = false; this->highlightBaseName = false; this->highlightMegabytes = false; + this->expandSystemTime = false; return this; } @@ -241,13 +265,23 @@ void ProcessList_delete(ProcessList* this) { free(this->totalTime); free(this->userTime); free(this->systemTime); + free(this->systemAllTime); free(this->niceTime); free(this->idleTime); + free(this->ioWaitTime); + free(this->irqTime); + free(this->softIrqTime); + free(this->stealTime); free(this->totalPeriod); free(this->userPeriod); free(this->systemPeriod); + free(this->systemAllPeriod); free(this->nicePeriod); free(this->idlePeriod); + free(this->ioWaitPeriod); + free(this->irqPeriod); + free(this->softIrqPeriod); + free(this->stealPeriod); #ifdef DEBUG fclose(this->traceFile); @@ -596,7 +630,7 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl } void ProcessList_scan(ProcessList* this) { - unsigned long long int usertime, nicetime, systemtime, idletime, totaltime; + unsigned long long int usertime, nicetime, systemtime, systemalltime, idletime, totaltime; unsigned long long int swapFree; FILE* status; @@ -656,22 +690,37 @@ void ProcessList_scan(ProcessList* this) { } // Fields existing on kernels >= 2.6 // (and RHEL's patched kernel 2.4...) - systemtime += ioWait + irq + softIrq + steal; - totaltime = usertime + nicetime + systemtime + idletime; + systemalltime = systemtime + ioWait + irq + softIrq + steal; + totaltime = usertime + nicetime + systemalltime + idletime; assert (usertime >= this->userTime[i]); assert (nicetime >= this->niceTime[i]); assert (systemtime >= this->systemTime[i]); assert (idletime >= this->idleTime[i]); assert (totaltime >= this->totalTime[i]); + assert (systemalltime >= this->systemAllTime[i]); + assert (ioWait >= this->ioWaitTime[i]); + assert (irqTime >= this->irqTime[i]); + assert (softIrqTime >= this->softIrqTime[i]); + assert (stealTime >= this->stealTime[i]); this->userPeriod[i] = usertime - this->userTime[i]; this->nicePeriod[i] = nicetime - this->niceTime[i]; this->systemPeriod[i] = systemtime - this->systemTime[i]; + this->systemAllPeriod[i] = systemalltime - this->systemAllTime[i]; this->idlePeriod[i] = idletime - this->idleTime[i]; + this->ioWaitPeriod[i] = ioWait - this->ioWaitTime[i]; + this->irqPeriod[i] = irq - this->irqTime[i]; + this->softIrqPeriod[i] = softIrq - this->softIrqTime[i]; + this->stealPeriod[i] = steal - this->stealTime[i]; this->totalPeriod[i] = totaltime - this->totalTime[i]; this->userTime[i] = usertime; this->niceTime[i] = nicetime; this->systemTime[i] = systemtime; + this->systemAllTime[i] = systemalltime; this->idleTime[i] = idletime; + this->ioWaitTime[i] = ioWait; + this->irqTime[i] = irq; + this->softIrqTime[i] = softIrq; + this->stealTime[i] = steal; this->totalTime[i] = totaltime; } float period = (float)this->totalPeriod[0] / this->processorCount; diff --git a/ProcessList.h b/ProcessList.h index b38cefcd..9c42a722 100644 --- a/ProcessList.h +++ b/ProcessList.h @@ -74,13 +74,23 @@ typedef struct ProcessList_ { unsigned long long int* totalTime; unsigned long long int* userTime; unsigned long long int* systemTime; + unsigned long long int* systemAllTime; unsigned long long int* idleTime; unsigned long long int* niceTime; + unsigned long long int* ioWaitTime; + unsigned long long int* irqTime; + unsigned long long int* softIrqTime; + unsigned long long int* stealTime; unsigned long long int* totalPeriod; unsigned long long int* userPeriod; unsigned long long int* systemPeriod; + unsigned long long int* systemAllPeriod; unsigned long long int* idlePeriod; unsigned long long int* nicePeriod; + unsigned long long int* ioWaitPeriod; + unsigned long long int* irqPeriod; + unsigned long long int* softIrqPeriod; + unsigned long long int* stealPeriod; unsigned long long int totalMem; unsigned long long int usedMem; @@ -102,6 +112,7 @@ typedef struct ProcessList_ { bool treeView; bool highlightBaseName; bool highlightMegabytes; + bool expandSystemTime; #ifdef DEBUG FILE* traceFile; #endif diff --git a/Settings.c b/Settings.c index ca07389b..8fc1c6d0 100644 --- a/Settings.c +++ b/Settings.c @@ -139,6 +139,8 @@ bool Settings_read(Settings* this, char* fileName) { this->pl->highlightMegabytes = atoi(option[1]); } else if (String_eq(option[0], "header_margin")) { this->header->margin = atoi(option[1]); + } else if (String_eq(option[0], "expand_system_time")) { + this->pl->expandSystemTime = atoi(option[1]); } else if (String_eq(option[0], "delay")) { this->delay = atoi(option[1]); } else if (String_eq(option[0], "color_scheme")) { @@ -195,6 +197,7 @@ bool Settings_write(Settings* this) { fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes); fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView); fprintf(fd, "header_margin=%d\n", (int) this->header->margin); + fprintf(fd, "expand_system_time=%d\n", (int) this->pl->expandSystemTime); fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme); fprintf(fd, "delay=%d\n", (int) this->delay); fprintf(fd, "left_meters="); diff --git a/htop.c b/htop.c index c5bd6f05..ca39f6a5 100644 --- a/htop.c +++ b/htop.c @@ -52,7 +52,7 @@ void printHelpFlag() { exit(0); } -void showHelp() { +void showHelp(ProcessList* pl) { clear(); attrset(CRT_colors[HELP_BOLD]); mvaddstr(0, 0, "htop " VERSION " - (C) 2004-2006 Hisham Muhammad."); @@ -62,10 +62,20 @@ void showHelp() { mvaddstr(3, 0, "CPU usage bar: "); #define addattrstr(a,s) attrset(a);addstr(s) addattrstr(CRT_colors[BAR_BORDER], "["); - addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/"); - addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/"); - addattrstr(CRT_colors[CPU_KERNEL], "kernel"); - addattrstr(CRT_colors[BAR_SHADOW], " used%"); + if (pl->expandSystemTime) { + addattrstr(CRT_colors[CPU_NICE], "low"); addstr("/"); + addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/"); + addattrstr(CRT_colors[CPU_KERNEL], "kernel"); addstr("/"); + addattrstr(CRT_colors[CPU_IOWAIT], "io-wait"); addstr("/"); + addattrstr(CRT_colors[CPU_IRQ], "irq"); addstr("/"); + addattrstr(CRT_colors[CPU_SOFTIRQ], "soft-irq"); + addattrstr(CRT_colors[BAR_SHADOW], " used%"); + } else { + addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/"); + addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/"); + addattrstr(CRT_colors[CPU_KERNEL], "kernel"); + addattrstr(CRT_colors[BAR_SHADOW], " used%"); + } addattrstr(CRT_colors[BAR_BORDER], "]"); attrset(CRT_colors[DEFAULT_COLOR]); mvaddstr(4, 0, "Memory bar: "); @@ -73,16 +83,16 @@ void showHelp() { addattrstr(CRT_colors[MEMORY_USED], "used"); addstr("/"); addattrstr(CRT_colors[MEMORY_BUFFERS], "buffers"); addstr("/"); addattrstr(CRT_colors[MEMORY_CACHE], "cache"); - addattrstr(CRT_colors[BAR_SHADOW], " used/total"); + addattrstr(CRT_colors[BAR_SHADOW], " used/total"); addattrstr(CRT_colors[BAR_BORDER], "]"); attrset(CRT_colors[DEFAULT_COLOR]); mvaddstr(5, 0, "Swap bar: "); addattrstr(CRT_colors[BAR_BORDER], "["); addattrstr(CRT_colors[SWAP], "used"); - addattrstr(CRT_colors[BAR_SHADOW], " used/total"); + addattrstr(CRT_colors[BAR_SHADOW], " used/total"); addattrstr(CRT_colors[BAR_BORDER], "]"); attrset(CRT_colors[DEFAULT_COLOR]); - mvaddstr(6,0, "Type and layout of header meters is configurable in the setup screen."); + mvaddstr(6,0, "Type and layout of header meters are configurable in the setup screen."); mvaddstr( 8, 0, " Arrows: scroll process list F5 t: tree view"); mvaddstr( 9, 0, " Digits: incremental PID search u: show processes of a single user"); @@ -473,7 +483,7 @@ int main(int argc, char** argv) { case KEY_F(1): case 'h': { - showHelp(); + showHelp(pl); FunctionBar_draw(defaultBar, NULL); refreshTimeout = 0; break;