perf callchain: Enable printing the srcline in the history
[deliverable/linux.git] / tools / perf / util / callchain.h
1 #ifndef __PERF_CALLCHAIN_H
2 #define __PERF_CALLCHAIN_H
3
4 #include "../perf.h"
5 #include <linux/list.h>
6 #include <linux/rbtree.h>
7 #include "event.h"
8 #include "symbol.h"
9
10 enum perf_call_graph_mode {
11 CALLCHAIN_NONE,
12 CALLCHAIN_FP,
13 CALLCHAIN_DWARF,
14 CALLCHAIN_MAX
15 };
16
17 enum chain_mode {
18 CHAIN_NONE,
19 CHAIN_FLAT,
20 CHAIN_GRAPH_ABS,
21 CHAIN_GRAPH_REL
22 };
23
24 enum chain_order {
25 ORDER_CALLER,
26 ORDER_CALLEE
27 };
28
29 struct callchain_node {
30 struct callchain_node *parent;
31 struct list_head val;
32 struct rb_node rb_node_in; /* to insert nodes in an rbtree */
33 struct rb_node rb_node; /* to sort nodes in an output tree */
34 struct rb_root rb_root_in; /* input tree of children */
35 struct rb_root rb_root; /* sorted output tree of children */
36 unsigned int val_nr;
37 u64 hit;
38 u64 children_hit;
39 };
40
41 struct callchain_root {
42 u64 max_depth;
43 struct callchain_node node;
44 };
45
46 struct callchain_param;
47
48 typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_root *,
49 u64, struct callchain_param *);
50
51 enum chain_key {
52 CCKEY_FUNCTION,
53 CCKEY_ADDRESS
54 };
55
56 struct callchain_param {
57 bool enabled;
58 enum perf_call_graph_mode record_mode;
59 u32 dump_size;
60 enum chain_mode mode;
61 u32 print_limit;
62 double min_percent;
63 sort_chain_func_t sort;
64 enum chain_order order;
65 enum chain_key key;
66 };
67
68 extern struct callchain_param callchain_param;
69
70 struct callchain_list {
71 u64 ip;
72 struct map_symbol ms;
73 char *srcline;
74 struct list_head list;
75 };
76
77 /*
78 * A callchain cursor is a single linked list that
79 * let one feed a callchain progressively.
80 * It keeps persistent allocated entries to minimize
81 * allocations.
82 */
83 struct callchain_cursor_node {
84 u64 ip;
85 struct map *map;
86 struct symbol *sym;
87 struct callchain_cursor_node *next;
88 };
89
90 struct callchain_cursor {
91 u64 nr;
92 struct callchain_cursor_node *first;
93 struct callchain_cursor_node **last;
94 u64 pos;
95 struct callchain_cursor_node *curr;
96 };
97
98 extern __thread struct callchain_cursor callchain_cursor;
99
100 static inline void callchain_init(struct callchain_root *root)
101 {
102 INIT_LIST_HEAD(&root->node.val);
103
104 root->node.parent = NULL;
105 root->node.hit = 0;
106 root->node.children_hit = 0;
107 root->node.rb_root_in = RB_ROOT;
108 root->max_depth = 0;
109 }
110
111 static inline u64 callchain_cumul_hits(struct callchain_node *node)
112 {
113 return node->hit + node->children_hit;
114 }
115
116 int callchain_register_param(struct callchain_param *param);
117 int callchain_append(struct callchain_root *root,
118 struct callchain_cursor *cursor,
119 u64 period);
120
121 int callchain_merge(struct callchain_cursor *cursor,
122 struct callchain_root *dst, struct callchain_root *src);
123
124 /*
125 * Initialize a cursor before adding entries inside, but keep
126 * the previously allocated entries as a cache.
127 */
128 static inline void callchain_cursor_reset(struct callchain_cursor *cursor)
129 {
130 cursor->nr = 0;
131 cursor->last = &cursor->first;
132 }
133
134 int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip,
135 struct map *map, struct symbol *sym);
136
137 /* Close a cursor writing session. Initialize for the reader */
138 static inline void callchain_cursor_commit(struct callchain_cursor *cursor)
139 {
140 cursor->curr = cursor->first;
141 cursor->pos = 0;
142 }
143
144 /* Cursor reading iteration helpers */
145 static inline struct callchain_cursor_node *
146 callchain_cursor_current(struct callchain_cursor *cursor)
147 {
148 if (cursor->pos == cursor->nr)
149 return NULL;
150
151 return cursor->curr;
152 }
153
154 static inline void callchain_cursor_advance(struct callchain_cursor *cursor)
155 {
156 cursor->curr = cursor->curr->next;
157 cursor->pos++;
158 }
159
160 struct option;
161 struct hist_entry;
162
163 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
164 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
165
166 int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
167 struct perf_evsel *evsel, struct addr_location *al,
168 int max_stack);
169 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
170 int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node,
171 bool hide_unresolved);
172
173 extern const char record_callchain_help[];
174 int parse_callchain_record_opt(const char *arg);
175 int parse_callchain_report_opt(const char *arg);
176 int perf_callchain_config(const char *var, const char *value);
177
178 static inline void callchain_cursor_snapshot(struct callchain_cursor *dest,
179 struct callchain_cursor *src)
180 {
181 *dest = *src;
182
183 dest->first = src->curr;
184 dest->nr -= src->pos;
185 }
186
187 #ifdef HAVE_SKIP_CALLCHAIN_IDX
188 extern int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain);
189 #else
190 static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
191 struct ip_callchain *chain __maybe_unused)
192 {
193 return -1;
194 }
195 #endif
196
197 char *callchain_list__sym_name(struct callchain_list *cl,
198 char *bf, size_t bfsize, bool show_dso);
199
200 #endif /* __PERF_CALLCHAIN_H */
This page took 0.07293 seconds and 5 git commands to generate.