mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
CPU: print core count for different core types
This commit is contained in:
@@ -4,6 +4,12 @@
|
||||
|
||||
#define FF_CPU_TEMP_UNSET (0/0.0)
|
||||
|
||||
typedef struct FFCPUCore
|
||||
{
|
||||
uint32_t freq;
|
||||
uint32_t count;
|
||||
} FFCPUCore;
|
||||
|
||||
typedef struct FFCPUResult
|
||||
{
|
||||
FFstrbuf name;
|
||||
@@ -17,7 +23,7 @@ typedef struct FFCPUResult
|
||||
double frequencyMax; // GHz
|
||||
double frequencyMin; // GHz
|
||||
|
||||
uint8_t coreCounts[8]; // number of P cores, E cores, etc.
|
||||
FFCPUCore coreTypes[8]; // number of P cores, E cores, etc.
|
||||
|
||||
double temperature;
|
||||
} FFCPUResult;
|
||||
|
||||
@@ -85,13 +85,14 @@ static const char* detectCoreCount(FFCPUResult* cpu)
|
||||
int nPerfLevels = ffSysctlGetInt("hw.nperflevels", 0);
|
||||
if (nPerfLevels <= 0) return "sysctl(hw.nperflevels) failed";
|
||||
|
||||
if (nPerfLevels > (int) sizeof(cpu->coreCounts))
|
||||
nPerfLevels = (int) sizeof(cpu->coreCounts);
|
||||
char sysctlKey[] = "hw.perflevelN.logicalcpu";
|
||||
for (int i = 0; i < nPerfLevels; ++i)
|
||||
{
|
||||
sysctlKey[strlen("hw.perflevel")] = (char) ('0' + i);
|
||||
cpu->coreCounts[i] = (uint8_t) ffSysctlGetInt(sysctlKey, 0);
|
||||
cpu->coreTypes[i < (int) sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]) : i : (int) sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]) - 1] = {
|
||||
.freq = nPerfLevels - i,
|
||||
.count = ffSysctlGetInt(sysctlKey, 0),
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t freq = (uint64_t) -1;
|
||||
uint32_t ifreq = (uint32_t) -1;
|
||||
for (uint16_t i = 0; i < cpu->coresLogical; ++i)
|
||||
{
|
||||
@@ -57,13 +56,13 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
if (!(cpu->frequencyMin <= fmin)) cpu->frequencyMin = fmin; // Counting for NaN
|
||||
if (!(cpu->frequencyMax >= fmax)) cpu->frequencyMax = fmax;
|
||||
|
||||
if (freq != fmax)
|
||||
if (cpu->coreTypes[ifreq].freq != fmax)
|
||||
{
|
||||
freq = fmax;
|
||||
++ifreq;
|
||||
if (cpu->coreTypes[ifreq].count && ifreq < sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]))
|
||||
++ifreq;
|
||||
cpu->coreTypes[ifreq].freq = fmax;
|
||||
}
|
||||
if (__builtin_expect(ifreq < sizeof(cpu->coreCounts), true))
|
||||
cpu->coreCounts[ifreq]++;
|
||||
cpu->coreTypes[ifreq].count++;
|
||||
}
|
||||
}
|
||||
cpu->frequencyMin /= 1000;
|
||||
|
||||
@@ -136,11 +136,9 @@ 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;
|
||||
|
||||
uint32_t ifreq = 0;
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dir)) != NULL)
|
||||
while ((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
if (ffStrStartsWith(entry->d_name, "policy") && isdigit(entry->d_name[strlen("policy")]))
|
||||
{
|
||||
@@ -161,13 +159,13 @@ static bool detectFrequency(FFCPUResult* cpu)
|
||||
else
|
||||
cpu->frequencyMax = fmax;
|
||||
|
||||
if (fmax != freq)
|
||||
if (cpu->coreTypes[ifreq].freq != fmax)
|
||||
{
|
||||
freq = fmax;
|
||||
++ifreq;
|
||||
if (cpu->coreTypes[ifreq].count && ifreq < sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]))
|
||||
++ifreq;
|
||||
cpu->coreTypes[ifreq].freq = fmax;
|
||||
}
|
||||
if (__builtin_expect(ifreq < sizeof(cpu->coreCounts), true))
|
||||
cpu->coreCounts[ifreq] += getNumCores(&path, &buffer);
|
||||
cpu->coreTypes[ifreq].count += getNumCores(&path, &buffer);
|
||||
}
|
||||
uint32_t fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer);
|
||||
if (fmin > 0)
|
||||
|
||||
@@ -160,23 +160,22 @@ static const char* detectByRegistry(FFCPUResult* cpu)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* detectCoreCounts(FFCPUResult* cpu)
|
||||
static const char* detectCoreTypes(FFCPUResult* cpu)
|
||||
{
|
||||
FF_AUTO_FREE PROCESSOR_POWER_INFORMATION* pinfo = calloc(cpu->coresLogical, sizeof(PROCESSOR_POWER_INFORMATION));
|
||||
if (!NT_SUCCESS(NtPowerInformation(ProcessorInformation, NULL, 0, pinfo, (ULONG) sizeof(PROCESSOR_POWER_INFORMATION) * cpu->coresLogical)))
|
||||
return "NtPowerInformation(ProcessorInformation, NULL, 0, pinfo, size) failed";
|
||||
|
||||
uint64_t freq = (uint64_t) -1;
|
||||
uint32_t ifreq = (uint32_t) -1;
|
||||
for (uint32_t i = 0; i < cpu->coresLogical && pinfo[i].MhzLimit; ++i)
|
||||
uint32_t ifreq = 0;
|
||||
for (uint32_t i = 1; i < cpu->coresLogical && pinfo[i].MhzLimit; ++i)
|
||||
{
|
||||
if (freq != pinfo[i].MhzLimit)
|
||||
if (cpu->coreTypes[ifreq].freq != pinfo[i].MhzLimit)
|
||||
{
|
||||
freq = pinfo[i].MhzLimit;
|
||||
++ifreq;
|
||||
if (cpu->coreTypes[ifreq].count && ifreq < sizeof(cpu->coreTypes) / sizeof(cpu->coreTypes[0]))
|
||||
++ifreq;
|
||||
cpu->coreTypes[ifreq].freq = pinfo[i].MhzLimit;
|
||||
}
|
||||
if (__builtin_expect(ifreq < sizeof(cpu->coreCounts), true))
|
||||
cpu->coreCounts[ifreq]++;
|
||||
cpu->coreTypes[ifreq].count++;
|
||||
}
|
||||
|
||||
if (cpu->frequencyBase != cpu->frequencyBase)
|
||||
@@ -193,7 +192,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
|
||||
return error;
|
||||
|
||||
detectSpeedByCpuid(cpu);
|
||||
detectCoreCounts(cpu);
|
||||
detectCoreTypes(cpu);
|
||||
|
||||
if (cpu->frequencyMax != cpu->frequencyMax)
|
||||
detectMaxSpeedBySmbios(cpu);
|
||||
|
||||
+32
-8
@@ -6,7 +6,12 @@
|
||||
#include "modules/cpu/cpu.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#define FF_CPU_NUM_FORMAT_ARGS 8
|
||||
#define FF_CPU_NUM_FORMAT_ARGS 9
|
||||
|
||||
static int sortCores(const FFCPUCore* a, const FFCPUCore* b)
|
||||
{
|
||||
return (int)b->freq - (int)a->freq;
|
||||
}
|
||||
|
||||
void ffPrintCPU(FFCPUOptions* options)
|
||||
{
|
||||
@@ -51,9 +56,9 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
ffStrbufAppendF(&str, " (%u)", cpu.coresOnline);
|
||||
|
||||
double freq = cpu.frequencyMax;
|
||||
if(freq != freq)
|
||||
if(freq <= 0.0000001)
|
||||
freq = cpu.frequencyBase;
|
||||
if(freq == freq)
|
||||
if(freq > 0.0000001)
|
||||
ffStrbufAppendF(&str, " @ %.*f GHz", options->freqNdigits, freq);
|
||||
|
||||
if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET
|
||||
@@ -66,6 +71,19 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
}
|
||||
else
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY coreTypes = ffStrbufCreate();
|
||||
uint32_t typeCount = 0;
|
||||
while (cpu.coreTypes[typeCount].count != 0) typeCount++;
|
||||
if (typeCount > 0)
|
||||
{
|
||||
qsort(cpu.coreTypes, typeCount, sizeof(cpu.coreTypes[0]), (void*) sortCores);
|
||||
|
||||
for (uint32_t i = 0; i < typeCount; i++)
|
||||
ffStrbufAppendF(&coreTypes, "%s%u", i == 0 ? "" : " + ", cpu.coreTypes[i].count);
|
||||
}
|
||||
else
|
||||
ffStrbufAppendF(&coreTypes, "%u", cpu.coresOnline);
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
|
||||
ffTempsAppendNum(cpu.temperature, &tempStr, options->tempConfig, &options->moduleArgs);
|
||||
FF_PRINT_FORMAT_CHECKED(FF_CPU_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_CPU_NUM_FORMAT_ARGS, ((FFformatarg[]){
|
||||
@@ -76,7 +94,8 @@ void ffPrintCPU(FFCPUOptions* options)
|
||||
{FF_FORMAT_ARG_TYPE_UINT16, &cpu.coresOnline},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyBase},
|
||||
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpu.frequencyMax},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr}
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &tempStr},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &coreTypes},
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -180,9 +199,13 @@ 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_val* coreTypes = yyjson_mut_obj_add_arr(doc, obj, "coreTypes");
|
||||
for (uint32_t i = 0; i < sizeof (cpu.coreTypes) / sizeof (cpu.coreTypes[0]) && cpu.coreTypes[i].count > 0; i++)
|
||||
{
|
||||
yyjson_mut_val* core = yyjson_mut_arr_add_obj(doc, coreTypes);
|
||||
yyjson_mut_obj_add_uint(doc, core, "count", cpu.coreTypes[i].count);
|
||||
yyjson_mut_obj_add_uint(doc, core, "freq", cpu.coreTypes[i].freq);
|
||||
}
|
||||
|
||||
yyjson_mut_obj_add_real(doc, obj, "temperature", cpu.temperature);
|
||||
}
|
||||
@@ -201,7 +224,8 @@ void ffPrintCPUHelpFormat(void)
|
||||
"Online core count",
|
||||
"Base frequency",
|
||||
"Max frequency",
|
||||
"Temperature (formatted)"
|
||||
"Temperature (formatted)",
|
||||
"Logical core count grouped by frequency",
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user