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: }