diff options
Diffstat (limited to 'tools/perf/builtin-diff.c')
-rw-r--r-- | tools/perf/builtin-diff.c | 74 |
1 files changed, 32 insertions, 42 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index bd71b8ceafb7..18b3f505f9db 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -42,8 +42,8 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi | |||
42 | struct addr_location al; | 42 | struct addr_location al; |
43 | struct sample_data data = { .period = 1, }; | 43 | struct sample_data data = { .period = 1, }; |
44 | 44 | ||
45 | dump_printf("(IP, %d): %d: %p\n", event->header.misc, | 45 | dump_printf("(IP, %d): %d: %#Lx\n", event->header.misc, |
46 | event->ip.pid, (void *)(long)event->ip.ip); | 46 | event->ip.pid, event->ip.ip); |
47 | 47 | ||
48 | if (event__preprocess_sample(event, session, &al, NULL) < 0) { | 48 | if (event__preprocess_sample(event, session, &al, NULL) < 0) { |
49 | pr_warning("problem processing %d event, skipping it.\n", | 49 | pr_warning("problem processing %d event, skipping it.\n", |
@@ -51,12 +51,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi | |||
51 | return -1; | 51 | return -1; |
52 | } | 52 | } |
53 | 53 | ||
54 | if (al.filtered) | 54 | if (al.filtered || al.sym == NULL) |
55 | return 0; | 55 | return 0; |
56 | 56 | ||
57 | event__parse_sample(event, session->sample_type, &data); | 57 | event__parse_sample(event, session->sample_type, &data); |
58 | 58 | ||
59 | if (al.sym && perf_session__add_hist_entry(session, &al, data.period)) { | 59 | if (perf_session__add_hist_entry(session, &al, data.period)) { |
60 | pr_warning("problem incrementing symbol count, skipping event\n"); | 60 | pr_warning("problem incrementing symbol count, skipping event\n"); |
61 | return -1; | 61 | return -1; |
62 | } | 62 | } |
@@ -66,12 +66,12 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi | |||
66 | } | 66 | } |
67 | 67 | ||
68 | static struct perf_event_ops event_ops = { | 68 | static struct perf_event_ops event_ops = { |
69 | .process_sample_event = diff__process_sample_event, | 69 | .sample = diff__process_sample_event, |
70 | .process_mmap_event = event__process_mmap, | 70 | .mmap = event__process_mmap, |
71 | .process_comm_event = event__process_comm, | 71 | .comm = event__process_comm, |
72 | .process_exit_event = event__process_task, | 72 | .exit = event__process_task, |
73 | .process_fork_event = event__process_task, | 73 | .fork = event__process_task, |
74 | .process_lost_event = event__process_lost, | 74 | .lost = event__process_lost, |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static void perf_session__insert_hist_entry_by_name(struct rb_root *root, | 77 | static void perf_session__insert_hist_entry_by_name(struct rb_root *root, |
@@ -82,29 +82,19 @@ static void perf_session__insert_hist_entry_by_name(struct rb_root *root, | |||
82 | struct hist_entry *iter; | 82 | struct hist_entry *iter; |
83 | 83 | ||
84 | while (*p != NULL) { | 84 | while (*p != NULL) { |
85 | int cmp; | ||
86 | parent = *p; | 85 | parent = *p; |
87 | iter = rb_entry(parent, struct hist_entry, rb_node); | 86 | iter = rb_entry(parent, struct hist_entry, rb_node); |
88 | 87 | if (hist_entry__cmp(he, iter) < 0) | |
89 | cmp = strcmp(he->map->dso->name, iter->map->dso->name); | ||
90 | if (cmp > 0) | ||
91 | p = &(*p)->rb_left; | 88 | p = &(*p)->rb_left; |
92 | else if (cmp < 0) | 89 | else |
93 | p = &(*p)->rb_right; | 90 | p = &(*p)->rb_right; |
94 | else { | ||
95 | cmp = strcmp(he->sym->name, iter->sym->name); | ||
96 | if (cmp > 0) | ||
97 | p = &(*p)->rb_left; | ||
98 | else | ||
99 | p = &(*p)->rb_right; | ||
100 | } | ||
101 | } | 91 | } |
102 | 92 | ||
103 | rb_link_node(&he->rb_node, parent, p); | 93 | rb_link_node(&he->rb_node, parent, p); |
104 | rb_insert_color(&he->rb_node, root); | 94 | rb_insert_color(&he->rb_node, root); |
105 | } | 95 | } |
106 | 96 | ||
107 | static void perf_session__resort_by_name(struct perf_session *self) | 97 | static void perf_session__resort_hist_entries(struct perf_session *self) |
108 | { | 98 | { |
109 | unsigned long position = 1; | 99 | unsigned long position = 1; |
110 | struct rb_root tmp = RB_ROOT; | 100 | struct rb_root tmp = RB_ROOT; |
@@ -122,29 +112,28 @@ static void perf_session__resort_by_name(struct perf_session *self) | |||
122 | self->hists = tmp; | 112 | self->hists = tmp; |
123 | } | 113 | } |
124 | 114 | ||
115 | static void perf_session__set_hist_entries_positions(struct perf_session *self) | ||
116 | { | ||
117 | perf_session__output_resort(self, self->events_stats.total); | ||
118 | perf_session__resort_hist_entries(self); | ||
119 | } | ||
120 | |||
125 | static struct hist_entry * | 121 | static struct hist_entry * |
126 | perf_session__find_hist_entry_by_name(struct perf_session *self, | 122 | perf_session__find_hist_entry(struct perf_session *self, |
127 | struct hist_entry *he) | 123 | struct hist_entry *he) |
128 | { | 124 | { |
129 | struct rb_node *n = self->hists.rb_node; | 125 | struct rb_node *n = self->hists.rb_node; |
130 | 126 | ||
131 | while (n) { | 127 | while (n) { |
132 | struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); | 128 | struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); |
133 | int cmp = strcmp(he->map->dso->name, iter->map->dso->name); | 129 | int64_t cmp = hist_entry__cmp(he, iter); |
134 | 130 | ||
135 | if (cmp > 0) | 131 | if (cmp < 0) |
136 | n = n->rb_left; | 132 | n = n->rb_left; |
137 | else if (cmp < 0) | 133 | else if (cmp > 0) |
138 | n = n->rb_right; | 134 | n = n->rb_right; |
139 | else { | 135 | else |
140 | cmp = strcmp(he->sym->name, iter->sym->name); | 136 | return iter; |
141 | if (cmp > 0) | ||
142 | n = n->rb_left; | ||
143 | else if (cmp < 0) | ||
144 | n = n->rb_right; | ||
145 | else | ||
146 | return iter; | ||
147 | } | ||
148 | } | 137 | } |
149 | 138 | ||
150 | return NULL; | 139 | return NULL; |
@@ -155,11 +144,9 @@ static void perf_session__match_hists(struct perf_session *old_session, | |||
155 | { | 144 | { |
156 | struct rb_node *nd; | 145 | struct rb_node *nd; |
157 | 146 | ||
158 | perf_session__resort_by_name(old_session); | ||
159 | |||
160 | for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) { | 147 | for (nd = rb_first(&new_session->hists); nd; nd = rb_next(nd)) { |
161 | struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); | 148 | struct hist_entry *pos = rb_entry(nd, struct hist_entry, rb_node); |
162 | pos->pair = perf_session__find_hist_entry_by_name(old_session, pos); | 149 | pos->pair = perf_session__find_hist_entry(old_session, pos); |
163 | } | 150 | } |
164 | } | 151 | } |
165 | 152 | ||
@@ -177,9 +164,12 @@ static int __cmd_diff(void) | |||
177 | ret = perf_session__process_events(session[i], &event_ops); | 164 | ret = perf_session__process_events(session[i], &event_ops); |
178 | if (ret) | 165 | if (ret) |
179 | goto out_delete; | 166 | goto out_delete; |
180 | perf_session__output_resort(session[i], session[i]->events_stats.total); | ||
181 | } | 167 | } |
182 | 168 | ||
169 | perf_session__output_resort(session[1], session[1]->events_stats.total); | ||
170 | if (show_displacement) | ||
171 | perf_session__set_hist_entries_positions(session[0]); | ||
172 | |||
183 | perf_session__match_hists(session[0], session[1]); | 173 | perf_session__match_hists(session[0], session[1]); |
184 | perf_session__fprintf_hists(session[1], session[0], | 174 | perf_session__fprintf_hists(session[1], session[0], |
185 | show_displacement, stdout); | 175 | show_displacement, stdout); |
@@ -204,7 +194,7 @@ static const struct option options[] = { | |||
204 | OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), | 194 | OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), |
205 | OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, | 195 | OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, |
206 | "load module symbols - WARNING: use only with -k and LIVE kernel"), | 196 | "load module symbols - WARNING: use only with -k and LIVE kernel"), |
207 | OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths, | 197 | OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths, |
208 | "Don't shorten the pathnames taking into account the cwd"), | 198 | "Don't shorten the pathnames taking into account the cwd"), |
209 | OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", | 199 | OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", |
210 | "only consider symbols in these dsos"), | 200 | "only consider symbols in these dsos"), |