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