Files
fastfetch/src/modules/cpu.c
T

210 lines
6.6 KiB
C
Raw Normal View History

2021-02-18 22:25:36 +01:00
#include "fastfetch.h"
2021-04-09 14:07:05 +02:00
#include <string.h>
2022-06-15 16:14:46 +02:00
#include <errno.h>
2021-04-09 14:07:05 +02:00
2021-04-15 18:59:26 +02:00
#define FF_CPU_MODULE_NAME "CPU"
2022-06-15 16:14:46 +02:00
#define FF_CPU_NUM_FORMAT_ARGS 15
2021-06-16 11:47:32 +02:00
static double getGhz(const char* policyFile, const char* cpuFile)
2021-06-16 11:28:33 +02:00
{
FFstrbuf content;
ffStrbufInit(&content);
2021-06-16 11:47:32 +02:00
ffGetFileContent(policyFile, &content);
if(content.length == 0)
ffGetFileContent(cpuFile, &content);
2022-06-16 14:55:02 +02:00
double herz = ffStrbufToDouble(&content);
2021-06-16 11:28:33 +02:00
ffStrbufDestroy(&content);
2022-06-16 14:55:02 +02:00
//ffStrbufToDouble failed
if(herz != herz)
return 0;
2021-06-16 11:47:32 +02:00
herz /= 1000.0; //to MHz
return herz / 1000.0; //to GHz
2021-06-16 11:28:33 +02:00
}
static double detectCPUTemp(const FFinstance* instance)
{
const FFTempsResult *temps = ffDetectTemps(instance);
for(uint32_t i = 0; i < temps->values.length; i++)
{
FFTempValue* value = ffListGet(&temps->values, i);
if(
2022-06-17 23:38:33 +02:00
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
ffStrbufCompS(&value->name, "k10temp") == 0 ||
ffStrbufCompS(&value->name, "coretemp") == 0
) return value->value;
}
return 0.0 / 0.0; //NaN
}
2021-02-27 18:30:05 +01:00
void ffPrintCPU(FFinstance* instance)
2021-02-18 22:25:36 +01:00
{
2022-06-17 18:15:36 +02:00
if(ffPrintFromCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpu, FF_CPU_NUM_FORMAT_ARGS))
2021-02-22 16:52:51 +01:00
return;
2022-05-23 20:01:18 +02:00
FILE* cpuinfo = fopen("/proc/cpuinfo", "r");
2021-04-03 21:51:50 +02:00
if(cpuinfo == NULL)
{
2022-06-17 18:15:36 +02:00
ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, "fopen(\"""/proc/cpuinfo\", \"r\") == NULL");
2021-04-03 21:51:50 +02:00
return;
}
2021-06-16 11:28:33 +02:00
FFstrbuf name;
2021-11-17 10:59:31 +01:00
ffStrbufInitA(&name, 64);
2021-06-16 11:28:33 +02:00
FFstrbuf vendor;
2021-11-17 10:59:31 +01:00
ffStrbufInitA(&vendor, 64);
2021-06-16 11:28:33 +02:00
FFstrbuf physicalCoresString;
ffStrbufInit(&physicalCoresString);
FFstrbuf procGhzString;
ffStrbufInit(&procGhzString);
2021-03-27 18:14:19 +01:00
2021-03-28 13:02:40 +02:00
char* line = NULL;
size_t len = 0;
while(getline(&line, &len, cpuinfo) != -1)
2021-02-19 16:23:41 +01:00
{
2021-03-28 13:02:40 +02:00
//Stop after the first CPU
2021-10-20 06:04:55 +00:00
if(name.length > 0 && (*line == '\0' || *line == '\n'))
2021-03-28 13:02:40 +02:00
break;
2021-10-20 06:04:55 +00:00
(void)(
2022-04-08 15:50:49 +02:00
ffParsePropLine(line, "model name :", &name) ||
ffParsePropLine(line, "vendor_id :", &vendor) ||
ffParsePropLine(line, "cpu cores :", &physicalCoresString) ||
ffParsePropLine(line, "cpu MHz :", &procGhzString) ||
(name.length == 0 && ffParsePropLine(line, "Hardware :", &name)) //For Android devices
2021-10-20 06:04:55 +00:00
);
2021-02-19 16:23:41 +01:00
}
2021-02-18 22:25:36 +01:00
2021-03-28 13:02:40 +02:00
if(line != NULL)
free(line);
fclose(cpuinfo);
2022-06-16 14:55:02 +02:00
double procGhz = ffStrbufToDouble(&procGhzString);
if(procGhz != procGhz)
procGhz = 0; //NaN
else
procGhz /= 1000.0; //To GHz
2021-06-16 11:28:33 +02:00
ffStrbufDestroy(&procGhzString);
2021-06-16 11:47:32 +02:00
double biosLimit = getGhz("/sys/devices/system/cpu/cpufreq/policy0/bios_limit", "/sys/devices/system/cpu/cpu0/cpufreq/bios_limit");
double scalingMaxFreq = getGhz("/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq");
double scalingMinFreq = getGhz("/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq", "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq");
double infoMaxFreq = getGhz("/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq");
double infoMinFreq = getGhz("/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq", "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq");
2021-02-18 22:25:36 +01:00
2021-03-28 13:02:40 +02:00
int numProcsOnline = get_nprocs();
int numProcsAvailable = get_nprocs_conf();
2021-03-19 20:57:07 +01:00
2021-06-16 11:28:33 +02:00
int physicalCores = 1;
sscanf(physicalCoresString.chars, "%i", &physicalCores);
ffStrbufDestroy(&physicalCoresString);
2021-04-03 21:51:50 +02:00
//The current get_nprocs* returns 1 on failure. It also makes no sense to have a (1) as count
int numProcs = numProcsOnline;
if(numProcs <= 1)
numProcs = numProcsAvailable;
if(numProcs <= 1)
numProcs = physicalCores;
double ghz = biosLimit;
if(ghz == 0)
ghz = scalingMaxFreq;
if(ghz == 0)
ghz = infoMaxFreq;
2021-06-16 11:28:33 +02:00
if(ghz == 0)
ghz = procGhz;
2021-04-03 21:51:50 +02:00
if(ghz == 0)
ghz = scalingMinFreq;
if(ghz == 0)
ghz = infoMinFreq;
if(
2021-06-16 11:28:33 +02:00
name.length == 0 &&
vendor.length == 0 &&
2021-04-03 21:51:50 +02:00
numProcs <= 1 &&
ghz <= 0
) {
2021-06-16 11:28:33 +02:00
ffStrbufDestroy(&name);
ffStrbufDestroy(&vendor);
2022-06-17 18:15:36 +02:00
ffPrintError(instance, FF_CPU_MODULE_NAME, 0, &instance->config.cpu, "No CPU info found in /proc/cpuinfo");
2021-04-03 21:51:50 +02:00
return;
}
FFstrbuf namePretty;
ffStrbufInitA(&namePretty, 64);
2021-06-16 11:28:33 +02:00
ffStrbufAppend(&namePretty, &name);
2021-04-17 14:37:32 +02:00
const char* removeStrings[] = {
"(R)", "(r)", "(TM)", "(tm)",
2021-05-02 21:45:47 +02:00
" CPU", " FPU", " APU", " Processor",
2021-04-17 14:37:32 +02:00
" Dual-Core", " Quad-Core", " Six-Core", " Eight-Core", " Ten-Core",
" 2-Core", " 4-Core", " 6-Core", " 8-Core", " 10-Core", " 12-Core", " 14-Core", " 16-Core"
};
ffStrbufRemoveStringsA(&namePretty, sizeof(removeStrings) / sizeof(removeStrings[0]), removeStrings);
2021-04-03 21:51:50 +02:00
ffStrbufSubstrBeforeFirstC(&namePretty, '@'); //Cut the speed output in the name as we append our own
ffStrbufTrimRight(&namePretty, ' '); //If we removed the @ in previous step there was most likely a space before it
double cpuTemp;
if(instance->config.cpu.outputFormat.length > 0)
cpuTemp = detectCPUTemp(instance);
2022-06-16 13:36:00 +02:00
2021-04-03 12:14:25 +02:00
FFstrbuf cpu;
ffStrbufInitA(&cpu, 128);
2021-03-19 20:57:07 +01:00
2021-04-15 18:59:26 +02:00
if(namePretty.length > 0)
ffStrbufAppend(&cpu, &namePretty);
2021-06-16 11:28:33 +02:00
else if(name.length > 0)
ffStrbufAppend(&cpu, &name);
else if(vendor.length > 0)
2021-03-19 20:57:07 +01:00
{
2021-06-16 11:28:33 +02:00
ffStrbufAppend(&cpu, &vendor);
2022-01-09 16:51:57 +01:00
ffStrbufAppendS(&cpu, " CPU");
2021-03-19 20:57:07 +01:00
}
else
2022-01-09 16:51:57 +01:00
ffStrbufAppendS(&cpu, "CPU");
2021-04-15 18:59:26 +02:00
if(numProcs > 1)
ffStrbufAppendF(&cpu, " (%i)", numProcs);
if(ghz > 0)
ffStrbufAppendF(&cpu, " @ %.9gGHz", ghz);
2022-06-17 18:15:36 +02:00
ffPrintAndWriteToCache(instance, FF_CPU_MODULE_NAME, &instance->config.cpu, &cpu, FF_CPU_NUM_FORMAT_ARGS, (FFformatarg[]){
2021-06-16 11:28:33 +02:00
{FF_FORMAT_ARG_TYPE_STRBUF, &name},
2021-04-15 18:59:26 +02:00
{FF_FORMAT_ARG_TYPE_STRBUF, &namePretty},
2021-06-16 11:28:33 +02:00
{FF_FORMAT_ARG_TYPE_STRBUF, &vendor},
2021-04-15 18:59:26 +02:00
{FF_FORMAT_ARG_TYPE_INT, &numProcsOnline},
{FF_FORMAT_ARG_TYPE_INT, &numProcsAvailable},
{FF_FORMAT_ARG_TYPE_INT, &physicalCores},
{FF_FORMAT_ARG_TYPE_INT, &numProcs},
2022-06-16 13:13:36 +02:00
{FF_FORMAT_ARG_TYPE_DOUBLE, &cpuTemp},
2021-06-16 11:28:33 +02:00
{FF_FORMAT_ARG_TYPE_DOUBLE, &biosLimit},
2021-04-15 18:59:26 +02:00
{FF_FORMAT_ARG_TYPE_DOUBLE, &scalingMaxFreq},
{FF_FORMAT_ARG_TYPE_DOUBLE, &scalingMinFreq},
{FF_FORMAT_ARG_TYPE_DOUBLE, &infoMaxFreq},
{FF_FORMAT_ARG_TYPE_DOUBLE, &infoMinFreq},
2021-06-16 11:28:33 +02:00
{FF_FORMAT_ARG_TYPE_DOUBLE, &procGhz},
2021-04-15 18:59:26 +02:00
{FF_FORMAT_ARG_TYPE_DOUBLE, &ghz}
});
2021-03-27 18:14:19 +01:00
2021-04-03 21:51:50 +02:00
ffStrbufDestroy(&cpu);
2021-06-16 11:28:33 +02:00
ffStrbufDestroy(&namePretty);
ffStrbufDestroy(&name);
ffStrbufDestroy(&vendor);
2021-03-27 18:14:19 +01:00
}