#include <u.h>
#include <libc.h>
#include <ctype.h>
-#include <auth.h>
-#include <fcall.h>
#include <draw.h>
#include <event.h>
+#include <keyboard.h>
#define MAXNUM 10 /* maximum number of numbers on data line */
enum
{
- /* old /dev/swap */
+ /* /dev/swap */
Mem = 0,
Maxmem,
Swap,
Maxswap,
+ Reclaim,
+ Maxreclaim,
+ Kern,
+ Maxkern,
+ Draw,
+ Maxdraw,
/* /dev/sysstats */
Procno = 0,
Load,
Idle,
InIntr,
+
/* /net/ether0/stats */
In = 0,
Link,
int tempfd;
int disable;
- uvlong devswap[4];
+ uvlong devswap[10];
uvlong devsysstat[10];
uvlong prevsysstat[10];
int nproc;
enum
{
Mainproc,
- Mouseproc,
+ Inputproc,
NPROC,
};
Mload,
Mmem,
Mswap,
+ Mreclaim,
+ Mkern,
+ Mdraw,
Msyscall,
Mtlbmiss,
Mtlbpurge,
"add load ",
"add mem ",
"add swap ",
+ "add reclaim ",
+ "add kern ",
+ "add draw ",
"add syscall ",
"add tlbmiss ",
"add tlbpurge",
idleval(Machine*, uvlong*, uvlong*, int),
memval(Machine*, uvlong*, uvlong*, int),
swapval(Machine*, uvlong*, uvlong*, int),
+ reclaimval(Machine*, uvlong*, uvlong*, int),
+ kernval(Machine*, uvlong*, uvlong*, int),
+ drawval(Machine*, uvlong*, uvlong*, int),
syscallval(Machine*, uvlong*, uvlong*, int),
tlbmissval(Machine*, uvlong*, uvlong*, int),
tlbpurgeval(Machine*, uvlong*, uvlong*, int),
loadval,
memval,
swapval,
+ reclaimval,
+ kernval,
+ drawval,
syscallval,
tlbmissval,
tlbpurgeval,
Graph *graph;
Machine *mach;
char *mysysname;
-char argchars[] = "8bceEfiImlnpstwz";
+char argchars[] = "8bcdeEfiIkmlnprstwz";
int pids[NPROC];
int parity; /* toggled to avoid patterns in textured background */
int nmach;
double scale = 1.0;
int logscale = 0;
int ylabels = 0;
-int oldsystem = 0;
int sleeptime = 1000;
-char *procnames[NPROC] = {"main", "mouse"};
+char *procnames[NPROC] = {"main", "input"};
void
killall(char *s)
return i == n;
}
-/* Network on fd1, mount driver on fd0 */
-static int
-filter(int fd)
-{
- int p[2];
-
- if(pipe(p) < 0){
- fprint(2, "stats: can't pipe: %r\n");
- killall("pipe");
- }
-
- switch(rfork(RFNOWAIT|RFPROC|RFFDG)) {
- case -1:
- sysfatal("rfork record module");
- case 0:
- dup(fd, 1);
- close(fd);
- dup(p[0], 0);
- close(p[0]);
- close(p[1]);
- execl("/bin/aux/fcall", "fcall", nil);
- fprint(2, "stats: can't exec fcall: %r\n");
- killall("fcall");
- default:
- close(fd);
- close(p[0]);
- }
- return p[1];
-}
-
-/*
- * 9fs
- */
-int
-connect9fs(char *addr)
-{
- char dir[256], *na;
- int fd;
-
- fprint(2, "connect9fs...");
- na = netmkaddr(addr, 0, "9fs");
-
- fprint(2, "dial %s...", na);
- if((fd = dial(na, 0, dir, 0)) < 0)
- return -1;
-
- fprint(2, "dir %s...", dir);
-// if(strstr(dir, "tcp"))
-// fd = filter(fd);
- return fd;
-}
-
int
-old9p(int fd)
+readswap(Machine *m, uvlong *a)
{
- int p[2];
+ static int xxx = 0;
- if(pipe(p) < 0)
- return -1;
+ if(strstr(m->buf, "memory\n")){
+ /* new /dev/swap - skip first 3 numbers */
+ if(!readnums(m, 7, a, 1))
+ return 0;
- switch(rfork(RFPROC|RFFDG|RFNAMEG)) {
- case -1:
- return -1;
- case 0:
- if(fd != 1){
- dup(fd, 1);
- close(fd);
- }
- if(p[0] != 0){
- dup(p[0], 0);
- close(p[0]);
+ a[Mem] = a[3];
+ a[Maxmem] = a[4];
+ a[Swap] = a[5];
+ a[Maxswap] = a[6];
+
+ a[Reclaim] = 0;
+ a[Maxreclaim] = 0;
+ if(m->bufp = strstr(m->buf, "reclaim")){
+ while(m->bufp > m->buf && m->bufp[-1] != '\n')
+ m->bufp--;
+ a[Reclaim] = strtoull(m->bufp, &m->bufp, 10);
+ while(*m->bufp++ == '/')
+ a[Maxreclaim] = strtoull(m->bufp, &m->bufp, 10);
}
- close(p[1]);
- if(0){
- fd = open("/sys/log/cpu", OWRITE);
- if(fd != 2){
- dup(fd, 2);
- close(fd);
- }
- execl("/bin/srvold9p", "srvold9p", "-ds", nil);
- } else
- execl("/bin/srvold9p", "srvold9p", "-s", nil);
- return -1;
- default:
- close(fd);
- close(p[0]);
- }
- return p[1];
-}
-
-
-/*
- * exportfs
- */
-int
-connectexportfs(char *addr)
-{
- char buf[ERRMAX], dir[256], *na;
- int fd, n;
- char *tree;
- AuthInfo *ai;
-
- tree = "/";
- na = netmkaddr(addr, 0, "exportfs");
- if((fd = dial(na, 0, dir, 0)) < 0)
- return -1;
- ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client");
- if(ai == nil)
- return -1;
- auth_freeAI(ai);
+ a[Kern] = 0;
+ a[Maxkern] = 0;
+ if(m->bufp = strstr(m->buf, "kernel malloc")){
+ while(m->bufp > m->buf && m->bufp[-1] != '\n')
+ m->bufp--;
+ a[Kern] = strtoull(m->bufp, &m->bufp, 10);
+ while(*m->bufp++ == '/')
+ a[Maxkern] = strtoull(m->bufp, &m->bufp, 10);
+ }
- n = write(fd, tree, strlen(tree));
- if(n < 0){
- close(fd);
- return -1;
- }
+ a[Draw] = 0;
+ a[Maxdraw] = 0;
+ if(m->bufp = strstr(m->buf, "kernel draw")){
+ while(m->bufp > m->buf && m->bufp[-1] != '\n')
+ m->bufp--;
+ a[Draw] = strtoull(m->bufp, &m->bufp, 10);
+ while(*m->bufp++ == '/')
+ a[Maxdraw] = strtoull(m->bufp, &m->bufp, 10);
+ }
- strcpy(buf, "can't read tree");
- n = read(fd, buf, sizeof buf - 1);
- if(n!=2 || buf[0]!='O' || buf[1]!='K'){
- buf[sizeof buf - 1] = '\0';
- werrstr("bad remote tree: %s\n", buf);
- close(fd);
- return -1;
+ return 1;
}
-// if(strstr(dir, "tcp"))
-// fd = filter(fd);
-
- if(oldsystem)
- return old9p(fd);
+ a[Reclaim] = 0;
+ a[Maxreclaim] = 0;
+ a[Kern] = 0;
+ a[Maxkern] = 0;
+ a[Draw] = 0;
+ a[Maxdraw] = 0;
- return fd;
-}
-
-int
-readswap(Machine *m, uvlong *a)
-{
- if(strstr(m->buf, "memory\n")){
- /* new /dev/swap - skip first 3 numbers */
- if(!readnums(m, 7, a, 1))
- return 0;
- a[0] = a[3];
- a[1] = a[4];
- a[2] = a[5];
- a[3] = a[6];
- return 1;
- }
- return readnums(m, nelem(m->devswap), a, 0);
+ return readnums(m, 4, a, 0);
}
char*
int
initmach(Machine *m, char *name)
{
- int n, fd;
+ int n;
uvlong a[MAXNUM];
char *p, mpt[256], buf[256];
if(m->remote == 0)
strcpy(mpt, "");
else{
+ Waitmsg *w;
+ int pid;
+
snprint(mpt, sizeof mpt, "/n/%s", p);
- fd = connectexportfs(name);
- if(fd < 0){
- fprint(2, "can't connect to %s: %r\n", name);
+
+ pid = fork();
+ switch(pid){
+ case -1:
+ fprint(2, "can't fork: %r\n");
return 0;
+ case 0:
+ execl("/bin/rimport", "rimport", name, "/", mpt, nil);
+ fprint(2, "can't exec: %r\n");
+ exits("exec");
}
- /* BUG? need to use amount() now? */
- if(mount(fd, -1, mpt, MREPL, "") < 0){
- fprint(2, "stats: mount %s on %s failed (%r); trying /n/sid\n", name, mpt);
- strcpy(mpt, "/n/sid");
- if(mount(fd, -1, mpt, MREPL, "") < 0){
- fprint(2, "stats: mount %s on %s failed: %r\n", name, mpt);
- return 0;
- }
+ w = wait();
+ if(w == nil || w->pid != pid || w->msg[0] != '\0'){
+ free(w);
+ return 0;
}
+ free(w);
}
snprint(buf, sizeof buf, "%s/dev/swap", mpt);
m->swapfd = open(buf, OREAD);
if(loadbuf(m, &m->swapfd) && readswap(m, a))
memmove(m->devswap, a, sizeof m->devswap);
- else{
- m->devswap[Maxswap] = 100;
- m->devswap[Maxmem] = 100;
- }
snprint(buf, sizeof buf, "%s/dev/sysstat", mpt);
m->statsfd = open(buf, OREAD);
snprint(buf, sizeof buf, "%s/mnt/apm/battery", mpt);
m->batteryfd = open(buf, OREAD);
+ if(m->batteryfd < 0){
+ snprint(buf, sizeof buf, "%s/mnt/acpi/battery", mpt);
+ m->batteryfd = open(buf, OREAD);
+ }
m->bitsybatfd = -1;
if(m->batteryfd >= 0){
if(loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0))
}
snprint(buf, sizeof buf, "%s/dev/cputemp", mpt);
m->tempfd = open(buf, OREAD);
+ if(m->tempfd < 0){
+ snprint(buf, sizeof buf, "%s/mnt/acpi/cputemp", mpt);
+ m->tempfd = open(buf, OREAD);
+ }
if(loadbuf(m, &m->tempfd))
for(n=0; n < nelem(m->temp) && readnums(m, 2, a, 0); n++)
m->temp[n] = a[0];
int
needswap(int init)
{
- return init | present[Mmem] | present[Mswap];
+ return init | present[Mmem] | present[Mswap] | present[Mreclaim] | present[Mkern] | present[Mdraw];
}
{
*v = m->devswap[Mem];
*vmax = m->devswap[Maxmem];
+ if(*vmax == 0)
+ *vmax = 1;
}
void
{
*v = m->devswap[Swap];
*vmax = m->devswap[Maxswap];
+ if(*vmax == 0)
+ *vmax = 1;
+}
+
+void
+reclaimval(Machine *m, uvlong *v, uvlong *vmax, int)
+{
+ *v = m->devswap[Reclaim];
+ *vmax = m->devswap[Maxreclaim];
+ if(*vmax == 0)
+ *vmax = 1;
+}
+
+void
+kernval(Machine *m, uvlong *v, uvlong *vmax, int)
+{
+ *v = m->devswap[Kern];
+ *vmax = m->devswap[Maxkern];
+ if(*vmax == 0)
+ *vmax = 1;
+}
+
+void
+drawval(Machine *m, uvlong *v, uvlong *vmax, int)
+{
+ *v = m->devswap[Draw];
+ *vmax = m->devswap[Maxdraw];
+ if(*vmax == 0)
+ *vmax = 1;
}
void
}
void
-etherval(Machine *m, uvlong *v, uvlong *vmax, int init)
+etherval(Machine *m, uvlong *v, uvlong *vmax, int)
{
*v = m->netetherstats[In]-m->prevetherstats[In] + m->netetherstats[Out]-m->prevetherstats[Out];
- *vmax = sleeptime*m->nproc;
- if(init)
- *vmax = sleeptime;
+ *vmax = sleeptime;
}
void
-etherinval(Machine *m, uvlong *v, uvlong *vmax, int init)
+etherinval(Machine *m, uvlong *v, uvlong *vmax, int)
{
*v = m->netetherstats[In]-m->prevetherstats[In];
- *vmax = sleeptime*m->nproc;
- if(init)
- *vmax = sleeptime;
+ *vmax = sleeptime;
}
void
-etheroutval(Machine *m, uvlong *v, uvlong *vmax, int init)
+etheroutval(Machine *m, uvlong *v, uvlong *vmax, int)
{
*v = m->netetherstats[Out]-m->prevetherstats[Out];
- *vmax = sleeptime*m->nproc;
- if(init)
- *vmax = sleeptime;
+ *vmax = sleeptime;
}
void
-ethererrval(Machine *m, uvlong *v, uvlong *vmax, int init)
+ethererrval(Machine *m, uvlong *v, uvlong *vmax, int)
{
int i;
*v = 0;
for(i=Err0; i<nelem(m->netetherstats); i++)
- *v += m->netetherstats[i];
- *vmax = (sleeptime/1000)*10*m->nproc;
- if(init)
- *vmax = (sleeptime/1000)*10;
+ *v += m->netetherstats[i]-m->prevetherstats[i];
+ *vmax = (sleeptime/1000)*10;
}
void
{
ulong l;
- *vmax = sleeptime;
+ *vmax = 100;
l = m->temp[0];
if(l == ~0 || l == 0)
*v = 0;
else
- *v = (l-20)*27;
+ *v = l;
}
void
uvlong v, vmax;
g->newvalue(g->mach, &v, &vmax, 1);
+ if(vmax == 0)
+ vmax = 1;
if(logscale){
for(j=1; j<=2; j++)
sprint(strs[j-1], "%g", scale*pow(10., j)*(double)vmax/100.);
/* label right, if requested */
if(ylabels && dy>Nlab*(font->height+1)){
wid = labelwidth();
- if(wid < (maxx-startx)-30){
+ if(wid < dx-10){
/* else there's not enough room */
maxx -= 1+Lx+wid;
draw(screen, Rect(maxx, starty, maxx+1, screen->r.max.y), display->black, nil, ZP);
/* create graphs */
for(i=0; i<nmach; i++){
- machr = Rect(startx+i*dx, starty, maxx, screen->r.max.y);
- if(i < nmach-1)
- machr.max.x = startx+(i+1)*dx - 1;
+ machr = Rect(startx+i*dx, starty, startx+(i+1)*dx - 1, screen->r.max.y);
+ if(i == nmach-1)
+ machr.max.x = maxx;
y = starty;
for(j=0; j<ngraph; j++, y+=dy){
g = &graph[i*ngraph+j];
if(r.max.x <= g->r.max.x)
g->overtmp = allocimage(display, r, screen->chan, 0, -1);
g->newvalue(g->mach, &v, &vmax, 0);
+ if(vmax == 0)
+ vmax = 1;
redraw(g, vmax);
}
}
}
void
-mouseproc(void)
+inputproc(void)
{
- Mouse mouse;
+ Event e;
int i;
for(;;){
- mouse = emouse();
- if(mouse.buttons == 4){
- lockdisplay(display);
- for(i=0; i<Nmenu2; i++)
- if(present[i])
- memmove(menu2str[i], "drop ", Opwid);
- else
- memmove(menu2str[i], "add ", Opwid);
- i = emenuhit(3, &mouse, &menu2);
- if(i >= 0){
- if(!present[i])
- addgraph(i);
- else if(ngraph > 1)
- dropgraph(i);
- resize();
+ switch(eread(Emouse|Ekeyboard, &e)){
+ case Emouse:
+ if(e.mouse.buttons == 4){
+ lockdisplay(display);
+ for(i=0; i<Nmenu2; i++)
+ if(present[i])
+ memmove(menu2str[i], "drop ", Opwid);
+ else
+ memmove(menu2str[i], "add ", Opwid);
+ i = emenuhit(3, &e.mouse, &menu2);
+ if(i >= 0){
+ if(!present[i])
+ addgraph(i);
+ else if(ngraph > 1)
+ dropgraph(i);
+ resize();
+ }
+ unlockdisplay(display);
}
- unlockdisplay(display);
+ break;
+ case Ekeyboard:
+ if(e.kbdc==Kdel || e.kbdc=='q')
+ killall(nil);
+ break;
}
}
}
uvlong v, vmax, nargs;
char args[100];
+ quotefmtinstall();
+
nmach = 1;
mysysname = getenv("sysname");
if(mysysname == nil){
ylabels++;
break;
case 'O':
- oldsystem = 1;
break;
default:
if(nargs>=sizeof args || strchr(argchars, ARGC())==nil)
initmach(&mach[0], mysysname);
readmach(&mach[0], 1);
}else{
+ rfork(RFNAMEG);
for(i=j=0; i<argc; i++){
if (addmachine(argv[i]))
readmach(&mach[j++], 1);
case 'p':
addgraph(Mtlbpurge);
break;
+ case 'r':
+ addgraph(Mreclaim);
+ break;
case 's':
addgraph(Msyscall);
break;
case 'w':
addgraph(Mswap);
break;
+ case 'k':
+ addgraph(Mkern);
+ break;
+ case 'd':
+ addgraph(Mdraw);
+ break;
case 'z':
addgraph(Mtemp);
break;
fprint(2, "stats: initdraw failed: %r\n");
exits("initdraw");
}
+ display->locking = 1; /* tell library we're using the display lock */
colinit();
- einit(Emouse);
- startproc(mouseproc, Mouseproc);
+ einit(Emouse|Ekeyboard);
+ startproc(inputproc, Inputproc);
pids[Mainproc] = getpid();
- display->locking = 1; /* tell library we're using the display lock */
resize();
parity = 1-parity;
for(i=0; i<nmach*ngraph; i++){
graph[i].newvalue(graph[i].mach, &v, &vmax, 0);
+ if(vmax == 0)
+ vmax = 1;
graph[i].update(&graph[i], v, vmax);
}
flushimage(display, 1);