first working version.
[unix-history] / usr / src / usr.bin / systat / iostat.c
CommitLineData
8b38f7fc 1#ifndef lint
d742bf91 2static char sccsid[] = "@(#)iostat.c 1.3 (Lucasfilm) %G%";
8b38f7fc
SL
3#endif
4
5/*
6 * iostat
7 */
8#include "systat.h"
9
10#include <sys/buf.h>
11#include <sys/dk.h>
12#ifdef vax
13#include <vaxuba/ubavar.h>
14#include <vaxmba/mbavar.h>
15#endif
16#ifdef sun
17#include <sundev/mbvar.h>
18#endif
19
20WINDOW *
21openiostat()
22{
23 static WINDOW *w = NULL;
24
25 if (w == NULL)
959d10ab 26 w = newwin(20, 70, 4, 5);
8b38f7fc
SL
27 return (w);
28}
29
30closeiostat(w)
31 WINDOW *w;
32{
33
34 if (w == NULL)
35 return;
36 move(5, 0);
37 clrtobot();
38 wclear(w);
39 wrefresh(w);
40}
41
42static struct nlist nlst[] = {
43#define X_DK_BUSY 0
44 { "_dk_busy" },
45#define X_DK_TIME 1
46 { "_dk_time" },
47#define X_DK_XFER 2
48 { "_dk_xfer" },
49#define X_DK_WDS 3
50 { "_dk_wds" },
51#define X_DK_SEEK 4
52 { "_dk_seek" },
53#define X_CP_TIME 5
54 { "_cp_time" },
55#define X_DK_MSPW 6
56 { "_dk_mspw" },
57#define X_HZ 7
58 { "_hz" },
59
60#ifdef vax
61#define X_MBDINIT 8
62 { "_mbdinit" },
63#define X_UBDINIT 9
64 { "_ubdinit" },
65#endif
66#ifdef sun
67#define X_MBDINIT 8
68 { "_mbdinit" },
69#endif
70 { "" },
71};
72
73char dr_name[DK_NDRIVE][10];
74
75struct {
76 int dk_busy;
77 long cp_time[CPUSTATES];
78 long dk_time[DK_NDRIVE];
79 long dk_wds[DK_NDRIVE];
80 long dk_seek[DK_NDRIVE];
81 long dk_xfer[DK_NDRIVE];
82 float dk_mspw[DK_NDRIVE];
83} s, s1;
84
85int kmem;
86int hz;
87double etime;
88
89initiostat()
90{
91 register i;
92
93 if (nlst[X_DK_BUSY].n_type == 0) {
94 nlist("/vmunix", nlst);
95 if (nlst[X_DK_BUSY].n_type == 0) {
96 error("Disk init information isn't in namelist");
97 return;
98 }
99 }
100 lseek(kmem, (long)nlst[X_DK_MSPW].n_value, L_SET);
101 read(kmem, s.dk_mspw, sizeof s.dk_mspw);
102 for (i = 0; i < DK_NDRIVE; i++)
103 sprintf(dr_name[i], "dk%d", i);
104 lseek(kmem, (long)nlst[X_DK_MSPW].n_value, L_SET);
105 read(kmem, s.dk_mspw, sizeof s.dk_mspw);
106 lseek(kmem, (long)nlst[X_HZ].n_value, L_SET);
107 read(kmem, &hz, sizeof hz);
108 read_names();
109}
110
111fetchiostat()
112{
113
114 if (nlst[X_DK_BUSY].n_type == 0)
115 return;
116 lseek(kmem, (long)nlst[X_DK_BUSY].n_value, L_SET);
117 read(kmem, &s.dk_busy, sizeof s.dk_busy);
118 lseek(kmem, (long)nlst[X_DK_TIME].n_value, L_SET);
119 read(kmem, s.dk_time, sizeof s.dk_time);
120 lseek(kmem, (long)nlst[X_DK_XFER].n_value, L_SET);
121 read(kmem, s.dk_xfer, sizeof s.dk_xfer);
122 lseek(kmem, (long)nlst[X_DK_WDS].n_value, L_SET);
123 read(kmem, s.dk_wds, sizeof s.dk_wds);
124 lseek(kmem, (long)nlst[X_DK_SEEK].n_value, L_SET);
125 read(kmem, s.dk_seek, sizeof s.dk_seek);
126 lseek(kmem, (long)nlst[X_CP_TIME].n_value, L_SET);
127 read(kmem, s.cp_time, sizeof s.cp_time);
128}
129
130labeliostat()
131{
132 register int i, row;
133
134 if (nlst[X_DK_BUSY].n_type == 0) {
135 error("No dk_busy defined.");
136 return;
137 }
138 row = 5;
959d10ab
SL
139 move(row, 0); clrtoeol();
140 mvaddstr(row++, 10,
141 "/0 /10 /20 /30 /40 /50 /60 /70 /80 /90 /100");
8b38f7fc
SL
142 mvaddstr(row++, 0, "cpu user|"); clrtoeol();
143 mvaddstr(row++, 0, " nice|"); clrtoeol();
144 mvaddstr(row++, 0, " system|"); clrtoeol();
145 mvaddstr(row++, 0, " idle|"); clrtoeol();
146 row++;
147 for (i = 0; i < DK_NDRIVE; i++)
148 if (s.dk_mspw[i] != 0.0) {
149 mvprintw(row++, 0, "%3.3s bps|", dr_name[i]);
150 clrtoeol();
151 mvaddstr(row++, 0, " tps|"); clrtoeol();
152 mvaddstr(row++, 0, " mps|"); clrtoeol();
153 }
154}
155
156showiostat()
157{
158 register int i;
159 register long t;
160 int row;
161
162 if (nlst[X_DK_BUSY].n_type == 0)
163 return;
164 for (i = 0; i < DK_NDRIVE; i++) {
165#define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
166 X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
167 }
168 etime = 0;
169 for(i = 0; i < CPUSTATES; i++) {
170 X(cp_time);
171 etime += s.cp_time[i];
172 }
173 if (etime == 0.0)
174 etime = 1.0;
175 etime /= (float) hz;
176 row = 2;
177 for (i = 0; i < CPUSTATES; i++)
178 stat1(row++, i);
179 row++;
180 for (i = 0; i < DK_NDRIVE; i++)
181 if (s.dk_mspw[i] != 0.0)
182 row = stats(row, i);
183}
184
185stats(row, dn)
186 int row, dn;
187{
188 register i;
189 double atime, words, xtime, itime;
190
191 if (s.dk_mspw[dn] == 0.0) {
192 wmove(wnd, row++, 5); wclrtoeol(wnd);
193 wmove(wnd, row++, 5); wclrtoeol(wnd);
194 wmove(wnd, row++, 5); wclrtoeol(wnd);
195 return (row);
196 }
197 atime = s.dk_time[dn];
198 atime /= (float) hz;
199 words = s.dk_wds[dn]*32.0; /* number of words transferred */
200 xtime = s.dk_mspw[dn]*words; /* transfer time */
201 itime = atime - xtime; /* time not transferring */
202 if (xtime < 0)
203 itime += xtime, xtime = 0;
204 if (itime < 0)
205 xtime += itime, itime = 0;
959d10ab
SL
206 wmove(wnd, row++, 5); histogram(words / 512 / etime, 60, 1.0, 'X');
207 wmove(wnd, row++, 5); histogram(s.dk_xfer[dn] / etime, 60, 1.0, 'X');
8b38f7fc 208 wmove(wnd, row++, 5); histogram(s.dk_seek[dn] ?
959d10ab 209 itime * 1000. / s.dk_seek[dn] : 0, 60, 1.0, 'X');
8b38f7fc
SL
210 return (row);
211}
212
213stat1(row, o)
214 int row, o;
215{
216 register i;
217 double time;
218
219 time = 0;
220 for (i = 0; i < CPUSTATES; i++)
221 time += s.cp_time[i];
222 if (time == 0.0)
223 time = 1.0;
959d10ab 224 wmove(wnd, row, 5); histogram(100*s.cp_time[o] / time, 60, 0.5, 'X');
8b38f7fc
SL
225}
226
959d10ab 227histogram(val, colwidth, scale, c)
8b38f7fc
SL
228 double val;
229 int colwidth;
959d10ab 230 double scale;
8b38f7fc
SL
231 char c;
232{
233 char buf[10];
234 register int k;
959d10ab 235 register int v = (int)(val * scale) + 0.5;
8b38f7fc
SL
236
237 k = MIN(v, colwidth);
238 if (v > colwidth) {
d742bf91 239 sprintf(buf, "%4.1f", val);
8b38f7fc
SL
240 k -= strlen(buf);
241 while (k--)
242 waddch(wnd, c);
243 waddstr(wnd, buf);
244 return;
245 }
246 while (k--)
247 waddch(wnd, c);
248 wclrtoeol(wnd);
249}
250
251#define steal(where, var) \
252 lseek(kmem, where, L_SET); read(kmem, &var, sizeof var);
253
254#ifdef vax
255read_names()
256{
257 struct mba_device mdev;
258 register struct mba_device *mp;
259 struct mba_driver mdrv;
260 short two_char;
261 char *cp = (char *) &two_char;
262 struct uba_device udev, *up;
263 struct uba_driver udrv;
264
265 mp = (struct mba_device *) nlst[X_MBDINIT].n_value;
266 up = (struct uba_device *) nlst[X_UBDINIT].n_value;
267 if (up == 0) {
268 error("Disk init info not in namelist\n");
269 return;
270 }
271 if (mp) for (;;) {
272 steal(mp++, mdev);
273 if (mdev.mi_driver == 0)
274 break;
275 if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
276 continue;
277 steal(mdev.mi_driver, mdrv);
278 steal(mdrv.md_dname, two_char);
279 sprintf(dr_name[mdev.mi_dk], "%c%c%d",
280 cp[0], cp[1], mdev.mi_unit);
281 }
282 if (up) for (;;) {
283 steal(up++, udev);
284 if (udev.ui_driver == 0)
285 break;
286 if (udev.ui_dk < 0 || udev.ui_alive == 0)
287 continue;
288 steal(udev.ui_driver, udrv);
289 steal(udrv.ud_dname, two_char);
290 sprintf(dr_name[udev.ui_dk], "%c%c%d",
291 cp[0], cp[1], udev.ui_unit);
292 }
293}
294#endif
295
296#ifdef sun
297read_names()
298{
299 struct mb_device mdev;
300 register struct mb_device *mp;
301 struct mb_driver mdrv;
302 short two_char;
303 char *cp = (char *) &two_char;
304
305 mp = (struct mb_device *) nlst[X_MBDINIT].n_value;
306 if (mp == 0) {
307 error("Disk init info not in namelist\n");
308 return;
309 }
310 for (;;) {
311 steal(mp++, mdev);
312 if (mdev.md_driver == 0)
313 break;
314 if (mdev.md_dk < 0 || mdev.md_alive == 0)
315 continue;
316 steal(mdev.md_driver, mdrv);
317 steal(mdrv.mdr_dname, two_char);
318 sprintf(dr_name[mdev.md_dk], "%c%c%d",
319 cp[0], cp[1], mdev.md_unit);
320 }
321}
322#endif