when printing header after SIGCONT, reset count to next header
[unix-history] / usr / src / usr.sbin / iostat / iostat.c
CommitLineData
d6046558 1static char *sccsid = "@(#)iostat.c 4.12 (Berkeley) 84/11/26";
be974f30
BJ
2/*
3 * iostat
4 */
700789be 5#include <stdio.h>
be974f30 6#include <nlist.h>
700789be
MT
7#include <sys/types.h>
8#include <sys/buf.h>
41b4a915
BS
9#include <sys/dk.h>
10#ifdef vax
4e7e20a4
KM
11#include <vaxuba/ubavar.h>
12#include <vaxmba/mbavar.h>
41b4a915 13#endif
be974f30
BJ
14
15struct nlist nl[] = {
16 { "_dk_busy" },
17#define X_DK_BUSY 0
18 { "_dk_time" },
19#define X_DK_TIME 1
20 { "_dk_xfer" },
21#define X_DK_XFER 2
22 { "_dk_wds" },
23#define X_DK_WDS 3
24 { "_tk_nin" },
25#define X_TK_NIN 4
26 { "_tk_nout" },
27#define X_TK_NOUT 5
28 { "_dk_seek" },
29#define X_DK_SEEK 6
30 { "_cp_time" },
31#define X_CP_TIME 7
32 { "_dk_mspw" },
33#define X_DK_MSPW 8
22f209a2
SL
34 { "_hz" },
35#define X_HZ 9
d66f1fc6
SL
36 { "_phz" },
37#define X_PHZ 10
41b4a915 38#ifdef vax
700789be 39 { "_mbdinit" },
d66f1fc6 40#define X_MBDINIT 11
700789be 41 { "_ubdinit" },
d66f1fc6 42#define X_UBDINIT 12
41b4a915 43#endif
be974f30
BJ
44 { 0 },
45};
700789be
MT
46
47char dr_name[DK_NDRIVE][10];
48
be974f30
BJ
49struct
50{
51 int dk_busy;
52 long cp_time[CPUSTATES];
53 long dk_time[DK_NDRIVE];
54 long dk_wds[DK_NDRIVE];
55 long dk_seek[DK_NDRIVE];
56 long dk_xfer[DK_NDRIVE];
57 float dk_mspw[DK_NDRIVE];
58 long tk_nin;
59 long tk_nout;
60} s, s1;
61
62int mf;
22f209a2 63int hz;
d66f1fc6 64int phz;
be974f30
BJ
65double etime;
66
67main(argc, argv)
68char *argv[];
69{
70 extern char *ctime();
71 register i;
72 int iter;
73 double f1, f2;
74 long t;
8b6704d4 75 int tohdr = 1;
be974f30
BJ
76
77 nlist("/vmunix", nl);
78 if(nl[X_DK_BUSY].n_type == 0) {
79 printf("dk_busy not found in /vmunix namelist\n");
80 exit(1);
81 }
82 mf = open("/dev/kmem", 0);
83 if(mf < 0) {
84 printf("cannot open /dev/kmem\n");
85 exit(1);
86 }
87 iter = 0;
88 while (argc>1&&argv[1][0]=='-') {
89 argc--;
90 argv++;
91 }
92 lseek(mf, (long)nl[X_DK_MSPW].n_value, 0);
93 read(mf, s.dk_mspw, sizeof s.dk_mspw);
700789be
MT
94 for (i = 0; i < DK_NDRIVE; i++)
95 sprintf(dr_name[i], "dk%d", i);
96 read_names();
be974f30
BJ
97 if(argc > 2)
98 iter = atoi(argv[2]);
be974f30 99loop:
8b6704d4 100 if (--tohdr == 0) {
700789be 101 printf(" tty");
8b6704d4
BJ
102 for (i = 0; i < DK_NDRIVE; i++)
103 if (s.dk_mspw[i] != 0.0)
700789be
MT
104 printf(" %3.3s ", dr_name[i]);
105 printf(" cpu\n");
8b6704d4
BJ
106 printf(" tin tout");
107 for (i = 0; i < DK_NDRIVE; i++)
108 if (s.dk_mspw[i] != 0.0)
4e7e20a4 109 printf(" bps tps msps ");
8b6704d4
BJ
110 printf(" us ni sy id\n");
111 tohdr = 19;
112 }
be974f30
BJ
113 lseek(mf, (long)nl[X_DK_BUSY].n_value, 0);
114 read(mf, &s.dk_busy, sizeof s.dk_busy);
115 lseek(mf, (long)nl[X_DK_TIME].n_value, 0);
116 read(mf, s.dk_time, sizeof s.dk_time);
117 lseek(mf, (long)nl[X_DK_XFER].n_value, 0);
118 read(mf, s.dk_xfer, sizeof s.dk_xfer);
119 lseek(mf, (long)nl[X_DK_WDS].n_value, 0);
120 read(mf, s.dk_wds, sizeof s.dk_wds);
121 lseek(mf, (long)nl[X_TK_NIN].n_value, 0);
122 read(mf, &s.tk_nin, sizeof s.tk_nin);
123 lseek(mf, (long)nl[X_TK_NOUT].n_value, 0);
124 read(mf, &s.tk_nout, sizeof s.tk_nout);
125 lseek(mf, (long)nl[X_DK_SEEK].n_value, 0);
126 read(mf, s.dk_seek, sizeof s.dk_seek);
127 lseek(mf, (long)nl[X_CP_TIME].n_value, 0);
128 read(mf, s.cp_time, sizeof s.cp_time);
129 lseek(mf, (long)nl[X_DK_MSPW].n_value, 0);
130 read(mf, s.dk_mspw, sizeof s.dk_mspw);
22f209a2
SL
131 lseek(mf, (long)nl[X_HZ].n_value, 0);
132 read(mf, &hz, sizeof hz);
d66f1fc6
SL
133 lseek(mf, (long)nl[X_PHZ].n_value, 0);
134 read(mf, &phz, sizeof phz);
135 if (phz)
136 hz = phz;
be974f30
BJ
137 for (i = 0; i < DK_NDRIVE; i++) {
138#define X(fld) t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
139 X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
140 }
141 t = s.tk_nin; s.tk_nin -= s1.tk_nin; s1.tk_nin = t;
142 t = s.tk_nout; s.tk_nout -= s1.tk_nout; s1.tk_nout = t;
143 etime = 0;
144 for(i=0; i<CPUSTATES; i++) {
145 X(cp_time);
146 etime += s.cp_time[i];
147 }
148 if (etime == 0.0)
149 etime = 1.0;
22f209a2 150 etime /= (float) hz;
be974f30
BJ
151 printf("%4.0f%5.0f", s.tk_nin/etime, s.tk_nout/etime);
152 for (i=0; i<DK_NDRIVE; i++)
153 if (s.dk_mspw[i] != 0.0)
154 stats(i);
155 for (i=0; i<CPUSTATES; i++)
156 stat1(i);
157 printf("\n");
afebff53 158 fflush(stdout);
be974f30
BJ
159contin:
160 --iter;
161 if(iter)
162 if(argc > 1) {
163 sleep(atoi(argv[1]));
164 goto loop;
165 }
166}
167
168stats(dn)
169{
170 register i;
171 double atime, words, xtime, itime;
172
173 if (s.dk_mspw[dn] == 0.0) {
174 printf("%4.0f%4.0f%5.1f ", 0.0, 0.0, 0.0);
175 return;
176 }
177 atime = s.dk_time[dn];
22f209a2 178 atime /= (float) hz;
be974f30
BJ
179 words = s.dk_wds[dn]*32.0; /* number of words transferred */
180 xtime = s.dk_mspw[dn]*words; /* transfer time */
181 itime = atime - xtime; /* time not transferring */
182/*
183 printf("\ndn %d, words %8.2f, atime %6.2f, xtime %6.2f, itime %6.2f\n",
184 dn, words, atime, xtime, itime);
185*/
186 if (xtime < 0)
187 itime += xtime, xtime = 0;
188 if (itime < 0)
189 xtime += itime, itime = 0;
4e7e20a4 190 printf("%4.0f", words/512/etime);
be974f30
BJ
191 printf("%4.0f", s.dk_xfer[dn]/etime);
192 printf("%5.1f ",
193 s.dk_seek[dn] ? itime*1000./s.dk_seek[dn] : 0.0);
194/*
195 printf("%4.1f",
196 s.dk_xfer[dn] ? xtime*1000./s.dk_xfer[dn] : 0.0);
197*/
198}
199
200stat1(o)
201{
202 register i;
203 double time;
204
205 time = 0;
206 for(i=0; i<CPUSTATES; i++)
207 time += s.cp_time[i];
208 if (time == 0.0)
209 time = 1.0;
afebff53 210 printf("%3.0f", 100.*s.cp_time[o]/time);
be974f30 211}
700789be 212
700789be 213#define steal(where, var) lseek(mf, where, 0); read(mf, &var, sizeof var);
41b4a915
BS
214
215#ifdef vax
700789be
MT
216read_names()
217{
218 struct mba_device mdev;
219 register struct mba_device *mp;
220 struct mba_driver mdrv;
221 short two_char;
222 char *cp = (char *) &two_char;
223 struct uba_device udev, *up;
224 struct uba_driver udrv;
225
226 mp = (struct mba_device *) nl[X_MBDINIT].n_value;
227 up = (struct uba_device *) nl[X_UBDINIT].n_value;
0e22e6c5 228 if (up == 0)
700789be
MT
229 {
230 fprintf(stderr, "iostat: Disk init info not in namelist\n");
231 exit(1);
232 }
41b4a915 233 if (mp) for (;;) {
700789be
MT
234 steal(mp++, mdev);
235 if (mdev.mi_driver == 0)
236 break;
237 if (mdev.mi_dk < 0 || mdev.mi_alive == 0)
238 continue;
239 steal(mdev.mi_driver, mdrv);
240 steal(mdrv.md_dname, two_char);
241 sprintf(dr_name[mdev.mi_dk], "%c%c%d", cp[0], cp[1], mdev.mi_unit);
242 }
41b4a915 243 if (up) for (;;) {
700789be
MT
244 steal(up++, udev);
245 if (udev.ui_driver == 0)
246 break;
247 if (udev.ui_dk < 0 || udev.ui_alive == 0)
248 continue;
249 steal(udev.ui_driver, udrv);
250 steal(udrv.ud_dname, two_char);
251 sprintf(dr_name[udev.ui_dk], "%c%c%d", cp[0], cp[1], udev.ui_unit);
252 }
253}
41b4a915 254#endif