From 9de0b7f8937b7f6ce990132609f0b26851b31f2b Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 3 Jan 2025 15:36:22 +0100 Subject: Monitor CPU --- cpuload.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 cpuload.cpp (limited to 'cpuload.cpp') diff --git a/cpuload.cpp b/cpuload.cpp new file mode 100644 index 0000000..77abc3e --- /dev/null +++ b/cpuload.cpp @@ -0,0 +1,71 @@ +#include "cpuload.h" + +#include +#include + +#include +#include + +int get_number_of_cpus() +{ + int result{}; + std::string stat = Reichwein::File::getFile("/proc/stat"); + std::vector lines = Reichwein::Stringhelper::split(stat, "\n"); + for (const auto& line: lines) { + std::vector words = Reichwein::Stringhelper::split(line, " "); + // /proc/stat line, e.g.: cpu0 1132 34 1441 11311718 3675 127 438 + if (words.size() >= 8) { + if (words[0].size() > 3 && words[0].substr(0, 3) == "cpu") { + ++result; + } + } + } + return result; +} + +// returns empty vector if no data is available yet +// Note: to be called several times, because data is generated differentially from /proc/stat +std::vector get_cpu_loads() +{ + using clock_type = std::chrono::high_resolution_clock; + static int number_of_cpus = get_number_of_cpus(); + static std::vector stat_cpus_sum(number_of_cpus); + static std::vector stat_cpus_idle(number_of_cpus); + static std::chrono::time_point timestamp{}; + + std::string stat = Reichwein::File::getFile("/proc/stat"); + + std::vector lines = Reichwein::Stringhelper::split(stat, "\n"); + + std::vector result; + + int i = 0; + for (const auto& line: lines) { + std::vector words = Reichwein::Stringhelper::split(line, " "); + // /proc/stat line, e.g.: cpu0 1132 34 1441 11311718 3675 127 438 + // idle value is at index 4 + if (words.size() >= 8) { + if (words[0].size() > 3 && words[0].substr(0, 3) == "cpu") { + uint64_t sum = std::accumulate(words.begin() + 1, words.end(), uint64_t{}, [](uint64_t sum, const std::string& s){return sum + std::stoull(s);}); + uint64_t idle = std::stoull(words[4]); + + // previous data available + if (timestamp == std::chrono::time_point{}) + { + uint64_t sum_diff = sum - stat_cpus_sum[i]; + uint64_t idle_diff = idle - stat_cpus_idle[i]; + int percentage = (sum_diff == 0) ? 0 : ((sum_diff - idle_diff) * 100 / sum_diff); + result.push_back(percentage); + } + + stat_cpus_sum[i] = sum; + stat_cpus_idle[i] = idle; + + ++i; + } + } + } + + return result; +} + -- cgit v1.2.3