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