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
9f86ef3ceSDavid 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;
18853458f3SDavid du Colombier uvlong *data;
197dd7cddfSDavid du Colombier int ndata;
207dd7cddfSDavid du Colombier char *label;
21b2495906SDavid du Colombier void (*newvalue)(Machine*, uvlong*, uvlong*, int);
22b2495906SDavid du Colombier void (*update)(Graph*, uvlong, uvlong);
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 {
302e7ae8b5SDavid du Colombier /* old /dev/swap */
317dd7cddfSDavid du Colombier Mem = 0,
327dd7cddfSDavid du Colombier Maxmem,
333e12c5d1SDavid du Colombier Swap,
347dd7cddfSDavid du Colombier Maxswap,
352e7ae8b5SDavid du Colombier
367dd7cddfSDavid du Colombier /* /dev/sysstats */
377dd7cddfSDavid du Colombier Procno = 0,
387dd7cddfSDavid du Colombier Context,
397dd7cddfSDavid du Colombier Interrupt,
403e12c5d1SDavid du Colombier Syscall,
413e12c5d1SDavid du Colombier Fault,
427dd7cddfSDavid du Colombier TLBfault,
437dd7cddfSDavid du Colombier TLBpurge,
443e12c5d1SDavid du Colombier Load,
45dc5a79c1SDavid du Colombier Idle,
46f86ef3ceSDavid du Colombier InIntr,
473432ceaeSDavid du Colombier /* /net/ether0/stats */
487dd7cddfSDavid du Colombier In = 0,
497def40e1SDavid du Colombier Link,
507dd7cddfSDavid du Colombier Out,
517dd7cddfSDavid du Colombier Err0,
523e12c5d1SDavid du Colombier };
533e12c5d1SDavid du Colombier
547dd7cddfSDavid du Colombier struct Machine
553e12c5d1SDavid du Colombier {
567dd7cddfSDavid du Colombier char *name;
57eebedd9aSDavid du Colombier char *shortname;
587dd7cddfSDavid du Colombier int remote;
597dd7cddfSDavid du Colombier int statsfd;
607dd7cddfSDavid du Colombier int swapfd;
617dd7cddfSDavid du Colombier int etherfd;
629a747e4fSDavid du Colombier int ifstatsfd;
6380ee5cbfSDavid du Colombier int batteryfd;
649a747e4fSDavid du Colombier int bitsybatfd;
65b2495906SDavid du Colombier int tempfd;
667dd7cddfSDavid du Colombier int disable;
673e12c5d1SDavid du Colombier
68b2495906SDavid du Colombier uvlong devswap[4];
69b2495906SDavid du Colombier uvlong devsysstat[10];
70b2495906SDavid du Colombier uvlong prevsysstat[10];
717dd7cddfSDavid du Colombier int nproc;
72eebedd9aSDavid du Colombier int lgproc;
73b2495906SDavid du Colombier uvlong netetherstats[8];
74b2495906SDavid du Colombier uvlong prevetherstats[8];
75b2495906SDavid du Colombier uvlong batterystats[2];
76b2495906SDavid du Colombier uvlong netetherifstats[2];
77b2495906SDavid du Colombier uvlong temp[10];
783e12c5d1SDavid du Colombier
79b4aa05a1SDavid du Colombier /* big enough to hold /dev/sysstat even with many processors */
80b4aa05a1SDavid du Colombier char buf[8*1024];
817dd7cddfSDavid du Colombier char *bufp;
827dd7cddfSDavid du Colombier char *ebufp;
833e12c5d1SDavid du Colombier };
847dd7cddfSDavid du Colombier
857dd7cddfSDavid du Colombier enum
867dd7cddfSDavid du Colombier {
877dd7cddfSDavid du Colombier Mainproc,
887dd7cddfSDavid du Colombier Mouseproc,
897dd7cddfSDavid du Colombier NPROC,
907dd7cddfSDavid du Colombier };
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier enum
937dd7cddfSDavid du Colombier {
947dd7cddfSDavid du Colombier Ncolor = 6,
957dd7cddfSDavid du Colombier Ysqueeze = 2, /* vertical squeezing of label text */
967dd7cddfSDavid du Colombier Labspace = 2, /* room around label */
977dd7cddfSDavid du Colombier Dot = 2, /* height of dot */
987dd7cddfSDavid du Colombier Opwid = 5, /* strlen("add ") or strlen("drop ") */
9980ee5cbfSDavid du Colombier Nlab = 3, /* max number of labels on y axis */
10080ee5cbfSDavid du Colombier Lablen = 16, /* max length of label */
10180ee5cbfSDavid du Colombier Lx = 4, /* label tick length */
1027dd7cddfSDavid du Colombier };
1037dd7cddfSDavid du Colombier
1047dd7cddfSDavid du Colombier enum Menu2
1057dd7cddfSDavid du Colombier {
106f86ef3ceSDavid du Colombier Mbattery,
1077dd7cddfSDavid du Colombier Mcontext,
1087dd7cddfSDavid du Colombier Mether,
1097dd7cddfSDavid du Colombier Methererr,
1107dd7cddfSDavid du Colombier Metherin,
1117dd7cddfSDavid du Colombier Metherout,
1127dd7cddfSDavid du Colombier Mfault,
113f86ef3ceSDavid du Colombier Midle,
114f86ef3ceSDavid du Colombier Minintr,
1157dd7cddfSDavid du Colombier Mintr,
1167dd7cddfSDavid du Colombier Mload,
1177dd7cddfSDavid du Colombier Mmem,
1187dd7cddfSDavid du Colombier Mswap,
1197dd7cddfSDavid du Colombier Msyscall,
1207dd7cddfSDavid du Colombier Mtlbmiss,
1217dd7cddfSDavid du Colombier Mtlbpurge,
1229a747e4fSDavid du Colombier Msignal,
123b2495906SDavid du Colombier Mtemp,
1247dd7cddfSDavid du Colombier Nmenu2,
1257dd7cddfSDavid du Colombier };
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier char *menu2str[Nmenu2+1] = {
128f86ef3ceSDavid du Colombier "add battery ",
1297dd7cddfSDavid du Colombier "add context ",
1307dd7cddfSDavid du Colombier "add ether ",
1317dd7cddfSDavid du Colombier "add ethererr",
1327dd7cddfSDavid du Colombier "add etherin ",
1337dd7cddfSDavid du Colombier "add etherout",
1347dd7cddfSDavid du Colombier "add fault ",
135f86ef3ceSDavid du Colombier "add idle ",
136f86ef3ceSDavid du Colombier "add inintr ",
1377dd7cddfSDavid du Colombier "add intr ",
1387dd7cddfSDavid du Colombier "add load ",
1397dd7cddfSDavid du Colombier "add mem ",
1407dd7cddfSDavid du Colombier "add swap ",
1417dd7cddfSDavid du Colombier "add syscall ",
1427dd7cddfSDavid du Colombier "add tlbmiss ",
1437dd7cddfSDavid du Colombier "add tlbpurge",
1449a747e4fSDavid du Colombier "add 802.11b ",
145b2495906SDavid du Colombier "add temp ",
1467dd7cddfSDavid du Colombier nil,
1477dd7cddfSDavid du Colombier };
1487dd7cddfSDavid du Colombier
1497dd7cddfSDavid du Colombier
150b2495906SDavid du Colombier void contextval(Machine*, uvlong*, uvlong*, int),
151b2495906SDavid du Colombier etherval(Machine*, uvlong*, uvlong*, int),
152b2495906SDavid du Colombier ethererrval(Machine*, uvlong*, uvlong*, int),
153b2495906SDavid du Colombier etherinval(Machine*, uvlong*, uvlong*, int),
154b2495906SDavid du Colombier etheroutval(Machine*, uvlong*, uvlong*, int),
155b2495906SDavid du Colombier faultval(Machine*, uvlong*, uvlong*, int),
156b2495906SDavid du Colombier intrval(Machine*, uvlong*, uvlong*, int),
157b2495906SDavid du Colombier inintrval(Machine*, uvlong*, uvlong*, int),
158b2495906SDavid du Colombier loadval(Machine*, uvlong*, uvlong*, int),
159b2495906SDavid du Colombier idleval(Machine*, uvlong*, uvlong*, int),
160b2495906SDavid du Colombier memval(Machine*, uvlong*, uvlong*, int),
161b2495906SDavid du Colombier swapval(Machine*, uvlong*, uvlong*, int),
162b2495906SDavid du Colombier syscallval(Machine*, uvlong*, uvlong*, int),
163b2495906SDavid du Colombier tlbmissval(Machine*, uvlong*, uvlong*, int),
164b2495906SDavid du Colombier tlbpurgeval(Machine*, uvlong*, uvlong*, int),
165b2495906SDavid du Colombier batteryval(Machine*, uvlong*, uvlong*, int),
166b2495906SDavid du Colombier signalval(Machine*, uvlong*, uvlong*, int),
167b2495906SDavid du Colombier tempval(Machine*, uvlong*, uvlong*, int);
1687dd7cddfSDavid du Colombier
1697dd7cddfSDavid du Colombier Menu menu2 = {menu2str, nil};
1707dd7cddfSDavid du Colombier int present[Nmenu2];
171b2495906SDavid du Colombier void (*newvaluefn[Nmenu2])(Machine*, uvlong*, uvlong*, int init) = {
172f86ef3ceSDavid du Colombier batteryval,
1737dd7cddfSDavid du Colombier contextval,
1747dd7cddfSDavid du Colombier etherval,
1757dd7cddfSDavid du Colombier ethererrval,
1767dd7cddfSDavid du Colombier etherinval,
1777dd7cddfSDavid du Colombier etheroutval,
1787dd7cddfSDavid du Colombier faultval,
179f86ef3ceSDavid du Colombier idleval,
180f86ef3ceSDavid du Colombier inintrval,
1817dd7cddfSDavid du Colombier intrval,
1827dd7cddfSDavid du Colombier loadval,
1837dd7cddfSDavid du Colombier memval,
1847dd7cddfSDavid du Colombier swapval,
1857dd7cddfSDavid du Colombier syscallval,
1867dd7cddfSDavid du Colombier tlbmissval,
1877dd7cddfSDavid du Colombier tlbpurgeval,
1889a747e4fSDavid du Colombier signalval,
189b2495906SDavid du Colombier tempval,
1907dd7cddfSDavid du Colombier };
1917dd7cddfSDavid du Colombier
1927dd7cddfSDavid du Colombier Image *cols[Ncolor][3];
1937dd7cddfSDavid du Colombier Graph *graph;
1947dd7cddfSDavid du Colombier Machine *mach;
1957dd7cddfSDavid du Colombier Font *mediumfont;
1967dd7cddfSDavid du Colombier char *mysysname;
197*fee9fd16SDavid du Colombier char *mycputype;
198b2495906SDavid du Colombier char argchars[] = "8bceEfiImlnpstwz";
1997dd7cddfSDavid du Colombier int pids[NPROC];
2007dd7cddfSDavid du Colombier int parity; /* toggled to avoid patterns in textured background */
2017dd7cddfSDavid du Colombier int nmach;
2027dd7cddfSDavid du Colombier int ngraph; /* totaly number is ngraph*nmach */
20380ee5cbfSDavid du Colombier double scale = 1.0;
20480ee5cbfSDavid du Colombier int logscale = 0;
20580ee5cbfSDavid du Colombier int ylabels = 0;
2069a747e4fSDavid du Colombier int oldsystem = 0;
207186fc3d1SDavid du Colombier int sleeptime = 1000;
2087dd7cddfSDavid du Colombier
2097dd7cddfSDavid du Colombier char *procnames[NPROC] = {"main", "mouse"};
2107dd7cddfSDavid du Colombier
2117dd7cddfSDavid du Colombier void
killall(char * s)2127dd7cddfSDavid du Colombier killall(char *s)
2137dd7cddfSDavid du Colombier {
2147dd7cddfSDavid du Colombier int i, pid;
2157dd7cddfSDavid du Colombier
2167dd7cddfSDavid du Colombier pid = getpid();
2177dd7cddfSDavid du Colombier for(i=0; i<NPROC; i++)
2187dd7cddfSDavid du Colombier if(pids[i] && pids[i]!=pid)
2197dd7cddfSDavid du Colombier postnote(PNPROC, pids[i], "kill");
2207dd7cddfSDavid du Colombier exits(s);
2217dd7cddfSDavid du Colombier }
2227dd7cddfSDavid du Colombier
2237dd7cddfSDavid du Colombier void*
emalloc(ulong sz)2247dd7cddfSDavid du Colombier emalloc(ulong sz)
2257dd7cddfSDavid du Colombier {
2267dd7cddfSDavid du Colombier void *v;
2277dd7cddfSDavid du Colombier v = malloc(sz);
2287dd7cddfSDavid du Colombier if(v == nil) {
2297dd7cddfSDavid du Colombier fprint(2, "stats: out of memory allocating %ld: %r\n", sz);
2307dd7cddfSDavid du Colombier killall("mem");
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier memset(v, 0, sz);
2337dd7cddfSDavid du Colombier return v;
2347dd7cddfSDavid du Colombier }
2357dd7cddfSDavid du Colombier
2367dd7cddfSDavid du Colombier void*
erealloc(void * v,ulong sz)2377dd7cddfSDavid du Colombier erealloc(void *v, ulong sz)
2387dd7cddfSDavid du Colombier {
2397dd7cddfSDavid du Colombier v = realloc(v, sz);
2407dd7cddfSDavid du Colombier if(v == nil) {
2417dd7cddfSDavid du Colombier fprint(2, "stats: out of memory reallocating %ld: %r\n", sz);
2427dd7cddfSDavid du Colombier killall("mem");
2437dd7cddfSDavid du Colombier }
2447dd7cddfSDavid du Colombier return v;
2453e12c5d1SDavid du Colombier }
2463e12c5d1SDavid du Colombier
2473e12c5d1SDavid du Colombier char*
estrdup(char * s)2487dd7cddfSDavid du Colombier estrdup(char *s)
2493e12c5d1SDavid du Colombier {
2507dd7cddfSDavid du Colombier char *t;
2517dd7cddfSDavid du Colombier if((t = strdup(s)) == nil) {
2527dd7cddfSDavid du Colombier fprint(2, "stats: out of memory in strdup(%.10s): %r\n", s);
2537dd7cddfSDavid du Colombier killall("mem");
2547dd7cddfSDavid du Colombier }
2557dd7cddfSDavid du Colombier return t;
2563e12c5d1SDavid du Colombier }
2573e12c5d1SDavid du Colombier
2583e12c5d1SDavid du Colombier void
mkcol(int i,int c0,int c1,int c2)2597dd7cddfSDavid du Colombier mkcol(int i, int c0, int c1, int c2)
2603e12c5d1SDavid du Colombier {
2617dd7cddfSDavid du Colombier cols[i][0] = allocimagemix(display, c0, DWhite);
2627dd7cddfSDavid du Colombier cols[i][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c1);
2637dd7cddfSDavid du Colombier cols[i][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, c2);
2647dd7cddfSDavid du Colombier }
2653e12c5d1SDavid du Colombier
2667dd7cddfSDavid du Colombier void
colinit(void)2677dd7cddfSDavid du Colombier colinit(void)
2687dd7cddfSDavid du Colombier {
2697dd7cddfSDavid du Colombier mediumfont = openfont(display, "/lib/font/bit/pelm/latin1.8.font");
2707dd7cddfSDavid du Colombier if(mediumfont == nil)
2717dd7cddfSDavid du Colombier mediumfont = font;
2727dd7cddfSDavid du Colombier
2737dd7cddfSDavid du Colombier /* Peach */
2747dd7cddfSDavid du Colombier mkcol(0, 0xFFAAAAFF, 0xFFAAAAFF, 0xBB5D5DFF);
2757dd7cddfSDavid du Colombier /* Aqua */
2767dd7cddfSDavid du Colombier mkcol(1, DPalebluegreen, DPalegreygreen, DPurpleblue);
2777dd7cddfSDavid du Colombier /* Yellow */
2787dd7cddfSDavid du Colombier mkcol(2, DPaleyellow, DDarkyellow, DYellowgreen);
2797dd7cddfSDavid du Colombier /* Green */
2807dd7cddfSDavid du Colombier mkcol(3, DPalegreen, DMedgreen, DDarkgreen);
2817dd7cddfSDavid du Colombier /* Blue */
2827dd7cddfSDavid du Colombier mkcol(4, 0x00AAFFFF, 0x00AAFFFF, 0x0088CCFF);
2837dd7cddfSDavid du Colombier /* Grey */
2847dd7cddfSDavid du Colombier cols[5][0] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xEEEEEEFF);
2857dd7cddfSDavid du Colombier cols[5][1] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0xCCCCCCFF);
2867dd7cddfSDavid du Colombier cols[5][2] = allocimage(display, Rect(0,0,1,1), CMAP8, 1, 0x888888FF);
2877dd7cddfSDavid du Colombier }
2887dd7cddfSDavid du Colombier
2897dd7cddfSDavid du Colombier int
loadbuf(Machine * m,int * fd)2907dd7cddfSDavid du Colombier loadbuf(Machine *m, int *fd)
2917dd7cddfSDavid du Colombier {
2927dd7cddfSDavid du Colombier int n;
2937dd7cddfSDavid du Colombier
2947dd7cddfSDavid du Colombier
2957dd7cddfSDavid du Colombier if(*fd < 0)
2967dd7cddfSDavid du Colombier return 0;
2977dd7cddfSDavid du Colombier seek(*fd, 0, 0);
2982e7ae8b5SDavid du Colombier n = read(*fd, m->buf, sizeof m->buf-1);
2997dd7cddfSDavid du Colombier if(n <= 0){
3007dd7cddfSDavid du Colombier close(*fd);
3017dd7cddfSDavid du Colombier *fd = -1;
3027dd7cddfSDavid du Colombier return 0;
3037dd7cddfSDavid du Colombier }
3047dd7cddfSDavid du Colombier m->bufp = m->buf;
3057dd7cddfSDavid du Colombier m->ebufp = m->buf+n;
3062e7ae8b5SDavid du Colombier m->buf[n] = 0;
3077dd7cddfSDavid du Colombier return 1;
3087dd7cddfSDavid du Colombier }
3097dd7cddfSDavid du Colombier
3107dd7cddfSDavid du Colombier void
label(Point p,int dy,char * text)3117dd7cddfSDavid du Colombier label(Point p, int dy, char *text)
3127dd7cddfSDavid du Colombier {
3137dd7cddfSDavid du Colombier char *s;
3147dd7cddfSDavid du Colombier Rune r[2];
3157dd7cddfSDavid du Colombier int w, maxw, maxy;
3167dd7cddfSDavid du Colombier
3177dd7cddfSDavid du Colombier p.x += Labspace;
3187dd7cddfSDavid du Colombier maxy = p.y+dy;
3197dd7cddfSDavid du Colombier maxw = 0;
3207dd7cddfSDavid du Colombier r[1] = '\0';
3217dd7cddfSDavid du Colombier for(s=text; *s; ){
3227dd7cddfSDavid du Colombier if(p.y+mediumfont->height-Ysqueeze > maxy)
3237dd7cddfSDavid du Colombier break;
3247dd7cddfSDavid du Colombier w = chartorune(r, s);
3257dd7cddfSDavid du Colombier s += w;
3267dd7cddfSDavid du Colombier w = runestringwidth(mediumfont, r);
3277dd7cddfSDavid du Colombier if(w > maxw)
3287dd7cddfSDavid du Colombier maxw = w;
3297dd7cddfSDavid du Colombier runestring(screen, p, display->black, ZP, mediumfont, r);
3307dd7cddfSDavid du Colombier p.y += mediumfont->height-Ysqueeze;
3317dd7cddfSDavid du Colombier }
3327dd7cddfSDavid du Colombier }
3337dd7cddfSDavid du Colombier
3347dd7cddfSDavid du Colombier Point
paritypt(int x)3357dd7cddfSDavid du Colombier paritypt(int x)
3367dd7cddfSDavid du Colombier {
3377dd7cddfSDavid du Colombier return Pt(x+parity, 0);
3387dd7cddfSDavid du Colombier }
3397dd7cddfSDavid du Colombier
3407dd7cddfSDavid du Colombier Point
datapoint(Graph * g,int x,uvlong v,uvlong vmax)341b2495906SDavid du Colombier datapoint(Graph *g, int x, uvlong v, uvlong vmax)
3427dd7cddfSDavid du Colombier {
3437dd7cddfSDavid du Colombier Point p;
34480ee5cbfSDavid du Colombier double y;
3457dd7cddfSDavid du Colombier
3467dd7cddfSDavid du Colombier p.x = x;
34780ee5cbfSDavid du Colombier y = ((double)v)/(vmax*scale);
34880ee5cbfSDavid du Colombier if(logscale){
34980ee5cbfSDavid du Colombier /*
35080ee5cbfSDavid du Colombier * Arrange scale to cover a factor of 1000.
35180ee5cbfSDavid du Colombier * vmax corresponds to the 100 mark.
35280ee5cbfSDavid du Colombier * 10*vmax is the top of the scale.
35380ee5cbfSDavid du Colombier */
35480ee5cbfSDavid du Colombier if(y <= 0.)
35580ee5cbfSDavid du Colombier y = 0;
35680ee5cbfSDavid du Colombier else{
35780ee5cbfSDavid du Colombier y = log10(y);
35880ee5cbfSDavid du Colombier /* 1 now corresponds to the top; -2 to the bottom; rescale */
35980ee5cbfSDavid du Colombier y = (y+2.)/3.;
36080ee5cbfSDavid du Colombier }
36180ee5cbfSDavid du Colombier }
362853458f3SDavid du Colombier if(y < 0x7fffffff){ /* avoid floating overflow */
36380ee5cbfSDavid du Colombier p.y = g->r.max.y - Dy(g->r)*y - Dot;
3647dd7cddfSDavid du Colombier if(p.y < g->r.min.y)
3657dd7cddfSDavid du Colombier p.y = g->r.min.y;
3667dd7cddfSDavid du Colombier if(p.y > g->r.max.y-Dot)
3677dd7cddfSDavid du Colombier p.y = g->r.max.y-Dot;
368853458f3SDavid du Colombier }else
369853458f3SDavid du Colombier p.y = g->r.max.y-Dot;
3707dd7cddfSDavid du Colombier return p;
3717dd7cddfSDavid du Colombier }
3727dd7cddfSDavid du Colombier
3737dd7cddfSDavid du Colombier void
drawdatum(Graph * g,int x,uvlong prev,uvlong v,uvlong vmax)374b2495906SDavid du Colombier drawdatum(Graph *g, int x, uvlong prev, uvlong v, uvlong vmax)
3757dd7cddfSDavid du Colombier {
3767dd7cddfSDavid du Colombier int c;
3777dd7cddfSDavid du Colombier Point p, q;
3787dd7cddfSDavid du Colombier
3797dd7cddfSDavid du Colombier c = g->colindex;
3807dd7cddfSDavid du Colombier p = datapoint(g, x, v, vmax);
3817dd7cddfSDavid du Colombier q = datapoint(g, x, prev, vmax);
3827dd7cddfSDavid du Colombier if(p.y < q.y){
3837dd7cddfSDavid du Colombier draw(screen, Rect(p.x, g->r.min.y, p.x+1, p.y), cols[c][0], nil, paritypt(p.x));
3847dd7cddfSDavid du Colombier draw(screen, Rect(p.x, p.y, p.x+1, q.y+Dot), cols[c][2], nil, ZP);
3857dd7cddfSDavid du Colombier draw(screen, Rect(p.x, q.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);
3867dd7cddfSDavid du Colombier }else{
3877dd7cddfSDavid du Colombier draw(screen, Rect(p.x, g->r.min.y, p.x+1, q.y), cols[c][0], nil, paritypt(p.x));
3887dd7cddfSDavid du Colombier draw(screen, Rect(p.x, q.y, p.x+1, p.y+Dot), cols[c][2], nil, ZP);
3897dd7cddfSDavid du Colombier draw(screen, Rect(p.x, p.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);
3907dd7cddfSDavid du Colombier }
3917dd7cddfSDavid du Colombier
3927dd7cddfSDavid du Colombier }
3937dd7cddfSDavid du Colombier
3947dd7cddfSDavid du Colombier void
redraw(Graph * g,uvlong vmax)395b2495906SDavid du Colombier redraw(Graph *g, uvlong vmax)
3967dd7cddfSDavid du Colombier {
3977dd7cddfSDavid du Colombier int i, c;
3987dd7cddfSDavid du Colombier
3997dd7cddfSDavid du Colombier c = g->colindex;
4007dd7cddfSDavid du Colombier draw(screen, g->r, cols[c][0], nil, paritypt(g->r.min.x));
4017dd7cddfSDavid du Colombier for(i=1; i<Dx(g->r); i++)
4027dd7cddfSDavid du Colombier drawdatum(g, g->r.max.x-i, g->data[i-1], g->data[i], vmax);
4037dd7cddfSDavid du Colombier drawdatum(g, g->r.min.x, g->data[i], g->data[i], vmax);
4047dd7cddfSDavid du Colombier g->overflow = 0;
4057dd7cddfSDavid du Colombier }
4067dd7cddfSDavid du Colombier
4077dd7cddfSDavid du Colombier void
update1(Graph * g,uvlong v,uvlong vmax)408b2495906SDavid du Colombier update1(Graph *g, uvlong v, uvlong vmax)
4097dd7cddfSDavid du Colombier {
41031a0f4b7SDavid du Colombier char buf[48];
41180ee5cbfSDavid du Colombier int overflow;
4127dd7cddfSDavid du Colombier
4137dd7cddfSDavid du Colombier if(g->overflow && g->overtmp!=nil)
4147dd7cddfSDavid du Colombier draw(screen, g->overtmp->r, g->overtmp, nil, g->overtmp->r.min);
4157dd7cddfSDavid du Colombier draw(screen, g->r, screen, nil, Pt(g->r.min.x+1, g->r.min.y));
4167dd7cddfSDavid du Colombier drawdatum(g, g->r.max.x-1, g->data[0], v, vmax);
4177dd7cddfSDavid du Colombier memmove(g->data+1, g->data, (g->ndata-1)*sizeof(g->data[0]));
4187dd7cddfSDavid du Colombier g->data[0] = v;
4197dd7cddfSDavid du Colombier g->overflow = 0;
42080ee5cbfSDavid du Colombier if(logscale)
42180ee5cbfSDavid du Colombier overflow = (v>10*vmax*scale);
42280ee5cbfSDavid du Colombier else
42380ee5cbfSDavid du Colombier overflow = (v>vmax*scale);
42480ee5cbfSDavid du Colombier if(overflow && g->overtmp!=nil){
4257dd7cddfSDavid du Colombier g->overflow = 1;
4267dd7cddfSDavid du Colombier draw(g->overtmp, g->overtmp->r, screen, nil, g->overtmp->r.min);
427b2495906SDavid du Colombier sprint(buf, "%llud", v);
4287dd7cddfSDavid du Colombier string(screen, g->overtmp->r.min, display->black, ZP, mediumfont, buf);
4297dd7cddfSDavid du Colombier }
4307dd7cddfSDavid du Colombier }
4317dd7cddfSDavid du Colombier
4327dd7cddfSDavid du Colombier /* read one line of text from buffer and process integers */
4337dd7cddfSDavid du Colombier int
readnums(Machine * m,int n,uvlong * a,int spanlines)434b2495906SDavid du Colombier readnums(Machine *m, int n, uvlong *a, int spanlines)
4357dd7cddfSDavid du Colombier {
4367dd7cddfSDavid du Colombier int i;
437853458f3SDavid du Colombier char *p, *q, *ep;
4387dd7cddfSDavid du Colombier
4397dd7cddfSDavid du Colombier if(spanlines)
4407dd7cddfSDavid du Colombier ep = m->ebufp;
4417dd7cddfSDavid du Colombier else
4427dd7cddfSDavid du Colombier for(ep=m->bufp; ep<m->ebufp; ep++)
4437dd7cddfSDavid du Colombier if(*ep == '\n')
4447dd7cddfSDavid du Colombier break;
4457dd7cddfSDavid du Colombier p = m->bufp;
4467dd7cddfSDavid du Colombier for(i=0; i<n && p<ep; i++){
447b2495906SDavid du Colombier while(p<ep && (!isascii(*p) || !isdigit(*p)) && *p!='-')
4487dd7cddfSDavid du Colombier p++;
4497dd7cddfSDavid du Colombier if(p == ep)
4507dd7cddfSDavid du Colombier break;
451853458f3SDavid du Colombier a[i] = strtoull(p, &q, 10);
452853458f3SDavid du Colombier p = q;
4537dd7cddfSDavid du Colombier }
4547dd7cddfSDavid du Colombier if(ep < m->ebufp)
4557dd7cddfSDavid du Colombier ep++;
4567dd7cddfSDavid du Colombier m->bufp = ep;
4577dd7cddfSDavid du Colombier return i == n;
4587dd7cddfSDavid du Colombier }
4597dd7cddfSDavid du Colombier
4607dd7cddfSDavid du Colombier /* Network on fd1, mount driver on fd0 */
4617dd7cddfSDavid du Colombier static int
filter(int fd)4627dd7cddfSDavid du Colombier filter(int fd)
4637dd7cddfSDavid du Colombier {
4647dd7cddfSDavid du Colombier int p[2];
4657dd7cddfSDavid du Colombier
4667dd7cddfSDavid du Colombier if(pipe(p) < 0){
4677dd7cddfSDavid du Colombier fprint(2, "stats: can't pipe: %r\n");
4687dd7cddfSDavid du Colombier killall("pipe");
4697dd7cddfSDavid du Colombier }
4707dd7cddfSDavid du Colombier
4717dd7cddfSDavid du Colombier switch(rfork(RFNOWAIT|RFPROC|RFFDG)) {
4727dd7cddfSDavid du Colombier case -1:
4737dd7cddfSDavid du Colombier sysfatal("rfork record module");
4747dd7cddfSDavid du Colombier case 0:
4757dd7cddfSDavid du Colombier dup(fd, 1);
4767dd7cddfSDavid du Colombier close(fd);
4777dd7cddfSDavid du Colombier dup(p[0], 0);
4787dd7cddfSDavid du Colombier close(p[0]);
4797dd7cddfSDavid du Colombier close(p[1]);
480f19e7b74SDavid du Colombier execl("/bin/aux/fcall", "fcall", nil);
4817dd7cddfSDavid du Colombier fprint(2, "stats: can't exec fcall: %r\n");
4827dd7cddfSDavid du Colombier killall("fcall");
4837dd7cddfSDavid du Colombier default:
4847dd7cddfSDavid du Colombier close(fd);
4857dd7cddfSDavid du Colombier close(p[0]);
4867dd7cddfSDavid du Colombier }
4877dd7cddfSDavid du Colombier return p[1];
4887dd7cddfSDavid du Colombier }
4897dd7cddfSDavid du Colombier
4907dd7cddfSDavid du Colombier /*
4917dd7cddfSDavid du Colombier * 9fs
4927dd7cddfSDavid du Colombier */
4937dd7cddfSDavid du Colombier int
connect9fs(char * addr)4947dd7cddfSDavid du Colombier connect9fs(char *addr)
4957dd7cddfSDavid du Colombier {
4969a747e4fSDavid du Colombier char dir[256], *na;
4977dd7cddfSDavid du Colombier int fd;
4987dd7cddfSDavid du Colombier
4997dd7cddfSDavid du Colombier fprint(2, "connect9fs...");
5007dd7cddfSDavid du Colombier na = netmkaddr(addr, 0, "9fs");
5017dd7cddfSDavid du Colombier
5027dd7cddfSDavid du Colombier fprint(2, "dial %s...", na);
5037dd7cddfSDavid du Colombier if((fd = dial(na, 0, dir, 0)) < 0)
5047dd7cddfSDavid du Colombier return -1;
5057dd7cddfSDavid du Colombier
5067dd7cddfSDavid du Colombier fprint(2, "dir %s...", dir);
5079a747e4fSDavid du Colombier // if(strstr(dir, "tcp"))
5089a747e4fSDavid du Colombier // fd = filter(fd);
5097dd7cddfSDavid du Colombier return fd;
5107dd7cddfSDavid du Colombier }
5117dd7cddfSDavid du Colombier
5129a747e4fSDavid du Colombier int
old9p(int fd)5139a747e4fSDavid du Colombier old9p(int fd)
5149a747e4fSDavid du Colombier {
5159a747e4fSDavid du Colombier int p[2];
5169a747e4fSDavid du Colombier
5179a747e4fSDavid du Colombier if(pipe(p) < 0)
5189a747e4fSDavid du Colombier return -1;
5199a747e4fSDavid du Colombier
5209a747e4fSDavid du Colombier switch(rfork(RFPROC|RFFDG|RFNAMEG)) {
5219a747e4fSDavid du Colombier case -1:
5229a747e4fSDavid du Colombier return -1;
5239a747e4fSDavid du Colombier case 0:
5249a747e4fSDavid du Colombier if(fd != 1){
5259a747e4fSDavid du Colombier dup(fd, 1);
5269a747e4fSDavid du Colombier close(fd);
5279a747e4fSDavid du Colombier }
5289a747e4fSDavid du Colombier if(p[0] != 0){
5299a747e4fSDavid du Colombier dup(p[0], 0);
5309a747e4fSDavid du Colombier close(p[0]);
5319a747e4fSDavid du Colombier }
5329a747e4fSDavid du Colombier close(p[1]);
5339a747e4fSDavid du Colombier if(0){
5349a747e4fSDavid du Colombier fd = open("/sys/log/cpu", OWRITE);
5359a747e4fSDavid du Colombier if(fd != 2){
5369a747e4fSDavid du Colombier dup(fd, 2);
5379a747e4fSDavid du Colombier close(fd);
5389a747e4fSDavid du Colombier }
539f19e7b74SDavid du Colombier execl("/bin/srvold9p", "srvold9p", "-ds", nil);
5409a747e4fSDavid du Colombier } else
541f19e7b74SDavid du Colombier execl("/bin/srvold9p", "srvold9p", "-s", nil);
5429a747e4fSDavid du Colombier return -1;
5439a747e4fSDavid du Colombier default:
5449a747e4fSDavid du Colombier close(fd);
5459a747e4fSDavid du Colombier close(p[0]);
5469a747e4fSDavid du Colombier }
5479a747e4fSDavid du Colombier return p[1];
5489a747e4fSDavid du Colombier }
5499a747e4fSDavid du Colombier
5509a747e4fSDavid du Colombier
5517dd7cddfSDavid du Colombier /*
5527dd7cddfSDavid du Colombier * exportfs
5537dd7cddfSDavid du Colombier */
5547dd7cddfSDavid du Colombier int
connectexportfs(char * addr)5557dd7cddfSDavid du Colombier connectexportfs(char *addr)
5567dd7cddfSDavid du Colombier {
5579a747e4fSDavid du Colombier char buf[ERRMAX], dir[256], *na;
5587dd7cddfSDavid du Colombier int fd, n;
5597dd7cddfSDavid du Colombier char *tree;
5609a747e4fSDavid du Colombier AuthInfo *ai;
5617dd7cddfSDavid du Colombier
5627dd7cddfSDavid du Colombier tree = "/";
5637dd7cddfSDavid du Colombier na = netmkaddr(addr, 0, "exportfs");
5647dd7cddfSDavid du Colombier if((fd = dial(na, 0, dir, 0)) < 0)
5657dd7cddfSDavid du Colombier return -1;
5667dd7cddfSDavid du Colombier
5679a747e4fSDavid du Colombier ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client");
5689a747e4fSDavid du Colombier if(ai == nil)
5697dd7cddfSDavid du Colombier return -1;
5707dd7cddfSDavid du Colombier
5717dd7cddfSDavid du Colombier n = write(fd, tree, strlen(tree));
5727dd7cddfSDavid du Colombier if(n < 0){
5737dd7cddfSDavid du Colombier close(fd);
5747dd7cddfSDavid du Colombier return -1;
5757dd7cddfSDavid du Colombier }
5767dd7cddfSDavid du Colombier
5777dd7cddfSDavid du Colombier strcpy(buf, "can't read tree");
5787dd7cddfSDavid du Colombier n = read(fd, buf, sizeof buf - 1);
5797dd7cddfSDavid du Colombier if(n!=2 || buf[0]!='O' || buf[1]!='K'){
5807dd7cddfSDavid du Colombier buf[sizeof buf - 1] = '\0';
5817dd7cddfSDavid du Colombier werrstr("bad remote tree: %s\n", buf);
5827dd7cddfSDavid du Colombier close(fd);
5837dd7cddfSDavid du Colombier return -1;
5847dd7cddfSDavid du Colombier }
5857dd7cddfSDavid du Colombier
5869a747e4fSDavid du Colombier // if(strstr(dir, "tcp"))
5879a747e4fSDavid du Colombier // fd = filter(fd);
5889a747e4fSDavid du Colombier
5899a747e4fSDavid du Colombier if(oldsystem)
5909a747e4fSDavid du Colombier return old9p(fd);
5917dd7cddfSDavid du Colombier
5927dd7cddfSDavid du Colombier return fd;
5937dd7cddfSDavid du Colombier }
5947dd7cddfSDavid du Colombier
5958c1c8807SDavid du Colombier int
readswap(Machine * m,uvlong * a)596b2495906SDavid du Colombier readswap(Machine *m, uvlong *a)
5972e7ae8b5SDavid du Colombier {
5982e7ae8b5SDavid du Colombier if(strstr(m->buf, "memory\n")){
5992e7ae8b5SDavid du Colombier /* new /dev/swap - skip first 3 numbers */
6002e7ae8b5SDavid du Colombier if(!readnums(m, 7, a, 1))
6012e7ae8b5SDavid du Colombier return 0;
6022e7ae8b5SDavid du Colombier a[0] = a[3];
6032e7ae8b5SDavid du Colombier a[1] = a[4];
6042e7ae8b5SDavid du Colombier a[2] = a[5];
6052e7ae8b5SDavid du Colombier a[3] = a[6];
6062e7ae8b5SDavid du Colombier return 1;
6072e7ae8b5SDavid du Colombier }
6082e7ae8b5SDavid du Colombier return readnums(m, nelem(m->devswap), a, 0);
6092e7ae8b5SDavid du Colombier }
6102e7ae8b5SDavid du Colombier
611eebedd9aSDavid du Colombier char*
shortname(char * s)612eebedd9aSDavid du Colombier shortname(char *s)
613eebedd9aSDavid du Colombier {
614eebedd9aSDavid du Colombier char *p, *e;
615eebedd9aSDavid du Colombier
616eebedd9aSDavid du Colombier p = estrdup(s);
617eebedd9aSDavid du Colombier e = strchr(p, '.');
618eebedd9aSDavid du Colombier if(e)
619eebedd9aSDavid du Colombier *e = 0;
620eebedd9aSDavid du Colombier return p;
621eebedd9aSDavid du Colombier }
622eebedd9aSDavid du Colombier
623eebedd9aSDavid du Colombier int
ilog10(uvlong j)624b2495906SDavid du Colombier ilog10(uvlong j)
625eebedd9aSDavid du Colombier {
626eebedd9aSDavid du Colombier int i;
627eebedd9aSDavid du Colombier
628eebedd9aSDavid du Colombier for(i = 0; j >= 10; i++)
629eebedd9aSDavid du Colombier j /= 10;
630eebedd9aSDavid du Colombier return i;
631eebedd9aSDavid du Colombier }
632eebedd9aSDavid du Colombier
6332e7ae8b5SDavid du Colombier int
initmach(Machine * m,char * name)6347dd7cddfSDavid du Colombier initmach(Machine *m, char *name)
6357dd7cddfSDavid du Colombier {
6367dd7cddfSDavid du Colombier int n, fd;
637b2495906SDavid du Colombier uvlong a[MAXNUM];
6387dd7cddfSDavid du Colombier char *p, mpt[256], buf[256];
6397dd7cddfSDavid du Colombier
6407dd7cddfSDavid du Colombier p = strchr(name, '!');
6418c1c8807SDavid du Colombier if(p)
6427dd7cddfSDavid du Colombier p++;
6438c1c8807SDavid du Colombier else
6447dd7cddfSDavid du Colombier p = name;
6457dd7cddfSDavid du Colombier m->name = estrdup(p);
646eebedd9aSDavid du Colombier m->shortname = shortname(p);
6477dd7cddfSDavid du Colombier m->remote = (strcmp(p, mysysname) != 0);
6487dd7cddfSDavid du Colombier if(m->remote == 0)
6497dd7cddfSDavid du Colombier strcpy(mpt, "");
6507dd7cddfSDavid du Colombier else{
6517dd7cddfSDavid du Colombier snprint(mpt, sizeof mpt, "/n/%s", p);
6527dd7cddfSDavid du Colombier fd = connectexportfs(name);
6537dd7cddfSDavid du Colombier if(fd < 0){
6547dd7cddfSDavid du Colombier fprint(2, "can't connect to %s: %r\n", name);
6558c1c8807SDavid du Colombier return 0;
6567dd7cddfSDavid du Colombier }
6579a747e4fSDavid du Colombier /* BUG? need to use amount() now? */
6589a747e4fSDavid du Colombier if(mount(fd, -1, mpt, MREPL, "") < 0){
6597dd7cddfSDavid du Colombier fprint(2, "stats: mount %s on %s failed (%r); trying /n/sid\n", name, mpt);
6607dd7cddfSDavid du Colombier strcpy(mpt, "/n/sid");
6619a747e4fSDavid du Colombier if(mount(fd, -1, mpt, MREPL, "") < 0){
6627dd7cddfSDavid du Colombier fprint(2, "stats: mount %s on %s failed: %r\n", name, mpt);
6638c1c8807SDavid du Colombier return 0;
6647dd7cddfSDavid du Colombier }
6657dd7cddfSDavid du Colombier }
6667dd7cddfSDavid du Colombier }
6677dd7cddfSDavid du Colombier
6687dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/swap", mpt);
6697dd7cddfSDavid du Colombier m->swapfd = open(buf, OREAD);
6702e7ae8b5SDavid du Colombier if(loadbuf(m, &m->swapfd) && readswap(m, a))
6717dd7cddfSDavid du Colombier memmove(m->devswap, a, sizeof m->devswap);
672b2495906SDavid du Colombier else{
673b2495906SDavid du Colombier m->devswap[Maxswap] = 100;
674b2495906SDavid du Colombier m->devswap[Maxmem] = 100;
675b2495906SDavid du Colombier }
6767dd7cddfSDavid du Colombier
6777dd7cddfSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/sysstat", mpt);
6787dd7cddfSDavid du Colombier m->statsfd = open(buf, OREAD);
6797dd7cddfSDavid du Colombier if(loadbuf(m, &m->statsfd)){
6807dd7cddfSDavid du Colombier for(n=0; readnums(m, nelem(m->devsysstat), a, 0); n++)
6817dd7cddfSDavid du Colombier ;
6827dd7cddfSDavid du Colombier m->nproc = n;
6837dd7cddfSDavid du Colombier }else
6847dd7cddfSDavid du Colombier m->nproc = 1;
685eebedd9aSDavid du Colombier m->lgproc = ilog10(m->nproc);
6867dd7cddfSDavid du Colombier
6873432ceaeSDavid du Colombier snprint(buf, sizeof buf, "%s/net/ether0/stats", mpt);
6883432ceaeSDavid du Colombier m->etherfd = open(buf, OREAD);
6897dd7cddfSDavid du Colombier if(loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1))
6907dd7cddfSDavid du Colombier memmove(m->netetherstats, a, sizeof m->netetherstats);
69180ee5cbfSDavid du Colombier
6923432ceaeSDavid du Colombier snprint(buf, sizeof buf, "%s/net/ether0/ifstats", mpt);
6933432ceaeSDavid du Colombier m->ifstatsfd = open(buf, OREAD);
6949a747e4fSDavid du Colombier if(loadbuf(m, &m->ifstatsfd)){
6959a747e4fSDavid du Colombier /* need to check that this is a wavelan interface */
6969a747e4fSDavid du Colombier if(strncmp(m->buf, "Signal: ", 8) == 0 && readnums(m, nelem(m->netetherifstats), a, 1))
6979a747e4fSDavid du Colombier memmove(m->netetherifstats, a, sizeof m->netetherifstats);
6989a747e4fSDavid du Colombier }
6999a747e4fSDavid du Colombier
70080ee5cbfSDavid du Colombier snprint(buf, sizeof buf, "%s/mnt/apm/battery", mpt);
70180ee5cbfSDavid du Colombier m->batteryfd = open(buf, OREAD);
7029a747e4fSDavid du Colombier m->bitsybatfd = -1;
7039a747e4fSDavid du Colombier if(m->batteryfd >= 0){
70480ee5cbfSDavid du Colombier if(loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0))
70580ee5cbfSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats));
7069a747e4fSDavid du Colombier }else{
7079a747e4fSDavid du Colombier snprint(buf, sizeof buf, "%s/dev/battery", mpt);
7089a747e4fSDavid du Colombier m->bitsybatfd = open(buf, OREAD);
7099a747e4fSDavid du Colombier if(loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0))
7109a747e4fSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats));
7119a747e4fSDavid du Colombier }
712b2495906SDavid du Colombier snprint(buf, sizeof buf, "%s/dev/cputemp", mpt);
713b2495906SDavid du Colombier m->tempfd = open(buf, OREAD);
714b2495906SDavid du Colombier if(loadbuf(m, &m->tempfd))
715b2495906SDavid du Colombier for(n=0; n < nelem(m->temp) && readnums(m, 2, a, 0); n++)
716b2495906SDavid du Colombier m->temp[n] = a[0];
7178c1c8807SDavid du Colombier return 1;
7187dd7cddfSDavid du Colombier }
7197dd7cddfSDavid du Colombier
7207dd7cddfSDavid du Colombier jmp_buf catchalarm;
7217dd7cddfSDavid du Colombier
7227dd7cddfSDavid du Colombier void
alarmed(void * a,char * s)7237dd7cddfSDavid du Colombier alarmed(void *a, char *s)
7247dd7cddfSDavid du Colombier {
7257dd7cddfSDavid du Colombier if(strcmp(s, "alarm") == 0)
7267dd7cddfSDavid du Colombier notejmp(a, catchalarm, 1);
7273e12c5d1SDavid du Colombier noted(NDFLT);
7283e12c5d1SDavid du Colombier }
7297dd7cddfSDavid du Colombier
7307dd7cddfSDavid du Colombier int
needswap(int init)7317dd7cddfSDavid du Colombier needswap(int init)
7327dd7cddfSDavid du Colombier {
7337dd7cddfSDavid du Colombier return init | present[Mmem] | present[Mswap];
7347dd7cddfSDavid du Colombier }
7357dd7cddfSDavid du Colombier
7367dd7cddfSDavid du Colombier
7377dd7cddfSDavid du Colombier int
needstat(int init)7387dd7cddfSDavid du Colombier needstat(int init)
7397dd7cddfSDavid du Colombier {
740dc5a79c1SDavid du Colombier return init | present[Mcontext] | present[Mfault] | present[Mintr] | present[Mload] | present[Midle] |
741f86ef3ceSDavid du Colombier present[Minintr] | present[Msyscall] | present[Mtlbmiss] | present[Mtlbpurge];
7427dd7cddfSDavid du Colombier }
7437dd7cddfSDavid du Colombier
7447dd7cddfSDavid du Colombier
7457dd7cddfSDavid du Colombier int
needether(int init)7467dd7cddfSDavid du Colombier needether(int init)
7477dd7cddfSDavid du Colombier {
7487dd7cddfSDavid du Colombier return init | present[Mether] | present[Metherin] | present[Metherout] | present[Methererr];
7497dd7cddfSDavid du Colombier }
7507dd7cddfSDavid du Colombier
75180ee5cbfSDavid du Colombier int
needbattery(int init)75280ee5cbfSDavid du Colombier needbattery(int init)
75380ee5cbfSDavid du Colombier {
75480ee5cbfSDavid du Colombier return init | present[Mbattery];
75580ee5cbfSDavid du Colombier }
75680ee5cbfSDavid du Colombier
7579a747e4fSDavid du Colombier int
needsignal(int init)7589a747e4fSDavid du Colombier needsignal(int init)
7599a747e4fSDavid du Colombier {
7609a747e4fSDavid du Colombier return init | present[Msignal];
7619a747e4fSDavid du Colombier }
7629a747e4fSDavid du Colombier
763b2495906SDavid du Colombier int
needtemp(int init)764b2495906SDavid du Colombier needtemp(int init)
765b2495906SDavid du Colombier {
766b2495906SDavid du Colombier return init | present[Mtemp];
767b2495906SDavid du Colombier }
768b2495906SDavid du Colombier
7697dd7cddfSDavid du Colombier void
readmach(Machine * m,int init)7707dd7cddfSDavid du Colombier readmach(Machine *m, int init)
7717dd7cddfSDavid du Colombier {
7727dd7cddfSDavid du Colombier int n, i;
773b2495906SDavid du Colombier uvlong a[nelem(m->devsysstat)];
7747dd7cddfSDavid du Colombier char buf[32];
7757dd7cddfSDavid du Colombier
7767dd7cddfSDavid du Colombier if(m->remote && (m->disable || setjmp(catchalarm))){
7778c1c8807SDavid du Colombier if (m->disable++ >= 5)
7788c1c8807SDavid du Colombier m->disable = 0; /* give it another chance */
7797dd7cddfSDavid du Colombier memmove(m->devsysstat, m->prevsysstat, sizeof m->devsysstat);
7807dd7cddfSDavid du Colombier memmove(m->netetherstats, m->prevetherstats, sizeof m->netetherstats);
7817dd7cddfSDavid du Colombier return;
7827dd7cddfSDavid du Colombier }
7838c1c8807SDavid du Colombier snprint(buf, sizeof buf, "%s", m->name);
7848c1c8807SDavid du Colombier if (strcmp(m->name, buf) != 0){
7858c1c8807SDavid du Colombier free(m->name);
7868c1c8807SDavid du Colombier m->name = estrdup(buf);
787eebedd9aSDavid du Colombier free(m->shortname);
788eebedd9aSDavid du Colombier m->shortname = shortname(buf);
7898c1c8807SDavid du Colombier if(display != nil) /* else we're still initializing */
7908c1c8807SDavid du Colombier eresized(0);
7918c1c8807SDavid du Colombier }
7927dd7cddfSDavid du Colombier if(m->remote){
7937dd7cddfSDavid du Colombier notify(alarmed);
7947dd7cddfSDavid du Colombier alarm(5000);
7957dd7cddfSDavid du Colombier }
7962e7ae8b5SDavid du Colombier if(needswap(init) && loadbuf(m, &m->swapfd) && readswap(m, a))
7977dd7cddfSDavid du Colombier memmove(m->devswap, a, sizeof m->devswap);
7987dd7cddfSDavid du Colombier if(needstat(init) && loadbuf(m, &m->statsfd)){
7997dd7cddfSDavid du Colombier memmove(m->prevsysstat, m->devsysstat, sizeof m->devsysstat);
8007dd7cddfSDavid du Colombier memset(m->devsysstat, 0, sizeof m->devsysstat);
8017dd7cddfSDavid du Colombier for(n=0; n<m->nproc && readnums(m, nelem(m->devsysstat), a, 0); n++)
8027dd7cddfSDavid du Colombier for(i=0; i<nelem(m->devsysstat); i++)
8037dd7cddfSDavid du Colombier m->devsysstat[i] += a[i];
8047dd7cddfSDavid du Colombier }
8057dd7cddfSDavid du Colombier if(needether(init) && loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1)){
8067dd7cddfSDavid du Colombier memmove(m->prevetherstats, m->netetherstats, sizeof m->netetherstats);
8077dd7cddfSDavid du Colombier memmove(m->netetherstats, a, sizeof m->netetherstats);
8087dd7cddfSDavid du Colombier }
8099a747e4fSDavid du Colombier if(needsignal(init) && loadbuf(m, &m->ifstatsfd) && strncmp(m->buf, "Signal: ", 8)==0 && readnums(m, nelem(m->netetherifstats), a, 1)){
8109a747e4fSDavid du Colombier memmove(m->netetherifstats, a, sizeof m->netetherifstats);
8119a747e4fSDavid du Colombier }
81280ee5cbfSDavid du Colombier if(needbattery(init) && loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0))
81380ee5cbfSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats));
8149a747e4fSDavid du Colombier if(needbattery(init) && loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0))
8159a747e4fSDavid du Colombier memmove(m->batterystats, a, sizeof(m->batterystats));
816b2495906SDavid du Colombier if(needtemp(init) && loadbuf(m, &m->tempfd))
817b2495906SDavid du Colombier for(n=0; n < nelem(m->temp) && readnums(m, 2, a, 0); n++)
818b2495906SDavid du Colombier m->temp[n] = a[0];
8197dd7cddfSDavid du Colombier if(m->remote){
8207dd7cddfSDavid du Colombier alarm(0);
8217dd7cddfSDavid du Colombier notify(nil);
8227dd7cddfSDavid du Colombier }
8237dd7cddfSDavid du Colombier }
8247dd7cddfSDavid du Colombier
8257dd7cddfSDavid du Colombier void
memval(Machine * m,uvlong * v,uvlong * vmax,int)826b2495906SDavid du Colombier memval(Machine *m, uvlong *v, uvlong *vmax, int)
8277dd7cddfSDavid du Colombier {
8287dd7cddfSDavid du Colombier *v = m->devswap[Mem];
8297dd7cddfSDavid du Colombier *vmax = m->devswap[Maxmem];
8307dd7cddfSDavid du Colombier }
8317dd7cddfSDavid du Colombier
8327dd7cddfSDavid du Colombier void
swapval(Machine * m,uvlong * v,uvlong * vmax,int)833b2495906SDavid du Colombier swapval(Machine *m, uvlong *v, uvlong *vmax, int)
8347dd7cddfSDavid du Colombier {
8357dd7cddfSDavid du Colombier *v = m->devswap[Swap];
8367dd7cddfSDavid du Colombier *vmax = m->devswap[Maxswap];
8377dd7cddfSDavid du Colombier }
8387dd7cddfSDavid du Colombier
8397dd7cddfSDavid du Colombier void
contextval(Machine * m,uvlong * v,uvlong * vmax,int init)840b2495906SDavid du Colombier contextval(Machine *m, uvlong *v, uvlong *vmax, int init)
8417dd7cddfSDavid du Colombier {
8427dd7cddfSDavid du Colombier *v = m->devsysstat[Context]-m->prevsysstat[Context];
843186fc3d1SDavid du Colombier *vmax = sleeptime*m->nproc;
84480ee5cbfSDavid du Colombier if(init)
845186fc3d1SDavid du Colombier *vmax = sleeptime;
8467dd7cddfSDavid du Colombier }
8477dd7cddfSDavid du Colombier
848b2495906SDavid du Colombier /*
849b2495906SDavid du Colombier * bug: need to factor in HZ
850b2495906SDavid du Colombier */
8517dd7cddfSDavid du Colombier void
intrval(Machine * m,uvlong * v,uvlong * vmax,int init)852b2495906SDavid du Colombier intrval(Machine *m, uvlong *v, uvlong *vmax, int init)
8537dd7cddfSDavid du Colombier {
8547dd7cddfSDavid du Colombier *v = m->devsysstat[Interrupt]-m->prevsysstat[Interrupt];
855b2495906SDavid du Colombier *vmax = sleeptime*m->nproc*10;
85680ee5cbfSDavid du Colombier if(init)
857b2495906SDavid du Colombier *vmax = sleeptime*10;
8587dd7cddfSDavid du Colombier }
8597dd7cddfSDavid du Colombier
8607dd7cddfSDavid du Colombier void
syscallval(Machine * m,uvlong * v,uvlong * vmax,int init)861b2495906SDavid du Colombier syscallval(Machine *m, uvlong *v, uvlong *vmax, int init)
8627dd7cddfSDavid du Colombier {
8637dd7cddfSDavid du Colombier *v = m->devsysstat[Syscall]-m->prevsysstat[Syscall];
864186fc3d1SDavid du Colombier *vmax = sleeptime*m->nproc;
86580ee5cbfSDavid du Colombier if(init)
866186fc3d1SDavid du Colombier *vmax = sleeptime;
8677dd7cddfSDavid du Colombier }
8687dd7cddfSDavid du Colombier
8697dd7cddfSDavid du Colombier void
faultval(Machine * m,uvlong * v,uvlong * vmax,int init)870b2495906SDavid du Colombier faultval(Machine *m, uvlong *v, uvlong *vmax, int init)
8717dd7cddfSDavid du Colombier {
8727dd7cddfSDavid du Colombier *v = m->devsysstat[Fault]-m->prevsysstat[Fault];
873186fc3d1SDavid du Colombier *vmax = sleeptime*m->nproc;
87480ee5cbfSDavid du Colombier if(init)
875186fc3d1SDavid du Colombier *vmax = sleeptime;
8767dd7cddfSDavid du Colombier }
8777dd7cddfSDavid du Colombier
8787dd7cddfSDavid du Colombier void
tlbmissval(Machine * m,uvlong * v,uvlong * vmax,int init)879b2495906SDavid du Colombier tlbmissval(Machine *m, uvlong *v, uvlong *vmax, int init)
8807dd7cddfSDavid du Colombier {
8817dd7cddfSDavid du Colombier *v = m->devsysstat[TLBfault]-m->prevsysstat[TLBfault];
882186fc3d1SDavid du Colombier *vmax = (sleeptime/1000)*10*m->nproc;
88380ee5cbfSDavid du Colombier if(init)
884186fc3d1SDavid du Colombier *vmax = (sleeptime/1000)*10;
885*fee9fd16SDavid du Colombier if (mycputype && strcmp(mycputype, "mips") == 0)
886*fee9fd16SDavid du Colombier *vmax *= 50000; /* mainly for 16-entry tlbs (rb) */
8877dd7cddfSDavid du Colombier }
8887dd7cddfSDavid du Colombier
8897dd7cddfSDavid du Colombier void
tlbpurgeval(Machine * m,uvlong * v,uvlong * vmax,int init)890b2495906SDavid du Colombier tlbpurgeval(Machine *m, uvlong *v, uvlong *vmax, int init)
8917dd7cddfSDavid du Colombier {
8927dd7cddfSDavid du Colombier *v = m->devsysstat[TLBpurge]-m->prevsysstat[TLBpurge];
893186fc3d1SDavid du Colombier *vmax = (sleeptime/1000)*10*m->nproc;
89480ee5cbfSDavid du Colombier if(init)
895186fc3d1SDavid du Colombier *vmax = (sleeptime/1000)*10;
8967dd7cddfSDavid du Colombier }
8977dd7cddfSDavid du Colombier
8987dd7cddfSDavid du Colombier void
loadval(Machine * m,uvlong * v,uvlong * vmax,int init)899b2495906SDavid du Colombier loadval(Machine *m, uvlong *v, uvlong *vmax, int init)
9007dd7cddfSDavid du Colombier {
9017dd7cddfSDavid du Colombier *v = m->devsysstat[Load];
9027dd7cddfSDavid du Colombier *vmax = 1000*m->nproc;
90380ee5cbfSDavid du Colombier if(init)
90480ee5cbfSDavid du Colombier *vmax = 1000;
9057dd7cddfSDavid du Colombier }
9067dd7cddfSDavid du Colombier
9077dd7cddfSDavid du Colombier void
idleval(Machine * m,uvlong * v,uvlong * vmax,int)908b2495906SDavid du Colombier idleval(Machine *m, uvlong *v, uvlong *vmax, int)
909dc5a79c1SDavid du Colombier {
910f86ef3ceSDavid du Colombier *v = m->devsysstat[Idle]/m->nproc;
911dc5a79c1SDavid du Colombier *vmax = 100;
912dc5a79c1SDavid du Colombier }
913dc5a79c1SDavid du Colombier
914dc5a79c1SDavid du Colombier void
inintrval(Machine * m,uvlong * v,uvlong * vmax,int)915b2495906SDavid du Colombier inintrval(Machine *m, uvlong *v, uvlong *vmax, int)
916f86ef3ceSDavid du Colombier {
917f86ef3ceSDavid du Colombier *v = m->devsysstat[InIntr]/m->nproc;
918f86ef3ceSDavid du Colombier *vmax = 100;
919f86ef3ceSDavid du Colombier }
920f86ef3ceSDavid du Colombier
921f86ef3ceSDavid du Colombier void
etherval(Machine * m,uvlong * v,uvlong * vmax,int init)922b2495906SDavid du Colombier etherval(Machine *m, uvlong *v, uvlong *vmax, int init)
9237dd7cddfSDavid du Colombier {
9247dd7cddfSDavid du Colombier *v = m->netetherstats[In]-m->prevetherstats[In] + m->netetherstats[Out]-m->prevetherstats[Out];
925186fc3d1SDavid du Colombier *vmax = sleeptime*m->nproc;
92680ee5cbfSDavid du Colombier if(init)
927186fc3d1SDavid du Colombier *vmax = sleeptime;
9287dd7cddfSDavid du Colombier }
9297dd7cddfSDavid du Colombier
9307dd7cddfSDavid du Colombier void
etherinval(Machine * m,uvlong * v,uvlong * vmax,int init)931b2495906SDavid du Colombier etherinval(Machine *m, uvlong *v, uvlong *vmax, int init)
9327dd7cddfSDavid du Colombier {
9337dd7cddfSDavid du Colombier *v = m->netetherstats[In]-m->prevetherstats[In];
934186fc3d1SDavid du Colombier *vmax = sleeptime*m->nproc;
93580ee5cbfSDavid du Colombier if(init)
936186fc3d1SDavid du Colombier *vmax = sleeptime;
9377dd7cddfSDavid du Colombier }
9387dd7cddfSDavid du Colombier
9397dd7cddfSDavid du Colombier void
etheroutval(Machine * m,uvlong * v,uvlong * vmax,int init)940b2495906SDavid du Colombier etheroutval(Machine *m, uvlong *v, uvlong *vmax, int init)
9417dd7cddfSDavid du Colombier {
9427dd7cddfSDavid du Colombier *v = m->netetherstats[Out]-m->prevetherstats[Out];
943186fc3d1SDavid du Colombier *vmax = sleeptime*m->nproc;
94480ee5cbfSDavid du Colombier if(init)
945186fc3d1SDavid du Colombier *vmax = sleeptime;
9467dd7cddfSDavid du Colombier }
9477dd7cddfSDavid du Colombier
9487dd7cddfSDavid du Colombier void
ethererrval(Machine * m,uvlong * v,uvlong * vmax,int init)949b2495906SDavid du Colombier ethererrval(Machine *m, uvlong *v, uvlong *vmax, int init)
9507dd7cddfSDavid du Colombier {
9517dd7cddfSDavid du Colombier int i;
9527dd7cddfSDavid du Colombier
9537dd7cddfSDavid du Colombier *v = 0;
9547dd7cddfSDavid du Colombier for(i=Err0; i<nelem(m->netetherstats); i++)
9557dd7cddfSDavid du Colombier *v += m->netetherstats[i];
956186fc3d1SDavid du Colombier *vmax = (sleeptime/1000)*10*m->nproc;
95780ee5cbfSDavid du Colombier if(init)
958186fc3d1SDavid du Colombier *vmax = (sleeptime/1000)*10;
95980ee5cbfSDavid du Colombier }
96080ee5cbfSDavid du Colombier
96180ee5cbfSDavid du Colombier void
batteryval(Machine * m,uvlong * v,uvlong * vmax,int)962b2495906SDavid du Colombier batteryval(Machine *m, uvlong *v, uvlong *vmax, int)
96380ee5cbfSDavid du Colombier {
96480ee5cbfSDavid du Colombier *v = m->batterystats[0];
9659a747e4fSDavid du Colombier if(m->bitsybatfd >= 0)
9669a747e4fSDavid du Colombier *vmax = 184; // at least on my bitsy...
9679a747e4fSDavid du Colombier else
96880ee5cbfSDavid du Colombier *vmax = 100;
9697dd7cddfSDavid du Colombier }
9707dd7cddfSDavid du Colombier
9717dd7cddfSDavid du Colombier void
signalval(Machine * m,uvlong * v,uvlong * vmax,int)972b2495906SDavid du Colombier signalval(Machine *m, uvlong *v, uvlong *vmax, int)
9739a747e4fSDavid du Colombier {
974f86ef3ceSDavid du Colombier ulong l;
9759a747e4fSDavid du Colombier
976186fc3d1SDavid du Colombier *vmax = sleeptime;
9779a747e4fSDavid du Colombier l = m->netetherifstats[0];
9789a747e4fSDavid du Colombier /*
9799a747e4fSDavid du Colombier * Range is seen to be from about -45 (strong) to -95 (weak); rescale
9809a747e4fSDavid du Colombier */
9819a747e4fSDavid du Colombier if(l == 0){ /* probably not present */
9829a747e4fSDavid du Colombier *v = 0;
9839a747e4fSDavid du Colombier return;
9849a747e4fSDavid du Colombier }
9859a747e4fSDavid du Colombier *v = 20*(l+95);
9869a747e4fSDavid du Colombier }
9879a747e4fSDavid du Colombier
9889a747e4fSDavid du Colombier void
tempval(Machine * m,uvlong * v,uvlong * vmax,int)989b2495906SDavid du Colombier tempval(Machine *m, uvlong *v, uvlong *vmax, int)
990b2495906SDavid du Colombier {
991b2495906SDavid du Colombier ulong l;
992b2495906SDavid du Colombier
993b2495906SDavid du Colombier *vmax = sleeptime;
994b2495906SDavid du Colombier l = m->temp[0];
995b2495906SDavid du Colombier if(l == ~0 || l == 0)
996b2495906SDavid du Colombier *v = 0;
997b2495906SDavid du Colombier else
998b2495906SDavid du Colombier *v = (l-20)*27;
999b2495906SDavid du Colombier }
1000b2495906SDavid du Colombier
1001b2495906SDavid du Colombier void
usage(void)10027dd7cddfSDavid du Colombier usage(void)
10037dd7cddfSDavid du Colombier {
10049a747e4fSDavid du Colombier fprint(2, "usage: stats [-O] [-S scale] [-LY] [-%s] [machine...]\n", argchars);
10057dd7cddfSDavid du Colombier exits("usage");
10067dd7cddfSDavid du Colombier }
10077dd7cddfSDavid du Colombier
10087dd7cddfSDavid du Colombier void
addgraph(int n)10097dd7cddfSDavid du Colombier addgraph(int n)
10107dd7cddfSDavid du Colombier {
10117dd7cddfSDavid du Colombier Graph *g, *ograph;
10127dd7cddfSDavid du Colombier int i, j;
10137dd7cddfSDavid du Colombier static int nadd;
10147dd7cddfSDavid du Colombier
10157dd7cddfSDavid du Colombier if(n > nelem(menu2str))
10167dd7cddfSDavid du Colombier abort();
10177dd7cddfSDavid du Colombier /* avoid two adjacent graphs of same color */
10187dd7cddfSDavid du Colombier if(ngraph>0 && graph[ngraph-1].colindex==nadd%Ncolor)
10197dd7cddfSDavid du Colombier nadd++;
10207dd7cddfSDavid du Colombier ograph = graph;
10217dd7cddfSDavid du Colombier graph = emalloc(nmach*(ngraph+1)*sizeof(Graph));
10227dd7cddfSDavid du Colombier for(i=0; i<nmach; i++)
10237dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++)
10247dd7cddfSDavid du Colombier graph[i*(ngraph+1)+j] = ograph[i*ngraph+j];
10257dd7cddfSDavid du Colombier free(ograph);
10267dd7cddfSDavid du Colombier ngraph++;
10277dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){
10287dd7cddfSDavid du Colombier g = &graph[i*ngraph+(ngraph-1)];
10297dd7cddfSDavid du Colombier memset(g, 0, sizeof(Graph));
10307dd7cddfSDavid du Colombier g->label = menu2str[n]+Opwid;
10317dd7cddfSDavid du Colombier g->newvalue = newvaluefn[n];
10327dd7cddfSDavid du Colombier g->update = update1; /* no other update functions yet */
10337dd7cddfSDavid du Colombier g->mach = &mach[i];
10347dd7cddfSDavid du Colombier g->colindex = nadd%Ncolor;
10357dd7cddfSDavid du Colombier }
10367dd7cddfSDavid du Colombier present[n] = 1;
10377dd7cddfSDavid du Colombier nadd++;
10387dd7cddfSDavid du Colombier }
10397dd7cddfSDavid du Colombier
10407dd7cddfSDavid du Colombier void
dropgraph(int which)10417dd7cddfSDavid du Colombier dropgraph(int which)
10427dd7cddfSDavid du Colombier {
10437dd7cddfSDavid du Colombier Graph *ograph;
10447dd7cddfSDavid du Colombier int i, j, n;
10457dd7cddfSDavid du Colombier
10467dd7cddfSDavid du Colombier if(which > nelem(menu2str))
10477dd7cddfSDavid du Colombier abort();
10487dd7cddfSDavid du Colombier /* convert n to index in graph table */
10497dd7cddfSDavid du Colombier n = -1;
10507dd7cddfSDavid du Colombier for(i=0; i<ngraph; i++)
10517dd7cddfSDavid du Colombier if(strcmp(menu2str[which]+Opwid, graph[i].label) == 0){
10527dd7cddfSDavid du Colombier n = i;
10537dd7cddfSDavid du Colombier break;
10547dd7cddfSDavid du Colombier }
10557dd7cddfSDavid du Colombier if(n < 0){
10567dd7cddfSDavid du Colombier fprint(2, "stats: internal error can't drop graph\n");
10577dd7cddfSDavid du Colombier killall("error");
10587dd7cddfSDavid du Colombier }
10597dd7cddfSDavid du Colombier ograph = graph;
10607dd7cddfSDavid du Colombier graph = emalloc(nmach*(ngraph-1)*sizeof(Graph));
10617dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){
10627dd7cddfSDavid du Colombier for(j=0; j<n; j++)
10637dd7cddfSDavid du Colombier graph[i*(ngraph-1)+j] = ograph[i*ngraph+j];
10647dd7cddfSDavid du Colombier free(ograph[i*ngraph+j].data);
10657dd7cddfSDavid du Colombier freeimage(ograph[i*ngraph+j].overtmp);
10667dd7cddfSDavid du Colombier for(j++; j<ngraph; j++)
10677dd7cddfSDavid du Colombier graph[i*(ngraph-1)+j-1] = ograph[i*ngraph+j];
10687dd7cddfSDavid du Colombier }
10697dd7cddfSDavid du Colombier free(ograph);
10707dd7cddfSDavid du Colombier ngraph--;
10717dd7cddfSDavid du Colombier present[which] = 0;
10727dd7cddfSDavid du Colombier }
10737dd7cddfSDavid du Colombier
10748c1c8807SDavid du Colombier int
addmachine(char * name)10757dd7cddfSDavid du Colombier addmachine(char *name)
10767dd7cddfSDavid du Colombier {
10777dd7cddfSDavid du Colombier if(ngraph > 0){
10787dd7cddfSDavid du Colombier fprint(2, "stats: internal error: ngraph>0 in addmachine()\n");
10797dd7cddfSDavid du Colombier usage();
10807dd7cddfSDavid du Colombier }
10817dd7cddfSDavid du Colombier if(mach == nil)
10827dd7cddfSDavid du Colombier nmach = 0; /* a little dance to get us started with local machine by default */
10837dd7cddfSDavid du Colombier mach = erealloc(mach, (nmach+1)*sizeof(Machine));
10847dd7cddfSDavid du Colombier memset(mach+nmach, 0, sizeof(Machine));
10858c1c8807SDavid du Colombier if (initmach(mach+nmach, name)){
10867dd7cddfSDavid du Colombier nmach++;
10878c1c8807SDavid du Colombier return 1;
10888c1c8807SDavid du Colombier } else
10898c1c8807SDavid du Colombier return 0;
10907dd7cddfSDavid du Colombier }
10917dd7cddfSDavid du Colombier
10927dd7cddfSDavid du Colombier void
labelstrs(Graph * g,char strs[Nlab][Lablen],int * np)109380ee5cbfSDavid du Colombier labelstrs(Graph *g, char strs[Nlab][Lablen], int *np)
109480ee5cbfSDavid du Colombier {
109580ee5cbfSDavid du Colombier int j;
1096b2495906SDavid du Colombier uvlong v, vmax;
109780ee5cbfSDavid du Colombier
109880ee5cbfSDavid du Colombier g->newvalue(g->mach, &v, &vmax, 1);
109980ee5cbfSDavid du Colombier if(logscale){
110080ee5cbfSDavid du Colombier for(j=1; j<=2; j++)
110180ee5cbfSDavid du Colombier sprint(strs[j-1], "%g", scale*pow(10., j)*(double)vmax/100.);
110280ee5cbfSDavid du Colombier *np = 2;
110380ee5cbfSDavid du Colombier }else{
110480ee5cbfSDavid du Colombier for(j=1; j<=3; j++)
110580ee5cbfSDavid du Colombier sprint(strs[j-1], "%g", scale*(double)j*(double)vmax/4.0);
110680ee5cbfSDavid du Colombier *np = 3;
110780ee5cbfSDavid du Colombier }
110880ee5cbfSDavid du Colombier }
110980ee5cbfSDavid du Colombier
111080ee5cbfSDavid du Colombier int
labelwidth(void)111180ee5cbfSDavid du Colombier labelwidth(void)
111280ee5cbfSDavid du Colombier {
111380ee5cbfSDavid du Colombier int i, j, n, w, maxw;
111480ee5cbfSDavid du Colombier char strs[Nlab][Lablen];
111580ee5cbfSDavid du Colombier
111680ee5cbfSDavid du Colombier maxw = 0;
111780ee5cbfSDavid du Colombier for(i=0; i<ngraph; i++){
111880ee5cbfSDavid du Colombier /* choose value for rightmost graph */
111980ee5cbfSDavid du Colombier labelstrs(&graph[ngraph*(nmach-1)+i], strs, &n);
112080ee5cbfSDavid du Colombier for(j=0; j<n; j++){
112180ee5cbfSDavid du Colombier w = stringwidth(mediumfont, strs[j]);
112280ee5cbfSDavid du Colombier if(w > maxw)
112380ee5cbfSDavid du Colombier maxw = w;
112480ee5cbfSDavid du Colombier }
112580ee5cbfSDavid du Colombier }
112680ee5cbfSDavid du Colombier return maxw;
112780ee5cbfSDavid du Colombier }
112880ee5cbfSDavid du Colombier
112980ee5cbfSDavid du Colombier void
resize(void)11307dd7cddfSDavid du Colombier resize(void)
11317dd7cddfSDavid du Colombier {
113280ee5cbfSDavid du Colombier int i, j, k, n, startx, starty, x, y, dx, dy, ly, ondata, maxx, wid, nlab;
11337dd7cddfSDavid du Colombier Graph *g;
11347dd7cddfSDavid du Colombier Rectangle machr, r;
1135b2495906SDavid du Colombier uvlong v, vmax;
113680ee5cbfSDavid du Colombier char buf[128], labs[Nlab][Lablen];
11377dd7cddfSDavid du Colombier
11387dd7cddfSDavid du Colombier draw(screen, screen->r, display->white, nil, ZP);
11397dd7cddfSDavid du Colombier
11407dd7cddfSDavid du Colombier /* label left edge */
11417dd7cddfSDavid du Colombier x = screen->r.min.x;
11427dd7cddfSDavid du Colombier y = screen->r.min.y + Labspace+mediumfont->height+Labspace;
11437dd7cddfSDavid du Colombier dy = (screen->r.max.y - y)/ngraph;
11447dd7cddfSDavid du Colombier dx = Labspace+stringwidth(mediumfont, "0")+Labspace;
11457dd7cddfSDavid du Colombier startx = x+dx+1;
11467dd7cddfSDavid du Colombier starty = y;
11477dd7cddfSDavid du Colombier for(i=0; i<ngraph; i++,y+=dy){
11487dd7cddfSDavid du Colombier draw(screen, Rect(x, y-1, screen->r.max.x, y), display->black, nil, ZP);
11497dd7cddfSDavid du Colombier draw(screen, Rect(x, y, x+dx, screen->r.max.y), cols[graph[i].colindex][0], nil, paritypt(x));
11507dd7cddfSDavid du Colombier label(Pt(x, y), dy, graph[i].label);
11517dd7cddfSDavid du Colombier draw(screen, Rect(x+dx, y, x+dx+1, screen->r.max.y), cols[graph[i].colindex][2], nil, ZP);
11527dd7cddfSDavid du Colombier }
11537dd7cddfSDavid du Colombier
11547dd7cddfSDavid du Colombier /* label top edge */
11557dd7cddfSDavid du Colombier dx = (screen->r.max.x - startx)/nmach;
11567dd7cddfSDavid du Colombier for(x=startx, i=0; i<nmach; i++,x+=dx){
11577dd7cddfSDavid du Colombier draw(screen, Rect(x-1, starty-1, x, screen->r.max.y), display->black, nil, ZP);
11587dd7cddfSDavid du Colombier j = dx/stringwidth(mediumfont, "0");
11597dd7cddfSDavid du Colombier n = mach[i].nproc;
1160eebedd9aSDavid du Colombier if(n>1 && j>=1+3+mach[i].lgproc){ /* first char of name + (n) */
1161eebedd9aSDavid du Colombier j -= 3+mach[i].lgproc;
11627dd7cddfSDavid du Colombier if(j <= 0)
11637dd7cddfSDavid du Colombier j = 1;
1164eebedd9aSDavid du Colombier snprint(buf, sizeof buf, "%.*s(%d)", j, mach[i].shortname, n);
11657dd7cddfSDavid du Colombier }else
1166eebedd9aSDavid du Colombier snprint(buf, sizeof buf, "%.*s", j, mach[i].shortname);
11677dd7cddfSDavid du Colombier string(screen, Pt(x+Labspace, screen->r.min.y + Labspace), display->black, ZP, mediumfont, buf);
11687dd7cddfSDavid du Colombier }
11697dd7cddfSDavid du Colombier
117080ee5cbfSDavid du Colombier maxx = screen->r.max.x;
117180ee5cbfSDavid du Colombier
117280ee5cbfSDavid du Colombier /* label right, if requested */
117380ee5cbfSDavid du Colombier if(ylabels && dy>Nlab*(mediumfont->height+1)){
117480ee5cbfSDavid du Colombier wid = labelwidth();
117580ee5cbfSDavid du Colombier if(wid < (maxx-startx)-30){
117680ee5cbfSDavid du Colombier /* else there's not enough room */
117780ee5cbfSDavid du Colombier maxx -= 1+Lx+wid;
117880ee5cbfSDavid du Colombier draw(screen, Rect(maxx, starty, maxx+1, screen->r.max.y), display->black, nil, ZP);
117980ee5cbfSDavid du Colombier y = starty;
118080ee5cbfSDavid du Colombier for(j=0; j<ngraph; j++, y+=dy){
118180ee5cbfSDavid du Colombier /* choose value for rightmost graph */
118280ee5cbfSDavid du Colombier g = &graph[ngraph*(nmach-1)+j];
118380ee5cbfSDavid du Colombier labelstrs(g, labs, &nlab);
118480ee5cbfSDavid du Colombier r = Rect(maxx+1, y, screen->r.max.x, y+dy-1);
118580ee5cbfSDavid du Colombier if(j == ngraph-1)
118680ee5cbfSDavid du Colombier r.max.y = screen->r.max.y;
118780ee5cbfSDavid du Colombier draw(screen, r, cols[g->colindex][0], nil, paritypt(r.min.x));
118880ee5cbfSDavid du Colombier for(k=0; k<nlab; k++){
118980ee5cbfSDavid du Colombier ly = y + (dy*(nlab-k)/(nlab+1));
119080ee5cbfSDavid du Colombier draw(screen, Rect(maxx+1, ly, maxx+1+Lx, ly+1), display->black, nil, ZP);
119180ee5cbfSDavid du Colombier ly -= mediumfont->height/2;
119280ee5cbfSDavid du Colombier string(screen, Pt(maxx+1+Lx, ly), display->black, ZP, mediumfont, labs[k]);
119380ee5cbfSDavid du Colombier }
119480ee5cbfSDavid du Colombier }
119580ee5cbfSDavid du Colombier }
119680ee5cbfSDavid du Colombier }
119780ee5cbfSDavid du Colombier
11987dd7cddfSDavid du Colombier /* create graphs */
11997dd7cddfSDavid du Colombier for(i=0; i<nmach; i++){
120080ee5cbfSDavid du Colombier machr = Rect(startx+i*dx, starty, maxx, screen->r.max.y);
12017dd7cddfSDavid du Colombier if(i < nmach-1)
12027dd7cddfSDavid du Colombier machr.max.x = startx+(i+1)*dx - 1;
12037dd7cddfSDavid du Colombier y = starty;
12047dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++, y+=dy){
12057dd7cddfSDavid du Colombier g = &graph[i*ngraph+j];
12067dd7cddfSDavid du Colombier /* allocate data */
12077dd7cddfSDavid du Colombier ondata = g->ndata;
12087dd7cddfSDavid du Colombier g->ndata = Dx(machr)+1; /* may be too many if label will be drawn here; so what? */
1209853458f3SDavid du Colombier g->data = erealloc(g->data, g->ndata*sizeof(g->data[0]));
12107dd7cddfSDavid du Colombier if(g->ndata > ondata)
1211853458f3SDavid du Colombier memset(g->data+ondata, 0, (g->ndata-ondata)*sizeof(g->data[0]));
12127dd7cddfSDavid du Colombier /* set geometry */
12137dd7cddfSDavid du Colombier g->r = machr;
12147dd7cddfSDavid du Colombier g->r.min.y = y;
12157dd7cddfSDavid du Colombier g->r.max.y = y+dy - 1;
12167dd7cddfSDavid du Colombier if(j == ngraph-1)
12177dd7cddfSDavid du Colombier g->r.max.y = screen->r.max.y;
12187dd7cddfSDavid du Colombier draw(screen, g->r, cols[g->colindex][0], nil, paritypt(g->r.min.x));
12197dd7cddfSDavid du Colombier g->overflow = 0;
12207dd7cddfSDavid du Colombier r = g->r;
12217dd7cddfSDavid du Colombier r.max.y = r.min.y+mediumfont->height;
122231a0f4b7SDavid du Colombier r.max.x = r.min.x+stringwidth(mediumfont, "999999999999");
12237dd7cddfSDavid du Colombier freeimage(g->overtmp);
12247dd7cddfSDavid du Colombier g->overtmp = nil;
12257dd7cddfSDavid du Colombier if(r.max.x <= g->r.max.x)
12267dd7cddfSDavid du Colombier g->overtmp = allocimage(display, r, screen->chan, 0, -1);
122780ee5cbfSDavid du Colombier g->newvalue(g->mach, &v, &vmax, 0);
12287dd7cddfSDavid du Colombier redraw(g, vmax);
12297dd7cddfSDavid du Colombier }
12307dd7cddfSDavid du Colombier }
12317dd7cddfSDavid du Colombier
12327dd7cddfSDavid du Colombier flushimage(display, 1);
12337dd7cddfSDavid du Colombier }
12347dd7cddfSDavid du Colombier
12357dd7cddfSDavid du Colombier void
eresized(int new)12367dd7cddfSDavid du Colombier eresized(int new)
12377dd7cddfSDavid du Colombier {
12387dd7cddfSDavid du Colombier lockdisplay(display);
12397dd7cddfSDavid du Colombier if(new && getwindow(display, Refnone) < 0) {
12407dd7cddfSDavid du Colombier fprint(2, "stats: can't reattach to window\n");
12417dd7cddfSDavid du Colombier killall("reattach");
12427dd7cddfSDavid du Colombier }
12437dd7cddfSDavid du Colombier resize();
12447dd7cddfSDavid du Colombier unlockdisplay(display);
12457dd7cddfSDavid du Colombier }
12467dd7cddfSDavid du Colombier
12477dd7cddfSDavid du Colombier void
mouseproc(void)12487dd7cddfSDavid du Colombier mouseproc(void)
12497dd7cddfSDavid du Colombier {
12507dd7cddfSDavid du Colombier Mouse mouse;
12517dd7cddfSDavid du Colombier int i;
12527dd7cddfSDavid du Colombier
12537dd7cddfSDavid du Colombier for(;;){
12547dd7cddfSDavid du Colombier mouse = emouse();
12557dd7cddfSDavid du Colombier if(mouse.buttons == 4){
12567dd7cddfSDavid du Colombier lockdisplay(display);
12577dd7cddfSDavid du Colombier for(i=0; i<Nmenu2; i++)
12587dd7cddfSDavid du Colombier if(present[i])
12597dd7cddfSDavid du Colombier memmove(menu2str[i], "drop ", Opwid);
12607dd7cddfSDavid du Colombier else
12617dd7cddfSDavid du Colombier memmove(menu2str[i], "add ", Opwid);
12627dd7cddfSDavid du Colombier i = emenuhit(3, &mouse, &menu2);
12637dd7cddfSDavid du Colombier if(i >= 0){
12647dd7cddfSDavid du Colombier if(!present[i])
12657dd7cddfSDavid du Colombier addgraph(i);
12667dd7cddfSDavid du Colombier else if(ngraph > 1)
12677dd7cddfSDavid du Colombier dropgraph(i);
12687dd7cddfSDavid du Colombier resize();
12697dd7cddfSDavid du Colombier }
12707dd7cddfSDavid du Colombier unlockdisplay(display);
12717dd7cddfSDavid du Colombier }
12727dd7cddfSDavid du Colombier }
12737dd7cddfSDavid du Colombier }
12747dd7cddfSDavid du Colombier
12757dd7cddfSDavid du Colombier void
startproc(void (* f)(void),int index)12767dd7cddfSDavid du Colombier startproc(void (*f)(void), int index)
12777dd7cddfSDavid du Colombier {
12787dd7cddfSDavid du Colombier int pid;
12797dd7cddfSDavid du Colombier
12807dd7cddfSDavid du Colombier switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT)){
12817dd7cddfSDavid du Colombier case -1:
12827dd7cddfSDavid du Colombier fprint(2, "stats: fork failed: %r\n");
12837dd7cddfSDavid du Colombier killall("fork failed");
12847dd7cddfSDavid du Colombier case 0:
12857dd7cddfSDavid du Colombier f();
12867dd7cddfSDavid du Colombier fprint(2, "stats: %s process exits\n", procnames[index]);
12877dd7cddfSDavid du Colombier if(index >= 0)
12887dd7cddfSDavid du Colombier killall("process died");
12897dd7cddfSDavid du Colombier exits(nil);
12907dd7cddfSDavid du Colombier }
12917dd7cddfSDavid du Colombier if(index >= 0)
12927dd7cddfSDavid du Colombier pids[index] = pid;
12937dd7cddfSDavid du Colombier }
12947dd7cddfSDavid du Colombier
12957dd7cddfSDavid du Colombier void
main(int argc,char * argv[])12967dd7cddfSDavid du Colombier main(int argc, char *argv[])
12977dd7cddfSDavid du Colombier {
12987dd7cddfSDavid du Colombier int i, j;
1299de8abbc9SDavid du Colombier double secs;
1300b2495906SDavid du Colombier uvlong v, vmax, nargs;
13017dd7cddfSDavid du Colombier char args[100];
13027dd7cddfSDavid du Colombier
13037dd7cddfSDavid du Colombier nmach = 1;
13047dd7cddfSDavid du Colombier mysysname = getenv("sysname");
13057dd7cddfSDavid du Colombier if(mysysname == nil){
13067dd7cddfSDavid du Colombier fprint(2, "stats: can't find $sysname: %r\n");
13077dd7cddfSDavid du Colombier exits("sysname");
13087dd7cddfSDavid du Colombier }
13097dd7cddfSDavid du Colombier mysysname = estrdup(mysysname);
1310*fee9fd16SDavid du Colombier mycputype = getenv("cputype");
13117dd7cddfSDavid du Colombier
13127dd7cddfSDavid du Colombier nargs = 0;
13137dd7cddfSDavid du Colombier ARGBEGIN{
13143f695129SDavid du Colombier case 'T':
1315de8abbc9SDavid du Colombier secs = atof(EARGF(usage()));
1316de8abbc9SDavid du Colombier if(secs > 0)
1317de8abbc9SDavid du Colombier sleeptime = 1000*secs;
13183f695129SDavid du Colombier break;
131980ee5cbfSDavid du Colombier case 'S':
1320de8abbc9SDavid du Colombier scale = atof(EARGF(usage()));
1321de8abbc9SDavid du Colombier if(scale <= 0)
132280ee5cbfSDavid du Colombier usage();
132380ee5cbfSDavid du Colombier break;
132480ee5cbfSDavid du Colombier case 'L':
132580ee5cbfSDavid du Colombier logscale++;
132680ee5cbfSDavid du Colombier break;
132780ee5cbfSDavid du Colombier case 'Y':
132880ee5cbfSDavid du Colombier ylabels++;
132980ee5cbfSDavid du Colombier break;
13309a747e4fSDavid du Colombier case 'O':
13319a747e4fSDavid du Colombier oldsystem = 1;
13329a747e4fSDavid du Colombier break;
13337dd7cddfSDavid du Colombier default:
13347dd7cddfSDavid du Colombier if(nargs>=sizeof args || strchr(argchars, ARGC())==nil)
13357dd7cddfSDavid du Colombier usage();
13367dd7cddfSDavid du Colombier args[nargs++] = ARGC();
13377dd7cddfSDavid du Colombier }ARGEND
13387dd7cddfSDavid du Colombier
13397dd7cddfSDavid du Colombier if(argc == 0){
13407dd7cddfSDavid du Colombier mach = emalloc(nmach*sizeof(Machine));
13417dd7cddfSDavid du Colombier initmach(&mach[0], mysysname);
13427dd7cddfSDavid du Colombier readmach(&mach[0], 1);
13437dd7cddfSDavid du Colombier }else{
13448c1c8807SDavid du Colombier for(i=j=0; i<argc; i++){
13458c1c8807SDavid du Colombier if (addmachine(argv[i]))
13468c1c8807SDavid du Colombier readmach(&mach[j++], 1);
13477dd7cddfSDavid du Colombier }
1348a8453668SDavid du Colombier if (j == 0)
1349a8453668SDavid du Colombier exits("connect");
13507dd7cddfSDavid du Colombier }
13517dd7cddfSDavid du Colombier
13527dd7cddfSDavid du Colombier for(i=0; i<nargs; i++)
13537dd7cddfSDavid du Colombier switch(args[i]){
13547dd7cddfSDavid du Colombier default:
13557dd7cddfSDavid du Colombier fprint(2, "stats: internal error: unknown arg %c\n", args[i]);
13567dd7cddfSDavid du Colombier usage();
135780ee5cbfSDavid du Colombier case 'b':
135880ee5cbfSDavid du Colombier addgraph(Mbattery);
135980ee5cbfSDavid du Colombier break;
13607dd7cddfSDavid du Colombier case 'c':
13617dd7cddfSDavid du Colombier addgraph(Mcontext);
13627dd7cddfSDavid du Colombier break;
13637dd7cddfSDavid du Colombier case 'e':
13647dd7cddfSDavid du Colombier addgraph(Mether);
13657dd7cddfSDavid du Colombier break;
13667dd7cddfSDavid du Colombier case 'E':
13677dd7cddfSDavid du Colombier addgraph(Metherin);
13687dd7cddfSDavid du Colombier addgraph(Metherout);
13697dd7cddfSDavid du Colombier break;
13707dd7cddfSDavid du Colombier case 'f':
13717dd7cddfSDavid du Colombier addgraph(Mfault);
13727dd7cddfSDavid du Colombier break;
13737dd7cddfSDavid du Colombier case 'i':
13747dd7cddfSDavid du Colombier addgraph(Mintr);
13757dd7cddfSDavid du Colombier break;
1376f86ef3ceSDavid du Colombier case 'I':
1377f86ef3ceSDavid du Colombier addgraph(Mload);
1378f86ef3ceSDavid du Colombier addgraph(Midle);
1379f86ef3ceSDavid du Colombier addgraph(Minintr);
1380f86ef3ceSDavid du Colombier break;
13817dd7cddfSDavid du Colombier case 'l':
13827dd7cddfSDavid du Colombier addgraph(Mload);
13837dd7cddfSDavid du Colombier break;
13847dd7cddfSDavid du Colombier case 'm':
13857dd7cddfSDavid du Colombier addgraph(Mmem);
13867dd7cddfSDavid du Colombier break;
13877dd7cddfSDavid du Colombier case 'n':
13887dd7cddfSDavid du Colombier addgraph(Metherin);
13897dd7cddfSDavid du Colombier addgraph(Metherout);
13907dd7cddfSDavid du Colombier addgraph(Methererr);
13917dd7cddfSDavid du Colombier break;
13927dd7cddfSDavid du Colombier case 'p':
13937dd7cddfSDavid du Colombier addgraph(Mtlbpurge);
13947dd7cddfSDavid du Colombier break;
13957dd7cddfSDavid du Colombier case 's':
13967dd7cddfSDavid du Colombier addgraph(Msyscall);
13977dd7cddfSDavid du Colombier break;
13987dd7cddfSDavid du Colombier case 't':
13997dd7cddfSDavid du Colombier addgraph(Mtlbmiss);
14007dd7cddfSDavid du Colombier addgraph(Mtlbpurge);
14017dd7cddfSDavid du Colombier break;
14029a747e4fSDavid du Colombier case '8':
14039a747e4fSDavid du Colombier addgraph(Msignal);
14049a747e4fSDavid du Colombier break;
14057dd7cddfSDavid du Colombier case 'w':
14067dd7cddfSDavid du Colombier addgraph(Mswap);
14077dd7cddfSDavid du Colombier break;
1408b2495906SDavid du Colombier case 'z':
1409b2495906SDavid du Colombier addgraph(Mtemp);
1410b2495906SDavid du Colombier break;
14117dd7cddfSDavid du Colombier }
14127dd7cddfSDavid du Colombier
14137dd7cddfSDavid du Colombier if(ngraph == 0)
14147dd7cddfSDavid du Colombier addgraph(Mload);
14157dd7cddfSDavid du Colombier
14167dd7cddfSDavid du Colombier for(i=0; i<nmach; i++)
14177dd7cddfSDavid du Colombier for(j=0; j<ngraph; j++)
14187dd7cddfSDavid du Colombier graph[i*ngraph+j].mach = &mach[i];
14197dd7cddfSDavid du Colombier
14207dd7cddfSDavid du Colombier if(initdraw(nil, nil, "stats") < 0){
14217dd7cddfSDavid du Colombier fprint(2, "stats: initdraw failed: %r\n");
14227dd7cddfSDavid du Colombier exits("initdraw");
14237dd7cddfSDavid du Colombier }
14247dd7cddfSDavid du Colombier colinit();
14257dd7cddfSDavid du Colombier einit(Emouse);
14267dd7cddfSDavid du Colombier notify(nil);
14277dd7cddfSDavid du Colombier startproc(mouseproc, Mouseproc);
14287dd7cddfSDavid du Colombier pids[Mainproc] = getpid();
14297dd7cddfSDavid du Colombier display->locking = 1; /* tell library we're using the display lock */
14307dd7cddfSDavid du Colombier
14317dd7cddfSDavid du Colombier resize();
14327dd7cddfSDavid du Colombier
14337dd7cddfSDavid du Colombier unlockdisplay(display); /* display is still locked from initdraw() */
14347dd7cddfSDavid du Colombier for(;;){
14357dd7cddfSDavid du Colombier for(i=0; i<nmach; i++)
14367dd7cddfSDavid du Colombier readmach(&mach[i], 0);
14377dd7cddfSDavid du Colombier lockdisplay(display);
14387dd7cddfSDavid du Colombier parity = 1-parity;
14397dd7cddfSDavid du Colombier for(i=0; i<nmach*ngraph; i++){
144080ee5cbfSDavid du Colombier graph[i].newvalue(graph[i].mach, &v, &vmax, 0);
14417dd7cddfSDavid du Colombier graph[i].update(&graph[i], v, vmax);
14427dd7cddfSDavid du Colombier }
14437dd7cddfSDavid du Colombier flushimage(display, 1);
14447dd7cddfSDavid du Colombier unlockdisplay(display);
14453f695129SDavid du Colombier sleep(sleeptime);
14467dd7cddfSDavid du Colombier }
14477dd7cddfSDavid du Colombier }
1448