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