summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Scott <nathans@redhat.com>2020-08-20 14:47:07 +1000
committerNathan Scott <nathans@redhat.com>2020-08-20 14:47:07 +1000
commit6b443c5da9227221ed793616f156800ab4ee2717 (patch)
treea545f96ff0d3a7c022efec5eccf8a6ec796c9b03
parent011125dab2338acac9c4bbc7b04604f01f40e54b (diff)
parent81b64691a7ee55e5c665ac78290495b0aea946d7 (diff)
Merge branch 'hishamhm-pull-932'
-rw-r--r--CPUMeter.c28
-rw-r--r--CPUMeter.h3
-rw-r--r--DisplayOptionsPanel.c2
-rw-r--r--Settings.c10
-rw-r--r--Settings.h2
-rw-r--r--darwin/Platform.c2
-rw-r--r--dragonflybsd/Platform.c3
-rw-r--r--freebsd/Platform.c3
-rw-r--r--linux/LinuxProcessList.c74
-rw-r--r--linux/LinuxProcessList.h6
-rw-r--r--linux/Platform.c3
-rw-r--r--linux/Platform.h2
-rw-r--r--openbsd/Platform.c1
-rw-r--r--solaris/Platform.c3
-rw-r--r--unsupported/Platform.c5
15 files changed, 141 insertions, 6 deletions
diff --git a/CPUMeter.c b/CPUMeter.c
index 8a23c487..badcedab 100644
--- a/CPUMeter.c
+++ b/CPUMeter.c
@@ -28,7 +28,8 @@ typedef enum {
CPU_METER_STEAL = 5,
CPU_METER_GUEST = 6,
CPU_METER_IOWAIT = 7,
- CPU_METER_ITEMCOUNT = 8, // number of entries in this enum
+ CPU_METER_FREQUENCY = 8,
+ CPU_METER_ITEMCOUNT = 9, // number of entries in this enum
} CPUMeterValues;
}*/
@@ -63,7 +64,30 @@ static void CPUMeter_updateValues(Meter* this, char* buffer, int size) {
}
memset(this->values, 0, sizeof(double) * CPU_METER_ITEMCOUNT);
double percent = Platform_setCPUValues(this, cpu);
- xSnprintf(buffer, size, "%5.1f%%", percent);
+ if (this->pl->settings->showCPUFrequency) {
+ /* Initial frequency is in MHz. Emit it as GHz if it's larger than 1000MHz */
+ double cpuFrequency = this->values[CPU_METER_FREQUENCY];
+ char unit = 'M';
+ char cpuFrequencyBuffer[16];
+ if (cpuFrequency < 0) {
+ xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "N/A");
+ } else {
+ if (cpuFrequency > 1000) {
+ cpuFrequency /= 1000;
+ unit = 'G';
+ }
+ xSnprintf(cpuFrequencyBuffer, sizeof(cpuFrequencyBuffer), "%.3f%cHz", cpuFrequency, unit);
+ }
+ if (this->pl->settings->showCPUUsage) {
+ xSnprintf(buffer, size, "%5.1f%% %s", percent, cpuFrequencyBuffer);
+ } else {
+ xSnprintf(buffer, size, "%s", cpuFrequencyBuffer);
+ }
+ } else if (this->pl->settings->showCPUUsage) {
+ xSnprintf(buffer, size, "%5.1f%%", percent);
+ } else if (size > 0) {
+ buffer[0] = '\0';
+ }
}
static void CPUMeter_display(Object* cast, RichString* out) {
diff --git a/CPUMeter.h b/CPUMeter.h
index 2f163968..6f8599a8 100644
--- a/CPUMeter.h
+++ b/CPUMeter.h
@@ -20,7 +20,8 @@ typedef enum {
CPU_METER_STEAL = 5,
CPU_METER_GUEST = 6,
CPU_METER_IOWAIT = 7,
- CPU_METER_ITEMCOUNT = 8, // number of entries in this enum
+ CPU_METER_FREQUENCY = 8,
+ CPU_METER_ITEMCOUNT = 9, // number of entries in this enum
} CPUMeterValues;
diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c
index ece4c7c5..0f44acc2 100644
--- a/DisplayOptionsPanel.c
+++ b/DisplayOptionsPanel.c
@@ -97,6 +97,8 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Count CPUs from 0 instead of 1"), &(settings->countCPUsFromZero)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Update process names on every refresh"), &(settings->updateProcessNames)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Add guest time in CPU meter percentage"), &(settings->accountGuestInCPUMeter)));
+ Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU percentage numerically"), &(settings->showCPUUsage)));
+ Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Also show CPU frequency"), &(settings->showCPUFrequency)));
Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Enable the mouse"), &(settings->enableMouse)));
return this;
}
diff --git a/Settings.c b/Settings.c
index 69a94a8b..116595b4 100644
--- a/Settings.c
+++ b/Settings.c
@@ -45,6 +45,8 @@ typedef struct Settings_ {
bool countCPUsFromZero;
bool detailedCPUTime;
+ bool showCPUUsage;
+ bool showCPUFrequency;
bool treeView;
bool showProgramPath;
bool hideThreads;
@@ -224,6 +226,10 @@ static bool Settings_read(Settings* this, const char* fileName) {
this->detailedCPUTime = atoi(option[1]);
} else if (String_eq(option[0], "cpu_count_from_zero")) {
this->countCPUsFromZero = atoi(option[1]);
+ } else if (String_eq(option[0], "show_cpu_usage")) {
+ this->showCPUUsage = atoi(option[1]);
+ } else if (String_eq(option[0], "show_cpu_frequency")) {
+ this->showCPUFrequency = atoi(option[1]);
} else if (String_eq(option[0], "update_process_names")) {
this->updateProcessNames = atoi(option[1]);
} else if (String_eq(option[0], "account_guest_in_cpu_meter")) {
@@ -315,6 +321,8 @@ bool Settings_write(Settings* this) {
fprintf(fd, "header_margin=%d\n", (int) this->headerMargin);
fprintf(fd, "detailed_cpu_time=%d\n", (int) this->detailedCPUTime);
fprintf(fd, "cpu_count_from_zero=%d\n", (int) this->countCPUsFromZero);
+ fprintf(fd, "show_cpu_usage=%d\n", (int) this->showCPUUsage);
+ fprintf(fd, "show_cpu_frequency=%d\n", (int) this->showCPUFrequency);
fprintf(fd, "update_process_names=%d\n", (int) this->updateProcessNames);
fprintf(fd, "account_guest_in_cpu_meter=%d\n", (int) this->accountGuestInCPUMeter);
fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme);
@@ -344,6 +352,8 @@ Settings* Settings_new(int cpuCount) {
this->highlightMegabytes = false;
this->detailedCPUTime = false;
this->countCPUsFromZero = false;
+ this->showCPUUsage = true;
+ this->showCPUFrequency = false;
this->updateProcessNames = false;
this->cpuCount = cpuCount;
this->showProgramPath = true;
diff --git a/Settings.h b/Settings.h
index b9bcf87b..cf8217b5 100644
--- a/Settings.h
+++ b/Settings.h
@@ -36,6 +36,8 @@ typedef struct Settings_ {
bool countCPUsFromZero;
bool detailedCPUTime;
+ bool showCPUUsage;
+ bool showCPUFrequency;
bool treeView;
bool showProgramPath;
bool hideThreads;
diff --git a/darwin/Platform.c b/darwin/Platform.c
index 27a7b850..a052ea8a 100644
--- a/darwin/Platform.c
+++ b/darwin/Platform.c
@@ -217,6 +217,8 @@ double Platform_setCPUValues(Meter* mtr, int cpu) {
/* Convert to percent and return */
total = mtr->values[CPU_METER_NICE] + mtr->values[CPU_METER_NORMAL] + mtr->values[CPU_METER_KERNEL];
+ mtr->values[CPU_METER_FREQUENCY] = -1;
+
return CLAMP(total, 0.0, 100.0);
}
diff --git a/dragonflybsd/Platform.c b/dragonflybsd/Platform.c
index 370943d7..250e50e7 100644
--- a/dragonflybsd/Platform.c
+++ b/dragonflybsd/Platform.c
@@ -179,6 +179,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
percent = CLAMP(percent, 0.0, 100.0);
if (isnan(percent)) percent = 0.0;
+
+ v[CPU_METER_FREQUENCY] = -1;
+
return percent;
}
diff --git a/freebsd/Platform.c b/freebsd/Platform.c
index 5dd6ca41..16d02329 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -178,6 +178,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
percent = CLAMP(percent, 0.0, 100.0);
if (isnan(percent)) percent = 0.0;
+
+ v[CPU_METER_FREQUENCY] = -1;
+
return percent;
}
diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c
index 7717d5a4..5cbaee6a 100644
--- a/linux/LinuxProcessList.c
+++ b/linux/LinuxProcessList.c
@@ -74,6 +74,8 @@ typedef struct CPUData_ {
unsigned long long int softIrqPeriod;
unsigned long long int stealPeriod;
unsigned long long int guestPeriod;
+
+ double frequency;
} CPUData;
typedef struct TtyDriver_ {
@@ -100,6 +102,10 @@ typedef struct LinuxProcessList_ {
#define PROCDIR "/proc"
#endif
+#ifndef PROCCPUINFOFILE
+#define PROCCPUINFOFILE PROCDIR "/cpuinfo"
+#endif
+
#ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat"
#endif
@@ -1108,18 +1114,86 @@ static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) {
cpuData->stealTime = steal;
cpuData->guestTime = virtalltime;
cpuData->totalTime = totaltime;
+
}
double period = (double)this->cpus[0].totalPeriod / cpus;
fclose(file);
return period;
}
+static inline double LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) {
+ ProcessList* pl = (ProcessList*) this;
+ Settings* settings = pl->settings;
+
+ int cpus = this->super.cpuCount;
+ assert(cpus > 0);
+
+ for (int i = 0; i <= cpus; i++) {
+ CPUData* cpuData = &(this->cpus[i]);
+ cpuData->frequency = -1;
+ }
+
+ int numCPUsWithFrequency = 0;
+ double totalFrequency = 0;
+
+ if (settings->showCPUFrequency) {
+ FILE* file = fopen(PROCCPUINFOFILE, "r");
+ if (file == NULL) {
+ CRT_fatalError("Cannot open " PROCCPUINFOFILE);
+ }
+
+ int cpuid = -1;
+ double frequency;
+ while (!feof(file)) {
+ char buffer[PROC_LINE_LENGTH];
+ char *ok = fgets(buffer, PROC_LINE_LENGTH, file);
+ if (!ok) break;
+
+ if (
+ (sscanf(buffer, "processor : %d", &cpuid) == 1) ||
+ (sscanf(buffer, "processor: %d", &cpuid) == 1)
+ ) {
+ if (cpuid < 0 || cpuid > (cpus - 1)) {
+ char buffer[64];
+ xSnprintf(buffer, sizeof(buffer), PROCCPUINFOFILE " contains out-of-range CPU number %d", cpuid);
+ CRT_fatalError(buffer);
+ }
+ } else if (
+ (sscanf(buffer, "cpu MHz : %lf", &frequency) == 1) ||
+ (sscanf(buffer, "cpu MHz: %lf", &frequency) == 1)
+ ) {
+ if (cpuid < 0) {
+ CRT_fatalError(PROCCPUINFOFILE " is malformed: cpu MHz line without corresponding processor line");
+ }
+
+ int cpu = cpuid + 1;
+ CPUData* cpuData = &(this->cpus[cpu]);
+ cpuData->frequency = frequency;
+ numCPUsWithFrequency++;
+ totalFrequency += frequency;
+ } else if (buffer[0] == '\n') {
+ cpuid = -1;
+ }
+ }
+ fclose(file);
+
+ if (numCPUsWithFrequency > 0) {
+ this->cpus[0].frequency = totalFrequency / numCPUsWithFrequency;
+ }
+ }
+
+ double period = (double)this->cpus[0].totalPeriod / cpus;
+ return period;
+}
+
void ProcessList_goThroughEntries(ProcessList* super) {
LinuxProcessList* this = (LinuxProcessList*) super;
LinuxProcessList_scanMemoryInfo(super);
double period = LinuxProcessList_scanCPUTime(this);
+ LinuxProcessList_scanCPUFrequency(this);
+
struct timeval tv;
gettimeofday(&tv, NULL);
LinuxProcessList_recurseProcTree(this, PROCDIR, NULL, period, tv);
diff --git a/linux/LinuxProcessList.h b/linux/LinuxProcessList.h
index 4e0acc80..24b94d87 100644
--- a/linux/LinuxProcessList.h
+++ b/linux/LinuxProcessList.h
@@ -47,6 +47,8 @@ typedef struct CPUData_ {
unsigned long long int softIrqPeriod;
unsigned long long int stealPeriod;
unsigned long long int guestPeriod;
+
+ double frequency;
} CPUData;
typedef struct TtyDriver_ {
@@ -73,6 +75,10 @@ typedef struct LinuxProcessList_ {
#define PROCDIR "/proc"
#endif
+#ifndef PROCCPUINFOFILE
+#define PROCCPUINFOFILE PROCDIR "/cpuinfo"
+#endif
+
#ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat"
#endif
diff --git a/linux/Platform.c b/linux/Platform.c
index 130403f2..afdd3f02 100644
--- a/linux/Platform.c
+++ b/linux/Platform.c
@@ -198,6 +198,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
}
percent = CLAMP(percent, 0.0, 100.0);
if (isnan(percent)) percent = 0.0;
+
+ v[CPU_METER_FREQUENCY] = cpuData->frequency;
+
return percent;
}
diff --git a/linux/Platform.h b/linux/Platform.h
index 14eafbfc..bb2c4b09 100644
--- a/linux/Platform.h
+++ b/linux/Platform.h
@@ -47,6 +47,4 @@ extern char* Platform_getProcessEnv(pid_t pid);
extern void Platform_getPressureStall(const char *file, bool some, double* ten, double* sixty, double* threehundred);
-void Platform_getPressureStall(const char *file, bool some, double* ten, double* sixty, double* threehundred);
-
#endif
diff --git a/openbsd/Platform.c b/openbsd/Platform.c
index 343f4e79..0f5279e8 100644
--- a/openbsd/Platform.c
+++ b/openbsd/Platform.c
@@ -170,6 +170,7 @@ double Platform_setCPUValues(Meter* this, int cpu) {
v[CPU_METER_STEAL] = 0.0;
v[CPU_METER_GUEST] = 0.0;
v[CPU_METER_IOWAIT] = 0.0;
+ v[CPU_METER_FREQUENCY] = -1;
Meter_setItems(this, 8);
totalPercent = v[0]+v[1]+v[2]+v[3];
} else {
diff --git a/solaris/Platform.c b/solaris/Platform.c
index 396b502c..1322598e 100644
--- a/solaris/Platform.c
+++ b/solaris/Platform.c
@@ -203,6 +203,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
percent = CLAMP(percent, 0.0, 100.0);
if (isnan(percent)) percent = 0.0;
+
+ v[CPU_METER_FREQUENCY] = -1;
+
return percent;
}
diff --git a/unsupported/Platform.c b/unsupported/Platform.c
index e4c0e8ce..0e46a348 100644
--- a/unsupported/Platform.c
+++ b/unsupported/Platform.c
@@ -108,8 +108,11 @@ int Platform_getMaxPid() {
}
double Platform_setCPUValues(Meter* this, int cpu) {
- (void) this;
(void) cpu;
+
+ double* v = this->values;
+ v[CPU_METER_FREQUENCY] = -1;
+
return 0.0;
}

© 2014-2024 Faster IT GmbH | imprint | privacy policy