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