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 9*f86ef3ceSDavid du Colombier #define MAXNUM 10 /* 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; 21*f86ef3ceSDavid du Colombier void (*newvalue)(Machine*, ulong*, ulong*, int); 22*f86ef3ceSDavid du Colombier void (*update)(Graph*, ulong, ulong); 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, 44dc5a79c1SDavid du Colombier Idle, 45*f86ef3ceSDavid du Colombier InIntr, 467dd7cddfSDavid du Colombier /* /net/ether0/0/stats */ 477dd7cddfSDavid du Colombier In = 0, 487dd7cddfSDavid du Colombier Out, 497dd7cddfSDavid du Colombier Err0, 503e12c5d1SDavid du Colombier }; 513e12c5d1SDavid du Colombier 527dd7cddfSDavid du Colombier struct Machine 533e12c5d1SDavid du Colombier { 547dd7cddfSDavid du Colombier char *name; 557dd7cddfSDavid du Colombier int remote; 567dd7cddfSDavid du Colombier int statsfd; 577dd7cddfSDavid du Colombier int swapfd; 587dd7cddfSDavid du Colombier int etherfd; 599a747e4fSDavid du Colombier int ifstatsfd; 6080ee5cbfSDavid du Colombier int batteryfd; 619a747e4fSDavid du Colombier int bitsybatfd; 627dd7cddfSDavid du Colombier int disable; 633e12c5d1SDavid du Colombier 64*f86ef3ceSDavid du Colombier ulong devswap[4]; 65*f86ef3ceSDavid du Colombier ulong devsysstat[10]; 66*f86ef3ceSDavid du Colombier ulong prevsysstat[10]; 677dd7cddfSDavid du Colombier int nproc; 68*f86ef3ceSDavid du Colombier ulong netetherstats[8]; 69*f86ef3ceSDavid du Colombier ulong prevetherstats[8]; 70*f86ef3ceSDavid du Colombier ulong batterystats[2]; 71*f86ef3ceSDavid du Colombier ulong netetherifstats[2]; 723e12c5d1SDavid du Colombier 737dd7cddfSDavid du Colombier char buf[1024]; 747dd7cddfSDavid du Colombier char *bufp; 757dd7cddfSDavid du Colombier char *ebufp; 763e12c5d1SDavid du Colombier }; 777dd7cddfSDavid du Colombier 787dd7cddfSDavid du Colombier enum 797dd7cddfSDavid du Colombier { 807dd7cddfSDavid du Colombier Mainproc, 817dd7cddfSDavid du Colombier Mouseproc, 827dd7cddfSDavid du Colombier NPROC, 837dd7cddfSDavid du Colombier }; 847dd7cddfSDavid du Colombier 857dd7cddfSDavid du Colombier enum 867dd7cddfSDavid du Colombier { 877dd7cddfSDavid du Colombier Ncolor = 6, 887dd7cddfSDavid du Colombier Ysqueeze = 2, /* vertical squeezing of label text */ 897dd7cddfSDavid du Colombier Labspace = 2, /* room around label */ 907dd7cddfSDavid du Colombier Dot = 2, /* height of dot */ 917dd7cddfSDavid du Colombier Opwid = 5, /* strlen("add ") or strlen("drop ") */ 9280ee5cbfSDavid du Colombier Nlab = 3, /* max number of labels on y axis */ 9380ee5cbfSDavid du Colombier Lablen = 16, /* max length of label */ 9480ee5cbfSDavid du Colombier Lx = 4, /* label tick length */ 957dd7cddfSDavid du Colombier }; 967dd7cddfSDavid du Colombier 977dd7cddfSDavid du Colombier enum Menu2 987dd7cddfSDavid du Colombier { 99*f86ef3ceSDavid du Colombier Mbattery, 1007dd7cddfSDavid du Colombier Mcontext, 1017dd7cddfSDavid du Colombier Mether, 1027dd7cddfSDavid du Colombier Methererr, 1037dd7cddfSDavid du Colombier Metherin, 1047dd7cddfSDavid du Colombier Metherout, 1057dd7cddfSDavid du Colombier Mfault, 106*f86ef3ceSDavid du Colombier Midle, 107*f86ef3ceSDavid du Colombier Minintr, 1087dd7cddfSDavid du Colombier Mintr, 1097dd7cddfSDavid du Colombier Mload, 1107dd7cddfSDavid du Colombier Mmem, 1117dd7cddfSDavid du Colombier Mswap, 1127dd7cddfSDavid du Colombier Msyscall, 1137dd7cddfSDavid du Colombier Mtlbmiss, 1147dd7cddfSDavid du Colombier Mtlbpurge, 1159a747e4fSDavid du Colombier Msignal, 1167dd7cddfSDavid du Colombier Nmenu2, 1177dd7cddfSDavid du Colombier }; 1187dd7cddfSDavid du Colombier 1197dd7cddfSDavid du Colombier char *menu2str[Nmenu2+1] = { 120*f86ef3ceSDavid du Colombier "add battery ", 1217dd7cddfSDavid du Colombier "add context ", 1227dd7cddfSDavid du Colombier "add ether ", 1237dd7cddfSDavid du Colombier "add ethererr", 1247dd7cddfSDavid du Colombier "add etherin ", 1257dd7cddfSDavid du Colombier "add etherout", 1267dd7cddfSDavid du Colombier "add fault ", 127*f86ef3ceSDavid du Colombier "add idle ", 128*f86ef3ceSDavid du Colombier "add inintr ", 1297dd7cddfSDavid du Colombier "add intr ", 1307dd7cddfSDavid du Colombier "add load ", 1317dd7cddfSDavid du Colombier "add mem ", 1327dd7cddfSDavid du Colombier "add swap ", 1337dd7cddfSDavid du Colombier "add syscall ", 1347dd7cddfSDavid du Colombier "add tlbmiss ", 1357dd7cddfSDavid du Colombier "add tlbpurge", 1369a747e4fSDavid du Colombier "add 802.11b ", 1377dd7cddfSDavid du Colombier nil, 1387dd7cddfSDavid du Colombier }; 1397dd7cddfSDavid du Colombier 1407dd7cddfSDavid du Colombier 141*f86ef3ceSDavid du Colombier void contextval(Machine*, ulong*, ulong*, int), 142*f86ef3ceSDavid du Colombier etherval(Machine*, ulong*, ulong*, int), 143*f86ef3ceSDavid du Colombier ethererrval(Machine*, ulong*, ulong*, int), 144*f86ef3ceSDavid du Colombier etherinval(Machine*, ulong*, ulong*, int), 145*f86ef3ceSDavid du Colombier etheroutval(Machine*, ulong*, ulong*, int), 146*f86ef3ceSDavid du Colombier faultval(Machine*, ulong*, ulong*, int), 147*f86ef3ceSDavid du Colombier intrval(Machine*, ulong*, ulong*, int), 148*f86ef3ceSDavid du Colombier inintrval(Machine*, ulong*, ulong*, int), 149*f86ef3ceSDavid du Colombier loadval(Machine*, ulong*, ulong*, int), 150*f86ef3ceSDavid du Colombier idleval(Machine*, ulong*, ulong*, int), 151*f86ef3ceSDavid du Colombier memval(Machine*, ulong*, ulong*, int), 152*f86ef3ceSDavid du Colombier swapval(Machine*, ulong*, ulong*, int), 153*f86ef3ceSDavid du Colombier syscallval(Machine*, ulong*, ulong*, int), 154*f86ef3ceSDavid du Colombier tlbmissval(Machine*, ulong*, ulong*, int), 155*f86ef3ceSDavid du Colombier tlbpurgeval(Machine*, ulong*, ulong*, int), 156*f86ef3ceSDavid du Colombier batteryval(Machine*, ulong*, ulong*, int), 157*f86ef3ceSDavid du Colombier signalval(Machine*, ulong*, ulong*, int); 1587dd7cddfSDavid du Colombier 1597dd7cddfSDavid du Colombier Menu menu2 = {menu2str, nil}; 1607dd7cddfSDavid du Colombier int present[Nmenu2]; 161*f86ef3ceSDavid du Colombier void (*newvaluefn[Nmenu2])(Machine*, ulong*, ulong*, int init) = { 162*f86ef3ceSDavid du Colombier batteryval, 1637dd7cddfSDavid du Colombier contextval, 1647dd7cddfSDavid du Colombier etherval, 1657dd7cddfSDavid du Colombier ethererrval, 1667dd7cddfSDavid du Colombier etherinval, 1677dd7cddfSDavid du Colombier etheroutval, 1687dd7cddfSDavid du Colombier faultval, 169*f86ef3ceSDavid du Colombier idleval, 170*f86ef3ceSDavid du Colombier inintrval, 1717dd7cddfSDavid du Colombier intrval, 1727dd7cddfSDavid du Colombier loadval, 1737dd7cddfSDavid du Colombier memval, 1747dd7cddfSDavid du Colombier swapval, 1757dd7cddfSDavid du Colombier syscallval, 1767dd7cddfSDavid du Colombier tlbmissval, 1777dd7cddfSDavid du Colombier tlbpurgeval, 1789a747e4fSDavid du Colombier signalval, 1797dd7cddfSDavid du Colombier }; 1807dd7cddfSDavid du Colombier 1817dd7cddfSDavid du Colombier Image *cols[Ncolor][3]; 1827dd7cddfSDavid du Colombier Graph *graph; 1837dd7cddfSDavid du Colombier Machine *mach; 1847dd7cddfSDavid du Colombier Font *mediumfont; 1857dd7cddfSDavid du Colombier char *mysysname; 186*f86ef3ceSDavid du Colombier char argchars[] = "8bceEfiImlnpstw"; 1877dd7cddfSDavid du Colombier int pids[NPROC]; 1887dd7cddfSDavid du Colombier int parity; /* toggled to avoid patterns in textured background */ 1897dd7cddfSDavid du Colombier int nmach; 1907dd7cddfSDavid du Colombier int ngraph; /* totaly number is ngraph*nmach */ 19180ee5cbfSDavid du Colombier double scale = 1.0; 19280ee5cbfSDavid du Colombier int logscale = 0; 19380ee5cbfSDavid du Colombier int ylabels = 0; 1949a747e4fSDavid du Colombier int oldsystem = 0; 1957dd7cddfSDavid du Colombier 1967dd7cddfSDavid du Colombier char *procnames[NPROC] = {"main", "mouse"}; 1977dd7cddfSDavid du Colombier 1987dd7cddfSDavid du Colombier void 1997dd7cddfSDavid du Colombier killall(char *s) 2007dd7cddfSDavid du Colombier { 2017dd7cddfSDavid du Colombier int i, pid; 2027dd7cddfSDavid du Colombier 2037dd7cddfSDavid du Colombier pid = getpid(); 2047dd7cddfSDavid du Colombier for(i=0; i<NPROC; i++) 2057dd7cddfSDavid du Colombier if(pids[i] && pids[i]!=pid) 2067dd7cddfSDavid du Colombier postnote(PNPROC, pids[i], "kill"); 2077dd7cddfSDavid du Colombier exits(s); 2087dd7cddfSDavid du Colombier } 2097dd7cddfSDavid du Colombier 2107dd7cddfSDavid du Colombier void* 2117dd7cddfSDavid du Colombier emalloc(ulong sz) 2127dd7cddfSDavid du Colombier { 2137dd7cddfSDavid du Colombier void *v; 2147dd7cddfSDavid du Colombier v = malloc(sz); 2157dd7cddfSDavid du Colombier if(v == nil) { 2167dd7cddfSDavid du Colombier fprint(2, "stats: out of memory allocating %ld: %r\n", sz); 2177dd7cddfSDavid du Colombier killall("mem"); 2187dd7cddfSDavid du Colombier } 2197dd7cddfSDavid du Colombier memset(v, 0, sz); 2207dd7cddfSDavid du Colombier return v; 2217dd7cddfSDavid du Colombier } 2227dd7cddfSDavid du Colombier 2237dd7cddfSDavid du Colombier void* 2247dd7cddfSDavid du Colombier erealloc(void *v, ulong sz) 2257dd7cddfSDavid du Colombier { 2267dd7cddfSDavid du Colombier v = realloc(v, sz); 2277dd7cddfSDavid du Colombier if(v == nil) { 2287dd7cddfSDavid du Colombier fprint(2, "stats: out of memory reallocating %ld: %r\n", sz); 2297dd7cddfSDavid du Colombier killall("mem"); 2307dd7cddfSDavid du Colombier } 2317dd7cddfSDavid du Colombier return v; 2323e12c5d1SDavid du Colombier } 2333e12c5d1SDavid du Colombier 2343e12c5d1SDavid du Colombier char* 2357dd7cddfSDavid du Colombier estrdup(char *s) 2363e12c5d1SDavid du Colombier { 2377dd7cddfSDavid du Colombier char *t; 2387dd7cddfSDavid du Colombier if((t = strdup(s)) == nil) { 2397dd7cddfSDavid du Colombier fprint(2, "stats: out of memory in strdup(%.10s): %r\n", s); 2407dd7cddfSDavid du Colombier killall("mem"); 2417dd7cddfSDavid du Colombier } 2427dd7cddfSDavid du Colombier return t; 2433e12c5d1SDavid du Colombier } 2443e12c5d1SDavid du Colombier 2453e12c5d1SDavid du Colombier void 2467dd7cddfSDavid du Colombier mkcol(int i, int c0, int c1, int c2) 2473e12c5d1SDavid du Colombier { 2487dd7cddfSDavid du Colombier cols[i][0] = allocimagemix(display, c0, DWhite); 2497dd7cddfSDavid du Colombier cols[i][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c1); 2507dd7cddfSDavid du Colombier cols[i][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c2); 2517dd7cddfSDavid du Colombier } 2523e12c5d1SDavid du Colombier 2537dd7cddfSDavid du Colombier void 2547dd7cddfSDavid du Colombier colinit(void) 2557dd7cddfSDavid du Colombier { 2567dd7cddfSDavid du Colombier mediumfont = openfont(display, "/lib/font/bit/pelm/latin1.8.font"); 2577dd7cddfSDavid du Colombier if(mediumfont == nil) 2587dd7cddfSDavid du Colombier mediumfont = font; 2597dd7cddfSDavid du Colombier 2607dd7cddfSDavid du Colombier /* Peach */ 2617dd7cddfSDavid du Colombier mkcol(0, 0xFFAAAAFF, 0xFFAAAAFF, 0xBB5D5DFF); 2627dd7cddfSDavid du Colombier /* Aqua */ 2637dd7cddfSDavid du Colombier mkcol(1, DPalebluegreen, DPalegreygreen, DPurpleblue); 2647dd7cddfSDavid du Colombier /* Yellow */ 2657dd7cddfSDavid du Colombier mkcol(2, DPaleyellow, DDarkyellow, DYellowgreen); 2667dd7cddfSDavid du Colombier /* Green */ 2677dd7cddfSDavid du Colombier mkcol(3, DPalegreen, DMedgreen, DDarkgreen); 2687dd7cddfSDavid du Colombier /* Blue */ 2697dd7cddfSDavid du Colombier mkcol(4, 0x00AAFFFF, 0x00AAFFFF, 0x0088CCFF); 2707dd7cddfSDavid du Colombier /* Grey */ 2717dd7cddfSDavid du Colombier cols[5][0] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xEEEEEEFF); 2727dd7cddfSDavid du Colombier cols[5][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF); 2737dd7cddfSDavid du Colombier cols[5][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x888888FF); 2747dd7cddfSDavid du Colombier } 2757dd7cddfSDavid du Colombier 2767dd7cddfSDavid du Colombier int 2777dd7cddfSDavid du Colombier loadbuf(Machine *m, int *fd) 2787dd7cddfSDavid du Colombier { 2797dd7cddfSDavid du Colombier int n; 2807dd7cddfSDavid du Colombier 2817dd7cddfSDavid du Colombier 2827dd7cddfSDavid du Colombier if(*fd < 0) 2837dd7cddfSDavid du Colombier return 0; 2847dd7cddfSDavid du Colombier seek(*fd, 0, 0); 2857dd7cddfSDavid du Colombier n = read(*fd, m->buf, sizeof m->buf); 2867dd7cddfSDavid du Colombier if(n <= 0){ 2877dd7cddfSDavid du Colombier close(*fd); 2887dd7cddfSDavid du Colombier *fd = -1; 2897dd7cddfSDavid du Colombier return 0; 2907dd7cddfSDavid du Colombier } 2917dd7cddfSDavid du Colombier m->bufp = m->buf; 2927dd7cddfSDavid du Colombier m->ebufp = m->buf+n; 2937dd7cddfSDavid du Colombier return 1; 2947dd7cddfSDavid du Colombier } 2957dd7cddfSDavid du Colombier 2967dd7cddfSDavid du Colombier void 2977dd7cddfSDavid du Colombier label(Point p, int dy, char *text) 2987dd7cddfSDavid du Colombier { 2997dd7cddfSDavid du Colombier char *s; 3007dd7cddfSDavid du Colombier Rune r[2]; 3017dd7cddfSDavid du Colombier int w, maxw, maxy; 3027dd7cddfSDavid du Colombier 3037dd7cddfSDavid du Colombier p.x += Labspace; 3047dd7cddfSDavid du Colombier maxy = p.y+dy; 3057dd7cddfSDavid du Colombier maxw = 0; 3067dd7cddfSDavid du Colombier r[1] = '\0'; 3077dd7cddfSDavid du Colombier for(s=text; *s; ){ 3087dd7cddfSDavid du Colombier if(p.y+mediumfont->height-Ysqueeze > maxy) 3097dd7cddfSDavid du Colombier break; 3107dd7cddfSDavid du Colombier w = chartorune(r, s); 3117dd7cddfSDavid du Colombier s += w; 3127dd7cddfSDavid du Colombier w = runestringwidth(mediumfont, r); 3137dd7cddfSDavid du Colombier if(w > maxw) 3147dd7cddfSDavid du Colombier maxw = w; 3157dd7cddfSDavid du Colombier runestring(screen, p, display->black, ZP, mediumfont, r); 3167dd7cddfSDavid du Colombier p.y += mediumfont->height-Ysqueeze; 3177dd7cddfSDavid du Colombier } 3187dd7cddfSDavid du Colombier } 3197dd7cddfSDavid du Colombier 3207dd7cddfSDavid du Colombier Point 3217dd7cddfSDavid du Colombier paritypt(int x) 3227dd7cddfSDavid du Colombier { 3237dd7cddfSDavid du Colombier return Pt(x+parity, 0); 3247dd7cddfSDavid du Colombier } 3257dd7cddfSDavid du Colombier 3267dd7cddfSDavid du Colombier Point 327*f86ef3ceSDavid du Colombier datapoint(Graph *g, int x, ulong v, ulong vmax) 3287dd7cddfSDavid du Colombier { 3297dd7cddfSDavid du Colombier Point p; 33080ee5cbfSDavid du Colombier double y; 3317dd7cddfSDavid du Colombier 3327dd7cddfSDavid du Colombier p.x = x; 33380ee5cbfSDavid du Colombier y = ((double)v)/(vmax*scale); 33480ee5cbfSDavid du Colombier if(logscale){ 33580ee5cbfSDavid du Colombier /* 33680ee5cbfSDavid du Colombier * Arrange scale to cover a factor of 1000. 33780ee5cbfSDavid du Colombier * vmax corresponds to the 100 mark. 33880ee5cbfSDavid du Colombier * 10*vmax is the top of the scale. 33980ee5cbfSDavid du Colombier */ 34080ee5cbfSDavid du Colombier if(y <= 0.) 34180ee5cbfSDavid du Colombier y = 0; 34280ee5cbfSDavid du Colombier else{ 34380ee5cbfSDavid du Colombier y = log10(y); 34480ee5cbfSDavid du Colombier /* 1 now corresponds to the top; -2 to the bottom; rescale */ 34580ee5cbfSDavid du Colombier y = (y+2.)/3.; 34680ee5cbfSDavid du Colombier } 34780ee5cbfSDavid du Colombier } 34880ee5cbfSDavid du Colombier p.y = g->r.max.y - Dy(g->r)*y - Dot; 3497dd7cddfSDavid du Colombier if(p.y < g->r.min.y) 3507dd7cddfSDavid du Colombier p.y = g->r.min.y; 3517dd7cddfSDavid du Colombier if(p.y > g->r.max.y-Dot) 3527dd7cddfSDavid du Colombier p.y = g->r.max.y-Dot; 3537dd7cddfSDavid du Colombier return p; 3547dd7cddfSDavid du Colombier } 3557dd7cddfSDavid du Colombier 3567dd7cddfSDavid du Colombier void 357*f86ef3ceSDavid du Colombier drawdatum(Graph *g, int x, ulong prev, ulong v, ulong vmax) 3587dd7cddfSDavid du Colombier { 3597dd7cddfSDavid du Colombier int c; 3607dd7cddfSDavid du Colombier Point p, q; 3617dd7cddfSDavid du Colombier 3627dd7cddfSDavid du Colombier c = g->colindex; 3637dd7cddfSDavid du Colombier p = datapoint(g, x, v, vmax); 3647dd7cddfSDavid du Colombier q = datapoint(g, x, prev, vmax); 3657dd7cddfSDavid du Colombier if(p.y < q.y){ 3667dd7cddfSDavid du Colombier draw(screen, Rect(p.x, g->r.min.y, p.x+1, p.y), cols[c][0], nil, paritypt(p.x)); 3677dd7cddfSDavid du Colombier draw(screen, Rect(p.x, p.y, p.x+1, q.y+Dot), cols[c][2], nil, ZP); 3687dd7cddfSDavid du Colombier draw(screen, Rect(p.x, q.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP); 3697dd7cddfSDavid du Colombier }else{ 3707dd7cddfSDavid du Colombier draw(screen, Rect(p.x, g->r.min.y, p.x+1, q.y), cols[c][0], nil, paritypt(p.x)); 3717dd7cddfSDavid du Colombier draw(screen, Rect(p.x, q.y, p.x+1, p.y+Dot), cols[c][2], nil, ZP); 3727dd7cddfSDavid du Colombier draw(screen, Rect(p.x, p.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP); 3737dd7cddfSDavid du Colombier } 3747dd7cddfSDavid du Colombier 3757dd7cddfSDavid du Colombier } 3767dd7cddfSDavid du Colombier 3777dd7cddfSDavid du Colombier void 3787dd7cddfSDavid du Colombier redraw(Graph *g, int vmax) 3797dd7cddfSDavid du Colombier { 3807dd7cddfSDavid du Colombier int i, c; 3817dd7cddfSDavid du Colombier 3827dd7cddfSDavid du Colombier c = g->colindex; 3837dd7cddfSDavid du Colombier draw(screen, g->r, cols[c][0], nil, paritypt(g->r.min.x)); 3847dd7cddfSDavid du Colombier for(i=1; i<Dx(g->r); i++) 3857dd7cddfSDavid du Colombier drawdatum(g, g->r.max.x-i, g->data[i-1], g->data[i], vmax); 3867dd7cddfSDavid du Colombier drawdatum(g, g->r.min.x, g->data[i], g->data[i], vmax); 3877dd7cddfSDavid du Colombier g->overflow = 0; 3887dd7cddfSDavid du Colombier } 3897dd7cddfSDavid du Colombier 3907dd7cddfSDavid du Colombier void 391*f86ef3ceSDavid du Colombier update1(Graph *g, ulong v, ulong vmax) 3927dd7cddfSDavid du Colombier { 3937dd7cddfSDavid du Colombier char buf[32]; 39480ee5cbfSDavid du Colombier int overflow; 3957dd7cddfSDavid du Colombier 3967dd7cddfSDavid du Colombier if(g->overflow && g->overtmp!=nil) 3977dd7cddfSDavid du Colombier draw(screen, g->overtmp->r, g->overtmp, nil, g->overtmp->r.min); 3987dd7cddfSDavid du Colombier draw(screen, g->r, screen, nil, Pt(g->r.min.x+1, g->r.min.y)); 3997dd7cddfSDavid du Colombier drawdatum(g, g->r.max.x-1, g->data[0], v, vmax); 4007dd7cddfSDavid du Colombier memmove(g->data+1, g->data, (g->ndata-1)*sizeof(g->data[0])); 4017dd7cddfSDavid du Colombier g->data[0] = v; 4027dd7cddfSDavid du Colombier g->overflow = 0; 40380ee5cbfSDavid du Colombier if(logscale) 40480ee5cbfSDavid du Colombier overflow = (v>10*vmax*scale); 40580ee5cbfSDavid du Colombier else 40680ee5cbfSDavid du Colombier overflow = (v>vmax*scale); 40780ee5cbfSDavid du Colombier if(overflow && g->overtmp!=nil){ 4087dd7cddfSDavid du Colombier g->overflow = 1; 4097dd7cddfSDavid du Colombier draw(g->overtmp, g->overtmp->r, screen, nil, g->overtmp->r.min); 4107dd7cddfSDavid du Colombier sprint(buf, "%ld", v); 4117dd7cddfSDavid du Colombier string(screen, g->overtmp->r.min, display->black, ZP, mediumfont, buf); 4127dd7cddfSDavid du Colombier } 4137dd7cddfSDavid du Colombier } 4147dd7cddfSDavid du Colombier 4157dd7cddfSDavid du Colombier /* read one line of text from buffer and process integers */ 4167dd7cddfSDavid du Colombier int 417*f86ef3ceSDavid du Colombier readnums(Machine *m, int n, ulong *a, int spanlines) 4187dd7cddfSDavid du Colombier { 4197dd7cddfSDavid du Colombier int i; 4207dd7cddfSDavid du Colombier char *p, *ep; 4217dd7cddfSDavid du Colombier 4227dd7cddfSDavid du Colombier if(spanlines) 4237dd7cddfSDavid du Colombier ep = m->ebufp; 4247dd7cddfSDavid du Colombier else 4257dd7cddfSDavid du Colombier for(ep=m->bufp; ep<m->ebufp; ep++) 4267dd7cddfSDavid du Colombier if(*ep == '\n') 4277dd7cddfSDavid du Colombier break; 4287dd7cddfSDavid du Colombier p = m->bufp; 4297dd7cddfSDavid du Colombier for(i=0; i<n && p<ep; i++){ 4309a747e4fSDavid du Colombier while(p<ep && !isdigit(*p) && *p!='-') 4317dd7cddfSDavid du Colombier p++; 4327dd7cddfSDavid du Colombier if(p == ep) 4337dd7cddfSDavid du Colombier break; 434*f86ef3ceSDavid du Colombier a[i] = strtoul(p, &p, 10); 4357dd7cddfSDavid du Colombier } 4367dd7cddfSDavid du Colombier if(ep < m->ebufp) 4377dd7cddfSDavid du Colombier ep++; 4387dd7cddfSDavid du Colombier m->bufp = ep; 4397dd7cddfSDavid du Colombier return i == n; 4407dd7cddfSDavid du Colombier } 4417dd7cddfSDavid du Colombier 4427dd7cddfSDavid du Colombier /* Network on fd1, mount driver on fd0 */ 4437dd7cddfSDavid du Colombier static int 4447dd7cddfSDavid du Colombier filter(int fd) 4457dd7cddfSDavid du Colombier { 4467dd7cddfSDavid du Colombier int p[2]; 4477dd7cddfSDavid du Colombier 4487dd7cddfSDavid du Colombier if(pipe(p) < 0){ 4497dd7cddfSDavid du Colombier fprint(2, "stats: can't pipe: %r\n"); 4507dd7cddfSDavid du Colombier killall("pipe"); 4517dd7cddfSDavid du Colombier } 4527dd7cddfSDavid du Colombier 4537dd7cddfSDavid du Colombier switch(rfork(RFNOWAIT|RFPROC|RFFDG)) { 4547dd7cddfSDavid du Colombier case -1: 4557dd7cddfSDavid du Colombier sysfatal("rfork record module"); 4567dd7cddfSDavid du Colombier case 0: 4577dd7cddfSDavid du Colombier dup(fd, 1); 4587dd7cddfSDavid du Colombier close(fd); 4597dd7cddfSDavid du Colombier dup(p[0], 0); 4607dd7cddfSDavid du Colombier close(p[0]); 4617dd7cddfSDavid du Colombier close(p[1]); 4627dd7cddfSDavid du Colombier execl("/bin/aux/fcall", "fcall", 0); 4637dd7cddfSDavid du Colombier fprint(2, "stats: can't exec fcall: %r\n"); 4647dd7cddfSDavid du Colombier killall("fcall"); 4657dd7cddfSDavid du Colombier default: 4667dd7cddfSDavid du Colombier close(fd); 4677dd7cddfSDavid du Colombier close(p[0]); 4687dd7cddfSDavid du Colombier } 4697dd7cddfSDavid du Colombier return p[1]; 4707dd7cddfSDavid du Colombier } 4717dd7cddfSDavid du Colombier 4727dd7cddfSDavid du Colombier /* 4737dd7cddfSDavid du Colombier * 9fs 4747dd7cddfSDavid du Colombier */ 4757dd7cddfSDavid du Colombier int 4767dd7cddfSDavid du Colombier connect9fs(char *addr) 4777dd7cddfSDavid du Colombier { 4789a747e4fSDavid du Colombier char dir[256], *na; 4797dd7cddfSDavid du Colombier int fd; 4807dd7cddfSDavid du Colombier 4817dd7cddfSDavid du Colombier fprint(2, "connect9fs..."); 4827dd7cddfSDavid du Colombier na = netmkaddr(addr, 0, "9fs"); 4837dd7cddfSDavid du Colombier 4847dd7cddfSDavid du Colombier fprint(2, "dial %s...", na); 4857dd7cddfSDavid du Colombier if((fd = dial(na, 0, dir, 0)) < 0) 4867dd7cddfSDavid du Colombier return -1; 4877dd7cddfSDavid du Colombier 4887dd7cddfSDavid du Colombier fprint(2, "dir %s...", dir); 4899a747e4fSDavid du Colombier // if(strstr(dir, "tcp")) 4909a747e4fSDavid du Colombier // fd = filter(fd); 4917dd7cddfSDavid du Colombier return fd; 4927dd7cddfSDavid du Colombier } 4937dd7cddfSDavid du Colombier 4949a747e4fSDavid du Colombier int 4959a747e4fSDavid du Colombier old9p(int fd) 4969a747e4fSDavid du Colombier { 4979a747e4fSDavid du Colombier int p[2]; 4989a747e4fSDavid du Colombier 4999a747e4fSDavid du Colombier if(pipe(p) < 0) 5009a747e4fSDavid du Colombier return -1; 5019a747e4fSDavid du Colombier 5029a747e4fSDavid du Colombier switch(rfork(RFPROC|RFFDG|RFNAMEG)) { 5039a747e4fSDavid du Colombier case -1: 5049a747e4fSDavid du Colombier return -1; 5059a747e4fSDavid du Colombier case 0: 5069a747e4fSDavid du Colombier if(fd != 1){ 5079a747e4fSDavid du Colombier dup(fd, 1); 5089a747e4fSDavid du Colombier close(fd); 5099a747e4fSDavid du Colombier } 5109a747e4fSDavid du Colombier if(p[0] != 0){ 5119a747e4fSDavid du Colombier dup(p[0], 0); 5129a747e4fSDavid du Colombier close(p[0]); 5139a747e4fSDavid du Colombier } 5149a747e4fSDavid du Colombier close(p[1]); 5159a747e4fSDavid du Colombier if(0){ 5169a747e4fSDavid du Colombier fd = open("/sys/log/cpu", OWRITE); 5179a747e4fSDavid du Colombier if(fd != 2){ 5189a747e4fSDavid du Colombier dup(fd, 2); 5199a747e4fSDavid du Colombier close(fd); 5209a747e4fSDavid du Colombier } 5219a747e4fSDavid du Colombier execl("/bin/srvold9p", "srvold9p", "-ds", 0); 5229a747e4fSDavid du Colombier } else 5239a747e4fSDavid du Colombier execl("/bin/srvold9p", "srvold9p", "-s", 0); 5249a747e4fSDavid du Colombier return -1; 5259a747e4fSDavid du Colombier default: 5269a747e4fSDavid du Colombier close(fd); 5279a747e4fSDavid du Colombier close(p[0]); 5289a747e4fSDavid du Colombier } 5299a747e4fSDavid du Colombier return p[1]; 5309a747e4fSDavid du Colombier } 5319a747e4fSDavid du Colombier 5329a747e4fSDavid du Colombier 5337dd7cddfSDavid du Colombier /* 5347dd7cddfSDavid du Colombier * exportfs 5357dd7cddfSDavid du Colombier */ 5367dd7cddfSDavid du Colombier int 5377dd7cddfSDavid du Colombier connectexportfs(char *addr) 5387dd7cddfSDavid du Colombier { 5399a747e4fSDavid du Colombier char buf[ERRMAX], dir[256], *na; 5407dd7cddfSDavid du Colombier int fd, n; 5417dd7cddfSDavid du Colombier char *tree; 5429a747e4fSDavid du Colombier AuthInfo *ai; 5437dd7cddfSDavid du Colombier 5447dd7cddfSDavid du Colombier tree = "/"; 5457dd7cddfSDavid du Colombier na = netmkaddr(addr, 0, "exportfs"); 5467dd7cddfSDavid du Colombier if((fd = dial(na, 0, dir, 0)) < 0) 5477dd7cddfSDavid du Colombier return -1; 5487dd7cddfSDavid du Colombier 5499a747e4fSDavid du Colombier ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client"); 5509a747e4fSDavid du Colombier if(ai == nil) 5517dd7cddfSDavid du Colombier return -1; 5527dd7cddfSDavid du Colombier 5537dd7cddfSDavid du Colombier n = write(fd, tree, strlen(tree)); 5547dd7cddfSDavid du Colombier if(n < 0){ 5557dd7cddfSDavid du Colombier close(fd); 5567dd7cddfSDavid du Colombier return -1; 5577dd7cddfSDavid du Colombier } 5587dd7cddfSDavid du Colombier 5597dd7cddfSDavid du Colombier strcpy(buf, "can't read tree"); 5607dd7cddfSDavid du Colombier n = read(fd, buf, sizeof buf - 1); 5617dd7cddfSDavid du Colombier if(n!=2 || buf[0]!='O' || buf[1]!='K'){ 5627dd7cddfSDavid du Colombier buf[sizeof buf - 1] = '\0'; 5637dd7cddfSDavid du Colombier werrstr("bad remote tree: %s\n", buf); 5647dd7cddfSDavid du Colombier close(fd); 5657dd7cddfSDavid du Colombier return -1; 5667dd7cddfSDavid du Colombier } 5677dd7cddfSDavid du Colombier 5689a747e4fSDavid du Colombier // if(strstr(dir, "tcp")) 5699a747e4fSDavid du Colombier // fd = filter(fd); 5709a747e4fSDavid du Colombier 5719a747e4fSDavid du Colombier if(oldsystem) 5729a747e4fSDavid du Colombier return old9p(fd); 5737dd7cddfSDavid du Colombier 5747dd7cddfSDavid du Colombier return fd; 5757dd7cddfSDavid du Colombier } 5767dd7cddfSDavid du Colombier 5777dd7cddfSDavid du Colombier void 5787dd7cddfSDavid du Colombier initmach(Machine *m, char *name) 5797dd7cddfSDavid du Colombier { 5807dd7cddfSDavid du Colombier int n, fd; 581*f86ef3ceSDavid du Colombier ulong a[MAXNUM]; 5827dd7cddfSDavid du Colombier char *p, mpt[256], buf[256]; 5837dd7cddfSDavid du Colombier 5847dd7cddfSDavid du Colombier p = strchr(name, '!'); 5857dd7cddfSDavid du Colombier if(p){ 5867dd7cddfSDavid du Colombier p++; 5877dd7cddfSDavid du Colombier m->name = estrdup(p+1); 5887dd7cddfSDavid du Colombier }else 5897dd7cddfSDavid du Colombier p = name; 5907dd7cddfSDavid du Colombier m->name = estrdup(p); 5917dd7cddfSDavid du Colombier m->remote = (strcmp(p, mysysname) != 0); 5927dd7cddfSDavid du Colombier if(m->remote == 0) 5937dd7cddfSDavid du Colombier strcpy(mpt, ""); 5947dd7cddfSDavid du Colombier else{ 5957dd7cddfSDavid du Colombier snprint(mpt, sizeof mpt, "/n/%s", p); 5967dd7cddfSDavid du Colombier fd = connectexportfs(name); 5977dd7cddfSDavid du Colombier if(fd < 0){ 5987dd7cddfSDavid du Colombier fprint(2, "can't connect to %s: %r\n", name); 5997dd7cddfSDavid du Colombier killall("connect"); 6007dd7cddfSDavid du Colombier } 6019a747e4fSDavid du Colombier /* BUG? need to use amount() now? */ 6029a747e4fSDavid du Colombier if(mount(fd, -1, mpt, MREPL, "") < 0){ 6037dd7cddfSDavid du Colombier fprint(2, "stats: mount %s on %s failed (%r); trying /n/sid\n", name, mpt); 6047dd7cddfSDavid du Colombier strcpy(mpt, "/n/sid"); 6059a747e4fSDavid du Colombier if(mount(fd, -1, mpt, MREPL, "") < 0){ 6067dd7cddfSDavid du Colombier fprint(2, "stats: mount %s on %s failed: %r\n", name, mpt); 6077dd7cddfSDavid du Colombier killall("mount"); 6087dd7cddfSDavid du Colombier } 6097dd7cddfSDavid du Colombier } 6107dd7cddfSDavid du Colombier } 6117dd7cddfSDavid du Colombier 6127dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/swap", mpt); 6137dd7cddfSDavid du Colombier m->swapfd = open(buf, OREAD); 6147dd7cddfSDavid du Colombier if(loadbuf(m, &m->swapfd) && readnums(m, nelem(m->devswap), a, 0)) 6157dd7cddfSDavid du Colombier memmove(m->devswap, a, sizeof m->devswap); 6167dd7cddfSDavid du Colombier else 6177dd7cddfSDavid du Colombier m->devswap[Maxmem] = m->devswap[Maxswap] = 100; 6187dd7cddfSDavid du Colombier 6197dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/sysstat", mpt); 6207dd7cddfSDavid du Colombier m->statsfd = open(buf, OREAD); 6217dd7cddfSDavid du Colombier if(loadbuf(m, &m->statsfd)){ 6227dd7cddfSDavid du Colombier for(n=0; readnums(m, nelem(m->devsysstat), a, 0); n++) 6237dd7cddfSDavid du Colombier ; 6247dd7cddfSDavid du Colombier m->nproc = n; 6257dd7cddfSDavid du Colombier }else 6267dd7cddfSDavid du Colombier m->nproc = 1; 6277dd7cddfSDavid du Colombier 6287dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/net/ether0/0/stats", mpt); 6297dd7cddfSDavid du Colombier m->etherfd = open(buf, OREAD); 6307dd7cddfSDavid du Colombier if(loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1)) 6317dd7cddfSDavid du Colombier memmove(m->netetherstats, a, sizeof m->netetherstats); 63280ee5cbfSDavid du Colombier 6339a747e4fSDavid du Colombier snprint(buf, sizeof buf, "%s/net/ether0/0/ifstats", mpt); 6349a747e4fSDavid du Colombier m->ifstatsfd = open(buf, OREAD); 6359a747e4fSDavid du Colombier if(loadbuf(m, &m->ifstatsfd)){ 6369a747e4fSDavid du Colombier /* need to check that this is a wavelan interface */ 6379a747e4fSDavid du Colombier if(strncmp(m->buf, "Signal: ", 8) == 0 && readnums(m, nelem(m->netetherifstats), a, 1)) 6389a747e4fSDavid du Colombier memmove(m->netetherifstats, a, sizeof m->netetherifstats); 6399a747e4fSDavid du Colombier } 6409a747e4fSDavid du Colombier 64180ee5cbfSDavid du Colombier snprint(buf, sizeof buf, "%s/mnt/apm/battery", mpt); 64280ee5cbfSDavid du Colombier m->batteryfd = open(buf, OREAD); 6439a747e4fSDavid du Colombier m->bitsybatfd = -1; 6449a747e4fSDavid du Colombier if(m->batteryfd >= 0){ 64580ee5cbfSDavid du Colombier if(loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0)) 64680ee5cbfSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats)); 6479a747e4fSDavid du Colombier }else{ 6489a747e4fSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/battery", mpt); 6499a747e4fSDavid du Colombier m->bitsybatfd = open(buf, OREAD); 6509a747e4fSDavid du Colombier if(loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0)) 6519a747e4fSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats)); 6529a747e4fSDavid du Colombier } 6537dd7cddfSDavid du Colombier } 6547dd7cddfSDavid du Colombier 6557dd7cddfSDavid du Colombier jmp_buf catchalarm; 6567dd7cddfSDavid du Colombier 6577dd7cddfSDavid du Colombier void 6587dd7cddfSDavid du Colombier alarmed(void *a, char *s) 6597dd7cddfSDavid du Colombier { 6607dd7cddfSDavid du Colombier if(strcmp(s, "alarm") == 0) 6617dd7cddfSDavid du Colombier notejmp(a, catchalarm, 1); 6623e12c5d1SDavid du Colombier noted(NDFLT); 6633e12c5d1SDavid du Colombier } 6647dd7cddfSDavid du Colombier 6657dd7cddfSDavid du Colombier int 6667dd7cddfSDavid du Colombier needswap(int init) 6677dd7cddfSDavid du Colombier { 6687dd7cddfSDavid du Colombier return init | present[Mmem] | present[Mswap]; 6697dd7cddfSDavid du Colombier } 6707dd7cddfSDavid du Colombier 6717dd7cddfSDavid du Colombier 6727dd7cddfSDavid du Colombier int 6737dd7cddfSDavid du Colombier needstat(int init) 6747dd7cddfSDavid du Colombier { 675dc5a79c1SDavid du Colombier return init | present[Mcontext] | present[Mfault] | present[Mintr] | present[Mload] | present[Midle] | 676*f86ef3ceSDavid du Colombier present[Minintr] | present[Msyscall] | present[Mtlbmiss] | present[Mtlbpurge]; 6777dd7cddfSDavid du Colombier } 6787dd7cddfSDavid du Colombier 6797dd7cddfSDavid du Colombier 6807dd7cddfSDavid du Colombier int 6817dd7cddfSDavid du Colombier needether(int init) 6827dd7cddfSDavid du Colombier { 6837dd7cddfSDavid du Colombier return init | present[Mether] | present[Metherin] | present[Metherout] | present[Methererr]; 6847dd7cddfSDavid du Colombier } 6857dd7cddfSDavid du Colombier 68680ee5cbfSDavid du Colombier int 68780ee5cbfSDavid du Colombier needbattery(int init) 68880ee5cbfSDavid du Colombier { 68980ee5cbfSDavid du Colombier return init | present[Mbattery]; 69080ee5cbfSDavid du Colombier } 69180ee5cbfSDavid du Colombier 6929a747e4fSDavid du Colombier int 6939a747e4fSDavid du Colombier needsignal(int init) 6949a747e4fSDavid du Colombier { 6959a747e4fSDavid du Colombier return init | present[Msignal]; 6969a747e4fSDavid du Colombier } 6979a747e4fSDavid du Colombier 6987dd7cddfSDavid du Colombier void 6997dd7cddfSDavid du Colombier readmach(Machine *m, int init) 7007dd7cddfSDavid du Colombier { 7017dd7cddfSDavid du Colombier int n, i; 702*f86ef3ceSDavid du Colombier ulong a[8]; 7037dd7cddfSDavid du Colombier char buf[32]; 7047dd7cddfSDavid du Colombier 7057dd7cddfSDavid du Colombier if(m->remote && (m->disable || setjmp(catchalarm))){ 7067dd7cddfSDavid du Colombier if(m->disable == 0){ 7077dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s(dead)", m->name); 7087dd7cddfSDavid du Colombier m->name = estrdup(buf); 7097dd7cddfSDavid du Colombier if(display != nil) /* else we're still initializing */ 7107dd7cddfSDavid du Colombier eresized(0); 7117dd7cddfSDavid du Colombier } 7127dd7cddfSDavid du Colombier m->disable = 1; 7137dd7cddfSDavid du Colombier memmove(m->devsysstat, m->prevsysstat, sizeof m->devsysstat); 7147dd7cddfSDavid du Colombier memmove(m->netetherstats, m->prevetherstats, sizeof m->netetherstats); 7157dd7cddfSDavid du Colombier return; 7167dd7cddfSDavid du Colombier } 7177dd7cddfSDavid du Colombier if(m->remote){ 7187dd7cddfSDavid du Colombier notify(alarmed); 7197dd7cddfSDavid du Colombier alarm(5000); 7207dd7cddfSDavid du Colombier } 7217dd7cddfSDavid du Colombier if(needswap(init) && loadbuf(m, &m->swapfd) && readnums(m, nelem(m->devswap), a, 0)) 7227dd7cddfSDavid du Colombier memmove(m->devswap, a, sizeof m->devswap); 7237dd7cddfSDavid du Colombier if(needstat(init) && loadbuf(m, &m->statsfd)){ 7247dd7cddfSDavid du Colombier memmove(m->prevsysstat, m->devsysstat, sizeof m->devsysstat); 7257dd7cddfSDavid du Colombier memset(m->devsysstat, 0, sizeof m->devsysstat); 7267dd7cddfSDavid du Colombier for(n=0; n<m->nproc && readnums(m, nelem(m->devsysstat), a, 0); n++) 7277dd7cddfSDavid du Colombier for(i=0; i<nelem(m->devsysstat); i++) 7287dd7cddfSDavid du Colombier m->devsysstat[i] += a[i]; 7297dd7cddfSDavid du Colombier } 7307dd7cddfSDavid du Colombier if(needether(init) && loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1)){ 7317dd7cddfSDavid du Colombier memmove(m->prevetherstats, m->netetherstats, sizeof m->netetherstats); 7327dd7cddfSDavid du Colombier memmove(m->netetherstats, a, sizeof m->netetherstats); 7337dd7cddfSDavid du Colombier } 7349a747e4fSDavid du Colombier if(needsignal(init) && loadbuf(m, &m->ifstatsfd) && strncmp(m->buf, "Signal: ", 8)==0 && readnums(m, nelem(m->netetherifstats), a, 1)){ 7359a747e4fSDavid du Colombier memmove(m->netetherifstats, a, sizeof m->netetherifstats); 7369a747e4fSDavid du Colombier } 73780ee5cbfSDavid du Colombier if(needbattery(init) && loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0)) 73880ee5cbfSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats)); 7399a747e4fSDavid du Colombier if(needbattery(init) && loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0)) 7409a747e4fSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats)); 74180ee5cbfSDavid du Colombier 7427dd7cddfSDavid du Colombier if(m->remote){ 7437dd7cddfSDavid du Colombier alarm(0); 7447dd7cddfSDavid du Colombier notify(nil); 7457dd7cddfSDavid du Colombier } 7467dd7cddfSDavid du Colombier } 7477dd7cddfSDavid du Colombier 7487dd7cddfSDavid du Colombier void 749*f86ef3ceSDavid du Colombier memval(Machine *m, ulong *v, ulong *vmax, int) 7507dd7cddfSDavid du Colombier { 7517dd7cddfSDavid du Colombier *v = m->devswap[Mem]; 7527dd7cddfSDavid du Colombier *vmax = m->devswap[Maxmem]; 7537dd7cddfSDavid du Colombier } 7547dd7cddfSDavid du Colombier 7557dd7cddfSDavid du Colombier void 756*f86ef3ceSDavid du Colombier swapval(Machine *m, ulong *v, ulong *vmax, int) 7577dd7cddfSDavid du Colombier { 7587dd7cddfSDavid du Colombier *v = m->devswap[Swap]; 7597dd7cddfSDavid du Colombier *vmax = m->devswap[Maxswap]; 7607dd7cddfSDavid du Colombier } 7617dd7cddfSDavid du Colombier 7627dd7cddfSDavid du Colombier void 763*f86ef3ceSDavid du Colombier contextval(Machine *m, ulong *v, ulong *vmax, int init) 7647dd7cddfSDavid du Colombier { 7657dd7cddfSDavid du Colombier *v = m->devsysstat[Context]-m->prevsysstat[Context]; 7667dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 76780ee5cbfSDavid du Colombier if(init) 76880ee5cbfSDavid du Colombier *vmax = 1000; 7697dd7cddfSDavid du Colombier } 7707dd7cddfSDavid du Colombier 7717dd7cddfSDavid du Colombier void 772*f86ef3ceSDavid du Colombier intrval(Machine *m, ulong *v, ulong *vmax, int init) 7737dd7cddfSDavid du Colombier { 7747dd7cddfSDavid du Colombier *v = m->devsysstat[Interrupt]-m->prevsysstat[Interrupt]; 7757dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 77680ee5cbfSDavid du Colombier if(init) 77780ee5cbfSDavid du Colombier *vmax = 1000; 7787dd7cddfSDavid du Colombier } 7797dd7cddfSDavid du Colombier 7807dd7cddfSDavid du Colombier void 781*f86ef3ceSDavid du Colombier syscallval(Machine *m, ulong *v, ulong *vmax, int init) 7827dd7cddfSDavid du Colombier { 7837dd7cddfSDavid du Colombier *v = m->devsysstat[Syscall]-m->prevsysstat[Syscall]; 7847dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 78580ee5cbfSDavid du Colombier if(init) 78680ee5cbfSDavid du Colombier *vmax = 1000; 7877dd7cddfSDavid du Colombier } 7887dd7cddfSDavid du Colombier 7897dd7cddfSDavid du Colombier void 790*f86ef3ceSDavid du Colombier faultval(Machine *m, ulong *v, ulong *vmax, int init) 7917dd7cddfSDavid du Colombier { 7927dd7cddfSDavid du Colombier *v = m->devsysstat[Fault]-m->prevsysstat[Fault]; 7937dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 79480ee5cbfSDavid du Colombier if(init) 79580ee5cbfSDavid du Colombier *vmax = 1000; 7967dd7cddfSDavid du Colombier } 7977dd7cddfSDavid du Colombier 7987dd7cddfSDavid du Colombier void 799*f86ef3ceSDavid du Colombier tlbmissval(Machine *m, ulong *v, ulong *vmax, int init) 8007dd7cddfSDavid du Colombier { 8017dd7cddfSDavid du Colombier *v = m->devsysstat[TLBfault]-m->prevsysstat[TLBfault]; 8027dd7cddfSDavid du Colombier *vmax = 10*m->nproc; 80380ee5cbfSDavid du Colombier if(init) 80480ee5cbfSDavid du Colombier *vmax = 10; 8057dd7cddfSDavid du Colombier } 8067dd7cddfSDavid du Colombier 8077dd7cddfSDavid du Colombier void 808*f86ef3ceSDavid du Colombier tlbpurgeval(Machine *m, ulong *v, ulong *vmax, int init) 8097dd7cddfSDavid du Colombier { 8107dd7cddfSDavid du Colombier *v = m->devsysstat[TLBpurge]-m->prevsysstat[TLBpurge]; 8117dd7cddfSDavid du Colombier *vmax = 10*m->nproc; 81280ee5cbfSDavid du Colombier if(init) 81380ee5cbfSDavid du Colombier *vmax = 10; 8147dd7cddfSDavid du Colombier } 8157dd7cddfSDavid du Colombier 8167dd7cddfSDavid du Colombier void 817*f86ef3ceSDavid du Colombier loadval(Machine *m, ulong *v, ulong *vmax, int init) 8187dd7cddfSDavid du Colombier { 8197dd7cddfSDavid du Colombier *v = m->devsysstat[Load]; 8207dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 82180ee5cbfSDavid du Colombier if(init) 82280ee5cbfSDavid du Colombier *vmax = 1000; 8237dd7cddfSDavid du Colombier } 8247dd7cddfSDavid du Colombier 8257dd7cddfSDavid du Colombier void 826*f86ef3ceSDavid du Colombier idleval(Machine *m, ulong *v, ulong *vmax, int) 827dc5a79c1SDavid du Colombier { 828*f86ef3ceSDavid du Colombier *v = m->devsysstat[Idle]/m->nproc; 829dc5a79c1SDavid du Colombier *vmax = 100; 830dc5a79c1SDavid du Colombier } 831dc5a79c1SDavid du Colombier 832dc5a79c1SDavid du Colombier void 833*f86ef3ceSDavid du Colombier inintrval(Machine *m, ulong *v, ulong *vmax, int) 834*f86ef3ceSDavid du Colombier { 835*f86ef3ceSDavid du Colombier *v = m->devsysstat[InIntr]/m->nproc; 836*f86ef3ceSDavid du Colombier *vmax = 100; 837*f86ef3ceSDavid du Colombier } 838*f86ef3ceSDavid du Colombier 839*f86ef3ceSDavid du Colombier void 840*f86ef3ceSDavid du Colombier etherval(Machine *m, ulong *v, ulong *vmax, int init) 8417dd7cddfSDavid du Colombier { 8427dd7cddfSDavid du Colombier *v = m->netetherstats[In]-m->prevetherstats[In] + m->netetherstats[Out]-m->prevetherstats[Out]; 8437dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 84480ee5cbfSDavid du Colombier if(init) 84580ee5cbfSDavid du Colombier *vmax = 1000; 8467dd7cddfSDavid du Colombier } 8477dd7cddfSDavid du Colombier 8487dd7cddfSDavid du Colombier void 849*f86ef3ceSDavid du Colombier etherinval(Machine *m, ulong *v, ulong *vmax, int init) 8507dd7cddfSDavid du Colombier { 8517dd7cddfSDavid du Colombier *v = m->netetherstats[In]-m->prevetherstats[In]; 8527dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 85380ee5cbfSDavid du Colombier if(init) 85480ee5cbfSDavid du Colombier *vmax = 1000; 8557dd7cddfSDavid du Colombier } 8567dd7cddfSDavid du Colombier 8577dd7cddfSDavid du Colombier void 858*f86ef3ceSDavid du Colombier etheroutval(Machine *m, ulong *v, ulong *vmax, int init) 8597dd7cddfSDavid du Colombier { 8607dd7cddfSDavid du Colombier *v = m->netetherstats[Out]-m->prevetherstats[Out]; 8617dd7cddfSDavid du Colombier *vmax = 1000*m->nproc; 86280ee5cbfSDavid du Colombier if(init) 86380ee5cbfSDavid du Colombier *vmax = 1000; 8647dd7cddfSDavid du Colombier } 8657dd7cddfSDavid du Colombier 8667dd7cddfSDavid du Colombier void 867*f86ef3ceSDavid du Colombier ethererrval(Machine *m, ulong *v, ulong *vmax, int init) 8687dd7cddfSDavid du Colombier { 8697dd7cddfSDavid du Colombier int i; 8707dd7cddfSDavid du Colombier 8717dd7cddfSDavid du Colombier *v = 0; 8727dd7cddfSDavid du Colombier for(i=Err0; i<nelem(m->netetherstats); i++) 8737dd7cddfSDavid du Colombier *v += m->netetherstats[i]; 8747dd7cddfSDavid du Colombier *vmax = 10*m->nproc; 87580ee5cbfSDavid du Colombier if(init) 87680ee5cbfSDavid du Colombier *vmax = 10; 87780ee5cbfSDavid du Colombier } 87880ee5cbfSDavid du Colombier 87980ee5cbfSDavid du Colombier void 880*f86ef3ceSDavid du Colombier batteryval(Machine *m, ulong *v, ulong *vmax, int) 88180ee5cbfSDavid du Colombier { 88280ee5cbfSDavid du Colombier *v = m->batterystats[0]; 8839a747e4fSDavid du Colombier if(m->bitsybatfd >= 0) 8849a747e4fSDavid du Colombier *vmax = 184; // at least on my bitsy... 8859a747e4fSDavid du Colombier else 88680ee5cbfSDavid du Colombier *vmax = 100; 8877dd7cddfSDavid du Colombier } 8887dd7cddfSDavid du Colombier 8897dd7cddfSDavid du Colombier void 890*f86ef3ceSDavid du Colombier signalval(Machine *m, ulong *v, ulong *vmax, int) 8919a747e4fSDavid du Colombier { 892*f86ef3ceSDavid du Colombier ulong l; 8939a747e4fSDavid du Colombier 8949a747e4fSDavid du Colombier *vmax = 1000; 8959a747e4fSDavid du Colombier l = m->netetherifstats[0]; 8969a747e4fSDavid du Colombier /* 8979a747e4fSDavid du Colombier * Range is seen to be from about -45 (strong) to -95 (weak); rescale 8989a747e4fSDavid du Colombier */ 8999a747e4fSDavid du Colombier if(l == 0){ /* probably not present */ 9009a747e4fSDavid du Colombier *v = 0; 9019a747e4fSDavid du Colombier return; 9029a747e4fSDavid du Colombier } 9039a747e4fSDavid du Colombier *v = 20*(l+95); 9049a747e4fSDavid du Colombier } 9059a747e4fSDavid du Colombier 9069a747e4fSDavid du Colombier void 9077dd7cddfSDavid du Colombier usage(void) 9087dd7cddfSDavid du Colombier { 9099a747e4fSDavid du Colombier fprint(2, "usage: stats [-O] [-S scale] [-LY] [-%s] [machine...]\n", argchars); 9107dd7cddfSDavid du Colombier exits("usage"); 9117dd7cddfSDavid du Colombier } 9127dd7cddfSDavid du Colombier 9137dd7cddfSDavid du Colombier void 9147dd7cddfSDavid du Colombier addgraph(int n) 9157dd7cddfSDavid du Colombier { 9167dd7cddfSDavid du Colombier Graph *g, *ograph; 9177dd7cddfSDavid du Colombier int i, j; 9187dd7cddfSDavid du Colombier static int nadd; 9197dd7cddfSDavid du Colombier 9207dd7cddfSDavid du Colombier if(n > nelem(menu2str)) 9217dd7cddfSDavid du Colombier abort(); 9227dd7cddfSDavid du Colombier /* avoid two adjacent graphs of same color */ 9237dd7cddfSDavid du Colombier if(ngraph>0 && graph[ngraph-1].colindex==nadd%Ncolor) 9247dd7cddfSDavid du Colombier nadd++; 9257dd7cddfSDavid du Colombier ograph = graph; 9267dd7cddfSDavid du Colombier graph = emalloc(nmach*(ngraph+1)*sizeof(Graph)); 9277dd7cddfSDavid du Colombier for(i=0; i<nmach; i++) 9287dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++) 9297dd7cddfSDavid du Colombier graph[i*(ngraph+1)+j] = ograph[i*ngraph+j]; 9307dd7cddfSDavid du Colombier free(ograph); 9317dd7cddfSDavid du Colombier ngraph++; 9327dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){ 9337dd7cddfSDavid du Colombier g = &graph[i*ngraph+(ngraph-1)]; 9347dd7cddfSDavid du Colombier memset(g, 0, sizeof(Graph)); 9357dd7cddfSDavid du Colombier g->label = menu2str[n]+Opwid; 9367dd7cddfSDavid du Colombier g->newvalue = newvaluefn[n]; 9377dd7cddfSDavid du Colombier g->update = update1; /* no other update functions yet */ 9387dd7cddfSDavid du Colombier g->mach = &mach[i]; 9397dd7cddfSDavid du Colombier g->colindex = nadd%Ncolor; 9407dd7cddfSDavid du Colombier } 9417dd7cddfSDavid du Colombier present[n] = 1; 9427dd7cddfSDavid du Colombier nadd++; 9437dd7cddfSDavid du Colombier } 9447dd7cddfSDavid du Colombier 9457dd7cddfSDavid du Colombier void 9467dd7cddfSDavid du Colombier dropgraph(int which) 9477dd7cddfSDavid du Colombier { 9487dd7cddfSDavid du Colombier Graph *ograph; 9497dd7cddfSDavid du Colombier int i, j, n; 9507dd7cddfSDavid du Colombier 9517dd7cddfSDavid du Colombier if(which > nelem(menu2str)) 9527dd7cddfSDavid du Colombier abort(); 9537dd7cddfSDavid du Colombier /* convert n to index in graph table */ 9547dd7cddfSDavid du Colombier n = -1; 9557dd7cddfSDavid du Colombier for(i=0; i<ngraph; i++) 9567dd7cddfSDavid du Colombier if(strcmp(menu2str[which]+Opwid, graph[i].label) == 0){ 9577dd7cddfSDavid du Colombier n = i; 9587dd7cddfSDavid du Colombier break; 9597dd7cddfSDavid du Colombier } 9607dd7cddfSDavid du Colombier if(n < 0){ 9617dd7cddfSDavid du Colombier fprint(2, "stats: internal error can't drop graph\n"); 9627dd7cddfSDavid du Colombier killall("error"); 9637dd7cddfSDavid du Colombier } 9647dd7cddfSDavid du Colombier ograph = graph; 9657dd7cddfSDavid du Colombier graph = emalloc(nmach*(ngraph-1)*sizeof(Graph)); 9667dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){ 9677dd7cddfSDavid du Colombier for(j=0; j<n; j++) 9687dd7cddfSDavid du Colombier graph[i*(ngraph-1)+j] = ograph[i*ngraph+j]; 9697dd7cddfSDavid du Colombier free(ograph[i*ngraph+j].data); 9707dd7cddfSDavid du Colombier freeimage(ograph[i*ngraph+j].overtmp); 9717dd7cddfSDavid du Colombier for(j++; j<ngraph; j++) 9727dd7cddfSDavid du Colombier graph[i*(ngraph-1)+j-1] = ograph[i*ngraph+j]; 9737dd7cddfSDavid du Colombier } 9747dd7cddfSDavid du Colombier free(ograph); 9757dd7cddfSDavid du Colombier ngraph--; 9767dd7cddfSDavid du Colombier present[which] = 0; 9777dd7cddfSDavid du Colombier } 9787dd7cddfSDavid du Colombier 9797dd7cddfSDavid du Colombier void 9807dd7cddfSDavid du Colombier addmachine(char *name) 9817dd7cddfSDavid du Colombier { 9827dd7cddfSDavid du Colombier if(ngraph > 0){ 9837dd7cddfSDavid du Colombier fprint(2, "stats: internal error: ngraph>0 in addmachine()\n"); 9847dd7cddfSDavid du Colombier usage(); 9857dd7cddfSDavid du Colombier } 9867dd7cddfSDavid du Colombier if(mach == nil) 9877dd7cddfSDavid du Colombier nmach = 0; /* a little dance to get us started with local machine by default */ 9887dd7cddfSDavid du Colombier mach = erealloc(mach, (nmach+1)*sizeof(Machine)); 9897dd7cddfSDavid du Colombier memset(mach+nmach, 0, sizeof(Machine)); 9907dd7cddfSDavid du Colombier initmach(mach+nmach, name); 9917dd7cddfSDavid du Colombier nmach++; 9927dd7cddfSDavid du Colombier } 9937dd7cddfSDavid du Colombier 9947dd7cddfSDavid du Colombier void 99580ee5cbfSDavid du Colombier labelstrs(Graph *g, char strs[Nlab][Lablen], int *np) 99680ee5cbfSDavid du Colombier { 99780ee5cbfSDavid du Colombier int j; 998*f86ef3ceSDavid du Colombier ulong v, vmax; 99980ee5cbfSDavid du Colombier 100080ee5cbfSDavid du Colombier g->newvalue(g->mach, &v, &vmax, 1); 100180ee5cbfSDavid du Colombier if(logscale){ 100280ee5cbfSDavid du Colombier for(j=1; j<=2; j++) 100380ee5cbfSDavid du Colombier sprint(strs[j-1], "%g", scale*pow(10., j)*(double)vmax/100.); 100480ee5cbfSDavid du Colombier *np = 2; 100580ee5cbfSDavid du Colombier }else{ 100680ee5cbfSDavid du Colombier for(j=1; j<=3; j++) 100780ee5cbfSDavid du Colombier sprint(strs[j-1], "%g", scale*(double)j*(double)vmax/4.0); 100880ee5cbfSDavid du Colombier *np = 3; 100980ee5cbfSDavid du Colombier } 101080ee5cbfSDavid du Colombier } 101180ee5cbfSDavid du Colombier 101280ee5cbfSDavid du Colombier int 101380ee5cbfSDavid du Colombier labelwidth(void) 101480ee5cbfSDavid du Colombier { 101580ee5cbfSDavid du Colombier int i, j, n, w, maxw; 101680ee5cbfSDavid du Colombier char strs[Nlab][Lablen]; 101780ee5cbfSDavid du Colombier 101880ee5cbfSDavid du Colombier maxw = 0; 101980ee5cbfSDavid du Colombier for(i=0; i<ngraph; i++){ 102080ee5cbfSDavid du Colombier /* choose value for rightmost graph */ 102180ee5cbfSDavid du Colombier labelstrs(&graph[ngraph*(nmach-1)+i], strs, &n); 102280ee5cbfSDavid du Colombier for(j=0; j<n; j++){ 102380ee5cbfSDavid du Colombier w = stringwidth(mediumfont, strs[j]); 102480ee5cbfSDavid du Colombier if(w > maxw) 102580ee5cbfSDavid du Colombier maxw = w; 102680ee5cbfSDavid du Colombier } 102780ee5cbfSDavid du Colombier } 102880ee5cbfSDavid du Colombier return maxw; 102980ee5cbfSDavid du Colombier } 103080ee5cbfSDavid du Colombier 103180ee5cbfSDavid du Colombier void 10327dd7cddfSDavid du Colombier resize(void) 10337dd7cddfSDavid du Colombier { 103480ee5cbfSDavid du Colombier int i, j, k, n, startx, starty, x, y, dx, dy, ly, ondata, maxx, wid, nlab; 10357dd7cddfSDavid du Colombier Graph *g; 10367dd7cddfSDavid du Colombier Rectangle machr, r; 1037*f86ef3ceSDavid du Colombier ulong v, vmax; 103880ee5cbfSDavid du Colombier char buf[128], labs[Nlab][Lablen]; 10397dd7cddfSDavid du Colombier 10407dd7cddfSDavid du Colombier draw(screen, screen->r, display->white, nil, ZP); 10417dd7cddfSDavid du Colombier 10427dd7cddfSDavid du Colombier /* label left edge */ 10437dd7cddfSDavid du Colombier x = screen->r.min.x; 10447dd7cddfSDavid du Colombier y = screen->r.min.y + Labspace+mediumfont->height+Labspace; 10457dd7cddfSDavid du Colombier dy = (screen->r.max.y - y)/ngraph; 10467dd7cddfSDavid du Colombier dx = Labspace+stringwidth(mediumfont, "0")+Labspace; 10477dd7cddfSDavid du Colombier startx = x+dx+1; 10487dd7cddfSDavid du Colombier starty = y; 10497dd7cddfSDavid du Colombier for(i=0; i<ngraph; i++,y+=dy){ 10507dd7cddfSDavid du Colombier draw(screen, Rect(x, y-1, screen->r.max.x, y), display->black, nil, ZP); 10517dd7cddfSDavid du Colombier draw(screen, Rect(x, y, x+dx, screen->r.max.y), cols[graph[i].colindex][0], nil, paritypt(x)); 10527dd7cddfSDavid du Colombier label(Pt(x, y), dy, graph[i].label); 10537dd7cddfSDavid du Colombier draw(screen, Rect(x+dx, y, x+dx+1, screen->r.max.y), cols[graph[i].colindex][2], nil, ZP); 10547dd7cddfSDavid du Colombier } 10557dd7cddfSDavid du Colombier 10567dd7cddfSDavid du Colombier /* label top edge */ 10577dd7cddfSDavid du Colombier dx = (screen->r.max.x - startx)/nmach; 10587dd7cddfSDavid du Colombier for(x=startx, i=0; i<nmach; i++,x+=dx){ 10597dd7cddfSDavid du Colombier draw(screen, Rect(x-1, starty-1, x, screen->r.max.y), display->black, nil, ZP); 10607dd7cddfSDavid du Colombier j = dx/stringwidth(mediumfont, "0"); 10617dd7cddfSDavid du Colombier n = mach[i].nproc; 10627dd7cddfSDavid du Colombier if(n>1 && j>=1+3+(n>10)+(n>100)){ /* first char of name + (n) */ 10637dd7cddfSDavid du Colombier j -= 3+(n>10)+(n>100); 10647dd7cddfSDavid du Colombier if(j <= 0) 10657dd7cddfSDavid du Colombier j = 1; 10667dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%.*s(%d)", j, mach[i].name, n); 10677dd7cddfSDavid du Colombier }else 10687dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%.*s", j, mach[i].name); 10697dd7cddfSDavid du Colombier string(screen, Pt(x+Labspace, screen->r.min.y + Labspace), display->black, ZP, mediumfont, buf); 10707dd7cddfSDavid du Colombier } 10717dd7cddfSDavid du Colombier 107280ee5cbfSDavid du Colombier maxx = screen->r.max.x; 107380ee5cbfSDavid du Colombier 107480ee5cbfSDavid du Colombier /* label right, if requested */ 107580ee5cbfSDavid du Colombier if(ylabels && dy>Nlab*(mediumfont->height+1)){ 107680ee5cbfSDavid du Colombier wid = labelwidth(); 107780ee5cbfSDavid du Colombier if(wid < (maxx-startx)-30){ 107880ee5cbfSDavid du Colombier /* else there's not enough room */ 107980ee5cbfSDavid du Colombier maxx -= 1+Lx+wid; 108080ee5cbfSDavid du Colombier draw(screen, Rect(maxx, starty, maxx+1, screen->r.max.y), display->black, nil, ZP); 108180ee5cbfSDavid du Colombier y = starty; 108280ee5cbfSDavid du Colombier for(j=0; j<ngraph; j++, y+=dy){ 108380ee5cbfSDavid du Colombier /* choose value for rightmost graph */ 108480ee5cbfSDavid du Colombier g = &graph[ngraph*(nmach-1)+j]; 108580ee5cbfSDavid du Colombier labelstrs(g, labs, &nlab); 108680ee5cbfSDavid du Colombier r = Rect(maxx+1, y, screen->r.max.x, y+dy-1); 108780ee5cbfSDavid du Colombier if(j == ngraph-1) 108880ee5cbfSDavid du Colombier r.max.y = screen->r.max.y; 108980ee5cbfSDavid du Colombier draw(screen, r, cols[g->colindex][0], nil, paritypt(r.min.x)); 109080ee5cbfSDavid du Colombier for(k=0; k<nlab; k++){ 109180ee5cbfSDavid du Colombier ly = y + (dy*(nlab-k)/(nlab+1)); 109280ee5cbfSDavid du Colombier draw(screen, Rect(maxx+1, ly, maxx+1+Lx, ly+1), display->black, nil, ZP); 109380ee5cbfSDavid du Colombier ly -= mediumfont->height/2; 109480ee5cbfSDavid du Colombier string(screen, Pt(maxx+1+Lx, ly), display->black, ZP, mediumfont, labs[k]); 109580ee5cbfSDavid du Colombier } 109680ee5cbfSDavid du Colombier } 109780ee5cbfSDavid du Colombier } 109880ee5cbfSDavid du Colombier } 109980ee5cbfSDavid du Colombier 11007dd7cddfSDavid du Colombier /* create graphs */ 11017dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){ 110280ee5cbfSDavid du Colombier machr = Rect(startx+i*dx, starty, maxx, screen->r.max.y); 11037dd7cddfSDavid du Colombier if(i < nmach-1) 11047dd7cddfSDavid du Colombier machr.max.x = startx+(i+1)*dx - 1; 11057dd7cddfSDavid du Colombier y = starty; 11067dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++, y+=dy){ 11077dd7cddfSDavid du Colombier g = &graph[i*ngraph+j]; 11087dd7cddfSDavid du Colombier /* allocate data */ 11097dd7cddfSDavid du Colombier ondata = g->ndata; 11107dd7cddfSDavid du Colombier g->ndata = Dx(machr)+1; /* may be too many if label will be drawn here; so what? */ 1111*f86ef3ceSDavid du Colombier g->data = erealloc(g->data, g->ndata*sizeof(ulong)); 11127dd7cddfSDavid du Colombier if(g->ndata > ondata) 1113*f86ef3ceSDavid du Colombier memset(g->data+ondata, 0, (g->ndata-ondata)*sizeof(ulong)); 11147dd7cddfSDavid du Colombier /* set geometry */ 11157dd7cddfSDavid du Colombier g->r = machr; 11167dd7cddfSDavid du Colombier g->r.min.y = y; 11177dd7cddfSDavid du Colombier g->r.max.y = y+dy - 1; 11187dd7cddfSDavid du Colombier if(j == ngraph-1) 11197dd7cddfSDavid du Colombier g->r.max.y = screen->r.max.y; 11207dd7cddfSDavid du Colombier draw(screen, g->r, cols[g->colindex][0], nil, paritypt(g->r.min.x)); 11217dd7cddfSDavid du Colombier g->overflow = 0; 11227dd7cddfSDavid du Colombier r = g->r; 11237dd7cddfSDavid du Colombier r.max.y = r.min.y+mediumfont->height; 11247dd7cddfSDavid du Colombier r.max.x = r.min.x+stringwidth(mediumfont, "9999999"); 11257dd7cddfSDavid du Colombier freeimage(g->overtmp); 11267dd7cddfSDavid du Colombier g->overtmp = nil; 11277dd7cddfSDavid du Colombier if(r.max.x <= g->r.max.x) 11287dd7cddfSDavid du Colombier g->overtmp = allocimage(display, r, screen->chan, 0, -1); 112980ee5cbfSDavid du Colombier g->newvalue(g->mach, &v, &vmax, 0); 11307dd7cddfSDavid du Colombier redraw(g, vmax); 11317dd7cddfSDavid du Colombier } 11327dd7cddfSDavid du Colombier } 11337dd7cddfSDavid du Colombier 11347dd7cddfSDavid du Colombier flushimage(display, 1); 11357dd7cddfSDavid du Colombier } 11367dd7cddfSDavid du Colombier 11377dd7cddfSDavid du Colombier void 11387dd7cddfSDavid du Colombier eresized(int new) 11397dd7cddfSDavid du Colombier { 11407dd7cddfSDavid du Colombier lockdisplay(display); 11417dd7cddfSDavid du Colombier if(new && getwindow(display, Refnone) < 0) { 11427dd7cddfSDavid du Colombier fprint(2, "stats: can't reattach to window\n"); 11437dd7cddfSDavid du Colombier killall("reattach"); 11447dd7cddfSDavid du Colombier } 11457dd7cddfSDavid du Colombier resize(); 11467dd7cddfSDavid du Colombier unlockdisplay(display); 11477dd7cddfSDavid du Colombier } 11487dd7cddfSDavid du Colombier 11497dd7cddfSDavid du Colombier void 11507dd7cddfSDavid du Colombier mouseproc(void) 11517dd7cddfSDavid du Colombier { 11527dd7cddfSDavid du Colombier Mouse mouse; 11537dd7cddfSDavid du Colombier int i; 11547dd7cddfSDavid du Colombier 11557dd7cddfSDavid du Colombier for(;;){ 11567dd7cddfSDavid du Colombier mouse = emouse(); 11577dd7cddfSDavid du Colombier if(mouse.buttons == 4){ 11587dd7cddfSDavid du Colombier lockdisplay(display); 11597dd7cddfSDavid du Colombier for(i=0; i<Nmenu2; i++) 11607dd7cddfSDavid du Colombier if(present[i]) 11617dd7cddfSDavid du Colombier memmove(menu2str[i], "drop ", Opwid); 11627dd7cddfSDavid du Colombier else 11637dd7cddfSDavid du Colombier memmove(menu2str[i], "add ", Opwid); 11647dd7cddfSDavid du Colombier i = emenuhit(3, &mouse, &menu2); 11657dd7cddfSDavid du Colombier if(i >= 0){ 11667dd7cddfSDavid du Colombier if(!present[i]) 11677dd7cddfSDavid du Colombier addgraph(i); 11687dd7cddfSDavid du Colombier else if(ngraph > 1) 11697dd7cddfSDavid du Colombier dropgraph(i); 11707dd7cddfSDavid du Colombier resize(); 11717dd7cddfSDavid du Colombier } 11727dd7cddfSDavid du Colombier unlockdisplay(display); 11737dd7cddfSDavid du Colombier } 11747dd7cddfSDavid du Colombier } 11757dd7cddfSDavid du Colombier } 11767dd7cddfSDavid du Colombier 11777dd7cddfSDavid du Colombier void 11787dd7cddfSDavid du Colombier startproc(void (*f)(void), int index) 11797dd7cddfSDavid du Colombier { 11807dd7cddfSDavid du Colombier int pid; 11817dd7cddfSDavid du Colombier 11827dd7cddfSDavid du Colombier switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT)){ 11837dd7cddfSDavid du Colombier case -1: 11847dd7cddfSDavid du Colombier fprint(2, "stats: fork failed: %r\n"); 11857dd7cddfSDavid du Colombier killall("fork failed"); 11867dd7cddfSDavid du Colombier case 0: 11877dd7cddfSDavid du Colombier f(); 11887dd7cddfSDavid du Colombier fprint(2, "stats: %s process exits\n", procnames[index]); 11897dd7cddfSDavid du Colombier if(index >= 0) 11907dd7cddfSDavid du Colombier killall("process died"); 11917dd7cddfSDavid du Colombier exits(nil); 11927dd7cddfSDavid du Colombier } 11937dd7cddfSDavid du Colombier if(index >= 0) 11947dd7cddfSDavid du Colombier pids[index] = pid; 11957dd7cddfSDavid du Colombier } 11967dd7cddfSDavid du Colombier 11977dd7cddfSDavid du Colombier void 11987dd7cddfSDavid du Colombier main(int argc, char *argv[]) 11997dd7cddfSDavid du Colombier { 12007dd7cddfSDavid du Colombier int i, j; 120180ee5cbfSDavid du Colombier char *s; 1202*f86ef3ceSDavid du Colombier ulong v, vmax, nargs; 12037dd7cddfSDavid du Colombier char args[100]; 12043f695129SDavid du Colombier int sleeptime = 1000; 12057dd7cddfSDavid du Colombier 12067dd7cddfSDavid du Colombier nmach = 1; 12077dd7cddfSDavid du Colombier mysysname = getenv("sysname"); 12087dd7cddfSDavid du Colombier if(mysysname == nil){ 12097dd7cddfSDavid du Colombier fprint(2, "stats: can't find $sysname: %r\n"); 12107dd7cddfSDavid du Colombier exits("sysname"); 12117dd7cddfSDavid du Colombier } 12127dd7cddfSDavid du Colombier mysysname = estrdup(mysysname); 12137dd7cddfSDavid du Colombier 12147dd7cddfSDavid du Colombier nargs = 0; 12157dd7cddfSDavid du Colombier ARGBEGIN{ 12163f695129SDavid du Colombier case 'T': 12173f695129SDavid du Colombier s = ARGF(); 12183f695129SDavid du Colombier if(s == nil) 12193f695129SDavid du Colombier usage(); 12203f695129SDavid du Colombier i = atoi(s); 12213f695129SDavid du Colombier if(i > 0) 12223f695129SDavid du Colombier sleeptime = 1000*i; 12233f695129SDavid du Colombier break; 122480ee5cbfSDavid du Colombier case 'S': 122580ee5cbfSDavid du Colombier s = ARGF(); 122680ee5cbfSDavid du Colombier if(s == nil) 122780ee5cbfSDavid du Colombier usage(); 122880ee5cbfSDavid du Colombier scale = atof(s); 122980ee5cbfSDavid du Colombier if(scale <= 0.) 123080ee5cbfSDavid du Colombier usage(); 123180ee5cbfSDavid du Colombier break; 123280ee5cbfSDavid du Colombier case 'L': 123380ee5cbfSDavid du Colombier logscale++; 123480ee5cbfSDavid du Colombier break; 123580ee5cbfSDavid du Colombier case 'Y': 123680ee5cbfSDavid du Colombier ylabels++; 123780ee5cbfSDavid du Colombier break; 12389a747e4fSDavid du Colombier case 'O': 12399a747e4fSDavid du Colombier oldsystem = 1; 12409a747e4fSDavid du Colombier break; 12417dd7cddfSDavid du Colombier default: 12427dd7cddfSDavid du Colombier if(nargs>=sizeof args || strchr(argchars, ARGC())==nil) 12437dd7cddfSDavid du Colombier usage(); 12447dd7cddfSDavid du Colombier args[nargs++] = ARGC(); 12457dd7cddfSDavid du Colombier }ARGEND 12467dd7cddfSDavid du Colombier 12477dd7cddfSDavid du Colombier if(argc == 0){ 12487dd7cddfSDavid du Colombier mach = emalloc(nmach*sizeof(Machine)); 12497dd7cddfSDavid du Colombier initmach(&mach[0], mysysname); 12507dd7cddfSDavid du Colombier readmach(&mach[0], 1); 12517dd7cddfSDavid du Colombier }else{ 12527dd7cddfSDavid du Colombier for(i=0; i<argc; i++){ 12537dd7cddfSDavid du Colombier addmachine(argv[i]); 12547dd7cddfSDavid du Colombier readmach(&mach[i], 1); 12557dd7cddfSDavid du Colombier } 12567dd7cddfSDavid du Colombier } 12577dd7cddfSDavid du Colombier 12587dd7cddfSDavid du Colombier for(i=0; i<nargs; i++) 12597dd7cddfSDavid du Colombier switch(args[i]){ 12607dd7cddfSDavid du Colombier default: 12617dd7cddfSDavid du Colombier fprint(2, "stats: internal error: unknown arg %c\n", args[i]); 12627dd7cddfSDavid du Colombier usage(); 126380ee5cbfSDavid du Colombier case 'b': 126480ee5cbfSDavid du Colombier addgraph(Mbattery); 126580ee5cbfSDavid du Colombier break; 12667dd7cddfSDavid du Colombier case 'c': 12677dd7cddfSDavid du Colombier addgraph(Mcontext); 12687dd7cddfSDavid du Colombier break; 12697dd7cddfSDavid du Colombier case 'e': 12707dd7cddfSDavid du Colombier addgraph(Mether); 12717dd7cddfSDavid du Colombier break; 12727dd7cddfSDavid du Colombier case 'E': 12737dd7cddfSDavid du Colombier addgraph(Metherin); 12747dd7cddfSDavid du Colombier addgraph(Metherout); 12757dd7cddfSDavid du Colombier break; 12767dd7cddfSDavid du Colombier case 'f': 12777dd7cddfSDavid du Colombier addgraph(Mfault); 12787dd7cddfSDavid du Colombier break; 12797dd7cddfSDavid du Colombier case 'i': 12807dd7cddfSDavid du Colombier addgraph(Mintr); 12817dd7cddfSDavid du Colombier break; 1282*f86ef3ceSDavid du Colombier case 'I': 1283*f86ef3ceSDavid du Colombier addgraph(Mload); 1284*f86ef3ceSDavid du Colombier addgraph(Midle); 1285*f86ef3ceSDavid du Colombier addgraph(Minintr); 1286*f86ef3ceSDavid du Colombier break; 12877dd7cddfSDavid du Colombier case 'l': 12887dd7cddfSDavid du Colombier addgraph(Mload); 12897dd7cddfSDavid du Colombier break; 12907dd7cddfSDavid du Colombier case 'm': 12917dd7cddfSDavid du Colombier addgraph(Mmem); 12927dd7cddfSDavid du Colombier break; 12937dd7cddfSDavid du Colombier case 'n': 12947dd7cddfSDavid du Colombier addgraph(Metherin); 12957dd7cddfSDavid du Colombier addgraph(Metherout); 12967dd7cddfSDavid du Colombier addgraph(Methererr); 12977dd7cddfSDavid du Colombier break; 12987dd7cddfSDavid du Colombier case 'p': 12997dd7cddfSDavid du Colombier addgraph(Mtlbpurge); 13007dd7cddfSDavid du Colombier break; 13017dd7cddfSDavid du Colombier case 's': 13027dd7cddfSDavid du Colombier addgraph(Msyscall); 13037dd7cddfSDavid du Colombier break; 13047dd7cddfSDavid du Colombier case 't': 13057dd7cddfSDavid du Colombier addgraph(Mtlbmiss); 13067dd7cddfSDavid du Colombier addgraph(Mtlbpurge); 13077dd7cddfSDavid du Colombier break; 13089a747e4fSDavid du Colombier case '8': 13099a747e4fSDavid du Colombier addgraph(Msignal); 13109a747e4fSDavid du Colombier break; 13117dd7cddfSDavid du Colombier case 'w': 13127dd7cddfSDavid du Colombier addgraph(Mswap); 13137dd7cddfSDavid du Colombier break; 13147dd7cddfSDavid du Colombier } 13157dd7cddfSDavid du Colombier 13167dd7cddfSDavid du Colombier if(ngraph == 0) 13177dd7cddfSDavid du Colombier addgraph(Mload); 13187dd7cddfSDavid du Colombier 13197dd7cddfSDavid du Colombier for(i=0; i<nmach; i++) 13207dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++) 13217dd7cddfSDavid du Colombier graph[i*ngraph+j].mach = &mach[i]; 13227dd7cddfSDavid du Colombier 13237dd7cddfSDavid du Colombier if(initdraw(nil, nil, "stats") < 0){ 13247dd7cddfSDavid du Colombier fprint(2, "stats: initdraw failed: %r\n"); 13257dd7cddfSDavid du Colombier exits("initdraw"); 13267dd7cddfSDavid du Colombier } 13277dd7cddfSDavid du Colombier colinit(); 13287dd7cddfSDavid du Colombier einit(Emouse); 13297dd7cddfSDavid du Colombier notify(nil); 13307dd7cddfSDavid du Colombier startproc(mouseproc, Mouseproc); 13317dd7cddfSDavid du Colombier pids[Mainproc] = getpid(); 13327dd7cddfSDavid du Colombier display->locking = 1; /* tell library we're using the display lock */ 13337dd7cddfSDavid du Colombier 13347dd7cddfSDavid du Colombier resize(); 13357dd7cddfSDavid du Colombier 13367dd7cddfSDavid du Colombier unlockdisplay(display); /* display is still locked from initdraw() */ 13377dd7cddfSDavid du Colombier for(;;){ 13387dd7cddfSDavid du Colombier for(i=0; i<nmach; i++) 13397dd7cddfSDavid du Colombier readmach(&mach[i], 0); 13407dd7cddfSDavid du Colombier lockdisplay(display); 13417dd7cddfSDavid du Colombier parity = 1-parity; 13427dd7cddfSDavid du Colombier for(i=0; i<nmach*ngraph; i++){ 134380ee5cbfSDavid du Colombier graph[i].newvalue(graph[i].mach, &v, &vmax, 0); 13447dd7cddfSDavid du Colombier graph[i].update(&graph[i], v, vmax); 13457dd7cddfSDavid du Colombier } 13467dd7cddfSDavid du Colombier flushimage(display, 1); 13477dd7cddfSDavid du Colombier unlockdisplay(display); 13483f695129SDavid du Colombier sleep(sleeptime); 13497dd7cddfSDavid du Colombier } 13507dd7cddfSDavid du Colombier } 1351