|
|
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.