From 65357c8c46154de4e4eca14075bfe5523bb5fc14 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Mon, 7 Dec 2020 10:26:01 +0100 Subject: New upstream version 3.0.3 --- CPUMeter.c | 371 ++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 257 insertions(+), 114 deletions(-) (limited to 'CPUMeter.c') diff --git a/CPUMeter.c b/CPUMeter.c index cb77e71..97fc3f0 100644 --- a/CPUMeter.c +++ b/CPUMeter.c @@ -1,67 +1,107 @@ /* htop - CPUMeter.c (C) 2004-2011 Hisham H. Muhammad -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ +#include "config.h" // IWYU pragma: keep + #include "CPUMeter.h" +#include +#include +#include +#include + #include "CRT.h" -#include "Settings.h" +#include "Object.h" #include "Platform.h" +#include "ProcessList.h" +#include "RichString.h" +#include "Settings.h" +#include "XUtils.h" -#include -#include -#include -#include -int CPUMeter_attributes[] = { - CPU_NICE, CPU_NORMAL, CPU_SYSTEM, CPU_IRQ, CPU_SOFTIRQ, CPU_STEAL, CPU_GUEST, CPU_IOWAIT +static const int CPUMeter_attributes[] = { + CPU_NICE, + CPU_NORMAL, + CPU_SYSTEM, + CPU_IRQ, + CPU_SOFTIRQ, + CPU_STEAL, + CPU_GUEST, + CPU_IOWAIT }; +typedef struct CPUMeterData_ { + int cpus; + Meter** meters; +} CPUMeterData; + static void CPUMeter_init(Meter* this) { int cpu = this->param; if (this->pl->cpuCount > 1) { char caption[10]; - xSnprintf(caption, sizeof(caption), "%-3d", Settings_cpuId(this->pl->settings, cpu - 1)); + xSnprintf(caption, sizeof(caption), "%3d", Settings_cpuId(this->pl->settings, cpu - 1)); Meter_setCaption(this, caption); } if (this->param == 0) Meter_setCaption(this, "Avg"); } -static void CPUMeter_updateValues(Meter* this, char* buffer, int size) { +static void CPUMeter_updateValues(Meter* this, char* buffer, size_t size) { int cpu = this->param; if (cpu > this->pl->cpuCount) { xSnprintf(buffer, size, "absent"); + for (uint8_t i = 0; i < this->curItems; i++) + this->values[i] = 0; return; } memset(this->values, 0, sizeof(double) * CPU_METER_ITEMCOUNT); + + char cpuUsageBuffer[8] = { 0 }; + char cpuFrequencyBuffer[16] = { 0 }; + char cpuTemperatureBuffer[16] = { 0 }; + double percent = Platform_setCPUValues(this, cpu); + + if (this->pl->settings->showCPUUsage) { + xSnprintf(cpuUsageBuffer, sizeof(cpuUsageBuffer), "%5.1f%%", percent); + } + if (this->pl->settings->showCPUFrequency) { double cpuFrequency = this->values[CPU_METER_FREQUENCY]; - char cpuFrequencyBuffer[16]; - if (cpuFrequency < 0) { + if (isnan(cpuFrequency)) { xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "N/A"); } else { - xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "%.0fMHz", cpuFrequency); - } - if (this->pl->settings->showCPUUsage) { - xSnprintf(buffer, size, "%5.1f%% %s", percent, cpuFrequencyBuffer); - } else { - xSnprintf(buffer, size, "%s", cpuFrequencyBuffer); + xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "%4uMHz", (unsigned)cpuFrequency); } - } else if (this->pl->settings->showCPUUsage) { - xSnprintf(buffer, size, "%5.1f%%", percent); - } else if (size > 0) { - buffer[0] = '\0'; } + + #ifdef HAVE_SENSORS_SENSORS_H + if (this->pl->settings->showCPUTemperature) { + double cpuTemperature = this->values[CPU_METER_TEMPERATURE]; + if (isnan(cpuTemperature)) + xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "N/A"); + else if (this->pl->settings->degreeFahrenheit) + xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%3d%sF", (int)(cpuTemperature * 9 / 5 + 32), CRT_degreeSign); + else + xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%d%sC", (int)cpuTemperature, CRT_degreeSign); + } + #endif + + xSnprintf(buffer, size, "%s%s%s%s%s", + cpuUsageBuffer, + (cpuUsageBuffer[0] && (cpuFrequencyBuffer[0] || cpuTemperatureBuffer[0])) ? " " : "", + cpuFrequencyBuffer, + (cpuFrequencyBuffer[0] && cpuTemperatureBuffer[0]) ? " " : "", + cpuTemperatureBuffer); } -static void CPUMeter_display(Object* cast, RichString* out) { +static void CPUMeter_display(const Object* cast, RichString* out) { char buffer[50]; - Meter* this = (Meter*)cast; + const Meter* this = (const Meter*)cast; RichString_prune(out); if (this->param > this->pl->cpuCount) { RichString_append(out, CRT_colors[METER_TEXT], "absent"); @@ -83,12 +123,12 @@ static void CPUMeter_display(Object* cast, RichString* out) { xSnprintf(buffer, sizeof(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[CPU_METER_STEAL]) { + if (!isnan(this->values[CPU_METER_STEAL])) { xSnprintf(buffer, sizeof(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[CPU_METER_GUEST]) { + if (!isnan(this->values[CPU_METER_GUEST])) { xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_GUEST]); RichString_append(out, CRT_colors[METER_TEXT], "gu:"); RichString_append(out, CRT_colors[CPU_GUEST], buffer); @@ -103,16 +143,33 @@ static void CPUMeter_display(Object* cast, RichString* out) { xSnprintf(buffer, sizeof(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[CPU_METER_IRQ]) { + if (!isnan(this->values[CPU_METER_IRQ])) { xSnprintf(buffer, sizeof(buffer), "%5.1f%% ", this->values[CPU_METER_IRQ]); RichString_append(out, CRT_colors[METER_TEXT], "vir:"); RichString_append(out, CRT_colors[CPU_GUEST], buffer); } } + + #ifdef HAVE_SENSORS_SENSORS_H + if (this->pl->settings->showCPUTemperature) { + char cpuTemperatureBuffer[10]; + double cpuTemperature = this->values[CPU_METER_TEMPERATURE]; + if (isnan(cpuTemperature)) { + xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "N/A"); + } else if (this->pl->settings->degreeFahrenheit) { + xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%5.1f%sF", cpuTemperature * 9 / 5 + 32, CRT_degreeSign); + } else { + xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%5.1f%sC", cpuTemperature, CRT_degreeSign); + } + RichString_append(out, CRT_colors[METER_TEXT], "temp:"); + RichString_append(out, CRT_colors[METER_VALUE], cpuTemperatureBuffer); + } + #endif } static void AllCPUsMeter_getRange(Meter* this, int* start, int* count) { - int cpus = this->pl->cpuCount; + CPUMeterData* data = this->meterData; + int cpus = data->cpus; switch(Meter_name(this)[0]) { default: case 'A': // All @@ -130,75 +187,119 @@ static void AllCPUsMeter_getRange(Meter* this, int* start, int* count) { } } -static int MapClassnameToColumncount(Meter* this){ - if (strchr(Meter_name(this), '4')) - return 4; - else if (strchr(Meter_name(this), '2')) - return 2; - else - return 1; -} - -static void AllCPUsMeter_init(Meter* this) { +static void CPUMeterCommonInit(Meter* this, int ncol) { int cpus = this->pl->cpuCount; - if (!this->drawData) - this->drawData = xCalloc(cpus, sizeof(Meter*)); - Meter** meters = (Meter**) this->drawData; + CPUMeterData* data = this->meterData; + if (!data) { + data = this->meterData = xMalloc(sizeof(CPUMeterData)); + data->cpus = cpus; + data->meters = xCalloc(cpus, sizeof(Meter*)); + } + Meter** meters = data->meters; int start, count; AllCPUsMeter_getRange(this, &start, &count); for (int i = 0; i < count; i++) { if (!meters[i]) - meters[i] = Meter_new(this->pl, start+i+1, (MeterClass*) Class(CPUMeter)); + meters[i] = Meter_new(this->pl, start + i + 1, (const MeterClass*) Class(CPUMeter)); + Meter_init(meters[i]); } + if (this->mode == 0) this->mode = BAR_METERMODE; + int h = Meter_modes[this->mode]->h; - int ncol = MapClassnameToColumncount(this); - this->h = h * ((count + ncol - 1)/ ncol); + this->h = h * ((count + ncol - 1) / ncol); +} + +static void CPUMeterCommonUpdateMode(Meter* this, int mode, int ncol) { + CPUMeterData* data = this->meterData; + Meter** meters = data->meters; + this->mode = mode; + int h = Meter_modes[mode]->h; + int start, count; + AllCPUsMeter_getRange(this, &start, &count); + for (int i = 0; i < count; i++) { + Meter_setMode(meters[i], mode); + } + this->h = h * ((count + ncol - 1) / ncol); } static void AllCPUsMeter_done(Meter* this) { - Meter** meters = (Meter**) this->drawData; + CPUMeterData* data = this->meterData; + Meter** meters = data->meters; int start, count; AllCPUsMeter_getRange(this, &start, &count); for (int i = 0; i < count; i++) Meter_delete((Object*)meters[i]); + free(data->meters); + free(data); } -static void AllCPUsMeter_updateMode(Meter* this, int mode) { - Meter** meters = (Meter**) this->drawData; - this->mode = mode; - int h = Meter_modes[mode]->h; +static void SingleColCPUsMeter_init(Meter* this) { + CPUMeterCommonInit(this, 1); +} + +static void SingleColCPUsMeter_updateMode(Meter* this, int mode) { + CPUMeterCommonUpdateMode(this, mode, 1); +} + +static void DualColCPUsMeter_init(Meter* this) { + CPUMeterCommonInit(this, 2); +} + +static void DualColCPUsMeter_updateMode(Meter* this, int mode) { + CPUMeterCommonUpdateMode(this, mode, 2); +} + +static void QuadColCPUsMeter_init(Meter* this) { + CPUMeterCommonInit(this, 4); +} + +static void QuadColCPUsMeter_updateMode(Meter* this, int mode) { + CPUMeterCommonUpdateMode(this, mode, 4); +} + +static void OctoColCPUsMeter_init(Meter* this) { + CPUMeterCommonInit(this, 8); +} + +static void OctoColCPUsMeter_updateMode(Meter* this, int mode) { + CPUMeterCommonUpdateMode(this, mode, 8); +} + +static void CPUMeterCommonDraw(Meter* this, int x, int y, int w, int ncol) { + CPUMeterData* data = this->meterData; + Meter** meters = data->meters; int start, count; AllCPUsMeter_getRange(this, &start, &count); + int colwidth = (w - ncol) / ncol + 1; + int diff = (w - (colwidth * ncol)); + int nrows = (count + ncol - 1) / ncol; for (int i = 0; i < count; i++) { - Meter_setMode(meters[i], mode); + int d = (i / nrows) > diff ? diff : (i / nrows); // dynamic spacer + int xpos = x + ((i / nrows) * colwidth) + d; + int ypos = y + ((i % nrows) * meters[0]->h); + meters[i]->draw(meters[i], xpos, ypos, colwidth); } - int ncol = MapClassnameToColumncount(this); - this->h = h * ((count + ncol - 1)/ ncol); } static void DualColCPUsMeter_draw(Meter* this, int x, int y, int w) { - Meter** meters = (Meter**) this->drawData; - int start, count; - int pad = this->pl->settings->headerMargin ? 2 : 0; - AllCPUsMeter_getRange(this, &start, &count); - int height = (count+1)/2; - int startY = y; - for (int i = 0; i < height; i++) { - meters[i]->draw(meters[i], x, y, (w-pad)/2); - y += meters[i]->h; - } - y = startY; - for (int i = height; i < count; i++) { - meters[i]->draw(meters[i], x+(w-1)/2+1+(pad/2), y, (w-pad)/2); - y += meters[i]->h; - } + CPUMeterCommonDraw(this, x, y, w, 2); +} + +static void QuadColCPUsMeter_draw(Meter* this, int x, int y, int w) { + CPUMeterCommonDraw(this, x, y, w, 4); } +static void OctoColCPUsMeter_draw(Meter* this, int x, int y, int w) { + CPUMeterCommonDraw(this, x, y, w, 8); +} + + static void SingleColCPUsMeter_draw(Meter* this, int x, int y, int w) { - Meter** meters = (Meter**) this->drawData; + CPUMeterData* data = this->meterData; + Meter** meters = data->meters; int start, count; AllCPUsMeter_getRange(this, &start, &count); for (int i = 0; i < count; i++) { @@ -207,23 +308,8 @@ static void SingleColCPUsMeter_draw(Meter* this, int x, int y, int w) { } } -static void MultiColCPUsMeter_draw(Meter* this, int x, int y, int w){ - Meter** meters = (Meter**) this->drawData; - int start, count; - AllCPUsMeter_getRange(this, &start, &count); - int ncol = MapClassnameToColumncount(this); - int colwidth = (w-ncol)/ncol + 1; - int diff = (w - (colwidth * ncol)); - int nrows = (count + ncol - 1) / ncol; - for (int i = 0; i < count; i++){ - int d = (i/nrows) > diff ? diff : (i / nrows) ; // dynamic spacer - int xpos = x + ((i / nrows) * colwidth) + d; - int ypos = y + ((i % nrows) * meters[0]->h); - meters[i]->draw(meters[i], xpos, ypos, colwidth); - } -} -MeterClass CPUMeter_class = { +const MeterClass CPUMeter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -240,7 +326,7 @@ MeterClass CPUMeter_class = { .init = CPUMeter_init }; -MeterClass AllCPUsMeter_class = { +const MeterClass AllCPUsMeter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -254,12 +340,12 @@ MeterClass AllCPUsMeter_class = { .description = "CPUs (1/1): all CPUs", .caption = "CPU", .draw = SingleColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .init = SingleColCPUsMeter_init, + .updateMode = SingleColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -MeterClass AllCPUs2Meter_class = { +const MeterClass AllCPUs2Meter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -273,12 +359,12 @@ MeterClass AllCPUs2Meter_class = { .description = "CPUs (1&2/2): all CPUs in 2 shorter columns", .caption = "CPU", .draw = DualColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .init = DualColCPUsMeter_init, + .updateMode = DualColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -MeterClass LeftCPUsMeter_class = { +const MeterClass LeftCPUsMeter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -292,12 +378,12 @@ MeterClass LeftCPUsMeter_class = { .description = "CPUs (1/2): first half of list", .caption = "CPU", .draw = SingleColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .init = SingleColCPUsMeter_init, + .updateMode = SingleColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -MeterClass RightCPUsMeter_class = { +const MeterClass RightCPUsMeter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -311,12 +397,12 @@ MeterClass RightCPUsMeter_class = { .description = "CPUs (2/2): second half of list", .caption = "CPU", .draw = SingleColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .init = SingleColCPUsMeter_init, + .updateMode = SingleColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -MeterClass LeftCPUs2Meter_class = { +const MeterClass LeftCPUs2Meter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -330,12 +416,12 @@ MeterClass LeftCPUs2Meter_class = { .description = "CPUs (1&2/4): first half in 2 shorter columns", .caption = "CPU", .draw = DualColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .init = DualColCPUsMeter_init, + .updateMode = DualColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -MeterClass RightCPUs2Meter_class = { +const MeterClass RightCPUs2Meter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -349,12 +435,12 @@ MeterClass RightCPUs2Meter_class = { .description = "CPUs (3&4/4): second half in 2 shorter columns", .caption = "CPU", .draw = DualColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .init = DualColCPUsMeter_init, + .updateMode = DualColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -MeterClass AllCPUs4Meter_class = { +const MeterClass AllCPUs4Meter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -367,13 +453,13 @@ MeterClass AllCPUs4Meter_class = { .uiName = "CPUs (1&2&3&4/4)", .description = "CPUs (1&2&3&4/4): all CPUs in 4 shorter columns", .caption = "CPU", - .draw = MultiColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .draw = QuadColCPUsMeter_draw, + .init = QuadColCPUsMeter_init, + .updateMode = QuadColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -MeterClass LeftCPUs4Meter_class = { +const MeterClass LeftCPUs4Meter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -386,13 +472,13 @@ MeterClass LeftCPUs4Meter_class = { .uiName = "CPUs (1-4/8)", .description = "CPUs (1-4/8): first half in 4 shorter columns", .caption = "CPU", - .draw = MultiColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .draw = QuadColCPUsMeter_draw, + .init = QuadColCPUsMeter_init, + .updateMode = QuadColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -MeterClass RightCPUs4Meter_class = { +const MeterClass RightCPUs4Meter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, @@ -405,8 +491,65 @@ MeterClass RightCPUs4Meter_class = { .uiName = "CPUs (5-8/8)", .description = "CPUs (5-8/8): second half in 4 shorter columns", .caption = "CPU", - .draw = MultiColCPUsMeter_draw, - .init = AllCPUsMeter_init, - .updateMode = AllCPUsMeter_updateMode, + .draw = QuadColCPUsMeter_draw, + .init = QuadColCPUsMeter_init, + .updateMode = QuadColCPUsMeter_updateMode, + .done = AllCPUsMeter_done +}; + +const MeterClass AllCPUs8Meter_class = { + .super = { + .extends = Class(Meter), + .delete = Meter_delete, + .display = CPUMeter_display + }, + .defaultMode = CUSTOM_METERMODE, + .total = 100.0, + .attributes = CPUMeter_attributes, + .name = "AllCPUs8", + .uiName = "CPUs (1-8/8)", + .description = "CPUs (1-8/8): all CPUs in 8 shorter columns", + .caption = "CPU", + .draw = OctoColCPUsMeter_draw, + .init = OctoColCPUsMeter_init, + .updateMode = OctoColCPUsMeter_updateMode, + .done = AllCPUsMeter_done +}; + +const MeterClass LeftCPUs8Meter_class = { + .super = { + .extends = Class(Meter), + .delete = Meter_delete, + .display = CPUMeter_display + }, + .defaultMode = CUSTOM_METERMODE, + .total = 100.0, + .attributes = CPUMeter_attributes, + .name = "LeftCPUs8", + .uiName = "CPUs (1-8/16)", + .description = "CPUs (1-8/16): first half in 8 shorter columns", + .caption = "CPU", + .draw = OctoColCPUsMeter_draw, + .init = OctoColCPUsMeter_init, + .updateMode = OctoColCPUsMeter_updateMode, + .done = AllCPUsMeter_done +}; + +const MeterClass RightCPUs8Meter_class = { + .super = { + .extends = Class(Meter), + .delete = Meter_delete, + .display = CPUMeter_display + }, + .defaultMode = CUSTOM_METERMODE, + .total = 100.0, + .attributes = CPUMeter_attributes, + .name = "RightCPUs8", + .uiName = "CPUs (9-16/16)", + .description = "CPUs (9-16/16): second half in 8 shorter columns", + .caption = "CPU", + .draw = OctoColCPUsMeter_draw, + .init = OctoColCPUsMeter_init, + .updateMode = OctoColCPUsMeter_updateMode, .done = AllCPUsMeter_done }; -- cgit v1.2.3