Files
fastfetch/src/detection/cpu/cpu_bsd.c
T

118 lines
3.9 KiB
C
Raw Normal View History

2022-09-19 22:23:31 +02:00
#include "cpu.h"
2022-09-19 23:16:43 +02:00
#include "common/sysctl.h"
#include "util/stringUtils.h"
2024-09-24 10:58:16 +08:00
#include <sys/param.h>
2025-01-12 11:53:35 +08:00
#if __has_include(<sys/cpuset.h>)
#include <sys/cpuset.h>
#define FF_HAVE_CPUSET 1
#endif
2024-09-24 10:58:16 +08:00
static const char* detectCpuTemp(double* current)
{
int temp = ffSysctlGetInt("dev.cpu.0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
static const char* detectThermalTemp(double* current)
{
int temp = ffSysctlGetInt("hw.acpi.thermal.tz0.temperature", -999999);
if (temp == -999999)
return "ffSysctlGetInt(\"hw.acpi.thermal.tz0.temperature\") failed";
// In tenth of degrees Kelvin
*current = (double) temp / 10 - 273.15;
return NULL;
}
2022-09-19 22:23:31 +02:00
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
2022-09-19 22:23:31 +02:00
{
2024-10-27 11:43:36 +08:00
if (ffSysctlGetString("hw.model", &cpu->name) != NULL)
2023-06-12 09:56:03 +08:00
return "sysctlbyname(hw.model) failed";
cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
cpu->coresPhysical = 0;
cpu->coresOnline = (uint16_t) ffSysctlGetInt("kern.smp.cpus", cpu->coresLogical);
2023-06-12 09:56:03 +08:00
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffSysctlGetString("kern.sched.topology_spec", &buffer) == NULL && buffer.length > 0)
{
// <groups>
// <group level="1" cache-level="3">
// <cpu count="4" mask="f,0,0,0">0, 1, 2, 3</cpu>
// <children>
// <group level="2" cache-level="2">
// <cpu count="2" mask="3,0,0,0">0, 1</cpu>
// <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
// </group>
// <group level="2" cache-level="2">
// <cpu count="2" mask="c,0,0,0">2, 3</cpu>
// <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
// </group>
// </children>
// </group>
// </groups>
char* line = NULL;
size_t len = 0;
bool inLvl2 = false, threadGroup = false;
uint32_t cpuCount = 0;
while (ffStrbufGetline(&line, &len, &buffer))
{
if (!inLvl2)
{
if (ffStrStartsWith(line, " <group level=\"2\""))
{
inLvl2 = true;
cpuCount = 0;
threadGroup = false;
}
else if (ffStrStartsWith(line, " <group level=\"1\""))
cpu->packages++;
}
else
{
if (ffStrEquals(line, " </group>"))
{
cpu->coresPhysical += threadGroup ? 1 : cpuCount;
inLvl2 = false;
}
else if (cpuCount == 0 && ffStrStartsWith(line, " <cpu count=\""))
cpuCount = (uint32_t) strtoul(line + strlen(" <cpu count=\""), NULL, 10);
else if (cpuCount > 0 && ffStrStartsWith(line, " <flags>"))
{
if (ffStrContains(line, "<flag name=\"THREAD\">THREAD group</flag>"))
threadGroup = true;
}
}
}
}
2025-01-12 11:53:35 +08:00
#if FF_HAVE_CPUSET && (__x86_64__ || __i386__)
// Bind current process to the first two cores, which is *usually* a performance core
cpuset_t currentCPU;
CPU_ZERO(&currentCPU);
CPU_SET(1, &currentCPU);
CPU_SET(2, &currentCPU);
cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), &currentCPU);
#endif
2024-08-18 17:26:53 +08:00
2025-01-13 15:06:18 +08:00
ffCPUDetectSpeedByCpuid(cpu);
uint32_t clockrate = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
if (clockrate > cpu->frequencyBase) cpu->frequencyBase = clockrate;
cpu->temperature = FF_CPU_TEMP_UNSET;
2023-06-12 09:56:03 +08:00
if (options->temp)
2023-10-10 09:28:31 +08:00
{
2024-09-24 10:58:16 +08:00
if (detectCpuTemp(&cpu->temperature) != NULL)
detectThermalTemp(&cpu->temperature);
2023-10-10 09:28:31 +08:00
}
2023-06-12 09:56:03 +08:00
return NULL;
2022-09-19 22:23:31 +02:00
}