Skip to content

Commit bc05a30

Browse files
committed
CPU (Linux): improve temp detection
Support Android
1 parent 98c7803 commit bc05a30

File tree

1 file changed

+81
-51
lines changed

1 file changed

+81
-51
lines changed

src/detection/cpu/cpu_linux.c

Lines changed: 81 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,32 @@
1313

1414
#define FF_CPUINFO_PATH "/proc/cpuinfo"
1515

16-
static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
16+
static double parseTZDir(int dfd, FFstrbuf* buffer)
1717
{
18-
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
19-
uint32_t dirLength = dir->length;
20-
ffStrbufAppendS(dir, "temp1_input");
18+
if(!ffReadFileBufferRelative(dfd, "temp", buffer))
19+
return FF_CPU_TEMP_UNSET;
2120

22-
if(!ffReadFileBuffer(dir->chars, buffer))
23-
{
24-
// Some badly implemented system put temp file in /hwmonN/device
25-
ffStrbufSubstrBefore(dir, dirLength);
26-
ffStrbufAppendS(dir, "device/");
27-
dirLength = dir->length;
28-
ffStrbufAppendS(dir, "temp1_input");
29-
30-
if(!ffReadFileBuffer(dir->chars, buffer))
31-
return FF_CPU_TEMP_UNSET;
32-
}
21+
double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET);// millidegree Celsius
22+
if(value == FF_CPU_TEMP_UNSET)
23+
return FF_CPU_TEMP_UNSET;
3324

34-
ffStrbufSubstrBefore(dir, dirLength);
25+
if (!ffReadFileBufferRelative(dfd, "type", buffer) || ffStrbufStartsWithS(buffer, "cpu"))
26+
return FF_CPU_TEMP_UNSET;
3527

36-
double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET);// millidegree Celsius
28+
return value / 1000.;
29+
}
30+
31+
static double parseHwmonDir(int dfd, FFstrbuf* buffer)
32+
{
33+
//https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
34+
if(!ffReadFileBufferRelative(dfd, "temp1_input", buffer))
35+
return FF_CPU_TEMP_UNSET;
3736

37+
double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET);// millidegree Celsius
3838
if(value == FF_CPU_TEMP_UNSET)
3939
return FF_CPU_TEMP_UNSET;
4040

41-
ffStrbufAppendS(dir, "name");
42-
if (!ffReadFileBuffer(dir->chars, buffer))
41+
if (!ffReadFileBufferRelative(dfd, "temp1_label", buffer))
4342
return FF_CPU_TEMP_UNSET;
4443

4544
ffStrbufTrimRightSpace(buffer);
@@ -49,55 +48,86 @@ static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
4948
#if __x86_64__ || __i386__
5049
ffStrbufEqualS(buffer, "k10temp") || // AMD
5150
ffStrbufEqualS(buffer, "fam15h_power") || // AMD
52-
ffStrbufEqualS(buffer, "coretemp") // Intel
53-
#else
54-
ffStrbufEqualS(buffer, "temp") // Asahi
51+
ffStrbufEqualS(buffer, "coretemp") || // Intel
5552
#endif
53+
false
5654
) return value / 1000.;
5755

5856
return FF_CPU_TEMP_UNSET;
5957
}
6058

61-
static double detectTZTemp(FFstrbuf* buffer)
62-
{
63-
if (ffReadFileBuffer("/sys/class/thermal/thermal_zone0/temp", buffer))
64-
{
65-
double value = ffStrbufToDouble(buffer, FF_CPU_TEMP_UNSET);// millidegree Celsius
66-
return value != FF_CPU_TEMP_UNSET ? value / 1000. : FF_CPU_TEMP_UNSET;
67-
}
68-
return FF_CPU_TEMP_UNSET;
69-
}
70-
7159
static double detectCPUTemp(void)
7260
{
73-
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA(64);
74-
ffStrbufAppendS(&baseDir, "/sys/class/hwmon/");
75-
7661
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
62+
{
63+
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/hwmon/");
64+
if(dirp)
65+
{
66+
int dfd = dirfd(dirp);
67+
struct dirent* entry;
68+
while((entry = readdir(dirp)) != NULL)
69+
{
70+
if(entry->d_name[0] == '.')
71+
continue;
7772

78-
uint32_t baseDirLength = baseDir.length;
79-
80-
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
81-
if(dirp == NULL)
82-
return FF_CPU_TEMP_UNSET;
73+
FF_AUTO_CLOSE_FD int subfd = openat(dfd, entry->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
74+
if(subfd < 0)
75+
continue;
8376

84-
struct dirent* entry;
85-
while((entry = readdir(dirp)) != NULL)
77+
double result = parseHwmonDir(subfd, &buffer);
78+
if (result != FF_CPU_TEMP_UNSET)
79+
return result;
80+
}
81+
}
82+
}
8683
{
87-
if(entry->d_name[0] == '.')
88-
continue;
84+
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/thermal/");
85+
if(dirp)
86+
{
87+
int dfd = dirfd(dirp);
88+
struct dirent* entry;
89+
while((entry = readdir(dirp)) != NULL)
90+
{
91+
if(entry->d_name[0] == '.')
92+
continue;
93+
if(!ffStrStartsWith(entry->d_name, "thermal_zone"))
94+
continue;
95+
96+
FF_AUTO_CLOSE_FD int subfd = openat(dfd, entry->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
97+
if(subfd < 0)
98+
continue;
8999

90-
ffStrbufAppendS(&baseDir, entry->d_name);
91-
ffStrbufAppendC(&baseDir, '/');
100+
double result = parseTZDir(subfd, &buffer);
101+
if (result != FF_CPU_TEMP_UNSET)
102+
return result;
103+
}
104+
}
105+
}
106+
{
107+
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/devices/platform/");
108+
if(dirp)
109+
{
110+
int dfd = dirfd(dirp);
111+
struct dirent* entry;
112+
while((entry = readdir(dirp)) != NULL)
113+
{
114+
if(entry->d_name[0] == '.')
115+
continue;
116+
if(!ffStrStartsWith(entry->d_name, "cputemp."))
117+
continue;
92118

93-
double result = parseHwmonDir(&baseDir, &buffer);
94-
if (result != FF_CPU_TEMP_UNSET)
95-
return result;
119+
FF_AUTO_CLOSE_FD int subfd = openat(dfd, entry->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
120+
if(subfd < 0)
121+
continue;
96122

97-
ffStrbufSubstrBefore(&baseDir, baseDirLength);
123+
double result = parseHwmonDir(subfd, &buffer);
124+
if (result != FF_CPU_TEMP_UNSET)
125+
return result;
126+
}
127+
}
98128
}
99129

100-
return detectTZTemp(&buffer);
130+
return FF_CPU_TEMP_UNSET;
101131
}
102132

103133
#ifdef __ANDROID__

0 commit comments

Comments
 (0)