==> tests/load_proc.c <==1/* load.rs's proc_stat, cpu_rates, classes, psi_and_meminfo. */
2#include "mesh/abi/host_load.h"
3#include "mesh/check.h"
4#include "mesh/load_proc.h"
5
6#include <stdlib.h>
7#include <string.h>
8
9static const char *STAT = "cpu 100 10 50 1000 20 5 5 0 7 0\n"
10 "cpu0 50 5 25 500 10 2 3 0 7 0\n"
11 "cpu2 50 5 25 500 10 3 2 0 0 0\n"
12 "intr 12345\nctxt 99\n";
13
14int main(void) {
15 static mesh_cpu_times per[MESH_MAX_CPUS];
16 static bool have[MESH_MAX_CPUS];
17 mesh_cpu_times all;
18 size_t n;
19 char *err = NULL;
20 CHECK_I(mesh_parse_proc_stat(STAT, &all, per, have, &n, &err), 0);
21 CHECK(all.busy == 170 && all.total == 1190 && all.iowait == 20);
22 CHECK_U(n, 3);
23 CHECK(have[0] && per[0].busy == 85 && per[0].total == 595 && per[0].iowait == 10);
24 CHECK(!have[1]);
25 CHECK_I(mesh_parse_proc_stat("intr 1\n", &all, per, have, &n, &err), -1);
26 CHECK_S(err, "/proc/stat has no cpu line");
27 free(err);
28 CHECK_I(mesh_parse_proc_stat("cpu 1 2 3\ncpu0 1 2 3 4 5 6 7 8\n", &all, per, have, &n, &err), -1);
29 CHECK_S(err, "/proc/stat \"cpu 1 2 3\": 3 fields, want at least 8");
30 free(err);
31 CHECK_I(mesh_parse_proc_stat("cpu 1 2 3 4 5 6 7 8\n", &all, per, have, &n, &err), -1);
32 CHECK_S(err, "/proc/stat lists no cpuN line");
33 free(err);
34
35 float b, io;
36 mesh_cpu_times a = {100, 1000, 10}, c = {150, 1100, 30}, d = {50, 1100, 0};
37 mesh_cpu_times_since(&c, &a, &b, &io);
38 CHECK(b == 0.5f && io == 0.2f);
39 mesh_cpu_times_since(&a, &a, &b, &io);
40 CHECK(b == 0 && io == 0);
41 mesh_cpu_times_since(&d, &a, &b, &io);
42 CHECK(b == 0 && io == 0);
43
44 uint64_t gb10[6] = {718, 731, 997, 1017, 1024, 0};
45 bool gh[6] = {1, 1, 1, 1, 1, 0};
46 uint8_t cls[6];
47 mesh_classify(gb10, gh, 6, cls);
48 const uint8_t want[6] = {MESH_CORE_LITTLE, MESH_CORE_LITTLE, MESH_CORE_BIG, MESH_CORE_BIG, MESH_CORE_BIG, MESH_CORE_UNKNOWN};
49 CHECK(memcmp(cls, want, 6) == 0);
50 uint64_t ryzen[3] = {4951533, 4951533, 4951533};
51 bool rh[3] = {1, 1, 1};
52 mesh_classify(ryzen, rh, 3, cls);
53 CHECK(cls[0] == MESH_CORE_BIG && cls[2] == MESH_CORE_BIG);
54 bool none[2] = {0, 0};
55 mesh_classify(ryzen, none, 2, cls);
56 CHECK(cls[0] == MESH_CORE_UNKNOWN && cls[1] == MESH_CORE_UNKNOWN);
57 float util[4] = {1.0f, 0.5f, 0.0f, 0};
58 bool uh[4] = {1, 1, 1, 0};
59 uint8_t uc[4] = {MESH_CORE_BIG, MESH_CORE_LITTLE, MESH_CORE_BIG, MESH_CORE_BIG};
60 float al, bg, lt;
61 mesh_class_util(util, uh, uc, 4, &al, &bg, <);
62 CHECK(al == 0.5f && bg == 0.5f && lt == 0.5f);
63 uint8_t allbig[4] = {1, 1, 1, 1};
64 mesh_class_util(util, uh, allbig, 4, &al, &bg, <);
65 CHECK(lt == 0.0f);
66
67 mesh_psi p;
68 CHECK_I(mesh_parse_psi("some avg10=1.79 avg60=1.40 avg300=1.21 total=18570277423\nfull avg10=0.00 avg60=0.00 avg300=0.00 total=0\n", &p, &err), 0);
69 CHECK(p.some_total == 18570277423ull && p.full_total == 0);
70 CHECK(p.some_avg10 > 0.0178f && p.some_avg10 < 0.0180f);
71 CHECK_I(mesh_parse_psi("some avg10=1.0 total=5\n", &p, &err), 0);
72 CHECK_I(mesh_parse_psi("full avg10=0 total=1\n", &p, &err), -1);
73 CHECK_S(err, "PSI: no `some` line");
74 free(err);
75 CHECK_I(mesh_parse_psi("some avg10=x total=1\n", &p, &err), -1);
76 CHECK_S(err, "PSI line \"some avg10=x total=1\": no avg10/total");
77 free(err);
78 CHECK(mesh_psi_rate(1250000, 1000000, 1000000) == 0.25f);
79 CHECK(mesh_psi_rate(5, 10, 1000000) == 0.0f);
80 CHECK(mesh_psi_rate(10, 0, 0) == 0.0f);
81 mesh_meminfo m;
82 CHECK_I(mesh_parse_meminfo("MemTotal: 126000000 kB\nMemFree: 1 kB\nMemAvailable: 90000000 kB\nSwapTotal: 1000 kB\nSwapFree: 250 kB\n", &m, &err), 0);
83 CHECK(m.total_kb == 126000000 && m.avail_kb == 90000000 && m.swap_total_kb == 1000 && m.swap_free_kb == 250);
84 CHECK_I(mesh_parse_meminfo("MemTotal: 5 kB\n", &m, &err), -1);
85 CHECK_S(err, "/proc/meminfo: no MemTotal or MemAvailable");
86 free(err);
87 float la[3];
88 CHECK_I(mesh_parse_loadavg("1.50 2.25 3.00 4/1234 5678\n", la, &err), 0);
89 CHECK(la[0] == 1.5f && la[1] == 2.25f && la[2] == 3.0f);
90 CHECK_I(mesh_parse_loadavg("1.0 2.0\n", la, &err), -1);
91 CHECK_S(err, "/proc/loadavg \"1.0 2.0\\n\"");
92 free(err);
93 uint64_t v;
94 CHECK(mesh_proc_field("nr_free 5\npswpin 7\npswpout 9\n", "pswpout", &v) && v == 9);
95 CHECK(mesh_proc_field("Name:\tmeshd\nVmRSS:\t 123456 kB\nThreads:\t17\n", "VmRSS", &v) && v == 123456);
96 CHECK(mesh_proc_field("Threads:\t17\n", "Threads", &v) && v == 17);
97 CHECK(!mesh_proc_field("Threads:\t17\n", "VmRSS", &v));
98 return mesh_check_done();
99}