1 #define _KERNEL_STRUCTURES
3 #include <sys/sysctl.h>
4 #include <sys/vmmeter.h>
20 #define CPU_STARTX (3 + vmm_ncpus)
23 #define DRAW_ROW(n, y, w, fmt, args...) \
25 mvprintw(y, n, fmt, w - 1, args); \
29 #define DRAW_ROW2(n, y, w, fmt, args...) \
31 mvprintw(y, n, fmt, w - 1, w - 1, args); \
36 static int vmm_fetched;
37 static struct vmmeter vmm_totcur, vmm_totprev;
38 static struct vmmeter *vmm_cur, *vmm_prev;
39 static struct kinfo_cputime *vmm_cptime_cur, *vmm_cptime_prev;
41 static struct save_ctx symctx;
43 static int symbols_read;
52 vmm_totcur.v_intr = 0;
53 vmm_totcur.v_lock_colls = 0;
55 for (i = 0; i < vmm_ncpus; ++i) {
56 struct vmmeter *vmm = &vmm_cur[i];
60 snprintf(buf, sizeof(buf), "vm.cpu%d.vmmeter", i);
61 if (sysctlbyname(buf, vmm, &sz, NULL, 0))
62 err(1, "sysctlbyname(cpu%d)", i);
64 vmm->v_intr -= (vmm->v_timer + vmm->v_ipi);
66 vmm_totcur.v_ipi += vmm->v_ipi;
67 vmm_totcur.v_intr += vmm->v_intr;
68 vmm_totcur.v_lock_colls += vmm->v_lock_colls;
71 sz = vmm_ncpus * sizeof(struct kinfo_cputime);
72 if (sysctlbyname("kern.cputime", vmm_cptime_cur, &sz, NULL, 0))
73 err(1, "kern.cputime");
90 n = X_START + CPU_LABEL_W;
93 (u_int)((vmm_totcur.field - vmm_totprev.field) / naptime)
95 DRAW_ROW(n, TOT_START, 6, "%*s", ""); /* timer */
96 DRAW_ROW(n, TOT_START, 8, "%*u", DTOT(v_ipi));
97 DRAW_ROW(n, TOT_START, 8, "%*u", DTOT(v_intr));
99 DRAW_ROW(n, TOT_START, 6, "%*s", ""); /* user */
100 /* DRAW_ROW(n, TOT_START, 6, "%*s", ""); nice */
101 DRAW_ROW(n, TOT_START, 6, "%*s", ""); /* sys */
102 DRAW_ROW(n, TOT_START, 6, "%*s", ""); /* intr */
103 DRAW_ROW(n, TOT_START, 6, "%*s", ""); /* idle */
104 if (DTOT(v_lock_colls) > 9999999)
105 DRAW_ROW(n, TOT_START, 8, "%*u", 9999999);
107 DRAW_ROW(n, TOT_START, 8, "%*u", DTOT( v_lock_colls));
108 DRAW_ROW2(n, TOT_START, 18, "%*.*s", ""); /* label */
112 for (i = 0; i < vmm_ncpus; ++i) {
113 struct kinfo_cputime d;
114 uint64_t cp_total = 0;
116 n = X_START + CPU_LABEL_W;
118 #define D(idx, field) \
119 (u_int)((vmm_cur[idx].field - vmm_prev[idx].field) / naptime)
121 DRAW_ROW(n, CPU_START + i, 6, "%*u", D(i, v_timer));
122 DRAW_ROW(n, CPU_START + i, 8, "%*u", D(i, v_ipi));
123 DRAW_ROW(n, CPU_START + i, 8, "%*u", D(i, v_intr));
125 #define CPUD(dif, idx, field) \
127 dif.cp_##field = vmm_cptime_cur[idx].cp_##field - \
128 vmm_cptime_prev[idx].cp_##field; \
129 cp_total += dif.cp_##field; \
132 #define CPUV(dif, field) \
133 (dif.cp_##field * 100.0) / cp_total
144 DRAW_ROW(n, CPU_START + i, 6, "%*.1f",
145 CPUV(d, user) + CPUV(d, nice));
146 /* DRAW_ROW(n, CPU_START + i, 6, "%*.1f", CPUV(d, nice));*/
147 DRAW_ROW(n, CPU_START + i, 6, "%*.1f", CPUV(d, sys));
148 DRAW_ROW(n, CPU_START + i, 6, "%*.1f", CPUV(d, intr));
149 DRAW_ROW(n, CPU_START + i, 6, "%*.1f", CPUV(d, idle));
152 * Display token collision count and the last-colliding
155 if (D(i, v_lock_colls) > 9999999)
156 DRAW_ROW(n, CPU_START + i, 8, "%*u", 9999999);
158 DRAW_ROW(n, CPU_START + i, 8, "%*u",
161 if (D(i, v_lock_colls) == 0) {
162 DRAW_ROW2(n, CPU_START + i, 18, "%*.*s", "");
164 DRAW_ROW2(n, CPU_START + i, 18, "%*.*s",
165 vmm_cur[i].v_lock_name);
173 #define CPUC(idx, field) vmm_cptime_cur[idx].cp_##field
174 n = X_START + CPU_LABEL_W;
176 DRAW_ROW(n, CPU_STARTX + i, 15, "%-*s", CPUC(i, msg));
177 DRAW_ROW(n, CPU_STARTX + i, 35, "%-*s",
178 address_to_symbol((void *)(intptr_t)CPUC(i, stallpc),
190 memcpy(vmm_prev, vmm_cur, sizeof(struct vmmeter) * vmm_ncpus);
191 memcpy(vmm_cptime_prev, vmm_cptime_cur,
192 sizeof(struct kinfo_cputime) * vmm_ncpus);
193 vmm_totprev = vmm_totcur;
204 n = X_START + CPU_LABEL_W;
206 DRAW_ROW(n, TOT_START - 1, 6, "%*s", "timer");
207 DRAW_ROW(n, TOT_START - 1, 8, "%*s", "ipi");
208 DRAW_ROW(n, TOT_START - 1, 8, "%*s", "extint");
209 DRAW_ROW(n, TOT_START - 1, 6, "%*s", "user%");
210 /* DRAW_ROW(n, TOT_START - 1, 6, "%*s", "nice%");*/
211 DRAW_ROW(n, TOT_START - 1, 6, "%*s", "sys%");
212 DRAW_ROW(n, TOT_START - 1, 6, "%*s", "intr%");
213 DRAW_ROW(n, TOT_START - 1, 6, "%*s", "idle%");
214 DRAW_ROW(n, TOT_START - 1, 8, "%*s", "smpcol");
215 DRAW_ROW(n, TOT_START - 1, 18, "%*s", "label");
217 mvprintw(TOT_START, X_START, "total");
218 for (i = 0; i < vmm_ncpus; ++i)
219 mvprintw(CPU_START + i, X_START, "cpu%d", i);
222 n = X_START + CPU_LABEL_W;
223 DRAW_ROW(n, TOT_STARTX - 1, 15, "%-*s", "contention");
224 DRAW_ROW(n, TOT_STARTX - 1, 35, "%-*s", "function");
226 for (i = 0; i < vmm_ncpus; ++i)
227 mvprintw(CPU_STARTX + i, X_START, "cpu%d", i);
234 if (symbols_read == 0) {
239 if (kinfo_get_cpus(&vmm_ncpus))
240 err(1, "kinfo_get_cpus");
242 vmm_cur = calloc(vmm_ncpus, sizeof(*vmm_cur));
244 err(1, "calloc vmm_cur");
246 vmm_prev = calloc(vmm_ncpus, sizeof(*vmm_prev));
247 if (vmm_prev == NULL)
248 err(1, "calloc vmm_prev");
250 vmm_cptime_cur = calloc(vmm_ncpus, sizeof(*vmm_cptime_cur));
251 if (vmm_cptime_cur == NULL)
252 err(1, "calloc vmm_cptime_cur");
254 vmm_cptime_prev = calloc(vmm_ncpus, sizeof(*vmm_cptime_prev));
255 if (vmm_cptime_prev == NULL)
256 err(1, "calloc vmm_cptime_prev");
268 if (vmm_prev != NULL)
271 if (vmm_cptime_cur != NULL)
272 free(vmm_cptime_cur);
273 if (vmm_cptime_prev != NULL)
274 free(vmm_cptime_prev);