13e12c5d1SDavid du Colombier #include <u.h> 23e12c5d1SDavid du Colombier #include <libc.h> 37dd7cddfSDavid du Colombier #include <ctype.h> 47dd7cddfSDavid du Colombier #include <auth.h> 57dd7cddfSDavid du Colombier #include <fcall.h> 67dd7cddfSDavid du Colombier #include <draw.h> 77dd7cddfSDavid du Colombier #include <event.h> 83e12c5d1SDavid du Colombier 97dd7cddfSDavid du Colombier #define MAXNUM 8 /* maximum number of numbers on data line */ 103e12c5d1SDavid du Colombier 117dd7cddfSDavid du Colombier typedef struct Graph Graph; 127dd7cddfSDavid du Colombier typedef struct Machine Machine; 137dd7cddfSDavid du Colombier 147dd7cddfSDavid du Colombier struct Graph 157dd7cddfSDavid du Colombier { 167dd7cddfSDavid du Colombier int colindex; 177dd7cddfSDavid du Colombier Rectangle r; 187dd7cddfSDavid du Colombier int *data; 197dd7cddfSDavid du Colombier int ndata; 207dd7cddfSDavid du Colombier char *label; 2180ee5cbfSDavid du Colombier void (*newvalue)(Machine*, long*, long*, int); 227dd7cddfSDavid du Colombier void (*update)(Graph*, long, long); 237dd7cddfSDavid du Colombier Machine *mach; 247dd7cddfSDavid du Colombier int overflow; 257dd7cddfSDavid du Colombier Image *overtmp; 267dd7cddfSDavid du Colombier }; 273e12c5d1SDavid du Colombier 283e12c5d1SDavid du Colombier enum 293e12c5d1SDavid du Colombier { 307dd7cddfSDavid du Colombier /* /dev/swap */ 317dd7cddfSDavid du Colombier Mem = 0, 327dd7cddfSDavid du Colombier Maxmem, 333e12c5d1SDavid du Colombier Swap, 347dd7cddfSDavid du Colombier Maxswap, 357dd7cddfSDavid du Colombier /* /dev/sysstats */ 367dd7cddfSDavid du Colombier Procno = 0, 377dd7cddfSDavid du Colombier Context, 387dd7cddfSDavid du Colombier Interrupt, 393e12c5d1SDavid du Colombier Syscall, 403e12c5d1SDavid du Colombier Fault, 417dd7cddfSDavid du Colombier TLBfault, 427dd7cddfSDavid du Colombier TLBpurge, 433e12c5d1SDavid du Colombier Load, 447dd7cddfSDavid du Colombier /* /net/ether0/0/stats */ 457dd7cddfSDavid du Colombier In = 0, 467dd7cddfSDavid du Colombier Out, 477dd7cddfSDavid du Colombier Err0, 483e12c5d1SDavid du Colombier }; 493e12c5d1SDavid du Colombier 507dd7cddfSDavid du Colombier struct Machine 513e12c5d1SDavid du Colombier { 527dd7cddfSDavid du Colombier char *name; 537dd7cddfSDavid du Colombier int remote; 547dd7cddfSDavid du Colombier int statsfd; 557dd7cddfSDavid du Colombier int swapfd; 567dd7cddfSDavid du Colombier int etherfd; 579a747e4fSDavid du Colombier int ifstatsfd; 5880ee5cbfSDavid du Colombier int batteryfd; 599a747e4fSDavid du Colombier int bitsybatfd; 607dd7cddfSDavid du Colombier int disable; 613e12c5d1SDavid du Colombier 627dd7cddfSDavid du Colombier long devswap[4]; 637dd7cddfSDavid du Colombier long devsysstat[8]; 647dd7cddfSDavid du Colombier long prevsysstat[8]; 657dd7cddfSDavid du Colombier int nproc; 667dd7cddfSDavid du Colombier long netetherstats[8]; 677dd7cddfSDavid du Colombier long prevetherstats[8]; 6880ee5cbfSDavid du Colombier long batterystats[2]; 699a747e4fSDavid du Colombier long netetherifstats[2]; 703e12c5d1SDavid du Colombier 717dd7cddfSDavid du Colombier char buf[1024]; 727dd7cddfSDavid du Colombier char *bufp; 737dd7cddfSDavid du Colombier char *ebufp; 743e12c5d1SDavid du Colombier }; 757dd7cddfSDavid du Colombier 767dd7cddfSDavid du Colombier enum 777dd7cddfSDavid du Colombier { 787dd7cddfSDavid du Colombier Mainproc, 797dd7cddfSDavid du Colombier Mouseproc, 807dd7cddfSDavid du Colombier NPROC, 817dd7cddfSDavid du Colombier }; 827dd7cddfSDavid du Colombier 837dd7cddfSDavid du Colombier enum 847dd7cddfSDavid du Colombier { 857dd7cddfSDavid du Colombier Ncolor = 6, 867dd7cddfSDavid du Colombier Ysqueeze = 2, /* vertical squeezing of label text */ 877dd7cddfSDavid du Colombier Labspace = 2, /* room around label */ 887dd7cddfSDavid du Colombier Dot = 2, /* height of dot */ 897dd7cddfSDavid du Colombier Opwid = 5, /* strlen("add ") or strlen("drop ") */ 9080ee5cbfSDavid du Colombier Nlab = 3, /* max number of labels on y axis */ 9180ee5cbfSDavid du Colombier Lablen = 16, /* max length of label */ 9280ee5cbfSDavid du Colombier Lx = 4, /* label tick length */ 937dd7cddfSDavid du Colombier }; 947dd7cddfSDavid du Colombier 957dd7cddfSDavid du Colombier enum Menu2 967dd7cddfSDavid du Colombier { 977dd7cddfSDavid du Colombier Mcontext, 987dd7cddfSDavid du Colombier Mether, 997dd7cddfSDavid du Colombier Methererr, 1007dd7cddfSDavid du Colombier Metherin, 1017dd7cddfSDavid du Colombier Metherout, 1027dd7cddfSDavid du Colombier Mfault, 1037dd7cddfSDavid du Colombier Mintr, 1047dd7cddfSDavid du Colombier Mload, 1057dd7cddfSDavid du Colombier Mmem, 1067dd7cddfSDavid du Colombier Mswap, 1077dd7cddfSDavid du Colombier Msyscall, 1087dd7cddfSDavid du Colombier Mtlbmiss, 1097dd7cddfSDavid du Colombier Mtlbpurge, 11080ee5cbfSDavid du Colombier Mbattery, 1119a747e4fSDavid du Colombier Msignal, 1127dd7cddfSDavid du Colombier Nmenu2, 1137dd7cddfSDavid du Colombier }; 1147dd7cddfSDavid du Colombier 1157dd7cddfSDavid du Colombier char *menu2str[Nmenu2+1] = { 1167dd7cddfSDavid du Colombier "add context ", 1177dd7cddfSDavid du Colombier "add ether ", 1187dd7cddfSDavid du Colombier "add ethererr", 1197dd7cddfSDavid du Colombier "add etherin ", 1207dd7cddfSDavid du Colombier "add etherout", 1217dd7cddfSDavid du Colombier "add fault ", 1227dd7cddfSDavid du Colombier "add intr ", 1237dd7cddfSDavid du Colombier "add load ", 1247dd7cddfSDavid du Colombier "add mem ", 1257dd7cddfSDavid du Colombier "add swap ", 1267dd7cddfSDavid du Colombier "add syscall ", 1277dd7cddfSDavid du Colombier "add tlbmiss ", 1287dd7cddfSDavid du Colombier "add tlbpurge", 12980ee5cbfSDavid du Colombier "add battery ", 1309a747e4fSDavid du Colombier "add 802.11b ", 1317dd7cddfSDavid du Colombier nil, 1327dd7cddfSDavid du Colombier }; 1337dd7cddfSDavid du Colombier 1347dd7cddfSDavid du Colombier 13580ee5cbfSDavid du Colombier void contextval(Machine*, long*, long*, int), 13680ee5cbfSDavid du Colombier etherval(Machine*, long*, long*, int), 13780ee5cbfSDavid du Colombier ethererrval(Machine*, long*, long*, int), 13880ee5cbfSDavid du Colombier etherinval(Machine*, long*, long*, int), 13980ee5cbfSDavid du Colombier etheroutval(Machine*, long*, long*, int), 14080ee5cbfSDavid du Colombier faultval(Machine*, long*, long*, int), 14180ee5cbfSDavid du Colombier intrval(Machine*, long*, long*, int), 14280ee5cbfSDavid du Colombier loadval(Machine*, long*, long*, int), 14380ee5cbfSDavid du Colombier memval(Machine*, long*, long*, int), 14480ee5cbfSDavid du Colombier swapval(Machine*, long*, long*, int), 14580ee5cbfSDavid du Colombier syscallval(Machine*, long*, long*, int), 14680ee5cbfSDavid du Colombier tlbmissval(Machine*, long*, long*, int), 14780ee5cbfSDavid du Colombier tlbpurgeval(Machine*, long*, long*, int), 1489a747e4fSDavid du Colombier batteryval(Machine*, long*, long*, int), 1499a747e4fSDavid du Colombier signalval(Machine*, long*, long*, int); 1507dd7cddfSDavid du Colombier 1517dd7cddfSDavid du Colombier Menu menu2 = {menu2str, nil}; 1527dd7cddfSDavid du Colombier int present[Nmenu2]; 15380ee5cbfSDavid du Colombier void (*newvaluefn[Nmenu2])(Machine*, long*, long*, int init) = { 1547dd7cddfSDavid du Colombier contextval, 1557dd7cddfSDavid du Colombier etherval, 1567dd7cddfSDavid du Colombier ethererrval, 1577dd7cddfSDavid du Colombier etherinval, 1587dd7cddfSDavid du Colombier etheroutval, 1597dd7cddfSDavid du Colombier faultval, 1607dd7cddfSDavid du Colombier intrval, 1617dd7cddfSDavid du Colombier loadval, 1627dd7cddfSDavid du Colombier memval, 1637dd7cddfSDavid du Colombier swapval, 1647dd7cddfSDavid du Colombier syscallval, 1657dd7cddfSDavid du Colombier tlbmissval, 1667dd7cddfSDavid du Colombier tlbpurgeval, 16780ee5cbfSDavid du Colombier batteryval, 1689a747e4fSDavid du Colombier signalval, 1697dd7cddfSDavid du Colombier }; 1707dd7cddfSDavid du Colombier 1717dd7cddfSDavid du Colombier Image *cols[Ncolor][3]; 1727dd7cddfSDavid du Colombier Graph *graph; 1737dd7cddfSDavid du Colombier Machine *mach; 1747dd7cddfSDavid du Colombier Font *mediumfont; 1757dd7cddfSDavid du Colombier char *mysysname; 1769a747e4fSDavid du Colombier char argchars[] = "8bceEfimlnpstw"; 1777dd7cddfSDavid du Colombier int pids[NPROC]; 1787dd7cddfSDavid du Colombier int parity; /* toggled to avoid patterns in textured background */ 1797dd7cddfSDavid du Colombier int nmach; 1807dd7cddfSDavid du Colombier int ngraph; /* totaly number is ngraph*nmach */ 18180ee5cbfSDavid du Colombier double scale = 1.0; 18280ee5cbfSDavid du Colombier int logscale = 0; 18380ee5cbfSDavid du Colombier int ylabels = 0; 1849a747e4fSDavid du Colombier int oldsystem = 0; 1857dd7cddfSDavid du Colombier 1867dd7cddfSDavid du Colombier char *procnames[NPROC] = {"main", "mouse"}; 1877dd7cddfSDavid du Colombier 1887dd7cddfSDavid du Colombier void 1897dd7cddfSDavid du Colombier killall(char *s) 1907dd7cddfSDavid du Colombier { 1917dd7cddfSDavid du Colombier int i, pid; 1927dd7cddfSDavid du Colombier 1937dd7cddfSDavid du Colombier pid = getpid(); 1947dd7cddfSDavid du Colombier for(i=0; i<NPROC; i++) 1957dd7cddfSDavid du Colombier if(pids[i] && pids[i]!=pid) 1967dd7cddfSDavid du Colombier postnote(PNPROC, pids[i], "kill"); 1977dd7cddfSDavid du Colombier exits(s); 1987dd7cddfSDavid du Colombier } 1997dd7cddfSDavid du Colombier 2007dd7cddfSDavid du Colombier void* 2017dd7cddfSDavid du Colombier emalloc(ulong sz) 2027dd7cddfSDavid du Colombier { 2037dd7cddfSDavid du Colombier void *v; 2047dd7cddfSDavid du Colombier v = malloc(sz); 2057dd7cddfSDavid du Colombier if(v == nil) { 2067dd7cddfSDavid du Colombier fprint(2, "stats: out of memory allocating %ld: %r\n", sz); 2077dd7cddfSDavid du Colombier killall("mem"); 2087dd7cddfSDavid du Colombier } 2097dd7cddfSDavid du Colombier memset(v, 0, sz); 2107dd7cddfSDavid du Colombier return v; 2117dd7cddfSDavid du Colombier } 2127dd7cddfSDavid du Colombier 2137dd7cddfSDavid du Colombier void* 2147dd7cddfSDavid du Colombier erealloc(void *v, ulong sz) 2157dd7cddfSDavid du Colombier { 2167dd7cddfSDavid du Colombier v = realloc(v, sz); 2177dd7cddfSDavid du Colombier if(v == nil) { 2187dd7cddfSDavid du Colombier fprint(2, "stats: out of memory reallocating %ld: %r\n", sz); 2197dd7cddfSDavid du Colombier killall("mem"); 2207dd7cddfSDavid du Colombier } 2217dd7cddfSDavid du Colombier return v; 2223e12c5d1SDavid du Colombier } 2233e12c5d1SDavid du Colombier 2243e12c5d1SDavid du Colombier char* 2257dd7cddfSDavid du Colombier estrdup(char *s) 2263e12c5d1SDavid du Colombier { 2277dd7cddfSDavid du Colombier char *t; 2287dd7cddfSDavid du Colombier if((t = strdup(s)) == nil) { 2297dd7cddfSDavid du Colombier fprint(2, "stats: out of memory in strdup(%.10s): %r\n", s); 2307dd7cddfSDavid du Colombier killall("mem"); 2317dd7cddfSDavid du Colombier } 2327dd7cddfSDavid du Colombier return t; 2333e12c5d1SDavid du Colombier } 2343e12c5d1SDavid du Colombier 2353e12c5d1SDavid du Colombier void 2367dd7cddfSDavid du Colombier mkcol(int i, int c0, int c1, int c2) 2373e12c5d1SDavid du Colombier { 2387dd7cddfSDavid du Colombier cols[i][0] = allocimagemix(display, c0, DWhite); 2397dd7cddfSDavid du Colombier cols[i][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c1); 2407dd7cddfSDavid du Colombier cols[i][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c2); 2417dd7cddfSDavid du Colombier } 2423e12c5d1SDavid du Colombier 2437dd7cddfSDavid du Colombier void 2447dd7cddfSDavid du Colombier colinit(void) 2457dd7cddfSDavid du Colombier { 2467dd7cddfSDavid du Colombier mediumfont = openfont(display, "/lib/font/bit/pelm/latin1.8.font"); 2477dd7cddfSDavid du Colombier if(mediumfont == nil) 2487dd7cddfSDavid du Colombier mediumfont = font; 2497dd7cddfSDavid du Colombier 2507dd7cddfSDavid du Colombier /* Peach */ 2517dd7cddfSDavid du Colombier mkcol(0, 0xFFAAAAFF, 0xFFAAAAFF, 0xBB5D5DFF); 2527dd7cddfSDavid du Colombier /* Aqua */ 2537dd7cddfSDavid du Colombier mkcol(1, DPalebluegreen, DPalegreygreen, DPurpleblue); 2547dd7cddfSDavid du Colombier /* Yellow */ 2557dd7cddfSDavid du Colombier mkcol(2, DPaleyellow, DDarkyellow, DYellowgreen); 2567dd7cddfSDavid du Colombier /* Green */ 2577dd7cddfSDavid du Colombier mkcol(3, DPalegreen, DMedgreen, DDarkgreen); 2587dd7cddfSDavid du Colombier /* Blue */ 2597dd7cddfSDavid du Colombier mkcol(4, 0x00AAFFFF, 0x00AAFFFF, 0x0088CCFF); 2607dd7cddfSDavid du Colombier /* Grey */ 2617dd7cddfSDavid du Colombier cols[5][0] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xEEEEEEFF); 2627dd7cddfSDavid du Colombier cols[5][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF); 2637dd7cddfSDavid du Colombier cols[5][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x888888FF); 2647dd7cddfSDavid du Colombier } 2657dd7cddfSDavid du Colombier 2667dd7cddfSDavid du Colombier int 2677dd7cddfSDavid du Colombier loadbuf(Machine *m, int *fd) 2687dd7cddfSDavid du Colombier { 2697dd7cddfSDavid du Colombier int n; 2707dd7cddfSDavid du Colombier 2717dd7cddfSDavid du Colombier 2727dd7cddfSDavid du Colombier if(*fd < 0) 2737dd7cddfSDavid du Colombier return 0; 2747dd7cddfSDavid du Colombier seek(*fd, 0, 0); 2757dd7cddfSDavid du Colombier n = read(*fd, m->buf, sizeof m->buf); 2767dd7cddfSDavid du Colombier if(n <= 0){ 2777dd7cddfSDavid du Colombier close(*fd); 2787dd7cddfSDavid du Colombier *fd = -1; 2797dd7cddfSDavid du Colombier return 0; 2807dd7cddfSDavid du Colombier } 2817dd7cddfSDavid du Colombier m->bufp = m->buf; 2827dd7cddfSDavid du Colombier m->ebufp = m->buf+n; 2837dd7cddfSDavid du Colombier return 1; 2847dd7cddfSDavid du Colombier } 2857dd7cddfSDavid du Colombier 2867dd7cddfSDavid du Colombier void 2877dd7cddfSDavid du Colombier label(Point p, int dy, char *text) 2887dd7cddfSDavid du Colombier { 2897dd7cddfSDavid du Colombier char *s; 2907dd7cddfSDavid du Colombier Rune r[2]; 2917dd7cddfSDavid du Colombier int w, maxw, maxy; 2927dd7cddfSDavid du Colombier 2937dd7cddfSDavid du Colombier p.x += Labspace; 2947dd7cddfSDavid du Colombier maxy = p.y+dy; 2957dd7cddfSDavid du Colombier maxw = 0; 2967dd7cddfSDavid du Colombier r[1] = '\0'; 2977dd7cddfSDavid du Colombier for(s=text; *s; ){ 2987dd7cddfSDavid du Colombier if(p.y+mediumfont->height-Ysqueeze > maxy) 2997dd7cddfSDavid du Colombier break; 3007dd7cddfSDavid du Colombier w = chartorune(r, s); 3017dd7cddfSDavid du Colombier s += w; 3027dd7cddfSDavid du Colombier w = runestringwidth(mediumfont, r); 3037dd7cddfSDavid du Colombier if(w > maxw) 3047dd7cddfSDavid du Colombier maxw = w; 3057dd7cddfSDavid du Colombier runestring(screen, p, display->black, ZP, mediumfont, r); 3067dd7cddfSDavid du Colombier p.y += mediumfont->height-Ysqueeze; 3077dd7cddfSDavid du Colombier } 3087dd7cddfSDavid du Colombier } 3097dd7cddfSDavid du Colombier 3107dd7cddfSDavid du Colombier Point 3117dd7cddfSDavid du Colombier paritypt(int x) 3127dd7cddfSDavid du Colombier { 3137dd7cddfSDavid du Colombier return Pt(x+parity, 0); 3147dd7cddfSDavid du Colombier } 3157dd7cddfSDavid du Colombier 3167dd7cddfSDavid du Colombier Point 3177dd7cddfSDavid du Colombier datapoint(Graph *g, int x, long v, long vmax) 3187dd7cddfSDavid du Colombier { 3197dd7cddfSDavid du Colombier Point p; 32080ee5cbfSDavid du Colombier double y; 3217dd7cddfSDavid du Colombier 3227dd7cddfSDavid du Colombier p.x = x; 32380ee5cbfSDavid du Colombier y = ((double)v)/(vmax*scale); 32480ee5cbfSDavid du Colombier if(logscale){ 32580ee5cbfSDavid du Colombier /* 32680ee5cbfSDavid du Colombier * Arrange scale to cover a factor of 1000. 32780ee5cbfSDavid du Colombier * vmax corresponds to the 100 mark. 32880ee5cbfSDavid du Colombier * 10*vmax is the top of the scale. 32980ee5cbfSDavid du Colombier */ 33080ee5cbfSDavid du Colombier if(y <= 0.) 33180ee5cbfSDavid du Colombier y = 0; 33280ee5cbfSDavid du Colombier else{ 33380ee5cbfSDavid du Colombier y = log10(y); 33480ee5cbfSDavid du Colombier /* 1 now corresponds to the top; -2 to the bottom; rescale */ 33580ee5cbfSDavid du Colombier y = (y+2.)/3.; 33680ee5cbfSDavid du Colombier } 33780ee5cbfSDavid du Colombier } 33880ee5cbfSDavid du Colombier p.y = g->r.max.y - Dy(g->r)*y - Dot; 3397dd7cddfSDavid du Colombier if(p.y < g->r.min.y) 3407dd7cddfSDavid du Colombier p.y = g->r.min.y; 3417dd7cddfSDavid du Colombier if(p.y > g->r.max.y-Dot) 3427dd7cddfSDavid du Colombier p.y = g->r.max.y-Dot; 3437dd7cddfSDavid du Colombier return p; 3447dd7cddfSDavid du Colombier } 3457dd7cddfSDavid du Colombier 3467dd7cddfSDavid du Colombier void 3477dd7cddfSDavid du Colombier drawdatum(Graph *g, int x, long prev, long v, long vmax) 3487dd7cddfSDavid du Colombier { 3497dd7cddfSDavid du Colombier int c; 3507dd7cddfSDavid du Colombier Point p, q; 3517dd7cddfSDavid du Colombier 3527dd7cddfSDavid du Colombier c = g->colindex; 3537dd7cddfSDavid du Colombier p = datapoint(g, x, v, vmax); 3547dd7cddfSDavid du Colombier q = datapoint(g, x, prev, vmax); 3557dd7cddfSDavid du Colombier if(p.y < q.y){ 3567dd7cddfSDavid du Colombier draw(screen, Rect(p.x, g->r.min.y, p.x+1, p.y), cols[c][0], nil, paritypt(p.x)); 3577dd7cddfSDavid du Colombier draw(screen, Rect(p.x, p.y, p.x+1, q.y+Dot), cols[c][2], nil, ZP); 3587dd7cddfSDavid du Colombier draw(screen, Rect(p.x, q.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP); 3597dd7cddfSDavid du Colombier }else{ 3607dd7cddfSDavid du Colombier draw(screen, Rect(p.x, g->r.min.y, p.x+1, q.y), cols[c][0], nil, paritypt(p.x)); 3617dd7cddfSDavid du Colombier draw(screen, Rect(p.x, q.y, p.x+1, p.y+Dot), cols[c][2], nil, ZP); 3627dd7cddfSDavid du Colombier draw(screen, Rect(p.x, p.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP); 3637dd7cddfSDavid du Colombier } 3647dd7cddfSDavid du Colombier 3657dd7cddfSDavid du Colombier } 3667dd7cddfSDavid du Colombier 3677dd7cddfSDavid du Colombier void 3687dd7cddfSDavid du Colombier redraw(Graph *g, int vmax) 3697dd7cddfSDavid du Colombier { 3707dd7cddfSDavid du Colombier int i, c; 3717dd7cddfSDavid du Colombier 3727dd7cddfSDavid du Colombier c = g->colindex; 3737dd7cddfSDavid du Colombier draw(screen, g->r, cols[c][0], nil, paritypt(g->r.min.x)); 3747dd7cddfSDavid du Colombier for(i=1; i<Dx(g->r); i++) 3757dd7cddfSDavid du Colombier drawdatum(g, g->r.max.x-i, g->data[i-1], g->data[i], vmax); 3767dd7cddfSDavid du Colombier drawdatum(g, g->r.min.x, g->data[i], g->data[i], vmax); 3777dd7cddfSDavid du Colombier g->overflow = 0; 3787dd7cddfSDavid du Colombier } 3797dd7cddfSDavid du Colombier 3807dd7cddfSDavid du Colombier void 3817dd7cddfSDavid du Colombier update1(Graph *g, long v, long vmax) 3827dd7cddfSDavid du Colombier { 3837dd7cddfSDavid du Colombier char buf[32]; 38480ee5cbfSDavid du Colombier int overflow; 3857dd7cddfSDavid du Colombier 3867dd7cddfSDavid du Colombier if(g->overflow && g->overtmp!=nil) 3877dd7cddfSDavid du Colombier draw(screen, g->overtmp->r, g->overtmp, nil, g->overtmp->r.min); 3887dd7cddfSDavid du Colombier draw(screen, g->r, screen, nil, Pt(g->r.min.x+1, g->r.min.y)); 3897dd7cddfSDavid du Colombier drawdatum(g, g->r.max.x-1, g->data[0], v, vmax); 3907dd7cddfSDavid du Colombier memmove(g->data+1, g->data, (g->ndata-1)*sizeof(g->data[0])); 3917dd7cddfSDavid du Colombier g->data[0] = v; 3927dd7cddfSDavid du Colombier g->overflow = 0; 39380ee5cbfSDavid du Colombier if(logscale) 39480ee5cbfSDavid du Colombier overflow = (v>10*vmax*scale); 39580ee5cbfSDavid du Colombier else 39680ee5cbfSDavid du Colombier overflow = (v>vmax*scale); 39780ee5cbfSDavid du Colombier if(overflow && g->overtmp!=nil){ 3987dd7cddfSDavid du Colombier g->overflow = 1; 3997dd7cddfSDavid du Colombier draw(g->overtmp, g->overtmp->r, screen, nil, g->overtmp->r.min); 4007dd7cddfSDavid du Colombier sprint(buf, "%ld", v); 4017dd7cddfSDavid du Colombier string(screen, g->overtmp->r.min, display->black, ZP, mediumfont, buf); 4027dd7cddfSDavid du Colombier } 4037dd7cddfSDavid du Colombier } 4047dd7cddfSDavid du Colombier 4057dd7cddfSDavid du Colombier /* read one line of text from buffer and process integers */ 4067dd7cddfSDavid du Colombier int 4077dd7cddfSDavid du Colombier readnums(Machine *m, int n, long *a, int spanlines) 4087dd7cddfSDavid du Colombier { 4097dd7cddfSDavid du Colombier int i; 4107dd7cddfSDavid du Colombier char *p, *ep; 4117dd7cddfSDavid du Colombier 4127dd7cddfSDavid du Colombier if(spanlines) 4137dd7cddfSDavid du Colombier ep = m->ebufp; 4147dd7cddfSDavid du Colombier else 4157dd7cddfSDavid du Colombier for(ep=m->bufp; ep<m->ebufp; ep++) 4167dd7cddfSDavid du Colombier if(*ep == '\n') 4177dd7cddfSDavid du Colombier break; 4187dd7cddfSDavid du Colombier p = m->bufp; 4197dd7cddfSDavid du Colombier for(i=0; i<n && p<ep; i++){ 4209a747e4fSDavid du Colombier while(p<ep && !isdigit(*p) && *p!='-') 4217dd7cddfSDavid du Colombier p++; 4227dd7cddfSDavid du Colombier if(p == ep) 4237dd7cddfSDavid du Colombier break; 4247dd7cddfSDavid du Colombier a[i] = strtol(p, &p, 10); 4257dd7cddfSDavid du Colombier } 4267dd7cddfSDavid du Colombier if(ep < m->ebufp) 4277dd7cddfSDavid du Colombier ep++; 4287dd7cddfSDavid du Colombier m->bufp = ep; 4297dd7cddfSDavid du Colombier return i == n; 4307dd7cddfSDavid du Colombier } 4317dd7cddfSDavid du Colombier 4327dd7cddfSDavid du Colombier /* Network on fd1, mount driver on fd0 */ 4337dd7cddfSDavid du Colombier static int 4347dd7cddfSDavid du Colombier filter(int fd) 4357dd7cddfSDavid du Colombier { 4367dd7cddfSDavid du Colombier int p[2]; 4377dd7cddfSDavid du Colombier 4387dd7cddfSDavid du Colombier if(pipe(p) < 0){ 4397dd7cddfSDavid du Colombier fprint(2, "stats: can't pipe: %r\n"); 4407dd7cddfSDavid du Colombier killall("pipe"); 4417dd7cddfSDavid du Colombier } 4427dd7cddfSDavid du Colombier 4437dd7cddfSDavid du Colombier switch(rfork(RFNOWAIT|RFPROC|RFFDG)) { 4447dd7cddfSDavid du Colombier case -1: 4457dd7cddfSDavid du Colombier sysfatal("rfork record module"); 4467dd7cddfSDavid du Colombier case 0: 4477dd7cddfSDavid du Colombier dup(fd, 1); 4487dd7cddfSDavid du Colombier close(fd); 4497dd7cddfSDavid du Colombier dup(p[0], 0); 4507dd7cddfSDavid du Colombier close(p[0]); 4517dd7cddfSDavid du Colombier close(p[1]); 4527dd7cddfSDavid du Colombier execl("/bin/aux/fcall", "fcall", 0); 4537dd7cddfSDavid du Colombier fprint(2, "stats: can't exec fcall: %r\n"); 4547dd7cddfSDavid du Colombier killall("fcall"); 4557dd7cddfSDavid du Colombier default: 4567dd7cddfSDavid du Colombier close(fd); 4577dd7cddfSDavid du Colombier close(p[0]); 4587dd7cddfSDavid du Colombier } 4597dd7cddfSDavid du Colombier return p[1]; 4607dd7cddfSDavid du Colombier } 4617dd7cddfSDavid du Colombier 4627dd7cddfSDavid du Colombier /* 4637dd7cddfSDavid du Colombier * 9fs 4647dd7cddfSDavid du Colombier */ 4657dd7cddfSDavid du Colombier int 4667dd7cddfSDavid du Colombier connect9fs(char *addr) 4677dd7cddfSDavid du Colombier { 4689a747e4fSDavid du Colombier char dir[256], *na; 4697dd7cddfSDavid du Colombier int fd; 4707dd7cddfSDavid du Colombier 4717dd7cddfSDavid du Colombier fprint(2, "connect9fs..."); 4727dd7cddfSDavid du Colombier na = netmkaddr(addr, 0, "9fs"); 4737dd7cddfSDavid du Colombier 4747dd7cddfSDavid du Colombier fprint(2, "dial %s...", na); 4757dd7cddfSDavid du Colombier if((fd = dial(na, 0, dir, 0)) < 0) 4767dd7cddfSDavid du Colombier return -1; 4777dd7cddfSDavid du Colombier 4787dd7cddfSDavid du Colombier fprint(2, "dir %s...", dir); 4799a747e4fSDavid du Colombier // if(strstr(dir, "tcp")) 4809a747e4fSDavid du Colombier // fd = filter(fd); 4817dd7cddfSDavid du Colombier return fd; 4827dd7cddfSDavid du Colombier } 4837dd7cddfSDavid du Colombier 4849a747e4fSDavid du Colombier int 4859a747e4fSDavid du Colombier old9p(int fd) 4869a747e4fSDavid du Colombier { 4879a747e4fSDavid du Colombier int p[2]; 4889a747e4fSDavid du Colombier 4899a747e4fSDavid du Colombier if(pipe(p) < 0) 4909a747e4fSDavid du Colombier return -1; 4919a747e4fSDavid du Colombier 4929a747e4fSDavid du Colombier switch(rfork(RFPROC|RFFDG|RFNAMEG)) { 4939a747e4fSDavid du Colombier case -1: 4949a747e4fSDavid du Colombier return -1; 4959a747e4fSDavid du Colombier case 0: 4969a747e4fSDavid du Colombier if(fd != 1){ 4979a747e4fSDavid du Colombier dup(fd, 1); 4989a747e4fSDavid du Colombier close(fd); 4999a747e4fSDavid du Colombier } 5009a747e4fSDavid du Colombier if(p[0] != 0){ 5019a747e4fSDavid du Colombier dup(p[0], 0); 5029a747e4fSDavid du Colombier close(p[0]); 5039a747e4fSDavid du Colombier } 5049a747e4fSDavid du Colombier close(p[1]); 5059a747e4fSDavid du Colombier if(0){ 5069a747e4fSDavid du Colombier fd = open("/sys/log/cpu", OWRITE); 5079a747e4fSDavid du Colombier if(fd != 2){ 5089a747e4fSDavid du Colombier dup(fd, 2); 5099a747e4fSDavid du Colombier close(fd); 5109a747e4fSDavid du Colombier } 5119a747e4fSDavid du Colombier execl("/bin/srvold9p", "srvold9p", "-ds", 0); 5129a747e4fSDavid du Colombier } else 5139a747e4fSDavid du Colombier execl("/bin/srvold9p", "srvold9p", "-s", 0); 5149a747e4fSDavid du Colombier return -1; 5159a747e4fSDavid du Colombier default: 5169a747e4fSDavid du Colombier close(fd); 5179a747e4fSDavid du Colombier close(p[0]); 5189a747e4fSDavid du Colombier } 5199a747e4fSDavid du Colombier return p[1]; 5209a747e4fSDavid du Colombier } 5219a747e4fSDavid du Colombier 5229a747e4fSDavid du Colombier 5237dd7cddfSDavid du Colombier /* 5247dd7cddfSDavid du Colombier * exportfs 5257dd7cddfSDavid du Colombier */ 5267dd7cddfSDavid du Colombier int 5277dd7cddfSDavid du Colombier connectexportfs(char *addr) 5287dd7cddfSDavid du Colombier { 5299a747e4fSDavid du Colombier char buf[ERRMAX], dir[256], *na; 5307dd7cddfSDavid du Colombier int fd, n; 5317dd7cddfSDavid du Colombier char *tree; 5329a747e4fSDavid du Colombier AuthInfo *ai; 5337dd7cddfSDavid du Colombier 5347dd7cddfSDavid du Colombier tree = "/"; 5357dd7cddfSDavid du Colombier na = netmkaddr(addr, 0, "exportfs"); 5367dd7cddfSDavid du Colombier if((fd = dial(na, 0, dir, 0)) < 0) 5377dd7cddfSDavid du Colombier return -1; 5387dd7cddfSDavid du Colombier 5399a747e4fSDavid du Colombier ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client"); 5409a747e4fSDavid du Colombier if(ai == nil) 5417dd7cddfSDavid du Colombier return -1; 5427dd7cddfSDavid du Colombier 5437dd7cddfSDavid du Colombier n = write(fd, tree, strlen(tree)); 5447dd7cddfSDavid du Colombier if(n < 0){ 5457dd7cddfSDavid du Colombier close(fd); 5467dd7cddfSDavid du Colombier return -1; 5477dd7cddfSDavid du Colombier } 5487dd7cddfSDavid du Colombier 5497dd7cddfSDavid du Colombier strcpy(buf, "can't read tree"); 5507dd7cddfSDavid du Colombier n = read(fd, buf, sizeof buf - 1); 5517dd7cddfSDavid du Colombier if(n!=2 || buf[0]!='O' || buf[1]!='K'){ 5527dd7cddfSDavid du Colombier buf[sizeof buf - 1] = '\0'; 5537dd7cddfSDavid du Colombier werrstr("bad remote tree: %s\n", buf); 5547dd7cddfSDavid du Colombier close(fd); 5557dd7cddfSDavid du Colombier return -1; 5567dd7cddfSDavid du Colombier } 5577dd7cddfSDavid du Colombier 5589a747e4fSDavid du Colombier // if(strstr(dir, "tcp")) 5599a747e4fSDavid du Colombier // fd = filter(fd); 5609a747e4fSDavid du Colombier 5619a747e4fSDavid du Colombier if(oldsystem) 5629a747e4fSDavid du Colombier return old9p(fd); 5637dd7cddfSDavid du Colombier 5647dd7cddfSDavid du Colombier return fd; 5657dd7cddfSDavid du Colombier } 5667dd7cddfSDavid du Colombier 5677dd7cddfSDavid du Colombier void 5687dd7cddfSDavid du Colombier initmach(Machine *m, char *name) 5697dd7cddfSDavid du Colombier { 5707dd7cddfSDavid du Colombier int n, fd; 5717dd7cddfSDavid du Colombier long a[MAXNUM]; 5727dd7cddfSDavid du Colombier char *p, mpt[256], buf[256]; 5737dd7cddfSDavid du Colombier 5747dd7cddfSDavid du Colombier p = strchr(name, '!'); 5757dd7cddfSDavid du Colombier if(p){ 5767dd7cddfSDavid du Colombier p++; 5777dd7cddfSDavid du Colombier m->name = estrdup(p+1); 5787dd7cddfSDavid du Colombier }else 5797dd7cddfSDavid du Colombier p = name; 5807dd7cddfSDavid du Colombier m->name = estrdup(p); 5817dd7cddfSDavid du Colombier m->remote = (strcmp(p, mysysname) != 0); 5827dd7cddfSDavid du Colombier if(m->remote == 0) 5837dd7cddfSDavid du Colombier strcpy(mpt, ""); 5847dd7cddfSDavid du Colombier else{ 5857dd7cddfSDavid du Colombier snprint(mpt, sizeof mpt, "/n/%s", p); 5867dd7cddfSDavid du Colombier fd = connectexportfs(name); 5877dd7cddfSDavid du Colombier if(fd < 0){ 5887dd7cddfSDavid du Colombier fprint(2, "can't connect to %s: %r\n", name); 5897dd7cddfSDavid du Colombier killall("connect"); 5907dd7cddfSDavid du Colombier } 5919a747e4fSDavid du Colombier /* BUG? need to use amount() now? */ 5929a747e4fSDavid du Colombier if(mount(fd, -1, mpt, MREPL, "") < 0){ 5937dd7cddfSDavid du Colombier fprint(2, "stats: mount %s on %s failed (%r); trying /n/sid\n", name, mpt); 5947dd7cddfSDavid du Colombier strcpy(mpt, "/n/sid"); 5959a747e4fSDavid du Colombier if(mount(fd, -1, mpt, MREPL, "") < 0){ 5967dd7cddfSDavid du Colombier fprint(2, "stats: mount %s on %s failed: %r\n", name, mpt); 5977dd7cddfSDavid du Colombier killall("mount"); 5987dd7cddfSDavid du Colombier } 5997dd7cddfSDavid du Colombier } 6007dd7cddfSDavid du Colombier } 6017dd7cddfSDavid du Colombier 6027dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/swap", mpt); 6037dd7cddfSDavid du Colombier m->swapfd = open(buf, OREAD); 6047dd7cddfSDavid du Colombier if(loadbuf(m, &m->swapfd) && readnums(m, nelem(m->devswap), a, 0)) 6057dd7cddfSDavid du Colombier memmove(m->devswap, a, sizeof m->devswap); 6067dd7cddfSDavid du Colombier else 6077dd7cddfSDavid du Colombier m->devswap[Maxmem] = m->devswap[Maxswap] = 100; 6087dd7cddfSDavid du Colombier 6097dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/sysstat", mpt); 6107dd7cddfSDavid du Colombier m->statsfd = open(buf, OREAD); 6117dd7cddfSDavid du Colombier if(loadbuf(m, &m->statsfd)){ 6127dd7cddfSDavid du Colombier for(n=0; readnums(m, nelem(m->devsysstat), a, 0); n++) 6137dd7cddfSDavid du Colombier ; 6147dd7cddfSDavid du Colombier m->nproc = n; 6157dd7cddfSDavid du Colombier }else 6167dd7cddfSDavid du Colombier m->nproc = 1; 6177dd7cddfSDavid du Colombier 6187dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/net/ether0/0/stats", mpt); 6197dd7cddfSDavid du Colombier m->etherfd = open(buf, OREAD); 6207dd7cddfSDavid du Colombier if(loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1)) 6217dd7cddfSDavid du Colombier memmove(m->netetherstats, a, sizeof m->netetherstats); 62280ee5cbfSDavid du Colombier 6239a747e4fSDavid du Colombier snprint(buf, sizeof buf, "%s/net/ether0/0/ifstats", mpt); 6249a747e4fSDavid du Colombier m->ifstatsfd = open(buf, OREAD); 6259a747e4fSDavid du Colombier if(loadbuf(m, &m->ifstatsfd)){ 6269a747e4fSDavid du Colombier /* need to check that this is a wavelan interface */ 6279a747e4fSDavid du Colombier if(strncmp(m->buf, "Signal: ", 8) == 0 && readnums(m, nelem(m->netetherifstats), a, 1)) 6289a747e4fSDavid du Colombier memmove(m->netetherifstats, a, sizeof m->netetherifstats); 6299a747e4fSDavid du Colombier } 6309a747e4fSDavid du Colombier 63180ee5cbfSDavid du Colombier snprint(buf, sizeof buf, "%s/mnt/apm/battery", mpt); 63280ee5cbfSDavid du Colombier m->batteryfd = open(buf, OREAD); 6339a747e4fSDavid du Colombier m->bitsybatfd = -1; 6349a747e4fSDavid du Colombier if(m->batteryfd >= 0){ 63580ee5cbfSDavid du Colombier if(loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0)) 63680ee5cbfSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats)); 6379a747e4fSDavid du Colombier }else{ 6389a747e4fSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/battery", mpt); 6399a747e4fSDavid du Colombier m->bitsybatfd = open(buf, OREAD); 6409a747e4fSDavid du Colombier if(loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0)) 6419a747e4fSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats)); 6429a747e4fSDavid du Colombier } 6437dd7cddfSDavid du Colombier } 6447dd7cddfSDavid du Colombier 6457dd7cddfSDavid du Colombier jmp_buf catchalarm; 6467dd7cddfSDavid du Colombier 6477dd7cddfSDavid du Colombier void 6487dd7cddfSDavid du Colombier alarmed(void *a, char *s) 6497dd7cddfSDavid du Colombier { 6507dd7cddfSDavid du Colombier if(strcmp(s, "alarm") == 0) 6517dd7cddfSDavid du Colombier notejmp(a, catchalarm, 1); 6523e12c5d1SDavid du Colombier noted(NDFLT); 6533e12c5d1SDavid du Colombier } 6547dd7cddfSDavid du Colombier 6557dd7cddfSDavid du Colombier int 6567dd7cddfSDavid du Colombier needswap(int init) 6577dd7cddfSDavid du Colombier { 6587dd7cddfSDavid du Colombier return init | present[Mmem] | present[Mswap]; 6597dd7cddfSDavid du Colombier } 6607dd7cddfSDavid du Colombier 6617dd7cddfSDavid du Colombier 6627dd7cddfSDavid du Colombier int 6637dd7cddfSDavid du Colombier needstat(int init) 6647dd7cddfSDavid du Colombier { 6657dd7cddfSDavid du Colombier return init | present[Mcontext] | present[Mfault] | present[Mintr] | present[Mload] | 6667dd7cddfSDavid du Colombier present[Msyscall] | present[Mtlbmiss] | present[Mtlbpurge]; 6677dd7cddfSDavid du Colombier } 6687dd7cddfSDavid du Colombier 6697dd7cddfSDavid du Colombier 6707dd7cddfSDavid du Colombier int 6717dd7cddfSDavid du Colombier needether(int init) 6727dd7cddfSDavid du Colombier { 6737dd7cddfSDavid du Colombier return init | present[Mether] | present[Metherin] | present[Metherout] | present[Methererr]; 6747dd7cddfSDavid du Colombier } 6757dd7cddfSDavid du Colombier 67680ee5cbfSDavid du Colombier int 67780ee5cbfSDavid du Colombier needbattery(int init) 67880ee5cbfSDavid du Colombier { 67980ee5cbfSDavid du Colombier return init | present[Mbattery]; 68080ee5cbfSDavid du Colombier } 68180ee5cbfSDavid du Colombier 6829a747e4fSDavid du Colombier int 6839a747e4fSDavid du Colombier needsignal(int init) 6849a747e4fSDavid du Colombier { 6859a747e4fSDavid du Colombier return init | present[Msignal]; 6869a747e4fSDavid du Colombier } 6879a747e4fSDavid du Colombier 6887dd7cddfSDavid du Colombier void 6897dd7cddfSDavid du Colombier readmach(Machine *m, int init) 6907dd7cddfSDavid du Colombier { 6917dd7cddfSDavid du Colombier int n, i; 6927dd7cddfSDavid du Colombier long a[8]; 6937dd7cddfSDavid du Colombier char buf[32]; 6947dd7cddfSDavid du Colombier 6957dd7cddfSDavid du Colombier if(m->remote && (m->disable || setjmp(catchalarm))){ 6967dd7cddfSDavid du Colombier if(m->disable == 0){ 6977dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s(dead)", m->name); 6987dd7cddfSDavid du Colombier m->name = estrdup(buf); 6997dd7cddfSDavid du Colombier if(display != nil) /* else we're still initializing */ 7007dd7cddfSDavid du Colombier eresized(0); 7017dd7cddfSDavid du Colombier } 7027dd7cddfSDavid du Colombier m->disable = 1; 7037dd7cddfSDavid du Colombier memmove(m->devsysstat, m->prevsysstat, sizeof m->devsysstat); 7047dd7cddfSDavid du Colombier memmove(m->netetherstats, m->prevetherstats, sizeof m->netetherstats); 7057dd7cddfSDavid du Colombier return; 7067dd7cddfSDavid du Colombier } 7077dd7cddfSDavid du Colombier if(m->remote){ 7087dd7cddfSDavid du Colombier notify(alarmed); 7097dd7cddfSDavid du Colombier alarm(5000); 7107dd7cddfSDavid du Colombier } 7117dd7cddfSDavid du Colombier if(needswap(init) && loadbuf(m, &m->swapfd) && readnums(m, nelem(m->devswap), a, 0)) 7127dd7cddfSDavid du Colombier memmove(m->devswap, a, sizeof m->devswap); 7137dd7cddfSDavid du Colombier if(needstat(init) && loadbuf(m, &m->statsfd)){ 7147dd7cddfSDavid du Colombier memmove(m->prevsysstat, m->devsysstat, sizeof m->devsysstat); 7157dd7cddfSDavid du Colombier memset(m->devsysstat, 0, sizeof m->devsysstat); 7167dd7cddfSDavid du Colombier for(n=0; n<m->nproc && readnums(m, nelem(m->devsysstat), a, 0); n++) 7177dd7cddfSDavid du Colombier for(i=0; i<nelem(m->devsysstat); i++) 7187dd7cddfSDavid du Colombier m->devsysstat[i] += a[i]; 7197dd7cddfSDavid du Colombier } 7207dd7cddfSDavid du Colombier if(needether(init) && loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1)){ 7217dd7cddfSDavid du Colombier memmove(m->prevetherstats, m->netetherstats, sizeof m->netetherstats); 7227dd7cddfSDavid du Colombier memmove(m->netetherstats, a, sizeof m->netetherstats); 7237dd7cddfSDavid du Colombier } 7249a747e4fSDavid du Colombier if(needsignal(init) && loadbuf(m, &m->ifstatsfd) && strncmp(m->buf, "Signal: ", 8)==0 && readnums(m, nelem(m->netetherifstats), a, 1)){ 7259a747e4fSDavid du Colombier memmove(m->netetherifstats, a, sizeof m->netetherifstats); 7269a747e4fSDavid du Colombier } 72780ee5cbfSDavid du Colombier if(needbattery(init) && loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0)) 72880ee5cbfSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats)); 7299a747e4fSDavid du Colombier if(needbattery(init) && loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0)) 7309a747e4fSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats)); 73180ee5cbfSDavid du Colombier 7327dd7cddfSDavid du Colombier if(m->remote){ 7337dd7cddfSDavid du Colombier alarm(0); 7347dd7cddfSDavid du Colombier notify(nil); 7357dd7cddfSDavid du Colombier } 7367dd7cddfSDavid du Colombier } 7377dd7cddfSDavid du Colombier 7387dd7cddfSDavid du Colombier void 73980ee5cbfSDavid du Colombier memval(Machine *m, long *v, long *vmax, int) 7407dd7cddfSDavid du Colombier { 7417dd7cddfSDavid du Colombier *v = m->devswap[Mem]; 7427dd7cddfSDavid du Colombier *vmax = m->devswap[Maxmem]; 7437dd7cddfSDavid du Colombier } 7447dd7cddfSDavid du Colombier 7457dd7cddfSDavid du Colombier void 74680ee5cbfSDavid du Colombier swapval(Machine *m, long *v, long *vmax, int) 7477dd7cddfSDavid du Colombier { 7487dd7cddfSDavid du Colombier *v = m->devswap[Swap]; 7497dd7cddfSDavid du Colombier *vmax = m->devswap[Maxswap]; 7507dd7cddfSDavid du Colombier } 7517dd7cddfSDavid du Colombier 7527dd7cddfSDavid du Colombier void 75380ee5cbfSDavid du Colombier contextval(Machine *m, long *v, long *vmax, int init) 7547dd7cddfSDavid du Colombier { 7557dd7cddfSDavid du Colombier *v = m->devsysstat[Context]-m->prevsysstat[Context]; 7567dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 75780ee5cbfSDavid du Colombier if(init) 75880ee5cbfSDavid du Colombier *vmax = 1000; 7597dd7cddfSDavid du Colombier } 7607dd7cddfSDavid du Colombier 7617dd7cddfSDavid du Colombier void 76280ee5cbfSDavid du Colombier intrval(Machine *m, long *v, long *vmax, int init) 7637dd7cddfSDavid du Colombier { 7647dd7cddfSDavid du Colombier *v = m->devsysstat[Interrupt]-m->prevsysstat[Interrupt]; 7657dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 76680ee5cbfSDavid du Colombier if(init) 76780ee5cbfSDavid du Colombier *vmax = 1000; 7687dd7cddfSDavid du Colombier } 7697dd7cddfSDavid du Colombier 7707dd7cddfSDavid du Colombier void 77180ee5cbfSDavid du Colombier syscallval(Machine *m, long *v, long *vmax, int init) 7727dd7cddfSDavid du Colombier { 7737dd7cddfSDavid du Colombier *v = m->devsysstat[Syscall]-m->prevsysstat[Syscall]; 7747dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 77580ee5cbfSDavid du Colombier if(init) 77680ee5cbfSDavid du Colombier *vmax = 1000; 7777dd7cddfSDavid du Colombier } 7787dd7cddfSDavid du Colombier 7797dd7cddfSDavid du Colombier void 78080ee5cbfSDavid du Colombier faultval(Machine *m, long *v, long *vmax, int init) 7817dd7cddfSDavid du Colombier { 7827dd7cddfSDavid du Colombier *v = m->devsysstat[Fault]-m->prevsysstat[Fault]; 7837dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 78480ee5cbfSDavid du Colombier if(init) 78580ee5cbfSDavid du Colombier *vmax = 1000; 7867dd7cddfSDavid du Colombier } 7877dd7cddfSDavid du Colombier 7887dd7cddfSDavid du Colombier void 78980ee5cbfSDavid du Colombier tlbmissval(Machine *m, long *v, long *vmax, int init) 7907dd7cddfSDavid du Colombier { 7917dd7cddfSDavid du Colombier *v = m->devsysstat[TLBfault]-m->prevsysstat[TLBfault]; 7927dd7cddfSDavid du Colombier *vmax = 10*m->nproc; 79380ee5cbfSDavid du Colombier if(init) 79480ee5cbfSDavid du Colombier *vmax = 10; 7957dd7cddfSDavid du Colombier } 7967dd7cddfSDavid du Colombier 7977dd7cddfSDavid du Colombier void 79880ee5cbfSDavid du Colombier tlbpurgeval(Machine *m, long *v, long *vmax, int init) 7997dd7cddfSDavid du Colombier { 8007dd7cddfSDavid du Colombier *v = m->devsysstat[TLBpurge]-m->prevsysstat[TLBpurge]; 8017dd7cddfSDavid du Colombier *vmax = 10*m->nproc; 80280ee5cbfSDavid du Colombier if(init) 80380ee5cbfSDavid du Colombier *vmax = 10; 8047dd7cddfSDavid du Colombier } 8057dd7cddfSDavid du Colombier 8067dd7cddfSDavid du Colombier void 80780ee5cbfSDavid du Colombier loadval(Machine *m, long *v, long *vmax, int init) 8087dd7cddfSDavid du Colombier { 8097dd7cddfSDavid du Colombier *v = m->devsysstat[Load]; 8107dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 81180ee5cbfSDavid du Colombier if(init) 81280ee5cbfSDavid du Colombier *vmax = 1000; 8137dd7cddfSDavid du Colombier } 8147dd7cddfSDavid du Colombier 8157dd7cddfSDavid du Colombier void 81680ee5cbfSDavid du Colombier etherval(Machine *m, long *v, long *vmax, int init) 8177dd7cddfSDavid du Colombier { 8187dd7cddfSDavid du Colombier *v = m->netetherstats[In]-m->prevetherstats[In] + m->netetherstats[Out]-m->prevetherstats[Out]; 8197dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 82080ee5cbfSDavid du Colombier if(init) 82180ee5cbfSDavid du Colombier *vmax = 1000; 8227dd7cddfSDavid du Colombier } 8237dd7cddfSDavid du Colombier 8247dd7cddfSDavid du Colombier void 82580ee5cbfSDavid du Colombier etherinval(Machine *m, long *v, long *vmax, int init) 8267dd7cddfSDavid du Colombier { 8277dd7cddfSDavid du Colombier *v = m->netetherstats[In]-m->prevetherstats[In]; 8287dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 82980ee5cbfSDavid du Colombier if(init) 83080ee5cbfSDavid du Colombier *vmax = 1000; 8317dd7cddfSDavid du Colombier } 8327dd7cddfSDavid du Colombier 8337dd7cddfSDavid du Colombier void 83480ee5cbfSDavid du Colombier etheroutval(Machine *m, long *v, long *vmax, int init) 8357dd7cddfSDavid du Colombier { 8367dd7cddfSDavid du Colombier *v = m->netetherstats[Out]-m->prevetherstats[Out]; 8377dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 83880ee5cbfSDavid du Colombier if(init) 83980ee5cbfSDavid du Colombier *vmax = 1000; 8407dd7cddfSDavid du Colombier } 8417dd7cddfSDavid du Colombier 8427dd7cddfSDavid du Colombier void 84380ee5cbfSDavid du Colombier ethererrval(Machine *m, long *v, long *vmax, int init) 8447dd7cddfSDavid du Colombier { 8457dd7cddfSDavid du Colombier int i; 8467dd7cddfSDavid du Colombier 8477dd7cddfSDavid du Colombier *v = 0; 8487dd7cddfSDavid du Colombier for(i=Err0; i<nelem(m->netetherstats); i++) 8497dd7cddfSDavid du Colombier *v += m->netetherstats[i]; 8507dd7cddfSDavid du Colombier *vmax = 10*m->nproc; 85180ee5cbfSDavid du Colombier if(init) 85280ee5cbfSDavid du Colombier *vmax = 10; 85380ee5cbfSDavid du Colombier } 85480ee5cbfSDavid du Colombier 85580ee5cbfSDavid du Colombier void 85680ee5cbfSDavid du Colombier batteryval(Machine *m, long *v, long *vmax, int) 85780ee5cbfSDavid du Colombier { 85880ee5cbfSDavid du Colombier *v = m->batterystats[0]; 8599a747e4fSDavid du Colombier if(m->bitsybatfd >= 0) 8609a747e4fSDavid du Colombier *vmax = 184; // at least on my bitsy... 8619a747e4fSDavid du Colombier else 86280ee5cbfSDavid du Colombier *vmax = 100; 8637dd7cddfSDavid du Colombier } 8647dd7cddfSDavid du Colombier 8657dd7cddfSDavid du Colombier void 8669a747e4fSDavid du Colombier signalval(Machine *m, long *v, long *vmax, int) 8679a747e4fSDavid du Colombier { 8689a747e4fSDavid du Colombier long l; 8699a747e4fSDavid du Colombier 8709a747e4fSDavid du Colombier *vmax = 1000; 8719a747e4fSDavid du Colombier l = m->netetherifstats[0]; 8729a747e4fSDavid du Colombier /* 8739a747e4fSDavid du Colombier * Range is seen to be from about -45 (strong) to -95 (weak); rescale 8749a747e4fSDavid du Colombier */ 8759a747e4fSDavid du Colombier if(l == 0){ /* probably not present */ 8769a747e4fSDavid du Colombier *v = 0; 8779a747e4fSDavid du Colombier return; 8789a747e4fSDavid du Colombier } 8799a747e4fSDavid du Colombier *v = 20*(l+95); 8809a747e4fSDavid du Colombier } 8819a747e4fSDavid du Colombier 8829a747e4fSDavid du Colombier void 8837dd7cddfSDavid du Colombier usage(void) 8847dd7cddfSDavid du Colombier { 8859a747e4fSDavid du Colombier fprint(2, "usage: stats [-O] [-S scale] [-LY] [-%s] [machine...]\n", argchars); 8867dd7cddfSDavid du Colombier exits("usage"); 8877dd7cddfSDavid du Colombier } 8887dd7cddfSDavid du Colombier 8897dd7cddfSDavid du Colombier void 8907dd7cddfSDavid du Colombier addgraph(int n) 8917dd7cddfSDavid du Colombier { 8927dd7cddfSDavid du Colombier Graph *g, *ograph; 8937dd7cddfSDavid du Colombier int i, j; 8947dd7cddfSDavid du Colombier static int nadd; 8957dd7cddfSDavid du Colombier 8967dd7cddfSDavid du Colombier if(n > nelem(menu2str)) 8977dd7cddfSDavid du Colombier abort(); 8987dd7cddfSDavid du Colombier /* avoid two adjacent graphs of same color */ 8997dd7cddfSDavid du Colombier if(ngraph>0 && graph[ngraph-1].colindex==nadd%Ncolor) 9007dd7cddfSDavid du Colombier nadd++; 9017dd7cddfSDavid du Colombier ograph = graph; 9027dd7cddfSDavid du Colombier graph = emalloc(nmach*(ngraph+1)*sizeof(Graph)); 9037dd7cddfSDavid du Colombier for(i=0; i<nmach; i++) 9047dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++) 9057dd7cddfSDavid du Colombier graph[i*(ngraph+1)+j] = ograph[i*ngraph+j]; 9067dd7cddfSDavid du Colombier free(ograph); 9077dd7cddfSDavid du Colombier ngraph++; 9087dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){ 9097dd7cddfSDavid du Colombier g = &graph[i*ngraph+(ngraph-1)]; 9107dd7cddfSDavid du Colombier memset(g, 0, sizeof(Graph)); 9117dd7cddfSDavid du Colombier g->label = menu2str[n]+Opwid; 9127dd7cddfSDavid du Colombier g->newvalue = newvaluefn[n]; 9137dd7cddfSDavid du Colombier g->update = update1; /* no other update functions yet */ 9147dd7cddfSDavid du Colombier g->mach = &mach[i]; 9157dd7cddfSDavid du Colombier g->colindex = nadd%Ncolor; 9167dd7cddfSDavid du Colombier } 9177dd7cddfSDavid du Colombier present[n] = 1; 9187dd7cddfSDavid du Colombier nadd++; 9197dd7cddfSDavid du Colombier } 9207dd7cddfSDavid du Colombier 9217dd7cddfSDavid du Colombier void 9227dd7cddfSDavid du Colombier dropgraph(int which) 9237dd7cddfSDavid du Colombier { 9247dd7cddfSDavid du Colombier Graph *ograph; 9257dd7cddfSDavid du Colombier int i, j, n; 9267dd7cddfSDavid du Colombier 9277dd7cddfSDavid du Colombier if(which > nelem(menu2str)) 9287dd7cddfSDavid du Colombier abort(); 9297dd7cddfSDavid du Colombier /* convert n to index in graph table */ 9307dd7cddfSDavid du Colombier n = -1; 9317dd7cddfSDavid du Colombier for(i=0; i<ngraph; i++) 9327dd7cddfSDavid du Colombier if(strcmp(menu2str[which]+Opwid, graph[i].label) == 0){ 9337dd7cddfSDavid du Colombier n = i; 9347dd7cddfSDavid du Colombier break; 9357dd7cddfSDavid du Colombier } 9367dd7cddfSDavid du Colombier if(n < 0){ 9377dd7cddfSDavid du Colombier fprint(2, "stats: internal error can't drop graph\n"); 9387dd7cddfSDavid du Colombier killall("error"); 9397dd7cddfSDavid du Colombier } 9407dd7cddfSDavid du Colombier ograph = graph; 9417dd7cddfSDavid du Colombier graph = emalloc(nmach*(ngraph-1)*sizeof(Graph)); 9427dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){ 9437dd7cddfSDavid du Colombier for(j=0; j<n; j++) 9447dd7cddfSDavid du Colombier graph[i*(ngraph-1)+j] = ograph[i*ngraph+j]; 9457dd7cddfSDavid du Colombier free(ograph[i*ngraph+j].data); 9467dd7cddfSDavid du Colombier freeimage(ograph[i*ngraph+j].overtmp); 9477dd7cddfSDavid du Colombier for(j++; j<ngraph; j++) 9487dd7cddfSDavid du Colombier graph[i*(ngraph-1)+j-1] = ograph[i*ngraph+j]; 9497dd7cddfSDavid du Colombier } 9507dd7cddfSDavid du Colombier free(ograph); 9517dd7cddfSDavid du Colombier ngraph--; 9527dd7cddfSDavid du Colombier present[which] = 0; 9537dd7cddfSDavid du Colombier } 9547dd7cddfSDavid du Colombier 9557dd7cddfSDavid du Colombier void 9567dd7cddfSDavid du Colombier addmachine(char *name) 9577dd7cddfSDavid du Colombier { 9587dd7cddfSDavid du Colombier if(ngraph > 0){ 9597dd7cddfSDavid du Colombier fprint(2, "stats: internal error: ngraph>0 in addmachine()\n"); 9607dd7cddfSDavid du Colombier usage(); 9617dd7cddfSDavid du Colombier } 9627dd7cddfSDavid du Colombier if(mach == nil) 9637dd7cddfSDavid du Colombier nmach = 0; /* a little dance to get us started with local machine by default */ 9647dd7cddfSDavid du Colombier mach = erealloc(mach, (nmach+1)*sizeof(Machine)); 9657dd7cddfSDavid du Colombier memset(mach+nmach, 0, sizeof(Machine)); 9667dd7cddfSDavid du Colombier initmach(mach+nmach, name); 9677dd7cddfSDavid du Colombier nmach++; 9687dd7cddfSDavid du Colombier } 9697dd7cddfSDavid du Colombier 9707dd7cddfSDavid du Colombier void 97180ee5cbfSDavid du Colombier labelstrs(Graph *g, char strs[Nlab][Lablen], int *np) 97280ee5cbfSDavid du Colombier { 97380ee5cbfSDavid du Colombier int j; 97480ee5cbfSDavid du Colombier long v, vmax; 97580ee5cbfSDavid du Colombier 97680ee5cbfSDavid du Colombier g->newvalue(g->mach, &v, &vmax, 1); 97780ee5cbfSDavid du Colombier if(logscale){ 97880ee5cbfSDavid du Colombier for(j=1; j<=2; j++) 97980ee5cbfSDavid du Colombier sprint(strs[j-1], "%g", scale*pow(10., j)*(double)vmax/100.); 98080ee5cbfSDavid du Colombier *np = 2; 98180ee5cbfSDavid du Colombier }else{ 98280ee5cbfSDavid du Colombier for(j=1; j<=3; j++) 98380ee5cbfSDavid du Colombier sprint(strs[j-1], "%g", scale*(double)j*(double)vmax/4.0); 98480ee5cbfSDavid du Colombier *np = 3; 98580ee5cbfSDavid du Colombier } 98680ee5cbfSDavid du Colombier } 98780ee5cbfSDavid du Colombier 98880ee5cbfSDavid du Colombier int 98980ee5cbfSDavid du Colombier labelwidth(void) 99080ee5cbfSDavid du Colombier { 99180ee5cbfSDavid du Colombier int i, j, n, w, maxw; 99280ee5cbfSDavid du Colombier char strs[Nlab][Lablen]; 99380ee5cbfSDavid du Colombier 99480ee5cbfSDavid du Colombier maxw = 0; 99580ee5cbfSDavid du Colombier for(i=0; i<ngraph; i++){ 99680ee5cbfSDavid du Colombier /* choose value for rightmost graph */ 99780ee5cbfSDavid du Colombier labelstrs(&graph[ngraph*(nmach-1)+i], strs, &n); 99880ee5cbfSDavid du Colombier for(j=0; j<n; j++){ 99980ee5cbfSDavid du Colombier w = stringwidth(mediumfont, strs[j]); 100080ee5cbfSDavid du Colombier if(w > maxw) 100180ee5cbfSDavid du Colombier maxw = w; 100280ee5cbfSDavid du Colombier } 100380ee5cbfSDavid du Colombier } 100480ee5cbfSDavid du Colombier return maxw; 100580ee5cbfSDavid du Colombier } 100680ee5cbfSDavid du Colombier 100780ee5cbfSDavid du Colombier void 10087dd7cddfSDavid du Colombier resize(void) 10097dd7cddfSDavid du Colombier { 101080ee5cbfSDavid du Colombier int i, j, k, n, startx, starty, x, y, dx, dy, ly, ondata, maxx, wid, nlab; 10117dd7cddfSDavid du Colombier Graph *g; 10127dd7cddfSDavid du Colombier Rectangle machr, r; 10137dd7cddfSDavid du Colombier long v, vmax; 101480ee5cbfSDavid du Colombier char buf[128], labs[Nlab][Lablen]; 10157dd7cddfSDavid du Colombier 10167dd7cddfSDavid du Colombier draw(screen, screen->r, display->white, nil, ZP); 10177dd7cddfSDavid du Colombier 10187dd7cddfSDavid du Colombier /* label left edge */ 10197dd7cddfSDavid du Colombier x = screen->r.min.x; 10207dd7cddfSDavid du Colombier y = screen->r.min.y + Labspace+mediumfont->height+Labspace; 10217dd7cddfSDavid du Colombier dy = (screen->r.max.y - y)/ngraph; 10227dd7cddfSDavid du Colombier dx = Labspace+stringwidth(mediumfont, "0")+Labspace; 10237dd7cddfSDavid du Colombier startx = x+dx+1; 10247dd7cddfSDavid du Colombier starty = y; 10257dd7cddfSDavid du Colombier for(i=0; i<ngraph; i++,y+=dy){ 10267dd7cddfSDavid du Colombier draw(screen, Rect(x, y-1, screen->r.max.x, y), display->black, nil, ZP); 10277dd7cddfSDavid du Colombier draw(screen, Rect(x, y, x+dx, screen->r.max.y), cols[graph[i].colindex][0], nil, paritypt(x)); 10287dd7cddfSDavid du Colombier label(Pt(x, y), dy, graph[i].label); 10297dd7cddfSDavid du Colombier draw(screen, Rect(x+dx, y, x+dx+1, screen->r.max.y), cols[graph[i].colindex][2], nil, ZP); 10307dd7cddfSDavid du Colombier } 10317dd7cddfSDavid du Colombier 10327dd7cddfSDavid du Colombier /* label top edge */ 10337dd7cddfSDavid du Colombier dx = (screen->r.max.x - startx)/nmach; 10347dd7cddfSDavid du Colombier for(x=startx, i=0; i<nmach; i++,x+=dx){ 10357dd7cddfSDavid du Colombier draw(screen, Rect(x-1, starty-1, x, screen->r.max.y), display->black, nil, ZP); 10367dd7cddfSDavid du Colombier j = dx/stringwidth(mediumfont, "0"); 10377dd7cddfSDavid du Colombier n = mach[i].nproc; 10387dd7cddfSDavid du Colombier if(n>1 && j>=1+3+(n>10)+(n>100)){ /* first char of name + (n) */ 10397dd7cddfSDavid du Colombier j -= 3+(n>10)+(n>100); 10407dd7cddfSDavid du Colombier if(j <= 0) 10417dd7cddfSDavid du Colombier j = 1; 10427dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%.*s(%d)", j, mach[i].name, n); 10437dd7cddfSDavid du Colombier }else 10447dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%.*s", j, mach[i].name); 10457dd7cddfSDavid du Colombier string(screen, Pt(x+Labspace, screen->r.min.y + Labspace), display->black, ZP, mediumfont, buf); 10467dd7cddfSDavid du Colombier } 10477dd7cddfSDavid du Colombier 104880ee5cbfSDavid du Colombier maxx = screen->r.max.x; 104980ee5cbfSDavid du Colombier 105080ee5cbfSDavid du Colombier /* label right, if requested */ 105180ee5cbfSDavid du Colombier if(ylabels && dy>Nlab*(mediumfont->height+1)){ 105280ee5cbfSDavid du Colombier wid = labelwidth(); 105380ee5cbfSDavid du Colombier if(wid < (maxx-startx)-30){ 105480ee5cbfSDavid du Colombier /* else there's not enough room */ 105580ee5cbfSDavid du Colombier maxx -= 1+Lx+wid; 105680ee5cbfSDavid du Colombier draw(screen, Rect(maxx, starty, maxx+1, screen->r.max.y), display->black, nil, ZP); 105780ee5cbfSDavid du Colombier y = starty; 105880ee5cbfSDavid du Colombier for(j=0; j<ngraph; j++, y+=dy){ 105980ee5cbfSDavid du Colombier /* choose value for rightmost graph */ 106080ee5cbfSDavid du Colombier g = &graph[ngraph*(nmach-1)+j]; 106180ee5cbfSDavid du Colombier labelstrs(g, labs, &nlab); 106280ee5cbfSDavid du Colombier r = Rect(maxx+1, y, screen->r.max.x, y+dy-1); 106380ee5cbfSDavid du Colombier if(j == ngraph-1) 106480ee5cbfSDavid du Colombier r.max.y = screen->r.max.y; 106580ee5cbfSDavid du Colombier draw(screen, r, cols[g->colindex][0], nil, paritypt(r.min.x)); 106680ee5cbfSDavid du Colombier for(k=0; k<nlab; k++){ 106780ee5cbfSDavid du Colombier ly = y + (dy*(nlab-k)/(nlab+1)); 106880ee5cbfSDavid du Colombier draw(screen, Rect(maxx+1, ly, maxx+1+Lx, ly+1), display->black, nil, ZP); 106980ee5cbfSDavid du Colombier ly -= mediumfont->height/2; 107080ee5cbfSDavid du Colombier string(screen, Pt(maxx+1+Lx, ly), display->black, ZP, mediumfont, labs[k]); 107180ee5cbfSDavid du Colombier } 107280ee5cbfSDavid du Colombier } 107380ee5cbfSDavid du Colombier } 107480ee5cbfSDavid du Colombier } 107580ee5cbfSDavid du Colombier 10767dd7cddfSDavid du Colombier /* create graphs */ 10777dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){ 107880ee5cbfSDavid du Colombier machr = Rect(startx+i*dx, starty, maxx, screen->r.max.y); 10797dd7cddfSDavid du Colombier if(i < nmach-1) 10807dd7cddfSDavid du Colombier machr.max.x = startx+(i+1)*dx - 1; 10817dd7cddfSDavid du Colombier y = starty; 10827dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++, y+=dy){ 10837dd7cddfSDavid du Colombier g = &graph[i*ngraph+j]; 10847dd7cddfSDavid du Colombier /* allocate data */ 10857dd7cddfSDavid du Colombier ondata = g->ndata; 10867dd7cddfSDavid du Colombier g->ndata = Dx(machr)+1; /* may be too many if label will be drawn here; so what? */ 10877dd7cddfSDavid du Colombier g->data = erealloc(g->data, g->ndata*sizeof(long)); 10887dd7cddfSDavid du Colombier if(g->ndata > ondata) 10897dd7cddfSDavid du Colombier memset(g->data+ondata, 0, (g->ndata-ondata)*sizeof(long)); 10907dd7cddfSDavid du Colombier /* set geometry */ 10917dd7cddfSDavid du Colombier g->r = machr; 10927dd7cddfSDavid du Colombier g->r.min.y = y; 10937dd7cddfSDavid du Colombier g->r.max.y = y+dy - 1; 10947dd7cddfSDavid du Colombier if(j == ngraph-1) 10957dd7cddfSDavid du Colombier g->r.max.y = screen->r.max.y; 10967dd7cddfSDavid du Colombier draw(screen, g->r, cols[g->colindex][0], nil, paritypt(g->r.min.x)); 10977dd7cddfSDavid du Colombier g->overflow = 0; 10987dd7cddfSDavid du Colombier r = g->r; 10997dd7cddfSDavid du Colombier r.max.y = r.min.y+mediumfont->height; 11007dd7cddfSDavid du Colombier r.max.x = r.min.x+stringwidth(mediumfont, "9999999"); 11017dd7cddfSDavid du Colombier freeimage(g->overtmp); 11027dd7cddfSDavid du Colombier g->overtmp = nil; 11037dd7cddfSDavid du Colombier if(r.max.x <= g->r.max.x) 11047dd7cddfSDavid du Colombier g->overtmp = allocimage(display, r, screen->chan, 0, -1); 110580ee5cbfSDavid du Colombier g->newvalue(g->mach, &v, &vmax, 0); 11067dd7cddfSDavid du Colombier redraw(g, vmax); 11077dd7cddfSDavid du Colombier } 11087dd7cddfSDavid du Colombier } 11097dd7cddfSDavid du Colombier 11107dd7cddfSDavid du Colombier flushimage(display, 1); 11117dd7cddfSDavid du Colombier } 11127dd7cddfSDavid du Colombier 11137dd7cddfSDavid du Colombier void 11147dd7cddfSDavid du Colombier eresized(int new) 11157dd7cddfSDavid du Colombier { 11167dd7cddfSDavid du Colombier lockdisplay(display); 11177dd7cddfSDavid du Colombier if(new && getwindow(display, Refnone) < 0) { 11187dd7cddfSDavid du Colombier fprint(2, "stats: can't reattach to window\n"); 11197dd7cddfSDavid du Colombier killall("reattach"); 11207dd7cddfSDavid du Colombier } 11217dd7cddfSDavid du Colombier resize(); 11227dd7cddfSDavid du Colombier unlockdisplay(display); 11237dd7cddfSDavid du Colombier } 11247dd7cddfSDavid du Colombier 11257dd7cddfSDavid du Colombier void 11267dd7cddfSDavid du Colombier mouseproc(void) 11277dd7cddfSDavid du Colombier { 11287dd7cddfSDavid du Colombier Mouse mouse; 11297dd7cddfSDavid du Colombier int i; 11307dd7cddfSDavid du Colombier 11317dd7cddfSDavid du Colombier for(;;){ 11327dd7cddfSDavid du Colombier mouse = emouse(); 11337dd7cddfSDavid du Colombier if(mouse.buttons == 4){ 11347dd7cddfSDavid du Colombier lockdisplay(display); 11357dd7cddfSDavid du Colombier for(i=0; i<Nmenu2; i++) 11367dd7cddfSDavid du Colombier if(present[i]) 11377dd7cddfSDavid du Colombier memmove(menu2str[i], "drop ", Opwid); 11387dd7cddfSDavid du Colombier else 11397dd7cddfSDavid du Colombier memmove(menu2str[i], "add ", Opwid); 11407dd7cddfSDavid du Colombier i = emenuhit(3, &mouse, &menu2); 11417dd7cddfSDavid du Colombier if(i >= 0){ 11427dd7cddfSDavid du Colombier if(!present[i]) 11437dd7cddfSDavid du Colombier addgraph(i); 11447dd7cddfSDavid du Colombier else if(ngraph > 1) 11457dd7cddfSDavid du Colombier dropgraph(i); 11467dd7cddfSDavid du Colombier resize(); 11477dd7cddfSDavid du Colombier } 11487dd7cddfSDavid du Colombier unlockdisplay(display); 11497dd7cddfSDavid du Colombier } 11507dd7cddfSDavid du Colombier } 11517dd7cddfSDavid du Colombier } 11527dd7cddfSDavid du Colombier 11537dd7cddfSDavid du Colombier void 11547dd7cddfSDavid du Colombier startproc(void (*f)(void), int index) 11557dd7cddfSDavid du Colombier { 11567dd7cddfSDavid du Colombier int pid; 11577dd7cddfSDavid du Colombier 11587dd7cddfSDavid du Colombier switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT)){ 11597dd7cddfSDavid du Colombier case -1: 11607dd7cddfSDavid du Colombier fprint(2, "stats: fork failed: %r\n"); 11617dd7cddfSDavid du Colombier killall("fork failed"); 11627dd7cddfSDavid du Colombier case 0: 11637dd7cddfSDavid du Colombier f(); 11647dd7cddfSDavid du Colombier fprint(2, "stats: %s process exits\n", procnames[index]); 11657dd7cddfSDavid du Colombier if(index >= 0) 11667dd7cddfSDavid du Colombier killall("process died"); 11677dd7cddfSDavid du Colombier exits(nil); 11687dd7cddfSDavid du Colombier } 11697dd7cddfSDavid du Colombier if(index >= 0) 11707dd7cddfSDavid du Colombier pids[index] = pid; 11717dd7cddfSDavid du Colombier } 11727dd7cddfSDavid du Colombier 11737dd7cddfSDavid du Colombier void 11747dd7cddfSDavid du Colombier main(int argc, char *argv[]) 11757dd7cddfSDavid du Colombier { 11767dd7cddfSDavid du Colombier int i, j; 117780ee5cbfSDavid du Colombier char *s; 11787dd7cddfSDavid du Colombier long v, vmax, nargs; 11797dd7cddfSDavid du Colombier char args[100]; 1180*3f695129SDavid du Colombier int sleeptime = 1000; 11817dd7cddfSDavid du Colombier 11827dd7cddfSDavid du Colombier nmach = 1; 11837dd7cddfSDavid du Colombier mysysname = getenv("sysname"); 11847dd7cddfSDavid du Colombier if(mysysname == nil){ 11857dd7cddfSDavid du Colombier fprint(2, "stats: can't find $sysname: %r\n"); 11867dd7cddfSDavid du Colombier exits("sysname"); 11877dd7cddfSDavid du Colombier } 11887dd7cddfSDavid du Colombier mysysname = estrdup(mysysname); 11897dd7cddfSDavid du Colombier 11907dd7cddfSDavid du Colombier nargs = 0; 11917dd7cddfSDavid du Colombier ARGBEGIN{ 1192*3f695129SDavid du Colombier case 'T': 1193*3f695129SDavid du Colombier s = ARGF(); 1194*3f695129SDavid du Colombier if(s == nil) 1195*3f695129SDavid du Colombier usage(); 1196*3f695129SDavid du Colombier i = atoi(s); 1197*3f695129SDavid du Colombier if(i > 0) 1198*3f695129SDavid du Colombier sleeptime = 1000*i; 1199*3f695129SDavid du Colombier break; 120080ee5cbfSDavid du Colombier case 'S': 120180ee5cbfSDavid du Colombier s = ARGF(); 120280ee5cbfSDavid du Colombier if(s == nil) 120380ee5cbfSDavid du Colombier usage(); 120480ee5cbfSDavid du Colombier scale = atof(s); 120580ee5cbfSDavid du Colombier if(scale <= 0.) 120680ee5cbfSDavid du Colombier usage(); 120780ee5cbfSDavid du Colombier break; 120880ee5cbfSDavid du Colombier case 'L': 120980ee5cbfSDavid du Colombier logscale++; 121080ee5cbfSDavid du Colombier break; 121180ee5cbfSDavid du Colombier case 'Y': 121280ee5cbfSDavid du Colombier ylabels++; 121380ee5cbfSDavid du Colombier break; 12149a747e4fSDavid du Colombier case 'O': 12159a747e4fSDavid du Colombier oldsystem = 1; 12169a747e4fSDavid du Colombier break; 12177dd7cddfSDavid du Colombier default: 12187dd7cddfSDavid du Colombier if(nargs>=sizeof args || strchr(argchars, ARGC())==nil) 12197dd7cddfSDavid du Colombier usage(); 12207dd7cddfSDavid du Colombier args[nargs++] = ARGC(); 12217dd7cddfSDavid du Colombier }ARGEND 12227dd7cddfSDavid du Colombier 12237dd7cddfSDavid du Colombier if(argc == 0){ 12247dd7cddfSDavid du Colombier mach = emalloc(nmach*sizeof(Machine)); 12257dd7cddfSDavid du Colombier initmach(&mach[0], mysysname); 12267dd7cddfSDavid du Colombier readmach(&mach[0], 1); 12277dd7cddfSDavid du Colombier }else{ 12287dd7cddfSDavid du Colombier for(i=0; i<argc; i++){ 12297dd7cddfSDavid du Colombier addmachine(argv[i]); 12307dd7cddfSDavid du Colombier readmach(&mach[i], 1); 12317dd7cddfSDavid du Colombier } 12327dd7cddfSDavid du Colombier } 12337dd7cddfSDavid du Colombier 12347dd7cddfSDavid du Colombier for(i=0; i<nargs; i++) 12357dd7cddfSDavid du Colombier switch(args[i]){ 12367dd7cddfSDavid du Colombier default: 12377dd7cddfSDavid du Colombier fprint(2, "stats: internal error: unknown arg %c\n", args[i]); 12387dd7cddfSDavid du Colombier usage(); 123980ee5cbfSDavid du Colombier case 'b': 124080ee5cbfSDavid du Colombier addgraph(Mbattery); 124180ee5cbfSDavid du Colombier break; 12427dd7cddfSDavid du Colombier case 'c': 12437dd7cddfSDavid du Colombier addgraph(Mcontext); 12447dd7cddfSDavid du Colombier break; 12457dd7cddfSDavid du Colombier case 'e': 12467dd7cddfSDavid du Colombier addgraph(Mether); 12477dd7cddfSDavid du Colombier break; 12487dd7cddfSDavid du Colombier case 'E': 12497dd7cddfSDavid du Colombier addgraph(Metherin); 12507dd7cddfSDavid du Colombier addgraph(Metherout); 12517dd7cddfSDavid du Colombier break; 12527dd7cddfSDavid du Colombier case 'f': 12537dd7cddfSDavid du Colombier addgraph(Mfault); 12547dd7cddfSDavid du Colombier break; 12557dd7cddfSDavid du Colombier case 'i': 12567dd7cddfSDavid du Colombier addgraph(Mintr); 12577dd7cddfSDavid du Colombier break; 12587dd7cddfSDavid du Colombier case 'l': 12597dd7cddfSDavid du Colombier addgraph(Mload); 12607dd7cddfSDavid du Colombier break; 12617dd7cddfSDavid du Colombier case 'm': 12627dd7cddfSDavid du Colombier addgraph(Mmem); 12637dd7cddfSDavid du Colombier break; 12647dd7cddfSDavid du Colombier case 'n': 12657dd7cddfSDavid du Colombier addgraph(Metherin); 12667dd7cddfSDavid du Colombier addgraph(Metherout); 12677dd7cddfSDavid du Colombier addgraph(Methererr); 12687dd7cddfSDavid du Colombier break; 12697dd7cddfSDavid du Colombier case 'p': 12707dd7cddfSDavid du Colombier addgraph(Mtlbpurge); 12717dd7cddfSDavid du Colombier break; 12727dd7cddfSDavid du Colombier case 's': 12737dd7cddfSDavid du Colombier addgraph(Msyscall); 12747dd7cddfSDavid du Colombier break; 12757dd7cddfSDavid du Colombier case 't': 12767dd7cddfSDavid du Colombier addgraph(Mtlbmiss); 12777dd7cddfSDavid du Colombier addgraph(Mtlbpurge); 12787dd7cddfSDavid du Colombier break; 12799a747e4fSDavid du Colombier case '8': 12809a747e4fSDavid du Colombier addgraph(Msignal); 12819a747e4fSDavid du Colombier break; 12827dd7cddfSDavid du Colombier case 'w': 12837dd7cddfSDavid du Colombier addgraph(Mswap); 12847dd7cddfSDavid du Colombier break; 12857dd7cddfSDavid du Colombier } 12867dd7cddfSDavid du Colombier 12877dd7cddfSDavid du Colombier if(ngraph == 0) 12887dd7cddfSDavid du Colombier addgraph(Mload); 12897dd7cddfSDavid du Colombier 12907dd7cddfSDavid du Colombier for(i=0; i<nmach; i++) 12917dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++) 12927dd7cddfSDavid du Colombier graph[i*ngraph+j].mach = &mach[i]; 12937dd7cddfSDavid du Colombier 12947dd7cddfSDavid du Colombier if(initdraw(nil, nil, "stats") < 0){ 12957dd7cddfSDavid du Colombier fprint(2, "stats: initdraw failed: %r\n"); 12967dd7cddfSDavid du Colombier exits("initdraw"); 12977dd7cddfSDavid du Colombier } 12987dd7cddfSDavid du Colombier colinit(); 12997dd7cddfSDavid du Colombier einit(Emouse); 13007dd7cddfSDavid du Colombier notify(nil); 13017dd7cddfSDavid du Colombier startproc(mouseproc, Mouseproc); 13027dd7cddfSDavid du Colombier pids[Mainproc] = getpid(); 13037dd7cddfSDavid du Colombier display->locking = 1; /* tell library we're using the display lock */ 13047dd7cddfSDavid du Colombier 13057dd7cddfSDavid du Colombier resize(); 13067dd7cddfSDavid du Colombier 13077dd7cddfSDavid du Colombier unlockdisplay(display); /* display is still locked from initdraw() */ 13087dd7cddfSDavid du Colombier for(;;){ 13097dd7cddfSDavid du Colombier for(i=0; i<nmach; i++) 13107dd7cddfSDavid du Colombier readmach(&mach[i], 0); 13117dd7cddfSDavid du Colombier lockdisplay(display); 13127dd7cddfSDavid du Colombier parity = 1-parity; 13137dd7cddfSDavid du Colombier for(i=0; i<nmach*ngraph; i++){ 131480ee5cbfSDavid du Colombier graph[i].newvalue(graph[i].mach, &v, &vmax, 0); 13157dd7cddfSDavid du Colombier graph[i].update(&graph[i], v, vmax); 13167dd7cddfSDavid du Colombier } 13177dd7cddfSDavid du Colombier flushimage(display, 1); 13187dd7cddfSDavid du Colombier unlockdisplay(display); 1319*3f695129SDavid du Colombier sleep(sleeptime); 13207dd7cddfSDavid du Colombier } 13217dd7cddfSDavid du Colombier } 1322