|
|
1.1 root 1: static char *sccsid = "@(#)pmon.c 1.2 (Berkeley) 3/7/81";
2: /* Copyright (c) 1979 Regents of the University of California */
3: #
4: /*
5: * pxp - Pascal execution profiler
6: *
7: * Bill Joy UCB
8: * Version 1.2 January 1979
9: */
10:
11: #include "0.h"
12:
13: /*
14: * Profile counter processing cluster
15: *
16: * This file contains all routines which do the hard work in profiling.
17: *
18: * The first group of routines (getit, getpmon, getcore, and pmread)
19: * deal with extracting data from the pmon.out and (with more difficulty)
20: * core files.
21: *
22: * The routines cnttab and prttab collect counters for
23: * and print the summary table respectively.
24: *
25: * The routines "*cnt*" deal with manipulation of counters,
26: * especially the "current" counter px.
27: */
28: STATIC struct pxcnt px;
29:
30: /*
31: * Table to record info
32: * for procedure/function summary
33: */
34: STATIC struct pftab {
35: long pfcnt;
36: short pfline;
37: char *pfname;
38: short pflev;
39: } *zpf;
40:
41: /*
42: * Global variables
43: */
44: STATIC long *zbuf; /* Count buffer */
45: STATIC short zcnt; /* Number of counts */
46: STATIC short zpfcnt; /* Number of proc/funcs's */
47: STATIC short gcountr; /* Unique name generator */
48: STATIC short zfil; /* I/o unit for count data reads */
49: STATIC short lastpf; /* Total # of procs and funcs for consistency chk */
50:
51: getit(fp)
52: register char *fp;
53: {
54:
55: if (core)
56: getcore(fp);
57: else
58: getpmon(fp);
59: }
60:
61: /*
62: * Setup monitor data buffer from pmon.out
63: * style file whose name is fp.
64: */
65: getpmon(fp)
66: char *fp;
67: {
68: register char *cp;
69: short garbage;
70:
71: zfil = open(fp, 0);
72: if (zfil < 0) {
73: perror(fp);
74: pexit(NOSTART);
75: }
76: if (pmread() < 0 || read(zfil, &garbage, 1) == 1) {
77: Perror(fp, "Bad format for pmon.out style file");
78: exit(1);
79: }
80: close(zfil);
81: return;
82: }
83:
84: STATIC char nospcm[] = "Not enough memory for count buffers\n";
85:
86: pmnospac()
87: {
88:
89: write(2, nospcm, sizeof nospcm);
90: pexit(NOSTART);
91: }
92:
93: /*
94: * Structure of the first few
95: * items of a px core dump.
96: */
97: STATIC struct info {
98: char *off; /* Self-reference for pure text */
99: short type; /* 0 = non-pure text, 1 = pure text */
100: char *bp; /* Core address of pxps struct */
101: } inf;
102:
103: /*
104: * First few words of the px
105: * information structure.
106: */
107: STATIC struct pxps {
108: char *buf;
109: short cnt;
110: } pxp;
111:
112: getcore(fp)
113: char *fp;
114: {
115:
116: write(2, "-c: option not supported\n", sizeof("-c: option not supported\n"));
117: pexit(ERRS);
118: /*
119: short pm;
120:
121: zfil = open(fp, 0);
122: if (zfil < 0) {
123: perror(fp);
124: pexit(NOSTART);
125: }
126: if (lseek(zfil, 02000, 0) < 0)
127: goto format;
128: if (read(zfil, &inf, sizeof inf) < 0)
129: goto format;
130: if (inf.type != 0 && inf.type != 1)
131: goto format;
132: if (inf.type)
133: inf.bp =- inf.off;
134: if (lseek(zfil, inf.bp + 02000, 0) < 0)
135: goto format;
136: if (read(zfil, &pxp, sizeof pxp) != sizeof pxp)
137: goto format;
138: if (pxp.buf == NIL) {
139: Perror(fp, "No profile data in file");
140: exit(1);
141: }
142: if (inf.type)
143: pxp.buf =- inf.off;
144: if (lseek(zfil, pxp.buf + 02000, 0) < 0)
145: goto format;
146: if (pmread() < 0)
147: goto format;
148: close(zfil);
149: return;
150: format:
151: Perror(fp, "Not a Pascal system core file");
152: exit(1);
153: */
154: }
155:
156: pmread()
157: {
158: register i;
159: register char *cp;
160: struct {
161: long no;
162: long tim;
163: long cntrs;
164: long rtns;
165: } zmagic;
166:
167: if (read(zfil, &zmagic, sizeof zmagic) != sizeof zmagic)
168: return (-1);
169: if (zmagic.no != 0426)
170: return (-1);
171: ptvec = zmagic.tim;
172: zcnt = zmagic.cntrs;
173: zpfcnt = zmagic.rtns;
174: cp = zbuf = alloc(i = (zcnt + 1) * sizeof *zbuf);
175: if (cp == -1)
176: pmnospac();
177: cp = zpf = alloc(zpfcnt * sizeof *zpf);
178: if (cp == -1)
179: pmnospac();
180: i -= sizeof(zmagic);
181: if (read(zfil, zbuf + (sizeof(zmagic) / sizeof(*zbuf)), i) != i)
182: return (-1);
183: zbuf++;
184: return (0);
185: }
186:
187: cnttab(s, no)
188: char *s;
189: short no;
190: {
191: register struct pftab *pp;
192:
193: lastpf++;
194: if (table == 0)
195: return;
196: if (no == zpfcnt)
197: cPANIC();
198: pp = &zpf[no];
199: pp->pfname = s;
200: pp->pfline = line;
201: pp->pfcnt = nowcnt();
202: pp->pflev = cbn;
203: }
204:
205: prttab()
206: {
207: register i, j;
208: register struct pftab *zpfp;
209:
210: if (profile == 0 && table == 0)
211: return;
212: if (cnts != zcnt || lastpf != zpfcnt)
213: cPANIC();
214: if (table == 0)
215: return;
216: if (profile)
217: printf("\f\n");
218: header();
219: printf("\n\tLine\t Count\n\n");
220: zpfp = zpf;
221: for (i = 0; i < zpfcnt; i++) {
222: printf("\t%4d\t%8ld\t", zpfp->pfline, zpfp->pfcnt);
223: if (!justify)
224: for (j = zpfp->pflev * unit; j > 1; j--)
225: putchar(' ');
226: printf("%s\n", zpfp->pfname);
227: zpfp++;
228: }
229: }
230:
231: nowcntr()
232: {
233:
234: return (px.counter);
235: }
236:
237: long nowcnt()
238: {
239:
240: return (px.ntimes);
241: }
242:
243: long cntof(pxc)
244: struct pxcnt *pxc;
245: {
246:
247: if (profile == 0 && table == 0)
248: return;
249: return (pxc->ntimes);
250: }
251:
252: setcnt(l)
253: long l;
254: {
255:
256: if (profile == 0 && table == 0)
257: return;
258: px.counter = --gcountr;
259: px.ntimes = l;
260: px.gos = gocnt;
261: px.printed = 0;
262: }
263:
264: savecnt(pxc)
265: register struct pxcnt *pxc;
266: {
267:
268: if (profile == 0 && table == 0)
269: return;
270: pxc->ntimes = px.ntimes;
271: pxc->counter = px.counter;
272: pxc->gos = px.gos;
273: pxc->printed = 1;
274: }
275:
276: rescnt(pxc)
277: register struct pxcnt *pxc;
278: {
279:
280: if (profile == 0 && table == 0)
281: return;
282: px.ntimes = pxc->ntimes;
283: px.counter = pxc->counter;
284: px.gos = gocnt;
285: px.printed = pxc->printed;
286: return (gocnt != pxc->gos);
287: }
288:
289: getcnt()
290: {
291:
292: if (profile == 0 && table == 0)
293: return;
294: if (cnts == zcnt)
295: cPANIC();
296: px.counter = cnts;
297: px.ntimes = zbuf[cnts];
298: px.gos = gocnt;
299: px.printed = 0;
300: ++cnts;
301: }
302:
303: unprint()
304: {
305:
306: px.printed = 0;
307: }
308:
309: /*
310: * Control printing of '|'
311: * when profiling.
312: */
313: STATIC char nobar;
314:
315: baroff()
316: {
317:
318: nobar = 1;
319: }
320:
321: baron()
322: {
323:
324: nobar = 0;
325: }
326:
327: /*
328: * Do we want cnt and/or '|' on this line ?
329: * 1 = count and '|'
330: * 0 = only '|'
331: * -1 = spaces only
332: */
333: shudpcnt()
334: {
335:
336: register i;
337:
338: if (nobar)
339: return (-1);
340: i = px.printed;
341: px.printed = 1;
342: return (i == 0);
343: }
344:
345: STATIC char mism[] = "Program and counter data do not correspond\n";
346:
347: cPANIC()
348: {
349:
350: printf("cnts %d zcnt %d, lastpf %d zpfcnt %d\n",
351: cnts, zcnt, lastpf, zpfcnt);
352: flush();
353: write(2, mism, sizeof mism);
354: pexit(ERRS);
355: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.