ohmu
·
2026-10-15
1#include "gpu.h"
2#include "common/debug.h"
3#include "common/io.h"
4#include "common/strutil.h"
5
6#include <fcntl.h>
7
8static double parseTZDir(int dfd, FFstrbuf* buffer) {
9 if (!ffReadFileBufferRelative(dfd, "type", buffer) || !ffStrbufStartsWithS(buffer, "gpu")) {
10 return FF_GPU_TEMP_UNSET;
11 }
12
13 if (!ffReadFileBufferRelative(dfd, "temp", buffer)) {
14 return FF_GPU_TEMP_UNSET;
15 }
16
17 double value = ffStrbufToDouble(buffer, FF_GPU_TEMP_UNSET); // millidegree Celsius
18 if (value == FF_GPU_TEMP_UNSET) {
19 return FF_GPU_TEMP_UNSET;
20 }
21
22 return value / 1000.;
23}
24
25double ffGPUDetectTempFromTZ(void) {
26 FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/thermal/");
27 if (dirp) {
28 FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
29 int dfd = dirfd(dirp);
30 struct dirent* entry;
31 while ((entry = readdir(dirp)) != nullptr) {
32 if (entry->d_name[0] == '.') {
33 continue;
34 }
35 if (!ffStrStartsWith(entry->d_name, "thermal_zone")) {
36 continue;
37 }
38
39 FF_AUTO_CLOSE_FD int subfd = openat(dfd, entry->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
40 if (subfd < 0) {
41 continue;
42 }
43
44 double result = parseTZDir(subfd, &buffer);
45 if (result != FF_GPU_TEMP_UNSET) {
46 return result;
47 }
48 }
49 }
50 return FF_GPU_TEMP_UNSET;
51}
52
53const char* ffDetectGPUImpl(const FFGPUOptions* options, FFlist* gpus) {
54 FF_UNUSED(options, gpus);
55 FF_DEBUG("No permission. Fallbacks to Vulkan, OpenCL or OpenGL instead");
56 return "No permission. Fallbacks to Vulkan, OpenCL or OpenGL instead";
57}