diff options
author | Nathan Scott <nathans@redhat.com> | 2020-08-20 14:47:07 +1000 |
---|---|---|
committer | Nathan Scott <nathans@redhat.com> | 2020-08-20 14:47:07 +1000 |
commit | 6b443c5da9227221ed793616f156800ab4ee2717 (patch) | |
tree | a545f96ff0d3a7c022efec5eccf8a6ec796c9b03 /linux | |
parent | 011125dab2338acac9c4bbc7b04604f01f40e54b (diff) | |
parent | 81b64691a7ee55e5c665ac78290495b0aea946d7 (diff) |
Merge branch 'hishamhm-pull-932'
Diffstat (limited to 'linux')
-rw-r--r-- | linux/LinuxProcessList.c | 74 | ||||
-rw-r--r-- | linux/LinuxProcessList.h | 6 | ||||
-rw-r--r-- | linux/Platform.c | 3 | ||||
-rw-r--r-- | linux/Platform.h | 2 |
4 files changed, 83 insertions, 2 deletions
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 |