Blame


1 e21fee60 2004-04-23 devnull #include <u.h>
2 e21fee60 2004-04-23 devnull #include <libc.h>
3 e21fee60 2004-04-23 devnull #include <ctype.h>
4 e21fee60 2004-04-23 devnull #include <auth.h>
5 e21fee60 2004-04-23 devnull #include <fcall.h>
6 e21fee60 2004-04-23 devnull #include <draw.h>
7 e21fee60 2004-04-23 devnull #include <thread.h>
8 e21fee60 2004-04-23 devnull #include <mouse.h>
9 e21fee60 2004-04-23 devnull #include <keyboard.h>
10 e21fee60 2004-04-23 devnull
11 e21fee60 2004-04-23 devnull typedef struct Graph Graph;
12 e21fee60 2004-04-23 devnull typedef struct Machine Machine;
13 e21fee60 2004-04-23 devnull
14 e21fee60 2004-04-23 devnull enum
15 e21fee60 2004-04-23 devnull {
16 e21fee60 2004-04-23 devnull Ncolor = 6,
17 e21fee60 2004-04-23 devnull Ysqueeze = 2, /* vertical squeezing of label text */
18 e21fee60 2004-04-23 devnull Labspace = 2, /* room around label */
19 e21fee60 2004-04-23 devnull Dot = 2, /* height of dot */
20 e21fee60 2004-04-23 devnull Opwid = 5, /* strlen("add ") or strlen("drop ") */
21 e21fee60 2004-04-23 devnull Nlab = 3, /* max number of labels on y axis */
22 e21fee60 2004-04-23 devnull Lablen = 16, /* max length of label */
23 e21fee60 2004-04-23 devnull Lx = 4, /* label tick length */
24 e21fee60 2004-04-23 devnull
25 e21fee60 2004-04-23 devnull STACK = 8192,
26 e21fee60 2004-04-23 devnull XSTACK = 32768,
27 e21fee60 2004-04-23 devnull };
28 e21fee60 2004-04-23 devnull
29 e21fee60 2004-04-23 devnull enum
30 e21fee60 2004-04-23 devnull {
31 e21fee60 2004-04-23 devnull Vbattery,
32 e21fee60 2004-04-23 devnull Vcontext,
33 e21fee60 2004-04-23 devnull Vcpu,
34 e21fee60 2004-04-23 devnull Vether,
35 e21fee60 2004-04-23 devnull Vethererr,
36 e21fee60 2004-04-23 devnull Vetherin,
37 e21fee60 2004-04-23 devnull Vetherout,
38 e21fee60 2004-04-23 devnull Vfault,
39 e21fee60 2004-04-23 devnull Vfork,
40 e21fee60 2004-04-23 devnull Vidle,
41 e21fee60 2004-04-23 devnull Vintr,
42 e21fee60 2004-04-23 devnull Vload,
43 e21fee60 2004-04-23 devnull Vmem,
44 e21fee60 2004-04-23 devnull Vswap,
45 e21fee60 2004-04-23 devnull Vsys,
46 e21fee60 2004-04-23 devnull Vsyscall,
47 e21fee60 2004-04-23 devnull Vuser,
48 e21fee60 2004-04-23 devnull Nvalue,
49 e21fee60 2004-04-23 devnull };
50 e21fee60 2004-04-23 devnull
51 e21fee60 2004-04-23 devnull char*
52 e21fee60 2004-04-23 devnull labels[Nvalue] =
53 e21fee60 2004-04-23 devnull {
54 e21fee60 2004-04-23 devnull "battery",
55 e21fee60 2004-04-23 devnull "context",
56 e21fee60 2004-04-23 devnull "cpu",
57 e21fee60 2004-04-23 devnull "ether",
58 e21fee60 2004-04-23 devnull "ethererr",
59 e21fee60 2004-04-23 devnull "etherin",
60 e21fee60 2004-04-23 devnull "etherout",
61 e21fee60 2004-04-23 devnull "fault",
62 e21fee60 2004-04-23 devnull "fork",
63 e21fee60 2004-04-23 devnull "idle",
64 e21fee60 2004-04-23 devnull "intr",
65 e21fee60 2004-04-23 devnull "load",
66 e21fee60 2004-04-23 devnull "mem",
67 e21fee60 2004-04-23 devnull "swap",
68 e21fee60 2004-04-23 devnull "sys",
69 e21fee60 2004-04-23 devnull "syscall",
70 e21fee60 2004-04-23 devnull "user",
71 e21fee60 2004-04-23 devnull };
72 e21fee60 2004-04-23 devnull
73 e21fee60 2004-04-23 devnull struct Graph
74 e21fee60 2004-04-23 devnull {
75 e21fee60 2004-04-23 devnull int colindex;
76 e21fee60 2004-04-23 devnull Rectangle r;
77 e21fee60 2004-04-23 devnull int *data;
78 e21fee60 2004-04-23 devnull int ndata;
79 e21fee60 2004-04-23 devnull char *label;
80 e21fee60 2004-04-23 devnull int value;
81 272fd660 2004-04-23 devnull void (*update)(Graph*, long, ulong);
82 e21fee60 2004-04-23 devnull Machine *mach;
83 e21fee60 2004-04-23 devnull int overflow;
84 e21fee60 2004-04-23 devnull Image *overtmp;
85 e21fee60 2004-04-23 devnull ulong vmax;
86 e21fee60 2004-04-23 devnull };
87 e21fee60 2004-04-23 devnull
88 e21fee60 2004-04-23 devnull struct Machine
89 e21fee60 2004-04-23 devnull {
90 e21fee60 2004-04-23 devnull char *name;
91 e21fee60 2004-04-23 devnull int fd;
92 e21fee60 2004-04-23 devnull int pid;
93 e21fee60 2004-04-23 devnull int dead;
94 e21fee60 2004-04-23 devnull int absolute[Nvalue];
95 e21fee60 2004-04-23 devnull ulong last[Nvalue];
96 e21fee60 2004-04-23 devnull ulong val[Nvalue][2];
97 272fd660 2004-04-23 devnull ulong load;
98 272fd660 2004-04-23 devnull ulong nload;
99 e21fee60 2004-04-23 devnull };
100 e21fee60 2004-04-23 devnull
101 e21fee60 2004-04-23 devnull char *menu2str[Nvalue+1];
102 e21fee60 2004-04-23 devnull char xmenu2str[Nvalue+1][40];
103 e21fee60 2004-04-23 devnull
104 a8763864 2004-07-09 devnull Menu menu2 = {menu2str, 0};
105 e21fee60 2004-04-23 devnull int present[Nvalue];
106 e21fee60 2004-04-23 devnull Image *cols[Ncolor][3];
107 e21fee60 2004-04-23 devnull Graph *graph;
108 e21fee60 2004-04-23 devnull Machine *mach;
109 e21fee60 2004-04-23 devnull Font *mediumfont;
110 e21fee60 2004-04-23 devnull char *mysysname;
111 e21fee60 2004-04-23 devnull char argchars[] = "bceEfiIlmnsw";
112 e21fee60 2004-04-23 devnull int pids[1024];
113 e21fee60 2004-04-23 devnull int parity; /* toggled to avoid patterns in textured background */
114 e21fee60 2004-04-23 devnull int nmach;
115 e21fee60 2004-04-23 devnull int ngraph; /* totaly number is ngraph*nmach */
116 e21fee60 2004-04-23 devnull double scale = 1.0;
117 e21fee60 2004-04-23 devnull int logscale = 0;
118 e21fee60 2004-04-23 devnull int ylabels = 0;
119 e21fee60 2004-04-23 devnull int oldsystem = 0;
120 e21fee60 2004-04-23 devnull int sleeptime = 1000;
121 e21fee60 2004-04-23 devnull int changedvmax;
122 e21fee60 2004-04-23 devnull
123 e21fee60 2004-04-23 devnull Mousectl *mc;
124 e21fee60 2004-04-23 devnull Keyboardctl *kc;
125 e21fee60 2004-04-23 devnull
126 e21fee60 2004-04-23 devnull void
127 e21fee60 2004-04-23 devnull killall(char *s)
128 e21fee60 2004-04-23 devnull {
129 e21fee60 2004-04-23 devnull int i;
130 e21fee60 2004-04-23 devnull
131 e21fee60 2004-04-23 devnull for(i=0; i<nmach; i++)
132 e21fee60 2004-04-23 devnull if(mach[i].pid)
133 e21fee60 2004-04-23 devnull postnote(PNPROC, mach[i].pid, "kill");
134 28aaab76 2005-01-04 devnull threadexitsall(s);
135 e21fee60 2004-04-23 devnull }
136 e21fee60 2004-04-23 devnull
137 e21fee60 2004-04-23 devnull void*
138 e21fee60 2004-04-23 devnull emalloc(ulong sz)
139 e21fee60 2004-04-23 devnull {
140 e21fee60 2004-04-23 devnull void *v;
141 e21fee60 2004-04-23 devnull v = malloc(sz);
142 e21fee60 2004-04-23 devnull if(v == nil) {
143 e21fee60 2004-04-23 devnull fprint(2, "stats: out of memory allocating %ld: %r\n", sz);
144 e21fee60 2004-04-23 devnull killall("mem");
145 e21fee60 2004-04-23 devnull }
146 e21fee60 2004-04-23 devnull memset(v, 0, sz);
147 e21fee60 2004-04-23 devnull return v;
148 e21fee60 2004-04-23 devnull }
149 e21fee60 2004-04-23 devnull
150 e21fee60 2004-04-23 devnull void*
151 e21fee60 2004-04-23 devnull erealloc(void *v, ulong sz)
152 e21fee60 2004-04-23 devnull {
153 e21fee60 2004-04-23 devnull v = realloc(v, sz);
154 e21fee60 2004-04-23 devnull if(v == nil) {
155 e21fee60 2004-04-23 devnull fprint(2, "stats: out of memory reallocating %ld: %r\n", sz);
156 e21fee60 2004-04-23 devnull killall("mem");
157 e21fee60 2004-04-23 devnull }
158 e21fee60 2004-04-23 devnull return v;
159 e21fee60 2004-04-23 devnull }
160 e21fee60 2004-04-23 devnull
161 e21fee60 2004-04-23 devnull char*
162 e21fee60 2004-04-23 devnull estrdup(char *s)
163 e21fee60 2004-04-23 devnull {
164 e21fee60 2004-04-23 devnull char *t;
165 e21fee60 2004-04-23 devnull if((t = strdup(s)) == nil) {
166 e21fee60 2004-04-23 devnull fprint(2, "stats: out of memory in strdup(%.10s): %r\n", s);
167 e21fee60 2004-04-23 devnull killall("mem");
168 e21fee60 2004-04-23 devnull }
169 e21fee60 2004-04-23 devnull return t;
170 e21fee60 2004-04-23 devnull }
171 e21fee60 2004-04-23 devnull
172 e21fee60 2004-04-23 devnull void
173 e21fee60 2004-04-23 devnull mkcol(int i, int c0, int c1, int c2)
174 e21fee60 2004-04-23 devnull {
175 e21fee60 2004-04-23 devnull cols[i][0] = allocimagemix(display, c0, DWhite);
176 e21fee60 2004-04-23 devnull cols[i][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c1);
177 e21fee60 2004-04-23 devnull cols[i][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c2);
178 e21fee60 2004-04-23 devnull }
179 e21fee60 2004-04-23 devnull
180 e21fee60 2004-04-23 devnull void
181 e21fee60 2004-04-23 devnull colinit(void)
182 e21fee60 2004-04-23 devnull {
183 e21fee60 2004-04-23 devnull mediumfont = openfont(display, "/lib/font/bit/pelm/latin1.8.font");
184 e21fee60 2004-04-23 devnull if(mediumfont == nil)
185 e21fee60 2004-04-23 devnull mediumfont = font;
186 e21fee60 2004-04-23 devnull
187 e21fee60 2004-04-23 devnull /* Peach */
188 e21fee60 2004-04-23 devnull mkcol(0, 0xFFAAAAFF, 0xFFAAAAFF, 0xBB5D5DFF);
189 e21fee60 2004-04-23 devnull /* Aqua */
190 e21fee60 2004-04-23 devnull mkcol(1, DPalebluegreen, DPalegreygreen, DPurpleblue);
191 e21fee60 2004-04-23 devnull /* Yellow */
192 e21fee60 2004-04-23 devnull mkcol(2, DPaleyellow, DDarkyellow, DYellowgreen);
193 e21fee60 2004-04-23 devnull /* Green */
194 e21fee60 2004-04-23 devnull mkcol(3, DPalegreen, DMedgreen, DDarkgreen);
195 e21fee60 2004-04-23 devnull /* Blue */
196 e21fee60 2004-04-23 devnull mkcol(4, 0x00AAFFFF, 0x00AAFFFF, 0x0088CCFF);
197 e21fee60 2004-04-23 devnull /* Grey */
198 e21fee60 2004-04-23 devnull cols[5][0] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xEEEEEEFF);
199 e21fee60 2004-04-23 devnull cols[5][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF);
200 e21fee60 2004-04-23 devnull cols[5][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x888888FF);
201 e21fee60 2004-04-23 devnull }
202 e21fee60 2004-04-23 devnull
203 e21fee60 2004-04-23 devnull void
204 e21fee60 2004-04-23 devnull label(Point p, int dy, char *text)
205 e21fee60 2004-04-23 devnull {
206 e21fee60 2004-04-23 devnull char *s;
207 e21fee60 2004-04-23 devnull Rune r[2];
208 e21fee60 2004-04-23 devnull int w, maxw, maxy;
209 e21fee60 2004-04-23 devnull
210 e21fee60 2004-04-23 devnull p.x += Labspace;
211 e21fee60 2004-04-23 devnull maxy = p.y+dy;
212 e21fee60 2004-04-23 devnull maxw = 0;
213 e21fee60 2004-04-23 devnull r[1] = '\0';
214 e21fee60 2004-04-23 devnull for(s=text; *s; ){
215 e21fee60 2004-04-23 devnull if(p.y+mediumfont->height-Ysqueeze > maxy)
216 e21fee60 2004-04-23 devnull break;
217 e21fee60 2004-04-23 devnull w = chartorune(r, s);
218 e21fee60 2004-04-23 devnull s += w;
219 e21fee60 2004-04-23 devnull w = runestringwidth(mediumfont, r);
220 e21fee60 2004-04-23 devnull if(w > maxw)
221 e21fee60 2004-04-23 devnull maxw = w;
222 e21fee60 2004-04-23 devnull runestring(screen, p, display->black, ZP, mediumfont, r);
223 e21fee60 2004-04-23 devnull p.y += mediumfont->height-Ysqueeze;
224 e21fee60 2004-04-23 devnull }
225 e21fee60 2004-04-23 devnull }
226 e21fee60 2004-04-23 devnull
227 e21fee60 2004-04-23 devnull Point
228 e21fee60 2004-04-23 devnull paritypt(int x)
229 e21fee60 2004-04-23 devnull {
230 e21fee60 2004-04-23 devnull return Pt(x+parity, 0);
231 e21fee60 2004-04-23 devnull }
232 e21fee60 2004-04-23 devnull
233 e21fee60 2004-04-23 devnull Point
234 e21fee60 2004-04-23 devnull datapoint(Graph *g, int x, ulong v, ulong vmax)
235 e21fee60 2004-04-23 devnull {
236 e21fee60 2004-04-23 devnull Point p;
237 e21fee60 2004-04-23 devnull double y;
238 e21fee60 2004-04-23 devnull
239 e21fee60 2004-04-23 devnull p.x = x;
240 e21fee60 2004-04-23 devnull y = ((double)v)/(vmax*scale);
241 e21fee60 2004-04-23 devnull if(logscale){
242 e21fee60 2004-04-23 devnull /*
243 e21fee60 2004-04-23 devnull * Arrange scale to cover a factor of 1000.
244 e21fee60 2004-04-23 devnull * vmax corresponds to the 100 mark.
245 e21fee60 2004-04-23 devnull * 10*vmax is the top of the scale.
246 e21fee60 2004-04-23 devnull */
247 e21fee60 2004-04-23 devnull if(y <= 0.)
248 e21fee60 2004-04-23 devnull y = 0;
249 e21fee60 2004-04-23 devnull else{
250 e21fee60 2004-04-23 devnull y = log10(y);
251 e21fee60 2004-04-23 devnull /* 1 now corresponds to the top; -2 to the bottom; rescale */
252 e21fee60 2004-04-23 devnull y = (y+2.)/3.;
253 e21fee60 2004-04-23 devnull }
254 e21fee60 2004-04-23 devnull }
255 e21fee60 2004-04-23 devnull p.y = g->r.max.y - Dy(g->r)*y - Dot;
256 e21fee60 2004-04-23 devnull if(p.y < g->r.min.y)
257 e21fee60 2004-04-23 devnull p.y = g->r.min.y;
258 e21fee60 2004-04-23 devnull if(p.y > g->r.max.y-Dot)
259 e21fee60 2004-04-23 devnull p.y = g->r.max.y-Dot;
260 e21fee60 2004-04-23 devnull return p;
261 e21fee60 2004-04-23 devnull }
262 e21fee60 2004-04-23 devnull
263 e21fee60 2004-04-23 devnull void
264 e21fee60 2004-04-23 devnull drawdatum(Graph *g, int x, ulong prev, ulong v, ulong vmax)
265 e21fee60 2004-04-23 devnull {
266 e21fee60 2004-04-23 devnull int c;
267 e21fee60 2004-04-23 devnull Point p, q;
268 e21fee60 2004-04-23 devnull
269 e21fee60 2004-04-23 devnull c = g->colindex;
270 e21fee60 2004-04-23 devnull p = datapoint(g, x, v, vmax);
271 e21fee60 2004-04-23 devnull q = datapoint(g, x, prev, vmax);
272 e21fee60 2004-04-23 devnull if(p.y < q.y){
273 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, g->r.min.y, p.x+1, p.y), cols[c][0], nil, paritypt(p.x));
274 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, p.y, p.x+1, q.y+Dot), cols[c][2], nil, ZP);
275 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, q.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);
276 e21fee60 2004-04-23 devnull }else{
277 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, g->r.min.y, p.x+1, q.y), cols[c][0], nil, paritypt(p.x));
278 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, q.y, p.x+1, p.y+Dot), cols[c][2], nil, ZP);
279 e21fee60 2004-04-23 devnull draw(screen, Rect(p.x, p.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);
280 e21fee60 2004-04-23 devnull }
281 e21fee60 2004-04-23 devnull
282 e21fee60 2004-04-23 devnull }
283 e21fee60 2004-04-23 devnull
284 e21fee60 2004-04-23 devnull void
285 e21fee60 2004-04-23 devnull redraw(Graph *g, int vmax)
286 e21fee60 2004-04-23 devnull {
287 e21fee60 2004-04-23 devnull int i, c;
288 e21fee60 2004-04-23 devnull
289 e21fee60 2004-04-23 devnull if(vmax != g->vmax){
290 e21fee60 2004-04-23 devnull g->vmax = vmax;
291 e21fee60 2004-04-23 devnull changedvmax = 1;
292 e21fee60 2004-04-23 devnull }
293 e21fee60 2004-04-23 devnull c = g->colindex;
294 e21fee60 2004-04-23 devnull draw(screen, g->r, cols[c][0], nil, paritypt(g->r.min.x));
295 e21fee60 2004-04-23 devnull for(i=1; i<Dx(g->r); i++)
296 e21fee60 2004-04-23 devnull drawdatum(g, g->r.max.x-i, g->data[i-1], g->data[i], vmax);
297 e21fee60 2004-04-23 devnull drawdatum(g, g->r.min.x, g->data[i], g->data[i], vmax);
298 e21fee60 2004-04-23 devnull g->overflow = 0;
299 e21fee60 2004-04-23 devnull }
300 e21fee60 2004-04-23 devnull
301 e21fee60 2004-04-23 devnull void
302 272fd660 2004-04-23 devnull update1(Graph *g, long v, ulong vmax)
303 e21fee60 2004-04-23 devnull {
304 e21fee60 2004-04-23 devnull char buf[32];
305 e21fee60 2004-04-23 devnull int overflow;
306 e21fee60 2004-04-23 devnull
307 272fd660 2004-04-23 devnull if(v < 0)
308 272fd660 2004-04-23 devnull v = 0;
309 e21fee60 2004-04-23 devnull if(vmax != g->vmax){
310 e21fee60 2004-04-23 devnull g->vmax = vmax;
311 e21fee60 2004-04-23 devnull changedvmax = 1;
312 e21fee60 2004-04-23 devnull }
313 e21fee60 2004-04-23 devnull if(g->overflow && g->overtmp!=nil)
314 e21fee60 2004-04-23 devnull draw(screen, g->overtmp->r, g->overtmp, nil, g->overtmp->r.min);
315 e21fee60 2004-04-23 devnull draw(screen, g->r, screen, nil, Pt(g->r.min.x+1, g->r.min.y));
316 e21fee60 2004-04-23 devnull drawdatum(g, g->r.max.x-1, g->data[0], v, vmax);
317 e21fee60 2004-04-23 devnull memmove(g->data+1, g->data, (g->ndata-1)*sizeof(g->data[0]));
318 e21fee60 2004-04-23 devnull g->data[0] = v;
319 e21fee60 2004-04-23 devnull g->overflow = 0;
320 e21fee60 2004-04-23 devnull if(logscale)
321 e21fee60 2004-04-23 devnull overflow = (v>10*vmax*scale);
322 e21fee60 2004-04-23 devnull else
323 e21fee60 2004-04-23 devnull overflow = (v>vmax*scale);
324 e21fee60 2004-04-23 devnull if(overflow && g->overtmp!=nil){
325 e21fee60 2004-04-23 devnull g->overflow = 1;
326 e21fee60 2004-04-23 devnull draw(g->overtmp, g->overtmp->r, screen, nil, g->overtmp->r.min);
327 e21fee60 2004-04-23 devnull sprint(buf, "%ld", v);
328 e21fee60 2004-04-23 devnull string(screen, g->overtmp->r.min, display->black, ZP, mediumfont, buf);
329 e21fee60 2004-04-23 devnull }
330 e21fee60 2004-04-23 devnull }
331 e21fee60 2004-04-23 devnull
332 e21fee60 2004-04-23 devnull void
333 e21fee60 2004-04-23 devnull usage(void)
334 e21fee60 2004-04-23 devnull {
335 be36ff68 2004-04-29 devnull fprint(2, "usage: stats [-O] [-S scale] [-LY] [-W winsize] [-%s] [machine...]\n", argchars);
336 28aaab76 2005-01-04 devnull threadexitsall("usage");
337 e21fee60 2004-04-23 devnull }
338 e21fee60 2004-04-23 devnull
339 e21fee60 2004-04-23 devnull void
340 e21fee60 2004-04-23 devnull addgraph(int n)
341 e21fee60 2004-04-23 devnull {
342 e21fee60 2004-04-23 devnull Graph *g, *ograph;
343 e21fee60 2004-04-23 devnull int i, j;
344 e21fee60 2004-04-23 devnull static int nadd;
345 e21fee60 2004-04-23 devnull
346 e21fee60 2004-04-23 devnull if(n > Nvalue)
347 e21fee60 2004-04-23 devnull abort();
348 e21fee60 2004-04-23 devnull /* avoid two adjacent graphs of same color */
349 e21fee60 2004-04-23 devnull if(ngraph>0 && graph[ngraph-1].colindex==nadd%Ncolor)
350 e21fee60 2004-04-23 devnull nadd++;
351 e21fee60 2004-04-23 devnull ograph = graph;
352 e21fee60 2004-04-23 devnull graph = emalloc(nmach*(ngraph+1)*sizeof(Graph));
353 e21fee60 2004-04-23 devnull for(i=0; i<nmach; i++)
354 e21fee60 2004-04-23 devnull for(j=0; j<ngraph; j++)
355 e21fee60 2004-04-23 devnull graph[i*(ngraph+1)+j] = ograph[i*ngraph+j];
356 e21fee60 2004-04-23 devnull free(ograph);
357 e21fee60 2004-04-23 devnull ngraph++;
358 e21fee60 2004-04-23 devnull for(i=0; i<nmach; i++){
359 e21fee60 2004-04-23 devnull g = &graph[i*ngraph+(ngraph-1)];
360 e21fee60 2004-04-23 devnull memset(g, 0, sizeof(Graph));
361 e21fee60 2004-04-23 devnull g->value = n;
362 e21fee60 2004-04-23 devnull g->label = menu2str[n]+Opwid;
363 e21fee60 2004-04-23 devnull g->update = update1; /* no other update functions yet */
364 e21fee60 2004-04-23 devnull g->mach = &mach[i];
365 e21fee60 2004-04-23 devnull g->colindex = nadd%Ncolor;
366 e21fee60 2004-04-23 devnull }
367 e21fee60 2004-04-23 devnull present[n] = 1;
368 e21fee60 2004-04-23 devnull nadd++;
369 e21fee60 2004-04-23 devnull }
370 e21fee60 2004-04-23 devnull
371 e21fee60 2004-04-23 devnull void
372 e21fee60 2004-04-23 devnull dropgraph(int which)
373 e21fee60 2004-04-23 devnull {
374 e21fee60 2004-04-23 devnull Graph *ograph;
375 e21fee60 2004-04-23 devnull int i, j, n;
376 e21fee60 2004-04-23 devnull
377 e21fee60 2004-04-23 devnull if(which > nelem(menu2str))
378 e21fee60 2004-04-23 devnull abort();
379 e21fee60 2004-04-23 devnull /* convert n to index in graph table */
380 e21fee60 2004-04-23 devnull n = -1;
381 e21fee60 2004-04-23 devnull for(i=0; i<ngraph; i++)
382 e21fee60 2004-04-23 devnull if(strcmp(menu2str[which]+Opwid, graph[i].label) == 0){
383 e21fee60 2004-04-23 devnull n = i;
384 e21fee60 2004-04-23 devnull break;
385 e21fee60 2004-04-23 devnull }
386 e21fee60 2004-04-23 devnull if(n < 0){
387 e21fee60 2004-04-23 devnull fprint(2, "stats: internal error can't drop graph\n");
388 e21fee60 2004-04-23 devnull killall("error");
389 e21fee60 2004-04-23 devnull }
390 e21fee60 2004-04-23 devnull ograph = graph;
391 e21fee60 2004-04-23 devnull graph = emalloc(nmach*(ngraph-1)*sizeof(Graph));
392 e21fee60 2004-04-23 devnull for(i=0; i<nmach; i++){
393 e21fee60 2004-04-23 devnull for(j=0; j<n; j++)
394 e21fee60 2004-04-23 devnull graph[i*(ngraph-1)+j] = ograph[i*ngraph+j];
395 e21fee60 2004-04-23 devnull free(ograph[i*ngraph+j].data);
396 e21fee60 2004-04-23 devnull freeimage(ograph[i*ngraph+j].overtmp);
397 e21fee60 2004-04-23 devnull for(j++; j<ngraph; j++)
398 e21fee60 2004-04-23 devnull graph[i*(ngraph-1)+j-1] = ograph[i*ngraph+j];
399 e21fee60 2004-04-23 devnull }
400 e21fee60 2004-04-23 devnull free(ograph);
401 e21fee60 2004-04-23 devnull ngraph--;
402 e21fee60 2004-04-23 devnull present[which] = 0;
403 e21fee60 2004-04-23 devnull }
404 e21fee60 2004-04-23 devnull
405 e21fee60 2004-04-23 devnull int initmach(Machine*, char*);
406 e21fee60 2004-04-23 devnull
407 e21fee60 2004-04-23 devnull int
408 e21fee60 2004-04-23 devnull addmachine(char *name)
409 e21fee60 2004-04-23 devnull {
410 e21fee60 2004-04-23 devnull if(ngraph > 0){
411 e21fee60 2004-04-23 devnull fprint(2, "stats: internal error: ngraph>0 in addmachine()\n");
412 e21fee60 2004-04-23 devnull usage();
413 e21fee60 2004-04-23 devnull }
414 e21fee60 2004-04-23 devnull if(mach == nil)
415 e21fee60 2004-04-23 devnull nmach = 0; /* a little dance to get us started with local machine by default */
416 e21fee60 2004-04-23 devnull mach = erealloc(mach, (nmach+1)*sizeof(Machine));
417 e21fee60 2004-04-23 devnull memset(mach+nmach, 0, sizeof(Machine));
418 e21fee60 2004-04-23 devnull if (initmach(mach+nmach, name)){
419 e21fee60 2004-04-23 devnull nmach++;
420 e21fee60 2004-04-23 devnull return 1;
421 e21fee60 2004-04-23 devnull } else
422 e21fee60 2004-04-23 devnull return 0;
423 e21fee60 2004-04-23 devnull }
424 e21fee60 2004-04-23 devnull
425 e21fee60 2004-04-23 devnull void
426 e21fee60 2004-04-23 devnull newvalue(Machine *m, int i, ulong *v, ulong *vmax)
427 e21fee60 2004-04-23 devnull {
428 e21fee60 2004-04-23 devnull ulong now;
429 e21fee60 2004-04-23 devnull
430 272fd660 2004-04-23 devnull if(m->last[i] == 0)
431 272fd660 2004-04-23 devnull m->last[i] = m->val[i][0];
432 272fd660 2004-04-23 devnull
433 272fd660 2004-04-23 devnull if(i == Vload){
434 272fd660 2004-04-23 devnull /*
435 272fd660 2004-04-23 devnull * Invert the ewma to obtain the 5s load statistics.
436 272fd660 2004-04-23 devnull * Ewma is load' = (1884/2048)*load + (164/2048)*last5s, so we do
437 272fd660 2004-04-23 devnull * last5s = (load' - (1884/2048)*load) / (164/2048).
438 272fd660 2004-04-23 devnull */
439 272fd660 2004-04-23 devnull if(++m->nload%5 == 0){
440 272fd660 2004-04-23 devnull now = m->val[i][0];
441 272fd660 2004-04-23 devnull m->load = (now - (((vlong)m->last[i]*1884)/2048)) * 2048 / 164;
442 272fd660 2004-04-23 devnull m->last[i] = now;
443 272fd660 2004-04-23 devnull }
444 272fd660 2004-04-23 devnull *v = m->load;
445 272fd660 2004-04-23 devnull *vmax = m->val[i][1];
446 272fd660 2004-04-23 devnull }else if(m->absolute[i]){
447 e21fee60 2004-04-23 devnull *v = m->val[i][0];
448 e21fee60 2004-04-23 devnull *vmax = m->val[i][1];
449 e21fee60 2004-04-23 devnull }else{
450 e21fee60 2004-04-23 devnull now = m->val[i][0];
451 e21fee60 2004-04-23 devnull *v = (vlong)((now - m->last[i])*sleeptime)/1000;
452 e21fee60 2004-04-23 devnull m->last[i] = now;
453 e21fee60 2004-04-23 devnull *vmax = m->val[i][1];
454 e21fee60 2004-04-23 devnull }
455 e21fee60 2004-04-23 devnull if(*vmax == 0)
456 e21fee60 2004-04-23 devnull *vmax = 1;
457 e21fee60 2004-04-23 devnull }
458 e21fee60 2004-04-23 devnull
459 e21fee60 2004-04-23 devnull void
460 e21fee60 2004-04-23 devnull labelstrs(Graph *g, char strs[Nlab][Lablen], int *np)
461 e21fee60 2004-04-23 devnull {
462 e21fee60 2004-04-23 devnull int j;
463 e21fee60 2004-04-23 devnull ulong vmax;
464 e21fee60 2004-04-23 devnull
465 e21fee60 2004-04-23 devnull vmax = g->vmax;
466 e21fee60 2004-04-23 devnull if(logscale){
467 e21fee60 2004-04-23 devnull for(j=1; j<=2; j++)
468 e21fee60 2004-04-23 devnull sprint(strs[j-1], "%g", scale*pow(10., j)*(double)vmax/100.);
469 e21fee60 2004-04-23 devnull *np = 2;
470 e21fee60 2004-04-23 devnull }else{
471 e21fee60 2004-04-23 devnull for(j=1; j<=3; j++)
472 e21fee60 2004-04-23 devnull sprint(strs[j-1], "%g", scale*(double)j*(double)vmax/4.0);
473 e21fee60 2004-04-23 devnull *np = 3;
474 e21fee60 2004-04-23 devnull }
475 e21fee60 2004-04-23 devnull }
476 e21fee60 2004-04-23 devnull
477 e21fee60 2004-04-23 devnull int
478 e21fee60 2004-04-23 devnull labelwidth(void)
479 e21fee60 2004-04-23 devnull {
480 e21fee60 2004-04-23 devnull int i, j, n, w, maxw;
481 e21fee60 2004-04-23 devnull char strs[Nlab][Lablen];
482 e21fee60 2004-04-23 devnull
483 e21fee60 2004-04-23 devnull maxw = 0;
484 e21fee60 2004-04-23 devnull for(i=0; i<ngraph; i++){
485 e21fee60 2004-04-23 devnull /* choose value for rightmost graph */
486 e21fee60 2004-04-23 devnull labelstrs(&graph[ngraph*(nmach-1)+i], strs, &n);
487 e21fee60 2004-04-23 devnull for(j=0; j<n; j++){
488 e21fee60 2004-04-23 devnull w = stringwidth(mediumfont, strs[j]);
489 e21fee60 2004-04-23 devnull if(w > maxw)
490 e21fee60 2004-04-23 devnull maxw = w;
491 e21fee60 2004-04-23 devnull }
492 e21fee60 2004-04-23 devnull }
493 e21fee60 2004-04-23 devnull return maxw;
494 e21fee60 2004-04-23 devnull }
495 e21fee60 2004-04-23 devnull
496 e21fee60 2004-04-23 devnull void
497 e21fee60 2004-04-23 devnull resize(void)
498 e21fee60 2004-04-23 devnull {
499 e21fee60 2004-04-23 devnull int i, j, k, n, startx, starty, x, y, dx, dy, ly, ondata, maxx, wid, nlab;
500 e21fee60 2004-04-23 devnull Graph *g;
501 e21fee60 2004-04-23 devnull Rectangle machr, r;
502 e21fee60 2004-04-23 devnull ulong v, vmax;
503 e21fee60 2004-04-23 devnull char buf[128], labs[Nlab][Lablen];
504 e21fee60 2004-04-23 devnull
505 e21fee60 2004-04-23 devnull draw(screen, screen->r, display->white, nil, ZP);
506 e21fee60 2004-04-23 devnull
507 e21fee60 2004-04-23 devnull /* label left edge */
508 e21fee60 2004-04-23 devnull x = screen->r.min.x;
509 e21fee60 2004-04-23 devnull y = screen->r.min.y + Labspace+mediumfont->height+Labspace;
510 e21fee60 2004-04-23 devnull dy = (screen->r.max.y - y)/ngraph;
511 e21fee60 2004-04-23 devnull dx = Labspace+stringwidth(mediumfont, "0")+Labspace;
512 e21fee60 2004-04-23 devnull startx = x+dx+1;
513 e21fee60 2004-04-23 devnull starty = y;
514 e21fee60 2004-04-23 devnull for(i=0; i<ngraph; i++,y+=dy){
515 e21fee60 2004-04-23 devnull draw(screen, Rect(x, y-1, screen->r.max.x, y), display->black, nil, ZP);
516 e21fee60 2004-04-23 devnull draw(screen, Rect(x, y, x+dx, screen->r.max.y), cols[graph[i].colindex][0], nil, paritypt(x));
517 e21fee60 2004-04-23 devnull label(Pt(x, y), dy, graph[i].label);
518 e21fee60 2004-04-23 devnull draw(screen, Rect(x+dx, y, x+dx+1, screen->r.max.y), cols[graph[i].colindex][2], nil, ZP);
519 e21fee60 2004-04-23 devnull }
520 e21fee60 2004-04-23 devnull
521 e21fee60 2004-04-23 devnull /* label top edge */
522 e21fee60 2004-04-23 devnull dx = (screen->r.max.x - startx)/nmach;
523 e21fee60 2004-04-23 devnull for(x=startx, i=0; i<nmach; i++,x+=dx){
524 e21fee60 2004-04-23 devnull draw(screen, Rect(x-1, starty-1, x, screen->r.max.y), display->black, nil, ZP);
525 e21fee60 2004-04-23 devnull j = dx/stringwidth(mediumfont, "0");
526 e21fee60 2004-04-23 devnull // n = mach[i].nproc;
527 e21fee60 2004-04-23 devnull n = 1;
528 e21fee60 2004-04-23 devnull if(n>1 && j>=1+3+(n>10)+(n>100)){ /* first char of name + (n) */
529 e21fee60 2004-04-23 devnull j -= 3+(n>10)+(n>100);
530 e21fee60 2004-04-23 devnull if(j <= 0)
531 e21fee60 2004-04-23 devnull j = 1;
532 e21fee60 2004-04-23 devnull snprint(buf, sizeof buf, "%.*s(%d)", j, mach[i].name, n);
533 e21fee60 2004-04-23 devnull }else
534 e21fee60 2004-04-23 devnull snprint(buf, sizeof buf, "%.*s", j, mach[i].name);
535 e21fee60 2004-04-23 devnull string(screen, Pt(x+Labspace, screen->r.min.y + Labspace), display->black, ZP, mediumfont, buf);
536 e21fee60 2004-04-23 devnull }
537 e21fee60 2004-04-23 devnull
538 e21fee60 2004-04-23 devnull maxx = screen->r.max.x;
539 e21fee60 2004-04-23 devnull
540 e21fee60 2004-04-23 devnull /* label right, if requested */
541 e21fee60 2004-04-23 devnull if(ylabels && dy>Nlab*(mediumfont->height+1)){
542 e21fee60 2004-04-23 devnull wid = labelwidth();
543 e21fee60 2004-04-23 devnull if(wid < (maxx-startx)-30){
544 e21fee60 2004-04-23 devnull /* else there's not enough room */
545 e21fee60 2004-04-23 devnull maxx -= 1+Lx+wid;
546 e21fee60 2004-04-23 devnull draw(screen, Rect(maxx, starty, maxx+1, screen->r.max.y), display->black, nil, ZP);
547 e21fee60 2004-04-23 devnull y = starty;
548 e21fee60 2004-04-23 devnull for(j=0; j<ngraph; j++, y+=dy){
549 e21fee60 2004-04-23 devnull /* choose value for rightmost graph */
550 e21fee60 2004-04-23 devnull g = &graph[ngraph*(nmach-1)+j];
551 e21fee60 2004-04-23 devnull labelstrs(g, labs, &nlab);
552 e21fee60 2004-04-23 devnull r = Rect(maxx+1, y, screen->r.max.x, y+dy-1);
553 e21fee60 2004-04-23 devnull if(j == ngraph-1)
554 e21fee60 2004-04-23 devnull r.max.y = screen->r.max.y;
555 e21fee60 2004-04-23 devnull draw(screen, r, cols[g->colindex][0], nil, paritypt(r.min.x));
556 e21fee60 2004-04-23 devnull for(k=0; k<nlab; k++){
557 e21fee60 2004-04-23 devnull ly = y + (dy*(nlab-k)/(nlab+1));
558 e21fee60 2004-04-23 devnull draw(screen, Rect(maxx+1, ly, maxx+1+Lx, ly+1), display->black, nil, ZP);
559 e21fee60 2004-04-23 devnull ly -= mediumfont->height/2;
560 e21fee60 2004-04-23 devnull string(screen, Pt(maxx+1+Lx, ly), display->black, ZP, mediumfont, labs[k]);
561 e21fee60 2004-04-23 devnull }
562 e21fee60 2004-04-23 devnull }
563 e21fee60 2004-04-23 devnull }
564 e21fee60 2004-04-23 devnull }
565 e21fee60 2004-04-23 devnull
566 e21fee60 2004-04-23 devnull /* create graphs */
567 e21fee60 2004-04-23 devnull for(i=0; i<nmach; i++){
568 e21fee60 2004-04-23 devnull machr = Rect(startx+i*dx, starty, maxx, screen->r.max.y);
569 e21fee60 2004-04-23 devnull if(i < nmach-1)
570 e21fee60 2004-04-23 devnull machr.max.x = startx+(i+1)*dx - 1;
571 e21fee60 2004-04-23 devnull y = starty;
572 e21fee60 2004-04-23 devnull for(j=0; j<ngraph; j++, y+=dy){
573 e21fee60 2004-04-23 devnull g = &graph[i*ngraph+j];
574 e21fee60 2004-04-23 devnull /* allocate data */
575 e21fee60 2004-04-23 devnull ondata = g->ndata;
576 e21fee60 2004-04-23 devnull g->ndata = Dx(machr)+1; /* may be too many if label will be drawn here; so what? */
577 e21fee60 2004-04-23 devnull g->data = erealloc(g->data, g->ndata*sizeof(ulong));
578 e21fee60 2004-04-23 devnull if(g->ndata > ondata)
579 e21fee60 2004-04-23 devnull memset(g->data+ondata, 0, (g->ndata-ondata)*sizeof(ulong));
580 e21fee60 2004-04-23 devnull /* set geometry */
581 e21fee60 2004-04-23 devnull g->r = machr;
582 e21fee60 2004-04-23 devnull g->r.min.y = y;
583 e21fee60 2004-04-23 devnull g->r.max.y = y+dy - 1;
584 e21fee60 2004-04-23 devnull if(j == ngraph-1)
585 e21fee60 2004-04-23 devnull g->r.max.y = screen->r.max.y;
586 e21fee60 2004-04-23 devnull draw(screen, g->r, cols[g->colindex][0], nil, paritypt(g->r.min.x));
587 e21fee60 2004-04-23 devnull g->overflow = 0;
588 e21fee60 2004-04-23 devnull r = g->r;
589 e21fee60 2004-04-23 devnull r.max.y = r.min.y+mediumfont->height;
590 e21fee60 2004-04-23 devnull r.max.x = r.min.x+stringwidth(mediumfont, "9999999");
591 e21fee60 2004-04-23 devnull freeimage(g->overtmp);
592 e21fee60 2004-04-23 devnull g->overtmp = nil;
593 e21fee60 2004-04-23 devnull if(r.max.x <= g->r.max.x)
594 e21fee60 2004-04-23 devnull g->overtmp = allocimage(display, r, screen->chan, 0, -1);
595 e21fee60 2004-04-23 devnull newvalue(g->mach, g->value, &v, &vmax);
596 e21fee60 2004-04-23 devnull redraw(g, vmax);
597 e21fee60 2004-04-23 devnull }
598 e21fee60 2004-04-23 devnull }
599 e21fee60 2004-04-23 devnull
600 e21fee60 2004-04-23 devnull flushimage(display, 1);
601 e21fee60 2004-04-23 devnull }
602 e21fee60 2004-04-23 devnull
603 e21fee60 2004-04-23 devnull void
604 e21fee60 2004-04-23 devnull eresized(int new)
605 e21fee60 2004-04-23 devnull {
606 e21fee60 2004-04-23 devnull lockdisplay(display);
607 e21fee60 2004-04-23 devnull if(new && getwindow(display, Refnone) < 0) {
608 e21fee60 2004-04-23 devnull fprint(2, "stats: can't reattach to window\n");
609 e21fee60 2004-04-23 devnull killall("reattach");
610 e21fee60 2004-04-23 devnull }
611 e21fee60 2004-04-23 devnull resize();
612 e21fee60 2004-04-23 devnull unlockdisplay(display);
613 e21fee60 2004-04-23 devnull }
614 e21fee60 2004-04-23 devnull
615 e21fee60 2004-04-23 devnull void
616 e21fee60 2004-04-23 devnull mousethread(void *v)
617 e21fee60 2004-04-23 devnull {
618 e21fee60 2004-04-23 devnull Mouse m;
619 e21fee60 2004-04-23 devnull int i;
620 e21fee60 2004-04-23 devnull
621 e21fee60 2004-04-23 devnull USED(v);
622 e21fee60 2004-04-23 devnull
623 e21fee60 2004-04-23 devnull while(readmouse(mc) == 0){
624 e21fee60 2004-04-23 devnull m = mc->m;
625 e21fee60 2004-04-23 devnull if(m.buttons == 4){
626 e21fee60 2004-04-23 devnull for(i=0; i<Nvalue; i++)
627 e21fee60 2004-04-23 devnull if(present[i])
628 e21fee60 2004-04-23 devnull memmove(menu2str[i], "drop ", Opwid);
629 e21fee60 2004-04-23 devnull else
630 e21fee60 2004-04-23 devnull memmove(menu2str[i], "add ", Opwid);
631 e21fee60 2004-04-23 devnull lockdisplay(display);
632 e21fee60 2004-04-23 devnull i = menuhit(3, mc, &menu2, nil);
633 e21fee60 2004-04-23 devnull if(i >= 0){
634 e21fee60 2004-04-23 devnull if(!present[i])
635 e21fee60 2004-04-23 devnull addgraph(i);
636 e21fee60 2004-04-23 devnull else if(ngraph > 1)
637 e21fee60 2004-04-23 devnull dropgraph(i);
638 e21fee60 2004-04-23 devnull resize();
639 e21fee60 2004-04-23 devnull }
640 e21fee60 2004-04-23 devnull unlockdisplay(display);
641 e21fee60 2004-04-23 devnull }
642 e21fee60 2004-04-23 devnull }
643 e21fee60 2004-04-23 devnull }
644 e21fee60 2004-04-23 devnull
645 e21fee60 2004-04-23 devnull void
646 e21fee60 2004-04-23 devnull resizethread(void *v)
647 e21fee60 2004-04-23 devnull {
648 e21fee60 2004-04-23 devnull USED(v);
649 e21fee60 2004-04-23 devnull
650 e21fee60 2004-04-23 devnull while(recv(mc->resizec, 0) == 1){
651 e21fee60 2004-04-23 devnull lockdisplay(display);
652 e21fee60 2004-04-23 devnull if(getwindow(display, Refnone) < 0)
653 e21fee60 2004-04-23 devnull sysfatal("attach to window: %r");
654 e21fee60 2004-04-23 devnull resize();
655 e21fee60 2004-04-23 devnull unlockdisplay(display);
656 e21fee60 2004-04-23 devnull }
657 e21fee60 2004-04-23 devnull }
658 e21fee60 2004-04-23 devnull
659 e21fee60 2004-04-23 devnull void
660 e21fee60 2004-04-23 devnull keyboardthread(void *v)
661 e21fee60 2004-04-23 devnull {
662 e21fee60 2004-04-23 devnull Rune r;
663 e21fee60 2004-04-23 devnull
664 e21fee60 2004-04-23 devnull while(recv(kc->c, &r) == 1)
665 e21fee60 2004-04-23 devnull if(r == 0x7F || r == 'q')
666 e21fee60 2004-04-23 devnull killall("quit");
667 e21fee60 2004-04-23 devnull }
668 e21fee60 2004-04-23 devnull
669 f9979097 2004-12-26 devnull void machproc(void*);
670 f9979097 2004-12-26 devnull void updateproc(void*);
671 e21fee60 2004-04-23 devnull
672 e21fee60 2004-04-23 devnull void
673 e21fee60 2004-04-23 devnull threadmain(int argc, char *argv[])
674 e21fee60 2004-04-23 devnull {
675 e21fee60 2004-04-23 devnull int i, j;
676 e21fee60 2004-04-23 devnull char *s;
677 f9979097 2004-12-26 devnull ulong nargs;
678 e21fee60 2004-04-23 devnull char args[100];
679 e21fee60 2004-04-23 devnull
680 e21fee60 2004-04-23 devnull nmach = 1;
681 e21fee60 2004-04-23 devnull mysysname = sysname();
682 e21fee60 2004-04-23 devnull if(mysysname == nil){
683 e21fee60 2004-04-23 devnull fprint(2, "stats: can't find sysname: %r\n");
684 28aaab76 2005-01-04 devnull threadexitsall("sysname");
685 e21fee60 2004-04-23 devnull }
686 e21fee60 2004-04-23 devnull
687 e21fee60 2004-04-23 devnull nargs = 0;
688 e21fee60 2004-04-23 devnull ARGBEGIN{
689 e21fee60 2004-04-23 devnull case 'T':
690 e21fee60 2004-04-23 devnull s = ARGF();
691 e21fee60 2004-04-23 devnull if(s == nil)
692 e21fee60 2004-04-23 devnull usage();
693 e21fee60 2004-04-23 devnull i = atoi(s);
694 e21fee60 2004-04-23 devnull if(i > 0)
695 e21fee60 2004-04-23 devnull sleeptime = 1000*i;
696 e21fee60 2004-04-23 devnull break;
697 e21fee60 2004-04-23 devnull case 'S':
698 e21fee60 2004-04-23 devnull s = ARGF();
699 e21fee60 2004-04-23 devnull if(s == nil)
700 e21fee60 2004-04-23 devnull usage();
701 e21fee60 2004-04-23 devnull scale = atof(s);
702 e21fee60 2004-04-23 devnull if(scale <= 0.)
703 e21fee60 2004-04-23 devnull usage();
704 e21fee60 2004-04-23 devnull break;
705 e21fee60 2004-04-23 devnull case 'L':
706 e21fee60 2004-04-23 devnull logscale++;
707 e21fee60 2004-04-23 devnull break;
708 e21fee60 2004-04-23 devnull case 'Y':
709 e21fee60 2004-04-23 devnull ylabels++;
710 e21fee60 2004-04-23 devnull break;
711 e21fee60 2004-04-23 devnull case 'O':
712 e21fee60 2004-04-23 devnull oldsystem = 1;
713 e21fee60 2004-04-23 devnull break;
714 be36ff68 2004-04-29 devnull case 'W':
715 be36ff68 2004-04-29 devnull winsize = EARGF(usage());
716 be36ff68 2004-04-29 devnull break;
717 e21fee60 2004-04-23 devnull default:
718 e21fee60 2004-04-23 devnull if(nargs>=sizeof args || strchr(argchars, ARGC())==nil)
719 e21fee60 2004-04-23 devnull usage();
720 e21fee60 2004-04-23 devnull args[nargs++] = ARGC();
721 e21fee60 2004-04-23 devnull }ARGEND
722 e21fee60 2004-04-23 devnull
723 e21fee60 2004-04-23 devnull for(i=0; i<Nvalue; i++){
724 e21fee60 2004-04-23 devnull menu2str[i] = xmenu2str[i];
725 e21fee60 2004-04-23 devnull snprint(xmenu2str[i], sizeof xmenu2str[i], "add %s", labels[i]);
726 e21fee60 2004-04-23 devnull }
727 e21fee60 2004-04-23 devnull
728 e21fee60 2004-04-23 devnull if(argc == 0){
729 e21fee60 2004-04-23 devnull mach = emalloc(nmach*sizeof(Machine));
730 e21fee60 2004-04-23 devnull initmach(&mach[0], mysysname);
731 e21fee60 2004-04-23 devnull }else{
732 e21fee60 2004-04-23 devnull for(i=j=0; i<argc; i++)
733 e21fee60 2004-04-23 devnull addmachine(argv[i]);
734 e21fee60 2004-04-23 devnull }
735 e21fee60 2004-04-23 devnull
736 e21fee60 2004-04-23 devnull for(i=0; i<nmach; i++)
737 f9979097 2004-12-26 devnull proccreate(machproc, &mach[i], STACK);
738 e21fee60 2004-04-23 devnull
739 e21fee60 2004-04-23 devnull for(i=0; i<nargs; i++)
740 e21fee60 2004-04-23 devnull switch(args[i]){
741 e21fee60 2004-04-23 devnull default:
742 e21fee60 2004-04-23 devnull fprint(2, "stats: internal error: unknown arg %c\n", args[i]);
743 e21fee60 2004-04-23 devnull usage();
744 e21fee60 2004-04-23 devnull case 'b':
745 e21fee60 2004-04-23 devnull addgraph(Vbattery);
746 e21fee60 2004-04-23 devnull break;
747 e21fee60 2004-04-23 devnull case 'c':
748 e21fee60 2004-04-23 devnull addgraph(Vcontext);
749 e21fee60 2004-04-23 devnull break;
750 3df0f067 2004-06-09 devnull case 'C':
751 3df0f067 2004-06-09 devnull addgraph(Vcpu);
752 3df0f067 2004-06-09 devnull break;
753 e21fee60 2004-04-23 devnull case 'e':
754 e21fee60 2004-04-23 devnull addgraph(Vether);
755 e21fee60 2004-04-23 devnull break;
756 e21fee60 2004-04-23 devnull case 'E':
757 e21fee60 2004-04-23 devnull addgraph(Vetherin);
758 e21fee60 2004-04-23 devnull addgraph(Vetherout);
759 e21fee60 2004-04-23 devnull break;
760 e21fee60 2004-04-23 devnull case 'f':
761 e21fee60 2004-04-23 devnull addgraph(Vfault);
762 e21fee60 2004-04-23 devnull break;
763 e21fee60 2004-04-23 devnull case 'i':
764 e21fee60 2004-04-23 devnull addgraph(Vintr);
765 e21fee60 2004-04-23 devnull break;
766 e21fee60 2004-04-23 devnull case 'I':
767 e21fee60 2004-04-23 devnull addgraph(Vload);
768 e21fee60 2004-04-23 devnull addgraph(Vidle);
769 e21fee60 2004-04-23 devnull break;
770 e21fee60 2004-04-23 devnull case 'l':
771 e21fee60 2004-04-23 devnull addgraph(Vload);
772 e21fee60 2004-04-23 devnull break;
773 e21fee60 2004-04-23 devnull case 'm':
774 e21fee60 2004-04-23 devnull addgraph(Vmem);
775 e21fee60 2004-04-23 devnull break;
776 e21fee60 2004-04-23 devnull case 'n':
777 e21fee60 2004-04-23 devnull addgraph(Vetherin);
778 e21fee60 2004-04-23 devnull addgraph(Vetherout);
779 e21fee60 2004-04-23 devnull addgraph(Vethererr);
780 e21fee60 2004-04-23 devnull break;
781 e21fee60 2004-04-23 devnull case 's':
782 e21fee60 2004-04-23 devnull addgraph(Vsyscall);
783 e21fee60 2004-04-23 devnull break;
784 e21fee60 2004-04-23 devnull case 'w':
785 e21fee60 2004-04-23 devnull addgraph(Vswap);
786 e21fee60 2004-04-23 devnull break;
787 e21fee60 2004-04-23 devnull }
788 e21fee60 2004-04-23 devnull
789 e21fee60 2004-04-23 devnull if(ngraph == 0)
790 e21fee60 2004-04-23 devnull addgraph(Vload);
791 e21fee60 2004-04-23 devnull
792 e21fee60 2004-04-23 devnull for(i=0; i<nmach; i++)
793 e21fee60 2004-04-23 devnull for(j=0; j<ngraph; j++)
794 e21fee60 2004-04-23 devnull graph[i*ngraph+j].mach = &mach[i];
795 e21fee60 2004-04-23 devnull
796 a8763864 2004-07-09 devnull if(initdraw(0, nil, "stats") < 0)
797 e21fee60 2004-04-23 devnull sysfatal("initdraw: %r");
798 e21fee60 2004-04-23 devnull colinit();
799 272fd660 2004-04-23 devnull if((mc = initmouse(nil, screen)) == nil)
800 e21fee60 2004-04-23 devnull sysfatal("initmouse: %r");
801 e21fee60 2004-04-23 devnull if((kc = initkeyboard(nil)) == nil)
802 e21fee60 2004-04-23 devnull sysfatal("initkeyboard: %r");
803 e21fee60 2004-04-23 devnull
804 e21fee60 2004-04-23 devnull display->locking = 1;
805 e21fee60 2004-04-23 devnull threadcreate(keyboardthread, nil, XSTACK);
806 e21fee60 2004-04-23 devnull threadcreate(mousethread, nil, XSTACK);
807 e21fee60 2004-04-23 devnull threadcreate(resizethread, nil, XSTACK);
808 f9979097 2004-12-26 devnull proccreate(updateproc, nil, XSTACK);
809 e21fee60 2004-04-23 devnull resize();
810 e21fee60 2004-04-23 devnull unlockdisplay(display);
811 f9979097 2004-12-26 devnull }
812 e21fee60 2004-04-23 devnull
813 f9979097 2004-12-26 devnull void
814 f9979097 2004-12-26 devnull updateproc(void *z)
815 f9979097 2004-12-26 devnull {
816 f9979097 2004-12-26 devnull int i;
817 f9979097 2004-12-26 devnull ulong v, vmax;
818 f9979097 2004-12-26 devnull
819 f9979097 2004-12-26 devnull USED(z);
820 e21fee60 2004-04-23 devnull for(;;){
821 e21fee60 2004-04-23 devnull parity = 1-parity;
822 e21fee60 2004-04-23 devnull lockdisplay(display);
823 e21fee60 2004-04-23 devnull for(i=0; i<nmach*ngraph; i++){
824 e21fee60 2004-04-23 devnull newvalue(graph[i].mach, graph[i].value, &v, &vmax);
825 e21fee60 2004-04-23 devnull graph[i].update(&graph[i], v, vmax);
826 e21fee60 2004-04-23 devnull }
827 e21fee60 2004-04-23 devnull if(changedvmax){
828 e21fee60 2004-04-23 devnull changedvmax = 0;
829 e21fee60 2004-04-23 devnull resize();
830 e21fee60 2004-04-23 devnull }
831 e21fee60 2004-04-23 devnull flushimage(display, 1);
832 e21fee60 2004-04-23 devnull unlockdisplay(display);
833 f9979097 2004-12-26 devnull sleep(sleeptime);
834 e21fee60 2004-04-23 devnull }
835 e21fee60 2004-04-23 devnull }
836 e21fee60 2004-04-23 devnull
837 e21fee60 2004-04-23 devnull void
838 f9979097 2004-12-26 devnull machproc(void *v)
839 e21fee60 2004-04-23 devnull {
840 e21fee60 2004-04-23 devnull char buf[256], *f[4], *p;
841 e21fee60 2004-04-23 devnull int i, n, t;
842 e21fee60 2004-04-23 devnull Machine *m;
843 e21fee60 2004-04-23 devnull
844 e21fee60 2004-04-23 devnull m = v;
845 e21fee60 2004-04-23 devnull t = 0;
846 e21fee60 2004-04-23 devnull for(;;){
847 f9979097 2004-12-26 devnull n = read(m->fd, buf+t, sizeof buf-t);
848 e21fee60 2004-04-23 devnull m->dead = 0;
849 e21fee60 2004-04-23 devnull if(n <= 0)
850 e21fee60 2004-04-23 devnull break;
851 e21fee60 2004-04-23 devnull t += n;
852 e21fee60 2004-04-23 devnull while((p = memchr(buf, '\n', t)) != nil){
853 e21fee60 2004-04-23 devnull *p++ = 0;
854 e21fee60 2004-04-23 devnull n = tokenize(buf, f, nelem(f));
855 e21fee60 2004-04-23 devnull if(n >= 3){
856 e21fee60 2004-04-23 devnull for(i=0; i<Nvalue; i++){
857 e21fee60 2004-04-23 devnull if(strcmp(labels[i], f[0]) == 0){
858 e21fee60 2004-04-23 devnull if(*f[1] == '='){
859 e21fee60 2004-04-23 devnull m->absolute[i] = 1;
860 e21fee60 2004-04-23 devnull f[1]++;
861 e21fee60 2004-04-23 devnull }
862 e21fee60 2004-04-23 devnull m->val[i][0] = strtoul(f[1], 0, 0);
863 e21fee60 2004-04-23 devnull m->val[i][1] = strtoul(f[2], 0, 0);
864 e21fee60 2004-04-23 devnull }
865 e21fee60 2004-04-23 devnull }
866 e21fee60 2004-04-23 devnull }
867 e21fee60 2004-04-23 devnull t -= (p-buf);
868 e21fee60 2004-04-23 devnull memmove(buf, p, t);
869 e21fee60 2004-04-23 devnull }
870 e21fee60 2004-04-23 devnull }
871 e21fee60 2004-04-23 devnull if(m->fd){
872 e21fee60 2004-04-23 devnull close(m->fd);
873 e21fee60 2004-04-23 devnull m->fd = -1;
874 e21fee60 2004-04-23 devnull }
875 e21fee60 2004-04-23 devnull if(m->pid){
876 e21fee60 2004-04-23 devnull postnote(PNPROC, m->pid, "kill");
877 e21fee60 2004-04-23 devnull m->pid = 0;
878 e21fee60 2004-04-23 devnull }
879 e21fee60 2004-04-23 devnull }
880 e21fee60 2004-04-23 devnull
881 e21fee60 2004-04-23 devnull int
882 e21fee60 2004-04-23 devnull initmach(Machine *m, char *name)
883 e21fee60 2004-04-23 devnull {
884 e21fee60 2004-04-23 devnull char *args[5], *q;
885 e21fee60 2004-04-23 devnull int p[2], kfd[3], pid;
886 e21fee60 2004-04-23 devnull
887 e21fee60 2004-04-23 devnull m->name = name;
888 e21fee60 2004-04-23 devnull if(strcmp(name, mysysname) == 0)
889 e21fee60 2004-04-23 devnull name = nil;
890 e21fee60 2004-04-23 devnull
891 e21fee60 2004-04-23 devnull if(pipe(p) < 0)
892 e21fee60 2004-04-23 devnull sysfatal("pipe: %r");
893 e21fee60 2004-04-23 devnull
894 e21fee60 2004-04-23 devnull memset(args, 0, sizeof args);
895 b2741617 2004-04-23 devnull args[0] = "auxstats";
896 e21fee60 2004-04-23 devnull if(name){
897 e21fee60 2004-04-23 devnull args[1] = name;
898 e21fee60 2004-04-23 devnull if((q = strchr(name, ':')) != nil){
899 e21fee60 2004-04-23 devnull *q++ = 0;
900 e21fee60 2004-04-23 devnull args[2] = q;
901 e21fee60 2004-04-23 devnull }
902 e21fee60 2004-04-23 devnull }
903 e21fee60 2004-04-23 devnull kfd[0] = open("/dev/null", OREAD);
904 e21fee60 2004-04-23 devnull kfd[1] = p[1];
905 e21fee60 2004-04-23 devnull kfd[2] = dup(2, -1);
906 b2741617 2004-04-23 devnull if((pid = threadspawn(kfd, "auxstats", args)) < 0){
907 e21fee60 2004-04-23 devnull fprint(2, "spawn: %r\n");
908 e21fee60 2004-04-23 devnull close(kfd[0]);
909 e21fee60 2004-04-23 devnull close(p[0]);
910 e21fee60 2004-04-23 devnull close(p[1]);
911 e21fee60 2004-04-23 devnull return 0;
912 e21fee60 2004-04-23 devnull }
913 e21fee60 2004-04-23 devnull m->fd = p[0];
914 e21fee60 2004-04-23 devnull m->pid = pid;
915 e21fee60 2004-04-23 devnull if((q = strchr(m->name, '.')) != nil)
916 e21fee60 2004-04-23 devnull *q = 0;
917 e21fee60 2004-04-23 devnull return 1;
918 e21fee60 2004-04-23 devnull }
919 e21fee60 2004-04-23 devnull