home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / prof.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  5.8 KB  |  310 lines

  1. /*
  2.  *  Print execution profile
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <a.out.h>
  9.  
  10. typedef    short UNIT;        /* unit of profiling */
  11.  
  12. struct stat stbuf;
  13. struct    nl {
  14.     char    name[8];
  15.     unsigned value;
  16.     float    time;
  17.     long    ncall;
  18. };
  19.  
  20. struct hdr {
  21.     UNIT    *lowpc;
  22.     UNIT    *highpc;
  23.     int    ncount;
  24. };
  25.  
  26. struct nl nl[1200];
  27.  
  28. struct cnt {
  29.     unsigned cvalue;
  30.     long    cncall;
  31. } cbuf[350];
  32.  
  33. FILE    *pfile, *nfile;
  34. unsigned highpc;
  35. unsigned lowpc;
  36. double    ransca;
  37. double    ranoff;
  38. unsigned pcl;
  39. unsigned pch;
  40. unsigned bufs;
  41. int    nname;
  42. double    ftime;
  43. double    actime;
  44. double    totime;
  45. double    maxtime;
  46. double    scale;
  47. double    lastx;
  48. double    lasty;
  49. struct nl *np;
  50. struct nl *npe;
  51. int    aflg;
  52. int    vflg;
  53. int    lflg;
  54. long    symoff;
  55.  
  56. main(argc, argv)
  57. char **argv;
  58. {
  59.     char *namfil;
  60.     int timcmp(), valcmp();
  61.     int i, overlap;
  62.     long pfpos;
  63.     double lastsx;
  64.     struct cnt *cp;
  65.     double tx, ty;
  66.     struct exec xbuf;
  67.     struct hdr h;
  68.  
  69.     lowpc = -1;
  70.     highpc = -1;
  71.     argv++;
  72.     namfil = "a.out";
  73.     while (argc>1) {
  74.         if (**argv == '-') {
  75.             if (*++*argv == 'l')
  76.                 lflg++;
  77.             if (**argv == 'a')
  78.                 aflg = 040;
  79.             if(**argv == 'v')
  80.                 vflg++;
  81.             if(**argv >= '0' && **argv <= '9') {
  82.                 i = atoi(*argv);
  83.                 if(lowpc == -1)
  84.                     lowpc = i;
  85.                 else
  86.                     highpc = i;
  87.             }
  88.         } else
  89.             namfil = *argv;
  90.         argc--;
  91.         argv++;
  92.     }
  93.     if (lowpc >= 100)
  94.         lowpc = 0;
  95.     if(highpc <= lowpc || highpc > 100)
  96.         highpc = 100;
  97.     ransca = 100./(highpc-lowpc);
  98.     ranoff = 2040. + 40.8*lowpc*ransca;
  99.     if((nfile=fopen(namfil,"r"))==NULL) {
  100.         fprintf(stderr, "%s: not found\n", namfil);
  101.         done();
  102.     }
  103.     fread((char *)&xbuf, 1, sizeof(xbuf), nfile);
  104.     if (xbuf.a_magic!=A_MAGIC1 && xbuf.a_magic!=A_MAGIC2 && xbuf.a_magic!=A_MAGIC3) {
  105.         fprintf(stderr, "%s: bad format\n", namfil);
  106.         done();
  107.     }
  108.     symoff = (long)xbuf.a_text + xbuf.a_data;
  109.     if ((xbuf.a_flag&01) == 0)
  110.         symoff *= 2;
  111.     fseek(nfile, symoff+sizeof(xbuf), 0);
  112.     if((pfile = fopen("mon.out","r")) == NULL) {
  113.         fprintf(stderr, "No mon.out\n");
  114.         done();
  115.     }
  116.     fstat(fileno(pfile), &stbuf);
  117.     fread((char *)&h, sizeof(struct hdr), 1, pfile);
  118.     lowpc = h.lowpc - (UNIT *)0;
  119.     highpc = h.highpc - (UNIT *)0;
  120.     bufs = stbuf.st_size - sizeof(struct hdr) - h.ncount*sizeof(struct cnt);
  121.     fread((char *)cbuf, sizeof(struct cnt), h.ncount, pfile);
  122.     pfpos = ftell(pfile);
  123.     npe = nl;
  124.     for (nname = 0; xbuf.a_syms > 0; xbuf.a_syms -= sizeof(struct nlist)) {
  125.         struct nlist nbuf;
  126.         fread((char *)&nbuf, sizeof(nbuf), 1, nfile);
  127.         if (nbuf.n_type!=N_TEXT && nbuf.n_type!=N_TEXT+N_EXT)
  128.             continue;
  129.         if (aflg==0 && nbuf.n_type!=N_TEXT+N_EXT)
  130.             continue;
  131.         npe->value = nbuf.n_value/sizeof(UNIT);
  132.         for (i=0; i<8; i++)
  133.             npe->name[i] = nbuf.n_name[i];
  134.         npe++;
  135.         nname++;
  136.     }
  137.     if (nname == 0) {
  138.         fprintf(stderr, "%s: no symbols\n", namfil);
  139.         done();
  140.     }
  141.     npe->value = -1;
  142.     npe++;
  143.     for (cp = cbuf; cp < &cbuf[h.ncount]; cp++)
  144.         for (np = nl; np < npe; np++)
  145.             if ((unsigned)(cp->cvalue/sizeof(UNIT) - np->value) <=10) {
  146.                 np->ncall = cp->cncall;
  147.                 break;
  148.             }
  149.     qsort(nl, nname, sizeof(struct nl), valcmp);
  150.     scale = highpc - lowpc;
  151.     scale /= bufs/sizeof(UNIT);
  152.     for(i=0;;i++) {
  153.         register j;
  154.         unsigned UNIT ccnt;
  155.         fread((char *)&ccnt, sizeof(ccnt), 1, pfile);
  156.         if(feof(pfile))
  157.             break;
  158.         if (ccnt == 0)
  159.             continue;
  160.         pcl = lowpc + scale*i;
  161.         pch = lowpc + scale*(i+1);
  162.         ftime = ccnt;
  163.         totime += ftime;
  164.         if(ftime > maxtime)
  165.             maxtime = ftime;
  166.         for (j=0; j<nname; j++) {
  167.             if (pch < nl[j].value)
  168.                 break;
  169.             if (pcl >= nl[j+1].value)
  170.                 continue;
  171.             overlap=(min(pch,nl[j+1].value)-max(pcl,nl[j].value));
  172.             nl[j].time += overlap*ftime/scale;
  173.         }
  174.     }
  175.     if (totime==0.0) {
  176.         fprintf(stderr, "No time accumulated\n");
  177.         done();
  178.     }
  179. #ifdef plot
  180.     if(!vflg)
  181.         goto print;
  182.     openpl();
  183.     erase();
  184.     space(-2048, -2048, 2048, 2048);
  185.     line(-2040, -2040, -2040, 2040);
  186.     line(0, 2040, 0, -2040);
  187.     for(i=0; i<11; i++)
  188.         line(-2040, 2040-i*408, 0, 2040-i*408);
  189.     lastx = 0.;
  190.     lasty = ranoff;
  191.     scale = (4080.*ransca)/(bufs/sizeof(UNIT));
  192.     fclose(pfile);    /*to turn off eof*/
  193.     pfile = fopen("mon.out", "r");
  194.     fseek(pfile, pfpos, 0);
  195.     lastsx = 0.0;
  196.     for(;;) {
  197.         unsigned UNIT ccnt;
  198.         fread((char *)&ccnt, sizeof(ccnt), 1, pfile);
  199.         if(feof(pfile))
  200.             break;
  201.         ftime = ccnt;
  202.         tx = lastsx;
  203.         ty = lasty;
  204.         lastsx -= 2000.*ftime/totime;
  205.         lasty -= scale;
  206.         if(lasty >= -2040. && ty <= 2040.) {
  207.             line((int)tx, (int)ty, (int)lastsx, (int)lasty);
  208.             if (ccnt!=0 || lastx!=0.0) {
  209.                 tx = lastx;
  210.                 lastx = -ftime*2000./maxtime;
  211.                 ty += scale/2;
  212.                 line(0, (int)ty, (int)tx, (int)ty);
  213.             }
  214.         }
  215.     }
  216.     scale = (4080.*ransca)/(highpc-lowpc);
  217.     lastx = 50.;
  218.     for(np = nl; np<npe;  np++) {
  219.         if(np->value < lowpc)
  220.             continue;
  221.         if(np->value >= highpc)
  222.             continue;
  223.         ftime = np->time/totime;
  224.         lasty = ranoff - (np->value - lowpc)*scale;
  225.         if(lasty >= -2040. && lasty <= 2040.) {
  226.             char bufl[8+3], *namp;
  227.             register j;
  228.             line(0, (int)lasty, 50, (int)lasty);
  229.             line((int)(lastx-50),(int)lasty,(int)lastx,(int)lasty);
  230.             point((int)(lastx+30), (int)(lasty+10));
  231.             namp = bufl;
  232.             for(j=0; j<8; j++)
  233.                 if(np->name[j] != '_')
  234.                     *namp++ = np->name[j];
  235.             *namp++ = '\n';
  236.             *namp++ = 0;
  237.             label(bufl);
  238.         }
  239.         lastx += 500.;
  240.         if(lastx > 2000.)
  241.             lastx = 50.;
  242.     }
  243.     done();
  244.  
  245. print:
  246. #endif
  247.     actime = 0;
  248.     printf("    name %%time  cumsecs  #call  ms/call\n");
  249.     if (!lflg)
  250.         qsort(nl, nname, sizeof(struct nl), timcmp);
  251.     for (np = nl; np<npe-1; np++) {
  252.         ftime = np->time/totime;
  253.         actime += np->time;
  254.         printf("%8.8s%6.1f%9.2f", np->name, 100*ftime, actime/60);
  255.         if(np->ncall!=0) {
  256.             printf("%6ld", np->ncall);
  257.             printf(" %7.2f\n", np->time/(np->ncall*.06));
  258.         } else
  259.             printf("\n");
  260.     }
  261.     done();
  262. }
  263.  
  264. min(a, b)
  265. unsigned a, b;
  266. {
  267.     if (a<b)
  268.         return(a);
  269.     return(b);
  270. }
  271.  
  272. max(a, b)
  273. unsigned a, b;
  274. {
  275.     if (a>b)
  276.         return(a);
  277.     return(b);
  278. }
  279.  
  280. valcmp(p1, p2)
  281. struct nl *p1, *p2;
  282. {
  283.     return(p1->value - p2->value);
  284. }
  285.  
  286. timcmp(p1, p2)
  287. struct nl *p1, *p2;
  288. {
  289.     float d;
  290.  
  291.     d = p2->time - p1->time;
  292.     if (d > 0.0)
  293.         return(1);
  294.     if (d < 0.0)
  295.         return(-1);
  296.     return(0);
  297. }
  298.  
  299. done()
  300. {
  301.  
  302. #ifdef plot
  303.     if(vflg) {
  304.         point(0, -2040);
  305.         closepl();
  306.     }
  307. #endif
  308.     exit(0);
  309. }
  310.