==> src/load_text.c <==1/* load.rs text(), field by field. */
2#include "mesh/load_text.h"
3#include "mesh/abi.h"
4#include "mesh/prog_table.h"
5#include "mesh/rsfmt.h"
6
7#include <stdlib.h>
8#include <string.h>
9
10static const uint8_t *H;
11static uint32_t u(size_t o) { return (uint32_t)H[o] | (uint32_t)H[o + 1] << 8 | (uint32_t)H[o + 2] << 16 | (uint32_t)H[o + 3] << 24; }
12static uint64_t u64(size_t o) { return (uint64_t)u(o) | (uint64_t)u(o + 4) << 32; }
13static float f(size_t o) { uint32_t x = u(o); float y; memcpy(&y, &x, 4); return y; }
14
15/* `{:.p}` of an f32 when on, else "-". */
16static void opt(mesh_buf *b, bool on, float v, int p) {
17 if (on) mesh_rs_fixed(b, v, p);
18 else mesh_buf_putc(b, '-');
19}
20static void fx(mesh_buf *b, float v, int p) { mesh_rs_fixed(b, v, p); }
21
22void mesh_load_text(mesh_shared *sh, mesh_buf *out) {
23 uint8_t *hb = malloc(MESH_SNAP_HOST);
24 mesh_host_block_bytes(&sh->host, hb);
25 H = hb;
26 uint32_t flags = u(MESH_S_LOAD_FLAGS);
27 uint64_t at = u64(MESH_S_LOAD_AT_MS);
28 mesh_buf_printf(out, "load samples %u age_ms ", u(MESH_S_LOAD_SAMPLES));
29 if (at == 0) mesh_buf_putc(out, '-');
30 else {
31 uint64_t up = mesh_host_block_uptime_ms(&sh->host);
32 mesh_buf_printf(out, "%llu", (unsigned long long)(up > at ? up - at : 0));
33 }
34 mesh_buf_printf(out, " sample_us %u\n", u(MESH_S_SAMPLE_US));
35 bool g = flags & MESH_LF_GPU;
36 mesh_buf_puts(out, "gpu share ");
37 opt(out, g, f(MESH_S_GPU_SHARE), 3);
38 mesh_buf_puts(out, " share10 ");
39 opt(out, g, f(MESH_S_GPU_SHARE10), 3);
40 mesh_buf_puts(out, " slice_us ");
41 opt(out, g, f(MESH_S_GPU_SLICE_US), 0);
42 mesh_buf_puts(out, " gap_us ");
43 opt(out, g, f(MESH_S_GPU_GAP_US), 0);
44 mesh_buf_puts(out, " max_gap_us ");
45 fx(out, f(MESH_S_GPU_MAX_GAP_US), 0);
46 mesh_buf_puts(out, " gaps_s ");
47 fx(out, f(MESH_S_GPU_GAPS_S), 1);
48 mesh_buf_puts(out, " observed ");
49 fx(out, f(MESH_S_GPU_OBS), 2);
50 mesh_buf_puts(out, " inflate ");
51 opt(out, g, f(MESH_S_GPU_INFLATE), 2);
52 mesh_buf_puts(out, " queue_us ");
53 fx(out, f(MESH_S_GPU_QUEUE_US), 1);
54 mesh_buf_puts(out, " util_ext ");
55 opt(out, flags & MESH_LF_GPU_EXT, f(MESH_S_GPU_UTIL_EXT), 2);
56 mesh_buf_puts(out, "\ncpu util ");
57 fx(out, f(MESH_S_CPU_UTIL), 3);
58 mesh_buf_puts(out, " big ");
59 fx(out, f(MESH_S_CPU_BIG), 3);
60 mesh_buf_puts(out, " little ");
61 fx(out, f(MESH_S_CPU_LITTLE), 3);
62 mesh_buf_puts(out, " iowait ");
63 fx(out, f(MESH_S_CPU_IOWAIT), 3);
64 mesh_buf_printf(out, " cpus %u big %u little %u loadavg ", u(MESH_S_CPUS), u(MESH_S_CPUS_BIG), u(MESH_S_CPUS_LITTLE));
65 fx(out, f(MESH_S_LOADAVG), 2);
66 mesh_buf_putc(out, ' ');
67 fx(out, f(MESH_S_LOADAVG + 4), 2);
68 mesh_buf_putc(out, ' ');
69 fx(out, f(MESH_S_LOADAVG + 8), 2);
70 mesh_buf_puts(out, "\ncores ");
71 uint32_t n = u(MESH_S_CPUS) < MESH_MAX_CPUS ? u(MESH_S_CPUS) : MESH_MAX_CPUS;
72 for (uint32_t i = 0; i < n; i++) {
73 uint8_t cl = H[MESH_S_CORE_CLASS + i], p = H[MESH_S_CORE_UTIL + i];
74 const char *c = cl == 1 ? "B" : cl == 2 ? "L" : "?";
75 if (p == 0xff) mesh_buf_printf(out, "%s%s-", i ? " " : "", c);
76 else mesh_buf_printf(out, "%s%s%u", i ? " " : "", c, p);
77 }
78 mesh_buf_putc(out, '\n');
79 if (flags & MESH_LF_PSI) {
80 const size_t o[8] = {MESH_S_PSI_CPU, MESH_S_PSI_MEM, MESH_S_PSI_MEM_FULL, MESH_S_PSI_IO, MESH_S_PSI_IO_FULL, MESH_S_PSI_CPU10, MESH_S_PSI_MEM10, MESH_S_PSI_IO10};
81 const char *k[8] = {"psi cpu ", " mem ", " mem_full ", " io ", " io_full ", " avg10 cpu ", " mem ", " io "};
82 for (int i = 0; i < 8; i++) { mesh_buf_puts(out, k[i]); fx(out, f(o[i]), 4); }
83 mesh_buf_putc(out, '\n');
84 } else mesh_buf_puts(out, "psi -\n");
85 mesh_buf_printf(out, "mem total_mb %u avail_mb %u free ", u(MESH_S_MEM_TOTAL_MB), u(MESH_S_MEM_AVAIL_MB));
86 fx(out, f(MESH_S_MEM_FREE), 3);
87 mesh_buf_printf(out, " swap_mb %u/%u swap_out_s ", u(MESH_S_SWAP_USED_MB), u(MESH_S_SWAP_TOTAL_MB));
88 fx(out, f(MESH_S_SWAP_OUT_S), 1);
89 mesh_buf_printf(out, " compressed_mb %u level ", u(MESH_S_MEM_COMPRESSED_MB));
90 if (flags & MESH_LF_MEM_LEVEL) mesh_buf_printf(out, "%u", u(MESH_S_MEM_LEVEL));
91 else mesh_buf_putc(out, '-');
92 mesh_buf_puts(out, "\nmeshd cpu ");
93 fx(out, f(MESH_S_MESHD_CPU), 3);
94 mesh_buf_puts(out, " rss_mb ");
95 fx(out, f(MESH_S_MESHD_RSS_MB), 1);
96 mesh_buf_printf(out, " threads %u log_dropped %u\nexec cpu ", u(MESH_S_MESHD_THREADS), u(MESH_S_LOG_DROPPED));
97 fx(out, f(MESH_S_EXEC_CPU), 3);
98 mesh_buf_puts(out, " rss_mb ");
99 mesh_rs_fixed(out, (double)u64(MESH_S_EXEC_RSS) / 1048576.0, 1);
100 mesh_buf_printf(out, " wasm_lanes %u workers %u spawns %u crashes %u\n", u(MESH_S_WASM_LANES), u(MESH_S_WORKERS), u(MESH_S_WORKER_SPAWNS),
101 u(MESH_S_WORKER_CRASHES));
102 mesh_buf_printf(out, "disk free_mb %u total_mb %u\nthermal ", u(MESH_S_DISK_FREE_MB), u(MESH_S_DISK_TOTAL_MB));
103 if (flags & MESH_LF_THERMAL) mesh_buf_puts(out, u(MESH_S_THERMAL) < MESH_THERMAL_STATES_LEN ? MESH_THERMAL_STATES[u(MESH_S_THERMAL)] : "?");
104 else mesh_buf_putc(out, '-');
105 mesh_buf_puts(out, " temp_c ");
106 opt(out, flags & MESH_LF_TEMP, f(MESH_S_TEMP_C), 1);
107 mesh_buf_putc(out, '\n');
108 for (uint32_t s = 0; s < MESH_PROG_SLOTS; s++) {
109 size_t p = mesh_pload(s);
110 uint32_t pf = u(p + MESH_PL_FLAGS);
111 if (!(pf & MESH_PLF_LOADED)) continue;
112 char name[MESH_NAME_BYTES + 1];
113 mesh_pt_name_of(sh->mb, s, name);
114 bool gg = pf & MESH_PLF_GPU, l = pf & MESH_PLF_LAT;
115 mesh_buf_printf(out, "program %s slot %u share ", name, s);
116 opt(out, gg, f(p + MESH_PL_SHARE), 3);
117 mesh_buf_puts(out, " share10 ");
118 opt(out, gg, f(p + MESH_PL_SHARE10), 3);
119 mesh_buf_puts(out, " slice_us ");
120 opt(out, gg, f(p + MESH_PL_SLICE_US), 0);
121 mesh_buf_puts(out, " gap_us ");
122 opt(out, gg, f(p + MESH_PL_GAP_US), 0);
123 mesh_buf_puts(out, " max_gap_us ");
124 fx(out, f(p + MESH_PL_MAX_GAP_US), 0);
125 mesh_buf_puts(out, " observed ");
126 fx(out, f(p + MESH_PL_OBS), 3);
127 mesh_buf_puts(out, " p50_us ");
128 opt(out, l, f(p + MESH_PL_P50_US), 1);
129 mesh_buf_puts(out, " p90_us ");
130 opt(out, l, f(p + MESH_PL_P90_US), 1);
131 mesh_buf_puts(out, " p99_us ");
132 opt(out, l, f(p + MESH_PL_P99_US), 1);
133 mesh_buf_puts(out, " max_us ");
134 opt(out, l, f(p + MESH_PL_MAX_US), 1);
135 mesh_buf_printf(out, " lat_n %u task_us ", u(p + MESH_PL_LAT_N));
136 opt(out, pf & MESH_PLF_TASK, f(p + MESH_PL_TASK_US), 1);
137 mesh_buf_puts(out, " tasks_s ");
138 fx(out, f(p + MESH_PL_TASKS_S), 1);
139 mesh_buf_puts(out, " busy ");
140 fx(out, f(p + MESH_PL_BUSY), 3);
141 mesh_buf_puts(out, " queue_us ");
142 fx(out, f(p + MESH_PL_QUEUE_US), 1);
143 if (pf & MESH_PLF_HOST) {
144 uint32_t ex = mesh_mailbox_get(sh->mb, mesh_prog_ext(s) + MESH_PX_EXEC);
145 mesh_buf_printf(out, " exec %s cpu ", ex < MESH_BACKENDS_LEN ? MESH_BACKENDS[ex] : "?");
146 fx(out, f(p + MESH_PL_CPU), 3);
147 mesh_buf_puts(out, " cpu10 ");
148 fx(out, f(p + MESH_PL_CPU10), 3);
149 mesh_buf_puts(out, " cpu_task_us ");
150 fx(out, f(p + MESH_PL_CPU_TASK_US), 1);
151 mesh_buf_printf(out, " cpu_ms %llu rss_mb ", (unsigned long long)(u64(p + MESH_PL_CPU_NS) / 1000000));
152 mesh_rs_fixed(out, (double)u64(p + MESH_PL_RSS) / 1048576.0, 1);
153 mesh_buf_printf(out, " units %u", u(p + MESH_PL_UNITS));
154 }
155 mesh_buf_putc(out, '\n');
156 }
157 free(hb);
158}