diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-02-08 10:27:39 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-02-08 12:03:36 -0500 |
commit | ce6f4fab4059cd72638a0cfa596a8ee2c79c1c8e (patch) | |
tree | 00416d7a54d9ef265b9358022e804217dcb5d870 /tools/perf/builtin-top.c | |
parent | e3087b80aa0bceda9863f33307460f3ba79f2b15 (diff) |
perf annotate: Move locking to struct annotation
Since we'll need it when implementing the live annotate TUI browser.
This also simplifies things a bit by having the list head for the source
code to be in the dynamicly allocated part of struct annotation, that
way we don't have to pass it around, it can be found from the struct
symbol that is passed everywhere.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r-- | tools/perf/builtin-top.c | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b790673cb0aa..7dbf22d096b8 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -139,7 +139,7 @@ static void sig_winch_handler(int sig __used) | |||
139 | static int parse_source(struct sym_entry *syme) | 139 | static int parse_source(struct sym_entry *syme) |
140 | { | 140 | { |
141 | struct symbol *sym; | 141 | struct symbol *sym; |
142 | struct sym_entry_source *source; | 142 | struct annotation *notes; |
143 | struct map *map; | 143 | struct map *map; |
144 | int err = -1; | 144 | int err = -1; |
145 | 145 | ||
@@ -152,39 +152,35 @@ static int parse_source(struct sym_entry *syme) | |||
152 | /* | 152 | /* |
153 | * We can't annotate with just /proc/kallsyms | 153 | * We can't annotate with just /proc/kallsyms |
154 | */ | 154 | */ |
155 | if (map->dso->origin == DSO__ORIG_KERNEL) | 155 | if (map->dso->origin == DSO__ORIG_KERNEL) { |
156 | pr_err("Can't annotate %s: No vmlinux file was found in the " | ||
157 | "path\n", sym->name); | ||
158 | sleep(1); | ||
156 | return -1; | 159 | return -1; |
157 | |||
158 | if (syme->src == NULL) { | ||
159 | syme->src = zalloc(sizeof(*source)); | ||
160 | if (syme->src == NULL) | ||
161 | return -1; | ||
162 | pthread_mutex_init(&syme->src->lock, NULL); | ||
163 | INIT_LIST_HEAD(&syme->src->head); | ||
164 | } | 160 | } |
165 | 161 | ||
166 | source = syme->src; | 162 | notes = symbol__annotation(sym); |
167 | 163 | if (notes->src != NULL) { | |
168 | if (symbol__annotation(sym)->histograms != NULL) { | 164 | pthread_mutex_lock(¬es->lock); |
169 | pthread_mutex_lock(&source->lock); | ||
170 | goto out_assign; | 165 | goto out_assign; |
171 | } | 166 | } |
172 | 167 | ||
173 | pthread_mutex_lock(&source->lock); | 168 | pthread_mutex_lock(¬es->lock); |
174 | 169 | ||
175 | if (symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) { | 170 | if (symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) { |
176 | pr_err("Not enough memory for annotating '%s' symbol!\n", | 171 | pr_err("Not enough memory for annotating '%s' symbol!\n", |
177 | sym->name); | 172 | sym->name); |
173 | sleep(1); | ||
178 | goto out_unlock; | 174 | goto out_unlock; |
179 | } | 175 | } |
180 | 176 | ||
181 | err = symbol__annotate(sym, syme->map, &source->head, 0); | 177 | err = symbol__annotate(sym, syme->map, 0); |
182 | if (err == 0) { | 178 | if (err == 0) { |
183 | out_assign: | 179 | out_assign: |
184 | sym_filter_entry = syme; | 180 | sym_filter_entry = syme; |
185 | } | 181 | } |
186 | out_unlock: | 182 | out_unlock: |
187 | pthread_mutex_unlock(&source->lock); | 183 | pthread_mutex_unlock(¬es->lock); |
188 | return err; | 184 | return err; |
189 | } | 185 | } |
190 | 186 | ||
@@ -196,20 +192,27 @@ static void __zero_source_counters(struct sym_entry *syme) | |||
196 | 192 | ||
197 | static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip) | 193 | static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip) |
198 | { | 194 | { |
195 | struct annotation *notes; | ||
196 | struct symbol *sym; | ||
197 | |||
199 | if (syme != sym_filter_entry) | 198 | if (syme != sym_filter_entry) |
200 | return; | 199 | return; |
201 | 200 | ||
202 | if (pthread_mutex_trylock(&syme->src->lock)) | 201 | sym = sym_entry__symbol(syme); |
202 | notes = symbol__annotation(sym); | ||
203 | |||
204 | if (pthread_mutex_trylock(¬es->lock)) | ||
203 | return; | 205 | return; |
204 | 206 | ||
205 | ip = syme->map->map_ip(syme->map, ip); | 207 | ip = syme->map->map_ip(syme->map, ip); |
206 | symbol__inc_addr_samples(sym_entry__symbol(syme), syme->map, counter, ip); | 208 | symbol__inc_addr_samples(sym, syme->map, counter, ip); |
207 | 209 | ||
208 | pthread_mutex_unlock(&syme->src->lock); | 210 | pthread_mutex_unlock(¬es->lock); |
209 | } | 211 | } |
210 | 212 | ||
211 | static void show_details(struct sym_entry *syme) | 213 | static void show_details(struct sym_entry *syme) |
212 | { | 214 | { |
215 | struct annotation *notes; | ||
213 | struct symbol *symbol; | 216 | struct symbol *symbol; |
214 | int more; | 217 | int more; |
215 | 218 | ||
@@ -217,24 +220,26 @@ static void show_details(struct sym_entry *syme) | |||
217 | return; | 220 | return; |
218 | 221 | ||
219 | symbol = sym_entry__symbol(syme); | 222 | symbol = sym_entry__symbol(syme); |
220 | if (!syme->src || symbol__annotation(symbol)->histograms == NULL) | 223 | notes = symbol__annotation(symbol); |
221 | return; | 224 | |
225 | pthread_mutex_lock(¬es->lock); | ||
226 | |||
227 | if (notes->src == NULL) | ||
228 | goto out_unlock; | ||
222 | 229 | ||
223 | printf("Showing %s for %s\n", event_name(top.sym_evsel), symbol->name); | 230 | printf("Showing %s for %s\n", event_name(top.sym_evsel), symbol->name); |
224 | printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); | 231 | printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); |
225 | 232 | ||
226 | pthread_mutex_lock(&syme->src->lock); | 233 | more = symbol__annotate_printf(symbol, syme->map, top.sym_evsel->idx, |
227 | more = symbol__annotate_printf(symbol, syme->map, &syme->src->head, | 234 | 0, sym_pcnt_filter, top.print_entries); |
228 | top.sym_evsel->idx, 0, sym_pcnt_filter, | ||
229 | top.print_entries); | ||
230 | if (top.zero) | 235 | if (top.zero) |
231 | symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx); | 236 | symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx); |
232 | else | 237 | else |
233 | symbol__annotate_decay_histogram(symbol, &syme->src->head, | 238 | symbol__annotate_decay_histogram(symbol, top.sym_evsel->idx); |
234 | top.sym_evsel->idx); | ||
235 | pthread_mutex_unlock(&syme->src->lock); | ||
236 | if (more != 0) | 239 | if (more != 0) |
237 | printf("%d lines not displayed, maybe increase display entries [e]\n", more); | 240 | printf("%d lines not displayed, maybe increase display entries [e]\n", more); |
241 | out_unlock: | ||
242 | pthread_mutex_unlock(¬es->lock); | ||
238 | } | 243 | } |
239 | 244 | ||
240 | static const char CONSOLE_CLEAR[] = "[H[2J"; | 245 | static const char CONSOLE_CLEAR[] = "[H[2J"; |
@@ -372,10 +377,8 @@ static void prompt_symbol(struct sym_entry **target, const char *msg) | |||
372 | 377 | ||
373 | /* zero counters of active symbol */ | 378 | /* zero counters of active symbol */ |
374 | if (syme) { | 379 | if (syme) { |
375 | pthread_mutex_lock(&syme->src->lock); | ||
376 | __zero_source_counters(syme); | 380 | __zero_source_counters(syme); |
377 | *target = NULL; | 381 | *target = NULL; |
378 | pthread_mutex_unlock(&syme->src->lock); | ||
379 | } | 382 | } |
380 | 383 | ||
381 | fprintf(stdout, "\n%s: ", msg); | 384 | fprintf(stdout, "\n%s: ", msg); |
@@ -554,10 +557,8 @@ static void handle_keypress(struct perf_session *session, int c) | |||
554 | else { | 557 | else { |
555 | struct sym_entry *syme = sym_filter_entry; | 558 | struct sym_entry *syme = sym_filter_entry; |
556 | 559 | ||
557 | pthread_mutex_lock(&syme->src->lock); | ||
558 | sym_filter_entry = NULL; | 560 | sym_filter_entry = NULL; |
559 | __zero_source_counters(syme); | 561 | __zero_source_counters(syme); |
560 | pthread_mutex_unlock(&syme->src->lock); | ||
561 | } | 562 | } |
562 | break; | 563 | break; |
563 | case 'U': | 564 | case 'U': |
@@ -653,7 +654,7 @@ static int symbol_filter(struct map *map, struct symbol *sym) | |||
653 | 654 | ||
654 | syme = symbol__priv(sym); | 655 | syme = symbol__priv(sym); |
655 | syme->map = map; | 656 | syme->map = map; |
656 | syme->src = NULL; | 657 | symbol__annotate_init(map, sym); |
657 | 658 | ||
658 | if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) { | 659 | if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) { |
659 | /* schedule initial sym_filter_entry setup */ | 660 | /* schedule initial sym_filter_entry setup */ |