| plan 9 kernel history: overview | file list | diff list |
1990/0928/port/devkprof.c (diff list | history)
| port/devkprof.c on 1990/0330 | ||
| 1990/0330 | #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" | |
| 1990/03292 | ||
| 1990/0330 | #include "devtab.h" | |
| 1990/03292 | #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]={ | |
| 1990/0330 | "kpdata", Kprofdataqid, NBUF*sizeof timerbuf[0], 0600, "kpstart", Kprofstartqid, 0, 0600, "kpstartclr", Kprofstartclrqid, 0, 0600, "kpstop", Kprofstopqid, 0, 0600, | |
| 1990/03292 | }; void | |
| 1990/0330 | kprofreset(void) { } void | |
| 1990/03292 | kprofinit(void) { | |
| 1990/0330 | extern void *etext; | |
| 1990/03292 | if((((unsigned long)&etext)-KTZERO)>MAXPC) print("kernel profiling limited to %lud\n", MAXPC); } Chan * kprofattach(char *spec) { | |
| 1990/0330 | return devattach('t', spec); | |
| 1990/03292 | } Chan * kprofclone(Chan *c, Chan *nc) { | |
| 1990/0330 | return devclone(c, nc); | |
| 1990/03292 | } int kprofwalk(Chan *c, char *name) { return devwalk(c, name, kproftab, (long)Nkproftab, devgen); } void | |
| 1990/0330 | kprofstat(Chan *c, char *db) | |
| 1990/03292 | { devstat(c, db, kproftab, (long)Nkproftab, devgen); } Chan * | |
| 1990/0330 | kprofopen(Chan *c, int omode) | |
| 1990/03292 | { | |
| 1990/0330 | if(c->qid == CHDIR){ if(omode != OREAD) error(0, Eperm); } c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; | |
| 1990/03292 | return c; } void kprofcreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1990/0330 | error(0, Eperm); | |
| 1990/03292 | } void kprofremove(Chan *c) { | |
| 1990/0330 | error(0, Eperm); | |
| 1990/03292 | } void | |
| 1990/0330 | kprofwstat(Chan *c, char *dp) | |
| 1990/03292 | { | |
| 1990/0330 | error(0, Eperm); | |
| 1990/03292 | } void kprofclose(Chan *c) { } | |
| 1990/0330 | void kprofuserstr(Error *e, char *buf) { consuserstr(e, buf); } void kproferrstr(Error *e, char *buf) { rooterrstr(e, buf); } | |
| 1990/03292 | long | |
| 1990/0330 | kprofread(Chan *c, void *a, long n) | |
| 1990/03292 | { switch((int)(c->qid&~CHDIR)){ case Kprofdirqid: | |
| 1990/0330 | return devdirread(c, a, n, kproftab, Nkproftab, devgen); | |
| 1990/03292 | case Kprofdataqid: | |
| 1990/0330 | if(c->offset >= NBUF*sizeof timerbuf[0]){ n = 0; | |
| 1990/03292 | break; } | |
| 1990/0330 | if(c->offset+n > NBUF*sizeof timerbuf[0]) n = NBUF*sizeof timerbuf[0]-c->offset; | |
| 1990/03292 | memcpy(a, ((char *)timerbuf)+c->offset, n); break; default: n=0; break; } return n; } long kprofwrite(Chan *c, char *a, long n) { switch((int)(c->qid&~CHDIR)){ case Kprofstartclrqid: memset((char *)timerbuf, 0, NBUF*sizeof timerbuf[0]); case Kprofstartqid: | |
| 1990/0330 | duartstarttimer(); | |
| 1990/03292 | break; case Kprofstopqid: | |
| 1990/0330 | duartstoptimer(); | |
| 1990/03292 | break; default: | |
| 1990/0330 | error(0, Ebadusefd); | |
| 1990/03292 | } return n; } void kproftimer(ulong pc) { | |
| 1990/0928 | extern ulong splpc; | |
| 1990/03292 | timerbuf[0]++; if(KTZERO<=pc && pc<KTZERO+MAXPC){ | |
| 1990/0330 | pc -= KTZERO; pc >>= LRES; | |
| 1990/03292 | timerbuf[pc]++; | |
| 1990/0331 | } else timerbuf[1]++; | |
| 1990/03292 | } | |