|
|
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(".data"); ! 69: mcount() ! 70: { ! 71: register int *selfpc; /* PCC a5 */ ! 72: register long **cntp; /* PCC a4 */ ! 73: ! 74: /* ! 75: * find the return address for mcount, ! 76: * and address of counter pointer ! 77: */ ! 78: #ifdef __GNUC__ ! 79: asm("movl a6@(4),%0" : "=r" (selfpc)); /* selfpc = ... (jsb frame) */ ! 80: asm("movl a0,%0" : "=r" (cntp)); /* address of count local */ ! 81: #else ! 82: asm(" movl a6@(4),a5"); /* selfpc = ... (jsb frame) */ ! 83: asm(" movl a0,a4"); /* address of count local */ ! 84: #endif ! 85: /* ! 86: * check that we aren't recursively invoked. ! 87: */ ! 88: if (profiling) ! 89: return; ! 90: profiling++; ! 91: /* ! 92: * check that counter is allocated ! 93: */ ! 94: if (*cntp == 0) { ! 95: /* ! 96: * check that a counter is available ! 97: */ ! 98: if (cntrs++ == numctrs) ! 99: goto overflow; ! 100: countbase->pc = selfpc; ! 101: *cntp = &countbase->ncall; ! 102: countbase++; ! 103: } ! 104: (**cntp)++; ! 105: profiling--; ! 106: return; ! 107: ! 108: overflow: ! 109: # define TOLIMIT "mcount: counter overflow\n" ! 110: write( 2 , TOLIMIT , sizeof( TOLIMIT ) ); ! 111: profiling--; ! 112: } ! 113: asm(".text"); ! 114: asm(".data"); ! 115: ! 116: monitor(lowpc, highpc, buf, bufsiz, cntsiz) ! 117: char *lowpc, *highpc; ! 118: char *buf; ! 119: int bufsiz, cntsiz; ! 120: { ! 121: register int o; ! 122: struct phdr *php; ! 123: static int ssiz; ! 124: static char *sbuf; ! 125: ! 126: if (lowpc == 0) { ! 127: moncontrol(0); ! 128: o = creat("mon.out", 0666); ! 129: write(o, sbuf, ssiz); ! 130: close(o); ! 131: return; ! 132: } ! 133: sbuf = buf; ! 134: ssiz = bufsiz; ! 135: php = (struct phdr *)&buf[0]; ! 136: php->lpc = (int *)lowpc; ! 137: php->hpc = (int *)highpc; ! 138: php->ncnt = cntsiz; ! 139: numctrs = cntsiz; ! 140: countbase = (struct cnt *)(buf + sizeof(struct phdr)); ! 141: o = sizeof(struct phdr) + cntsiz * sizeof(struct cnt); ! 142: buf += o; ! 143: bufsiz -= o; ! 144: if (bufsiz <= 0) ! 145: return; ! 146: o = (highpc - lowpc); ! 147: if(bufsiz < o) ! 148: o = ((float) bufsiz / o) * 65536; ! 149: else ! 150: o = 65536; ! 151: s_scale = o; ! 152: s_sbuf = buf; ! 153: s_bufsiz = bufsiz; ! 154: s_lowpc = lowpc; ! 155: moncontrol(1); ! 156: } ! 157: ! 158: /* ! 159: * Control profiling ! 160: * profiling is what mcount checks to see if ! 161: * all the data structures are ready. ! 162: */ ! 163: moncontrol(mode) ! 164: int mode; ! 165: { ! 166: if (mode) { ! 167: /* start */ ! 168: profil(s_sbuf, s_bufsiz, s_lowpc, s_scale); ! 169: profiling = 0; ! 170: } else { ! 171: /* stop */ ! 172: profil((char *)0, 0, 0, 0); ! 173: profiling = 3; ! 174: } ! 175: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.