/* * Print execution profile */ struct nl { char name[8]; int value; float time; /***/ long ncall; }; struct nl nl[600]; struct fnl { char fname[8]; int flag; int fvalue; }; struct cnt { int cvalue; /***/ long cncall; } cbuf[200]; struct inode { int idev; int inum; int flags; char nlink; char uid; char gid; char size0; int size; int ptr[8]; int ctime[2]; int mtime[2]; int fill; }; int ibuf[131]; /***/ int obuf[131]; /***/ int buf[17]; int i; int j; int highpc; int lowpc; int ccnt; int pcl; int pch; int bufs; int nname; double time; double totime; double maxtime; double scale; double lastx; double lasty; struct nl *np; struct nl *npe; int aflg; int vflg; int lflg; int symoff; int symsiz; int vf; int etext; int ncount; main(argc, argv) char **argv; { /***/ register off; char *namfil; int timcmp(), valcmp(); int nf, pf, overlap; /***/ double fnc, lastsx; struct cnt *cp; obuf[0] = 1; argv++; namfil = "a.out"; while (argc>1) { if (**argv == '-') { if (*++*argv == 'l') lflg++; if (**argv == 'a') aflg = 040; if(**argv == 'v') vflg++; } else namfil = *argv; argc--; argv++; } if ((nf = open(namfil, 0)) < 0) { printf("Can't find %s\n", namfil); done(); } /***/ read(nf, buf, 32); if (buf[0] != 0407 && buf[0] != 0410 && buf[0] != 0411) { /* a.out magic */ printf("Bad format: %s\n", namfil); done(); } symsiz = buf[4]; symoff = buf[1] + buf[2]; if (buf[7] != 1) symoff =<< 1; /***/ seek(nf, symoff+32, 0); if ((pf = open("mon.out", 0)) < 0) { printf("No mon.out\n"); done(); } fstat(pf, buf); /***/ read(pf, &lowpc, sizeof lowpc); /***/ read(pf, &highpc, sizeof highpc); /***/ read(pf, &ncount, sizeof ncount); /***/ bufs = buf->size/(sizeof *buf) - (2*ncount+3); /***/ read(pf, cbuf, ncount*sizeof *cbuf); /***/ lowpc = (lowpc>>1); /***/ highpc = (highpc>>1); npe = nl; initf(nf); /***/ for (nname = 0; symsiz > 0; symsiz =- sizeof (struct fnl)) { /***/ for(i=0; i<sizeof (struct fnl); i++) buf->fname[i] = getc(ibuf); if ((buf->flag | aflg) != 042) continue; /***/ buf->fvalue = (buf->fvalue>>1); npe->value = buf->fvalue; for (i=0; i<8; i++) npe->name[i] = buf->fname[i]; npe++; nname++; } if (nname == 0) { printf("No symbols: %s\n", namfil); done(); } /***/ npe->value = 0x7fffffff; npe++; for (cp = cbuf; cp < &cbuf[ncount]; cp++) for (np = nl; np < npe; np++) /***/ if ((off = cp->cvalue-(np->value<<1))>0 && off<32) { /***/ np->ncall = cp->cncall; break; } /***/ qsort(nl, nname, sizeof (struct nl), &valcmp); scale = (highpc-lowpc)/(bufs+0.0); initf(pf); for (i=0; (j = getc(ibuf)) != -1; i++) { ccnt.fname[0] = j; ccnt.fname[1] = getc(ibuf); /***/ ccnt.fname[2] = getc(ibuf); /***/ ccnt.fname[3] = getc(ibuf); if (ccnt == 0) continue; time = ccnt; if (ccnt<0) time =+ 65536.; totime =+ time; if(time > maxtime) maxtime = time; pcl = lowpc + scale*i - 1; pch = lowpc + scale*(i+1) - 1; for (j=0; j<nname; j++) { if (pch < nl[j].value) break; if (pcl >= nl[j+1].value) continue; overlap=(min(pch,nl[j+1].value)-max(pcl,nl[j].value)); nl[j].time =+ overlap*time/scale; } } if (totime==0.0) { printf("No time accumulated\n"); done(); } if(!vflg) goto print; /*** vf = open("/dev/vt0", 1); if(vf < 0) { printf("Cannot open vt\n"); done(); } obuf[0] = vf; vtch(1); vtch(1); vtch(3); point(-2048., -2048.); point(-2048., 2048.); vtch(3); point(0., -2048.); point(0., 2048.); for(j=0; j<9; j++) { vtch(3); point(-2048., 2048. - j*512.); point(0., 2048. - j*512.); } lastx = 0.; lasty = 2048.; scale = 4096./(i+2); seek(pf, 3*sizeof(*buf) + ncount*sizeof(*cbuf), 0); initf(pf); lastsx = 0.0; while((j = getc(ibuf)) != -1) { ccnt.fname[0] = j; ccnt.fname[1] = getc(ibuf); time = ccnt; if(ccnt < 0) time =+ 65536.; vtch(3); point(lastsx, lasty); lastsx =- 2000.*time/totime; point(lastsx, lasty-scale); if (ccnt!=0 || lastx!=0.0) { vtch(3); point(lastx, lasty); lastx = -time*2000./maxtime; point(lastx, lasty); } lasty =- scale; } scale = 4096./(highpc-lowpc); lastx = 50.; for(np = nl; np<npe; np++) { if(np->value < lowpc) continue; if(np->value >= highpc) continue; time = np->time/totime; lasty = 2048. - (np->value - lowpc)*scale; vtch(3); point(0., lasty); point(50., lasty); vtch(3); point(lastx-50., lasty); point(lastx, lasty); vtch(9); point(lastx+10., lasty+60.); vtch(1); vtch(3); for(j=0; j<8; j++) if(np->name[j] != '_') vtch(np->name[j]); vtch(0); lastx =+ 500.; if(lastx > 2000.) lastx = 50.; } done(); ***/ print: printf(" name %%time #call ms/call\n"); if (!lflg) /***/ qsort(nl, nname, sizeof (struct nl), &timcmp); for (np = nl; np<npe-1; np++) { time = np->time/totime; printf("%8.8s%6.1f", np->name, 100*time); /***/ fnc = np->ncall; if (fnc != 0.0) { /***/ printf("%6d", np->ncall); printf(" %7.2f\n", np->time/(fnc*.06)); } else printf("\n"); } done(); } min(a, b) { if (a<b) return(a); return(b); } max(a, b) { if (a>b) return(a); return(b); } valcmp(p1, p2) struct nl *p1, *p2; { return(p1->value - p2->value); } timcmp(p1, p2) struct nl *p1, *p2; { float d; /*** d = p2->time - p1->time; ***/ d = p2->time; d =- p1->time; if (d > 0.0) return(1); if (d < 0.0) return(-1); return(0); } vtch(c) int c; { putchar(c&0377); } point(x, y) float x, y; { point1(x); point1(y); } putchar(c) { putc(c, obuf); } point1(xy) float xy; { int ixy; struct { char b1; char b2;}; if(xy > 2047.) xy = 2047.; if(xy < -2048.) xy = -2048.; ixy = xy; vtch(ixy.b1); vtch(ixy.b2); } done() { fflush(obuf); exit(); } initf(f) { ibuf[0] = f; ibuf[1] = 0; ibuf[2] = 0; ibuf[3] = 0; }