home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume26
/
perfmon
/
barmon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-08
|
6KB
|
226 lines
static char *what = "@(#)barmon.c 1.7 1/18/92 (c) 1991 Larry McVoy";
#include <stdio.h>
#include <curses.h>
#include <sys/dk.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <ctype.h>
#include <rpcsvc/rstat.h>
#define LABEL 10
/*
* XXX - this should be an array of structs.
*/
#define USRLABEL "[% USER CPU]"
#define USRWID 11
#define USRLEFT LABEL
#define USRRIGHT (USRLEFT+USRWID)
#define SYSLABEL "[% SYS CPU ]"
#define SYSWID 11
#define SYSLEFT (USRRIGHT+1)
#define SYSRIGHT (SYSLEFT+SYSWID)
#define PKTFMT "[PKTS %5d]"
#define PKTWID 11
#define PKTLEFT (SYSRIGHT+1)
#define PKTRIGHT (PKTLEFT+PKTWID)
#define PKTADJUST 100
#define DISKFMT "[DISK %5d]"
#define DISKWID 11
#define DISKLEFT (PKTRIGHT+1)
#define DISKRIGHT (DISKLEFT+DISKWID)
#define DISKADJUST 10
#define PAGEFMT "[PAGE %5d]"
#define PAGEWID 11
#define PAGELEFT (DISKRIGHT+1)
#define PAGERIGHT (PAGELEFT+PAGEWID)
#define PAGEADJUST 10
#define SLPDEFAULT 5
#define sane(x) ((x) > 100000 ? (-1) : (x))
#define scale(x) sane(secs == 1 ? (x) : (x) / secs)
#define sleep(x) usleep(1000000 * (x))
char **hosts;
struct statstime *orig, *new;
struct mystat {
int usr;
int sys;
int pkt;
int page;
int disk;
} *save;
int secs;
int n;
int pagemax = 10, pktmax = 100, diskmax = 20;
int newpagemax = 10, newpktmax = 100, newdiskmax = 20;
catch() {}
main(ac, av)
char **av;
{
int i;
char *calloc();
struct itimerval it;
time_t clock;
if (isdigit(av[ac - 1][0])) {
secs = atoi(av[ac - 1]);
ac--;
} else {
secs = SLPDEFAULT;
}
hosts = (char**)calloc(ac, sizeof(char *));
orig = (struct statstime*)calloc(ac, sizeof(struct statstime));
new = (struct statstime*)calloc(ac, sizeof(struct statstime));
save = (struct mystat*)calloc(ac, sizeof(struct mystat));
/*
* Go through it once to fire up all the rstatd's.
*/
for (i = 1; i < ac; ++i) {
if (rstat(av[i], &orig[i - 1]) == 0) {
hosts[n++] = av[i];
} else {
perror(av[i]);
exit(1);
}
}
/*
* Initialize
* XXX - cath sigint and restore modes?
*/
initscr();
clear();
mvaddstr(0, USRLEFT, USRLABEL);
mvaddstr(0, SYSLEFT, SYSLABEL);
mvprintw(0, PKTLEFT, PKTFMT, pktmax);
mvprintw(0, DISKLEFT, DISKFMT, diskmax);
mvprintw(0, PAGELEFT, PAGEFMT, pagemax);
for(i = 1; i < ac; ++i) {
if (strlen(av[i]) >= LABEL)
av[i][LABEL] = 0; /* XXX off by 1? */
mvaddstr(i, 0, av[i]);
mvaddch(i, USRLEFT, '[');
mvaddch(i, USRRIGHT, ']');
mvaddch(i, SYSLEFT, '[');
mvaddch(i, SYSRIGHT, ']');
mvaddch(i, PKTLEFT, '[');
mvaddch(i, PKTRIGHT, ']');
mvaddch(i, DISKLEFT, '[');
mvaddch(i, DISKRIGHT, ']');
mvaddch(i, PAGELEFT, '[');
mvaddch(i, PAGERIGHT, ']');
}
/*
* Set up an interval timer - this should help get rid of delays.
*/
it.it_interval.tv_sec = secs;
it.it_interval.tv_usec = secs;
it.it_value.tv_sec = secs;
it.it_value.tv_usec = secs;
signal(SIGALRM, catch);
setitimer(ITIMER_REAL, &it, 0);
sigblock(sigmask(SIGALRM));
/*
* Do it again now that it is fast.
*/
for (i = 0; i < ac - 1; ++i) {
rstat(hosts[i], &orig[i]);
}
while (1) {
/*
* We need the signal handling because of the fact that the
* rstat could be infinitely long.
* XXX - need corbin's async rpc's.
*/
sigpause(0);
newpktmax = newdiskmax = newpagemax = 0;
for (i = 0; i < ac - 1; ++i) {
getstats(i);
}
#define adjustmax(n, o, a) if (n > o) { \
o = ((n + a - 1) / a) * a; \
} else if (n < o / 2) { \
o /= 2; \
o = ((o + a - 1) / a) * a; \
}
adjustmax(newdiskmax, diskmax, DISKADJUST);
adjustmax(newpktmax, pktmax, PKTADJUST);
adjustmax(newpagemax, pagemax, PAGEADJUST);
mvprintw(0, PKTLEFT, PKTFMT, pktmax);
mvprintw(0, DISKLEFT, DISKFMT, diskmax);
mvprintw(0, PAGELEFT, PAGEFMT, pagemax);
for (i = 0; i < ac - 1; ++i) {
display(i);
}
time(&clock);
mvprintw(23, 0, "%.24s", ctime(&clock));
refresh();
}
}
/*
* Get the statistics and rescale
*/
getstats(i)
{
int y, u, s, d, pkt, pg, pos;
if (rstat(hosts[i], &new[i]) != 0) {
perror(hosts[i]);
exit(1);
}
u = scale(new[i].cp_time[0] - orig[i].cp_time[0]);
s = scale(new[i].cp_time[2] - orig[i].cp_time[2]);
pkt = scale(new[i].if_ipackets - orig[i].if_ipackets) +
scale(new[i].if_opackets - orig[i].if_opackets);
d = scale(new[i].dk_xfer[0] - orig[i].dk_xfer[0]) +
scale(new[i].dk_xfer[1] - orig[i].dk_xfer[1]) +
scale(new[i].dk_xfer[2] - orig[i].dk_xfer[2]) +
scale(new[i].dk_xfer[3] - orig[i].dk_xfer[3]);
pg = scale(new[i].v_pgpgin - orig[i].v_pgpgin) +
scale(new[i].v_pgpgout - orig[i].v_pgpgout);
while (u + s > 100) /* timing errors */
u--, s--;
#define adjust(x, w, m) if (x > m) x = m; \
x = (x + ((m/(w-1) / 2))) * (w - 1) / m;
adjust(u, USRWID, 100);
adjust(s, SYSWID, 100);
if (newpktmax < pkt)
newpktmax = pkt;
adjust(pkt, PKTWID, pktmax);
if (newdiskmax < d)
newdiskmax = d;
adjust(d, DISKWID, diskmax);
if (newpagemax < pg)
newpagemax = pg;
adjust(pg, PAGEWID, pagemax);
save[i].usr = u;
save[i].sys = s;
save[i].pkt = pkt;
save[i].disk = d;
save[i].page = pg;
orig[i] = new[i];
}
display(i)
{
int y, pos;
y = i + 1;
for (pos = USRLEFT + 1; pos < USRRIGHT; ++pos)
mvaddch(y, pos, save[i].usr-- > 0 ? 'U' : ' ');
for (pos = SYSLEFT + 1; pos < SYSRIGHT; ++pos)
mvaddch(y, pos, save[i].sys-- > 0 ? 'S' : ' ');
for (pos = PKTLEFT + 1; pos < PKTRIGHT; ++pos)
mvaddch(y, pos, save[i].pkt-- > 0 ? 'N' : ' ');
for (pos = DISKLEFT + 1; pos < DISKRIGHT; ++pos)
mvaddch(y, pos, save[i].disk-- > 0 ? 'D' : ' ');
for (pos = PAGELEFT + 1; pos < PAGERIGHT; ++pos)
mvaddch(y, pos, save[i].page-- > 0 ? 'P' : ' ');
}