earlw@pesnta.UUCP (Earl Wallace) (06/28/85)
This program compiles and runs under XELOS R01 and should run on R00. It is another in the unfinished-project series of programs. To compile: cc -O -n -o dstats dstats.c -lcurses To run: dstats (updates screen every 5 seconds) dstats n (updates screen every 'n' seconds) The program: /* * dstats - cute little sysinfo display map with interval updates * * June 1985 earlw@pesnta */ #include <stdio.h> #include <curses.h> #include <signal.h> #include <sys/types.h> #include <sys/sysinfo.h> #include <sys/times.h> #include <sys/utsname.h> #include <fcntl.h> #include <time.h> #define INTERVAL 5 extern int errno; extern char *ctime(), *buildline(); extern long lseek(), time(), times(); extern unsigned sleep(); extern void update(), display(), diff(), strap(); struct sysinfo Sysinfo[3]; /* sysinfo stuff */ struct utsname Uts; /* naming struct */ struct tms Tms; /* process times */ struct tm Tm; /* local time */ int sysinfo_fd; char crtbuf[2000]; main(argc, argv) int argc; char *argv[]; { register struct sysinfo *b0 = &Sysinfo[0]; register struct sysinfo *b1 = &Sysinfo[1]; register struct sysinfo *br = &Sysinfo[2]; register long elasped, base, stop; register int cnt; int interval = INTERVAL, curmode; long curtime; char *tp; if (argc > 1) interval = atoi(argv[1]); for (cnt=0; cnt < 20; cnt++) /* catch all signals */ signal(cnt, strap); if ((sysinfo_fd=open("/dev/sysinfo", O_RDONLY)) < 0) { fprintf(stderr, "can't open /dev/sysinfo - "); perror(""); exit(1); } /* * get system name */ if (uname(&Uts) < 0) { fprintf(stderr, "can't get system name\n"); exit(9); } /* * since we are starting, we get our base time and do the initial * load of the sysinfo structure, after this we alternate buffers. */ initscr(); /* init screen */ base = times(&Tms); /* this is our base time */ update(b1); /* update structures set b1 */ /* * display time each second and update stats every interval seconds, * do this forever. */ for (;;) { /* * print date/time each second */ for (cnt=0; cnt < interval; cnt++) { time(&curtime); /* get current time */ tp = ctime(&curtime); /* convert time to string */ tp[24] = '\0'; /* null out the newline */ move(0,0); /* row 1, col 1 */ printw("%s %s %s %s %s %s", tp, Uts.sysname, Uts.nodename, Uts.release, Uts.version, Uts.machine); move(23,79); /* row 24, col 80 */ refresh(); /* refresh screen */ sleep(1); /* sleep one second */ } /* * do stats update */ if (curmode == 0) { update(b0); /* update structures set b0 */ stop = times(&Tms); /* get stop time */ elasped = stop - base; /* get elasped time */ base += elasped; /* new base value */ diff(b0, b1, br); /* b0 - b1 = br */ curmode = 1; /* switch mode */ } else { update(b1); /* update structures set b1 */ stop = times(&Tms); /* get stop time */ elasped = stop - base; /* get elasped time */ base += elasped; /* new base value */ diff(b1, b0, br); /* b1 - b0 = br */ curmode = 0; /* switch mode */ } display(br, elasped); /* display results */ } } /* * update sysinfo structure */ void update(bx) register struct sysinfo *bx; { register long cnt; lseek(sysinfo_fd, 0L, 0); /* rewind ? */ if ((cnt=read(sysinfo_fd, bx, sizeof sysinfo)) < 0 || cnt != sizeof sysinfo) { endwin(); /* shutdown curses */ fprintf(stderr, "Sysinfo read failed, want %d, got %d - ", sizeof sysinfo, cnt); perror(""); exit(10); } } /* * catch those signals if we can, we may miss one sometimes.... */ void strap(sno) register int sno; { clear(); endwin(); exit(sno); } /* * determine differences via brute force method * diff(bx, by, br); bx - by = br */ void diff(bx, by, br) register struct sysinfo *bx, *by, *br; { br->cpu[CPU_IDLE] = bx->cpu[CPU_IDLE] - by->cpu[CPU_IDLE]; br->cpu[CPU_USER] = bx->cpu[CPU_USER] - by->cpu[CPU_USER]; br->cpu[CPU_KERNAL] = bx->cpu[CPU_KERNAL] - by->cpu[CPU_KERNAL]; br->cpu[CPU_WAIT] = bx->cpu[CPU_WAIT] - by->cpu[CPU_WAIT]; br->wait[W_IO] = bx->wait[W_IO] - by->wait[W_IO]; br->wait[W_SWAP] = bx->wait[W_SWAP] - by->wait[W_SWAP]; br->wait[W_PIO] = bx->wait[W_PIO] - by->wait[W_PIO]; br->bread = bx->bread - by->bread; br->bwrite = bx->bwrite - by->bwrite; br->lread = bx->lread - by->lread; br->lwrite = bx->lwrite - by->lwrite; br->phread = bx->phread - by->phread; br->phwrite = bx->phwrite - by->phwrite; br->swapin = bx->swapin - by->swapin; br->swapout = bx->swapout - by->swapout; br->bswapin = bx->bswapin - by->bswapin; br->bswapout = bx->bswapout - by->bswapout; br->pswitch = bx->pswitch - by->pswitch; br->syscall = bx->syscall - by->syscall; br->sysread = bx->sysread - by->sysread; br->syswrite = bx->syswrite - by->syswrite; br->sysfork = bx->sysfork - by->sysfork; br->sysexec = bx->sysexec - by->sysexec; br->runque = bx->runque - by->runque; br->runocc = bx->runocc - by->runocc; br->swpque = bx->swpque - by->swpque; br->swpocc = bx->swpocc - by->swpocc; br->iget = bx->iget - by->iget; br->namei = bx->namei - by->namei; br->dirblk = bx->dirblk - by->dirblk; br->readch = bx->readch - by->readch; br->writech = bx->writech - by->writech; br->rcvint = bx->rcvint - by->rcvint; br->xmtint = bx->xmtint - by->xmtint; br->mdmint = bx->mdmint - by->mdmint; br->rawch = bx->rawch - by->rawch; br->canch = bx->canch - by->canch; br->outch = bx->outch - by->outch; br->msg = bx->msg - by->msg; br->sema = bx->sema - by->sema; } /* * display results */ void display(br, et) register struct sysinfo *br; register long et; { register float scale, sec, fl; scale = 100.0/(float)et; /* scale for percentages */ sec = (float)et/(float)Tms.tms_cfreq; /* convert to seconds */ move(2,0); fl = scale * (float)br->cpu[CPU_USER]; printw("cpu/user %5.1f%%: %s", fl, buildline(fl, 60)); move(3,0); fl = scale * (float)br->cpu[CPU_KERNAL]; printw("cpu/kernel %5.1f%%: %s", fl, buildline(fl, 60)); move(4,0); fl = scale * (float)br->cpu[CPU_IDLE]; printw("cpu/idle %5.1f%%: %s", fl, buildline(fl, 60)); move(5,0); fl = scale * (float)br->cpu[CPU_WAIT]; printw("cpu/wait %5.1f%%: %s", fl, buildline(fl, 60)); move(6,0); fl = scale * (float)br->wait[W_IO]; printw("wait/io %5.1f%%: %s", fl, buildline(fl, 60)); move(7,0); fl = scale * (float)br->wait[W_SWAP]; printw("wait/swap %5.1f%%: %s", fl, buildline(fl, 60)); move(8,0); fl = scale * (float)br->wait[W_PIO]; printw("wait/pio %5.1f%%: %s", fl, buildline(fl, 60)); move(10,0); printw("%7.1f bread/s %7.1f bwrite/s ", (float)br->bread / sec, (float)br->bwrite / sec); printw("%7.1f lread/s %7.1f lwrite/s ", (float)br->lread / sec, (float)br->lwrite / sec); move(11,0); printw("%7.1f phread/s %7.1f phwrite/s ", (float)br->phread / sec, (float)br->phwrite / sec); printw("%7.1f swapin/s %7.1f swapout/s ", (float)br->swapin / sec, (float)br->swapout / sec); move(12,0); printw("%7.1f bswapin/s %7.1f bswapout/s ", (float)br->bswapin / sec, (float)br->bswapout / sec); printw("%7.1f pswitch/s %7.1f syscall/s ", (float)br->pswitch / sec, (float)br->syscall / sec); move(13,0); printw("%7.1f sysread/s %7.1f syswrite/s ", (float)br->sysread / sec, (float)br->syswrite / sec); printw("%7.1f sysfork/s %7.1f sysexec/s ", (float)br->sysfork / sec, (float)br->sysexec / sec); move(14,0); printw("%7.1f runque/s %7.1f runocc/s ", (float)br->runque / sec, (float)br->runocc / sec); printw("%7.1f swpque/s %7.1f swpocc/s ", (float)br->swpque / sec, (float)br->swpocc / sec); move(15,0); printw("%7.1f iget/s %7.1f namei/s ", (float)br->iget / sec, (float)br->namei / sec); printw("%7.1f dirblk/s %7.1f readch/s ", (float)br->dirblk / sec, (float)br->readch / sec); move(16,0); printw("%7.1f writech/s %7.1f rcvint/s ", (float)br->writech / sec, (float)br->rcvint / sec); printw("%7.1f xmtint/s %7.1f mdmint/s ", (float)br->xmtint / sec, (float)br->mdmint / sec); move(17,0); printw("%7.1f rawch/s %7.1f canch/s ", (float)br->rawch / sec, (float)br->canch / sec); printw("%7.1f outch/s %7.1f msg/s ", (float)br->outch / sec, (float)br->msg / sec); move(18,0); printw("%7.1f sema/s", (float)br->sema / sec); } /* * build '**' line (scale for %100 being 'len' characters) */ char * buildline(val, len) register float val; register int len; { register char *p, *pe, *cp; static char linebuf[81]; p = linebuf; pe = linebuf+len; cp = (int)(val/(100.0/(float)len)) + linebuf; for (; p < cp; p++) *p = '*'; for (; p < pe; p++) *p = ' '; *p = '\0'; return (linebuf); }