1 #define _KERNEL_STRUCTURES
3 #include <sys/sysctl.h>
4 #include <sys/vmmeter.h>
19 #define CPU_STARTX (3 + vmm_ncpus)
22 #define DRAW_ROW(n, y, w, fmt, args...) \
24 mvprintw(y, n, fmt, w - 1, args); \
28 #define DRAW_ROW2(n, y, w, fmt, args...) \
30 mvprintw(y, n, fmt, w - 1, w - 1, args); \
35 static int vmm_fetched;
36 static struct vmmeter *vmm_cur, *vmm_prev;
37 static struct kinfo_cputime *vmm_cptime_cur, *vmm_cptime_prev;
39 static struct save_ctx symctx;
41 static int symbols_read;
49 for (i = 0; i < vmm_ncpus; ++i) {
50 struct vmmeter *vmm = &vmm_cur[i];
54 snprintf(buf, sizeof(buf), "vm.cpu%d.vmmeter", i);
55 if (sysctlbyname(buf, vmm, &sz, NULL, 0))
56 err(1, "sysctlbyname(cpu%d)", i);
58 vmm->v_intr -= (vmm->v_timer + vmm->v_ipi);
61 sz = vmm_ncpus * sizeof(struct kinfo_cputime);
62 if (sysctlbyname("kern.cputime", vmm_cptime_cur, &sz, NULL, 0))
63 err(1, "kern.cputime");
80 for (i = 0; i < vmm_ncpus; ++i) {
81 struct kinfo_cputime d;
82 uint64_t cp_total = 0;
84 n = X_START + CPU_LABEL_W;
86 #define D(idx, field) \
87 (vmm_cur[idx].field - vmm_prev[idx].field) / (u_int)naptime
89 DRAW_ROW(n, CPU_START + i, 6, "%*u", D(i, v_timer));
90 DRAW_ROW(n, CPU_START + i, 8, "%*u", D(i, v_ipi));
91 DRAW_ROW(n, CPU_START + i, 8, "%*u", D(i, v_intr));
93 #define CPUD(dif, idx, field) \
95 dif.cp_##field = vmm_cptime_cur[idx].cp_##field - \
96 vmm_cptime_prev[idx].cp_##field; \
97 cp_total += dif.cp_##field; \
100 #define CPUV(dif, field) \
101 (dif.cp_##field * 100.0) / cp_total
112 DRAW_ROW(n, CPU_START + i, 6, "%*.1f",
113 CPUV(d, user) + CPUV(d, nice));
114 /* DRAW_ROW(n, CPU_START + i, 6, "%*.1f", CPUV(d, nice));*/
115 DRAW_ROW(n, CPU_START + i, 6, "%*.1f", CPUV(d, sys));
116 DRAW_ROW(n, CPU_START + i, 6, "%*.1f", CPUV(d, intr));
117 DRAW_ROW(n, CPU_START + i, 6, "%*.1f", CPUV(d, idle));
120 * Display token collision count and the last-colliding
123 if (D(i, v_lock_colls) > 9999999)
124 DRAW_ROW(n, CPU_START + i, 8, "%*u", 9999999);
126 DRAW_ROW(n, CPU_START + i, 8, "%*u",
129 if (D(i, v_lock_colls) == 0) {
130 DRAW_ROW2(n, CPU_START + i, 18, "%*.*s", "");
132 DRAW_ROW2(n, CPU_START + i, 18, "%*.*s",
133 vmm_cur[i].v_lock_name);
139 #define CPUC(idx, field) vmm_cptime_cur[idx].cp_##field
142 n = X_START + CPU_LABEL_W;
144 DRAW_ROW(n, CPU_STARTX + i, 15, "%-*s", CPUC(i, msg));
145 DRAW_ROW(n, CPU_STARTX + i, 35, "%-*s",
146 address_to_symbol((void *)(intptr_t)CPUC(i, stallpc),
158 memcpy(vmm_prev, vmm_cur, sizeof(struct vmmeter) * vmm_ncpus);
159 memcpy(vmm_cptime_prev, vmm_cptime_cur,
160 sizeof(struct kinfo_cputime) * vmm_ncpus);
171 n = X_START + CPU_LABEL_W;
173 DRAW_ROW(n, CPU_START - 1, 6, "%*s", "timer");
174 DRAW_ROW(n, CPU_START - 1, 8, "%*s", "ipi");
175 DRAW_ROW(n, CPU_START - 1, 8, "%*s", "extint");
176 DRAW_ROW(n, CPU_START - 1, 6, "%*s", "user%");
177 /* DRAW_ROW(n, CPU_START - 1, 6, "%*s", "nice%");*/
178 DRAW_ROW(n, CPU_START - 1, 6, "%*s", "sys%");
179 DRAW_ROW(n, CPU_START - 1, 6, "%*s", "intr%");
180 DRAW_ROW(n, CPU_START - 1, 6, "%*s", "idle%");
181 DRAW_ROW(n, CPU_START - 1, 8, "%*s", "smpcol");
182 DRAW_ROW(n, CPU_START - 1, 18, "%*s", "label");
184 for (i = 0; i < vmm_ncpus; ++i)
185 mvprintw(CPU_START + i, X_START, "cpu%d", i);
188 n = X_START + CPU_LABEL_W;
189 DRAW_ROW(n, CPU_STARTX - 1, 15, "%-*s", "contention");
190 DRAW_ROW(n, CPU_STARTX - 1, 35, "%-*s", "function");
192 for (i = 0; i < vmm_ncpus; ++i)
193 mvprintw(CPU_STARTX + i, X_START, "cpu%d", i);
200 if (symbols_read == 0) {
205 if (kinfo_get_cpus(&vmm_ncpus))
206 err(1, "kinfo_get_cpus");
208 vmm_cur = calloc(vmm_ncpus, sizeof(*vmm_cur));
210 err(1, "calloc vmm_cur");
212 vmm_prev = calloc(vmm_ncpus, sizeof(*vmm_prev));
213 if (vmm_prev == NULL)
214 err(1, "calloc vmm_prev");
216 vmm_cptime_cur = calloc(vmm_ncpus, sizeof(*vmm_cptime_cur));
217 if (vmm_cptime_cur == NULL)
218 err(1, "calloc vmm_cptime_cur");
220 vmm_cptime_prev = calloc(vmm_ncpus, sizeof(*vmm_cptime_prev));
221 if (vmm_cptime_prev == NULL)
222 err(1, "calloc vmm_cptime_prev");
234 if (vmm_prev != NULL)
237 if (vmm_cptime_cur != NULL)
238 free(vmm_cptime_cur);
239 if (vmm_cptime_prev != NULL)
240 free(vmm_cptime_prev);