master ohmu/fastfetch-openbsd / src / detection / cpuusage / cpuusage.c
ohmu  ·  2026-10-15
 1#include "fastfetch.h"
 2#include "detection/cpuusage/cpuusage.h"
 3#include "common/time.h"
 4
 5#include <stdint.h>
 6
 7static FFlist cpuTimes1;
 8static uint64_t startTime;
 9
10void ffPrepareCPUUsage(void) {
11    if (startTime != 0) {
12        return; // Already prepared
13    }
14
15    ffListInit(&cpuTimes1);
16    ffGetCpuUsageInfo(&cpuTimes1);
17    startTime = ffTimeGetNow();
18}
19
20const char* ffGetCpuUsageResult(FFCPUUsageOptions* options, FFlist* result) {
21    const char* error = nullptr;
22    if (startTime == 0) {
23        ffListInit(&cpuTimes1);
24        error = ffGetCpuUsageInfo(&cpuTimes1);
25        if (error) {
26            return error;
27        }
28        ffTimeSleep(options->waitTime);
29    } else {
30        uint64_t elapsedTime = ffTimeGetNow() - startTime;
31        if (elapsedTime < options->waitTime) {
32            ffTimeSleep(options->waitTime - (uint32_t) elapsedTime);
33        }
34    }
35
36    if (cpuTimes1.length == 0) {
37        return "No CPU cores found";
38    }
39
40    FF_LIST_AUTO_DESTROY cpuTimes2 = ffListCreate();
41    uint32_t retryCount = 0;
42
43retry:
44    error = ffGetCpuUsageInfo(&cpuTimes2);
45    if (error) {
46        return error;
47    }
48    if (cpuTimes1.length != cpuTimes2.length) {
49        return "Unexpected CPU usage result";
50    }
51
52    for (uint32_t i = 0; i < cpuTimes1.length; ++i) {
53        FFCpuUsageInfo* cpuTime1 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes1, i);
54        FFCpuUsageInfo* cpuTime2 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes2, i);
55        if (cpuTime2->totalAll <= cpuTime1->totalAll) {
56            if (++retryCount <= 3) {
57                ffListClear(&cpuTimes2);
58                ffTimeSleep(options->waitTime);
59                goto retry;
60            }
61            return "CPU time did not increase. Try increasing wait time.";
62        }
63    }
64
65    for (uint32_t i = 0; i < cpuTimes1.length; ++i) {
66        FFCpuUsageInfo* cpuTime1 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes1, i);
67        FFCpuUsageInfo* cpuTime2 = FF_LIST_GET(FFCpuUsageInfo, cpuTimes2, i);
68        *FF_LIST_ADD(double, *result) = (double) (cpuTime2->inUseAll - cpuTime1->inUseAll) / (double) (cpuTime2->totalAll - cpuTime1->totalAll) * 100;
69        cpuTime1->inUseAll = cpuTime2->inUseAll;
70        cpuTime1->totalAll = cpuTime2->totalAll;
71    }
72    startTime = ffTimeGetNow();
73    return nullptr;
74}