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