home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / pxp / pmon.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  6KB  |  351 lines

  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.     int    pfline;
  36.     char    *pfname;
  37.     int    pflev;
  38. } *zpf;
  39.  
  40. /*
  41.  * Global variables
  42.  */
  43. STATIC    long *zbuf;     /* Count buffer */
  44. STATIC    int zcnt;    /* Number of counts */
  45. STATIC    int zpfcnt;    /* Number of proc/funcs's */
  46. STATIC    int gcountr;    /* Unique name generator */
  47. STATIC    int zfil;    /* I/o unit for count data reads */
  48. STATIC    int 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.     int 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.     int    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.     int    cnt;
  109. } pxp;
  110.  
  111. getcore(fp)
  112.     char *fp;
  113. {
  114.     int pm;
  115.  
  116.     zfil = open(fp, 0);
  117.     if (zfil < 0) {
  118.         perror(fp);
  119.         pexit(NOSTART);
  120.     }
  121.     if (seek(zfil, 02000, 0) < 0)
  122.         goto format;
  123.     if (read(zfil, &inf, sizeof inf) < 0)
  124.         goto format;
  125.     if (inf.type != 0 && inf.type != 1)
  126.         goto format;
  127.     if (inf.type)
  128.         inf.bp =- inf.off;
  129.     if (seek(zfil, inf.bp + 02000, 0) < 0)
  130.         goto format;
  131.     if (read(zfil, &pxp, sizeof pxp) != sizeof pxp)
  132.         goto format;
  133.     if (pxp.buf == NIL) {
  134.         Perror(fp, "No profile data in file");
  135.         exit(1);
  136.     }
  137.     if (inf.type)
  138.         pxp.buf =- inf.off;
  139.     if (seek(zfil, pxp.buf + 02000, 0) < 0)
  140.         goto format;
  141.     if (pmread() < 0)
  142.         goto format;
  143.     close(zfil);
  144.     return;
  145. format:
  146.     Perror(fp, "Not a Pascal system core file");
  147.     exit(1);
  148. }
  149.  
  150. pmread()
  151. {
  152.     register i;
  153.     register char *cp;
  154.     struct {
  155.         int    no;
  156.         int    no2;
  157.         int    tvec[2];
  158.     } zmagic;
  159.  
  160.     if (read(zfil, &zmagic, sizeof zmagic) != sizeof zmagic)
  161.         return (-1);
  162.     if (zmagic.no != 0426 || zmagic.no2)
  163.         return (-1);
  164.     ptvec[0] = zmagic.tvec[0];
  165.     ptvec[1] = zmagic.tvec[1];
  166.     if (read(zfil, &zcnt, 2) != 2)
  167.         return (-1);
  168.     if (read(zfil, &zpfcnt, 2) != 2)
  169.         return (-1);
  170.     cp = zbuf = alloc(i = zcnt * sizeof *zbuf);
  171.     if (cp == -1)
  172.         pmnospac();
  173.     cp = zpf = alloc(zpfcnt * sizeof *zpf);
  174.     if (cp == -1)
  175.         pmnospac();
  176.     if (read(zfil, zbuf, i) != i)
  177.         return (-1);
  178.     zbuf =- 2;
  179.     return (0);
  180. }
  181.  
  182. cnttab(s, no)
  183.     char *s;
  184.     int no;
  185. {
  186.     register struct pftab *pp;
  187.  
  188.     lastpf++;
  189.     if (table == 0)
  190.         return;
  191.     if (no == zpfcnt)
  192.         cPANIC();
  193.     pp = &zpf[no];
  194.     pp->pfname = s;
  195.     pp->pfline = line;
  196.     pp->pfcnt = nowcnt();
  197.     pp->pflev = cbn;
  198. }
  199.  
  200. prttab()
  201. {
  202.     register i, j;
  203.     register struct pftab *zpfp;
  204.  
  205.     if (profile == 0 && table == 0)
  206.         return;
  207.     if (cnts != zcnt || lastpf != zpfcnt)
  208.         cPANIC();
  209.     if (table == 0)
  210.         return;
  211.     if (profile)
  212.         printf("\f\n");
  213.     header();
  214.     printf("\n\tLine\t   Count\n\n");
  215.     zpfp = zpf;
  216.     for (i = 0; i < zpfcnt; i++) {
  217.         printf("\t%4d\t%8ld\t", zpfp->pfline, zpfp->pfcnt);
  218.         if (!justify)
  219.             for (j = zpfp->pflev * unit; j > 1; j--)
  220.                 putchar(' ');
  221.         printf("%s\n", zpfp->pfname);
  222.         zpfp++;
  223.     }
  224. }
  225.  
  226. nowcntr()
  227. {
  228.  
  229.     return (px.counter);
  230. }
  231.  
  232. long nowcnt()
  233. {
  234.  
  235.     return (px.ntimes);
  236. }
  237.  
  238. long cntof(pxc)
  239.     struct pxcnt *pxc;
  240. {
  241.  
  242.     if (profile == 0 && table == 0)
  243.         return;
  244.     return (pxc->ntimes);
  245. }
  246.  
  247. setcnt(l)
  248.     long l;
  249. {
  250.  
  251.     if (profile == 0 && table == 0)
  252.         return;
  253.     px.counter = --gcountr;
  254.     px.ntimes = l;
  255.     px.gos = gocnt;
  256.     px.printed = 0;
  257. }
  258.  
  259. savecnt(pxc)
  260.     register struct pxcnt *pxc;
  261. {
  262.  
  263.     if (profile == 0 && table == 0)
  264.         return;
  265.     pxc->ntimes = px.ntimes;
  266.     pxc->counter = px.counter;
  267.     pxc->gos = px.gos;
  268.     pxc->printed = 1;
  269. }
  270.  
  271. rescnt(pxc)
  272.     register struct pxcnt *pxc;
  273. {
  274.  
  275.     if (profile == 0 && table == 0)
  276.         return;
  277.     px.ntimes = pxc->ntimes;
  278.     px.counter = pxc->counter;
  279.     px.gos = gocnt;
  280.     px.printed = pxc->printed;
  281.     return (gocnt != pxc->gos);
  282. }
  283.  
  284. getcnt()
  285. {
  286.  
  287.     if (profile == 0 && table == 0)
  288.         return;
  289.     if (cnts == zcnt)
  290.         cPANIC();
  291.     px.counter = cnts;
  292.     px.ntimes = zbuf[cnts];
  293.     px.gos = gocnt;
  294.     px.printed = 0;
  295.     ++cnts;
  296. }
  297.  
  298. unprint()
  299. {
  300.  
  301.     px.printed = 0;
  302. }
  303.  
  304. /*
  305.  * Control printing of '|'
  306.  * when profiling.
  307.  */
  308. STATIC    char    nobar;
  309.  
  310. baroff()
  311. {
  312.  
  313.     nobar = 1;
  314. }
  315.  
  316. baron()
  317. {
  318.  
  319.     nobar = 0;
  320. }
  321.  
  322. /*
  323.  * Do we want cnt and/or '|' on this line ?
  324.  *    1 = count and '|'
  325.  *    0 = only '|'
  326.  *     -1 = spaces only
  327.  */
  328. shudpcnt()
  329. {
  330.  
  331.     register i;
  332.  
  333.     if (nobar)
  334.         return (-1);
  335.     i = px.printed;
  336.     px.printed = 1;
  337.     return (i == 0);
  338. }
  339.  
  340. STATIC    char mism[]    "Program and counter data do not correspond\n";
  341.  
  342. cPANIC()
  343. {
  344.  
  345.     printf("cnts %d zcnt %d, lastpf %d zpfcnt %d\n",
  346.         cnts, zcnt, lastpf, zpfcnt);
  347.     flush();
  348.     write(2, mism, sizeof mism);
  349.     pexit(ERRS);
  350. }
  351.