|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "../port/error.h" ! 7: ! 8: #include "devtab.h" ! 9: ! 10: #define LRES 3 /* log of PC resolution */ ! 11: #define SZ 4 /* sizeof of count cell; well known as 4 */ ! 12: ! 13: struct ! 14: { ! 15: int minpc; ! 16: int maxpc; ! 17: int nbuf; ! 18: int time; ! 19: ulong *buf; ! 20: }kprof; ! 21: ! 22: enum{ ! 23: Kprofdirqid, ! 24: Kprofdataqid, ! 25: Kprofctlqid, ! 26: Nkproftab=Kprofctlqid, ! 27: Kprofmaxqid, ! 28: }; ! 29: Dirtab kproftab[Nkproftab]={ ! 30: "kpdata", {Kprofdataqid}, 0, 0600, ! 31: "kpctl", {Kprofctlqid}, 0, 0600, ! 32: }; ! 33: ! 34: void kproftimer(ulong); ! 35: ! 36: void ! 37: kprofreset(void) ! 38: { ! 39: } ! 40: ! 41: void ! 42: kprofinit(void) ! 43: { ! 44: if(SZ != sizeof kprof.buf[0]) ! 45: panic("kprof size"); ! 46: } ! 47: ! 48: Chan * ! 49: kprofattach(char *spec) ! 50: { ! 51: ulong n; ! 52: ! 53: /* allocate when first used */ ! 54: kprof.minpc = KTZERO; ! 55: kprof.maxpc = (ulong)etext; ! 56: kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES; ! 57: n = kprof.nbuf*SZ; ! 58: if(kprof.buf == 0) { ! 59: kprof.buf = xalloc(n); ! 60: if(kprof.buf == 0) ! 61: error(Enomem); ! 62: } ! 63: kproftab[0].length = n; ! 64: return devattach('T', spec); ! 65: } ! 66: Chan * ! 67: kprofclone(Chan *c, Chan *nc) ! 68: { ! 69: return devclone(c, nc); ! 70: } ! 71: ! 72: int ! 73: kprofwalk(Chan *c, char *name) ! 74: { ! 75: return devwalk(c, name, kproftab, (long)Nkproftab, devgen); ! 76: } ! 77: ! 78: void ! 79: kprofstat(Chan *c, char *db) ! 80: { ! 81: devstat(c, db, kproftab, (long)Nkproftab, devgen); ! 82: } ! 83: ! 84: Chan * ! 85: kprofopen(Chan *c, int omode) ! 86: { ! 87: if(c->qid.path == CHDIR){ ! 88: if(omode != OREAD) ! 89: error(Eperm); ! 90: } ! 91: c->mode = openmode(omode); ! 92: c->flag |= COPEN; ! 93: c->offset = 0; ! 94: return c; ! 95: } ! 96: ! 97: void ! 98: kprofcreate(Chan *c, char *name, int omode, ulong perm) ! 99: { ! 100: USED(c, name, omode, perm); ! 101: error(Eperm); ! 102: } ! 103: ! 104: void ! 105: kprofremove(Chan *c) ! 106: { ! 107: USED(c); ! 108: error(Eperm); ! 109: } ! 110: ! 111: void ! 112: kprofwstat(Chan *c, char *dp) ! 113: { ! 114: USED(c, dp); ! 115: error(Eperm); ! 116: } ! 117: ! 118: void ! 119: kprofclose(Chan *c) ! 120: { ! 121: USED(c); ! 122: } ! 123: ! 124: long ! 125: kprofread(Chan *c, void *va, long n, ulong offset) ! 126: { ! 127: ulong tabend; ! 128: ulong w, *bp; ! 129: uchar *a, *ea; ! 130: ! 131: switch(c->qid.path & ~CHDIR){ ! 132: case Kprofdirqid: ! 133: return devdirread(c, va, n, kproftab, Nkproftab, devgen); ! 134: ! 135: case Kprofdataqid: ! 136: tabend = kprof.nbuf*SZ; ! 137: if(offset & (SZ-1)) ! 138: error(Ebadarg); ! 139: if(offset >= tabend){ ! 140: n = 0; ! 141: break; ! 142: } ! 143: if(offset+n > tabend) ! 144: n = tabend-offset; ! 145: n &= ~(SZ-1); ! 146: a = va; ! 147: ea = a + n; ! 148: bp = kprof.buf + offset/SZ; ! 149: while(a < ea){ ! 150: w = *bp++; ! 151: *a++ = w>>24; ! 152: *a++ = w>>16; ! 153: *a++ = w>>8; ! 154: *a++ = w>>0; ! 155: } ! 156: break; ! 157: ! 158: default: ! 159: n = 0; ! 160: break; ! 161: } ! 162: return n; ! 163: } ! 164: ! 165: long ! 166: kprofwrite(Chan *c, char *a, long n, ulong offset) ! 167: { ! 168: USED(offset); ! 169: ! 170: switch((int)(c->qid.path&~CHDIR)){ ! 171: case Kprofctlqid: ! 172: if(strncmp(a, "startclr", 8) == 0){ ! 173: memset((char *)kprof.buf, 0, kprof.nbuf*SZ); ! 174: kprof.time = 1; ! 175: }else if(strncmp(a, "start", 5) == 0) ! 176: kprof.time = 1; ! 177: else if(strncmp(a, "stop", 4) == 0) ! 178: kprof.time = 0; ! 179: else ! 180: error(Ebadctl); ! 181: break; ! 182: default: ! 183: error(Ebadusefd); ! 184: } ! 185: return n; ! 186: } ! 187: ! 188: void ! 189: kproftimer(ulong pc) ! 190: { ! 191: extern void spldone(void); ! 192: ! 193: if(kprof.time == 0) ! 194: return; ! 195: /* ! 196: * if the pc is coming out of spllo or splx, ! 197: * use the pc saved when we went splhi. ! 198: */ ! 199: if(pc>=(ulong)splx && pc<=(ulong)spldone) ! 200: pc = m->splpc; ! 201: ! 202: kprof.buf[0] += TK2MS(1); ! 203: if(kprof.minpc<=pc && pc<kprof.maxpc){ ! 204: pc -= kprof.minpc; ! 205: pc >>= LRES; ! 206: kprof.buf[pc] += TK2MS(1); ! 207: }else ! 208: kprof.buf[1] += TK2MS(1); ! 209: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.