67 lines
2.4 KiB
C++
67 lines
2.4 KiB
C++
#include <array>
|
|
#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 std::array<char, 32> buf;
|
|
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++) {
|
|
uint32_t t = 0;
|
|
utils::fastReadNum<1000>("/sys/devices/system/cpu/cpu" + std::to_string(i) + "/cpufreq/cpuinfo_avg_freq", buf, t);
|
|
c->avg_freq += t;
|
|
}
|
|
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
|