diff --git a/src/detection/cpu/cpu.h b/src/detection/cpu/cpu.h index e53772f74..628698e4b 100644 --- a/src/detection/cpu/cpu.h +++ b/src/detection/cpu/cpu.h @@ -15,6 +15,7 @@ typedef struct FFCPUResult double frequencyBase; // GHz double frequencyMax; // GHz + double frequencyMin; // GHz double temperature; } FFCPUResult; diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index ce95795f8..de3b18707 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -53,15 +53,13 @@ static const char* detectFrequency(FFCPUResult* cpu) if (ffCfDictGetData(properties, CFSTR("voltage-states1-sram"), 0, 4, (uint8_t*) &eMin, NULL) != NULL) // eCore return "\"voltage-states1-sram\" in \"pmgr\" is not found"; - cpu->frequencyBase = (pMin < eMin ? pMin : eMin) / (1000.0 * 1000 * 1000); + cpu->frequencyMin = (pMin < eMin ? pMin : eMin) / (1000.0 * 1000 * 1000); if (pCoreLength >= 8) { ffCfDictGetData(properties, CFSTR("voltage-states5-sram"), pCoreLength - 8, 4, (uint8_t*) &aMax, NULL); cpu->frequencyMax = aMax / (1000.0 * 1000 * 1000); } - else - cpu->frequencyMax = 0.0; return NULL; } @@ -69,6 +67,7 @@ static const char* detectFrequency(FFCPUResult* cpu) static const char* detectFrequency(FFCPUResult* cpu) { cpu->frequencyBase = ffSysctlGetInt64("hw.cpufrequency", 0) / 1000.0 / 1000.0 / 1000.0; + cpu->frequencyMin = ffSysctlGetInt64("hw.cpufrequency_min", 0) / 1000.0 / 1000.0 / 1000.0; cpu->frequencyMax = ffSysctlGetInt64("hw.cpufrequency_max", 0); if(cpu->frequencyMax > 0.0) cpu->frequencyMax /= 1000.0 * 1000.0 * 1000.0; diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 225e09fbe..e1d647cd3 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -12,7 +12,6 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) cpu->coresOnline = cpu->coresPhysical; cpu->frequencyBase = ffSysctlGetInt("hw.clockrate", 0) / 1000.0; - cpu->frequencyMax = cpu->frequencyBase; cpu->temperature = FF_CPU_TEMP_UNSET; if (options->temp) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index dfc4984b0..6a3619c23 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -26,7 +26,7 @@ static void detectAndroid(FFCPUResult* cpu) } #endif -static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch) +static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch) { FF_AUTO_CLOSE_FILE FILE* cpuinfo = fopen("/proc/cpuinfo", "r"); if(cpuinfo == NULL) @@ -49,7 +49,6 @@ static const char* parseCpuInfo(FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, ffParsePropLine(line, "model name :", &cpu->name) || ffParsePropLine(line, "vendor_id :", &cpu->vendor) || ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) || - ffParsePropLine(line, "cpu MHz :", cpuMHz) || ffParsePropLine(line, "isa :", cpuIsa) || ffParsePropLine(line, "uarch :", cpuUarch) || @@ -102,7 +101,7 @@ static double getFrequency(FFstrbuf* basePath, const char* cpuinfoFileName, cons if (ok) return ffStrbufToDouble(buffer) / 1e6; } - + return 0.0/0.0; } @@ -123,10 +122,28 @@ static bool detectFrequency(FFCPUResult* cpu) ffStrbufAppendS(&path, entry->d_name); double fbase = getFrequency(&path, "/base_frequency", NULL, &buffer); if (fbase == fbase) - cpu->frequencyBase = cpu->frequencyBase > fbase ? cpu->frequencyBase : fbase; + { + 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) - cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax; + { + if (cpu->frequencyMax == cpu->frequencyMax) + cpu->frequencyMax = cpu->frequencyMax > fmax ? cpu->frequencyMax : fmax; + else + cpu->frequencyMax = fmax; + } + double fmin = getFrequency(&path, "/cpuinfo_min_freq", "/scaling_min_freq", &buffer); + if (fmin == fmin) + { + if (cpu->frequencyMin == cpu->frequencyMin) + cpu->frequencyMin = cpu->frequencyMin < fmin ? cpu->frequencyMin : fmin; + else + cpu->frequencyMin = fmin; + } ffStrbufSubstrBefore(&path, baseLen); } } @@ -215,19 +232,18 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) cpu->temperature = options->temp ? detectCPUTemp() : FF_CPU_TEMP_UNSET; FF_STRBUF_AUTO_DESTROY physicalCoresBuffer = ffStrbufCreate(); - FF_STRBUF_AUTO_DESTROY cpuMHz = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY cpuIsa = ffStrbufCreate(); FF_STRBUF_AUTO_DESTROY cpuUarch = ffStrbufCreate(); - const char* error = parseCpuInfo(cpu, &physicalCoresBuffer, &cpuMHz, &cpuIsa, &cpuUarch); + const char* error = parseCpuInfo(cpu, &physicalCoresBuffer, &cpuIsa, &cpuUarch); if (error) return error; cpu->coresLogical = (uint16_t) get_nprocs_conf(); cpu->coresOnline = (uint16_t) get_nprocs(); cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical); - if (!detectFrequency(cpu)) - cpu->frequencyBase = cpu->frequencyMax = ffStrbufToDouble(&cpuMHz) / 1000; + detectFrequency(cpu); + // cpu MHz is current frequency, not max or base if(cpuUarch.length > 0) { diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index faa9bda22..855ae7d29 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -64,14 +64,13 @@ static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu) return "No active CPU is found in SMBIOS data"; } - double speed; if (data->MaxSpeed > 0 && data->MaxSpeed < 30000) // VMware reports weird values - speed = data->MaxSpeed / 1000.0; - else - speed = data->CurrentSpeed / 1000.0; + { + double speed = data->MaxSpeed / 1000.0; + if (cpu->frequencyBase < speed) + cpu->frequencyMax = speed; + } - if (cpu->frequencyMax < speed) - cpu->frequencyMax = speed; return NULL; } @@ -119,7 +118,7 @@ static const char* detectByRegistry(FFCPUResult* cpu) { uint32_t mhz; if(ffRegReadUint(hKey, L"~MHz", &mhz, NULL)) - cpu->frequencyBase = cpu->frequencyMax = mhz / 1000.0; + cpu->frequencyBase = mhz / 1000.0; } ffRegReadStrbuf(hKey, L"ProcessorNameString", &cpu->name, NULL); diff --git a/src/modules/cpu/cpu.c b/src/modules/cpu/cpu.c index c9e23c477..5da296f30 100644 --- a/src/modules/cpu/cpu.c +++ b/src/modules/cpu/cpu.c @@ -13,7 +13,7 @@ void ffPrintCPU(FFCPUOptions* options) FFCPUResult cpu; cpu.temperature = FF_CPU_TEMP_UNSET; cpu.coresPhysical = cpu.coresLogical = cpu.coresOnline = 0; - cpu.frequencyMax = cpu.frequencyBase = 0; + cpu.frequencyMin = cpu.frequencyMax = cpu.frequencyBase = 0.0/0.0; ffStrbufInit(&cpu.name); ffStrbufInit(&cpu.vendor); @@ -48,8 +48,11 @@ void ffPrintCPU(FFCPUOptions* options) if(cpu.coresOnline > 1) ffStrbufAppendF(&str, " (%u)", cpu.coresOnline); - if(cpu.frequencyMax > 0.0) - ffStrbufAppendF(&str, " @ %.*f GHz", options->freqNdigits, cpu.frequencyMax); + double freq = cpu.frequencyMax; + if(freq != freq) + freq = cpu.frequencyBase; + if(freq == freq) + ffStrbufAppendF(&str, " @ %.*f GHz", options->freqNdigits, freq); if(cpu.temperature == cpu.temperature) //FF_CPU_TEMP_UNSET { @@ -143,7 +146,7 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_ FFCPUResult cpu; cpu.temperature = FF_CPU_TEMP_UNSET; cpu.coresPhysical = cpu.coresLogical = cpu.coresOnline = 0; - cpu.frequencyMax = cpu.frequencyBase = 0; + cpu.frequencyMin = cpu.frequencyMax = cpu.frequencyBase = 0.0/0.0; ffStrbufInit(&cpu.name); ffStrbufInit(&cpu.vendor); @@ -171,6 +174,7 @@ void ffGenerateCPUJsonResult(FFCPUOptions* options, yyjson_mut_doc* doc, yyjson_ yyjson_mut_val* frequency = yyjson_mut_obj_add_obj(doc, obj, "frequency"); yyjson_mut_obj_add_real(doc, frequency, "base", cpu.frequencyBase); yyjson_mut_obj_add_real(doc, frequency, "max", cpu.frequencyMax); + yyjson_mut_obj_add_real(doc, frequency, "min", cpu.frequencyMin); yyjson_mut_obj_add_real(doc, obj, "temperature", cpu.temperature); }