1/* Modified by Broadcom Corp. Portions Copyright (c) Broadcom Corp, 2010. */ 2// old: "Copyright 1994 by Henry Ware <al172@yfn.ysu.edu>. Copyleft same year." 3// most code copyright 2002 Albert Cahalan 4// 5// 27/05/2003 (Fabian Frederick) : Add unit conversion + interface 6// Export proc/stat access to libproc 7// Adapt vmstat helpfile 8// 31/05/2003 (Fabian) : Add diskstat support (/libproc) 9// June 2003 (Fabian) : -S <x> -s & -s -S <x> patch 10// June 2003 (Fabian) : -Adding diskstat against 3.1.9, slabinfo 11// -patching 'header' in disk & slab 12// July 2003 (Fabian) : -Adding disk partition output 13// -Adding disk table 14// -Syncing help / usage 15 16#include <stdio.h> 17#include <stdlib.h> 18#include <ctype.h> 19#include <string.h> 20#include <assert.h> 21#include <fcntl.h> 22#include <limits.h> 23#include <termios.h> 24#include <unistd.h> 25#include <sys/types.h> 26#include <sys/ioctl.h> 27#include <sys/dir.h> 28#include <dirent.h> 29 30#include "proc/sysinfo.h" 31#include "proc/version.h" 32 33static unsigned long dataUnit=1024; 34static char szDataUnit [16]; 35#define UNIT_B 1 36#define UNIT_k 1000 37#define UNIT_K 1024 38#define UNIT_m 1000000 39#define UNIT_M 1048576 40 41#define VMSTAT 0 42#define DISKSTAT 0x00000001 43#define VMSUMSTAT 0x00000002 44#define SLABSTAT 0x00000004 45#define PARTITIONSTAT 0x00000008 46#define DISKSUMSTAT 0x00000010 47#define ITLBSTAT 0x00000020 48#define DTLBSTAT 0x00000040 49#define CPUCACHESTAT 0x00000080 50 51static int statMode=VMSTAT; 52 53#define FALSE 0 54#define TRUE 1 55 56static int a_option; /* "-a" means "show active/inactive" */ 57 58static unsigned sleep_time = 1; 59static unsigned long num_updates; 60 61static unsigned int height; // window height 62static unsigned int moreheaders=TRUE; 63 64 65///////////////////////////////////////////////////////////////////////// 66 67static void usage(void) NORETURN; 68static void usage(void) { 69 fprintf(stderr,"usage: vmstat [-V] [-n] [delay [count]]\n"); 70 fprintf(stderr," -V prints version.\n"); 71 fprintf(stderr," -n causes the headers not to be reprinted regularly.\n"); 72 fprintf(stderr," -a print inactive/active page stats.\n"); 73 fprintf(stderr," -d prints disk statistics\n"); 74 fprintf(stderr," -D prints disk table\n"); 75 fprintf(stderr," -p prints disk partition statistics\n"); 76 fprintf(stderr," -s prints vm table\n"); 77 fprintf(stderr," -m prints slabinfo\n"); 78 fprintf(stderr," -S unit size\n"); 79 fprintf(stderr," -I ITLB stats\n"); 80 fprintf(stderr," -P DTLB stats\n"); 81 fprintf(stderr," -C I/D cache stats\n"); 82 fprintf(stderr," delay is the delay between updates in seconds. \n"); 83 fprintf(stderr," unit size k:1000 K:1024 m:1000000 M:1048576 (default is K)\n"); 84 fprintf(stderr," count is the number of updates.\n"); 85 exit(EXIT_FAILURE); 86} 87 88///////////////////////////////////////////////////////////////////////////// 89 90 91//////////////////////////////////////////////////////////////////////////// 92 93static void new_header(void){ 94 printf("procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----"); 95 if (statMode & ITLBSTAT) { 96 printf(" -----------itlb------------"); 97 } else if(statMode & DTLBSTAT) { 98 printf(" -------dtlb--------"); 99 } else if (statMode & CPUCACHESTAT) { 100 printf(" ------------i/d cache-------------"); 101 } 102 printf("\n"); 103 104 printf( 105 "%2s %2s %6s %6s %6s %6s %4s %4s %5s %5s %4s %4s %2s %2s %2s %2s", 106 "r","b", 107 "swpd", "free", a_option?"inact":"buff", a_option?"active":"cache", 108 "si","so", 109 "bi","bo", 110 "in","cs", 111 "us","sy","id","wa" 112 ); 113 114 if (statMode & ITLBSTAT) { 115 printf(" %6s %6s %6s", "ia", "im", "jm"); 116 } else if(statMode & DTLBSTAT) { 117 printf(" %6s %6s", "ja", "jm"); 118 } else if (statMode & CPUCACHESTAT) { 119 printf(" %6s %6s %6s %6s", "ia", "im", "dw", "dm"); 120 } 121 122 printf("\n"); 123} 124 125//////////////////////////////////////////////////////////////////////////// 126 127static unsigned long unitConvert(unsigned int size){ 128 float cvSize; 129 cvSize=(float)size/dataUnit*((statMode==SLABSTAT)?1:1024); 130 return ((unsigned long) cvSize); 131} 132 133//////////////////////////////////////////////////////////////////////////// 134 135static void new_format(int mode) { 136 const char format[]="%2u %2u %6lu %6lu %6lu %6lu %4u %4u %5u %5u %4u %4u %2u %2u %2u %2u"; 137 unsigned int tog=0; /* toggle switch for cleaner code */ 138 unsigned int i; 139 unsigned int hz = Hertz; 140 unsigned int running,blocked,dummy_1,dummy_2; 141 jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2], cpu_iow[2], cpu_xxx[2], cpu_yyy[2], cpu_zzz[2]; 142 jiff duse, dsys, didl, diow, dstl, Div, divo2; 143 unsigned long itlb_access[2], itlb_miss[2], ijtlb_miss[2]; 144 unsigned long itlba, itlbm, ijtlbm; 145 unsigned long djtlb_access[2], djtlb_miss[2]; 146 unsigned long djtlba, djtlbm; 147 unsigned long icache_access[2], icache_miss[2], dcache_wb[2], dcache_miss[2]; 148 unsigned long icachea, icachem, dcachewb, dcachem; 149 unsigned long pgpgin[2], pgpgout[2], pswpin[2], pswpout[2]; 150 unsigned int intr[2], ctxt[2]; 151 unsigned int sleep_half; 152 unsigned long kb_per_page = sysconf(_SC_PAGESIZE) / 1024ul; 153 int debt = 0; // handle idle ticks running backwards 154 155 sleep_half=(sleep_time/2); 156 new_header(); 157 meminfo(); 158 159 getstat(cpu_use,cpu_nic,cpu_sys,cpu_idl,cpu_iow,cpu_xxx,cpu_yyy,cpu_zzz, 160 pgpgin,pgpgout,pswpin,pswpout, 161 intr,ctxt, 162 &running,&blocked, 163 &dummy_1, &dummy_2); 164 165 duse= *cpu_use + *cpu_nic; 166 dsys= *cpu_sys + *cpu_xxx + *cpu_yyy; 167 didl= *cpu_idl; 168 diow= *cpu_iow; 169 dstl= *cpu_zzz; 170 Div= duse+dsys+didl+diow+dstl; 171 divo2= Div/2UL; 172 printf(format, 173 running, blocked, 174 unitConvert(kb_swap_used), unitConvert(kb_main_free), 175 unitConvert(a_option?kb_inactive:kb_main_buffers), 176 unitConvert(a_option?kb_active:kb_main_cached), 177 (unsigned)( (*pswpin * unitConvert(kb_per_page) * hz + divo2) / Div ), 178 (unsigned)( (*pswpout * unitConvert(kb_per_page) * hz + divo2) / Div ), 179 (unsigned)( (*pgpgin * hz + divo2) / Div ), 180 (unsigned)( (*pgpgout * hz + divo2) / Div ), 181 (unsigned)( (*intr * hz + divo2) / Div ), 182 (unsigned)( (*ctxt * hz + divo2) / Div ), 183 (unsigned)( (100*duse + divo2) / Div ), 184 (unsigned)( (100*dsys + divo2) / Div ), 185 (unsigned)( (100*didl + divo2) / Div ), 186 (unsigned)( (100*diow + divo2) / Div ) /* , 187 (unsigned)( (100*dstl + divo2) / Div ) */ 188 ); 189 190 if (mode & ITLBSTAT) { 191 const char format[] = " %6lu %6lu %6lu"; 192 193 getitlbstat(itlb_access, itlb_miss, ijtlb_miss); 194 195 printf(format, *itlb_access, *itlb_miss, *ijtlb_miss); 196 } else if (mode & DTLBSTAT) { 197 const char format[] = " %6lu %6lu"; 198 199 getdjtlbstat(djtlb_access, djtlb_miss); 200 201 printf(format, *djtlb_access, *djtlb_miss); 202 } else if (mode & CPUCACHESTAT) { 203 const char format[] = " %6lu %6lu %6lu %6lu"; 204 205 getcpucachestat(icache_access, icache_miss, dcache_wb, dcache_miss); 206 207 printf(format, *icache_access, *icache_miss, *dcache_wb, *dcache_miss); 208 } 209 210 printf("\n"); 211 212 for(i=1;i<num_updates;i++) { /* \\\\\\\\\\\\\\\\\\\\ main loop ////////////////// */ 213 sleep(sleep_time); 214 if (moreheaders && ((i%height)==0)) new_header(); 215 tog= !tog; 216 217 meminfo(); 218 219 getstat(cpu_use+tog,cpu_nic+tog,cpu_sys+tog,cpu_idl+tog,cpu_iow+tog,cpu_xxx+tog,cpu_yyy+tog,cpu_zzz+tog, 220 pgpgin+tog,pgpgout+tog,pswpin+tog,pswpout+tog, 221 intr+tog,ctxt+tog, 222 &running,&blocked, 223 &dummy_1,&dummy_2); 224 225 duse= cpu_use[tog]-cpu_use[!tog] + cpu_nic[tog]-cpu_nic[!tog]; 226 dsys= cpu_sys[tog]-cpu_sys[!tog] + cpu_xxx[tog]-cpu_xxx[!tog] + cpu_yyy[tog]-cpu_yyy[!tog]; 227 didl= cpu_idl[tog]-cpu_idl[!tog]; 228 diow= cpu_iow[tog]-cpu_iow[!tog]; 229 dstl= cpu_zzz[tog]-cpu_zzz[!tog]; 230 231 /* idle can run backwards for a moment -- kernel "feature" */ 232 if(debt){ 233 didl = (int)didl + debt; 234 debt = 0; 235 } 236 if( (int)didl < 0 ){ 237 debt = (int)didl; 238 didl = 0; 239 } 240 241 Div= duse+dsys+didl+diow+dstl; 242 divo2= Div/2UL; 243 printf(format, 244 running, blocked, 245 unitConvert(kb_swap_used),unitConvert(kb_main_free), 246 unitConvert(a_option?kb_inactive:kb_main_buffers), 247 unitConvert(a_option?kb_active:kb_main_cached), 248 (unsigned)( ( (pswpin [tog] - pswpin [!tog])*unitConvert(kb_per_page)+sleep_half )/sleep_time ), /*si*/ 249 (unsigned)( ( (pswpout[tog] - pswpout[!tog])*unitConvert(kb_per_page)+sleep_half )/sleep_time ), /*so*/ 250 (unsigned)( ( pgpgin [tog] - pgpgin [!tog] +sleep_half )/sleep_time ), /*bi*/ 251 (unsigned)( ( pgpgout[tog] - pgpgout[!tog] +sleep_half )/sleep_time ), /*bo*/ 252 (unsigned)( ( intr [tog] - intr [!tog] +sleep_half )/sleep_time ), /*in*/ 253 (unsigned)( ( ctxt [tog] - ctxt [!tog] +sleep_half )/sleep_time ), /*cs*/ 254 (unsigned)( (100*duse+divo2)/Div ), /*us*/ 255 (unsigned)( (100*dsys+divo2)/Div ), /*sy*/ 256 (unsigned)( (100*didl+divo2)/Div ), /*id*/ 257 (unsigned)( (100*diow+divo2)/Div )/*, //wa 258 (unsigned)( (100*dstl+divo2)/Div ) //st */ 259 ); 260 261 if (mode & ITLBSTAT) { 262 const char format[] = " %6lu %6lu %6lu"; 263 264 getitlbstat(itlb_access+tog, itlb_miss+tog, ijtlb_miss+tog); 265 266 itlba = itlb_access[tog]-itlb_access[!tog]; 267 itlbm = itlb_miss[tog]-itlb_miss[!tog]; 268 ijtlbm = ijtlb_miss[tog]-ijtlb_miss[!tog]; 269 printf(format, itlba, itlbm, ijtlbm); 270 271 } else if (mode & DTLBSTAT) { 272 const char format[] = " %6lu %6lu"; 273 274 getdjtlbstat(djtlb_access+tog, djtlb_miss+tog); 275 276 djtlba = djtlb_access[tog]-djtlb_access[!tog]; 277 djtlbm = djtlb_miss[tog]-djtlb_miss[!tog]; 278 printf(format, djtlba, djtlbm); 279 280 } else if (mode & CPUCACHESTAT) { 281 const char format[] = " %6lu %6lu %6lu %6lu"; 282 283 getcpucachestat(icache_access+tog, icache_miss+tog, dcache_wb+tog, dcache_miss+tog); 284 285 icachea = icache_access[tog]-icache_access[!tog]; 286 icachem = icache_miss[tog]-icache_miss[!tog]; 287 dcachewb = dcache_wb[tog]-dcache_wb[!tog]; 288 dcachem = dcache_miss[tog]-dcache_miss[!tog]; 289 printf(format, icachea, icachem, dcachewb, dcachem); 290 } 291 printf("\n"); 292 } 293} 294 295//////////////////////////////////////////////////////////////////////////// 296 297static void diskpartition_header(const char *partition_name){ 298 printf("%-10s %10s %10s %10s %10s\n",partition_name, "reads ", "read sectors", "writes ", "requested writes"); 299} 300 301//////////////////////////////////////////////////////////////////////////// 302 303static int diskpartition_format(const char* partition_name){ 304 FILE *fDiskstat; 305 struct disk_stat *disks; 306 struct partition_stat *partitions, *current_partition=NULL; 307 unsigned long ndisks, j, k, npartitions; 308 const char format[] = "%20u %10llu %10u %10u\n"; 309 310 fDiskstat=fopen("/proc/diskstats","rb"); 311 if(!fDiskstat){ 312 fprintf(stderr, "Your kernel doesn't support diskstat. (2.5.70 or above required)\n"); 313 exit(0); 314 } 315 316 fclose(fDiskstat); 317 ndisks=getdiskstat(&disks,&partitions); 318 npartitions=getpartitions_num(disks, ndisks); 319 for(k=0; k<npartitions; k++){ 320 if(!strcmp(partition_name, partitions[k].partition_name)){ 321 current_partition=&(partitions[k]); 322 } 323 } 324 if(!current_partition){ 325 return -1; 326 } 327 diskpartition_header(partition_name); 328 printf (format, 329 current_partition->reads,current_partition->reads_sectors,current_partition->writes,current_partition->requested_writes); 330 fflush(stdout); 331 free(disks); 332 free(partitions); 333 for(j=1; j<num_updates; j++){ 334 if (moreheaders && ((j%height)==0)) diskpartition_header(partition_name); 335 sleep(sleep_time); 336 ndisks=getdiskstat(&disks,&partitions); 337 npartitions=getpartitions_num(disks, ndisks); 338 current_partition=NULL; 339 for(k=0; k<npartitions; k++){ 340 if(!strcmp(partition_name, partitions[k].partition_name)){ 341 current_partition=&(partitions[k]); 342 } 343 } 344 if(!current_partition){ 345 return -1; 346 } 347 printf (format, 348 current_partition->reads,current_partition->reads_sectors,current_partition->writes,current_partition->requested_writes); 349 fflush(stdout); 350 free(disks); 351 free(partitions); 352 } 353 return 0; 354} 355 356//////////////////////////////////////////////////////////////////////////// 357 358static void diskheader(void){ 359 printf("disk- ------------reads------------ ------------writes----------- -----IO------\n"); 360 361 printf("%5s %6s %6s %7s %7s %6s %6s %7s %7s %6s %6s\n", 362 " ", "total", "merged","sectors","ms","total","merged","sectors","ms","cur","sec"); 363 364} 365 366//////////////////////////////////////////////////////////////////////////// 367 368static void diskformat(void){ 369 FILE *fDiskstat; 370 struct disk_stat *disks; 371 struct partition_stat *partitions; 372 unsigned long ndisks,i,j,k; 373 const char format[]="%-5s %6u %6u %7llu %7u %6u %6u %7llu %7u %6u %6u\n"; 374 if ((fDiskstat=fopen("/proc/diskstats", "rb"))){ 375 fclose(fDiskstat); 376 ndisks=getdiskstat(&disks,&partitions); 377 for(k=0; k<ndisks; k++){ 378 if (moreheaders && ((k%height)==0)) diskheader(); 379 printf(format, 380 disks[k].disk_name, 381 disks[k].reads, 382 disks[k].merged_reads, 383 disks[k].reads_sectors, 384 disks[k].milli_reading, 385 disks[k].writes, 386 disks[k].merged_writes, 387 disks[k].written_sectors, 388 disks[k].milli_writing, 389 disks[k].inprogress_IO?disks[k].inprogress_IO/1000:0, 390 disks[k].milli_spent_IO?disks[k].milli_spent_IO/1000:0/*, 391 disks[i].weighted_milli_spent_IO/1000*/ 392 ); 393 fflush(stdout); 394 } 395 free(disks); 396 free(partitions); 397 for(j=1; j<num_updates; j++){ 398 sleep(sleep_time); 399 ndisks=getdiskstat(&disks,&partitions); 400 for(i=0; i<ndisks; i++,k++){ 401 if (moreheaders && ((k%height)==0)) diskheader(); 402 printf(format, 403 disks[i].disk_name, 404 disks[i].reads, 405 disks[i].merged_reads, 406 disks[i].reads_sectors, 407 disks[i].milli_reading, 408 disks[i].writes, 409 disks[i].merged_writes, 410 disks[i].written_sectors, 411 disks[i].milli_writing, 412 disks[i].inprogress_IO?disks[i].inprogress_IO/1000:0, 413 disks[i].milli_spent_IO?disks[i].milli_spent_IO/1000:0/*, 414 disks[i].weighted_milli_spent_IO/1000*/ 415 ); 416 fflush(stdout); 417 } 418 free(disks); 419 free(partitions); 420 } 421 }else{ 422 fprintf(stderr, "Your kernel doesn't support diskstat (2.5.70 or above required)\n"); 423 exit(0); 424 } 425} 426 427//////////////////////////////////////////////////////////////////////////// 428 429static void slabheader(void){ 430 printf("%-24s %6s %6s %6s %6s\n","Cache","Num", "Total", "Size", "Pages"); 431} 432 433//////////////////////////////////////////////////////////////////////////// 434 435static void slabformat (void){ 436 FILE *fSlab; 437 struct slab_cache *slabs; 438 unsigned long nSlab,i,j,k; 439 const char format[]="%-24s %6u %6u %6u %6u\n"; 440 441 fSlab=fopen("/proc/slabinfo", "rb"); 442 if(!fSlab){ 443 fprintf(stderr, "Your kernel doesn't support slabinfo.\n"); 444 return; 445 } 446 447 nSlab = getslabinfo(&slabs); 448 for(k=0; k<nSlab; k++){ 449 if (moreheaders && ((k%height)==0)) slabheader(); 450 printf(format, 451 slabs[k].name, 452 slabs[k].active_objs, 453 slabs[k].num_objs, 454 slabs[k].objsize, 455 slabs[k].objperslab 456 ); 457 } 458 free(slabs); 459 for(j=1,k=1; j<num_updates; j++) { 460 sleep(sleep_time); 461 nSlab = getslabinfo(&slabs); 462 for(i=0; i<nSlab; i++,k++){ 463 if (moreheaders && ((k%height)==0)) slabheader(); 464 printf(format, 465 slabs[i].name, 466 slabs[i].active_objs, 467 slabs[i].num_objs, 468 slabs[i].objsize, 469 slabs[i].objperslab 470 ); 471 } 472 free(slabs); 473 } 474} 475 476//////////////////////////////////////////////////////////////////////////// 477 478static void disksum_format(void) { 479 480 FILE *fDiskstat; 481 struct disk_stat *disks; 482 struct partition_stat *partitions; 483 int ndisks, i; 484 unsigned long reads, merged_reads, read_sectors, milli_reading, writes, 485 merged_writes, written_sectors, milli_writing, inprogress_IO, 486 milli_spent_IO, weighted_milli_spent_IO; 487 488 reads=merged_reads=read_sectors=milli_reading=writes=merged_writes= \ 489 written_sectors=milli_writing=inprogress_IO=milli_spent_IO= \ 490 weighted_milli_spent_IO=0; 491 492 if ((fDiskstat=fopen("/proc/diskstats", "rb"))){ 493 fclose(fDiskstat); 494 ndisks=getdiskstat(&disks, &partitions); 495 printf("%13d disks \n", ndisks); 496 printf("%13d partitions \n", getpartitions_num(disks, ndisks)); 497 498 for(i=0; i<ndisks; i++){ 499 reads+=disks[i].reads; 500 merged_reads+=disks[i].merged_reads; 501 read_sectors+=disks[i].reads_sectors; 502 milli_reading+=disks[i].milli_reading; 503 writes+=disks[i].writes; 504 merged_writes+=disks[i].merged_writes; 505 written_sectors+=disks[i].written_sectors; 506 milli_writing+=disks[i].milli_writing; 507 inprogress_IO+=disks[i].inprogress_IO?disks[i].inprogress_IO/1000:0; 508 milli_spent_IO+=disks[i].milli_spent_IO?disks[i].milli_spent_IO/1000:0; 509 } 510 511 printf("%13lu total reads\n",reads); 512 printf("%13lu merged reads\n",merged_reads); 513 printf("%13lu read sectors\n",read_sectors); 514 printf("%13lu milli reading\n",milli_reading); 515 printf("%13lu writes\n",writes); 516 printf("%13lu merged writes\n",merged_writes); 517 printf("%13lu written sectors\n",written_sectors); 518 printf("%13lu milli writing\n",milli_writing); 519 printf("%13lu inprogress IO\n",inprogress_IO); 520 printf("%13lu milli spent IO\n",milli_spent_IO); 521 522 free(disks); 523 free(partitions); 524 } 525} 526 527//////////////////////////////////////////////////////////////////////////// 528 529static void sum_format(void) { 530 unsigned int running, blocked, btime, processes; 531 jiff cpu_use, cpu_nic, cpu_sys, cpu_idl, cpu_iow, cpu_xxx, cpu_yyy, cpu_zzz; 532 unsigned long pgpgin, pgpgout, pswpin, pswpout; 533 unsigned int intr, ctxt; 534 535 meminfo(); 536 537 getstat(&cpu_use, &cpu_nic, &cpu_sys, &cpu_idl, 538 &cpu_iow, &cpu_xxx, &cpu_yyy, &cpu_zzz, 539 &pgpgin, &pgpgout, &pswpin, &pswpout, 540 &intr, &ctxt, 541 &running, &blocked, 542 &btime, &processes); 543 544 printf("%13lu %s total memory\n", unitConvert(kb_main_total),szDataUnit); 545 printf("%13lu %s used memory\n", unitConvert(kb_main_used),szDataUnit); 546 printf("%13lu %s active memory\n", unitConvert(kb_active),szDataUnit); 547 printf("%13lu %s inactive memory\n", unitConvert(kb_inactive),szDataUnit); 548 printf("%13lu %s free memory\n", unitConvert(kb_main_free),szDataUnit); 549 printf("%13lu %s buffer memory\n", unitConvert(kb_main_buffers),szDataUnit); 550 printf("%13lu %s swap cache\n", unitConvert(kb_main_cached),szDataUnit); 551 printf("%13lu %s total swap\n", unitConvert(kb_swap_total),szDataUnit); 552 printf("%13lu %s used swap\n", unitConvert(kb_swap_used),szDataUnit); 553 printf("%13lu %s free swap\n", unitConvert(kb_swap_free),szDataUnit); 554 printf("%13Lu non-nice user cpu ticks\n", cpu_use); 555 printf("%13Lu nice user cpu ticks\n", cpu_nic); 556 printf("%13Lu system cpu ticks\n", cpu_sys); 557 printf("%13Lu idle cpu ticks\n", cpu_idl); 558 printf("%13Lu IO-wait cpu ticks\n", cpu_iow); 559 printf("%13Lu IRQ cpu ticks\n", cpu_xxx); 560 printf("%13Lu softirq cpu ticks\n", cpu_yyy); 561 printf("%13Lu stolen cpu ticks\n", cpu_zzz); 562 printf("%13lu pages paged in\n", pgpgin); 563 printf("%13lu pages paged out\n", pgpgout); 564 printf("%13lu pages swapped in\n", pswpin); 565 printf("%13lu pages swapped out\n", pswpout); 566 printf("%13u interrupts\n", intr); 567 printf("%13u CPU context switches\n", ctxt); 568 printf("%13u boot time\n", btime); 569 printf("%13u forks\n", processes); 570} 571 572//////////////////////////////////////////////////////////////////////////// 573 574static void fork_format(void) { 575 unsigned int running, blocked, btime, processes; 576 jiff cpu_use, cpu_nic, cpu_sys, cpu_idl, cpu_iow, cpu_xxx, cpu_yyy, cpu_zzz; 577 unsigned long pgpgin, pgpgout, pswpin, pswpout; 578 unsigned int intr, ctxt; 579 580 getstat(&cpu_use, &cpu_nic, &cpu_sys, &cpu_idl, 581 &cpu_iow, &cpu_xxx, &cpu_yyy, &cpu_zzz, 582 &pgpgin, &pgpgout, &pswpin, &pswpout, 583 &intr, &ctxt, 584 &running, &blocked, 585 &btime, &processes); 586 587 printf("%13u forks\n", processes); 588} 589 590//////////////////////////////////////////////////////////////////////////// 591 592static int winhi(void) { 593 struct winsize win; 594 int rows = 24; 595 596 if (ioctl(1, TIOCGWINSZ, &win) != -1 && win.ws_row > 0) 597 rows = win.ws_row; 598 599 return rows; 600} 601 602//////////////////////////////////////////////////////////////////////////// 603 604int main(int argc, char *argv[]) { 605 char partition[16]; 606 unsigned long perfopt; 607 608 argc=0; /* redefined as number of integer arguments */ 609 for (argv++;*argv;argv++) { 610 if ('-' ==(**argv)) { 611 switch (*(++(*argv))) { 612 613 case 'V': 614 //display_version(); 615 exit(0); 616 case 'd': 617 statMode |= DISKSTAT; 618 break; 619 case 'a': 620 /* active/inactive mode */ 621 a_option=1; 622 break; 623 case 'f': 624 fork_format(); 625 exit(0); 626 case 'm': 627 statMode |= SLABSTAT; 628 break; 629 case 'D': 630 statMode |= DISKSUMSTAT; 631 break; 632 case 'I': 633 statMode |= ITLBSTAT; 634 break; 635 case 'P': 636 statMode |= DTLBSTAT; 637 break; 638 case 'C': 639 statMode |= CPUCACHESTAT; 640 break; 641 case 'n': 642 /* print only one header */ 643 moreheaders=FALSE; 644 break; 645 case 'p': 646 statMode |= PARTITIONSTAT; 647 if (argv[1]){ 648 char *cp = *++argv; 649 if(!memcmp(cp,"/dev/",5)) cp += 5; 650 snprintf(partition, sizeof partition, "%s", cp); 651 }else{ 652 fprintf(stderr, "-p requires an argument\n"); 653 exit(EXIT_FAILURE); 654 } 655 break; 656 case 'S': 657 if (argv[1]){ 658 ++argv; 659 if (!strcmp(*argv, "k")) dataUnit=UNIT_k; 660 else if (!strcmp(*argv, "K")) dataUnit=UNIT_K; 661 else if (!strcmp(*argv, "m")) dataUnit=UNIT_m; 662 else if (!strcmp(*argv, "M")) dataUnit=UNIT_M; 663 else {fprintf(stderr, "-S requires k, K, m or M (default is kb)\n"); 664 exit(EXIT_FAILURE); 665 } 666 strcpy(szDataUnit, *argv); 667 }else {fprintf(stderr, "-S requires an argument\n"); 668 exit(EXIT_FAILURE); 669 } 670 break; 671 case 's': 672 statMode |= VMSUMSTAT; 673 break; 674 default: 675 /* no other aguments defined yet. */ 676 usage(); 677 } 678 }else{ 679 argc++; 680 switch (argc) { 681 case 1: 682 if ((sleep_time = atoi(*argv)) == 0) 683 usage(); 684 num_updates = ULONG_MAX; 685 break; 686 case 2: 687 num_updates = atol(*argv); 688 break; 689 default: 690 usage(); 691 } /* switch */ 692 } 693} 694 perfopt = (statMode & (ITLBSTAT | DTLBSTAT | CPUCACHESTAT)); 695 if (perfopt & (perfopt - 1)) { 696 printf("May use only one among I/P/C options\n"); 697 exit(0); 698 } 699 700 if (moreheaders) { 701 int tmp=winhi()-3; 702 height=((tmp>0)?tmp:22); 703 } 704 setlinebuf(stdout); 705 switch(statMode){ 706 case(VMSTAT): 707 case(ITLBSTAT): 708 case(DTLBSTAT): 709 case(CPUCACHESTAT): new_format(statMode); 710 break; 711 case(VMSUMSTAT): sum_format(); 712 break; 713 case(DISKSTAT): diskformat(); 714 break; 715 case(PARTITIONSTAT): if(diskpartition_format(partition)==-1) 716 printf("Partition was not found\n"); 717 break; 718 case(SLABSTAT): slabformat(); 719 break; 720 case(DISKSUMSTAT): disksum_format(); 721 break; 722 default: usage(); 723 break; 724 } 725 return 0; 726} 727