|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)iostat.c 5.3 (Berkeley) 1/12/86";
9: #endif not lint
10:
11: /*
12: * iostat
13: */
14: #include "systat.h"
15: #include <sys/buf.h>
16:
17: WINDOW *
18: openiostat()
19: {
20:
21: return (subwin(stdscr, LINES-1-5, 0, 5, 0));
22: }
23:
24: closeiostat(w)
25: WINDOW *w;
26: {
27:
28: if (w == NULL)
29: return;
30: wclear(w);
31: wrefresh(w);
32: delwin(w);
33: }
34:
35: static struct nlist nlst[] = {
36: #define X_DK_BUSY 0
37: { "_dk_busy" },
38: #define X_DK_TIME 1
39: { "_dk_time" },
40: #define X_DK_XFER 2
41: { "_dk_xfer" },
42: #define X_DK_WDS 3
43: { "_dk_wds" },
44: #define X_DK_SEEK 4
45: { "_dk_seek" },
46: #define X_CP_TIME 5
47: { "_cp_time" },
48: #ifdef vax
49: #define X_MBDINIT (X_CP_TIME+1)
50: { "_mbdinit" },
51: #define X_UBDINIT (X_CP_TIME+2)
52: { "_ubdinit" },
53: #endif
54: #ifdef tahoe
55: #define X_VBDINIT (X_CP_TIME+1)
56: { "_vbdinit" },
57: #endif
58: { "" },
59: };
60:
61: static struct {
62: int dk_busy;
63: long cp_time[CPUSTATES];
64: long *dk_time;
65: long *dk_wds;
66: long *dk_seek;
67: long *dk_xfer;
68: } s, s1;
69:
70: static int linesperregion;
71: static double etime;
72: static int numbers = 0; /* default display bar graphs */
73: static int msps = 0; /* default ms/seek shown */
74:
75: initiostat()
76: {
77:
78: if (nlst[X_DK_BUSY].n_type == 0) {
79: nlist("/vmunix", nlst);
80: if (nlst[X_DK_BUSY].n_type == 0) {
81: error("Disk init information isn't in namelist");
82: return(0);
83: }
84: }
85: if (! dkinit())
86: return(0);
87: if (dk_ndrive) {
88: #define allocate(e, t) \
89: s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
90: s1./**/e = (t *)calloc(dk_ndrive, sizeof (t));
91: allocate(dk_time, long);
92: allocate(dk_wds, long);
93: allocate(dk_seek, long);
94: allocate(dk_xfer, long);
95: #undef allocate
96: }
97: return(1);
98: }
99:
100: fetchiostat()
101: {
102:
103: if (nlst[X_DK_BUSY].n_type == 0)
104: return;
105: s.dk_busy = getw(nlst[X_DK_BUSY].n_value);
106: lseek(kmem, (long)nlst[X_DK_TIME].n_value, L_SET);
107: read(kmem, s.dk_time, dk_ndrive * sizeof (long));
108: lseek(kmem, (long)nlst[X_DK_XFER].n_value, L_SET);
109: read(kmem, s.dk_xfer, dk_ndrive * sizeof (long));
110: lseek(kmem, (long)nlst[X_DK_WDS].n_value, L_SET);
111: read(kmem, s.dk_wds, dk_ndrive * sizeof (long));
112: lseek(kmem, (long)nlst[X_DK_SEEK].n_value, L_SET);
113: read(kmem, s.dk_seek, dk_ndrive * sizeof (long));
114: lseek(kmem, (long)nlst[X_CP_TIME].n_value, L_SET);
115: read(kmem, s.cp_time, sizeof s.cp_time);
116: }
117:
118: #define INSET 10
119:
120: labeliostat()
121: {
122: int row;
123:
124: if (nlst[X_DK_BUSY].n_type == 0) {
125: error("No dk_busy defined.");
126: return;
127: }
128: row = 0;
129: wmove(wnd, row, 0); wclrtobot(wnd);
130: mvwaddstr(wnd, row++, INSET,
131: "/0 /10 /20 /30 /40 /50 /60 /70 /80 /90 /100");
132: mvwaddstr(wnd, row++, 0, "cpu user|");
133: mvwaddstr(wnd, row++, 0, " nice|");
134: mvwaddstr(wnd, row++, 0, " system|");
135: mvwaddstr(wnd, row++, 0, " idle|");
136: if (numbers)
137: row = numlabels(row + 1);
138: else
139: row = barlabels(row + 1);
140: }
141:
142: static
143: numlabels(row)
144: {
145: int i, col, regions, ndrives;
146:
147: #define COLWIDTH 14
148: #define DRIVESPERLINE ((wnd->_maxx - INSET) / COLWIDTH)
149: for (ndrives = 0, i = 0; i < dk_ndrive; i++)
150: if (dk_select[i])
151: ndrives++;
152: regions = howmany(ndrives, DRIVESPERLINE);
153: /*
154: * Deduct -regions for blank line after each scrolling region.
155: */
156: linesperregion = (wnd->_maxy - row - regions) / regions;
157: /*
158: * Minimum region contains space for two
159: * label lines and one line of statistics.
160: */
161: if (linesperregion < 3)
162: linesperregion = 3;
163: col = 0;
164: for (i = 0; i < dk_ndrive; i++)
165: if (dk_select[i] && dk_mspw[i] != 0.0) {
166: if (col + COLWIDTH >= wnd->_maxx - INSET) {
167: col = 0, row += linesperregion + 1;
168: if (row > wnd->_maxy - (linesperregion + 1))
169: break;
170: }
171: mvwaddstr(wnd, row, col + 4, dr_name[i]);
172: mvwaddstr(wnd, row + 1, col, "bps tps msps");
173: col += COLWIDTH;
174: }
175: if (col)
176: row += linesperregion + 1;
177: return (row);
178: }
179:
180: static
181: barlabels(row)
182: int row;
183: {
184: int i;
185:
186: mvwaddstr(wnd, row++, INSET,
187: "/0 /5 /10 /15 /20 /25 /30 /35 /40 /45 /50");
188: linesperregion = 2 + msps;
189: for (i = 0; i < dk_ndrive; i++)
190: if (dk_select[i] && dk_mspw[i] != 0.0) {
191: if (row > wnd->_maxy - linesperregion)
192: break;
193: mvwprintw(wnd, row++, 0, "%3.3s bps|", dr_name[i]);
194: mvwaddstr(wnd, row++, 0, " tps|");
195: if (msps)
196: mvwaddstr(wnd, row++, 0, " msps|");
197: }
198: return (row);
199: }
200:
201: showiostat()
202: {
203: register int i, row, col;
204: register long t;
205:
206: if (nlst[X_DK_BUSY].n_type == 0)
207: return;
208: for (i = 0; i < dk_ndrive; i++) {
209: #define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
210: X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
211: }
212: etime = 0;
213: for(i = 0; i < CPUSTATES; i++) {
214: X(cp_time);
215: etime += s.cp_time[i];
216: }
217: if (etime == 0.0)
218: etime = 1.0;
219: etime /= (float) hz;
220: row = 1;
221: for (i = 0; i < CPUSTATES; i++)
222: stat1(row++, i);
223: if (!numbers) {
224: row += 2;
225: for (i = 0; i < dk_ndrive; i++)
226: if (dk_select[i] && dk_mspw[i] != 0.0) {
227: if (row > wnd->_maxy - linesperregion)
228: break;
229: row = stats(row, INSET, i);
230: }
231: return;
232: }
233: col = 0;
234: wmove(wnd, row + linesperregion, 0);
235: wdeleteln(wnd);
236: wmove(wnd, row + 3, 0);
237: winsertln(wnd);
238: for (i = 0; i < dk_ndrive; i++)
239: if (dk_select[i] && dk_mspw[i] != 0.0) {
240: if (col + COLWIDTH >= wnd->_maxx) {
241: col = 0, row += linesperregion + 1;
242: if (row > wnd->_maxy - (linesperregion + 1))
243: break;
244: wmove(wnd, row + linesperregion, 0);
245: wdeleteln(wnd);
246: wmove(wnd, row + 3, 0);
247: winsertln(wnd);
248: }
249: (void) stats(row + 3, col, i);
250: col += COLWIDTH;
251: }
252: }
253:
254: static
255: stats(row, col, dn)
256: int row, dn;
257: {
258: double atime, words, xtime, itime;
259:
260: atime = s.dk_time[dn];
261: atime /= (float) hz;
262: words = s.dk_wds[dn]*32.0; /* number of words transferred */
263: xtime = dk_mspw[dn]*words; /* transfer time */
264: itime = atime - xtime; /* time not transferring */
265: if (xtime < 0)
266: itime += xtime, xtime = 0;
267: if (itime < 0)
268: xtime += itime, itime = 0;
269: if (numbers) {
270: mvwprintw(wnd, row, col, "%3.0f%4.0f%5.1f",
271: words / 512 / etime, s.dk_xfer[dn] / etime,
272: s.dk_seek[dn] ? itime * 1000. / s.dk_seek[dn] : 0.0);
273: return (row);
274: }
275: wmove(wnd, row++, col);
276: histogram(words / 512 / etime, 50, 1.0);
277: wmove(wnd, row++, col);
278: histogram(s.dk_xfer[dn] / etime, 50, 1.0);
279: if (msps) {
280: wmove(wnd, row++, col);
281: histogram(s.dk_seek[dn] ? itime * 1000. / s.dk_seek[dn] : 0,
282: 50, 1.0);
283: }
284: return (row);
285: }
286:
287: static
288: stat1(row, o)
289: int row, o;
290: {
291: register i;
292: double time;
293:
294: time = 0;
295: for (i = 0; i < CPUSTATES; i++)
296: time += s.cp_time[i];
297: if (time == 0.0)
298: time = 1.0;
299: wmove(wnd, row, INSET);
300: #define CPUSCALE 0.5
301: histogram(100 * s.cp_time[o] / time, 50, CPUSCALE);
302: }
303:
304: histogram(val, colwidth, scale)
305: double val;
306: int colwidth;
307: double scale;
308: {
309: char buf[10];
310: register int k;
311: register int v = (int)(val * scale) + 0.5;
312:
313: k = MIN(v, colwidth);
314: if (v > colwidth) {
315: sprintf(buf, "%4.1f", val);
316: k -= strlen(buf);
317: while (k--)
318: waddch(wnd, 'X');
319: waddstr(wnd, buf);
320: return;
321: }
322: while (k--)
323: waddch(wnd, 'X');
324: wclrtoeol(wnd);
325: }
326:
327: cmdiostat(cmd, args)
328: char *cmd, *args;
329: {
330:
331: if (prefix(cmd, "msps"))
332: msps = !msps;
333: else if (prefix(cmd, "numbers"))
334: numbers = 1;
335: else if (prefix(cmd, "bars"))
336: numbers = 0;
337: else if (!dkcmd(cmd, args))
338: return (0);
339: wclear(wnd);
340: labeliostat();
341: refresh();
342: return (1);
343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.