mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
CPU (Linux): detect core count for different core types
This commit is contained in:
@@ -17,6 +17,8 @@ typedef struct FFCPUResult
|
||||
double frequencyMax; // GHz
|
||||
double frequencyMin; // GHz
|
||||
|
||||
uint8_t coreCounts[8]; // number of P cores, E cores, etc.
|
||||
|
||||
double temperature;
|
||||
} FFCPUResult;
|
||||
|
||||
|
||||
@@ -88,14 +88,14 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static double getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, const char* scalingFileName, FFstrbuf* buffer)
|
||||
static uint32_t getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, const char* scalingFileName, FFstrbuf* buffer)
|
||||
{
|
||||
uint32_t baseLen = basePath->length;
|
||||
ffStrbufAppendS(basePath, cpuinfoFileName);
|
||||
bool ok = ffReadFileBuffer(basePath->chars, buffer);
|
||||
ffStrbufSubstrBefore(basePath, baseLen);
|
||||
if (ok)
|
||||
return ffStrbufToDouble(buffer) / 1e6;
|
||||
return (uint32_t) ffStrbufToUInt(buffer, 0);
|
||||
|
||||
if (scalingFileName)
|
||||
{
|
||||
@@ -103,10 +103,28 @@ static double getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, cons
|
||||
ok = ffReadFileBuffer(basePath->chars, buffer);
|
||||
ffStrbufSubstrBefore(basePath, baseLen);
|
||||
if (ok)
|
||||
return ffStrbufToDouble(buffer) / 1e6;
|
||||
return (uint32_t) ffStrbufToUInt(buffer, 0);
|
||||
}
|
||||
|
||||
return 0.0/0.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t getNumCores(FFstrbuf* basePath, FFstrbuf* buffer)
|
||||
{
|
||||
uint32_t baseLen = basePath->length;
|
||||
ffStrbufAppendS(basePath, "/affected_cpus");
|
||||
bool ok = ffReadFileBuffer(basePath->chars, buffer);
|
||||
ffStrbufSubstrBefore(basePath, baseLen);
|
||||
if (ok)
|
||||
return (uint8_t) ffStrbufCountC(buffer, ' ') + 1;
|
||||
|
||||
ffStrbufAppendS(basePath, "/related_cpus");
|
||||
ok = ffReadFileBuffer(basePath->chars, buffer);
|
||||
ffStrbufSubstrBefore(basePath, baseLen);
|
||||
if (ok)
|
||||
return (uint8_t) ffStrbufCountC(buffer, ' ') + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool detectFrequency(FFCPUResult* cpu)
|
||||
@@ -118,30 +136,41 @@ static bool detectFrequency(FFCPUResult* cpu)
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
uint32_t baseLen = path.length;
|
||||
|
||||
uint64_t freq = (uint64_t) -1;
|
||||
uint32_t ifreq = (uint32_t) -1;
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if (ffStrStartsWith(entry->d_name, "policy") && isdigit(entry->d_name[strlen("policy")]))
|
||||
{
|
||||
ffStrbufAppendS(&path, entry->d_name);
|
||||
double fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
|
||||
if (fbase == fbase)
|
||||
uint32_t fbase = getFrequency(&path, "/base_frequency", NULL, &buffer);
|
||||
if (fbase > 0)
|
||||
{
|
||||
if (cpu->frequencyBase == cpu->frequencyBase)
|
||||
cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase;
|
||||
else
|
||||
cpu->frequencyBase = fbase;
|
||||
}
|
||||
double fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
|
||||
if (fmax == fmax)
|
||||
uint32_t fmax = getFrequency(&path, "/cpuinfo_max_freq", "/scaling_max_freq", &buffer);
|
||||
if (fmax > 0)
|
||||
{
|
||||
if (cpu->frequencyMax == cpu->frequencyMax)
|
||||
cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax;
|
||||
else
|
||||
cpu->frequencyMax = fmax;
|
||||
|
||||
if (fmax != freq)
|
||||
{
|
||||
freq = fmax;
|
||||
++ifreq;
|
||||
}
|
||||
if (__builtin_expect(ifreq < sizeof(cpu->coreCounts), true))
|
||||
cpu->coreCounts[ifreq] += getNumCores(&path, &buffer);
|
||||
}
|
||||
double fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
|
||||
if (fmin == fmin)
|
||||
uint32_t fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
|
||||
if (fmin > 0)
|
||||
{
|
||||
if (cpu->frequencyMin == cpu->frequencyMin)
|
||||
cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin;
|
||||
@@ -151,6 +180,9 @@ static bool detectFrequency(FFCPUResult* cpu)
|
||||
ffStrbufSubstrBefore(&path, baseLen);
|
||||
}
|
||||
}
|
||||
cpu->frequencyBase /= 1e6;
|
||||
cpu->frequencyMax /= 1e6;
|
||||
cpu->frequencyMin /= 1e6;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+20
-12
@@ -10,12 +10,14 @@
|
||||
|
||||
void ffPrintCPU(FFCPUOptions* options)
|
||||
{
|
||||
FFCPUResult cpu;
|
||||
cpu.temperature = FF_CPU_TEMP_UNSET;
|
||||
cpu.coresPhysical = cpu.coresLogical = cpu.coresOnline = 0;
|
||||
cpu.frequencyMin = cpu.frequencyMax = cpu.frequencyBase = 0.0/0.0;
|
||||
ffStrbufInit(&cpu.name);
|
||||
ffStrbufInit(&cpu.vendor);
|
||||
FFCPUResult cpu = {
|
||||
.temperature = FF_CPU_TEMP_UNSET,
|
||||
.frequencyMin = 0.0/0.0,
|
||||
.frequencyMax = 0.0/0.0,
|
||||
.frequencyBase = 0.0/0.0,
|
||||
.name = ffStrbufCreate(),
|
||||
.vendor = ffStrbufCreate()
|
||||
};
|
||||
|
||||
const char* error = ffDetectCPU(options, &cpu);
|
||||
|
||||
@@ -143,12 +145,14 @@ void ffGenerateCPUJsonConfig(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
|
||||
void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
FFCPUResult cpu;
|
||||
cpu.temperature = FF_CPU_TEMP_UNSET;
|
||||
cpu.coresPhysical = cpu.coresLogical = cpu.coresOnline = 0;
|
||||
cpu.frequencyMin = cpu.frequencyMax = cpu.frequencyBase = 0.0/0.0;
|
||||
ffStrbufInit(&cpu.name);
|
||||
ffStrbufInit(&cpu.vendor);
|
||||
FFCPUResult cpu = {
|
||||
.temperature = FF_CPU_TEMP_UNSET,
|
||||
.frequencyMin = 0.0/0.0,
|
||||
.frequencyMax = 0.0/0.0,
|
||||
.frequencyBase = 0.0/0.0,
|
||||
.name = ffStrbufCreate(),
|
||||
.vendor = ffStrbufCreate()
|
||||
};
|
||||
|
||||
const char* error = ffDetectCPU(options, &cpu);
|
||||
|
||||
@@ -176,6 +180,10 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_
|
||||
yyjson_mut_obj_add_real(doc, frequency, "max", cpu.frequencyMax);
|
||||
yyjson_mut_obj_add_real(doc, frequency, "min", cpu.frequencyMin);
|
||||
|
||||
yyjson_mut_val* coreCounts = yyjson_mut_obj_add_arr(doc, obj, "coreCounts");
|
||||
for (uint32_t i = 0; i < sizeof (cpu.coreCounts) && cpu.coreCounts[i] > 0; i++)
|
||||
yyjson_mut_arr_add_uint(doc, coreCounts, cpu.coreCounts[i]);
|
||||
|
||||
yyjson_mut_obj_add_real(doc, obj, "temperature", cpu.temperature);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user