|
|
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.