2006-03-04 18:16:49 +00:00
|
|
|
/*
|
|
|
|
htop - CPUMeter.c
|
2010-02-25 02:08:18 +00:00
|
|
|
(C) 2004-2010 Hisham H. Muhammad
|
2006-03-04 18:16:49 +00:00
|
|
|
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>
|
|
|
|
|
2006-06-06 20:41:01 +00:00
|
|
|
int CPUMeter_attributes[] = {
|
2007-11-09 00:40:59 +00:00
|
|
|
CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IRQ, CPU_SOFTIRQ, CPU_IOWAIT
|
2006-06-06 20:41:01 +00:00
|
|
|
};
|
2006-03-04 18:16:49 +00:00
|
|
|
|
|
|
|
#ifndef MIN
|
|
|
|
#define MIN(a,b) ((a)<(b)?(a):(b))
|
|
|
|
#endif
|
|
|
|
#ifndef MAX
|
|
|
|
#define MAX(a,b) ((a)>(b)?(a):(b))
|
|
|
|
#endif
|
|
|
|
|
2008-03-09 08:58:38 +00:00
|
|
|
static void CPUMeter_init(Meter* this) {
|
2006-04-10 20:40:38 +00:00
|
|
|
int processor = this->param;
|
|
|
|
if (this->pl->processorCount > 1) {
|
|
|
|
char caption[10];
|
2006-03-04 18:16:49 +00:00
|
|
|
sprintf(caption, "%-3d", processor);
|
2006-04-10 20:40:38 +00:00
|
|
|
Meter_setCaption(this, caption);
|
2006-03-04 18:16:49 +00:00
|
|
|
}
|
2006-04-10 20:40:38 +00:00
|
|
|
if (this->param == 0)
|
|
|
|
Meter_setCaption(this, "Avg");
|
2006-03-04 18:16:49 +00:00
|
|
|
}
|
|
|
|
|
2008-03-09 08:58:38 +00:00
|
|
|
static void CPUMeter_setValues(Meter* this, char* buffer, int size) {
|
2006-04-10 20:40:38 +00:00
|
|
|
ProcessList* pl = this->pl;
|
|
|
|
int processor = this->param;
|
2009-06-02 04:51:23 +00:00
|
|
|
if (processor > this->pl->processorCount) {
|
|
|
|
snprintf(buffer, size, "absent");
|
|
|
|
return;
|
|
|
|
}
|
2010-06-30 18:29:54 +00:00
|
|
|
double total = (double) (pl->totalPeriod[processor] == 0 ? 1 : pl->totalPeriod[processor]);
|
2006-10-04 14:21:27 +00:00
|
|
|
double cpu;
|
2006-04-10 20:40:38 +00:00
|
|
|
this->values[0] = pl->nicePeriod[processor] / total * 100.0;
|
|
|
|
this->values[1] = pl->userPeriod[processor] / total * 100.0;
|
2007-11-09 00:40:59 +00:00
|
|
|
if (pl->detailedCPUTime) {
|
2006-10-04 14:21:27 +00:00
|
|
|
this->values[2] = pl->systemPeriod[processor] / total * 100.0;
|
2007-11-09 00:40:59 +00:00
|
|
|
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;
|
2006-10-04 14:21:27 +00:00
|
|
|
this->type->items = 6;
|
|
|
|
cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+
|
2007-11-09 00:40:59 +00:00
|
|
|
this->values[3]+this->values[4])));
|
2006-10-04 14:21:27 +00:00
|
|
|
} 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])));
|
|
|
|
}
|
2010-02-25 01:40:14 +00:00
|
|
|
if (isnan(cpu)) cpu = 0.0;
|
2006-04-10 20:40:38 +00:00
|
|
|
snprintf(buffer, size, "%5.1f%%", cpu );
|
2006-03-04 18:16:49 +00:00
|
|
|
}
|
|
|
|
|
2008-03-09 08:58:38 +00:00
|
|
|
static void CPUMeter_display(Object* cast, RichString* out) {
|
2006-03-04 18:16:49 +00:00
|
|
|
char buffer[50];
|
|
|
|
Meter* this = (Meter*)cast;
|
2006-07-12 01:16:03 +00:00
|
|
|
RichString_init(out);
|
2009-06-02 04:51:23 +00:00
|
|
|
if (this->param > this->pl->processorCount) {
|
|
|
|
RichString_append(out, CRT_colors[METER_TEXT], "absent");
|
|
|
|
return;
|
|
|
|
}
|
2006-04-10 20:40:38 +00:00
|
|
|
sprintf(buffer, "%5.1f%% ", this->values[1]);
|
2006-03-04 18:16:49 +00:00
|
|
|
RichString_append(out, CRT_colors[METER_TEXT], ":");
|
|
|
|
RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
|
2007-11-09 00:40:59 +00:00
|
|
|
if (this->pl->detailedCPUTime) {
|
2006-10-04 14:21:27 +00:00
|
|
|
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);
|
2007-11-09 00:40:59 +00:00
|
|
|
sprintf(buffer, "%5.1f%% ", this->values[5]);
|
|
|
|
RichString_append(out, CRT_colors[METER_TEXT], "wa:");
|
|
|
|
RichString_append(out, CRT_colors[CPU_IOWAIT], buffer);
|
2006-10-04 14:21:27 +00:00
|
|
|
} 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);
|
|
|
|
}
|
2006-03-04 18:16:49 +00:00
|
|
|
}
|
2006-04-10 20:40:38 +00:00
|
|
|
|
2008-03-09 08:58:38 +00:00
|
|
|
static void AllCPUsMeter_init(Meter* this) {
|
2006-04-10 20:40:38 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-03-09 08:58:38 +00:00
|
|
|
static void AllCPUsMeter_done(Meter* this) {
|
2006-04-10 20:40:38 +00:00
|
|
|
int processors = this->pl->processorCount;
|
|
|
|
Meter** meters = (Meter**) this->drawBuffer;
|
|
|
|
for (int i = 0; i < processors; i++)
|
|
|
|
Meter_delete((Object*)meters[i]);
|
|
|
|
}
|
|
|
|
|
2008-03-09 08:58:38 +00:00
|
|
|
static void AllCPUsMeter_setMode(Meter* this, int mode) {
|
2006-05-09 18:35:51 +00:00
|
|
|
this->mode = mode;
|
|
|
|
int processors = this->pl->processorCount;
|
|
|
|
int h = Meter_modes[this->mode]->h;
|
|
|
|
this->h = h * processors;
|
|
|
|
}
|
|
|
|
|
2008-03-09 08:58:38 +00:00
|
|
|
static void AllCPUsMeter_draw(Meter* this, int x, int y, int w) {
|
2006-04-10 20:40:38 +00:00
|
|
|
int processors = this->pl->processorCount;
|
|
|
|
Meter** meters = (Meter**) this->drawBuffer;
|
|
|
|
for (int i = 0; i < processors; i++) {
|
|
|
|
Meter_setMode(meters[i], this->mode);
|
2006-05-09 18:35:51 +00:00
|
|
|
meters[i]->draw(meters[i], x, y, w);
|
|
|
|
y += meters[i]->h;
|
2006-04-10 20:40:38 +00:00
|
|
|
}
|
|
|
|
}
|
2008-03-09 08:58:38 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
};
|