| plan 9 kernel history: overview | file list | diff list |
1998/0917/port/devmntstats.c (diff list | history)
| port/devmntstats.c on 1998/0916 | ||
| 1998/0916 | #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" | |
| 1998/0917 | void (*mntstats)(int, Chan*, uvlong, ulong); | |
| 1998/0916 | enum { Qmntstat = 1<<12, Nhash= 31, Nms= 256, Nrpc= (Tmax-Tnop)/2, }; typedef struct Mntstats Mntstats; struct Mntstats { Mntstats *next; int inuse; Chan c; | |
| 1998/0917 | uvlong hi[Nrpc]; /* high water time spent */ uvlong tot[Nrpc]; /* cumulative time spent */ | |
| 1998/0916 | uvlong bytes[Nrpc]; /* cumulative bytes xfered */ ulong n[Nrpc]; /* number of messages/msg type */ | |
| 1998/0917 | 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 */ | |
| 1998/0916 | ulong last100[Nrpc]; /* avg time for last 100 */ }; static struct { Lock; Mntstats *hash[Nhash]; Mntstats all[Nms]; int n; } msalloc; static void | |
| 1998/0917 | _mntstats(int type, Chan *c, uvlong start, ulong bytes) | |
| 1998/0916 | { 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; | |
| 1998/0917 | m->bytes[type] += bytes; if(bytes >= 8*1024){ m->bigtot[type] += elapsed; m->bign[type]++; m->bigbytes[type] += bytes; } | |
| 1998/0916 | } 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 { | |
| 1998/0917 | Nline= 141, | |
| 1998/0916 | }; 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; | |
| 1998/0917 | 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]); | |
| 1998/0916 | 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, }; | |