Merge branch 'hishamhm-pull-932'

This commit is contained in:
Nathan Scott 2020-08-20 14:47:07 +10:00
commit 6b443c5da9
15 changed files with 141 additions and 6 deletions

View File

@ -28,7 +28,8 @@ typedef enum {
CPU_METER_STEAL = 5, CPU_METER_STEAL = 5,
CPU_METER_GUEST = 6, CPU_METER_GUEST = 6,
CPU_METER_IOWAIT = 7, 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; } CPUMeterValues;
}*/ }*/
@ -63,7 +64,30 @@ static void CPUMeter_updateValues(Meter* this, char* buffer, int size) {
} }
memset(this->values, 0, sizeof(double) * CPU_METER_ITEMCOUNT); memset(this->values, 0, sizeof(double) * CPU_METER_ITEMCOUNT);
double percent = Platform_setCPUValues(this, cpu); 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) { static void CPUMeter_display(Object* cast, RichString* out) {

View File

@ -20,7 +20,8 @@ typedef enum {
CPU_METER_STEAL = 5, CPU_METER_STEAL = 5,
CPU_METER_GUEST = 6, CPU_METER_GUEST = 6,
CPU_METER_IOWAIT = 7, 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; } CPUMeterValues;

View File

@ -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("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("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("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))); Panel_add(super, (Object*) CheckItem_newByRef(xStrdup("Enable the mouse"), &(settings->enableMouse)));
return this; return this;
} }

View File

@ -45,6 +45,8 @@ typedef struct Settings_ {
bool countCPUsFromZero; bool countCPUsFromZero;
bool detailedCPUTime; bool detailedCPUTime;
bool showCPUUsage;
bool showCPUFrequency;
bool treeView; bool treeView;
bool showProgramPath; bool showProgramPath;
bool hideThreads; bool hideThreads;
@ -224,6 +226,10 @@ static bool Settings_read(Settings* this, const char* fileName) {
this->detailedCPUTime = atoi(option[1]); this->detailedCPUTime = atoi(option[1]);
} else if (String_eq(option[0], "cpu_count_from_zero")) { } else if (String_eq(option[0], "cpu_count_from_zero")) {
this->countCPUsFromZero = atoi(option[1]); 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")) { } else if (String_eq(option[0], "update_process_names")) {
this->updateProcessNames = atoi(option[1]); this->updateProcessNames = atoi(option[1]);
} else if (String_eq(option[0], "account_guest_in_cpu_meter")) { } 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, "header_margin=%d\n", (int) this->headerMargin);
fprintf(fd, "detailed_cpu_time=%d\n", (int) this->detailedCPUTime); fprintf(fd, "detailed_cpu_time=%d\n", (int) this->detailedCPUTime);
fprintf(fd, "cpu_count_from_zero=%d\n", (int) this->countCPUsFromZero); 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, "update_process_names=%d\n", (int) this->updateProcessNames);
fprintf(fd, "account_guest_in_cpu_meter=%d\n", (int) this->accountGuestInCPUMeter); fprintf(fd, "account_guest_in_cpu_meter=%d\n", (int) this->accountGuestInCPUMeter);
fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme); fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme);
@ -344,6 +352,8 @@ Settings* Settings_new(int cpuCount) {
this->highlightMegabytes = false; this->highlightMegabytes = false;
this->detailedCPUTime = false; this->detailedCPUTime = false;
this->countCPUsFromZero = false; this->countCPUsFromZero = false;
this->showCPUUsage = true;
this->showCPUFrequency = false;
this->updateProcessNames = false; this->updateProcessNames = false;
this->cpuCount = cpuCount; this->cpuCount = cpuCount;
this->showProgramPath = true; this->showProgramPath = true;

View File

@ -36,6 +36,8 @@ typedef struct Settings_ {
bool countCPUsFromZero; bool countCPUsFromZero;
bool detailedCPUTime; bool detailedCPUTime;
bool showCPUUsage;
bool showCPUFrequency;
bool treeView; bool treeView;
bool showProgramPath; bool showProgramPath;
bool hideThreads; bool hideThreads;

View File

@ -217,6 +217,8 @@ double Platform_setCPUValues(Meter* mtr, int cpu) {
/* Convert to percent and return */ /* Convert to percent and return */
total = mtr->values[CPU_METER_NICE] + mtr->values[CPU_METER_NORMAL] + mtr->values[CPU_METER_KERNEL]; 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); return CLAMP(total, 0.0, 100.0);
} }

View File

@ -179,6 +179,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
percent = CLAMP(percent, 0.0, 100.0); percent = CLAMP(percent, 0.0, 100.0);
if (isnan(percent)) percent = 0.0; if (isnan(percent)) percent = 0.0;
v[CPU_METER_FREQUENCY] = -1;
return percent; return percent;
} }

View File

@ -178,6 +178,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
percent = CLAMP(percent, 0.0, 100.0); percent = CLAMP(percent, 0.0, 100.0);
if (isnan(percent)) percent = 0.0; if (isnan(percent)) percent = 0.0;
v[CPU_METER_FREQUENCY] = -1;
return percent; return percent;
} }

View File

@ -74,6 +74,8 @@ typedef struct CPUData_ {
unsigned long long int softIrqPeriod; unsigned long long int softIrqPeriod;
unsigned long long int stealPeriod; unsigned long long int stealPeriod;
unsigned long long int guestPeriod; unsigned long long int guestPeriod;
double frequency;
} CPUData; } CPUData;
typedef struct TtyDriver_ { typedef struct TtyDriver_ {
@ -100,6 +102,10 @@ typedef struct LinuxProcessList_ {
#define PROCDIR "/proc" #define PROCDIR "/proc"
#endif #endif
#ifndef PROCCPUINFOFILE
#define PROCCPUINFOFILE PROCDIR "/cpuinfo"
#endif
#ifndef PROCSTATFILE #ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat" #define PROCSTATFILE PROCDIR "/stat"
#endif #endif
@ -1108,18 +1114,86 @@ static inline double LinuxProcessList_scanCPUTime(LinuxProcessList* this) {
cpuData->stealTime = steal; cpuData->stealTime = steal;
cpuData->guestTime = virtalltime; cpuData->guestTime = virtalltime;
cpuData->totalTime = totaltime; cpuData->totalTime = totaltime;
} }
double period = (double)this->cpus[0].totalPeriod / cpus; double period = (double)this->cpus[0].totalPeriod / cpus;
fclose(file); fclose(file);
return period; 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) { void ProcessList_goThroughEntries(ProcessList* super) {
LinuxProcessList* this = (LinuxProcessList*) super; LinuxProcessList* this = (LinuxProcessList*) super;
LinuxProcessList_scanMemoryInfo(super); LinuxProcessList_scanMemoryInfo(super);
double period = LinuxProcessList_scanCPUTime(this); double period = LinuxProcessList_scanCPUTime(this);
LinuxProcessList_scanCPUFrequency(this);
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
LinuxProcessList_recurseProcTree(this, PROCDIR, NULL, period, tv); LinuxProcessList_recurseProcTree(this, PROCDIR, NULL, period, tv);

View File

@ -47,6 +47,8 @@ typedef struct CPUData_ {
unsigned long long int softIrqPeriod; unsigned long long int softIrqPeriod;
unsigned long long int stealPeriod; unsigned long long int stealPeriod;
unsigned long long int guestPeriod; unsigned long long int guestPeriod;
double frequency;
} CPUData; } CPUData;
typedef struct TtyDriver_ { typedef struct TtyDriver_ {
@ -73,6 +75,10 @@ typedef struct LinuxProcessList_ {
#define PROCDIR "/proc" #define PROCDIR "/proc"
#endif #endif
#ifndef PROCCPUINFOFILE
#define PROCCPUINFOFILE PROCDIR "/cpuinfo"
#endif
#ifndef PROCSTATFILE #ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat" #define PROCSTATFILE PROCDIR "/stat"
#endif #endif

View File

@ -198,6 +198,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
} }
percent = CLAMP(percent, 0.0, 100.0); percent = CLAMP(percent, 0.0, 100.0);
if (isnan(percent)) percent = 0.0; if (isnan(percent)) percent = 0.0;
v[CPU_METER_FREQUENCY] = cpuData->frequency;
return percent; return percent;
} }

View File

@ -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); 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 #endif

View File

@ -170,6 +170,7 @@ double Platform_setCPUValues(Meter* this, int cpu) {
v[CPU_METER_STEAL] = 0.0; v[CPU_METER_STEAL] = 0.0;
v[CPU_METER_GUEST] = 0.0; v[CPU_METER_GUEST] = 0.0;
v[CPU_METER_IOWAIT] = 0.0; v[CPU_METER_IOWAIT] = 0.0;
v[CPU_METER_FREQUENCY] = -1;
Meter_setItems(this, 8); Meter_setItems(this, 8);
totalPercent = v[0]+v[1]+v[2]+v[3]; totalPercent = v[0]+v[1]+v[2]+v[3];
} else { } else {

View File

@ -203,6 +203,9 @@ double Platform_setCPUValues(Meter* this, int cpu) {
percent = CLAMP(percent, 0.0, 100.0); percent = CLAMP(percent, 0.0, 100.0);
if (isnan(percent)) percent = 0.0; if (isnan(percent)) percent = 0.0;
v[CPU_METER_FREQUENCY] = -1;
return percent; return percent;
} }

View File

@ -108,8 +108,11 @@ int Platform_getMaxPid() {
} }
double Platform_setCPUValues(Meter* this, int cpu) { double Platform_setCPUValues(Meter* this, int cpu) {
(void) this;
(void) cpu; (void) cpu;
double* v = this->values;
v[CPU_METER_FREQUENCY] = -1;
return 0.0; return 0.0;
} }