File: | src/usr.bin/gprof/printgprof.c |
Warning: | line 327, column 5 Value stored to 'arcp' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: printgprof.c,v 1.15 2016/12/22 16:36:18 krw Exp $ */ |
2 | /* $NetBSD: printgprof.c,v 1.5 1995/04/19 07:16:21 cgd Exp $ */ |
3 | |
4 | /* |
5 | * Copyright (c) 1983, 1993 |
6 | * The Regents of the University of California. All rights reserved. |
7 | * |
8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions |
10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. |
16 | * 3. Neither the name of the University nor the names of its contributors |
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 | */ |
32 | |
33 | #include <string.h> |
34 | |
35 | #include "gprof.h" |
36 | #include "pathnames.h" |
37 | |
38 | int namecmp(const void *, const void *); |
39 | |
40 | void |
41 | printprof() |
42 | { |
43 | nltype *np; |
44 | nltype **sortednlp; |
45 | int index; |
46 | |
47 | actime = 0.0; |
48 | printf( "\f\n" ); |
49 | flatprofheader(); |
50 | /* |
51 | * Sort the symbol table in by time |
52 | */ |
53 | sortednlp = calloc( nname , sizeof(nltype *) ); |
54 | if ( sortednlp == (nltype **) 0 ) |
55 | warnx("[printprof] ran out of memory for time sorting"); |
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 | |
68 | int |
69 | timecmp(const void *v1, const void *v2) |
70 | { |
71 | const nltype * const *npp1 = v1; |
72 | const nltype * const *npp2 = v2; |
73 | |
74 | if ((*npp2) -> time < (*npp1) -> time) |
75 | return -1; |
76 | if ((*npp2) -> time > (*npp1) -> time) |
77 | return 1 ; |
78 | if ((*npp2) -> ncall < (*npp1) -> ncall) |
79 | return -1; |
80 | if ((*npp2) -> ncall > (*npp1) -> ncall) |
81 | return 1; |
82 | return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); |
83 | } |
84 | |
85 | /* |
86 | * header for flatprofline |
87 | */ |
88 | void |
89 | flatprofheader() |
90 | { |
91 | |
92 | if (bflag) |
93 | printblurb( _PATH_FLAT_BLURB"/usr/share/misc/gprof.flat" ); |
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 { |
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 | } |
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" ); |
110 | } |
111 | |
112 | void |
113 | flatprofline(nltype *np) |
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 ) { |
123 | printf( " %8ld %8.2f %8.2f " , np -> ncall , |
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 | |
133 | void |
134 | gprofheader() |
135 | { |
136 | |
137 | if ( bflag ) { |
138 | printblurb( _PATH_CALLG_BLURB"/usr/share/misc/gprof.callg" ); |
139 | } |
140 | printf( "\ngranularity: each sample hit covers %ld byte(s)" , |
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 | |
162 | void |
163 | gprofline(nltype *np) |
164 | { |
165 | char kirkbuffer[ BUFSIZ1024 ]; |
166 | |
167 | snprintf(kirkbuffer, sizeof kirkbuffer, "[%d]" , np -> index ); |
168 | printf( "%-6.6s %5.1f %7.2f %11.2f" , kirkbuffer , |
169 | 100 * ( np -> propself + np -> propchild ) / printtime , |
170 | np -> propself / hz , np -> propchild / hz ); |
171 | if ( ( np -> ncall + np -> selfcalls ) != 0 ) { |
172 | printf( " %7ld" , np -> npropcall ); |
173 | if ( np -> selfcalls != 0 ) { |
174 | printf( "+%-7ld " , np -> selfcalls ); |
175 | } else { |
176 | printf( " %7.7s " , "" ); |
177 | } |
178 | } else { |
179 | printf( " %7.7s %7.7s " , "" , "" ); |
180 | } |
181 | printname( np ); |
182 | printf( "\n" ); |
183 | } |
184 | |
185 | void |
186 | printgprof(nltype **timesortnlp) |
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 |
234 | totalcmp(const void *v1, const void *v2) |
235 | { |
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 ) |
244 | return 1; |
245 | if ( t2 < t1 ) |
246 | return -1; |
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 ) |
254 | return -1; |
255 | else if ( !np1cyclehdr && np2cyclehdr ) |
256 | return 1; |
257 | |
258 | if ( np1noname && !np2noname ) |
259 | return -1; |
260 | else if ( !np1noname && np2noname ) |
261 | return 1; |
262 | else if ( np1noname && np2noname ) |
263 | return 0; |
264 | |
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 | |
276 | void |
277 | printparents(nltype *childp) |
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 & DEADARC0x01 ) || |
297 | ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) { |
298 | /* |
299 | * selfcall or call among siblings |
300 | */ |
301 | printf( "%6.6s %5.5s %7.7s %11.11s %7ld %7.7s " , |
302 | "" , "" , "" , "" , |
303 | arcp -> arc_count , "" ); |
304 | printname( parentp ); |
305 | printf( "\n" ); |
306 | } else { |
307 | /* |
308 | * regular parent of child |
309 | */ |
310 | printf( "%6.6s %5.5s %7.2f %11.2f %7ld/%-7ld " , |
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 | |
320 | void |
321 | printchildren(nltype *parentp) |
322 | { |
323 | nltype *childp; |
324 | arctype *arcp; |
325 | |
326 | sortchildren( parentp ); |
327 | arcp = parentp -> children; |
Value stored to 'arcp' is never read | |
328 | for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) { |
329 | childp = arcp -> arc_childp; |
330 | if ( childp == parentp || ( arcp -> arc_flags & DEADARC0x01 ) || |
331 | ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) { |
332 | /* |
333 | * self call or call to sibling |
334 | */ |
335 | printf( "%6.6s %5.5s %7.7s %11.11s %7ld %7.7s " , |
336 | "" , "" , "" , "" , arcp -> arc_count , "" ); |
337 | printname( childp ); |
338 | printf( "\n" ); |
339 | } else { |
340 | /* |
341 | * regular child of parent |
342 | */ |
343 | printf( "%6.6s %5.5s %7.2f %11.2f %7ld/%-7ld " , |
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 | |
353 | void |
354 | printname(nltype *selfp) |
355 | { |
356 | |
357 | if ( selfp -> name != 0 ) { |
358 | printf( "%s" , selfp -> name ); |
359 | # ifdef DEBUG |
360 | if ( debug & DFNDEBUG1 ) { |
361 | printf( "{%d} " , selfp -> toporder ); |
362 | } |
363 | if ( debug & PROPDEBUG512 ) { |
364 | printf( "%5.2f%% " , selfp -> propfraction ); |
365 | } |
366 | # endif /* DEBUG */ |
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 | |
380 | void |
381 | sortchildren(nltype *parentp) |
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; |
397 | for (arcp = parentp -> children; arcp; arcp = detachedp) { |
398 | detachedp = arcp -> arc_childlist; |
399 | /* |
400 | * consider *arcp as disconnected |
401 | * insert it into sorted |
402 | */ |
403 | for ( prevp = &sorted ; |
404 | prevp -> arc_childlist ; |
405 | prevp = prevp -> arc_childlist ) { |
406 | if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN-1 ) { |
407 | break; |
408 | } |
409 | } |
410 | arcp -> arc_childlist = prevp -> arc_childlist; |
411 | prevp -> arc_childlist = arcp; |
412 | } |
413 | /* |
414 | * reattach sorted children to parent |
415 | */ |
416 | parentp -> children = sorted.arc_childlist; |
417 | } |
418 | |
419 | void |
420 | sortparents(nltype *childp) |
421 | { |
422 | arctype *arcp; |
423 | arctype *detachedp; |
424 | arctype sorted; |
425 | arctype *prevp; |
426 | |
427 | /* |
428 | * unlink parents from child, |
429 | * then insertion sort back on to sorted's parents. |
430 | * *arcp the arc you have detached and are inserting. |
431 | * *detachedp the rest of the arcs to be sorted. |
432 | * sorted arc list onto which you insertion sort. |
433 | * *prevp arc before the arc you are comparing. |
434 | */ |
435 | sorted.arc_parentlist = 0; |
436 | for (arcp = childp->parents; arcp; arcp = detachedp) { |
437 | detachedp = arcp->arc_parentlist; |
438 | /* |
439 | * consider *arcp as disconnected |
440 | * insert it into sorted |
441 | */ |
442 | for (prevp = &sorted; prevp->arc_parentlist; |
443 | prevp = prevp->arc_parentlist) |
444 | if (arccmp(arcp , prevp->arc_parentlist) != GREATERTHAN1) |
445 | break; |
446 | arcp->arc_parentlist = prevp->arc_parentlist; |
447 | prevp->arc_parentlist = arcp; |
448 | } |
449 | /* |
450 | * reattach sorted arcs to child |
451 | */ |
452 | childp -> parents = sorted.arc_parentlist; |
453 | } |
454 | |
455 | /* |
456 | * print a cycle header |
457 | */ |
458 | void |
459 | printcycle(nltype *cyclep) |
460 | { |
461 | char kirkbuffer[ BUFSIZ1024 ]; |
462 | |
463 | snprintf(kirkbuffer, sizeof kirkbuffer, "[%d]" , cyclep->index); |
464 | printf("%-6.6s %5.1f %7.2f %11.2f %7ld", kirkbuffer, |
465 | 100 * (cyclep->propself + cyclep->propchild) / printtime, |
466 | cyclep->propself / hz, cyclep->propchild / hz, cyclep->npropcall); |
467 | if (cyclep -> selfcalls != 0) |
468 | printf("+%-7ld" , cyclep->selfcalls); |
469 | else |
470 | printf(" %7.7s" , ""); |
471 | printf(" <cycle %d as a whole>\t[%d]\n" , |
472 | cyclep->cycleno , cyclep->index ); |
473 | } |
474 | |
475 | /* |
476 | * print the members of a cycle |
477 | */ |
478 | void |
479 | printmembers(nltype *cyclep) |
480 | { |
481 | nltype *memberp; |
482 | |
483 | sortmembers( cyclep ); |
484 | for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) { |
485 | printf( "%6.6s %5.5s %7.2f %11.2f %7ld" , "", "", |
486 | memberp->propself / hz, memberp->propchild / hz, memberp->npropcall ); |
487 | if (memberp -> selfcalls != 0) |
488 | printf("+%-7ld" , memberp -> selfcalls); |
489 | else |
490 | printf(" %7.7s", ""); |
491 | printf(" "); |
492 | printname(memberp); |
493 | printf("\n"); |
494 | } |
495 | } |
496 | |
497 | /* |
498 | * sort members of a cycle |
499 | */ |
500 | void |
501 | sortmembers(nltype *cyclep) |
502 | { |
503 | nltype *todo; |
504 | nltype *doing; |
505 | nltype *prev; |
506 | |
507 | /* |
508 | * detach cycle members from cyclehead, |
509 | * and insertion sort them back on. |
510 | */ |
511 | todo = cyclep -> cnext; |
512 | cyclep -> cnext = 0; |
513 | for (doing = todo; doing; doing = todo) { |
514 | todo = doing -> cnext; |
515 | for (prev = cyclep; prev -> cnext; prev = prev -> cnext) |
516 | if (membercmp(doing, prev->cnext ) == GREATERTHAN1) |
517 | break; |
518 | doing -> cnext = prev -> cnext; |
519 | prev -> cnext = doing; |
520 | } |
521 | } |
522 | |
523 | /* |
524 | * major sort is on propself + propchild, |
525 | * next is sort on ncalls + selfcalls. |
526 | */ |
527 | int |
528 | membercmp(nltype *this , nltype *that) |
529 | { |
530 | double thistime = this -> propself + this -> propchild; |
531 | double thattime = that -> propself + that -> propchild; |
532 | long thiscalls = this -> ncall + this -> selfcalls; |
533 | long thatcalls = that -> ncall + that -> selfcalls; |
534 | |
535 | if ( thistime > thattime ) { |
536 | return GREATERTHAN1; |
537 | } |
538 | if ( thistime < thattime ) { |
539 | return LESSTHAN-1; |
540 | } |
541 | if ( thiscalls > thatcalls ) { |
542 | return GREATERTHAN1; |
543 | } |
544 | if ( thiscalls < thatcalls ) { |
545 | return LESSTHAN-1; |
546 | } |
547 | return EQUALTO0; |
548 | } |
549 | /* |
550 | * compare two arcs to/from the same child/parent. |
551 | * - if one arc is a self arc, it's least. |
552 | * - if one arc is within a cycle, it's less than. |
553 | * - if both arcs are within a cycle, compare arc counts. |
554 | * - if neither arc is within a cycle, compare with |
555 | * arc_time + arc_childtime as major key |
556 | * arc count as minor key |
557 | */ |
558 | int |
559 | arccmp(arctype *thisp, arctype *thatp) |
560 | { |
561 | nltype *thisparentp = thisp -> arc_parentp; |
562 | nltype *thischildp = thisp -> arc_childp; |
563 | nltype *thatparentp = thatp -> arc_parentp; |
564 | nltype *thatchildp = thatp -> arc_childp; |
565 | double thistime; |
566 | double thattime; |
567 | |
568 | # ifdef DEBUG |
569 | if ( debug & TIMEDEBUG16 ) { |
570 | printf( "[arccmp] " ); |
571 | printname( thisparentp ); |
572 | printf( " calls " ); |
573 | printname ( thischildp ); |
574 | printf( " %f + %f %ld/%ld\n" , |
575 | thisp -> arc_time , thisp -> arc_childtime , |
576 | thisp -> arc_count , thischildp -> ncall ); |
577 | printf( "[arccmp] " ); |
578 | printname( thatparentp ); |
579 | printf( " calls " ); |
580 | printname( thatchildp ); |
581 | printf( " %f + %f %ld/%ld\n" , |
582 | thatp -> arc_time , thatp -> arc_childtime , |
583 | thatp -> arc_count , thatchildp -> ncall ); |
584 | printf( "\n" ); |
585 | } |
586 | # endif /* DEBUG */ |
587 | if ( thisparentp == thischildp ) { |
588 | /* this is a self call */ |
589 | return LESSTHAN-1; |
590 | } |
591 | if ( thatparentp == thatchildp ) { |
592 | /* that is a self call */ |
593 | return GREATERTHAN1; |
594 | } |
595 | if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 && |
596 | thisparentp -> cycleno == thischildp -> cycleno ) { |
597 | /* this is a call within a cycle */ |
598 | if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && |
599 | thatparentp -> cycleno == thatchildp -> cycleno ) { |
600 | /* that is a call within the cycle, too */ |
601 | if ( thisp -> arc_count < thatp -> arc_count ) { |
602 | return LESSTHAN-1; |
603 | } |
604 | if ( thisp -> arc_count > thatp -> arc_count ) { |
605 | return GREATERTHAN1; |
606 | } |
607 | return EQUALTO0; |
608 | } else { |
609 | /* that isn't a call within the cycle */ |
610 | return LESSTHAN-1; |
611 | } |
612 | } else { |
613 | /* this isn't a call within a cycle */ |
614 | if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && |
615 | thatparentp -> cycleno == thatchildp -> cycleno ) { |
616 | /* that is a call within a cycle */ |
617 | return GREATERTHAN1; |
618 | } else { |
619 | /* neither is a call within a cycle */ |
620 | thistime = thisp -> arc_time + thisp -> arc_childtime; |
621 | thattime = thatp -> arc_time + thatp -> arc_childtime; |
622 | if ( thistime < thattime ) |
623 | return LESSTHAN-1; |
624 | if ( thistime > thattime ) |
625 | return GREATERTHAN1; |
626 | if ( thisp -> arc_count < thatp -> arc_count ) |
627 | return LESSTHAN-1; |
628 | if ( thisp -> arc_count > thatp -> arc_count ) |
629 | return GREATERTHAN1; |
630 | return EQUALTO0; |
631 | } |
632 | } |
633 | } |
634 | |
635 | void |
636 | printblurb(const char *blurbname) |
637 | { |
638 | FILE *blurbfile; |
639 | int input; |
640 | |
641 | blurbfile = fopen( blurbname , "r" ); |
642 | if ( blurbfile == NULL((void *)0) ) { |
643 | warn("fopen: %s", blurbname ); |
644 | return; |
645 | } |
646 | while ( ( input = getc( blurbfile )(!__isthreaded ? (--(blurbfile)->_r < 0 ? __srget(blurbfile ) : (int)(*(blurbfile)->_p++)) : (getc)(blurbfile)) ) != EOF(-1) ) |
647 | putchar( input )(!__isthreaded ? __sputc(input, (&__sF[1])) : (putc)(input , (&__sF[1]))); |
648 | |
649 | fclose( blurbfile ); |
650 | } |
651 | |
652 | int |
653 | namecmp(const void *v1, const void *v2) |
654 | { |
655 | const nltype * const *npp1 = v1; |
656 | const nltype * const *npp2 = v2; |
657 | |
658 | return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); |
659 | } |
660 | |
661 | void |
662 | printindex() |
663 | { |
664 | nltype **namesortnlp; |
665 | nltype *nlp; |
666 | int index, nnames, todo, i, j; |
667 | char peterbuffer[ BUFSIZ1024 ]; |
668 | |
669 | /* |
670 | * Now, sort regular function name alphbetically |
671 | * to create an index. |
672 | */ |
673 | namesortnlp = calloc( nname + ncycle , sizeof(nltype *) ); |
674 | if ( namesortnlp == (nltype **) 0 ) |
675 | warnx("ran out of memory for sorting"); |
676 | for ( index = 0 , nnames = 0 ; index < nname ; index++ ) { |
677 | if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 ) |
678 | continue; |
679 | namesortnlp[nnames++] = &nl[index]; |
680 | } |
681 | qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp ); |
682 | for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) { |
683 | namesortnlp[todo++] = &cyclenl[index]; |
684 | } |
685 | printf( "\f\nIndex by function name\n\n" ); |
686 | index = ( todo + 2 ) / 3; |
687 | for ( i = 0; i < index ; i++ ) { |
688 | for ( j = i; j < todo ; j += index ) { |
689 | nlp = namesortnlp[ j ]; |
690 | if ( nlp -> printflag ) { |
691 | snprintf(peterbuffer, sizeof peterbuffer, "[%d]" , nlp -> index ); |
692 | } else { |
693 | snprintf(peterbuffer, sizeof peterbuffer, "(%d)" , nlp -> index ); |
694 | } |
695 | if ( j < nnames ) { |
696 | printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name ); |
697 | } else { |
698 | printf( "%6.6s " , peterbuffer ); |
699 | snprintf(peterbuffer, sizeof peterbuffer, "<cycle %d>" |
700 | , nlp -> cycleno ); |
701 | printf( "%-19.19s" , peterbuffer ); |
702 | } |
703 | } |
704 | printf( "\n" ); |
705 | } |
706 | free( namesortnlp ); |
707 | } |