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