| plan 9 kernel history: overview | file list | diff list |
1990/03292/port/devkprof.c (diff list | history)
| port/devkprof.c on 1990/03292 | ||
| 1990/03292 | #include "syslibc.h" #include "lock.h" #include "mem.h" #include "chan.h" #include "proc.h" #include "user.h" #include "errno.h" #include "dev.h" #include "misc.h" #include "lint.h" #include "devtab.h" #define MAXPC (100*1024L) #define RES 8 #define LRES 3 #define NBUF (MAXPC>>LRES) long timerbuf[NBUF]; enum{ Kprofdirqid, Kprofdataqid, Kprofstartqid, Kprofstartclrqid, Kprofstopqid, Nkproftab=Kprofstopqid, Kprofmaxqid, }; Dirtab kproftab[Nkproftab]={ "kpdata", Kprofdataqid, NBUF*sizeof timerbuf[0], "kpstart", Kprofstartqid, 0, "kpstartclr", Kprofstartclrqid, 0, "kpstop", Kprofstopqid, 0, }; void kprofinit(void) { if((((unsigned long)&etext)-KTZERO)>MAXPC) print("kernel profiling limited to %lud\n", MAXPC); } Chan * kprofattach(char *spec) { return devattach('k', spec); } Chan * kprofclone(Chan *c, Chan *nc) { return devclone('k', c, nc); } int kprofwalk(Chan *c, char *name) { return devwalk(c, name, kproftab, (long)Nkproftab, devgen); } void kprofstat(Chan *c, Dir *db) { devstat(c, db, kproftab, (long)Nkproftab, devgen); } Chan * kprofopen(Chan *c, int omode, int amode) { if(amode==Aattach) return c; omode&=~Otrunc; if(omode==Oexecute) errjmp(Eperm); if(((c->qid&CHDIR) || c->qid==Kprofdataqid) && omode!=Oread) errjmp(Eisdir); c->mode=omode|OPEN; c->offset=0; return c; } void kprofcreate(Chan *c, char *name, int omode, ulong perm) { Unused(c); Unused(name); Unused(omode); Unused(perm); devunk(); } void kprofremove(Chan *c) { Unused(c); devunk(); } void kprofwstat(Chan *c, Dir *dp) { Unused(c); Unused(dp); devunk(); } void kprofclose(Chan *c) { Unused(c); } long kprofread(Chan *c, char *a, long n) { switch((int)(c->qid&~CHDIR)){ case Kprofdirqid: return devdirread(c, a, n, kproftab, (long)Nkproftab, devgen); break; case Kprofdataqid: if(c->offset>=NBUF*sizeof timerbuf[0]){ n=0; break; } if(c->offset+n>NBUF*sizeof timerbuf[0]) n=NBUF*sizeof timerbuf[0]-c->offset; memcpy(a, ((char *)timerbuf)+c->offset, n); break; default: n=0; break; } c->offset+=n; return n; } long kprofwrite(Chan *c, char *a, long n) { Unused(a); switch((int)(c->qid&~CHDIR)){ case Kprofstartclrqid: memset((char *)timerbuf, 0, NBUF*sizeof timerbuf[0]); case Kprofstartqid: consstarttimer(); break; case Kprofstopqid: consstoptimer(); break; default: devunk(); } c->offset+=n; return n; } void kproftimer(ulong pc) { timerbuf[0]++; if(KTZERO<=pc && pc<KTZERO+MAXPC){ pc-=KTZERO; pc>>=LRES; timerbuf[pc]++; } } | |