Read CPU count every cycle to avoid issues when HT/SMT mode changes

This commit is contained in:
Christian Göttsche 2020-09-22 20:04:41 +02:00 committed by cgzones
parent 601480003f
commit 25022c219d
1 changed files with 69 additions and 25 deletions

View File

@ -149,6 +149,43 @@ static void LinuxProcessList_initNetlinkSocket(LinuxProcessList* this) {
#endif #endif
static int LinuxProcessList_computeCPUcount(void) {
FILE* file = fopen(PROCSTATFILE, "r");
if (file == NULL)
CRT_fatalError("Cannot open " PROCSTATFILE);
int cpus = 0;
char buffer[PROC_LINE_LENGTH + 1];
while(fgets(buffer, sizeof(buffer), file)) {
if (String_startsWith(buffer, "cpu"))
cpus++;
}
fclose(file);
/* subtract raw cpu entry */
if (cpus > 0)
cpus--;
return cpus;
}
static void LinuxProcessList_updateCPUcount(LinuxProcessList* this) {
ProcessList* pl = &(this->super);
int cpus = LinuxProcessList_computeCPUcount();
if (cpus == 0 || cpus == pl->cpuCount)
return;
pl->cpuCount = cpus;
free(this->cpus);
this->cpus = xCalloc(cpus + 1, sizeof(CPUData));
for (int i = 0; i <= cpus; i++) {
this->cpus[i].totalTime = 1;
this->cpus[i].totalPeriod = 1;
}
}
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) { ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, uid_t userId) {
LinuxProcessList* this = xCalloc(1, sizeof(LinuxProcessList)); LinuxProcessList* this = xCalloc(1, sizeof(LinuxProcessList));
ProcessList* pl = &(this->super); ProcessList* pl = &(this->super);
@ -169,34 +206,38 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
this->haveSmapsRollup = false; this->haveSmapsRollup = false;
} }
// Update CPU count: // Read btime
file = fopen(PROCSTATFILE, "r"); {
if (file == NULL) { FILE* statfile = fopen(PROCSTATFILE, "r");
if (statfile == NULL)
CRT_fatalError("Cannot open " PROCSTATFILE); CRT_fatalError("Cannot open " PROCSTATFILE);
}
int cpus = 0; while(true) {
do {
char buffer[PROC_LINE_LENGTH + 1]; char buffer[PROC_LINE_LENGTH + 1];
if (fgets(buffer, PROC_LINE_LENGTH + 1, file) == NULL) { if (fgets(buffer, sizeof(buffer), statfile) == NULL) {
CRT_fatalError("No btime in " PROCSTATFILE); CRT_fatalError("No btime in " PROCSTATFILE);
} else if (String_startsWith(buffer, "cpu")) {
cpus++;
} else if (String_startsWith(buffer, "btime ")) { } else if (String_startsWith(buffer, "btime ")) {
if (sscanf(buffer, "btime %lld\n", &btime) != 1) if (sscanf(buffer, "btime %lld\n", &btime) != 1)
CRT_fatalError("Failed to parse btime from " PROCSTATFILE); CRT_fatalError("Failed to parse btime from " PROCSTATFILE);
break; break;
} }
} while(true); }
fclose(file); fclose(statfile);
}
pl->cpuCount = MAXIMUM(cpus - 1, 1); // Initialze CPU count
this->cpus = xCalloc(cpus, sizeof(CPUData)); {
int cpus = LinuxProcessList_computeCPUcount();
pl->cpuCount = MAXIMUM(cpus, 1);
this->cpus = xCalloc(cpus + 1, sizeof(CPUData));
for (int i = 0; i < cpus; i++) { for (int i = 0; i <= cpus; i++) {
this->cpus[i].totalTime = 1; this->cpus[i].totalTime = 1;
this->cpus[i].totalPeriod = 1; this->cpus[i].totalPeriod = 1;
} }
}
return pl; return pl;
} }
@ -1332,6 +1373,9 @@ void ProcessList_goThroughEntries(ProcessList* super) {
LinuxProcessList_scanMemoryInfo(super); LinuxProcessList_scanMemoryInfo(super);
LinuxProcessList_scanZfsArcstats(this); LinuxProcessList_scanZfsArcstats(this);
LinuxProcessList_updateCPUcount(this);
double period = LinuxProcessList_scanCPUTime(this); double period = LinuxProcessList_scanCPUTime(this);
if (settings->showCPUFrequency) if (settings->showCPUFrequency)