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