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