## diffname port/devmntstats.c 1998/0916 ## diff -e /dev/null /n/emeliedump/1998/0916/sys/src/brazil/port/devmntstats.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" void (*mntstats)(int, Chan*, uvlong); enum { Qmntstat = 1<<12, Nhash= 31, Nms= 256, Nrpc= (Tmax-Tnop)/2, }; typedef struct Mntstats Mntstats; struct Mntstats { Mntstats *next; int inuse; Chan c; uvlong hi[Nrpc]; /* high water time spent/msg type */ uvlong tot[Nrpc]; /* cumulative time spent/msg type */ uvlong bytes[Nrpc]; /* cumulative bytes xfered */ ulong n[Nrpc]; /* number of messages/msg type */ ulong last100[Nrpc]; /* avg time for last 100 */ }; static struct { Lock; Mntstats *hash[Nhash]; Mntstats all[Nms]; int n; } msalloc; static void _mntstats(int type, Chan *c, uvlong start) { uint h; Mntstats **l, *m; uvlong elapsed; ulong x; elapsed = fastticks(nil) - start; type -= Tnop; type >>= 1; h = (c->dev<<4)+(c->type<<2)+c->qid.path; h %= Nhash; for(l = &msalloc.hash[h]; *l; l = &(*l)->next) if(eqchan(&(*l)->c, c, 0)) break; m = *l; if(m == nil){ lock(&msalloc); for(m = msalloc.all; m < &msalloc.all[Nms]; m++) if(m->inuse && eqchan(&m->c, c, 0)) break; if(m == &msalloc.all[Nms]) for(m = msalloc.all; m < &msalloc.all[Nms]; m++){ if(m->inuse == 0){ m->inuse = 1; m->c = *c; *l = m; msalloc.n++; break; } } unlock(&msalloc); if(m >= &msalloc.all[Nms]) return; } if(m->hi[type] < elapsed) m->hi[type] = elapsed; m->tot[type] += elapsed; m->n[type]++; x = elapsed; m->last100[type] = (m->last100[type]*127 + x)>>7; } static int mntstatsgen(Chan *c, Dirtab*, int, int i, Dir *dp) { Qid q; char name[NAMELEN]; Mntstats *m; m = &msalloc.all[i]; if(i > Nms || m->inuse == 0) return -1; q = (Qid){Qmntstat+i, 0}; snprint(name, NAMELEN, "%C%lud.%lux", devtab[m->c.type]->dc, m->c.dev, m->c.qid.path); devdir(c, q, name, 0, eve, 0666, dp); return 1; } static void mntstatsinit(void) { mntstats = _mntstats; } static Chan* mntstatsattach(char *spec) { return devattach('z', spec); } static int mntstatswalk(Chan *c, char *name) { return devwalk(c, name, 0, msalloc.n, mntstatsgen); } static void mntstatsstat(Chan *c, char *dp) { devstat(c, dp, 0, msalloc.n, mntstatsgen); } static Chan* mntstatsopen(Chan *c, int omode) { return devopen(c, omode, 0, msalloc.n, mntstatsgen); } static void mntstatsclose(Chan*) { } enum { Nline= 80, }; char *rpcname[Nrpc] = { "nop", "osession", "error", "flush", "oattach", "clone", "walk", "open", "create", "read", "write", "clunk", "remove", "stat", "wstat", "clwalk", "auth", "session", "attach", }; static long mntstatsread(Chan *c, void *buf, long n, vlong off) { char *a, *start; ulong o; char xbuf[Nline+1]; Mntstats *m; uvlong avg; start = a = buf; if(n <= 0) return n; if(c->qid.path & CHDIR) return devdirread(c, buf, n, 0, msalloc.n, mntstatsgen); m = &msalloc.all[c->qid.path - Qmntstat]; o = off; if((o % Nline) != 0) error(Ebadarg); n = n/Nline; o = o/Nline; while(n > 0 && o < Nrpc){ if(m->n[o] > 0) avg = m->tot[o]/m->n[o]; else avg = 0; sprint(xbuf, "%-8.8s %16.0llud %16.0llud %9.0lud %16.0llud %9.0lud\n", rpcname[o], m->hi[o], m->tot[o], m->n[o], avg, m->last100[o]); memmove(a, xbuf, Nline); a += Nline; o++; n--; } return a - start; } static long mntstatswrite(Chan*, void*, long, vlong) { lock(&msalloc); memset(msalloc.all, 0, sizeof(msalloc.all)); msalloc.n = 0; unlock(&msalloc); return 0; } Dev mntstatsdevtab = { 'z', "mntstats", devreset, mntstatsinit, mntstatsattach, devclone, mntstatswalk, mntstatsstat, mntstatsopen, devcreate, mntstatsclose, mntstatsread, devbread, mntstatswrite, devbwrite, devremove, devwstat, }; . ## diffname port/devmntstats.c 1998/0917 ## diff -e /n/emeliedump/1998/0916/sys/src/brazil/port/devmntstats.c /n/emeliedump/1998/0917/sys/src/brazil/port/devmntstats.c 196,198c sprint(xbuf, "%-8.8s %16.0llud %16.0llud %16.0llud %9.0lud %16.0llud %16.0llud %9.0lud %16.0llud %9.0lud\n", rpcname[o], m->hi[o], m->tot[o], m->bytes[o], m->n[o], m->bigtot[o], m->bigbytes[o], m->bign[o], avg, m->last100[o]); . 142c Nline= 141, . 84a m->bytes[type] += bytes; if(bytes >= 8*1024){ m->bigtot[type] += elapsed; m->bign[type]++; m->bigbytes[type] += bytes; } . 41c _mntstats(int type, Chan *c, uvlong start, ulong bytes) . 28a uvlong bigtot[Nrpc]; /* cumulative time spent in big messages */ uvlong bigbytes[Nrpc]; /* cumulative bytes xfered in big messages */ ulong bign[Nrpc]; /* number of big messages */ . 25,26c uvlong hi[Nrpc]; /* high water time spent */ uvlong tot[Nrpc]; /* cumulative time spent */ . 8c void (*mntstats)(int, Chan*, uvlong, ulong); . ## diffname port/devmntstats.c 1998/1003 ## diff -e /n/emeliedump/1998/0917/sys/src/brazil/port/devmntstats.c /n/emeliedump/1998/1003/sys/src/brazil/port/devmntstats.c 202,209c snprint(xbuf, sizeof(xbuf), "%-8.8s\t%20.0llud\n\t%20.0llud %20.0llud %9.0lud\n\t%20.0llud %20.0llud %9.0lud\n", rpcname[o], m->hi[o], m->tot[o], m->bytes[o], m->n[o], m->bigtot[o], m->bigbytes[o], m->bign[o]); . 185d 152c Nline= 136, . 87d 32d ## diffname port/devmntstats.c 1999/0211 ## diff -e /n/emeliedump/1998/1003/sys/src/brazil/port/devmntstats.c /n/emeliedump/1999/0211/sys/src/brazil/port/devmntstats.c 85d 48d ## diffname port/devmntstats.c 1999/1230 ## diff -e /n/emeliedump/1999/0211/sys/src/brazil/port/devmntstats.c /n/emeliedump/1999/1230/sys/src/9/port/devmntstats.c 99a if(i == DEVDOTDOT){ devdir(c, (Qid){CHDIR,0}, "#z", 0, eve, 0555, dp); return 1; } . ## diffname port/devmntstats.c 2001/0527 ## diff -e /n/emeliedump/1999/1230/sys/src/9/port/devmntstats.c /n/emeliedump/2001/0527/sys/src/9/port/devmntstats.c 110,111c snprint(up->genbuf, sizeof up->genbuf, "%C%lud.%lux", devtab[m->c.type]->dc, m->c.dev, m->c.qid.path); devdir(c, q, up->genbuf, 0, eve, 0666, dp); . 97d