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