skip to content
==> 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, &lt);
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, &lt);
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}