diff options
| -rw-r--r-- | tools/perf/builtin-annotate.c | 17 | ||||
| -rw-r--r-- | tools/perf/builtin-diff.c | 50 | ||||
| -rw-r--r-- | tools/perf/builtin-report.c | 71 | ||||
| -rw-r--r-- | tools/perf/builtin-trace.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/event.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/event.h | 14 | ||||
| -rw-r--r-- | tools/perf/util/hist.c | 92 | ||||
| -rw-r--r-- | tools/perf/util/hist.h | 48 | ||||
| -rw-r--r-- | tools/perf/util/session.c | 2 | ||||
| -rw-r--r-- | tools/perf/util/session.h | 12 |
10 files changed, 146 insertions, 164 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index c7ac45a59ed5..3940964161b3 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -96,8 +96,7 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip) | |||
| 96 | return 0; | 96 | return 0; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static int perf_session__add_hist_entry(struct perf_session *self, | 99 | static int hists__add_entry(struct hists *self, struct addr_location *al) |
| 100 | struct addr_location *al) | ||
| 101 | { | 100 | { |
| 102 | struct hist_entry *he; | 101 | struct hist_entry *he; |
| 103 | 102 | ||
| @@ -112,7 +111,7 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
| 112 | return 0; | 111 | return 0; |
| 113 | } | 112 | } |
| 114 | 113 | ||
| 115 | he = __perf_session__add_hist_entry(&self->hists, al, NULL, 1); | 114 | he = __hists__add_entry(self, al, NULL, 1); |
| 116 | if (he == NULL) | 115 | if (he == NULL) |
| 117 | return -ENOMEM; | 116 | return -ENOMEM; |
| 118 | 117 | ||
| @@ -132,7 +131,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) | |||
| 132 | return -1; | 131 | return -1; |
| 133 | } | 132 | } |
| 134 | 133 | ||
| 135 | if (!al.filtered && perf_session__add_hist_entry(session, &al)) { | 134 | if (!al.filtered && hists__add_entry(&session->hists, &al)) { |
| 136 | pr_warning("problem incrementing symbol count, " | 135 | pr_warning("problem incrementing symbol count, " |
| 137 | "skipping event\n"); | 136 | "skipping event\n"); |
| 138 | return -1; | 137 | return -1; |
| @@ -514,11 +513,11 @@ static void annotate_sym(struct hist_entry *he) | |||
| 514 | free_source_line(he, len); | 513 | free_source_line(he, len); |
| 515 | } | 514 | } |
| 516 | 515 | ||
| 517 | static void perf_session__find_annotations(struct perf_session *self) | 516 | static void hists__find_annotations(struct hists *self) |
| 518 | { | 517 | { |
| 519 | struct rb_node *nd; | 518 | struct rb_node *nd; |
| 520 | 519 | ||
| 521 | for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) { | 520 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { |
| 522 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); | 521 | struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); |
| 523 | struct sym_priv *priv; | 522 | struct sym_priv *priv; |
| 524 | 523 | ||
| @@ -570,9 +569,9 @@ static int __cmd_annotate(void) | |||
| 570 | if (verbose > 2) | 569 | if (verbose > 2) |
| 571 | perf_session__fprintf_dsos(session, stdout); | 570 | perf_session__fprintf_dsos(session, stdout); |
| 572 | 571 | ||
| 573 | perf_session__collapse_resort(&session->hists); | 572 | hists__collapse_resort(&session->hists); |
| 574 | perf_session__output_resort(&session->hists, session->event_total[0]); | 573 | hists__output_resort(&session->hists); |
| 575 | perf_session__find_annotations(session); | 574 | hists__find_annotations(&session->hists); |
| 576 | out_delete: | 575 | out_delete: |
| 577 | perf_session__delete(session); | 576 | perf_session__delete(session); |
| 578 | 577 | ||
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 613a5c4f6d83..3a95a0260a5b 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
| @@ -22,10 +22,10 @@ static char diff__default_sort_order[] = "dso,symbol"; | |||
| 22 | static bool force; | 22 | static bool force; |
| 23 | static bool show_displacement; | 23 | static bool show_displacement; |
| 24 | 24 | ||
| 25 | static int perf_session__add_hist_entry(struct perf_session *self, | 25 | static int hists__add_entry(struct hists *self, |
| 26 | struct addr_location *al, u64 count) | 26 | struct addr_location *al, u64 count) |
| 27 | { | 27 | { |
| 28 | if (__perf_session__add_hist_entry(&self->hists, al, NULL, count) != NULL) | 28 | if (__hists__add_entry(self, al, NULL, count) != NULL) |
| 29 | return 0; | 29 | return 0; |
| 30 | return -ENOMEM; | 30 | return -ENOMEM; |
| 31 | } | 31 | } |
| @@ -49,12 +49,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi | |||
| 49 | 49 | ||
| 50 | event__parse_sample(event, session->sample_type, &data); | 50 | event__parse_sample(event, session->sample_type, &data); |
| 51 | 51 | ||
| 52 | if (perf_session__add_hist_entry(session, &al, data.period)) { | 52 | if (hists__add_entry(&session->hists, &al, data.period)) { |
| 53 | pr_warning("problem incrementing symbol count, skipping event\n"); | 53 | pr_warning("problem incrementing symbol count, skipping event\n"); |
| 54 | return -1; | 54 | return -1; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | session->events_stats.total += data.period; | 57 | session->hists.stats.total += data.period; |
| 58 | return 0; | 58 | return 0; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| @@ -87,35 +87,34 @@ static void perf_session__insert_hist_entry_by_name(struct rb_root *root, | |||
| 87 | rb_insert_color(&he->rb_node, root); | 87 | rb_insert_color(&he->rb_node, root); |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static void perf_session__resort_hist_entries(struct perf_session *self) | 90 | static void hists__resort_entries(struct hists *self) |
| 91 | { | 91 | { |
| 92 | unsigned long position = 1; | 92 | unsigned long position = 1; |
| 93 | struct rb_root tmp = RB_ROOT; | 93 | struct rb_root tmp = RB_ROOT; |
| 94 | struct rb_node *next = rb_first(&self->hists); | 94 | struct rb_node *next = rb_first(&self->entries); |
| 95 | 95 | ||
| 96 | while (next != NULL) { | 96 | while (next != NULL) { |
| 97 | struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node); | 97 | struct hist_entry *n = rb_entry(next, struct hist_entry, rb_node); |
| 98 | 98 | ||
| 99 | next = rb_next(&n->rb_node); | 99 | next = rb_next(&n->rb_node); |
| 100 | rb_erase(&n->rb_node, &self->hists); | 100 | rb_erase(&n->rb_node, &self->entries); |
| 101 | n->position = position++; | 101 | n->position = position++; |
| 102 | perf_session__insert_hist_entry_by_name(&tmp, n); | 102 | perf_session__insert_hist_entry_by_name(&tmp, n); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | self->hists = tmp; | 105 | self->entries = tmp; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static void perf_session__set_hist_entries_positions(struct perf_session *self) | 108 | static void hists__set_positions(struct hists *self) |
| 109 | { | 109 | { |
| 110 | perf_session__output_resort(&self->hists, self->events_stats.total); | 110 | hists__output_resort(self); |
| 111 | perf_session__resort_hist_entries(self); | 111 | hists__resort_entries(self); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | static struct hist_entry * | 114 | static struct hist_entry *hists__find_entry(struct hists *self, |
| 115 | perf_session__find_hist_entry(struct perf_session *self, | 115 | struct hist_entry *he) |
| 116 | struct hist_entry *he) | ||
| 117 | { | 116 | { |
| 118 | struct rb_node *n = self->hists.rb_node; | 117 | struct rb_node *n = self->entries.rb_node; |
| 119 | 118 | ||
| 120 | while (n) { | 119 | while (n) { |
| 121 | struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); | 120 | struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); |
| @@ -132,14 +131,13 @@ perf_session__find_hist_entry(struct perf_session *self, | |||
| 132 | return NULL; | 131 | return NULL; |
| 133 | } | 132 | } |
| 134 | 133 | ||
| 135 | static void perf_session__match_hists(struct perf_session *old_session, | 134 | static void hists__match(struct hists *older, struct hists *newer) |
| 136 | struct perf_session *new_session) | ||
| 137 | { | 135 | { |
| 138 | struct rb_node *nd; | 136 | struct rb_node *nd; |
| 139 | 137 | ||
| 140 | for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) { | 138 | for (nd = rb_first(&newer->entries); nd; nd = rb_next(nd)) { |
| 141 | struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); | 139 | struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); |
| 142 | pos->pair = perf_session__find_hist_entry(old_session, pos); | 140 | pos->pair = hists__find_entry(older, pos); |
| 143 | } | 141 | } |
| 144 | } | 142 | } |
| 145 | 143 | ||
| @@ -159,15 +157,13 @@ static int __cmd_diff(void) | |||
| 159 | goto out_delete; | 157 | goto out_delete; |
| 160 | } | 158 | } |
| 161 | 159 | ||
| 162 | perf_session__output_resort(&session[1]->hists, | 160 | hists__output_resort(&session[1]->hists); |
| 163 | session[1]->events_stats.total); | ||
| 164 | if (show_displacement) | 161 | if (show_displacement) |
| 165 | perf_session__set_hist_entries_positions(session[0]); | 162 | hists__set_positions(&session[0]->hists); |
| 166 | 163 | ||
| 167 | perf_session__match_hists(session[0], session[1]); | 164 | hists__match(&session[0]->hists, &session[1]->hists); |
| 168 | perf_session__fprintf_hists(&session[1]->hists, session[0], | 165 | hists__fprintf(&session[1]->hists, &session[0]->hists, |
| 169 | show_displacement, stdout, | 166 | show_displacement, stdout); |
| 170 | session[1]->events_stats.total); | ||
| 171 | out_delete: | 167 | out_delete: |
| 172 | for (i = 0; i < 2; ++i) | 168 | for (i = 0; i < 2; ++i) |
| 173 | perf_session__delete(session[i]); | 169 | perf_session__delete(session[i]); |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 642a6d8eb5dc..53077fd973f0 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -44,16 +44,17 @@ static char *pretty_printing_style = default_pretty_printing_style; | |||
| 44 | 44 | ||
| 45 | static char callchain_default_opt[] = "fractal,0.5"; | 45 | static char callchain_default_opt[] = "fractal,0.5"; |
| 46 | 46 | ||
| 47 | static struct event_stat_id *get_stats(struct perf_session *self, | 47 | static struct hists *perf_session__hists_findnew(struct perf_session *self, |
| 48 | u64 event_stream, u32 type, u64 config) | 48 | u64 event_stream, u32 type, |
| 49 | u64 config) | ||
| 49 | { | 50 | { |
| 50 | struct rb_node **p = &self->stats_by_id.rb_node; | 51 | struct rb_node **p = &self->hists_tree.rb_node; |
| 51 | struct rb_node *parent = NULL; | 52 | struct rb_node *parent = NULL; |
| 52 | struct event_stat_id *iter, *new; | 53 | struct hists *iter, *new; |
| 53 | 54 | ||
| 54 | while (*p != NULL) { | 55 | while (*p != NULL) { |
| 55 | parent = *p; | 56 | parent = *p; |
| 56 | iter = rb_entry(parent, struct event_stat_id, rb_node); | 57 | iter = rb_entry(parent, struct hists, rb_node); |
| 57 | if (iter->config == config) | 58 | if (iter->config == config) |
| 58 | return iter; | 59 | return iter; |
| 59 | 60 | ||
| @@ -64,15 +65,15 @@ static struct event_stat_id *get_stats(struct perf_session *self, | |||
| 64 | p = &(*p)->rb_left; | 65 | p = &(*p)->rb_left; |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | new = malloc(sizeof(struct event_stat_id)); | 68 | new = malloc(sizeof(struct hists)); |
| 68 | if (new == NULL) | 69 | if (new == NULL) |
| 69 | return NULL; | 70 | return NULL; |
| 70 | memset(new, 0, sizeof(struct event_stat_id)); | 71 | memset(new, 0, sizeof(struct hists)); |
| 71 | new->event_stream = event_stream; | 72 | new->event_stream = event_stream; |
| 72 | new->config = config; | 73 | new->config = config; |
| 73 | new->type = type; | 74 | new->type = type; |
| 74 | rb_link_node(&new->rb_node, parent, p); | 75 | rb_link_node(&new->rb_node, parent, p); |
| 75 | rb_insert_color(&new->rb_node, &self->stats_by_id); | 76 | rb_insert_color(&new->rb_node, &self->hists_tree); |
| 76 | return new; | 77 | return new; |
| 77 | } | 78 | } |
| 78 | 79 | ||
| @@ -84,7 +85,7 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
| 84 | struct symbol *parent = NULL; | 85 | struct symbol *parent = NULL; |
| 85 | int err = -ENOMEM; | 86 | int err = -ENOMEM; |
| 86 | struct hist_entry *he; | 87 | struct hist_entry *he; |
| 87 | struct event_stat_id *stats; | 88 | struct hists *hists; |
| 88 | struct perf_event_attr *attr; | 89 | struct perf_event_attr *attr; |
| 89 | 90 | ||
| 90 | if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) { | 91 | if ((sort__has_parent || symbol_conf.use_callchain) && data->callchain) { |
| @@ -96,13 +97,12 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
| 96 | 97 | ||
| 97 | attr = perf_header__find_attr(data->id, &self->header); | 98 | attr = perf_header__find_attr(data->id, &self->header); |
| 98 | if (attr) | 99 | if (attr) |
| 99 | stats = get_stats(self, data->id, attr->type, attr->config); | 100 | hists = perf_session__hists_findnew(self, data->id, attr->type, attr->config); |
| 100 | else | 101 | else |
| 101 | stats = get_stats(self, data->id, 0, 0); | 102 | hists = perf_session__hists_findnew(self, data->id, 0, 0); |
| 102 | if (stats == NULL) | 103 | if (hists == NULL) |
| 103 | goto out_free_syms; | 104 | goto out_free_syms; |
| 104 | he = __perf_session__add_hist_entry(&stats->hists, al, parent, | 105 | he = __hists__add_entry(hists, al, parent, data->period); |
| 105 | data->period); | ||
| 106 | if (he == NULL) | 106 | if (he == NULL) |
| 107 | goto out_free_syms; | 107 | goto out_free_syms; |
| 108 | err = 0; | 108 | err = 0; |
| @@ -117,18 +117,19 @@ static int add_event_total(struct perf_session *session, | |||
| 117 | struct sample_data *data, | 117 | struct sample_data *data, |
| 118 | struct perf_event_attr *attr) | 118 | struct perf_event_attr *attr) |
| 119 | { | 119 | { |
| 120 | struct event_stat_id *stats; | 120 | struct hists *hists; |
| 121 | 121 | ||
| 122 | if (attr) | 122 | if (attr) |
| 123 | stats = get_stats(session, data->id, attr->type, attr->config); | 123 | hists = perf_session__hists_findnew(session, data->id, |
| 124 | attr->type, attr->config); | ||
| 124 | else | 125 | else |
| 125 | stats = get_stats(session, data->id, 0, 0); | 126 | hists = perf_session__hists_findnew(session, data->id, 0, 0); |
| 126 | 127 | ||
| 127 | if (!stats) | 128 | if (!hists) |
| 128 | return -ENOMEM; | 129 | return -ENOMEM; |
| 129 | 130 | ||
| 130 | stats->stats.total += data->period; | 131 | hists->stats.total += data->period; |
| 131 | session->events_stats.total += data->period; | 132 | session->hists.stats.total += data->period; |
| 132 | return 0; | 133 | return 0; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| @@ -292,35 +293,33 @@ static int __cmd_report(void) | |||
| 292 | if (verbose > 2) | 293 | if (verbose > 2) |
| 293 | perf_session__fprintf_dsos(session, stdout); | 294 | perf_session__fprintf_dsos(session, stdout); |
| 294 | 295 | ||
| 295 | next = rb_first(&session->stats_by_id); | 296 | next = rb_first(&session->hists_tree); |
| 296 | while (next) { | 297 | while (next) { |
| 297 | struct event_stat_id *stats; | 298 | struct hists *hists; |
| 298 | u64 nr_hists; | 299 | u64 nr_hists; |
| 299 | 300 | ||
| 300 | stats = rb_entry(next, struct event_stat_id, rb_node); | 301 | hists = rb_entry(next, struct hists, rb_node); |
| 301 | perf_session__collapse_resort(&stats->hists); | 302 | hists__collapse_resort(hists); |
| 302 | nr_hists = perf_session__output_resort(&stats->hists, | 303 | nr_hists = hists__output_resort(hists); |
| 303 | stats->stats.total); | ||
| 304 | if (use_browser) | 304 | if (use_browser) |
| 305 | perf_session__browse_hists(&stats->hists, nr_hists, | 305 | perf_session__browse_hists(&hists->entries, nr_hists, |
| 306 | stats->stats.total, help, | 306 | hists->stats.total, help, |
| 307 | input_name); | 307 | input_name); |
| 308 | else { | 308 | else { |
| 309 | if (rb_first(&session->stats_by_id) == | 309 | if (rb_first(&session->hists.entries) == |
| 310 | rb_last(&session->stats_by_id)) | 310 | rb_last(&session->hists.entries)) |
| 311 | fprintf(stdout, "# Samples: %Ld\n#\n", | 311 | fprintf(stdout, "# Samples: %Ld\n#\n", |
| 312 | stats->stats.total); | 312 | hists->stats.total); |
| 313 | else | 313 | else |
| 314 | fprintf(stdout, "# Samples: %Ld %s\n#\n", | 314 | fprintf(stdout, "# Samples: %Ld %s\n#\n", |
| 315 | stats->stats.total, | 315 | hists->stats.total, |
| 316 | __event_name(stats->type, stats->config)); | 316 | __event_name(hists->type, hists->config)); |
| 317 | 317 | ||
| 318 | perf_session__fprintf_hists(&stats->hists, NULL, false, stdout, | 318 | hists__fprintf(hists, NULL, false, stdout); |
| 319 | stats->stats.total); | ||
| 320 | fprintf(stdout, "\n\n"); | 319 | fprintf(stdout, "\n\n"); |
| 321 | } | 320 | } |
| 322 | 321 | ||
| 323 | next = rb_next(&stats->rb_node); | 322 | next = rb_next(&hists->rb_node); |
| 324 | } | 323 | } |
| 325 | 324 | ||
| 326 | if (!use_browser && sort_order == default_sort_order && | 325 | if (!use_browser && sort_order == default_sort_order && |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 9c483e92e8db..6e268ca761e9 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
| @@ -107,7 +107,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) | |||
| 107 | data.time, thread->comm); | 107 | data.time, thread->comm); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | session->events_stats.total += data.period; | 110 | session->hists.stats.total += data.period; |
| 111 | return 0; | 111 | return 0; |
| 112 | } | 112 | } |
| 113 | 113 | ||
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index d2ea9dd9fdf1..cce006ec8f05 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -368,7 +368,7 @@ int event__process_comm(event_t *self, struct perf_session *session) | |||
| 368 | int event__process_lost(event_t *self, struct perf_session *session) | 368 | int event__process_lost(event_t *self, struct perf_session *session) |
| 369 | { | 369 | { |
| 370 | dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); | 370 | dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost); |
| 371 | session->events_stats.lost += self->lost.lost; | 371 | session->hists.stats.lost += self->lost.lost; |
| 372 | return 0; | 372 | return 0; |
| 373 | } | 373 | } |
| 374 | 374 | ||
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 6cc1b1dced55..48c2cc9dae4f 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
| @@ -131,20 +131,6 @@ typedef union event_union { | |||
| 131 | struct build_id_event build_id; | 131 | struct build_id_event build_id; |
| 132 | } event_t; | 132 | } event_t; |
| 133 | 133 | ||
| 134 | struct events_stats { | ||
| 135 | u64 total; | ||
| 136 | u64 lost; | ||
| 137 | }; | ||
| 138 | |||
| 139 | struct event_stat_id { | ||
| 140 | struct rb_node rb_node; | ||
| 141 | struct rb_root hists; | ||
| 142 | struct events_stats stats; | ||
| 143 | u64 config; | ||
| 144 | u64 event_stream; | ||
| 145 | u32 type; | ||
| 146 | }; | ||
| 147 | |||
| 148 | void event__print_totals(void); | 134 | void event__print_totals(void); |
| 149 | 135 | ||
| 150 | struct perf_session; | 136 | struct perf_session; |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0f154a530dfd..410cf56c9662 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -8,21 +8,21 @@ struct callchain_param callchain_param = { | |||
| 8 | .min_percent = 0.5 | 8 | .min_percent = 0.5 |
| 9 | }; | 9 | }; |
| 10 | 10 | ||
| 11 | static void perf_session__add_cpumode_count(struct hist_entry *he, | 11 | static void hist_entry__add_cpumode_count(struct hist_entry *self, |
| 12 | unsigned int cpumode, u64 count) | 12 | unsigned int cpumode, u64 count) |
| 13 | { | 13 | { |
| 14 | switch (cpumode) { | 14 | switch (cpumode) { |
| 15 | case PERF_RECORD_MISC_KERNEL: | 15 | case PERF_RECORD_MISC_KERNEL: |
| 16 | he->count_sys += count; | 16 | self->count_sys += count; |
| 17 | break; | 17 | break; |
| 18 | case PERF_RECORD_MISC_USER: | 18 | case PERF_RECORD_MISC_USER: |
| 19 | he->count_us += count; | 19 | self->count_us += count; |
| 20 | break; | 20 | break; |
| 21 | case PERF_RECORD_MISC_GUEST_KERNEL: | 21 | case PERF_RECORD_MISC_GUEST_KERNEL: |
| 22 | he->count_guest_sys += count; | 22 | self->count_guest_sys += count; |
| 23 | break; | 23 | break; |
| 24 | case PERF_RECORD_MISC_GUEST_USER: | 24 | case PERF_RECORD_MISC_GUEST_USER: |
| 25 | he->count_guest_us += count; | 25 | self->count_guest_us += count; |
| 26 | break; | 26 | break; |
| 27 | default: | 27 | default: |
| 28 | break; | 28 | break; |
| @@ -47,12 +47,11 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) | |||
| 47 | return self; | 47 | return self; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | 50 | struct hist_entry *__hists__add_entry(struct hists *self, |
| 51 | struct addr_location *al, | 51 | struct addr_location *al, |
| 52 | struct symbol *sym_parent, | 52 | struct symbol *sym_parent, u64 count) |
| 53 | u64 count) | ||
| 54 | { | 53 | { |
| 55 | struct rb_node **p = &hists->rb_node; | 54 | struct rb_node **p = &self->entries.rb_node; |
| 56 | struct rb_node *parent = NULL; | 55 | struct rb_node *parent = NULL; |
| 57 | struct hist_entry *he; | 56 | struct hist_entry *he; |
| 58 | struct hist_entry entry = { | 57 | struct hist_entry entry = { |
| @@ -89,9 +88,9 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
| 89 | if (!he) | 88 | if (!he) |
| 90 | return NULL; | 89 | return NULL; |
| 91 | rb_link_node(&he->rb_node, parent, p); | 90 | rb_link_node(&he->rb_node, parent, p); |
| 92 | rb_insert_color(&he->rb_node, hists); | 91 | rb_insert_color(&he->rb_node, &self->entries); |
| 93 | out: | 92 | out: |
| 94 | perf_session__add_cpumode_count(he, al->cpumode, count); | 93 | hist_entry__add_cpumode_count(he, al->cpumode, count); |
| 95 | return he; | 94 | return he; |
| 96 | } | 95 | } |
| 97 | 96 | ||
| @@ -167,7 +166,7 @@ static void collapse__insert_entry(struct rb_root *root, struct hist_entry *he) | |||
| 167 | rb_insert_color(&he->rb_node, root); | 166 | rb_insert_color(&he->rb_node, root); |
| 168 | } | 167 | } |
| 169 | 168 | ||
| 170 | void perf_session__collapse_resort(struct rb_root *hists) | 169 | void hists__collapse_resort(struct hists *self) |
| 171 | { | 170 | { |
| 172 | struct rb_root tmp; | 171 | struct rb_root tmp; |
| 173 | struct rb_node *next; | 172 | struct rb_node *next; |
| @@ -177,28 +176,28 @@ void perf_session__collapse_resort(struct rb_root *hists) | |||
| 177 | return; | 176 | return; |
| 178 | 177 | ||
| 179 | tmp = RB_ROOT; | 178 | tmp = RB_ROOT; |
| 180 | next = rb_first(hists); | 179 | next = rb_first(&self->entries); |
| 181 | 180 | ||
| 182 | while (next) { | 181 | while (next) { |
| 183 | n = rb_entry(next, struct hist_entry, rb_node); | 182 | n = rb_entry(next, struct hist_entry, rb_node); |
| 184 | next = rb_next(&n->rb_node); | 183 | next = rb_next(&n->rb_node); |
| 185 | 184 | ||
| 186 | rb_erase(&n->rb_node, hists); | 185 | rb_erase(&n->rb_node, &self->entries); |
| 187 | collapse__insert_entry(&tmp, n); | 186 | collapse__insert_entry(&tmp, n); |
| 188 | } | 187 | } |
| 189 | 188 | ||
| 190 | *hists = tmp; | 189 | self->entries = tmp; |
| 191 | } | 190 | } |
| 192 | 191 | ||
| 193 | /* | 192 | /* |
| 194 | * reverse the map, sort on count. | 193 | * reverse the map, sort on count. |
| 195 | */ | 194 | */ |
| 196 | 195 | ||
| 197 | static void perf_session__insert_output_hist_entry(struct rb_root *root, | 196 | static void __hists__insert_output_entry(struct rb_root *entries, |
| 198 | struct hist_entry *he, | 197 | struct hist_entry *he, |
| 199 | u64 min_callchain_hits) | 198 | u64 min_callchain_hits) |
| 200 | { | 199 | { |
| 201 | struct rb_node **p = &root->rb_node; | 200 | struct rb_node **p = &entries->rb_node; |
| 202 | struct rb_node *parent = NULL; | 201 | struct rb_node *parent = NULL; |
| 203 | struct hist_entry *iter; | 202 | struct hist_entry *iter; |
| 204 | 203 | ||
| @@ -217,10 +216,10 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root, | |||
| 217 | } | 216 | } |
| 218 | 217 | ||
| 219 | rb_link_node(&he->rb_node, parent, p); | 218 | rb_link_node(&he->rb_node, parent, p); |
| 220 | rb_insert_color(&he->rb_node, root); | 219 | rb_insert_color(&he->rb_node, entries); |
| 221 | } | 220 | } |
| 222 | 221 | ||
| 223 | u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples) | 222 | u64 hists__output_resort(struct hists *self) |
| 224 | { | 223 | { |
| 225 | struct rb_root tmp; | 224 | struct rb_root tmp; |
| 226 | struct rb_node *next; | 225 | struct rb_node *next; |
| @@ -228,23 +227,21 @@ u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples) | |||
| 228 | u64 min_callchain_hits; | 227 | u64 min_callchain_hits; |
| 229 | u64 nr_hists = 0; | 228 | u64 nr_hists = 0; |
| 230 | 229 | ||
| 231 | min_callchain_hits = | 230 | min_callchain_hits = self->stats.total * (callchain_param.min_percent / 100); |
| 232 | total_samples * (callchain_param.min_percent / 100); | ||
| 233 | 231 | ||
| 234 | tmp = RB_ROOT; | 232 | tmp = RB_ROOT; |
| 235 | next = rb_first(hists); | 233 | next = rb_first(&self->entries); |
| 236 | 234 | ||
| 237 | while (next) { | 235 | while (next) { |
| 238 | n = rb_entry(next, struct hist_entry, rb_node); | 236 | n = rb_entry(next, struct hist_entry, rb_node); |
| 239 | next = rb_next(&n->rb_node); | 237 | next = rb_next(&n->rb_node); |
| 240 | 238 | ||
| 241 | rb_erase(&n->rb_node, hists); | 239 | rb_erase(&n->rb_node, &self->entries); |
| 242 | perf_session__insert_output_hist_entry(&tmp, n, | 240 | __hists__insert_output_entry(&tmp, n, min_callchain_hits); |
| 243 | min_callchain_hits); | ||
| 244 | ++nr_hists; | 241 | ++nr_hists; |
| 245 | } | 242 | } |
| 246 | 243 | ||
| 247 | *hists = tmp; | 244 | self->entries = tmp; |
| 248 | return nr_hists; | 245 | return nr_hists; |
| 249 | } | 246 | } |
| 250 | 247 | ||
| @@ -500,12 +497,9 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
| 500 | return ret; | 497 | return ret; |
| 501 | } | 498 | } |
| 502 | 499 | ||
| 503 | int hist_entry__snprintf(struct hist_entry *self, | 500 | int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size, |
| 504 | char *s, size_t size, | 501 | struct hists *pair_hists, bool show_displacement, |
| 505 | struct perf_session *pair_session, | 502 | long displacement, bool color, u64 session_total) |
| 506 | bool show_displacement, | ||
| 507 | long displacement, bool color, | ||
| 508 | u64 session_total) | ||
| 509 | { | 503 | { |
| 510 | struct sort_entry *se; | 504 | struct sort_entry *se; |
| 511 | u64 count, total, count_sys, count_us, count_guest_sys, count_guest_us; | 505 | u64 count, total, count_sys, count_us, count_guest_sys, count_guest_us; |
| @@ -515,9 +509,9 @@ int hist_entry__snprintf(struct hist_entry *self, | |||
| 515 | if (symbol_conf.exclude_other && !self->parent) | 509 | if (symbol_conf.exclude_other && !self->parent) |
| 516 | return 0; | 510 | return 0; |
| 517 | 511 | ||
| 518 | if (pair_session) { | 512 | if (pair_hists) { |
| 519 | count = self->pair ? self->pair->count : 0; | 513 | count = self->pair ? self->pair->count : 0; |
| 520 | total = pair_session->events_stats.total; | 514 | total = pair_hists->stats.total; |
| 521 | count_sys = self->pair ? self->pair->count_sys : 0; | 515 | count_sys = self->pair ? self->pair->count_sys : 0; |
| 522 | count_us = self->pair ? self->pair->count_us : 0; | 516 | count_us = self->pair ? self->pair->count_us : 0; |
| 523 | count_guest_sys = self->pair ? self->pair->count_guest_sys : 0; | 517 | count_guest_sys = self->pair ? self->pair->count_guest_sys : 0; |
| @@ -569,7 +563,7 @@ int hist_entry__snprintf(struct hist_entry *self, | |||
| 569 | ret += snprintf(s + ret, size - ret, "%11lld", count); | 563 | ret += snprintf(s + ret, size - ret, "%11lld", count); |
| 570 | } | 564 | } |
| 571 | 565 | ||
| 572 | if (pair_session) { | 566 | if (pair_hists) { |
| 573 | char bf[32]; | 567 | char bf[32]; |
| 574 | double old_percent = 0, new_percent = 0, diff; | 568 | double old_percent = 0, new_percent = 0, diff; |
| 575 | 569 | ||
| @@ -615,14 +609,12 @@ int hist_entry__snprintf(struct hist_entry *self, | |||
| 615 | return ret; | 609 | return ret; |
| 616 | } | 610 | } |
| 617 | 611 | ||
| 618 | int hist_entry__fprintf(struct hist_entry *self, | 612 | int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists, |
| 619 | struct perf_session *pair_session, | 613 | bool show_displacement, long displacement, FILE *fp, |
| 620 | bool show_displacement, | ||
| 621 | long displacement, FILE *fp, | ||
| 622 | u64 session_total) | 614 | u64 session_total) |
| 623 | { | 615 | { |
| 624 | char bf[512]; | 616 | char bf[512]; |
| 625 | hist_entry__snprintf(self, bf, sizeof(bf), pair_session, | 617 | hist_entry__snprintf(self, bf, sizeof(bf), pair_hists, |
| 626 | show_displacement, displacement, | 618 | show_displacement, displacement, |
| 627 | true, session_total); | 619 | true, session_total); |
| 628 | return fprintf(fp, "%s\n", bf); | 620 | return fprintf(fp, "%s\n", bf); |
| @@ -644,10 +636,8 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, FILE *fp, | |||
| 644 | left_margin); | 636 | left_margin); |
| 645 | } | 637 | } |
| 646 | 638 | ||
| 647 | size_t perf_session__fprintf_hists(struct rb_root *hists, | 639 | size_t hists__fprintf(struct hists *self, struct hists *pair, |
| 648 | struct perf_session *pair, | 640 | bool show_displacement, FILE *fp) |
| 649 | bool show_displacement, FILE *fp, | ||
| 650 | u64 session_total) | ||
| 651 | { | 641 | { |
| 652 | struct sort_entry *se; | 642 | struct sort_entry *se; |
| 653 | struct rb_node *nd; | 643 | struct rb_node *nd; |
| @@ -753,7 +743,7 @@ size_t perf_session__fprintf_hists(struct rb_root *hists, | |||
| 753 | fprintf(fp, "\n#\n"); | 743 | fprintf(fp, "\n#\n"); |
| 754 | 744 | ||
| 755 | print_entries: | 745 | print_entries: |
| 756 | for (nd = rb_first(hists); nd; nd = rb_next(nd)) { | 746 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { |
| 757 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | 747 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
| 758 | 748 | ||
| 759 | if (show_displacement) { | 749 | if (show_displacement) { |
| @@ -765,10 +755,10 @@ print_entries: | |||
| 765 | ++position; | 755 | ++position; |
| 766 | } | 756 | } |
| 767 | ret += hist_entry__fprintf(h, pair, show_displacement, | 757 | ret += hist_entry__fprintf(h, pair, show_displacement, |
| 768 | displacement, fp, session_total); | 758 | displacement, fp, self->stats.total); |
| 769 | 759 | ||
| 770 | if (symbol_conf.use_callchain) | 760 | if (symbol_conf.use_callchain) |
| 771 | ret += hist_entry__fprintf_callchain(h, fp, session_total); | 761 | ret += hist_entry__fprintf_callchain(h, fp, self->stats.total); |
| 772 | 762 | ||
| 773 | if (h->ms.map == NULL && verbose > 1) { | 763 | if (h->ms.map == NULL && verbose > 1) { |
| 774 | __map_groups__fprintf_maps(&h->thread->mg, | 764 | __map_groups__fprintf_maps(&h->thread->mg, |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index b49013adb34b..bdde81eca69f 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -6,34 +6,40 @@ | |||
| 6 | 6 | ||
| 7 | extern struct callchain_param callchain_param; | 7 | extern struct callchain_param callchain_param; |
| 8 | 8 | ||
| 9 | struct perf_session; | ||
| 10 | struct hist_entry; | 9 | struct hist_entry; |
| 11 | struct addr_location; | 10 | struct addr_location; |
| 12 | struct symbol; | 11 | struct symbol; |
| 13 | struct rb_root; | 12 | struct rb_root; |
| 14 | 13 | ||
| 15 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | 14 | struct events_stats { |
| 16 | struct addr_location *al, | 15 | u64 total; |
| 17 | struct symbol *parent, | 16 | u64 lost; |
| 18 | u64 count); | 17 | }; |
| 18 | |||
| 19 | struct hists { | ||
| 20 | struct rb_node rb_node; | ||
| 21 | struct rb_root entries; | ||
| 22 | struct events_stats stats; | ||
| 23 | u64 config; | ||
| 24 | u64 event_stream; | ||
| 25 | u32 type; | ||
| 26 | }; | ||
| 27 | |||
| 28 | struct hist_entry *__hists__add_entry(struct hists *self, | ||
| 29 | struct addr_location *al, | ||
| 30 | struct symbol *parent, u64 count); | ||
| 19 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); | 31 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); |
| 20 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); | 32 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); |
| 21 | int hist_entry__fprintf(struct hist_entry *self, | 33 | int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists, |
| 22 | struct perf_session *pair_session, | 34 | bool show_displacement, long displacement, FILE *fp, |
| 23 | bool show_displacement, | 35 | u64 total); |
| 24 | long displacement, FILE *fp, | 36 | int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size, |
| 25 | u64 session_total); | 37 | struct hists *pair_hists, bool show_displacement, |
| 26 | int hist_entry__snprintf(struct hist_entry *self, | 38 | long displacement, bool color, u64 total); |
| 27 | char *bf, size_t size, | ||
| 28 | struct perf_session *pair_session, | ||
| 29 | bool show_displacement, long displacement, | ||
| 30 | bool color, u64 session_total); | ||
| 31 | void hist_entry__free(struct hist_entry *); | 39 | void hist_entry__free(struct hist_entry *); |
| 32 | 40 | ||
| 33 | u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples); | 41 | u64 hists__output_resort(struct hists *self); |
| 34 | void perf_session__collapse_resort(struct rb_root *hists); | 42 | void hists__collapse_resort(struct hists *self); |
| 35 | size_t perf_session__fprintf_hists(struct rb_root *hists, | 43 | size_t hists__fprintf(struct hists *self, struct hists *pair, |
| 36 | struct perf_session *pair, | 44 | bool show_displacement, FILE *fp); |
| 37 | bool show_displacement, FILE *fp, | ||
| 38 | u64 session_total); | ||
| 39 | #endif /* __PERF_HIST_H */ | 45 | #endif /* __PERF_HIST_H */ |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 4130036a0109..72a7f6ae0293 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -89,7 +89,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc | |||
| 89 | 89 | ||
| 90 | memcpy(self->filename, filename, len); | 90 | memcpy(self->filename, filename, len); |
| 91 | self->threads = RB_ROOT; | 91 | self->threads = RB_ROOT; |
| 92 | self->stats_by_id = RB_ROOT; | 92 | self->hists_tree = RB_ROOT; |
| 93 | self->last_match = NULL; | 93 | self->last_match = NULL; |
| 94 | self->mmap_window = 32; | 94 | self->mmap_window = 32; |
| 95 | self->cwd = NULL; | 95 | self->cwd = NULL; |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 242d528bfae2..46190f94b547 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #ifndef __PERF_SESSION_H | 1 | #ifndef __PERF_SESSION_H |
| 2 | #define __PERF_SESSION_H | 2 | #define __PERF_SESSION_H |
| 3 | 3 | ||
| 4 | #include "hist.h" | ||
| 4 | #include "event.h" | 5 | #include "event.h" |
| 5 | #include "header.h" | 6 | #include "header.h" |
| 6 | #include "symbol.h" | 7 | #include "symbol.h" |
| @@ -28,11 +29,16 @@ struct perf_session { | |||
| 28 | struct thread *last_match; | 29 | struct thread *last_match; |
| 29 | struct machine host_machine; | 30 | struct machine host_machine; |
| 30 | struct rb_root machines; | 31 | struct rb_root machines; |
| 31 | struct events_stats events_stats; | 32 | struct rb_root hists_tree; |
| 32 | struct rb_root stats_by_id; | ||
| 33 | unsigned long event_total[PERF_RECORD_MAX]; | 33 | unsigned long event_total[PERF_RECORD_MAX]; |
| 34 | unsigned long unknown_events; | 34 | unsigned long unknown_events; |
| 35 | struct rb_root hists; | 35 | /* |
| 36 | * FIXME: should point to the first entry in hists_tree and | ||
| 37 | * be a hists instance. Right now its only 'report' | ||
| 38 | * that is using ->hists_tree while all the rest use | ||
| 39 | * ->hists. | ||
| 40 | */ | ||
| 41 | struct hists hists; | ||
| 36 | u64 sample_type; | 42 | u64 sample_type; |
| 37 | int fd; | 43 | int fd; |
| 38 | bool fd_pipe; | 44 | bool fd_pipe; |
