BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Sat, 20 Oct 1979 11:51:40 +0000 (03:51 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Sat, 20 Oct 1979 11:51:40 +0000 (03:51 -0800)
Work on file usr/src/cmd/pxp/pmon.c

Synthesized-from: 3bsd

usr/src/cmd/pxp/pmon.c [new file with mode: 0644]

diff --git a/usr/src/cmd/pxp/pmon.c b/usr/src/cmd/pxp/pmon.c
new file mode 100644 (file)
index 0000000..31ef728
--- /dev/null
@@ -0,0 +1,354 @@
+/* Copyright (c) 1979 Regents of the University of California */
+#
+/*
+ * pxp - Pascal execution profiler
+ *
+ * Bill Joy UCB
+ * Version 1.2 January 1979
+ */
+
+#include "0.h"
+
+/*
+ * Profile counter processing cluster
+ *
+ * This file contains all routines which do the hard work in profiling.
+ *
+ * The first group of routines (getit, getpmon, getcore, and pmread)
+ * deal with extracting data from the pmon.out and (with more difficulty)
+ * core files.
+ *
+ * The routines cnttab and prttab collect counters for
+ * and print the summary table respectively.
+ *
+ * The routines "*cnt*" deal with manipulation of counters,
+ * especially the "current" counter px.
+ */
+STATIC struct pxcnt px;
+
+/*
+ * Table to record info
+ * for procedure/function summary
+ */
+STATIC struct pftab {
+       long    pfcnt;
+       short   pfline;
+       char    *pfname;
+       short   pflev;
+} *zpf;
+
+/*
+ * Global variables
+ */
+STATIC long *zbuf;     /* Count buffer */
+STATIC short zcnt;     /* Number of counts */
+STATIC short zpfcnt;   /* Number of proc/funcs's */
+STATIC short gcountr;  /* Unique name generator */
+STATIC short zfil;     /* I/o unit for count data reads */
+STATIC short lastpf;   /* Total # of procs and funcs for consistency chk */
+
+getit(fp)
+       register char *fp;
+{
+
+       if (core)
+               getcore(fp);
+       else
+               getpmon(fp);
+}
+
+/*
+ * Setup monitor data buffer from pmon.out
+ * style file whose name is fp.
+ */
+getpmon(fp)
+       char *fp;
+{
+       register char *cp;
+       short garbage;
+
+       zfil = open(fp, 0);
+       if (zfil < 0) {
+               perror(fp);
+               pexit(NOSTART);
+       }
+       if (pmread() < 0 || read(zfil, &garbage, 1) == 1) {
+               Perror(fp, "Bad format for pmon.out style file");
+               exit(1);
+       }
+       close(zfil);
+       return;
+}
+
+STATIC char nospcm[]   "Not enough memory for count buffers\n";
+
+pmnospac()
+{
+
+       write(2, nospcm, sizeof nospcm);
+       pexit(NOSTART);
+}
+
+/*
+ * Structure of the first few
+ * items of a px core dump.
+ */
+STATIC struct info {
+       char    *off;           /* Self-reference for pure text */
+       short   type;           /* 0 = non-pure text, 1 = pure text */
+       char    *bp;            /* Core address of pxps struct */
+} inf;
+
+/*
+ * First few words of the px
+ * information structure.
+ */
+STATIC struct pxps {
+       char    *buf;
+       short   cnt;
+} pxp;
+
+getcore(fp)
+       char *fp;
+{
+
+       write(2, "-c: option not supported\n", sizeof("-c: option not supported\n"));
+       pexit(ERRS);
+/*
+       short pm;
+
+       zfil = open(fp, 0);
+       if (zfil < 0) {
+               perror(fp);
+               pexit(NOSTART);
+       }
+       if (lseek(zfil, 02000, 0) < 0)
+               goto format;
+       if (read(zfil, &inf, sizeof inf) < 0)
+               goto format;
+       if (inf.type != 0 && inf.type != 1)
+               goto format;
+       if (inf.type)
+               inf.bp =- inf.off;
+       if (lseek(zfil, inf.bp + 02000, 0) < 0)
+               goto format;
+       if (read(zfil, &pxp, sizeof pxp) != sizeof pxp)
+               goto format;
+       if (pxp.buf == NIL) {
+               Perror(fp, "No profile data in file");
+               exit(1);
+       }
+       if (inf.type)
+               pxp.buf =- inf.off;
+       if (lseek(zfil, pxp.buf + 02000, 0) < 0)
+               goto format;
+       if (pmread() < 0)
+               goto format;
+       close(zfil);
+       return;
+format:
+       Perror(fp, "Not a Pascal system core file");
+       exit(1);
+*/
+}
+
+pmread()
+{
+       register i;
+       register char *cp;
+       struct {
+               short   no;
+               short   no2;
+               long    tvec;
+       } zmagic;
+
+       if (read(zfil, &zmagic, sizeof zmagic) != sizeof zmagic)
+               return (-1);
+       if (zmagic.no != 0426 || zmagic.no2)
+               return (-1);
+       ptvec = zmagic.tvec;
+       if (read(zfil, &zcnt, 2) != 2)
+               return (-1);
+       if (read(zfil, &zpfcnt, 2) != 2)
+               return (-1);
+       cp = zbuf = alloc(i = zcnt * sizeof *zbuf);
+       if (cp == -1)
+               pmnospac();
+       cp = zpf = alloc(zpfcnt * sizeof *zpf);
+       if (cp == -1)
+               pmnospac();
+       if (read(zfil, zbuf, i) != i)
+               return (-1);
+       zbuf =- 2;
+       return (0);
+}
+
+cnttab(s, no)
+       char *s;
+       short no;
+{
+       register struct pftab *pp;
+
+       lastpf++;
+       if (table == 0)
+               return;
+       if (no == zpfcnt)
+               cPANIC();
+       pp = &zpf[no];
+       pp->pfname = s;
+       pp->pfline = line;
+       pp->pfcnt = nowcnt();
+       pp->pflev = cbn;
+}
+
+prttab()
+{
+       register i, j;
+       register struct pftab *zpfp;
+
+       if (profile == 0 && table == 0)
+               return;
+       if (cnts != zcnt || lastpf != zpfcnt)
+               cPANIC();
+       if (table == 0)
+               return;
+       if (profile)
+               printf("\f\n");
+       header();
+       printf("\n\tLine\t   Count\n\n");
+       zpfp = zpf;
+       for (i = 0; i < zpfcnt; i++) {
+               printf("\t%4d\t%8ld\t", zpfp->pfline, zpfp->pfcnt);
+               if (!justify)
+                       for (j = zpfp->pflev * unit; j > 1; j--)
+                               putchar(' ');
+               printf("%s\n", zpfp->pfname);
+               zpfp++;
+       }
+}
+
+nowcntr()
+{
+
+       return (px.counter);
+}
+
+long nowcnt()
+{
+
+       return (px.ntimes);
+}
+
+long cntof(pxc)
+       struct pxcnt *pxc;
+{
+
+       if (profile == 0 && table == 0)
+               return;
+       return (pxc->ntimes);
+}
+
+setcnt(l)
+       long l;
+{
+
+       if (profile == 0 && table == 0)
+               return;
+       px.counter = --gcountr;
+       px.ntimes = l;
+       px.gos = gocnt;
+       px.printed = 0;
+}
+
+savecnt(pxc)
+       register struct pxcnt *pxc;
+{
+
+       if (profile == 0 && table == 0)
+               return;
+       pxc->ntimes = px.ntimes;
+       pxc->counter = px.counter;
+       pxc->gos = px.gos;
+       pxc->printed = 1;
+}
+
+rescnt(pxc)
+       register struct pxcnt *pxc;
+{
+
+       if (profile == 0 && table == 0)
+               return;
+       px.ntimes = pxc->ntimes;
+       px.counter = pxc->counter;
+       px.gos = gocnt;
+       px.printed = pxc->printed;
+       return (gocnt != pxc->gos);
+}
+
+getcnt()
+{
+
+       if (profile == 0 && table == 0)
+               return;
+       if (cnts == zcnt)
+               cPANIC();
+       px.counter = cnts;
+       px.ntimes = zbuf[cnts];
+       px.gos = gocnt;
+       px.printed = 0;
+       ++cnts;
+}
+
+unprint()
+{
+
+       px.printed = 0;
+}
+
+/*
+ * Control printing of '|'
+ * when profiling.
+ */
+STATIC char    nobar;
+
+baroff()
+{
+
+       nobar = 1;
+}
+
+baron()
+{
+
+       nobar = 0;
+}
+
+/*
+ * Do we want cnt and/or '|' on this line ?
+ *     1 = count and '|'
+ *     0 = only '|'
+ *     -1 = spaces only
+ */
+shudpcnt()
+{
+
+       register i;
+
+       if (nobar)
+               return (-1);
+       i = px.printed;
+       px.printed = 1;
+       return (i == 0);
+}
+
+STATIC char mism[]     "Program and counter data do not correspond\n";
+
+cPANIC()
+{
+
+       printf("cnts %d zcnt %d, lastpf %d zpfcnt %d\n",
+               cnts, zcnt, lastpf, zpfcnt);
+       flush();
+       write(2, mism, sizeof mism);
+       pexit(ERRS);
+}