## 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
|