vnconfig.8: Describe autocloning & improve markup
[dragonfly.git] / usr.bin / systat / vmmeter.c
blobd798549e4fa9c172e74d0b46e038cd4afd247e63
1 #define _KERNEL_STRUCTURES
2 #include <sys/param.h>
3 #include <sys/sysctl.h>
4 #include <sys/vmmeter.h>
6 #include <err.h>
7 #include <kinfo.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <devstat.h>
13 #include "systat.h"
14 #include "extern.h"
16 #define X_START 1
17 #define CPU_START 1
18 #define CPU_LABEL_W 7
20 #define DRAW_ROW(n, y, w, fmt, args...) \
21 do { \
22 mvprintw(y, n, fmt, w, args); \
23 n += w; \
24 } while (0)
26 static int vmm_ncpus;
27 static int vmm_fetched;
28 static struct vmmeter *vmm_cur, *vmm_prev;
29 static struct kinfo_cputime *vmm_cptime_cur, *vmm_cptime_prev;
31 static void
32 getvmm(void)
34 size_t sz;
35 int i;
37 for (i = 0; i < vmm_ncpus; ++i) {
38 struct vmmeter *vmm = &vmm_cur[i];
39 char buf[64];
41 sz = sizeof(*vmm);
42 snprintf(buf, sizeof(buf), "vm.cpu%d.vmmeter", i);
43 if (sysctlbyname(buf, vmm, &sz, NULL, 0))
44 err(1, "sysctlbyname(cpu%d)", i);
46 vmm->v_intr -= (vmm->v_timer + vmm->v_ipi);
49 sz = vmm_ncpus * sizeof(struct kinfo_cputime);
50 if (sysctlbyname("kern.cputime", vmm_cptime_cur, &sz, NULL, 0))
51 err(1, "kern.cputime");
54 int
55 initvmm(void)
57 return 1;
60 void
61 showvmm(void)
63 int i, n;
65 if (!vmm_fetched)
66 return;
68 for (i = 0; i < vmm_ncpus; ++i) {
69 struct kinfo_cputime d;
70 uint64_t cp_total = 0;
72 n = X_START + CPU_LABEL_W;
74 #define D(idx, field) \
75 (vmm_cur[idx].field - vmm_prev[idx].field) / (u_int)naptime
77 DRAW_ROW(n, CPU_START + i, 6, "%*u", D(i, v_timer));
78 DRAW_ROW(n, CPU_START + i, 8, "%*u", D(i, v_ipi));
79 DRAW_ROW(n, CPU_START + i, 8, "%*u", D(i, v_intr));
81 #undef D
83 #define CPUD(dif, idx, field) \
84 do { \
85 dif.cp_##field = vmm_cptime_cur[idx].cp_##field - \
86 vmm_cptime_prev[idx].cp_##field; \
87 cp_total += dif.cp_##field; \
88 } while (0)
90 #define CPUV(dif, field) \
91 (dif.cp_##field * 100.0) / cp_total
93 CPUD(d, i, user);
94 CPUD(d, i, idle);
95 CPUD(d, i, intr);
96 CPUD(d, i, nice);
97 CPUD(d, i, sys);
99 if (cp_total == 0)
100 cp_total = 1;
102 DRAW_ROW(n, CPU_START + i, 7, "%*.1f", CPUV(d, user));
103 DRAW_ROW(n, CPU_START + i, 7, "%*.1f", CPUV(d, nice));
104 DRAW_ROW(n, CPU_START + i, 7, "%*.1f", CPUV(d, sys));
105 DRAW_ROW(n, CPU_START + i, 7, "%*.1f", CPUV(d, intr));
106 DRAW_ROW(n, CPU_START + i, 7, "%*.1f", CPUV(d, idle));
108 #undef CPUV
109 #undef CPUD
113 void
114 fetchvmm(void)
116 vmm_fetched = 1;
118 memcpy(vmm_prev, vmm_cur, sizeof(struct vmmeter) * vmm_ncpus);
119 memcpy(vmm_cptime_prev, vmm_cptime_cur,
120 sizeof(struct kinfo_cputime) * vmm_ncpus);
121 getvmm();
124 void
125 labelvmm(void)
127 int i, n;
129 clear();
131 n = X_START + CPU_LABEL_W;
133 DRAW_ROW(n, 0, 6, "%*s", "timer");
134 DRAW_ROW(n, 0, 8, "%*s", "ipi");
135 DRAW_ROW(n, 0, 8, "%*s", "extint");
136 DRAW_ROW(n, 0, 7, "%*s", "user%");
137 DRAW_ROW(n, 0, 7, "%*s", "nice%");
138 DRAW_ROW(n, 0, 7, "%*s", "sys%");
139 DRAW_ROW(n, 0, 7, "%*s", "intr%");
140 DRAW_ROW(n, 0, 7, "%*s", "idle%");
142 for (i = 0; i < vmm_ncpus; ++i)
143 mvprintw(CPU_START + i, X_START, "cpu%d", i);
146 WINDOW *
147 openvmm(void)
149 if (kinfo_get_cpus(&vmm_ncpus))
150 err(1, "kinfo_get_cpus");
152 vmm_cur = calloc(vmm_ncpus, sizeof(*vmm_cur));
153 if (vmm_cur == NULL)
154 err(1, "calloc vmm_cur");
156 vmm_prev = calloc(vmm_ncpus, sizeof(*vmm_prev));
157 if (vmm_prev == NULL)
158 err(1, "calloc vmm_prev");
160 vmm_cptime_cur = calloc(vmm_ncpus, sizeof(*vmm_cptime_cur));
161 if (vmm_cptime_cur == NULL)
162 err(1, "calloc vmm_cptime_cur");
164 vmm_cptime_prev = calloc(vmm_ncpus, sizeof(*vmm_cptime_prev));
165 if (vmm_cptime_prev == NULL)
166 err(1, "calloc vmm_cptime_prev");
168 getvmm();
170 return (stdscr);
173 void
174 closevmm(WINDOW *w)
176 if (vmm_cur != NULL)
177 free(vmm_cur);
178 if (vmm_prev != NULL)
179 free(vmm_prev);
181 if (vmm_cptime_cur != NULL)
182 free(vmm_cptime_cur);
183 if (vmm_cptime_prev != NULL)
184 free(vmm_cptime_prev);
186 vmm_fetched = 0;
188 if (w == NULL)
189 return;
190 wclear(w);
191 wrefresh(w);