From 71190654bc926fb137e829fb8e2f9efa1e4344ab Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Fri, 23 Oct 2015 13:46:21 -0200 Subject: [PATCH] Calculate CPU averages on Darwin (See #295). --- CPUMeter.c | 44 ++++++++++++++++++++++++++++-------------- CPUMeter.h | 13 +++++++++++++ darwin/DarwinProcess.c | 10 +++++----- darwin/Platform.c | 25 ++++++++++++++++++++---- linux/Platform.c | 16 +++++++-------- 5 files changed, 76 insertions(+), 32 deletions(-) diff --git a/CPUMeter.c b/CPUMeter.c index e2c45ccf..36d6c4e0 100644 --- a/CPUMeter.c +++ b/CPUMeter.c @@ -18,6 +18,19 @@ in the source distribution for its full text. /*{ #include "Meter.h" + +typedef enum { + CPU_METER_NICE = 0, + CPU_METER_NORMAL = 1, + CPU_METER_KERNEL = 2, + CPU_METER_IRQ = 3, + CPU_METER_SOFTIRQ = 4, + CPU_METER_STEAL = 5, + CPU_METER_GUEST = 6, + CPU_METER_IOWAIT = 7, + CPU_METER_ITEMCOUNT = 8, // number of entries in this enum +} CPUMeterValues; + }*/ int CPUMeter_attributes[] = { @@ -48,6 +61,7 @@ static void CPUMeter_setValues(Meter* this, char* buffer, int size) { snprintf(buffer, size, "absent"); return; } + memset(this->values, 0, sizeof(double) * CPU_METER_ITEMCOUNT); double percent = Platform_setCPUValues(this, cpu); snprintf(buffer, size, "%5.1f%%", percent); } @@ -60,44 +74,44 @@ static void CPUMeter_display(Object* cast, RichString* out) { RichString_append(out, CRT_colors[METER_TEXT], "absent"); return; } - sprintf(buffer, "%5.1f%% ", this->values[1]); + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_NORMAL]); RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[CPU_NORMAL], buffer); if (this->pl->settings->detailedCPUTime) { - sprintf(buffer, "%5.1f%% ", this->values[2]); + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_KERNEL]); RichString_append(out, CRT_colors[METER_TEXT], "sy:"); RichString_append(out, CRT_colors[CPU_KERNEL], buffer); - sprintf(buffer, "%5.1f%% ", this->values[0]); + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_NICE]); RichString_append(out, CRT_colors[METER_TEXT], "ni:"); RichString_append(out, CRT_colors[CPU_NICE_TEXT], buffer); - sprintf(buffer, "%5.1f%% ", this->values[3]); + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_IRQ]); RichString_append(out, CRT_colors[METER_TEXT], "hi:"); RichString_append(out, CRT_colors[CPU_IRQ], buffer); - sprintf(buffer, "%5.1f%% ", this->values[4]); + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_SOFTIRQ]); RichString_append(out, CRT_colors[METER_TEXT], "si:"); RichString_append(out, CRT_colors[CPU_SOFTIRQ], buffer); - if (this->values[5]) { - sprintf(buffer, "%5.1f%% ", this->values[5]); + if (this->values[CPU_METER_STEAL]) { + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_STEAL]); RichString_append(out, CRT_colors[METER_TEXT], "st:"); RichString_append(out, CRT_colors[CPU_STEAL], buffer); } - if (this->values[6]) { - sprintf(buffer, "%5.1f%% ", this->values[6]); + if (this->values[CPU_METER_GUEST]) { + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_GUEST]); RichString_append(out, CRT_colors[METER_TEXT], "gu:"); RichString_append(out, CRT_colors[CPU_GUEST], buffer); } - sprintf(buffer, "%5.1f%% ", this->values[7]); + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_IOWAIT]); RichString_append(out, CRT_colors[METER_TEXT], "wa:"); RichString_append(out, CRT_colors[CPU_IOWAIT], buffer); } else { - sprintf(buffer, "%5.1f%% ", this->values[2]); + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_KERNEL]); RichString_append(out, CRT_colors[METER_TEXT], "sys:"); RichString_append(out, CRT_colors[CPU_KERNEL], buffer); - sprintf(buffer, "%5.1f%% ", this->values[0]); + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_NICE]); RichString_append(out, CRT_colors[METER_TEXT], "low:"); RichString_append(out, CRT_colors[CPU_NICE_TEXT], buffer); - if (this->values[3]) { - sprintf(buffer, "%5.1f%% ", this->values[3]); + if (this->values[CPU_METER_IRQ]) { + sprintf(buffer, "%5.1f%% ", this->values[CPU_METER_IRQ]); RichString_append(out, CRT_colors[METER_TEXT], "vir:"); RichString_append(out, CRT_colors[CPU_GUEST], buffer); } @@ -203,7 +217,7 @@ MeterClass CPUMeter_class = { }, .setValues = CPUMeter_setValues, .defaultMode = BAR_METERMODE, - .maxItems = 8, + .maxItems = CPU_METER_ITEMCOUNT, .total = 100.0, .attributes = CPUMeter_attributes, .name = "CPU", diff --git a/CPUMeter.h b/CPUMeter.h index f91c7597..2f163968 100644 --- a/CPUMeter.h +++ b/CPUMeter.h @@ -11,6 +11,19 @@ in the source distribution for its full text. #include "Meter.h" +typedef enum { + CPU_METER_NICE = 0, + CPU_METER_NORMAL = 1, + CPU_METER_KERNEL = 2, + CPU_METER_IRQ = 3, + CPU_METER_SOFTIRQ = 4, + CPU_METER_STEAL = 5, + CPU_METER_GUEST = 6, + CPU_METER_IOWAIT = 7, + CPU_METER_ITEMCOUNT = 8, // number of entries in this enum +} CPUMeterValues; + + extern int CPUMeter_attributes[]; #ifndef MIN diff --git a/darwin/DarwinProcess.c b/darwin/DarwinProcess.c index 0b4ec3fe..83e9d828 100644 --- a/darwin/DarwinProcess.c +++ b/darwin/DarwinProcess.c @@ -220,11 +220,11 @@ char *DarwinProcess_getCmdLine(struct kinfo_proc* k, int show_args ) { /* Convert previous '\0'. */ *np = ' '; } - /* Note location of current '\0'. */ - np = cp; - } - } - } + /* Note location of current '\0'. */ + np = cp; + } + } + } #endif /* diff --git a/darwin/Platform.c b/darwin/Platform.c index f56d27f3..f8108e78 100644 --- a/darwin/Platform.c +++ b/darwin/Platform.c @@ -21,6 +21,7 @@ in the source distribution for its full text. /*{ #include "Action.h" +#include "CPUMeter.h" #include "BatteryMeter.h" #include "DarwinProcess.h" }*/ @@ -163,11 +164,27 @@ ProcessPidColumn Process_pidColumns[] = { { .id = 0, .label = NULL }, }; +static double Platform_setCPUAverageValues(Meter* mtr) { + DarwinProcessList *dpl = (DarwinProcessList *)mtr->pl; + int cpus = dpl->super.cpuCount; + double sumNice, sumNormal, sumKernel, sumPercent; + for (int i = 1; i <= cpus; i++) { + sumPercent += Platform_setCPUValues(mtr, i); + sumNice += mtr->values[CPU_METER_NICE]; + sumNormal += mtr->values[CPU_METER_NORMAL]; + sumKernel += mtr->values[CPU_METER_KERNEL]; + } + mtr->values[CPU_METER_NICE] = sumNice / cpus; + mtr->values[CPU_METER_NORMAL] = sumNormal / cpus; + mtr->values[CPU_METER_KERNEL] = sumKernel / cpus; + return sumPercent / cpus; +} + double Platform_setCPUValues(Meter* mtr, int cpu) { - /* All just from CPUMeter.c */ - static const int CPU_METER_NICE = 0; - static const int CPU_METER_NORMAL = 1; - static const int CPU_METER_KERNEL = 2; + + if (cpu == 0) { + return Platform_setCPUAverageValues(mtr); + } DarwinProcessList *dpl = (DarwinProcessList *)mtr->pl; processor_cpu_load_info_t prev = &dpl->prev_load[cpu-1]; diff --git a/linux/Platform.c b/linux/Platform.c index 32f73893..3a919bb1 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -162,15 +162,15 @@ double Platform_setCPUValues(Meter* this, int cpu) { double total = (double) ( cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod); double percent; double* v = this->values; - v[0] = cpuData->nicePeriod / total * 100.0; - v[1] = cpuData->userPeriod / total * 100.0; + v[CPU_METER_NICE] = cpuData->nicePeriod / total * 100.0; + v[CPU_METER_NORMAL] = cpuData->userPeriod / total * 100.0; if (this->pl->settings->detailedCPUTime) { - v[2] = cpuData->systemPeriod / total * 100.0; - v[3] = cpuData->irqPeriod / total * 100.0; - v[4] = cpuData->softIrqPeriod / total * 100.0; - v[5] = cpuData->stealPeriod / total * 100.0; - v[6] = cpuData->guestPeriod / total * 100.0; - v[7] = cpuData->ioWaitPeriod / total * 100.0; + v[CPU_METER_KERNEL] = cpuData->systemPeriod / total * 100.0; + v[CPU_METER_IRQ] = cpuData->irqPeriod / total * 100.0; + v[CPU_METER_SOFTIRQ] = cpuData->softIrqPeriod / total * 100.0; + v[CPU_METER_STEAL] = cpuData->stealPeriod / total * 100.0; + v[CPU_METER_GUEST] = cpuData->guestPeriod / total * 100.0; + v[CPU_METER_IOWAIT] = cpuData->ioWaitPeriod / total * 100.0; Meter_setItems(this, 8); if (this->pl->settings->accountGuestInCPUMeter) { percent = v[0]+v[1]+v[2]+v[3]+v[4]+v[5]+v[6];