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);
}