mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-28 07:44:06 +01:00
120 lines
3.7 KiB
C
120 lines
3.7 KiB
C
#include "cpu.h"
|
|
#include "common/debug.h"
|
|
#include "common/sysctl.h"
|
|
#include "common/io.h"
|
|
|
|
#include <sys/envsys.h>
|
|
#include <prop/proplib.h>
|
|
#include <paths.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
static void freePropDict(prop_dictionary_t* pdict) {
|
|
assert(pdict != nullptr);
|
|
if (*pdict == nullptr) {
|
|
return;
|
|
}
|
|
prop_object_release(*pdict);
|
|
}
|
|
|
|
static const char* detectCpuTemp(const FFCPUOptions* options, double* current) {
|
|
FF_AUTO_CLOSE_FD int fd = open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC);
|
|
if (fd < 0) {
|
|
FF_DEBUG("open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed: %s", strerror(errno));
|
|
return "open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed";
|
|
}
|
|
|
|
[[gnu::cleanup(freePropDict)]] prop_dictionary_t root = nullptr;
|
|
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0) {
|
|
FF_DEBUG("prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed: %s", strerror(errno));
|
|
return "prop_dictionary_recv_ioctl(ENVSYS_GETDICTIONARY) failed";
|
|
}
|
|
|
|
prop_array_t array;
|
|
|
|
if (options->tempSensor.length > 0) {
|
|
array = prop_dictionary_get(root, options->tempSensor.chars);
|
|
if (!array) {
|
|
FF_DEBUG("No temp data found in specified sensor");
|
|
return "No temp data found in specified sensor";
|
|
}
|
|
} else {
|
|
array = prop_dictionary_get(root, "coretemp0");
|
|
if (!array) {
|
|
array = prop_dictionary_get(root, "amdzentemp0");
|
|
}
|
|
if (!array) {
|
|
array = prop_dictionary_get(root, "viac7temp0");
|
|
}
|
|
if (!array) {
|
|
array = prop_dictionary_get(root, "acpitz0"); // Thermal Zones
|
|
}
|
|
if (!array) {
|
|
FF_DEBUG("No temp data found in root dictionary");
|
|
return "No temp data found in root dictionary";
|
|
}
|
|
}
|
|
|
|
if (prop_array_count(array) != 2) {
|
|
FF_DEBUG("Unexpected `xtemp0` data");
|
|
return "Unexpected `xtemp0` data";
|
|
}
|
|
|
|
prop_dictionary_t dict = prop_array_get(array, 0);
|
|
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY) {
|
|
FF_DEBUG("Unexpected `xtemp0[0]`");
|
|
return "Unexpected `xtemp0[0]`";
|
|
}
|
|
|
|
int temp = 0; // in µK
|
|
if (!prop_dictionary_get_int(dict, "cur-value", &temp)) {
|
|
FF_DEBUG("Failed to get temperature");
|
|
return "Failed to get temperature";
|
|
}
|
|
|
|
*current = temp / 1e6 - 273.15;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) {
|
|
if (ffSysctlGetString("machdep.cpu_brand", &cpu->name) != nullptr &&
|
|
ffSysctlGetString("machdep.dmi.processor-version", &cpu->name) != nullptr &&
|
|
ffSysctlGetString("hw.cpu0.name", &cpu->name) != nullptr &&
|
|
ffSysctlGetString("hw.model", &cpu->name) != nullptr) {
|
|
ffStrbufSetS(&cpu->name, "Unknown CPU");
|
|
}
|
|
|
|
if (ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor) == nullptr) {
|
|
ffStrbufTrimRightSpace(&cpu->vendor);
|
|
}
|
|
|
|
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
|
|
cpu->coresLogical = cpu->coresPhysical;
|
|
cpu->coresOnline = (uint16_t) ffSysctlGetInt("hw.ncpuonline", cpu->coresLogical);
|
|
|
|
ffCPUDetectByCpuid(cpu);
|
|
|
|
uint32_t freq = (uint32_t) ffSysctlGetInt("machdep.cpu.frequency.target", 0);
|
|
if (freq == 0) {
|
|
freq = (uint32_t) (ffSysctlGetInt64("hw.cpu0.clock_frequency", 0) / 1000000);
|
|
}
|
|
if (freq == 0) {
|
|
freq = (uint32_t) ffSysctlGetInt("machdep.dmi.processor-frequency", 0);
|
|
}
|
|
if (freq > cpu->frequencyBase) {
|
|
cpu->frequencyBase = freq;
|
|
}
|
|
|
|
cpu->temperature = FF_CPU_TEMP_UNSET;
|
|
|
|
if (options->temp) {
|
|
detectCpuTemp(options, &cpu->temperature);
|
|
}
|
|
|
|
return nullptr;
|
|
}
|