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