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
;
24 struct list_head siblings
;
25 struct list_head children
;
27 struct rb_node rb_node
; /* to sort nodes in an rbtree */
28 struct rb_root rb_root
; /* sorted 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
.siblings
);
90 INIT_LIST_HEAD(&root
->node
.children
);
91 INIT_LIST_HEAD(&root
->node
.val
);
93 root
->node
.parent
= NULL
;
95 root
->node
.children_hit
= 0;
99 static inline u64
callchain_cumul_hits(struct callchain_node
*node
)
101 return node
->hit
+ node
->children_hit
;
104 int callchain_register_param(struct callchain_param
*param
);
105 int callchain_append(struct callchain_root
*root
,
106 struct callchain_cursor
*cursor
,
109 int callchain_merge(struct callchain_cursor
*cursor
,
110 struct callchain_root
*dst
, struct callchain_root
*src
);
113 * Initialize a cursor before adding entries inside, but keep
114 * the previously allocated entries as a cache.
116 static inline void callchain_cursor_reset(struct callchain_cursor
*cursor
)
119 cursor
->last
= &cursor
->first
;
122 int callchain_cursor_append(struct callchain_cursor
*cursor
, u64 ip
,
123 struct map
*map
, struct symbol
*sym
);
125 /* Close a cursor writing session. Initialize for the reader */
126 static inline void callchain_cursor_commit(struct callchain_cursor
*cursor
)
128 cursor
->curr
= cursor
->first
;
132 /* Cursor reading iteration helpers */
133 static inline struct callchain_cursor_node
*
134 callchain_cursor_current(struct callchain_cursor
*cursor
)
136 if (cursor
->pos
== cursor
->nr
)
142 static inline void callchain_cursor_advance(struct callchain_cursor
*cursor
)
144 cursor
->curr
= cursor
->curr
->next
;
150 int record_parse_callchain(const char *arg
, struct perf_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 extern const char record_callchain_help
[];
155 #endif /* __PERF_CALLCHAIN_H */