|
|
1.1 ! root 1: static char *sccsid = "@(#)mon.c 2.0 (Tahoe) 5/7/84"; ! 2: ! 3: #define ARCDENSITY 5 /* density of routines */ ! 4: #define MINARCS 50 /* minimum number of counters */ ! 5: #define HISTFRACTION 2 /* fraction of text space for histograms */ ! 6: ! 7: ! 8: struct phdr { ! 9: char *lpc; ! 10: char *hpc; ! 11: int ncnt; ! 12: }; ! 13: ! 14: struct cnt { ! 15: char *pc; ! 16: long ncall; ! 17: } *countbase; ! 18: ! 19: static int cntrs = 0; ! 20: static int profiling = 3; ! 21: static char *s_sbuf; ! 22: static int s_bufsiz; ! 23: static int s_scale; ! 24: static char *s_lowpc; ! 25: ! 26: int numctrs; ! 27: ! 28: #define MSG "No space for monitor buffer(s)\n" ! 29: ! 30: monstartup(lowpc, highpc) ! 31: char *lowpc; ! 32: char *highpc; ! 33: { ! 34: int monsize; ! 35: char *buffer; ! 36: int cntsiz; ! 37: extern char *sbrk(); ! 38: extern char *minbrk; ! 39: ! 40: ! 41: cntsiz = (highpc - lowpc) * ARCDENSITY / 100; ! 42: if (cntsiz < MINARCS) ! 43: cntsiz = MINARCS; ! 44: monsize = (highpc - lowpc + HISTFRACTION - 1) / HISTFRACTION ! 45: + sizeof(struct phdr) + cntsiz * sizeof(struct cnt); ! 46: monsize = (monsize + 1) & ~1; ! 47: buffer = sbrk(monsize); ! 48: if (buffer == (char *)-1) { ! 49: write(2, MSG, sizeof(MSG)); ! 50: return; ! 51: } ! 52: minbrk = sbrk(0); ! 53: monitor(lowpc, highpc, buffer, monsize, cntsiz); ! 54: } ! 55: ! 56: mcount(cntpa) ! 57: long **cntpa; ! 58: { ! 59: register long **cntp; ! 60: register char *selfpc; ! 61: ! 62: /* ! 63: * find the return address for mcount, ! 64: * and address of counter pointer ! 65: */ ! 66: selfpc = *((char **)&cntpa-3); /* -8(fp) */ ! 67: cntp = cntpa; ! 68: /* ! 69: * check that we aren't recursively invoked. ! 70: */ ! 71: if (profiling) ! 72: goto out; ! 73: profiling++; ! 74: /* ! 75: * check that counter is allocated ! 76: */ ! 77: if (*cntp == 0) { ! 78: /* ! 79: * check that a counter is available ! 80: */ ! 81: if (cntrs++ == numctrs) ! 82: goto overflow; ! 83: countbase->pc = selfpc; ! 84: *cntp = &countbase->ncall; ! 85: countbase++; ! 86: } ! 87: (**cntp)++; ! 88: profiling--; ! 89: out: ! 90: return; ! 91: ! 92: overflow: ! 93: # define TOLIMIT "mcount: counter overflow\n" ! 94: write( 2 , TOLIMIT , sizeof( TOLIMIT ) ); ! 95: goto out; ! 96: } ! 97: ! 98: monitor(lowpc, highpc, buf, bufsiz, cntsiz) ! 99: char *lowpc, *highpc; ! 100: char *buf; ! 101: int bufsiz, cntsiz; ! 102: { ! 103: register int o; ! 104: struct phdr *php; ! 105: static int ssiz; ! 106: static char *sbuf; ! 107: ! 108: if (lowpc == 0) { ! 109: moncontrol(0); ! 110: o = creat("mon.out", 0666); ! 111: write(o, sbuf, ssiz); ! 112: close(o); ! 113: return; ! 114: } ! 115: sbuf = buf; ! 116: ssiz = bufsiz; ! 117: php = (struct phdr *)&buf[0]; ! 118: php->lpc = lowpc; ! 119: php->hpc = highpc; ! 120: php->ncnt = cntsiz; ! 121: numctrs = cntsiz; ! 122: countbase = (struct cnt *)(buf + sizeof(struct phdr)); ! 123: o = sizeof(struct phdr) + cntsiz * sizeof(struct cnt); ! 124: buf += o; ! 125: bufsiz -= o; ! 126: if (bufsiz <= 0) ! 127: return; ! 128: o = (highpc - lowpc); ! 129: if(bufsiz < o) ! 130: o = ((float) bufsiz / o) * 65536; ! 131: else ! 132: o = 65536; ! 133: s_scale = o; ! 134: s_sbuf = buf; ! 135: s_bufsiz = bufsiz; ! 136: s_lowpc = lowpc; ! 137: moncontrol(1); ! 138: } ! 139: ! 140: /* ! 141: * Control profiling ! 142: * profiling is what mcount checks to see if ! 143: * all the data structures are ready. ! 144: */ ! 145: moncontrol(mode) ! 146: int mode; ! 147: { ! 148: if (mode) { ! 149: /* start */ ! 150: profil(s_sbuf, s_bufsiz, s_lowpc, s_scale); ! 151: profiling = 0; ! 152: } else { ! 153: /* stop */ ! 154: profil((char *)0, 0, 0, 0); ! 155: profiling = 3; ! 156: } ! 157: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.