1 static char *sccsid = "@(#)vmstat.c 4.1 (Berkeley) 10/01/80"; 2 #include <stdio.h> 3 #include <sys/param.h> 4 #include <sys/vm.h> 5 #include <sys/dk.h> 6 #include <nlist.h> 7 8 struct nlist nl[] = { 9 #define X_DKBUSY 0 10 { "_dk_busy" }, 11 #define X_DKTIME 1 12 { "_dk_time" }, 13 #define X_DKNUMB 2 14 { "_dk_numb" }, 15 #define X_RATE 3 16 { "_rate" }, 17 #define X_TOTAL 4 18 { "_total" }, 19 #define X_DEFICIT 5 20 { "_deficit" }, 21 #define X_FORKSTAT 6 22 { "_forkstat" }, 23 #define X_SUM 7 24 { "_sum" }, 25 #define X_FIRSTFREE 8 26 { "_firstfree" }, 27 #define X_MAXFREE 9 28 { "_maxfree" }, 29 #define X_BOOTIME 10 30 { "_bootime" }, 31 #ifdef ERNIE 32 #define X_REC 10 33 { "_rectime" }, 34 #define X_PGIN 11 35 { "_pgintime" }, 36 #endif 37 { 0 }, 38 }; 39 40 double stat1(); 41 int firstfree, maxfree; 42 struct 43 { 44 int busy; 45 long etime[CPUSTATES][DK_NSTATES]; 46 long numb[DK_NDRIVE]; 47 struct vmmeter Rate; 48 struct vmtotal Total; 49 struct vmmeter Sum; 50 struct forkstat Forkstat; 51 #ifdef ERNIE 52 unsigned rectime; 53 unsigned pgintime; 54 #endif 55 } s, s1, z; 56 #define rate s.Rate 57 #define total s.Total 58 #define sum s.Sum 59 #define forkstat s.Forkstat 60 61 int iflag = 1; 62 int zero; 63 int deficit; 64 double etime; 65 int mf; 66 67 main(argc, argv) 68 char **argv; 69 { 70 time_t now; 71 int lines; 72 extern char *ctime(); 73 register i,j; 74 int iter, nintv; 75 time_t bootime; 76 double f1, f2; 77 long t; 78 extern char _sobuf[]; 79 80 setbuf(stdout, _sobuf); 81 nlist("/vmunix", nl); 82 if(nl[0].n_type == 0) { 83 printf("no /vmunix namelist\n"); 84 exit(1); 85 } 86 mf = open("/dev/kmem", 0); 87 if(mf < 0) { 88 printf("cannot open /dev/kmem\n"); 89 exit(1); 90 } 91 iter = 0; 92 argc--, argv++; 93 while (argc>0 && argv[0][0]=='-') { 94 char *cp = *argv++; 95 argc--; 96 while (*++cp) switch (*cp) { 97 98 #ifdef ERNIE 99 case 't': 100 dotimes(); 101 exit(0); 102 #endif 103 case 'z': 104 close(mf); 105 mf = open("/dev/kmem", 2); 106 lseek(mf, (long)nl[X_SUM].n_value, 0); 107 write(mf, &z.Sum, sizeof z.Sum); 108 exit(0); 109 110 case 'f': 111 doforkst(); 112 exit(0); 113 114 case 's': 115 dosum(); 116 exit(0); 117 118 case 'i': 119 iflag = 0; 120 break; 121 122 default: 123 fprintf(stderr, "usage: vmstat [ -fs ] [ interval ] [ count]\n"); 124 exit(1); 125 } 126 } 127 if(argc > 1) 128 iter = atoi(argv[1]); 129 lseek(mf, (long)nl[X_FIRSTFREE].n_value, 0); 130 read(mf, &firstfree, sizeof firstfree); 131 lseek(mf, (long)nl[X_MAXFREE].n_value, 0); 132 read(mf, &maxfree, sizeof maxfree); 133 lseek(mf, (long)nl[X_BOOTIME].n_value, 0); 134 read(mf, &bootime, sizeof bootime); 135 time(&now); 136 nintv = now - bootime; 137 if (nintv <= 0 || nintv > 60*60*24*365*10) { 138 printf("Time makes no sense... namelist must be wrong.\n"); 139 exit(1); 140 } 141 reprint: 142 lines = 20; 143 /* s1 = z; */ 144 if (iflag==0) 145 printf("\ 146 Procs Virtual Real Page Swap Disk Cpu\n\ 147 RQ DW PW SW AVM TX FRE RE AT PI PO FR DE SR I O D0 D1 D2 D3 CS US SY ID\n\ 148 "); 149 else 150 printf("\ 151 Procs Memory Page Swap Disk Faults Cpu\n\ 152 R B W AVM FRE RE AT PI PO FR DE SR I O D0 D1 D2 D3 IN SY CS US SY ID\n\ 153 "); 154 loop: 155 lseek(mf, (long)nl[X_DKBUSY].n_value, 0); 156 read(mf, &s.busy, sizeof s.busy); 157 lseek(mf, (long)nl[X_DKTIME].n_value, 0); 158 read(mf, s.etime, sizeof s.etime); 159 lseek(mf, (long)nl[X_DKNUMB].n_value, 0); 160 read(mf, s.numb, sizeof s.numb); 161 if (nintv != 1) { 162 lseek(mf, (long)nl[X_SUM].n_value, 0); 163 read(mf, &rate, sizeof rate); 164 } else { 165 lseek(mf, (long)nl[X_RATE].n_value, 0); 166 read(mf, &rate, sizeof rate); 167 } 168 lseek(mf, (long)nl[X_TOTAL].n_value, 0); 169 read(mf, &total, sizeof total); 170 lseek(mf, (long)nl[X_DEFICIT].n_value, 0); 171 read(mf, &deficit, sizeof deficit); 172 for (i=0; i < DK_NDRIVE; i++) { 173 t = s.numb[i]; 174 s.numb[i] -= s1.numb[i]; 175 s1.numb[i] = t; 176 } 177 for (i=0; i < CPUSTATES; i++) { 178 for (j=0; j < DK_NSTATES; j++) { 179 t = s.etime[i][j]; 180 s.etime[i][j] -= s1.etime[i][j]; 181 s1.etime[i][j] = t; 182 } 183 } 184 t = 0; 185 for (i=0; i < CPUSTATES; i++) 186 for (j=0; j < DK_NSTATES; j++) 187 t += s.etime[i][j]; 188 etime = t; 189 if(etime == 0.) 190 etime = 1.; 191 if (iflag) 192 printf("%2d%2d%2d", total.t_rq, total.t_dw+total.t_pw, 193 total.t_sw); 194 else 195 printf("%2d%3d%3d%3d%3d", total.t_rq, total.t_dw, total.t_pw, 196 total.t_sw); 197 if (iflag) 198 printf("%6d%5d", total.t_avm/2, total.t_free/2); 199 else 200 printf("%6d%3d%5d", total.t_avm/2, 201 pct(total.t_avmtxt, total.t_avm), total.t_free/2); 202 printf("%4d%3d%3d", 203 (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec))/nintv, 204 (rate.v_xsfrec+rate.v_xifrec)/nintv, rate.v_pgin/nintv); 205 printf("%3d%3d%4d%4.1f%2d%2d", rate.v_pgout/nintv, 206 rate.v_dfree/nintv, deficit/2, 207 (60.0 * rate.v_scan) / (LOOPSIZ*nintv), 208 rate.v_swpin/nintv, rate.v_swpout/nintv); 209 etime /= 60.; 210 printf(" "); 211 for(i=0; i<4; i++) 212 stats(i); 213 if (iflag) 214 printf("%4d%4d", (rate.v_intr/nintv) - HZ, 215 rate.v_syscall/nintv); 216 printf("%4d", rate.v_swtch/nintv); 217 for(i=0; i<CPUSTATES; i++) { 218 float f = stat1(i); 219 if (i == 0) { /* US+NI */ 220 i++; 221 f += stat1(i); 222 } 223 printf("%3.0f", f); 224 } 225 printf("\n"); 226 fflush(stdout); 227 contin: 228 nintv = 1; 229 --iter; 230 if(iter) 231 if(argc > 0) { 232 sleep(atoi(argv[0])); 233 if (--lines <= 0) 234 goto reprint; 235 goto loop; 236 } 237 } 238 239 #ifdef ERNIE 240 dotimes() 241 { 242 243 lseek(mf, (long)nl[X_REC].n_value, 0); 244 read(mf, &s.rectime, sizeof s.rectime); 245 lseek(mf, (long)nl[X_PGIN].n_value, 0); 246 read(mf, &s.pgintime, sizeof s.pgintime); 247 lseek(mf, (long)nl[X_SUM].n_value, 0); 248 read(mf, &sum, sizeof sum); 249 printf("%d reclaims, %d total time (usec)\n", sum.v_pgrec, s.rectime); 250 printf("average: %d usec / reclaim\n", s.rectime/sum.v_pgrec); 251 printf("\n"); 252 printf("%d page ins, %d total time (msec)\n",sum.v_pgin, s.pgintime/10); 253 printf("average: %8.1f msec / page in\n", s.pgintime/(sum.v_pgin*10.0)); 254 } 255 #endif 256 257 dosum() 258 { 259 260 lseek(mf, (long)nl[X_SUM].n_value, 0); 261 read(mf, &sum, sizeof sum); 262 printf("%9d swap ins\n", sum.v_swpin); 263 printf("%9d swap outs\n", sum.v_swpout); 264 printf("%9d pages swapped in\n", sum.v_pswpin / CLSIZE); 265 printf("%9d pages swapped out\n", sum.v_pswpout / CLSIZE); 266 printf("%9d total address trans. faults taken\n", sum.v_faults); 267 printf("%9d page ins\n", sum.v_pgin); 268 printf("%9d page outs\n", sum.v_pgout); 269 printf("%9d total reclaims\n", sum.v_pgrec); 270 printf("%9d reclaims from free list\n", sum.v_pgfrec); 271 printf("%9d intransit blocking page faults\n", sum.v_intrans); 272 printf("%9d zero fill pages created\n", sum.v_nzfod / CLSIZE); 273 printf("%9d zero fill page faults\n", sum.v_zfod / CLSIZE); 274 printf("%9d executable fill pages created\n", sum.v_nexfod / CLSIZE); 275 printf("%9d executable fill page faults\n", sum.v_exfod / CLSIZE); 276 printf("%9d swap text pages found in free list\n", sum.v_xsfrec); 277 printf("%9d inode text pages found in free list\n", sum.v_xifrec); 278 printf("%9d file fill pages created\n", sum.v_nvrfod / CLSIZE); 279 printf("%9d file fill page faults\n", sum.v_vrfod / CLSIZE); 280 printf("%9d pages examined by the clock daemon\n", sum.v_scan); 281 printf("%9d revolutions of the clock hand\n", sum.v_rev); 282 printf("%9d pages freed by the clock daemon\n", sum.v_dfree / CLSIZE); 283 printf("%9d cpu context switches\n", sum.v_swtch); 284 printf("%9d device interrupts\n", sum.v_intr); 285 printf("%9d pseduo-dma dz interrupts\n", sum.v_pdma); 286 printf("%9d traps\n", sum.v_trap); 287 printf("%9d system calls\n", sum.v_syscall); 288 } 289 290 291 doforkst() 292 { 293 294 lseek(mf, (long)nl[X_FORKSTAT].n_value, 0); 295 read(mf, &forkstat, sizeof forkstat); 296 printf("%d forks, %d pages, average=%.2f\n", 297 forkstat.cntfork, forkstat.sizfork, 298 (float) forkstat.sizfork / forkstat.cntfork); 299 printf("%d vforks, %d pages, average=%.2f\n", 300 forkstat.cntvfork, forkstat.sizvfork, 301 (float)forkstat.sizvfork / forkstat.cntvfork); 302 } 303 304 stats(dn) 305 { 306 307 if (dn >= DK_NDRIVE) { 308 printf(" 0"); 309 return; 310 } 311 printf("%3.0f", s.numb[dn]/etime); 312 } 313 314 double 315 stat1(row) 316 { 317 register i, j; 318 long t; 319 double f1, f2; 320 321 t = 0; 322 for(i=0; i<CPUSTATES; i++) 323 for(j=0; j<DK_NSTATES; j++) 324 t += s.etime[i][j]; 325 f1 = t; 326 if(f1 == 0.) 327 f1 = 1.; 328 t = 0; 329 for(j=0; j<DK_NSTATES; j++) 330 t += s.etime[row][j]; 331 f2 = t; 332 return(f2*100./f1); 333 } 334 335 pct(top, bot) 336 { 337 338 if (bot == 0) 339 return (0); 340 return ((top * 100) / bot); 341 } 342