1 #ifndef __PERF_CALLCHAIN_H
2 #define __PERF_CALLCHAIN_H
5 #include <linux/list.h>
6 #include <linux/rbtree.h>
22 struct callchain_node
{
23 struct callchain_node
*parent
;
25 struct rb_node rb_node_in
; /* to insert nodes in an rbtree */
26 struct rb_node rb_node
; /* to sort nodes in an output tree */
27 struct rb_root rb_root_in
; /* input tree of children */
28 struct rb_root rb_root
; /* sorted output tree of children */
34 struct callchain_root
{
36 struct callchain_node node
;
39 struct callchain_param
;
41 typedef void (*sort_chain_func_t
)(struct rb_root
*, struct callchain_root
*,
42 u64
, struct callchain_param
*);
49 struct callchain_param
{
53 sort_chain_func_t sort
;
54 enum chain_order order
;
58 struct callchain_list
{
61 struct list_head list
;
65 * A callchain cursor is a single linked list that
66 * let one feed a callchain progressively.
67 * It keeps persistent allocated entries to minimize
70 struct callchain_cursor_node
{
74 struct callchain_cursor_node
*next
;
77 struct callchain_cursor
{
79 struct callchain_cursor_node
*first
;
80 struct callchain_cursor_node
**last
;
82 struct callchain_cursor_node
*curr
;
85 extern __thread
struct callchain_cursor callchain_cursor
;
87 static inline void callchain_init(struct callchain_root
*root
)
89 INIT_LIST_HEAD(&root
->node
.val
);
91 root
->node
.parent
= NULL
;
93 root
->node
.children_hit
= 0;
94 root
->node
.rb_root_in
= RB_ROOT
;
98 static inline u64
callchain_cumul_hits(struct callchain_node
*node
)
100 return node
->hit
+ node
->children_hit
;
103 int callchain_register_param(struct callchain_param
*param
);
104 int callchain_append(struct callchain_root
*root
,
105 struct callchain_cursor
*cursor
,
108 int callchain_merge(struct callchain_cursor
*cursor
,
109 struct callchain_root
*dst
, struct callchain_root
*src
);
112 * Initialize a cursor before adding entries inside, but keep
113 * the previously allocated entries as a cache.
115 static inline void callchain_cursor_reset(struct callchain_cursor
*cursor
)
118 cursor
->last
= &cursor
->first
;
121 int callchain_cursor_append(struct callchain_cursor
*cursor
, u64 ip
,
122 struct map
*map
, struct symbol
*sym
);
124 /* Close a cursor writing session. Initialize for the reader */
125 static inline void callchain_cursor_commit(struct callchain_cursor
*cursor
)
127 cursor
->curr
= cursor
->first
;
131 /* Cursor reading iteration helpers */
132 static inline struct callchain_cursor_node
*
133 callchain_cursor_current(struct callchain_cursor
*cursor
)
135 if (cursor
->pos
== cursor
->nr
)
141 static inline void callchain_cursor_advance(struct callchain_cursor
*cursor
)
143 cursor
->curr
= cursor
->curr
->next
;
150 int record_parse_callchain(const char *arg
, struct record_opts
*opts
);
151 int record_parse_callchain_opt(const struct option
*opt
, const char *arg
, int unset
);
152 int record_callchain_opt(const struct option
*opt
, const char *arg
, int unset
);
154 int sample__resolve_callchain(struct perf_sample
*sample
, struct symbol
**parent
,
155 struct perf_evsel
*evsel
, struct addr_location
*al
,
157 int hist_entry__append_callchain(struct hist_entry
*he
, struct perf_sample
*sample
);
159 extern const char record_callchain_help
[];
160 #endif /* __PERF_CALLCHAIN_H */