summaryrefslogtreecommitdiffhomepage
path: root/cpuload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpuload.cpp')
-rw-r--r--cpuload.cpp71
1 files changed, 71 insertions, 0 deletions
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 <chrono>
+#include <numeric>
+
+#include <libreichwein/file.h>
+#include <libreichwein/stringhelper.h>
+
+int get_number_of_cpus()
+{
+ int result{};
+ std::string stat = Reichwein::File::getFile("/proc/stat");
+ std::vector<std::string> lines = Reichwein::Stringhelper::split(stat, "\n");
+ for (const auto& line: lines) {
+ std::vector<std::string> 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<int> get_cpu_loads()
+{
+ using clock_type = std::chrono::high_resolution_clock;
+ static int number_of_cpus = get_number_of_cpus();
+ static std::vector<int> stat_cpus_sum(number_of_cpus);
+ static std::vector<int> stat_cpus_idle(number_of_cpus);
+ static std::chrono::time_point<clock_type> timestamp{};
+
+ std::string stat = Reichwein::File::getFile("/proc/stat");
+
+ std::vector<std::string> lines = Reichwein::Stringhelper::split(stat, "\n");
+
+ std::vector<int> result;
+
+ int i = 0;
+ for (const auto& line: lines) {
+ std::vector<std::string> 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<clock_type>{})
+ {
+ 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;
+}
+