aboutsummaryrefslogtreecommitdiff
path: root/CPUMeter.c
diff options
context:
space:
mode:
Diffstat (limited to 'CPUMeter.c')
-rw-r--r--CPUMeter.c184
1 files changed, 184 insertions, 0 deletions
diff --git a/CPUMeter.c b/CPUMeter.c
new file mode 100644
index 0000000..a1144ea
--- /dev/null
+++ b/CPUMeter.c
@@ -0,0 +1,184 @@
+/*
+htop - CPUMeter.c
+(C) 2004-2010 Hisham H. Muhammad
+Released under the GNU GPL, see the COPYING file
+in the source distribution for its full text.
+*/
+
+#include "CPUMeter.h"
+#include "Meter.h"
+
+#include "ProcessList.h"
+
+#include <stdlib.h>
+#include <curses.h>
+#include <string.h>
+#include <math.h>
+
+#include "debug.h"
+#include <assert.h>
+
+int CPUMeter_attributes[] = {
+ CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IRQ, CPU_SOFTIRQ, CPU_IOWAIT, CPU_STEAL, CPU_GUEST
+};
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+static void CPUMeter_init(Meter* this) {
+ int cpu = this->param;
+ if (this->pl->cpuCount > 1) {
+ char caption[10];
+ sprintf(caption, "%-3d", cpu);
+ Meter_setCaption(this, caption);
+ }
+ if (this->param == 0)
+ Meter_setCaption(this, "Avg");
+}
+
+static void CPUMeter_setValues(Meter* this, char* buffer, int size) {
+ ProcessList* pl = this->pl;
+ int cpu = this->param;
+ if (cpu > this->pl->cpuCount) {
+ snprintf(buffer, size, "absent");
+ return;
+ }
+ CPUData* cpuData = &(pl->cpus[cpu]);
+ double total = (double) ( cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod);
+ double percent;
+ this->values[0] = cpuData->nicePeriod / total * 100.0;
+ this->values[1] = cpuData->userPeriod / total * 100.0;
+ if (pl->detailedCPUTime) {
+ this->values[2] = cpuData->systemPeriod / total * 100.0;
+ this->values[3] = cpuData->irqPeriod / total * 100.0;
+ this->values[4] = cpuData->softIrqPeriod / total * 100.0;
+ this->values[5] = cpuData->ioWaitPeriod / total * 100.0;
+ this->values[6] = cpuData->stealPeriod / total * 100.0;
+ this->values[7] = cpuData->guestPeriod / total * 100.0;
+ this->type->items = 8;
+ percent = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+
+ this->values[3]+this->values[4])));
+ } else {
+ this->values[2] = cpuData->systemAllPeriod / total * 100.0;
+ this->values[3] = (cpuData->stealPeriod + cpuData->guestPeriod) / total * 100.0;
+ this->type->items = 4;
+ percent = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+this->values[3])));
+ }
+ if (isnan(percent)) percent = 0.0;
+ snprintf(buffer, size, "%5.1f%%", percent);
+}
+
+static void CPUMeter_display(Object* cast, RichString* out) {
+ char buffer[50];
+ Meter* this = (Meter*)cast;
+ RichString_prune(out);
+ if (this->param > this->pl->cpuCount) {
+ RichString_append(out, CRT_colors[METER_TEXT], "absent");
+ return;
+ }
+ sprintf(buffer, "%5.1f%% ", this->values[1]);
+ RichString_append(out, CRT_colors[METER_TEXT], ":");
+ RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
+ if (this->pl->detailedCPUTime) {
+ 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], "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);
+ sprintf(buffer, "%5.1f%% ", this->values[5]);
+ RichString_append(out, CRT_colors[METER_TEXT], "wa:");
+ RichString_append(out, CRT_colors[CPU_IOWAIT], buffer);
+ sprintf(buffer, "%5.1f%% ", this->values[6]);
+ RichString_append(out, CRT_colors[METER_TEXT], "st:");
+ RichString_append(out, CRT_colors[CPU_STEAL], buffer);
+ if (this->values[7]) {
+ sprintf(buffer, "%5.1f%% ", this->values[7]);
+ RichString_append(out, CRT_colors[METER_TEXT], "gu:");
+ RichString_append(out, CRT_colors[CPU_GUEST], 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);
+ if (this->values[3]) {
+ sprintf(buffer, "%5.1f%% ", this->values[3]);
+ RichString_append(out, CRT_colors[METER_TEXT], "vir:");
+ RichString_append(out, CRT_colors[CPU_GUEST], buffer);
+ }
+ }
+}
+
+static void AllCPUsMeter_init(Meter* this) {
+ int cpus = this->pl->cpuCount;
+ this->drawBuffer = malloc(sizeof(Meter*) * cpus);
+ Meter** meters = (Meter**) this->drawBuffer;
+ for (int i = 0; i < cpus; i++)
+ meters[i] = Meter_new(this->pl, i+1, &CPUMeter);
+ this->h = cpus;
+ this->mode = BAR_METERMODE;
+}
+
+static void AllCPUsMeter_done(Meter* this) {
+ int cpus = this->pl->cpuCount;
+ Meter** meters = (Meter**) this->drawBuffer;
+ for (int i = 0; i < cpus; i++)
+ Meter_delete((Object*)meters[i]);
+}
+
+static void AllCPUsMeter_setMode(Meter* this, int mode) {
+ this->mode = mode;
+ int cpus = this->pl->cpuCount;
+ int h = Meter_modes[this->mode]->h;
+ this->h = h * cpus;
+}
+
+static void AllCPUsMeter_draw(Meter* this, int x, int y, int w) {
+ int cpus = this->pl->cpuCount;
+ Meter** meters = (Meter**) this->drawBuffer;
+ for (int i = 0; i < cpus; i++) {
+ Meter_setMode(meters[i], this->mode);
+ meters[i]->draw(meters[i], x, y, w);
+ y += meters[i]->h;
+ }
+}
+
+MeterType CPUMeter = {
+ .setValues = CPUMeter_setValues,
+ .display = CPUMeter_display,
+ .mode = BAR_METERMODE,
+ .items = 8,
+ .total = 100.0,
+ .attributes = CPUMeter_attributes,
+ .name = "CPU",
+ .uiName = "CPU",
+ .caption = "CPU",
+ .init = CPUMeter_init
+};
+
+MeterType AllCPUsMeter = {
+ .mode = 0,
+ .items = 1,
+ .total = 100.0,
+ .attributes = CPUMeter_attributes,
+ .name = "AllCPUs",
+ .uiName = "All CPUs",
+ .caption = "CPU",
+ .draw = AllCPUsMeter_draw,
+ .init = AllCPUsMeter_init,
+ .setMode = AllCPUsMeter_setMode,
+ .done = AllCPUsMeter_done
+};