Files
linuxSmartie/src/cpu.cpp
2026-01-02 12:24:33 +01:00

65 lines
2.4 KiB
C++

#include <chrono>
#include <cpu.hpp>
#include <cstdint>
#include <log.hpp>
#include <string>
#include <utils.hpp>
namespace cpu {
void detectHwmon(cpuSensors* target, const std::string& pci) {
const std::string path = "/sys/bus/pci/devices/" + pci + "/hwmon";
try {
target->hwmon = utils::getFirstDir(path);
} catch (...) {
applog(LOG::ERR, "NO CPU HWMON KERNEL MODULE DETECTED");
return;
}
target->zenpower = utils::fileExists(target->hwmon+ "/in1_input"); // idk if this is reliable, we're trying to avoid just reading the name
applog(LOG::INF, "Detected module \"{}\" in path \"{}\"", target->zenpower ? "zenpower" : "k10temp", target->hwmon);
}
void update(cpuSensors* c) {
static char buf[32];
struct EnergyTs {
uint64_t energy = 0;
std::chrono::time_point<std::chrono::steady_clock> ts;
};
static EnergyTs prev;
EnergyTs curr;
// read power from intel-rapl? works on amd too, btop uses this trick, seems accurate
// it tracks with "socket power" in hwinfo on windows, its actually the same thing i had in lcdsmartie
curr.ts = std::chrono::steady_clock::now();
utils::fastReadNum("/sys/class/powercap/intel-rapl:0/energy_uj", buf, curr.energy);
c->ptotal = static_cast<float>(curr.energy - prev.energy) / static_cast<float>(std::chrono::duration_cast<std::chrono::microseconds>(curr.ts - prev.ts).count());
prev = curr;
// lots of reads but still faster than reading /proc/cpuinfo
c->avg_freq = 0;
for (uint8_t i = 0; i < N_CPU; i++) {
utils::readFile("/sys/devices/system/cpu/cpu" + std::to_string(i) + "/cpufreq/cpuinfo_avg_freq", buf, sizeof(buf));
c->avg_freq += strtol(buf, nullptr, 10) / 1000;
}
c->avg_freq /= N_CPU;
if (c->hwmon.empty()) return; // break if no module
// commented out unused values so its faster
if (c->zenpower) {
utils::fastReadNum<1000>(c->hwmon + "/temp1_input", buf, c->tdie);
utils::fastReadNum<1000>(c->hwmon + "/temp2_input", buf, c->tctl);
utils::fastReadNum<1000>(c->hwmon + "/temp3_input", buf, c->tccd1);
utils::fastReadNum<1000>(c->hwmon + "/in1_input", buf, c->vcore);
utils::fastReadNum<1000>(c->hwmon + "/in2_input", buf, c->vsoc);
} else {
utils::fastReadNum<1000>(c->hwmon + "/temp1_input", buf, c->tctl);
utils::fastReadNum<1000>(c->hwmon + "/temp3_input", buf, c->tccd1);
}
}
} // namespace cpu