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