diff options
| author | John Kacur <jkacur@redhat.com> | 2009-09-28 09:32:55 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-09-30 07:57:56 -0400 |
| commit | 3d1d07ecd2009f65cb2091563fa21f9600c36774 (patch) | |
| tree | a1ef97a8264fc880ee8a9406a9be9070d0d12176 /tools/perf/builtin-annotate.c | |
| parent | dd68ada2d417e57b848822a1407b5317a54136c5 (diff) | |
perf tools: Put common histogram functions in their own file
Move histogram related functions into their own files (hist.c and
hist.h) and make use of them in builtin-annotate.c and
builtin-report.c.
Signed-off-by: John Kacur <jkacur@redhat.com>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <alpine.LFD.2.00.0909281531180.8316@localhost.localdomain>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/builtin-annotate.c')
| -rw-r--r-- | tools/perf/builtin-annotate.c | 152 |
1 files changed, 2 insertions, 150 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 059c565b31ea..df516dce9540 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "util/parse-events.h" | 23 | #include "util/parse-events.h" |
| 24 | #include "util/thread.h" | 24 | #include "util/thread.h" |
| 25 | #include "util/sort.h" | 25 | #include "util/sort.h" |
| 26 | #include "util/hist.h" | ||
| 26 | 27 | ||
| 27 | static char const *input_name = "perf.data"; | 28 | static char const *input_name = "perf.data"; |
| 28 | 29 | ||
| @@ -47,45 +48,6 @@ struct sym_ext { | |||
| 47 | char *path; | 48 | char *path; |
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 50 | /* | ||
| 51 | * histogram, sorted on item, collects counts | ||
| 52 | */ | ||
| 53 | |||
| 54 | static struct rb_root hist; | ||
| 55 | |||
| 56 | static int64_t | ||
| 57 | hist_entry__cmp(struct hist_entry *left, struct hist_entry *right) | ||
| 58 | { | ||
| 59 | struct sort_entry *se; | ||
| 60 | int64_t cmp = 0; | ||
| 61 | |||
| 62 | list_for_each_entry(se, &hist_entry__sort_list, list) { | ||
| 63 | cmp = se->cmp(left, right); | ||
| 64 | if (cmp) | ||
| 65 | break; | ||
| 66 | } | ||
| 67 | |||
| 68 | return cmp; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int64_t | ||
| 72 | hist_entry__collapse(struct hist_entry *left, struct hist_entry *right) | ||
| 73 | { | ||
| 74 | struct sort_entry *se; | ||
| 75 | int64_t cmp = 0; | ||
| 76 | |||
| 77 | list_for_each_entry(se, &hist_entry__sort_list, list) { | ||
| 78 | int64_t (*f)(struct hist_entry *, struct hist_entry *); | ||
| 79 | |||
| 80 | f = se->collapse ?: se->cmp; | ||
| 81 | |||
| 82 | cmp = f(left, right); | ||
| 83 | if (cmp) | ||
| 84 | break; | ||
| 85 | } | ||
| 86 | |||
| 87 | return cmp; | ||
| 88 | } | ||
| 89 | 51 | ||
| 90 | /* | 52 | /* |
| 91 | * collect histogram counts | 53 | * collect histogram counts |
| @@ -163,116 +125,6 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso, | |||
| 163 | return 0; | 125 | return 0; |
| 164 | } | 126 | } |
| 165 | 127 | ||
| 166 | static void hist_entry__free(struct hist_entry *he) | ||
| 167 | { | ||
| 168 | free(he); | ||
| 169 | } | ||
| 170 | |||
| 171 | /* | ||
| 172 | * collapse the histogram | ||
| 173 | */ | ||
| 174 | |||
| 175 | static struct rb_root collapse_hists; | ||
| 176 | |||
| 177 | static void collapse__insert_entry(struct hist_entry *he) | ||
| 178 | { | ||
| 179 | struct rb_node **p = &collapse_hists.rb_node; | ||
| 180 | struct rb_node *parent = NULL; | ||
| 181 | struct hist_entry *iter; | ||
| 182 | int64_t cmp; | ||
| 183 | |||
| 184 | while (*p != NULL) { | ||
| 185 | parent = *p; | ||
| 186 | iter = rb_entry(parent, struct hist_entry, rb_node); | ||
| 187 | |||
| 188 | cmp = hist_entry__collapse(iter, he); | ||
| 189 | |||
| 190 | if (!cmp) { | ||
| 191 | iter->count += he->count; | ||
| 192 | hist_entry__free(he); | ||
| 193 | return; | ||
| 194 | } | ||
| 195 | |||
| 196 | if (cmp < 0) | ||
| 197 | p = &(*p)->rb_left; | ||
| 198 | else | ||
| 199 | p = &(*p)->rb_right; | ||
| 200 | } | ||
| 201 | |||
| 202 | rb_link_node(&he->rb_node, parent, p); | ||
| 203 | rb_insert_color(&he->rb_node, &collapse_hists); | ||
| 204 | } | ||
| 205 | |||
| 206 | static void collapse__resort(void) | ||
| 207 | { | ||
| 208 | struct rb_node *next; | ||
| 209 | struct hist_entry *n; | ||
| 210 | |||
| 211 | if (!sort__need_collapse) | ||
| 212 | return; | ||
| 213 | |||
| 214 | next = rb_first(&hist); | ||
| 215 | while (next) { | ||
| 216 | n = rb_entry(next, struct hist_entry, rb_node); | ||
| 217 | next = rb_next(&n->rb_node); | ||
| 218 | |||
| 219 | rb_erase(&n->rb_node, &hist); | ||
| 220 | collapse__insert_entry(n); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * reverse the map, sort on count. | ||
| 226 | */ | ||
| 227 | |||
| 228 | static struct rb_root output_hists; | ||
| 229 | |||
| 230 | static void output__insert_entry(struct hist_entry *he) | ||
| 231 | { | ||
| 232 | struct rb_node **p = &output_hists.rb_node; | ||
| 233 | struct rb_node *parent = NULL; | ||
| 234 | struct hist_entry *iter; | ||
| 235 | |||
| 236 | while (*p != NULL) { | ||
| 237 | parent = *p; | ||
| 238 | iter = rb_entry(parent, struct hist_entry, rb_node); | ||
| 239 | |||
| 240 | if (he->count > iter->count) | ||
| 241 | p = &(*p)->rb_left; | ||
| 242 | else | ||
| 243 | p = &(*p)->rb_right; | ||
| 244 | } | ||
| 245 | |||
| 246 | rb_link_node(&he->rb_node, parent, p); | ||
| 247 | rb_insert_color(&he->rb_node, &output_hists); | ||
| 248 | } | ||
| 249 | |||
| 250 | static void output__resort(void) | ||
| 251 | { | ||
| 252 | struct rb_node *next; | ||
| 253 | struct hist_entry *n; | ||
| 254 | struct rb_root *tree = &hist; | ||
| 255 | |||
| 256 | if (sort__need_collapse) | ||
| 257 | tree = &collapse_hists; | ||
| 258 | |||
| 259 | next = rb_first(tree); | ||
| 260 | |||
| 261 | while (next) { | ||
| 262 | n = rb_entry(next, struct hist_entry, rb_node); | ||
| 263 | next = rb_next(&n->rb_node); | ||
| 264 | |||
| 265 | rb_erase(&n->rb_node, tree); | ||
| 266 | output__insert_entry(n); | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | static unsigned long total = 0, | ||
| 271 | total_mmap = 0, | ||
| 272 | total_comm = 0, | ||
| 273 | total_fork = 0, | ||
| 274 | total_unknown = 0; | ||
| 275 | |||
| 276 | static int | 128 | static int |
| 277 | process_sample_event(event_t *event, unsigned long offset, unsigned long head) | 129 | process_sample_event(event_t *event, unsigned long offset, unsigned long head) |
| 278 | { | 130 | { |
| @@ -861,7 +713,7 @@ more: | |||
| 861 | dsos__fprintf(stdout); | 713 | dsos__fprintf(stdout); |
| 862 | 714 | ||
| 863 | collapse__resort(); | 715 | collapse__resort(); |
| 864 | output__resort(); | 716 | output__resort(total); |
| 865 | 717 | ||
| 866 | find_annotations(); | 718 | find_annotations(); |
| 867 | 719 | ||
