Annotation of src/usr.bin/gprof/printgprof.c, Revision 1.3
1.3 ! mickey 1: /* $OpenBSD: printgprof.c,v 1.2 1996/06/26 05:33:59 deraadt Exp $ */
1.1 deraadt 2: /* $NetBSD: printgprof.c,v 1.5 1995/04/19 07:16:21 cgd Exp $ */
3:
4: /*
5: * Copyright (c) 1983, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: #if 0
39: static char sccsid[] = "@(#)printgprof.c 8.1 (Berkeley) 6/6/93";
40: #else
1.3 ! mickey 41: static char rcsid[] = "$OpenBSD: printgprof.c,v 1.2 1996/06/26 05:33:59 deraadt Exp $";
1.1 deraadt 42: #endif
43: #endif /* not lint */
44:
45: #include "gprof.h"
46: #include "pathnames.h"
47:
1.3 ! mickey 48: void
1.1 deraadt 49: printprof()
50: {
51: register nltype *np;
52: nltype **sortednlp;
1.3 ! mickey 53: int index;
1.1 deraadt 54:
55: actime = 0.0;
56: printf( "\f\n" );
57: flatprofheader();
58: /*
59: * Sort the symbol table in by time
60: */
61: sortednlp = (nltype **) calloc( nname , sizeof(nltype *) );
1.3 ! mickey 62: if ( sortednlp == (nltype **) 0 )
! 63: warnx("[printprof] ran out of memory for time sorting");
1.1 deraadt 64: for ( index = 0 ; index < nname ; index += 1 ) {
65: sortednlp[ index ] = &nl[ index ];
66: }
67: qsort( sortednlp , nname , sizeof(nltype *) , timecmp );
68: for ( index = 0 ; index < nname ; index += 1 ) {
69: np = sortednlp[ index ];
70: flatprofline( np );
71: }
72: actime = 0.0;
73: free( sortednlp );
74: }
75:
1.3 ! mickey 76: int
1.1 deraadt 77: timecmp( npp1 , npp2 )
78: nltype **npp1, **npp2;
79: {
80: double timediff;
81: long calldiff;
82:
83: timediff = (*npp2) -> time - (*npp1) -> time;
84: if ( timediff > 0.0 )
85: return 1 ;
86: if ( timediff < 0.0 )
87: return -1;
88: calldiff = (*npp2) -> ncall - (*npp1) -> ncall;
89: if ( calldiff > 0 )
90: return 1;
91: if ( calldiff < 0 )
92: return -1;
93: return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
94: }
95:
96: /*
97: * header for flatprofline
98: */
1.3 ! mickey 99: void
1.1 deraadt 100: flatprofheader()
101: {
102:
1.3 ! mickey 103: if (bflag)
1.1 deraadt 104: printblurb( _PATH_FLAT_BLURB );
1.3 ! mickey 105: printf("\ngranularity: each sample hit covers %ld byte(s)",
! 106: (long) scale * sizeof(UNIT));
! 107: if (totime > 0.0)
! 108: printf(" for %.2f%% of %.2f seconds\n\n" , 100.0/totime, totime / hz);
! 109: else {
1.1 deraadt 110: printf( " no time accumulated\n\n" );
111: /*
112: * this doesn't hurt sinc eall the numerators will be zero.
113: */
114: totime = 1.0;
115: }
1.3 ! mickey 116: printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
! 117: "% " , "cumulative" , "self " , "" , "self " , "total " , "" );
! 118: printf("%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
! 119: "time" , "seconds " , "seconds" , "calls" ,
! 120: "ms/call" , "ms/call" , "name" );
1.1 deraadt 121: }
122:
1.3 ! mickey 123: void
1.1 deraadt 124: flatprofline( np )
125: register nltype *np;
126: {
127:
128: if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) {
129: return;
130: }
131: actime += np -> time;
132: printf( "%5.1f %10.2f %8.2f" ,
133: 100 * np -> time / totime , actime / hz , np -> time / hz );
134: if ( np -> ncall != 0 ) {
1.3 ! mickey 135: printf( " %8ld %8.2f %8.2f " , np -> ncall ,
1.1 deraadt 136: 1000 * np -> time / hz / np -> ncall ,
137: 1000 * ( np -> time + np -> childtime ) / hz / np -> ncall );
138: } else {
139: printf( " %8.8s %8.8s %8.8s " , "" , "" , "" );
140: }
141: printname( np );
142: printf( "\n" );
143: }
144:
1.3 ! mickey 145: void
1.1 deraadt 146: gprofheader()
147: {
148:
149: if ( bflag ) {
150: printblurb( _PATH_CALLG_BLURB );
151: }
1.3 ! mickey 152: printf( "\ngranularity: each sample hit covers %ld byte(s)" ,
1.1 deraadt 153: (long) scale * sizeof(UNIT) );
154: if ( printtime > 0.0 ) {
155: printf( " for %.2f%% of %.2f seconds\n\n" ,
156: 100.0/printtime , printtime / hz );
157: } else {
158: printf( " no time propagated\n\n" );
159: /*
160: * this doesn't hurt, since all the numerators will be 0.0
161: */
162: printtime = 1.0;
163: }
164: printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
165: "" , "" , "" , "" , "called" , "total" , "parents");
166: printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
167: "index" , "%time" , "self" , "descendents" ,
168: "called" , "self" , "name" , "index" );
169: printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
170: "" , "" , "" , "" , "called" , "total" , "children");
171: printf( "\n" );
172: }
173:
1.3 ! mickey 174: void
1.1 deraadt 175: gprofline( np )
176: register nltype *np;
177: {
178: char kirkbuffer[ BUFSIZ ];
179:
180: sprintf( kirkbuffer , "[%d]" , np -> index );
1.3 ! mickey 181: printf( "%-6.6s %5.1f %7.2f %11.2f" , kirkbuffer ,
1.1 deraadt 182: 100 * ( np -> propself + np -> propchild ) / printtime ,
1.3 ! mickey 183: np -> propself / hz , np -> propchild / hz );
1.1 deraadt 184: if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
1.3 ! mickey 185: printf( " %7ld" , np -> npropcall );
1.1 deraadt 186: if ( np -> selfcalls != 0 ) {
1.3 ! mickey 187: printf( "+%-7ld " , np -> selfcalls );
1.1 deraadt 188: } else {
189: printf( " %7.7s " , "" );
190: }
191: } else {
192: printf( " %7.7s %7.7s " , "" , "" );
193: }
194: printname( np );
195: printf( "\n" );
196: }
197:
1.3 ! mickey 198: void
1.1 deraadt 199: printgprof(timesortnlp)
200: nltype **timesortnlp;
201: {
202: int index;
203: nltype *parentp;
204:
205: /*
206: * Print out the structured profiling list
207: */
208: gprofheader();
209: for ( index = 0 ; index < nname + ncycle ; index ++ ) {
210: parentp = timesortnlp[ index ];
211: if ( zflag == 0 &&
212: parentp -> ncall == 0 &&
213: parentp -> selfcalls == 0 &&
214: parentp -> propself == 0 &&
215: parentp -> propchild == 0 ) {
216: continue;
217: }
218: if ( ! parentp -> printflag ) {
219: continue;
220: }
221: if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
222: /*
223: * cycle header
224: */
225: printcycle( parentp );
226: printmembers( parentp );
227: } else {
228: printparents( parentp );
229: gprofline( parentp );
230: printchildren( parentp );
231: }
232: printf( "\n" );
233: printf( "-----------------------------------------------\n" );
234: printf( "\n" );
235: }
236: free( timesortnlp );
237: }
238:
239: /*
240: * sort by decreasing propagated time
241: * if times are equal, but one is a cycle header,
242: * say that's first (e.g. less, i.e. -1).
243: * if one's name doesn't have an underscore and the other does,
244: * say the one is first.
245: * all else being equal, sort by names.
246: */
247: int
248: totalcmp( npp1 , npp2 )
249: nltype **npp1;
250: nltype **npp2;
251: {
252: register nltype *np1 = *npp1;
253: register nltype *np2 = *npp2;
254: double diff;
255:
256: diff = ( np1 -> propself + np1 -> propchild )
257: - ( np2 -> propself + np2 -> propchild );
258: if ( diff < 0.0 )
259: return 1;
260: if ( diff > 0.0 )
261: return -1;
262: if ( np1 -> name == 0 && np1 -> cycleno != 0 )
263: return -1;
264: if ( np2 -> name == 0 && np2 -> cycleno != 0 )
265: return 1;
266: if ( np1 -> name == 0 )
267: return -1;
268: if ( np2 -> name == 0 )
269: return 1;
270: if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' )
271: return -1;
272: if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' )
273: return 1;
274: if ( np1 -> ncall > np2 -> ncall )
275: return -1;
276: if ( np1 -> ncall < np2 -> ncall )
277: return 1;
278: return strcmp( np1 -> name , np2 -> name );
279: }
280:
1.3 ! mickey 281: void
1.1 deraadt 282: printparents( childp )
283: nltype *childp;
284: {
285: nltype *parentp;
286: arctype *arcp;
287: nltype *cycleheadp;
288:
289: if ( childp -> cyclehead != 0 ) {
290: cycleheadp = childp -> cyclehead;
291: } else {
292: cycleheadp = childp;
293: }
294: if ( childp -> parents == 0 ) {
295: printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" ,
296: "" , "" , "" , "" , "" , "" );
297: return;
298: }
299: sortparents( childp );
300: for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
301: parentp = arcp -> arc_parentp;
302: if ( childp == parentp || ( arcp -> arc_flags & DEADARC ) ||
303: ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
304: /*
305: * selfcall or call among siblings
306: */
1.3 ! mickey 307: printf( "%6.6s %5.5s %7.7s %11.11s %7ld %7.7s " ,
1.1 deraadt 308: "" , "" , "" , "" ,
309: arcp -> arc_count , "" );
310: printname( parentp );
311: printf( "\n" );
312: } else {
313: /*
314: * regular parent of child
315: */
1.3 ! mickey 316: printf( "%6.6s %5.5s %7.2f %11.2f %7ld/%-7ld " ,
1.1 deraadt 317: "" , "" ,
318: arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
319: arcp -> arc_count , cycleheadp -> npropcall );
320: printname( parentp );
321: printf( "\n" );
322: }
323: }
324: }
325:
1.3 ! mickey 326: void
1.1 deraadt 327: printchildren( parentp )
328: nltype *parentp;
329: {
330: nltype *childp;
331: arctype *arcp;
332:
333: sortchildren( parentp );
334: arcp = parentp -> children;
335: for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
336: childp = arcp -> arc_childp;
337: if ( childp == parentp || ( arcp -> arc_flags & DEADARC ) ||
338: ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
339: /*
340: * self call or call to sibling
341: */
1.3 ! mickey 342: printf( "%6.6s %5.5s %7.7s %11.11s %7ld %7.7s " ,
1.1 deraadt 343: "" , "" , "" , "" , arcp -> arc_count , "" );
344: printname( childp );
345: printf( "\n" );
346: } else {
347: /*
348: * regular child of parent
349: */
1.3 ! mickey 350: printf( "%6.6s %5.5s %7.2f %11.2f %7ld/%-7ld " ,
1.1 deraadt 351: "" , "" ,
352: arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
353: arcp -> arc_count , childp -> cyclehead -> npropcall );
354: printname( childp );
355: printf( "\n" );
356: }
357: }
358: }
359:
1.3 ! mickey 360: void
1.1 deraadt 361: printname( selfp )
362: nltype *selfp;
363: {
364:
365: if ( selfp -> name != 0 ) {
366: printf( "%s" , selfp -> name );
367: # ifdef DEBUG
368: if ( debug & DFNDEBUG ) {
369: printf( "{%d} " , selfp -> toporder );
370: }
371: if ( debug & PROPDEBUG ) {
372: printf( "%5.2f%% " , selfp -> propfraction );
373: }
374: # endif DEBUG
375: }
376: if ( selfp -> cycleno != 0 ) {
377: printf( " <cycle %d>" , selfp -> cycleno );
378: }
379: if ( selfp -> index != 0 ) {
380: if ( selfp -> printflag ) {
381: printf( " [%d]" , selfp -> index );
382: } else {
383: printf( " (%d)" , selfp -> index );
384: }
385: }
386: }
387:
1.3 ! mickey 388: void
1.1 deraadt 389: sortchildren( parentp )
390: nltype *parentp;
391: {
392: arctype *arcp;
393: arctype *detachedp;
394: arctype sorted;
395: arctype *prevp;
396:
397: /*
398: * unlink children from parent,
399: * then insertion sort back on to sorted's children.
400: * *arcp the arc you have detached and are inserting.
401: * *detachedp the rest of the arcs to be sorted.
402: * sorted arc list onto which you insertion sort.
403: * *prevp arc before the arc you are comparing.
404: */
405: sorted.arc_childlist = 0;
1.3 ! mickey 406: for ( arcp = parentp -> children, detachedp = arcp -> arc_childlist;
1.1 deraadt 407: arcp ;
1.3 ! mickey 408: arcp = detachedp, detachedp = detachedp -> arc_childlist) {
1.1 deraadt 409: /*
410: * consider *arcp as disconnected
411: * insert it into sorted
412: */
413: for ( prevp = &sorted ;
414: prevp -> arc_childlist ;
415: prevp = prevp -> arc_childlist ) {
416: if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
417: break;
418: }
419: }
420: arcp -> arc_childlist = prevp -> arc_childlist;
421: prevp -> arc_childlist = arcp;
422: }
423: /*
424: * reattach sorted children to parent
425: */
426: parentp -> children = sorted.arc_childlist;
427: }
428:
1.3 ! mickey 429: void
1.1 deraadt 430: sortparents( childp )
431: nltype *childp;
432: {
433: arctype *arcp;
434: arctype *detachedp;
435: arctype sorted;
436: arctype *prevp;
437:
438: /*
439: * unlink parents from child,
440: * then insertion sort back on to sorted's parents.
441: * *arcp the arc you have detached and are inserting.
442: * *detachedp the rest of the arcs to be sorted.
443: * sorted arc list onto which you insertion sort.
444: * *prevp arc before the arc you are comparing.
445: */
446: sorted.arc_parentlist = 0;
1.3 ! mickey 447: for (arcp = childp->parents, detachedp = arcp->arc_parentlist;
! 448: arcp; arcp = detachedp, detachedp = detachedp->arc_parentlist) {
1.1 deraadt 449: /*
450: * consider *arcp as disconnected
451: * insert it into sorted
452: */
1.3 ! mickey 453: for (prevp = &sorted; prevp->arc_parentlist;
! 454: prevp = prevp->arc_parentlist)
! 455: if (arccmp(arcp , prevp->arc_parentlist) != GREATERTHAN)
1.1 deraadt 456: break;
1.3 ! mickey 457: arcp->arc_parentlist = prevp->arc_parentlist;
! 458: prevp->arc_parentlist = arcp;
1.1 deraadt 459: }
460: /*
461: * reattach sorted arcs to child
462: */
463: childp -> parents = sorted.arc_parentlist;
464: }
465:
466: /*
467: * print a cycle header
468: */
1.3 ! mickey 469: void
1.1 deraadt 470: printcycle( cyclep )
471: nltype *cyclep;
472: {
473: char kirkbuffer[ BUFSIZ ];
474:
1.3 ! mickey 475: sprintf(kirkbuffer , "[%d]" , cyclep->index);
! 476: printf("%-6.6s %5.1f %7.2f %11.2f %7ld", kirkbuffer,
! 477: 100 * (cyclep->propself + cyclep->propchild) / printtime,
! 478: cyclep->propself / hz, cyclep->propchild / hz, cyclep->npropcall);
! 479: if (cyclep -> selfcalls != 0)
! 480: printf("+%-7ld" , cyclep->selfcalls);
! 481: else
! 482: printf(" %7.7s" , "");
! 483: printf(" <cycle %d as a whole>\t[%d]\n" ,
! 484: cyclep->cycleno , cyclep->index );
1.1 deraadt 485: }
486:
487: /*
488: * print the members of a cycle
489: */
1.3 ! mickey 490: void
1.1 deraadt 491: printmembers( cyclep )
492: nltype *cyclep;
493: {
494: nltype *memberp;
495:
496: sortmembers( cyclep );
497: for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) {
1.3 ! mickey 498: printf( "%6.6s %5.5s %7.2f %11.2f %7ld" , "", "",
! 499: memberp->propself / hz, memberp->propchild / hz, memberp->npropcall );
! 500: if (memberp -> selfcalls != 0)
! 501: printf("+%-7ld" , memberp -> selfcalls);
! 502: else
! 503: printf(" %7.7s", "");
! 504: printf(" ");
! 505: printname(memberp);
! 506: printf("\n");
1.1 deraadt 507: }
508: }
509:
510: /*
511: * sort members of a cycle
512: */
1.3 ! mickey 513: void
1.1 deraadt 514: sortmembers( cyclep )
515: nltype *cyclep;
516: {
517: nltype *todo;
518: nltype *doing;
519: nltype *prev;
520:
521: /*
522: * detach cycle members from cyclehead,
523: * and insertion sort them back on.
524: */
525: todo = cyclep -> cnext;
526: cyclep -> cnext = 0;
1.3 ! mickey 527: for (doing = todo, todo = doing -> cnext;
! 528: doing; doing = todo, todo = doing -> cnext) {
! 529: for (prev = cyclep; prev -> cnext; prev = prev -> cnext)
! 530: if (membercmp(doing, prev->cnext ) == GREATERTHAN)
1.1 deraadt 531: break;
532: doing -> cnext = prev -> cnext;
533: prev -> cnext = doing;
534: }
535: }
536:
537: /*
538: * major sort is on propself + propchild,
539: * next is sort on ncalls + selfcalls.
540: */
541: int
542: membercmp( this , that )
543: nltype *this;
544: nltype *that;
545: {
546: double thistime = this -> propself + this -> propchild;
547: double thattime = that -> propself + that -> propchild;
548: long thiscalls = this -> ncall + this -> selfcalls;
549: long thatcalls = that -> ncall + that -> selfcalls;
550:
551: if ( thistime > thattime ) {
552: return GREATERTHAN;
553: }
554: if ( thistime < thattime ) {
555: return LESSTHAN;
556: }
557: if ( thiscalls > thatcalls ) {
558: return GREATERTHAN;
559: }
560: if ( thiscalls < thatcalls ) {
561: return LESSTHAN;
562: }
563: return EQUALTO;
564: }
565: /*
566: * compare two arcs to/from the same child/parent.
567: * - if one arc is a self arc, it's least.
568: * - if one arc is within a cycle, it's less than.
569: * - if both arcs are within a cycle, compare arc counts.
570: * - if neither arc is within a cycle, compare with
571: * arc_time + arc_childtime as major key
572: * arc count as minor key
573: */
574: int
575: arccmp( thisp , thatp )
576: arctype *thisp;
577: arctype *thatp;
578: {
579: nltype *thisparentp = thisp -> arc_parentp;
580: nltype *thischildp = thisp -> arc_childp;
581: nltype *thatparentp = thatp -> arc_parentp;
582: nltype *thatchildp = thatp -> arc_childp;
583: double thistime;
584: double thattime;
585:
586: # ifdef DEBUG
587: if ( debug & TIMEDEBUG ) {
588: printf( "[arccmp] " );
589: printname( thisparentp );
590: printf( " calls " );
591: printname ( thischildp );
592: printf( " %f + %f %d/%d\n" ,
593: thisp -> arc_time , thisp -> arc_childtime ,
594: thisp -> arc_count , thischildp -> ncall );
595: printf( "[arccmp] " );
596: printname( thatparentp );
597: printf( " calls " );
598: printname( thatchildp );
599: printf( " %f + %f %d/%d\n" ,
600: thatp -> arc_time , thatp -> arc_childtime ,
601: thatp -> arc_count , thatchildp -> ncall );
602: printf( "\n" );
603: }
604: # endif DEBUG
605: if ( thisparentp == thischildp ) {
606: /* this is a self call */
607: return LESSTHAN;
608: }
609: if ( thatparentp == thatchildp ) {
610: /* that is a self call */
611: return GREATERTHAN;
612: }
613: if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
614: thisparentp -> cycleno == thischildp -> cycleno ) {
615: /* this is a call within a cycle */
616: if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
617: thatparentp -> cycleno == thatchildp -> cycleno ) {
618: /* that is a call within the cycle, too */
619: if ( thisp -> arc_count < thatp -> arc_count ) {
620: return LESSTHAN;
621: }
622: if ( thisp -> arc_count > thatp -> arc_count ) {
623: return GREATERTHAN;
624: }
625: return EQUALTO;
626: } else {
627: /* that isn't a call within the cycle */
628: return LESSTHAN;
629: }
630: } else {
631: /* this isn't a call within a cycle */
632: if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
633: thatparentp -> cycleno == thatchildp -> cycleno ) {
634: /* that is a call within a cycle */
635: return GREATERTHAN;
636: } else {
637: /* neither is a call within a cycle */
638: thistime = thisp -> arc_time + thisp -> arc_childtime;
639: thattime = thatp -> arc_time + thatp -> arc_childtime;
640: if ( thistime < thattime )
641: return LESSTHAN;
642: if ( thistime > thattime )
643: return GREATERTHAN;
644: if ( thisp -> arc_count < thatp -> arc_count )
645: return LESSTHAN;
646: if ( thisp -> arc_count > thatp -> arc_count )
647: return GREATERTHAN;
648: return EQUALTO;
649: }
650: }
651: }
652:
1.3 ! mickey 653: void
1.1 deraadt 654: printblurb( blurbname )
655: char *blurbname;
656: {
657: FILE *blurbfile;
658: int input;
659:
660: blurbfile = fopen( blurbname , "r" );
661: if ( blurbfile == NULL ) {
1.3 ! mickey 662: warn("fopen: %s", blurbname );
1.1 deraadt 663: return;
664: }
1.3 ! mickey 665: while ( ( input = getc( blurbfile ) ) != EOF )
1.1 deraadt 666: putchar( input );
1.3 ! mickey 667:
1.1 deraadt 668: fclose( blurbfile );
669: }
670:
671: int
672: namecmp( npp1 , npp2 )
673: nltype **npp1, **npp2;
674: {
675: return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
676: }
677:
1.3 ! mickey 678: void
1.1 deraadt 679: printindex()
680: {
681: nltype **namesortnlp;
682: register nltype *nlp;
683: int index, nnames, todo, i, j;
684: char peterbuffer[ BUFSIZ ];
685:
686: /*
687: * Now, sort regular function name alphbetically
688: * to create an index.
689: */
690: namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
1.3 ! mickey 691: if ( namesortnlp == (nltype **) 0 )
! 692: warnx("ran out of memory for sorting");
1.1 deraadt 693: for ( index = 0 , nnames = 0 ; index < nname ; index++ ) {
694: if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 )
695: continue;
696: namesortnlp[nnames++] = &nl[index];
697: }
698: qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp );
699: for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) {
700: namesortnlp[todo++] = &cyclenl[index];
701: }
702: printf( "\f\nIndex by function name\n\n" );
703: index = ( todo + 2 ) / 3;
704: for ( i = 0; i < index ; i++ ) {
705: for ( j = i; j < todo ; j += index ) {
706: nlp = namesortnlp[ j ];
707: if ( nlp -> printflag ) {
708: sprintf( peterbuffer , "[%d]" , nlp -> index );
709: } else {
710: sprintf( peterbuffer , "(%d)" , nlp -> index );
711: }
712: if ( j < nnames ) {
713: printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name );
714: } else {
715: printf( "%6.6s " , peterbuffer );
716: sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno );
717: printf( "%-19.19s" , peterbuffer );
718: }
719: }
720: printf( "\n" );
721: }
722: free( namesortnlp );
723: }