8 * Return value of comparison functions used to sort tables:
14 /* declarations of automatically generated functions to output blurbs: */
15 extern void bsd_callg_blurb
PARAMS ((FILE * fp
));
16 extern void fsf_callg_blurb
PARAMS ((FILE * fp
));
18 double print_time
= 0.0;
22 DEFUN_VOID (print_header
)
32 if (!bsd_style_output
)
34 if (print_descriptions
)
36 printf ("\t\t Call graph (explanation follows)\n\n");
40 printf ("\t\t\tCall graph\n\n");
43 printf ("\ngranularity: each sample hit covers %ld byte(s)",
44 (long) hist_scale
* sizeof (UNIT
));
47 printf (" for %.2f%% of %.2f seconds\n\n",
48 100.0 / print_time
, print_time
/ hz
);
52 printf (" no time propagated\n\n");
54 * This doesn't hurt, since all the numerators will be 0.0:
60 printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
61 "", "", "", "", "called", "total", "parents");
62 printf ("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n",
63 "index", "%time", "self", "descendents",
64 "called", "self", "name", "index");
65 printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
66 "", "", "", "", "called", "total", "children");
71 printf ("index %% time self children called name\n");
77 * Print a cycle header.
80 DEFUN (print_cycle
, (cyc
), Sym
* cyc
)
84 sprintf (buf
, "[%d]", cyc
->cg
.index
);
85 printf (bsd_style_output
86 ? "%-6.6s %5.1f %7.2f %11.2f %7d"
87 : "%-6.6s %5.1f %7.2f %7.2f %7d", buf
,
88 100 * (cyc
->cg
.prop
.self
+ cyc
->cg
.prop
.child
) / print_time
,
89 cyc
->cg
.prop
.self
/ hz
, cyc
->cg
.prop
.child
/ hz
, cyc
->ncalls
);
90 if (cyc
->cg
.self_calls
!= 0)
92 printf ("+%-7d", cyc
->cg
.self_calls
);
96 printf (" %7.7s", "");
98 printf (" <cycle %d as a whole> [%d]\n", cyc
->cg
.cyc
.num
, cyc
->cg
.index
);
103 * Compare LEFT and RIGHT membmer. Major comparison key is
104 * CG.PROP.SELF+CG.PROP.CHILD, secondary key is NCALLS+CG.SELF_CALLS.
107 DEFUN (cmp_member
, (left
, right
), Sym
* left AND Sym
* right
)
109 double left_time
= left
->cg
.prop
.self
+ left
->cg
.prop
.child
;
110 double right_time
= right
->cg
.prop
.self
+ right
->cg
.prop
.child
;
111 long left_calls
= left
->ncalls
+ left
->cg
.self_calls
;
112 long right_calls
= right
->ncalls
+ right
->cg
.self_calls
;
114 if (left_time
> right_time
)
118 if (left_time
< right_time
)
123 if (left_calls
> right_calls
)
127 if (left_calls
< right_calls
)
136 * Sort members of a cycle.
139 DEFUN (sort_members
, (cyc
), Sym
* cyc
)
141 Sym
*todo
, *doing
, *prev
;
143 * Detach cycle members from cyclehead, and insertion sort them
146 todo
= cyc
->cg
.cyc
.next
;
147 cyc
->cg
.cyc
.next
= 0;
148 for (doing
= todo
; doing
&& doing
->cg
.cyc
.next
; doing
= todo
)
150 todo
= doing
->cg
.cyc
.next
;
151 for (prev
= cyc
; prev
->cg
.cyc
.next
; prev
= prev
->cg
.cyc
.next
)
153 if (cmp_member (doing
, prev
->cg
.cyc
.next
) == GREATERTHAN
)
158 doing
->cg
.cyc
.next
= prev
->cg
.cyc
.next
;
159 prev
->cg
.cyc
.next
= doing
;
165 * Print the members of a cycle.
168 DEFUN (print_members
, (cyc
), Sym
* cyc
)
173 for (member
= cyc
->cg
.cyc
.next
; member
; member
= member
->cg
.cyc
.next
)
175 printf (bsd_style_output
176 ? "%6.6s %5.5s %7.2f %11.2f %7d"
177 : "%6.6s %5.5s %7.2f %7.2f %7d",
178 "", "", member
->cg
.prop
.self
/ hz
, member
->cg
.prop
.child
/ hz
,
180 if (member
->cg
.self_calls
!= 0)
182 printf ("+%-7d", member
->cg
.self_calls
);
186 printf (" %7.7s", "");
196 * Compare two arcs to/from the same child/parent.
197 * - if one arc is a self arc, it's least.
198 * - if one arc is within a cycle, it's less than.
199 * - if both arcs are within a cycle, compare arc counts.
200 * - if neither arc is within a cycle, compare with
201 * time + child_time as major key
202 * arc count as minor key
205 DEFUN (cmp_arc
, (left
, right
), Arc
* left AND Arc
* right
)
207 Sym
*left_parent
= left
->parent
;
208 Sym
*left_child
= left
->child
;
209 Sym
*right_parent
= right
->parent
;
210 Sym
*right_child
= right
->child
;
211 double left_time
, right_time
;
214 printf ("[cmp_arc] ");
215 print_name (left_parent
);
217 print_name (left_child
);
218 printf (" %f + %f %d/%d\n", left
->time
, left
->child_time
,
219 left
->count
, left_child
->ncalls
);
220 printf ("[cmp_arc] ");
221 print_name (right_parent
);
223 print_name (right_child
);
224 printf (" %f + %f %d/%d\n", right
->time
, right
->child_time
,
225 right
->count
, right_child
->ncalls
);
228 if (left_parent
== left_child
)
230 return LESSTHAN
; /* left is a self call */
232 if (right_parent
== right_child
)
234 return GREATERTHAN
; /* right is a self call */
237 if (left_parent
->cg
.cyc
.num
!= 0 && left_child
->cg
.cyc
.num
!= 0
238 && left_parent
->cg
.cyc
.num
== left_child
->cg
.cyc
.num
)
240 /* left is a call within a cycle */
241 if (right_parent
->cg
.cyc
.num
!= 0 && right_child
->cg
.cyc
.num
!= 0
242 && right_parent
->cg
.cyc
.num
== right_child
->cg
.cyc
.num
)
244 /* right is a call within the cycle, too */
245 if (left
->count
< right
->count
)
249 if (left
->count
> right
->count
)
257 /* right isn't a call within the cycle */
263 /* left isn't a call within a cycle */
264 if (right_parent
->cg
.cyc
.num
!= 0 && right_child
->cg
.cyc
.num
!= 0
265 && right_parent
->cg
.cyc
.num
== right_child
->cg
.cyc
.num
)
267 /* right is a call within a cycle */
272 /* neither is a call within a cycle */
273 left_time
= left
->time
+ left
->child_time
;
274 right_time
= right
->time
+ right
->child_time
;
275 if (left_time
< right_time
)
279 if (left_time
> right_time
)
283 if (left
->count
< right
->count
)
287 if (left
->count
> right
->count
)
298 DEFUN (sort_parents
, (child
), Sym
* child
)
300 Arc
*arc
, *detached
, sorted
, *prev
;
303 * Unlink parents from child, then insertion sort back on to
305 * *arc the arc you have detached and are inserting.
306 * *detached the rest of the arcs to be sorted.
307 * sorted arc list onto which you insertion sort.
308 * *prev arc before the arc you are comparing.
310 sorted
.next_parent
= 0;
311 for (arc
= child
->cg
.parents
; arc
; arc
= detached
)
313 detached
= arc
->next_parent
;
315 /* consider *arc as disconnected; insert it into sorted: */
316 for (prev
= &sorted
; prev
->next_parent
; prev
= prev
->next_parent
)
318 if (cmp_arc (arc
, prev
->next_parent
) != GREATERTHAN
)
323 arc
->next_parent
= prev
->next_parent
;
324 prev
->next_parent
= arc
;
327 /* reattach sorted arcs to child: */
328 child
->cg
.parents
= sorted
.next_parent
;
333 DEFUN (print_parents
, (child
), Sym
* child
)
339 if (child
->cg
.cyc
.head
!= 0)
341 cycle_head
= child
->cg
.cyc
.head
;
347 if (!child
->cg
.parents
)
349 printf (bsd_style_output
350 ? "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n"
351 : "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n",
352 "", "", "", "", "", "");
355 sort_parents (child
);
356 for (arc
= child
->cg
.parents
; arc
; arc
= arc
->next_parent
)
358 parent
= arc
->parent
;
359 if (child
== parent
|| (child
->cg
.cyc
.num
!= 0
360 && parent
->cg
.cyc
.num
== child
->cg
.cyc
.num
))
362 /* selfcall or call among siblings: */
363 printf (bsd_style_output
364 ? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s "
365 : "%6.6s %5.5s %7.7s %7.7s %7d %7.7s ",
373 /* regular parent of child: */
374 printf (bsd_style_output
375 ? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d "
376 : "%6.6s %5.5s %7.2f %7.2f %7d/%-7d ",
378 arc
->time
/ hz
, arc
->child_time
/ hz
,
379 arc
->count
, cycle_head
->ncalls
);
388 DEFUN (sort_children
, (parent
), Sym
* parent
)
390 Arc
*arc
, *detached
, sorted
, *prev
;
392 * Unlink children from parent, then insertion sort back on to
394 * *arc the arc you have detached and are inserting.
395 * *detached the rest of the arcs to be sorted.
396 * sorted arc list onto which you insertion sort.
397 * *prev arc before the arc you are comparing.
399 sorted
.next_child
= 0;
400 for (arc
= parent
->cg
.children
; arc
; arc
= detached
)
402 detached
= arc
->next_child
;
404 /* consider *arc as disconnected; insert it into sorted: */
405 for (prev
= &sorted
; prev
->next_child
; prev
= prev
->next_child
)
407 if (cmp_arc (arc
, prev
->next_child
) != LESSTHAN
)
412 arc
->next_child
= prev
->next_child
;
413 prev
->next_child
= arc
;
416 /* reattach sorted children to parent: */
417 parent
->cg
.children
= sorted
.next_child
;
422 DEFUN (print_children
, (parent
), Sym
* parent
)
427 sort_children (parent
);
428 arc
= parent
->cg
.children
;
429 for (arc
= parent
->cg
.children
; arc
; arc
= arc
->next_child
)
432 if (child
== parent
|| (child
->cg
.cyc
.num
!= 0
433 && child
->cg
.cyc
.num
== parent
->cg
.cyc
.num
))
435 /* self call or call to sibling: */
436 printf (bsd_style_output
437 ? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s "
438 : "%6.6s %5.5s %7.7s %7.7s %7d %7.7s ",
439 "", "", "", "", arc
->count
, "");
445 /* regular child of parent: */
446 printf (bsd_style_output
447 ? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d "
448 : "%6.6s %5.5s %7.2f %7.2f %7d/%-7d ",
450 arc
->time
/ hz
, arc
->child_time
/ hz
,
451 arc
->count
, child
->cg
.cyc
.head
->ncalls
);
460 DEFUN (print_line
, (np
), Sym
* np
)
464 sprintf (buf
, "[%d]", np
->cg
.index
);
465 printf (bsd_style_output
466 ? "%-6.6s %5.1f %7.2f %11.2f"
467 : "%-6.6s %5.1f %7.2f %7.2f", buf
,
468 100 * (np
->cg
.prop
.self
+ np
->cg
.prop
.child
) / print_time
,
469 np
->cg
.prop
.self
/ hz
, np
->cg
.prop
.child
/ hz
);
470 if ((np
->ncalls
+ np
->cg
.self_calls
) != 0)
472 printf (" %7d", np
->ncalls
);
473 if (np
->cg
.self_calls
!= 0)
475 printf ("+%-7d ", np
->cg
.self_calls
);
479 printf (" %7.7s ", "");
484 printf (" %7.7s %7.7s ", "", "");
492 * Print dynamic call graph.
495 DEFUN (cg_print
, (timesortsym
), Sym
** timesortsym
)
500 if (print_descriptions
&& bsd_style_output
)
502 bsd_callg_blurb (stdout
);
507 for (index
= 0; index
< symtab
.len
+ num_cycles
; ++index
)
509 parent
= timesortsym
[index
];
510 if ((ignore_zeros
&& parent
->ncalls
== 0
511 && parent
->cg
.self_calls
== 0 && parent
->cg
.prop
.self
== 0
512 && parent
->cg
.prop
.child
== 0)
513 || !parent
->cg
.print_flag
)
517 if (!parent
->name
&& parent
->cg
.cyc
.num
!= 0)
520 print_cycle (parent
);
521 print_members (parent
);
525 print_parents (parent
);
527 print_children (parent
);
529 if (bsd_style_output
)
531 printf ("-----------------------------------------------\n");
532 if (bsd_style_output
)
536 if (print_descriptions
&& !bsd_style_output
)
538 fsf_callg_blurb (stdout
);
544 DEFUN (cmp_name
, (left
, right
), const PTR left AND
const PTR right
)
546 const Sym
**npp1
= (const Sym
**) left
;
547 const Sym
**npp2
= (const Sym
**) right
;
549 return strcmp ((*npp1
)->name
, (*npp2
)->name
);
554 DEFUN_VOID (cg_print_index
)
556 int index
, nnames
, todo
, i
, j
, col
, starting_col
;
557 Sym
**name_sorted_syms
, *sym
;
558 const char *filename
;
560 int column_width
= (output_width
- 1) / 3; /* don't write in last col! */
562 * Now, sort regular function name alphabetically to create an
565 name_sorted_syms
= (Sym
**) xmalloc ((symtab
.len
+ num_cycles
) * sizeof (Sym
*));
566 for (index
= 0, nnames
= 0; index
< symtab
.len
; index
++)
568 if (ignore_zeros
&& symtab
.base
[index
].ncalls
== 0
569 && symtab
.base
[index
].hist
.time
== 0)
573 name_sorted_syms
[nnames
++] = &symtab
.base
[index
];
575 qsort (name_sorted_syms
, nnames
, sizeof (Sym
*), cmp_name
);
576 for (index
= 1, todo
= nnames
; index
<= num_cycles
; index
++)
578 name_sorted_syms
[todo
++] = &cycle_header
[index
];
580 printf ("\f\nIndex by function name\n\n");
581 index
= (todo
+ 2) / 3;
582 for (i
= 0; i
< index
; i
++)
586 for (j
= i
; j
< todo
; j
+= index
)
588 sym
= name_sorted_syms
[j
];
589 if (sym
->cg
.print_flag
)
591 sprintf (buf
, "[%d]", sym
->cg
.index
);
595 sprintf (buf
, "(%d)", sym
->cg
.index
);
599 if (bsd_style_output
)
601 printf ("%6.6s %-19.19s", buf
, sym
->name
);
606 for (; col
< starting_col
+ 5; ++col
)
610 printf (" %s ", buf
);
611 col
+= print_name_only (sym
);
612 if (!line_granularity
&& sym
->is_static
&& sym
->file
)
614 filename
= sym
->file
->name
;
617 filename
= strrchr (filename
, '/');
624 filename
= sym
->file
->name
;
627 printf (" (%s)", filename
);
628 col
+= strlen (filename
) + 3;
634 if (bsd_style_output
)
636 printf ("%6.6s ", buf
);
637 sprintf (buf
, "<cycle %d>", sym
->cg
.cyc
.num
);
638 printf ("%-19.19s", buf
);
643 for (; col
< starting_col
+ 5; ++col
)
645 printf (" %s ", buf
);
646 sprintf (buf
, "<cycle %d>", sym
->cg
.cyc
.num
);
651 starting_col
+= column_width
;
655 free (name_sorted_syms
);
This page took 0.044521 seconds and 4 git commands to generate.