Skip to content

Commit 5d853f3

Browse files
GPU temp detection
1 parent 20e2f1e commit 5d853f3

File tree

9 files changed

+64
-34
lines changed

9 files changed

+64
-34
lines changed

DEVELOPMENT.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Here i just add things that are easy to forget.
1212
- `libffprint`: contains the printing functions, logos, format etc
1313
- `fastfetch` and `flashfetch`: Executables, that initialize the config of libffprint. Fist one at runtime, second one at compile time
1414
- [ ] Better OS output for all possible combinations of /etc/os-release variables.
15-
- [ ] Expose temperatures to GPU format string
1615
- [ ] Find wayland compositor by looking at \${XDG_RUNTIME_DIR}/${WAYLAND_DISPLAY:-wayland-0}
1716
- [ ] Make LocalIP module more configurable
1817
- [ ] Automatic migrate old config files to newer versions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Title, Separator, OS, Host, Kernel, Uptime, Processes, Packages, Shell, Resoluti
5050

5151
##### Logos
5252
```
53-
Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Debian, Devuan, Deepin, Endeavour, Fedora, Garuda, Gentoo, KDE Neon, Kubuntu, Linux, Manjaro, Mint, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Ubuntu, Void, Zorin
53+
Alpine, Android, Arch, Arco, Artix, Bedrock, CachyOS, CentOS, Debian, Devuan, Deepin, Endeavour, Fedora, Garuda, Gentoo, KDE Neon, Kubuntu, Linux, Manjaro, Mint, NixOS, OpenSUSE, OpenSUSE Tumbleweed, OpenSUSE LEAP, Pop!_OS, RebornOS, RedstarOS, Rocky, Ubuntu, Void, Zorin
5454
```
5555
* Most of the logos have a small variant. Access it by appending _small to the logo name.
5656
* Some logos have an old variant. Access it by appending _old to the logo name.

presets/verbose

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
--terminal-font-format "Raw: {}; Name: {}; Size: {}; Styles: {}; Pretty: {}"
2020
--cpu-format "Name: {}; Pretty: {}; Vendor: {}; Logical online: {}; Logical configured: {}; Physical: {}; Cores: {}; temperature: {}; bios: {}; scaling max: {}; scaling min: {}; info max: {}; info min: {}; cpuinfo: {}; frequency: {}"
2121
--cpu-usage-format "Percentage: {}"
22-
--gpu-format "Vendor: {}; Vendor pretty: {}; Name: {}; Name pretty: {}; Driver: {}"
22+
--gpu-format "Vendor: {}; Vendor pretty: {}; Name: {}; Name pretty: {}; Driver: {}; Temperature: {}"
2323
--memory-format "Used: {}; Total: {}; Percentage: {}"
2424
--disk-format "Used: {}; Total: {}; Files: {}; Percentage: {}"
2525
--battery-format "Manufactor: {}; Model: {}; Technology: {}; Capacaty: {}; Status: {}"

src/detection/temps.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <pthread.h>
44
#include <dirent.h>
55
#include <string.h>
6+
#include <math.h>
67

78
static bool isTempFile(const char* name)
89
{
@@ -20,22 +21,34 @@ static bool parseHwmonDir(FFstrbuf* dir, FFTempValue* value)
2021
return false;
2122

2223
uint32_t dirLength = dir->length;
24+
value->value = 0.0 / 0.0; //use NaN as error value
25+
26+
FFstrbuf valueString;
27+
ffStrbufInit(&valueString);
2328

2429
struct dirent* dirent;
2530
while((dirent = readdir(dirp)) != NULL)
2631
{
27-
if(isTempFile(dirent->d_name))
28-
{
29-
ffStrbufAppendS(dir, dirent->d_name);
30-
ffGetFileContent(dir->chars, &value->value);
31-
ffStrbufSubstrBefore(dir, dirLength);
32-
break;
33-
}
32+
if(!isTempFile(dirent->d_name))
33+
continue;
34+
35+
ffStrbufAppendS(dir, dirent->d_name);
36+
ffGetFileContent(dir->chars, &valueString);
37+
ffStrbufSubstrBefore(dir, dirLength);
38+
39+
//ffStrbufToDouble() returns NaN if the string couldn't be parsed
40+
value->value = ffStrbufToDouble(&valueString);
41+
if(value->value != value->value)
42+
continue;
43+
44+
value->value /= 1000.0; //millidegrees to degrees
45+
break;
3446
}
3547

3648
closedir(dirp);
49+
ffStrbufDestroy(&valueString);
3750

38-
if(value->value.length == 0)
51+
if(value->value != value->value)
3952
return false;
4053

4154
ffStrbufAppendS(dir, "name");
@@ -92,12 +105,10 @@ const FFTempsResult* ffDetectTemps(const FFinstance* instance)
92105
FFTempValue* temp = ffListAdd(&result.values);
93106
ffStrbufInit(&temp->name);
94107
ffStrbufInit(&temp->deviceClass);
95-
ffStrbufInit(&temp->value);
96108
if(!parseHwmonDir(&baseDir, temp))
97109
{
98110
ffStrbufDestroy(&temp->name);
99111
ffStrbufDestroy(&temp->deviceClass);
100-
ffStrbufDestroy(&temp->value);
101112
--result.values.length;
102113
}
103114

src/detection/vulkan.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ static void detectVulkan(const FFinstance* instance, FFVulkanResult* result)
174174
ffStrbufInit(&gpu->vendor);
175175
ffStrbufInit(&gpu->name);
176176
ffStrbufInit(&gpu->driver);
177+
gpu->temperature = 0.0 / 0.0; //NaN, no way to detect temperature using vulkan
177178
ffStrbufAppendS(&gpu->name, physicalDeviceProperties.properties.deviceName);
178179
}
179180

src/fastfetch.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,13 @@ static inline void printCommandHelp(const char* command)
262262
}
263263
else if(strcasecmp(command, "gpu-format") == 0)
264264
{
265-
constructAndPrintCommandHelpFormat("gpu", "{2} {4}", 5,
265+
constructAndPrintCommandHelpFormat("gpu", "{2} {4}", 6,
266266
"GPU vendor",
267267
"GPU vendor pretty",
268268
"GPU name",
269269
"GPU name pretty",
270-
"GPU driver"
270+
"GPU driver",
271+
"GPU temperature"
271272
);
272273
}
273274
else if(strcasecmp(command, "memory-format") == 0)

src/fastfetch.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ typedef struct FFGPUResult
242242
FFstrbuf vendor;
243243
FFstrbuf name;
244244
FFstrbuf driver;
245+
double temperature;
245246
} FFGPUResult;
246247

247248
typedef struct FFVulkanResult
@@ -273,8 +274,8 @@ typedef struct FFDisplayServerResult
273274
typedef struct FFTempValue
274275
{
275276
FFstrbuf name;
276-
FFstrbuf value;
277277
FFstrbuf deviceClass;
278+
double value;
278279
} FFTempValue;
279280

280281
typedef struct FFTempsResult

src/modules/cpu.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,10 @@ static double detectCPUTemp(const FFinstance* instance)
3636
FFTempValue* value = ffListGet(&temps->values, i);
3737

3838
if(
39-
ffStrbufFirstIndexS(&value->name, "cpu") == value->name.length &&
40-
ffStrbufCompS(&value->name, "k10temp") != 0 &&
41-
ffStrbufCompS(&value->name, "coretemp") != 0
42-
) continue;
43-
44-
double temp = ffStrbufToDouble(&value->value);
45-
46-
//NaN
47-
if(temp != temp)
48-
continue;
49-
50-
return temp / 1000.0; // millidegrees to degrees
39+
ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length ||
40+
ffStrbufCompS(&value->name, "k10temp") == 0 ||
41+
ffStrbufCompS(&value->name, "coretemp") == 0
42+
) return value->value;
5143
}
5244

5345
return 0.0 / 0.0; //NaN
@@ -170,8 +162,6 @@ void ffPrintCPU(FFinstance* instance)
170162
double cpuTemp;
171163
if(instance->config.cpu.outputFormat.length > 0)
172164
cpuTemp = detectCPUTemp(instance);
173-
else
174-
cpuTemp = 0.0 / 0.0; //NaN
175165

176166
FFstrbuf cpu;
177167
ffStrbufInitA(&cpu, 128);

src/modules/gpu.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <string.h>
44

55
#define FF_GPU_MODULE_NAME "GPU"
6-
#define FF_GPU_NUM_FORMAT_ARGS 5
6+
#define FF_GPU_NUM_FORMAT_ARGS 6
77

88
static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache, FFGPUResult* result)
99
{
@@ -39,6 +39,7 @@ static void printGPUResult(FFinstance* instance, uint8_t index, FFcache* cache,
3939
{FF_FORMAT_ARG_TYPE_STRBUF, &result->name},
4040
{FF_FORMAT_ARG_TYPE_STRBUF, &namePretty},
4141
{FF_FORMAT_ARG_TYPE_STRBUF, &result->driver},
42+
{FF_FORMAT_ARG_TYPE_DOUBLE, &result->temperature}
4243
});
4344

4445
ffStrbufDestroy(&result->vendor);
@@ -89,6 +90,26 @@ static void pciGetDriver(struct pci_dev* dev, FFstrbuf* driver, char*(*ffpci_get
8990
ffStrbufDestroy(&path);
9091
}
9192

93+
static double pciGetTemperatur(const FFinstance* instance, uint16_t deviceClass)
94+
{
95+
const FFTempsResult* tempsResult = ffDetectTemps(instance);
96+
97+
for(uint32_t i = 0; i < tempsResult->values.length; i++)
98+
{
99+
FFTempValue* tempValue = ffListGet(&tempsResult->values, i);
100+
101+
uint32_t tempClass;
102+
if(sscanf(tempValue->deviceClass.chars, "%x", &tempClass) != 1)
103+
continue;
104+
105+
//The kernel exposes the device class multiplied by 256 for some reason
106+
if(tempClass == deviceClass * 256)
107+
return tempValue->value;
108+
}
109+
110+
return 0.0 / 0.0; //NaN
111+
}
112+
92113
static bool pciPrintGPUs(FFinstance* instance)
93114
{
94115
FF_LIBRARY_LOAD(pci, instance->config.libPCI, false, "libpci.so", 4)
@@ -121,16 +142,22 @@ static bool pciPrintGPUs(FFinstance* instance)
121142
FFGPUResult* result = ffListAdd(&results);
122143

123144
ffStrbufInitA(&result->vendor, 256);
124-
ffpci_lookup_name(pacc, result->vendor.chars, (int) result->vendor.allocated -1, PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id);
145+
ffpci_lookup_name(pacc, result->vendor.chars, (int) ffStrbufGetFree(&result->vendor), PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id);
125146
ffStrbufRecalculateLength(&result->vendor);
126147

127148
ffStrbufInitA(&result->name, 256);
128-
ffpci_lookup_name(pacc, result->name.chars, (int) result->name.allocated - 1, PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id);
149+
ffpci_lookup_name(pacc, result->name.chars, (int) ffStrbufGetFree(&result->name), PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id);
129150
ffStrbufRecalculateLength(&result->name);
130151

131152
ffStrbufInit(&result->driver);
132-
if(instance->config.gpu.outputFormat.length > 0) //We only need it for the format string, so don't detect it if it isn't needed
153+
result->temperature = 0;
154+
155+
//We only need it for the format string, so don't detect it if it isn't needed
156+
if(instance->config.gpu.outputFormat.length > 0)
157+
{
133158
pciGetDriver(dev, &result->driver, ffpci_get_param);
159+
result->temperature = pciGetTemperatur(instance, dev->device_class);
160+
}
134161
};
135162
}
136163

0 commit comments

Comments
 (0)