/* htop - CPUMeter.c (C) 2004-2006 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 #include #include #include #include "debug.h" #include int CPUMeter_attributes[] = { CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IRQ, CPU_SOFTIRQ, CPU_IOWAIT }; #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 processor = this->param; if (this->pl->processorCount > 1) { char caption[10]; sprintf(caption, "%-3d", processor); 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 processor = this->param; if (processor > this->pl->processorCount) { snprintf(buffer, size, "absent"); return; } 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; if (pl->detailedCPUTime) { this->values[2] = pl->systemPeriod[processor] / total * 100.0; this->values[3] = pl->irqPeriod[processor] / total * 100.0; this->values[4] = pl->softIrqPeriod[processor] / total * 100.0; this->values[5] = pl->ioWaitPeriod[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]))); } 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 ); } static void CPUMeter_display(Object* cast, RichString* out) { char buffer[50]; Meter* this = (Meter*)cast; RichString_init(out); if (this->param > this->pl->processorCount) { 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); } 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); } } static void AllCPUsMeter_init(Meter* this) { int processors = this->pl->processorCount; this->drawBuffer = malloc(sizeof(Meter*) * processors); Meter** meters = (Meter**) this->drawBuffer; for (int i = 0; i < processors; i++) meters[i] = Meter_new(this->pl, i+1, &CPUMeter); this->h = processors; this->mode = BAR_METERMODE; } static void AllCPUsMeter_done(Meter* this) { int processors = this->pl->processorCount; Meter** meters = (Meter**) this->drawBuffer; for (int i = 0; i < processors; i++) Meter_delete((Object*)meters[i]); } static void AllCPUsMeter_setMode(Meter* this, int mode) { this->mode = mode; int processors = this->pl->processorCount; int h = Meter_modes[this->mode]->h; this->h = h * processors; } static void AllCPUsMeter_draw(Meter* this, int x, int y, int w) { int processors = this->pl->processorCount; Meter** meters = (Meter**) this->drawBuffer; for (int i = 0; i < processors; 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 = 6, .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 };