xref: /csrg-svn/usr.bin/pascal/pxp/pmon.c (revision 3051)
1*3051Smckusic static	char *sccsid = "@(#)pmon.c	1.2 (Berkeley) 03/07/81";
22860Speter /* Copyright (c) 1979 Regents of the University of California */
32860Speter #
42860Speter /*
52860Speter  * pxp - Pascal execution profiler
62860Speter  *
72860Speter  * Bill Joy UCB
82860Speter  * Version 1.2 January 1979
92860Speter  */
102860Speter 
112860Speter #include "0.h"
122860Speter 
132860Speter /*
142860Speter  * Profile counter processing cluster
152860Speter  *
162860Speter  * This file contains all routines which do the hard work in profiling.
172860Speter  *
182860Speter  * The first group of routines (getit, getpmon, getcore, and pmread)
192860Speter  * deal with extracting data from the pmon.out and (with more difficulty)
202860Speter  * core files.
212860Speter  *
222860Speter  * The routines cnttab and prttab collect counters for
232860Speter  * and print the summary table respectively.
242860Speter  *
252860Speter  * The routines "*cnt*" deal with manipulation of counters,
262860Speter  * especially the "current" counter px.
272860Speter  */
282860Speter STATIC	struct pxcnt px;
292860Speter 
302860Speter /*
312860Speter  * Table to record info
322860Speter  * for procedure/function summary
332860Speter  */
342860Speter STATIC	struct pftab {
352860Speter 	long	pfcnt;
362860Speter 	short	pfline;
372860Speter 	char	*pfname;
382860Speter 	short	pflev;
392860Speter } *zpf;
402860Speter 
412860Speter /*
422860Speter  * Global variables
432860Speter  */
442860Speter STATIC	long *zbuf; 	/* Count buffer */
452860Speter STATIC	short zcnt;	/* Number of counts */
462860Speter STATIC	short zpfcnt;	/* Number of proc/funcs's */
472860Speter STATIC	short gcountr;	/* Unique name generator */
482860Speter STATIC	short zfil;	/* I/o unit for count data reads */
492860Speter STATIC	short lastpf;	/* Total # of procs and funcs for consistency chk */
502860Speter 
512860Speter getit(fp)
522860Speter 	register char *fp;
532860Speter {
542860Speter 
552860Speter 	if (core)
562860Speter 		getcore(fp);
572860Speter 	else
582860Speter 		getpmon(fp);
592860Speter }
602860Speter 
612860Speter /*
622860Speter  * Setup monitor data buffer from pmon.out
632860Speter  * style file whose name is fp.
642860Speter  */
652860Speter getpmon(fp)
662860Speter 	char *fp;
672860Speter {
682860Speter 	register char *cp;
692860Speter 	short garbage;
702860Speter 
712860Speter 	zfil = open(fp, 0);
722860Speter 	if (zfil < 0) {
732860Speter 		perror(fp);
742860Speter 		pexit(NOSTART);
752860Speter 	}
762860Speter 	if (pmread() < 0 || read(zfil, &garbage, 1) == 1) {
772860Speter 		Perror(fp, "Bad format for pmon.out style file");
782860Speter 		exit(1);
792860Speter 	}
802860Speter 	close(zfil);
812860Speter 	return;
822860Speter }
832860Speter 
84*3051Smckusic STATIC	char nospcm[]	= "Not enough memory for count buffers\n";
852860Speter 
862860Speter pmnospac()
872860Speter {
882860Speter 
892860Speter 	write(2, nospcm, sizeof nospcm);
902860Speter 	pexit(NOSTART);
912860Speter }
922860Speter 
932860Speter /*
942860Speter  * Structure of the first few
952860Speter  * items of a px core dump.
962860Speter  */
972860Speter STATIC	struct info {
982860Speter 	char	*off;		/* Self-reference for pure text */
992860Speter 	short	type;		/* 0 = non-pure text, 1 = pure text */
1002860Speter 	char	*bp;		/* Core address of pxps struct */
1012860Speter } inf;
1022860Speter 
1032860Speter /*
1042860Speter  * First few words of the px
1052860Speter  * information structure.
1062860Speter  */
1072860Speter STATIC	struct pxps {
1082860Speter 	char	*buf;
1092860Speter 	short	cnt;
1102860Speter } pxp;
1112860Speter 
1122860Speter getcore(fp)
1132860Speter 	char *fp;
1142860Speter {
1152860Speter 
1162860Speter 	write(2, "-c: option not supported\n", sizeof("-c: option not supported\n"));
1172860Speter 	pexit(ERRS);
1182860Speter /*
1192860Speter 	short pm;
1202860Speter 
1212860Speter 	zfil = open(fp, 0);
1222860Speter 	if (zfil < 0) {
1232860Speter 		perror(fp);
1242860Speter 		pexit(NOSTART);
1252860Speter 	}
1262860Speter 	if (lseek(zfil, 02000, 0) < 0)
1272860Speter 		goto format;
1282860Speter 	if (read(zfil, &inf, sizeof inf) < 0)
1292860Speter 		goto format;
1302860Speter 	if (inf.type != 0 && inf.type != 1)
1312860Speter 		goto format;
1322860Speter 	if (inf.type)
1332860Speter 		inf.bp =- inf.off;
1342860Speter 	if (lseek(zfil, inf.bp + 02000, 0) < 0)
1352860Speter 		goto format;
1362860Speter 	if (read(zfil, &pxp, sizeof pxp) != sizeof pxp)
1372860Speter 		goto format;
1382860Speter 	if (pxp.buf == NIL) {
1392860Speter 		Perror(fp, "No profile data in file");
1402860Speter 		exit(1);
1412860Speter 	}
1422860Speter 	if (inf.type)
1432860Speter 		pxp.buf =- inf.off;
1442860Speter 	if (lseek(zfil, pxp.buf + 02000, 0) < 0)
1452860Speter 		goto format;
1462860Speter 	if (pmread() < 0)
1472860Speter 		goto format;
1482860Speter 	close(zfil);
1492860Speter 	return;
1502860Speter format:
1512860Speter 	Perror(fp, "Not a Pascal system core file");
1522860Speter 	exit(1);
1532860Speter */
1542860Speter }
1552860Speter 
1562860Speter pmread()
1572860Speter {
1582860Speter 	register i;
1592860Speter 	register char *cp;
1602860Speter 	struct {
1612860Speter 		long	no;
1622860Speter 		long	tim;
1632860Speter 		long	cntrs;
1642860Speter 		long	rtns;
1652860Speter 	} zmagic;
1662860Speter 
1672860Speter 	if (read(zfil, &zmagic, sizeof zmagic) != sizeof zmagic)
1682860Speter 		return (-1);
1692860Speter 	if (zmagic.no != 0426)
1702860Speter 		return (-1);
1712860Speter 	ptvec = zmagic.tim;
1722860Speter 	zcnt = zmagic.cntrs;
1732860Speter 	zpfcnt = zmagic.rtns;
1742860Speter 	cp = zbuf = alloc(i = (zcnt + 1) * sizeof *zbuf);
1752860Speter 	if (cp == -1)
1762860Speter 		pmnospac();
1772860Speter 	cp = zpf = alloc(zpfcnt * sizeof *zpf);
1782860Speter 	if (cp == -1)
1792860Speter 		pmnospac();
1802860Speter 	i -= sizeof(zmagic);
181*3051Smckusic 	if (read(zfil, zbuf + (sizeof(zmagic) / sizeof(*zbuf)), i) != i)
1822860Speter 		return (-1);
1832860Speter 	zbuf++;
1842860Speter 	return (0);
1852860Speter }
1862860Speter 
1872860Speter cnttab(s, no)
1882860Speter 	char *s;
1892860Speter 	short no;
1902860Speter {
1912860Speter 	register struct pftab *pp;
1922860Speter 
1932860Speter 	lastpf++;
1942860Speter 	if (table == 0)
1952860Speter 		return;
1962860Speter 	if (no == zpfcnt)
1972860Speter 		cPANIC();
1982860Speter 	pp = &zpf[no];
1992860Speter 	pp->pfname = s;
2002860Speter 	pp->pfline = line;
2012860Speter 	pp->pfcnt = nowcnt();
2022860Speter 	pp->pflev = cbn;
2032860Speter }
2042860Speter 
2052860Speter prttab()
2062860Speter {
2072860Speter 	register i, j;
2082860Speter 	register struct pftab *zpfp;
2092860Speter 
2102860Speter 	if (profile == 0 && table == 0)
2112860Speter 		return;
2122860Speter 	if (cnts != zcnt || lastpf != zpfcnt)
2132860Speter 		cPANIC();
2142860Speter 	if (table == 0)
2152860Speter 		return;
2162860Speter 	if (profile)
2172860Speter 		printf("\f\n");
2182860Speter 	header();
2192860Speter 	printf("\n\tLine\t   Count\n\n");
2202860Speter 	zpfp = zpf;
2212860Speter 	for (i = 0; i < zpfcnt; i++) {
2222860Speter 		printf("\t%4d\t%8ld\t", zpfp->pfline, zpfp->pfcnt);
2232860Speter 		if (!justify)
2242860Speter 			for (j = zpfp->pflev * unit; j > 1; j--)
2252860Speter 				putchar(' ');
2262860Speter 		printf("%s\n", zpfp->pfname);
2272860Speter 		zpfp++;
2282860Speter 	}
2292860Speter }
2302860Speter 
2312860Speter nowcntr()
2322860Speter {
2332860Speter 
2342860Speter 	return (px.counter);
2352860Speter }
2362860Speter 
2372860Speter long nowcnt()
2382860Speter {
2392860Speter 
2402860Speter 	return (px.ntimes);
2412860Speter }
2422860Speter 
2432860Speter long cntof(pxc)
2442860Speter 	struct pxcnt *pxc;
2452860Speter {
2462860Speter 
2472860Speter 	if (profile == 0 && table == 0)
2482860Speter 		return;
2492860Speter 	return (pxc->ntimes);
2502860Speter }
2512860Speter 
2522860Speter setcnt(l)
2532860Speter 	long l;
2542860Speter {
2552860Speter 
2562860Speter 	if (profile == 0 && table == 0)
2572860Speter 		return;
2582860Speter 	px.counter = --gcountr;
2592860Speter 	px.ntimes = l;
2602860Speter 	px.gos = gocnt;
2612860Speter 	px.printed = 0;
2622860Speter }
2632860Speter 
2642860Speter savecnt(pxc)
2652860Speter 	register struct pxcnt *pxc;
2662860Speter {
2672860Speter 
2682860Speter 	if (profile == 0 && table == 0)
2692860Speter 		return;
2702860Speter 	pxc->ntimes = px.ntimes;
2712860Speter 	pxc->counter = px.counter;
2722860Speter 	pxc->gos = px.gos;
2732860Speter 	pxc->printed = 1;
2742860Speter }
2752860Speter 
2762860Speter rescnt(pxc)
2772860Speter 	register struct pxcnt *pxc;
2782860Speter {
2792860Speter 
2802860Speter 	if (profile == 0 && table == 0)
2812860Speter 		return;
2822860Speter 	px.ntimes = pxc->ntimes;
2832860Speter 	px.counter = pxc->counter;
2842860Speter 	px.gos = gocnt;
2852860Speter 	px.printed = pxc->printed;
2862860Speter 	return (gocnt != pxc->gos);
2872860Speter }
2882860Speter 
2892860Speter getcnt()
2902860Speter {
2912860Speter 
2922860Speter 	if (profile == 0 && table == 0)
2932860Speter 		return;
2942860Speter 	if (cnts == zcnt)
2952860Speter 		cPANIC();
2962860Speter 	px.counter = cnts;
2972860Speter 	px.ntimes = zbuf[cnts];
2982860Speter 	px.gos = gocnt;
2992860Speter 	px.printed = 0;
3002860Speter 	++cnts;
3012860Speter }
3022860Speter 
3032860Speter unprint()
3042860Speter {
3052860Speter 
3062860Speter 	px.printed = 0;
3072860Speter }
3082860Speter 
3092860Speter /*
3102860Speter  * Control printing of '|'
3112860Speter  * when profiling.
3122860Speter  */
3132860Speter STATIC	char	nobar;
3142860Speter 
3152860Speter baroff()
3162860Speter {
3172860Speter 
3182860Speter 	nobar = 1;
3192860Speter }
3202860Speter 
3212860Speter baron()
3222860Speter {
3232860Speter 
3242860Speter 	nobar = 0;
3252860Speter }
3262860Speter 
3272860Speter /*
3282860Speter  * Do we want cnt and/or '|' on this line ?
3292860Speter  *	1 = count and '|'
3302860Speter  *	0 = only '|'
3312860Speter  *     -1 = spaces only
3322860Speter  */
3332860Speter shudpcnt()
3342860Speter {
3352860Speter 
3362860Speter 	register i;
3372860Speter 
3382860Speter 	if (nobar)
3392860Speter 		return (-1);
3402860Speter 	i = px.printed;
3412860Speter 	px.printed = 1;
3422860Speter 	return (i == 0);
3432860Speter }
3442860Speter 
345*3051Smckusic STATIC	char mism[]	= "Program and counter data do not correspond\n";
3462860Speter 
3472860Speter cPANIC()
3482860Speter {
3492860Speter 
3502860Speter 	printf("cnts %d zcnt %d, lastpf %d zpfcnt %d\n",
3512860Speter 		cnts, zcnt, lastpf, zpfcnt);
3522860Speter 	flush();
3532860Speter 	write(2, mism, sizeof mism);
3542860Speter 	pexit(ERRS);
3552860Speter }
356