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