1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#include "cpu.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>
static void freePropDict(prop_dictionary_t* pdict) {
assert(pdict != NULL);
if (*pdict == NULL) {
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) {
return "open(_PATH_SYSMON, O_RDONLY | O_CLOEXEC) failed";
}
FF_A_CLEANUP(freePropDict) prop_dictionary_t root = NULL;
if (prop_dictionary_recv_ioctl(fd, ENVSYS_GETDICTIONARY, &root) < 0) {
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) {
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) {
return "No temp data found in root dictionary";
}
}
if (prop_array_count(array) != 2) {
return "Unexpected `xtemp0` data";
}
prop_dictionary_t dict = prop_array_get(array, 0);
if (prop_object_type(dict) != PROP_TYPE_DICTIONARY) {
return "Unexpected `xtemp0[0]`";
}
int temp = 0; // in µK
if (!prop_dictionary_get_int(dict, "cur-value", &temp)) {
return "Failed to get temperature";
}
*current = temp / 1e6 - 273.15;
return NULL;
}
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) {
if (ffSysctlGetString("machdep.cpu_brand", &cpu->name) != NULL &&
ffSysctlGetString("machdep.dmi.processor-version", &cpu->name) != NULL &&
ffSysctlGetString("hw.cpu0.name", &cpu->name) != NULL &&
ffSysctlGetString("hw.model", &cpu->name) != NULL) {
ffStrbufSetS(&cpu->name, "Unknown CPU");
}
if (ffSysctlGetString("machdep.dmi.processor-vendor", &cpu->vendor) == NULL) {
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 NULL;
}
|