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