|
|
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.