aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-02-08 10:27:39 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-02-08 12:03:36 -0500
commitce6f4fab4059cd72638a0cfa596a8ee2c79c1c8e (patch)
tree00416d7a54d9ef265b9358022e804217dcb5d870 /tools/perf/builtin-top.c
parente3087b80aa0bceda9863f33307460f3ba79f2b15 (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.c67
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)
139static int parse_source(struct sym_entry *syme) 139static 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(&notes->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(&notes->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) {
183out_assign: 179out_assign:
184 sym_filter_entry = syme; 180 sym_filter_entry = syme;
185 } 181 }
186out_unlock: 182out_unlock:
187 pthread_mutex_unlock(&source->lock); 183 pthread_mutex_unlock(&notes->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
197static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip) 193static 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(&notes->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(&notes->lock);
209} 211}
210 212
211static void show_details(struct sym_entry *syme) 213static 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(&notes->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);
241out_unlock:
242 pthread_mutex_unlock(&notes->lock);
238} 243}
239 244
240static const char CONSOLE_CLEAR[] = ""; 245static const char CONSOLE_CLEAR[] = "";
@@ -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 */