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