aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/annotate.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/util/annotate.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/util/annotate.c')
-rw-r--r--tools/perf/util/annotate.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 6db435167d7..c777bdaf91d 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -14,25 +14,39 @@
14#include "symbol.h" 14#include "symbol.h"
15#include "debug.h" 15#include "debug.h"
16#include "annotate.h" 16#include "annotate.h"
17#include <pthread.h>
17 18
18int symbol__alloc_hist(struct symbol *sym, int nevents) 19int symbol__annotate_init(struct map *map __used, struct symbol *sym)
19{ 20{
20 struct annotation *notes = symbol__annotation(sym); 21 struct annotation *notes = symbol__annotation(sym);
22 pthread_mutex_init(&notes->lock, NULL);
23 return 0;
24}
21 25
22 notes->sizeof_sym_hist = (sizeof(*notes->histograms) + 26int symbol__alloc_hist(struct symbol *sym, int nevents)
27{
28 struct annotation *notes = symbol__annotation(sym);
29 size_t sizeof_sym_hist = (sizeof(struct sym_hist) +
23 (sym->end - sym->start) * sizeof(u64)); 30 (sym->end - sym->start) * sizeof(u64));
24 notes->histograms = calloc(nevents, notes->sizeof_sym_hist); 31
25 notes->nr_histograms = nevents; 32 notes->src = zalloc(sizeof(*notes->src) + nevents * sizeof_sym_hist);
26 return notes->histograms == NULL ? -1 : 0; 33 if (notes->src == NULL)
34 return -1;
35 notes->src->sizeof_sym_hist = sizeof_sym_hist;
36 notes->src->nr_histograms = nevents;
37 INIT_LIST_HEAD(&notes->src->source);
38 return 0;
27} 39}
28 40
29void symbol__annotate_zero_histograms(struct symbol *sym) 41void symbol__annotate_zero_histograms(struct symbol *sym)
30{ 42{
31 struct annotation *notes = symbol__annotation(sym); 43 struct annotation *notes = symbol__annotation(sym);
32 44
33 if (notes->histograms != NULL) 45 pthread_mutex_lock(&notes->lock);
34 memset(notes->histograms, 0, 46 if (notes->src != NULL)
35 notes->nr_histograms * notes->sizeof_sym_hist); 47 memset(notes->src->histograms, 0,
48 notes->src->nr_histograms * notes->src->sizeof_sym_hist);
49 pthread_mutex_unlock(&notes->lock);
36} 50}
37 51
38int symbol__inc_addr_samples(struct symbol *sym, struct map *map, 52int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
@@ -43,7 +57,7 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
43 struct sym_hist *h; 57 struct sym_hist *h;
44 58
45 notes = symbol__annotation(sym); 59 notes = symbol__annotation(sym);
46 if (notes->histograms == NULL) 60 if (notes->src == NULL)
47 return -ENOMEM; 61 return -ENOMEM;
48 62
49 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 63 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
@@ -95,8 +109,7 @@ struct objdump_line *objdump__get_next_ip_line(struct list_head *head,
95 return NULL; 109 return NULL;
96} 110}
97 111
98static int objdump_line__print(struct objdump_line *oline, 112static int objdump_line__print(struct objdump_line *oline, struct symbol *sym,
99 struct list_head *head, struct symbol *sym,
100 int evidx, u64 len, int min_pcnt, 113 int evidx, u64 len, int min_pcnt,
101 int printed, int max_lines) 114 int printed, int max_lines)
102{ 115{
@@ -109,10 +122,12 @@ static int objdump_line__print(struct objdump_line *oline,
109 double percent = 0.0; 122 double percent = 0.0;
110 const char *color; 123 const char *color;
111 struct annotation *notes = symbol__annotation(sym); 124 struct annotation *notes = symbol__annotation(sym);
112 struct source_line *src_line = notes->src_line; 125 struct source_line *src_line = notes->src->lines;
113 struct sym_hist *h = annotation__histogram(notes, evidx); 126 struct sym_hist *h = annotation__histogram(notes, evidx);
114 s64 offset = oline->offset; 127 s64 offset = oline->offset;
115 struct objdump_line *next = objdump__get_next_ip_line(head, oline); 128 struct objdump_line *next;
129
130 next = objdump__get_next_ip_line(&notes->src->source, oline);
116 131
117 while (offset < (s64)len && 132 while (offset < (s64)len &&
118 (next == NULL || offset < next->offset)) { 133 (next == NULL || offset < next->offset)) {
@@ -166,9 +181,10 @@ static int objdump_line__print(struct objdump_line *oline,
166 return 0; 181 return 0;
167} 182}
168 183
169static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, FILE *file, 184static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
170 struct list_head *head, size_t privsize) 185 FILE *file, size_t privsize)
171{ 186{
187 struct annotation *notes = symbol__annotation(sym);
172 struct objdump_line *objdump_line; 188 struct objdump_line *objdump_line;
173 char *line = NULL, *tmp, *tmp2, *c; 189 char *line = NULL, *tmp, *tmp2, *c;
174 size_t line_len; 190 size_t line_len;
@@ -222,13 +238,12 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, FILE
222 free(line); 238 free(line);
223 return -1; 239 return -1;
224 } 240 }
225 objdump__add_line(head, objdump_line); 241 objdump__add_line(&notes->src->source, objdump_line);
226 242
227 return 0; 243 return 0;
228} 244}
229 245
230int symbol__annotate(struct symbol *sym, struct map *map, 246int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
231 struct list_head *head, size_t privsize)
232{ 247{
233 struct dso *dso = map->dso; 248 struct dso *dso = map->dso;
234 char *filename = dso__build_id_filename(dso, NULL, 0); 249 char *filename = dso__build_id_filename(dso, NULL, 0);
@@ -297,7 +312,7 @@ fallback:
297 goto out_free_filename; 312 goto out_free_filename;
298 313
299 while (!feof(file)) 314 while (!feof(file))
300 if (symbol__parse_objdump_line(sym, map, file, head, privsize) < 0) 315 if (symbol__parse_objdump_line(sym, map, file, privsize) < 0)
301 break; 316 break;
302 317
303 pclose(file); 318 pclose(file);
@@ -330,14 +345,14 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
330static void symbol__free_source_line(struct symbol *sym, int len) 345static void symbol__free_source_line(struct symbol *sym, int len)
331{ 346{
332 struct annotation *notes = symbol__annotation(sym); 347 struct annotation *notes = symbol__annotation(sym);
333 struct source_line *src_line = notes->src_line; 348 struct source_line *src_line = notes->src->lines;
334 int i; 349 int i;
335 350
336 for (i = 0; i < len; i++) 351 for (i = 0; i < len; i++)
337 free(src_line[i].path); 352 free(src_line[i].path);
338 353
339 free(src_line); 354 free(src_line);
340 notes->src_line = NULL; 355 notes->src->lines = NULL;
341} 356}
342 357
343/* Get the filename:line for the colored entries */ 358/* Get the filename:line for the colored entries */
@@ -355,8 +370,8 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
355 if (!h->sum) 370 if (!h->sum)
356 return 0; 371 return 0;
357 372
358 src_line = notes->src_line = calloc(len, sizeof(struct source_line)); 373 src_line = notes->src->lines = calloc(len, sizeof(struct source_line));
359 if (!notes->src_line) 374 if (!notes->src->lines)
360 return -1; 375 return -1;
361 376
362 start = map->unmap_ip(map, sym->start); 377 start = map->unmap_ip(map, sym->start);
@@ -436,12 +451,12 @@ static void symbol__annotate_hits(struct symbol *sym, int evidx)
436 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); 451 printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum);
437} 452}
438 453
439int symbol__annotate_printf(struct symbol *sym, struct map *map, 454int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
440 struct list_head *head, int evidx, bool full_paths, 455 bool full_paths, int min_pcnt, int max_lines)
441 int min_pcnt, int max_lines)
442{ 456{
443 struct dso *dso = map->dso; 457 struct dso *dso = map->dso;
444 const char *filename = dso->long_name, *d_filename; 458 const char *filename = dso->long_name, *d_filename;
459 struct annotation *notes = symbol__annotation(sym);
445 struct objdump_line *pos; 460 struct objdump_line *pos;
446 int printed = 2; 461 int printed = 2;
447 int more = 0; 462 int more = 0;
@@ -460,8 +475,8 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
460 if (verbose) 475 if (verbose)
461 symbol__annotate_hits(sym, evidx); 476 symbol__annotate_hits(sym, evidx);
462 477
463 list_for_each_entry(pos, head, node) { 478 list_for_each_entry(pos, &notes->src->source, node) {
464 switch (objdump_line__print(pos, head, sym, evidx, len, min_pcnt, 479 switch (objdump_line__print(pos, sym, evidx, len, min_pcnt,
465 printed, max_lines)) { 480 printed, max_lines)) {
466 case 0: 481 case 0:
467 ++printed; 482 ++printed;
@@ -485,11 +500,10 @@ void symbol__annotate_zero_histogram(struct symbol *sym, int evidx)
485 struct annotation *notes = symbol__annotation(sym); 500 struct annotation *notes = symbol__annotation(sym);
486 struct sym_hist *h = annotation__histogram(notes, evidx); 501 struct sym_hist *h = annotation__histogram(notes, evidx);
487 502
488 memset(h, 0, notes->sizeof_sym_hist); 503 memset(h, 0, notes->src->sizeof_sym_hist);
489} 504}
490 505
491void symbol__annotate_decay_histogram(struct symbol *sym, 506void symbol__annotate_decay_histogram(struct symbol *sym, int evidx)
492 struct list_head *head, int evidx)
493{ 507{
494 struct annotation *notes = symbol__annotation(sym); 508 struct annotation *notes = symbol__annotation(sym);
495 struct sym_hist *h = annotation__histogram(notes, evidx); 509 struct sym_hist *h = annotation__histogram(notes, evidx);
@@ -497,7 +511,7 @@ void symbol__annotate_decay_histogram(struct symbol *sym,
497 511
498 h->sum = 0; 512 h->sum = 0;
499 513
500 list_for_each_entry(pos, head, node) { 514 list_for_each_entry(pos, &notes->src->source, node) {
501 if (pos->offset != -1) { 515 if (pos->offset != -1) {
502 h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8; 516 h->addr[pos->offset] = h->addr[pos->offset] * 7 / 8;
503 h->sum += h->addr[pos->offset]; 517 h->sum += h->addr[pos->offset];
@@ -522,10 +536,9 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
522 struct dso *dso = map->dso; 536 struct dso *dso = map->dso;
523 const char *filename = dso->long_name; 537 const char *filename = dso->long_name;
524 struct rb_root source_line = RB_ROOT; 538 struct rb_root source_line = RB_ROOT;
525 LIST_HEAD(head);
526 u64 len; 539 u64 len;
527 540
528 if (symbol__annotate(sym, map, &head, 0) < 0) 541 if (symbol__annotate(sym, map, 0) < 0)
529 return -1; 542 return -1;
530 543
531 len = sym->end - sym->start; 544 len = sym->end - sym->start;
@@ -536,12 +549,12 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
536 print_summary(&source_line, filename); 549 print_summary(&source_line, filename);
537 } 550 }
538 551
539 symbol__annotate_printf(sym, map, &head, evidx, full_paths, 552 symbol__annotate_printf(sym, map, evidx, full_paths,
540 min_pcnt, max_lines); 553 min_pcnt, max_lines);
541 if (print_lines) 554 if (print_lines)
542 symbol__free_source_line(sym, len); 555 symbol__free_source_line(sym, len);
543 556
544 objdump_line_list__purge(&head); 557 objdump_line_list__purge(&symbol__annotation(sym)->src->source);
545 558
546 return 0; 559 return 0;
547} 560}