Skip to content

Commit 979f7d1

Browse files
committed
CPU (Linux): fix max / min frequency detection for multi policy systems
1 parent f238138 commit 979f7d1

File tree

1 file changed

+48
-28
lines changed

1 file changed

+48
-28
lines changed

src/detection/cpu/cpu_linux.c

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,30 +85,58 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer,
8585
return NULL;
8686
}
8787

88-
static double getGHz(const char* file)
88+
static double getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, const char* scalingFileName, FFstrbuf* buffer)
8989
{
90-
FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate();
91-
if(ffAppendFileBuffer(file, &content))
92-
{
93-
double herz = ffStrbufToDouble(&content);
94-
95-
//ffStrbufToDouble failed
96-
if(herz != herz)
97-
return 0;
98-
99-
herz /= 1000.0; //to MHz
100-
return herz / 1000.0; //to GHz
101-
}
102-
return 0;
90+
uint32_t baseLen = basePath->length;
91+
ffStrbufAppendS(basePath, cpuinfoFileName);
92+
bool ok = ffReadFileBuffer(basePath->chars, buffer);
93+
ffStrbufSubstrBefore(basePath, baseLen);
94+
if (ok)
95+
return ffStrbufToDouble(buffer) / 1e6;
96+
97+
ffStrbufAppendS(basePath, scalingFileName);
98+
ok = ffReadFileBuffer(basePath->chars, buffer);
99+
ffStrbufSubstrBefore(basePath, baseLen);
100+
if (ok)
101+
return ffStrbufToDouble(buffer) / 1e6;
102+
103+
return 0.0/0.0;
103104
}
104105

105-
static double getFrequency(const char* info, const char* scaling)
106+
static bool detectFrequency(FFCPUResult* cpu)
106107
{
107-
double frequency = getGHz(info);
108-
if(frequency > 0.0)
109-
return frequency;
108+
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/devices/system/cpu/cpufreq/");
109+
FF_AUTO_CLOSE_DIR DIR* dir = opendir(path.chars);
110+
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
111+
uint32_t baseLen = path.length;
112+
bool flag = false;
113+
114+
struct dirent* entry;
115+
while((entry = readdir(dir)) != NULL)
116+
{
117+
if (ffStrStartsWith(entry->d_name, "policy") && isdigit(entry->d_name[strlen("policy")]))
118+
{
119+
ffStrbufAppendS(&path, entry->d_name);
120+
double fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
121+
if (fmin != fmin) continue;
122+
double fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
123+
if (fmax != fmax) continue;
110124

111-
return getGHz(scaling);
125+
if (flag)
126+
{
127+
cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin;
128+
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
129+
}
130+
else
131+
{
132+
cpu->frequencyMin = fmin;
133+
cpu->frequencyMax = fmax;
134+
flag = true;
135+
}
136+
ffStrbufSubstrBefore(&path, baseLen);
137+
}
138+
}
139+
return flag;
112140
}
113141

114142
static double detectCPUTemp(void)
@@ -204,16 +232,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
204232
cpu->coresOnline = (uint16_t) get_nprocs();
205233
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical);
206234

207-
#define BP "/sys/devices/system/cpu/cpufreq/policy0/"
208-
if(ffPathExists(BP, FF_PATHTYPE_DIRECTORY))
209-
{
210-
cpu->frequencyMin = getFrequency(BP"cpuinfo_min_freq", BP"scaling_min_freq");
211-
cpu->frequencyMax = getFrequency(BP"cpuinfo_max_freq", BP"scaling_max_freq");
212-
}
213-
else
214-
{
235+
if (!detectFrequency(cpu))
215236
cpu->frequencyMin = cpu->frequencyMax = ffStrbufToDouble(&cpuMHz) / 1000;
216-
}
217237

218238
if(cpuUarch.length > 0)
219239
{

0 commit comments

Comments
 (0)