From: Michael Tremer Date: Mon, 30 Oct 2023 11:00:11 +0000 (+0000) Subject: os: Add function to gather cpu stats X-Git-Tag: 0.9.30~1381 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8038a15dde4ddf08dc08872a09c2c97c8f677cab;p=pakfire.git os: Add function to gather cpu stats Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/os.h b/src/libpakfire/include/pakfire/os.h index dd600e633..70e608bee 100644 --- a/src/libpakfire/include/pakfire/os.h +++ b/src/libpakfire/include/pakfire/os.h @@ -37,6 +37,23 @@ struct pakfire_cpuinfo { int pakfire_cpuinfo(struct pakfire_cpuinfo* cpuinfo); +// CPU stat + +struct pakfire_cpustat { + double user; + double nice; + double system; + double idle; + double iowait; + double irq; + double softirq; + double steal; + double guest; + double guest_nice; +}; + +int pakfire_cpustat(struct pakfire_cpustat* cpustat); + // Meminfo struct pakfire_meminfo { diff --git a/src/libpakfire/os.c b/src/libpakfire/os.c index 63a225e66..bfb03a7df 100644 --- a/src/libpakfire/os.c +++ b/src/libpakfire/os.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -141,6 +142,55 @@ int pakfire_cpuinfo(struct pakfire_cpuinfo* cpuinfo) { return pakfire_parse_file("/proc/cpuinfo", pakfire_parse_cpuinfo, cpuinfo); } +// CPU Stats + +static int pakfire_parse_cpustat(char* line, size_t length, void* data) { + struct pakfire_cpustat* cpustat = data; + struct cpustat { + unsigned long int user; + unsigned long int nice; + unsigned long int system; + unsigned long int idle; + unsigned long int iowait; + unsigned long int irq; + unsigned long int softirq; + unsigned long int steal; + unsigned long int guest; + unsigned long int guest_nice; + } stat; + int r; + + // Only care about the line of interest + if (pakfire_string_startswith(line, "cpu ")) { + r = sscanf(line, "cpu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", + &stat.user, &stat.nice, &stat.system, &stat.idle, &stat.iowait, + &stat.irq, &stat.softirq, &stat.steal, &stat.guest, &stat.guest_nice); + if (r < 10) + return -EINVAL; + + // Fetch how many ticks a second + long int ticks = sysconf(_SC_CLK_TCK); + + // Convert to relative terms + cpustat->user = stat.user / ticks; + cpustat->nice = stat.nice / ticks; + cpustat->system = stat.system / ticks; + cpustat->idle = stat.idle / ticks; + cpustat->iowait = stat.iowait / ticks; + cpustat->irq = stat.irq / ticks; + cpustat->softirq = stat.softirq / ticks; + cpustat->steal = stat.steal / ticks; + cpustat->guest = stat.guest / ticks; + cpustat->guest_nice = stat.guest_nice / ticks; + } + + return 0; +} + +int pakfire_cpustat(struct pakfire_cpustat* cpustat) { + return pakfire_parse_file("/proc/stat", pakfire_parse_cpustat, cpustat); +} + // Meminfo static int pakfire_parse_meminfo_value(uint64_t* mem, const char* s) { diff --git a/tests/libpakfire/os.c b/tests/libpakfire/os.c index e631bad1e..9cc6a27da 100644 --- a/tests/libpakfire/os.c +++ b/tests/libpakfire/os.c @@ -38,6 +38,29 @@ FAIL: return EXIT_FAILURE; } +// This test parses /proc/stat +static int test_cpustat(const struct test* t) { + struct pakfire_cpustat cpustat = {}; + + ASSERT_SUCCESS(pakfire_cpustat(&cpustat)); + + ASSERT(cpustat.user >= 0); + ASSERT(cpustat.nice >= 0); + ASSERT(cpustat.system >= 0); + ASSERT(cpustat.idle >= 0); + ASSERT(cpustat.iowait >= 0); + ASSERT(cpustat.irq >= 0); + ASSERT(cpustat.softirq >= 0); + ASSERT(cpustat.steal >= 0); + ASSERT(cpustat.guest >= 0); + ASSERT(cpustat.guest_nice >= 0); + + return EXIT_SUCCESS; + +FAIL: + return EXIT_FAILURE; +} + // This test parses /proc/meminfo static int test_meminfo(const struct test* t) { struct pakfire_meminfo meminfo = {}; @@ -65,6 +88,7 @@ FAIL: int main(int argc, const char* argv[]) { testsuite_add_test(test_cpuinfo); + testsuite_add_test(test_cpustat); testsuite_add_test(test_meminfo); return testsuite_run(argc, argv);