mirror of
https://github.com/xzeldon/htop.git
synced 2025-07-14 13:04:35 +03:00
add support for steal/guest CPU time measurement
simplify processor data accounting (add CPUData structure) remove Process_clone trick
This commit is contained in:
83
CPUMeter.c
83
CPUMeter.c
@ -19,7 +19,7 @@ in the source distribution for its full text.
|
||||
#include <assert.h>
|
||||
|
||||
int CPUMeter_attributes[] = {
|
||||
CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IRQ, CPU_SOFTIRQ, CPU_IOWAIT
|
||||
CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IRQ, CPU_SOFTIRQ, CPU_IOWAIT, CPU_STEAL, CPU_GUEST
|
||||
};
|
||||
|
||||
#ifndef MIN
|
||||
@ -30,10 +30,10 @@ int CPUMeter_attributes[] = {
|
||||
#endif
|
||||
|
||||
static void CPUMeter_init(Meter* this) {
|
||||
int processor = this->param;
|
||||
if (this->pl->processorCount > 1) {
|
||||
int cpu = this->param;
|
||||
if (this->pl->cpuCount > 1) {
|
||||
char caption[10];
|
||||
sprintf(caption, "%-3d", processor);
|
||||
sprintf(caption, "%-3d", cpu);
|
||||
Meter_setCaption(this, caption);
|
||||
}
|
||||
if (this->param == 0)
|
||||
@ -42,37 +42,41 @@ static void CPUMeter_init(Meter* this) {
|
||||
|
||||
static void CPUMeter_setValues(Meter* this, char* buffer, int size) {
|
||||
ProcessList* pl = this->pl;
|
||||
int processor = this->param;
|
||||
if (processor > this->pl->processorCount) {
|
||||
int cpu = this->param;
|
||||
if (cpu > this->pl->cpuCount) {
|
||||
snprintf(buffer, size, "absent");
|
||||
return;
|
||||
}
|
||||
double total = (double) (pl->totalPeriod[processor] == 0 ? 1 : pl->totalPeriod[processor]);
|
||||
double cpu;
|
||||
this->values[0] = pl->nicePeriod[processor] / total * 100.0;
|
||||
this->values[1] = pl->userPeriod[processor] / total * 100.0;
|
||||
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] = 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[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] = 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])));
|
||||
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(cpu)) cpu = 0.0;
|
||||
snprintf(buffer, size, "%5.1f%%", cpu );
|
||||
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_init(out);
|
||||
if (this->param > this->pl->processorCount) {
|
||||
if (this->param > this->pl->cpuCount) {
|
||||
RichString_append(out, CRT_colors[METER_TEXT], "absent");
|
||||
return;
|
||||
}
|
||||
@ -95,6 +99,14 @@ static void CPUMeter_display(Object* cast, RichString* out) {
|
||||
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:");
|
||||
@ -102,37 +114,42 @@ static void CPUMeter_display(Object* cast, RichString* out) {
|
||||
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 processors = this->pl->processorCount;
|
||||
this->drawBuffer = malloc(sizeof(Meter*) * processors);
|
||||
int cpus = this->pl->cpuCount;
|
||||
this->drawBuffer = malloc(sizeof(Meter*) * cpus);
|
||||
Meter** meters = (Meter**) this->drawBuffer;
|
||||
for (int i = 0; i < processors; i++)
|
||||
for (int i = 0; i < cpus; i++)
|
||||
meters[i] = Meter_new(this->pl, i+1, &CPUMeter);
|
||||
this->h = processors;
|
||||
this->h = cpus;
|
||||
this->mode = BAR_METERMODE;
|
||||
}
|
||||
|
||||
static void AllCPUsMeter_done(Meter* this) {
|
||||
int processors = this->pl->processorCount;
|
||||
int cpus = this->pl->cpuCount;
|
||||
Meter** meters = (Meter**) this->drawBuffer;
|
||||
for (int i = 0; i < processors; i++)
|
||||
for (int i = 0; i < cpus; i++)
|
||||
Meter_delete((Object*)meters[i]);
|
||||
}
|
||||
|
||||
static void AllCPUsMeter_setMode(Meter* this, int mode) {
|
||||
this->mode = mode;
|
||||
int processors = this->pl->processorCount;
|
||||
int cpus = this->pl->cpuCount;
|
||||
int h = Meter_modes[this->mode]->h;
|
||||
this->h = h * processors;
|
||||
this->h = h * cpus;
|
||||
}
|
||||
|
||||
static void AllCPUsMeter_draw(Meter* this, int x, int y, int w) {
|
||||
int processors = this->pl->processorCount;
|
||||
int cpus = this->pl->cpuCount;
|
||||
Meter** meters = (Meter**) this->drawBuffer;
|
||||
for (int i = 0; i < processors; i++) {
|
||||
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;
|
||||
@ -143,7 +160,7 @@ MeterType CPUMeter = {
|
||||
.setValues = CPUMeter_setValues,
|
||||
.display = CPUMeter_display,
|
||||
.mode = BAR_METERMODE,
|
||||
.items = 6,
|
||||
.items = 8,
|
||||
.total = 100.0,
|
||||
.attributes = CPUMeter_attributes,
|
||||
.name = "CPU",
|
||||
|
Reference in New Issue
Block a user