Skip to content

Commit

Permalink
perf annotate: Move locking to struct annotation
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arnaldo Carvalho de Melo committed Feb 8, 2011
1 parent e3087b8 commit ce6f4fa
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 111 deletions.
14 changes: 8 additions & 6 deletions tools/perf/builtin-annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ static int hists__add_entry(struct hists *self, struct addr_location *al)
* All aggregated on the first sym_hist.
*/
struct annotation *notes = symbol__annotation(he->ms.sym);
if (notes->histograms == NULL && symbol__alloc_hist(he->ms.sym, 1) < 0)
if (notes->src == NULL &&
symbol__alloc_hist(he->ms.sym, 1) < 0)
return -ENOMEM;

return hist_entry__inc_addr_samples(he, 0, al->addr);
Expand All @@ -77,7 +78,8 @@ static int process_sample_event(union perf_event *event,
{
struct addr_location al;

if (perf_event__preprocess_sample(event, session, &al, sample, NULL) < 0) {
if (perf_event__preprocess_sample(event, session, &al, sample,
symbol__annotate_init) < 0) {
pr_warning("problem processing %d event, skipping it.\n",
event->header.type);
return -1;
Expand Down Expand Up @@ -111,7 +113,7 @@ static void hists__find_annotations(struct hists *self)
goto find_next;

notes = symbol__annotation(he->ms.sym);
if (notes->histograms == NULL) {
if (notes->src == NULL) {
find_next:
if (key == KEY_LEFT)
nd = rb_prev(nd);
Expand Down Expand Up @@ -142,11 +144,11 @@ static void hists__find_annotations(struct hists *self)
nd = rb_next(nd);
/*
* Since we have a hist_entry per IP for the same
* symbol, free he->ms.sym->histogram to signal we already
* symbol, free he->ms.sym->src to signal we already
* processed this symbol.
*/
free(notes->histograms);
notes->histograms = NULL;
free(notes->src);
notes->src = NULL;
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static int perf_session__add_hist_entry(struct perf_session *session,
* All aggregated on the first sym_hist.
*/
struct annotation *notes = symbol__annotation(he->ms.sym);
if (notes->histograms == NULL &&
if (notes->src == NULL &&
symbol__alloc_hist(he->ms.sym, 1) < 0)
err = -ENOMEM;
else
Expand Down Expand Up @@ -166,7 +166,8 @@ static int process_sample_event(union perf_event *event,
struct addr_location al;
struct perf_event_attr *attr;

if (perf_event__preprocess_sample(event, session, &al, sample, NULL) < 0) {
if (perf_event__preprocess_sample(event, session, &al, sample,
symbol__annotate_init) < 0) {
fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
Expand Down
67 changes: 34 additions & 33 deletions tools/perf/builtin-top.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static void sig_winch_handler(int sig __used)
static int parse_source(struct sym_entry *syme)
{
struct symbol *sym;
struct sym_entry_source *source;
struct annotation *notes;
struct map *map;
int err = -1;

Expand All @@ -152,39 +152,35 @@ static int parse_source(struct sym_entry *syme)
/*
* We can't annotate with just /proc/kallsyms
*/
if (map->dso->origin == DSO__ORIG_KERNEL)
if (map->dso->origin == DSO__ORIG_KERNEL) {
pr_err("Can't annotate %s: No vmlinux file was found in the "
"path\n", sym->name);
sleep(1);
return -1;

if (syme->src == NULL) {
syme->src = zalloc(sizeof(*source));
if (syme->src == NULL)
return -1;
pthread_mutex_init(&syme->src->lock, NULL);
INIT_LIST_HEAD(&syme->src->head);
}

source = syme->src;

if (symbol__annotation(sym)->histograms != NULL) {
pthread_mutex_lock(&source->lock);
notes = symbol__annotation(sym);
if (notes->src != NULL) {
pthread_mutex_lock(&notes->lock);
goto out_assign;
}

pthread_mutex_lock(&source->lock);
pthread_mutex_lock(&notes->lock);

if (symbol__alloc_hist(sym, top.evlist->nr_entries) < 0) {
pr_err("Not enough memory for annotating '%s' symbol!\n",
sym->name);
sleep(1);
goto out_unlock;
}

err = symbol__annotate(sym, syme->map, &source->head, 0);
err = symbol__annotate(sym, syme->map, 0);
if (err == 0) {
out_assign:
sym_filter_entry = syme;
}
out_unlock:
pthread_mutex_unlock(&source->lock);
pthread_mutex_unlock(&notes->lock);
return err;
}

Expand All @@ -196,45 +192,54 @@ static void __zero_source_counters(struct sym_entry *syme)

static void record_precise_ip(struct sym_entry *syme, int counter, u64 ip)
{
struct annotation *notes;
struct symbol *sym;

if (syme != sym_filter_entry)
return;

if (pthread_mutex_trylock(&syme->src->lock))
sym = sym_entry__symbol(syme);
notes = symbol__annotation(sym);

if (pthread_mutex_trylock(&notes->lock))
return;

ip = syme->map->map_ip(syme->map, ip);
symbol__inc_addr_samples(sym_entry__symbol(syme), syme->map, counter, ip);
symbol__inc_addr_samples(sym, syme->map, counter, ip);

pthread_mutex_unlock(&syme->src->lock);
pthread_mutex_unlock(&notes->lock);
}

static void show_details(struct sym_entry *syme)
{
struct annotation *notes;
struct symbol *symbol;
int more;

if (!syme)
return;

symbol = sym_entry__symbol(syme);
if (!syme->src || symbol__annotation(symbol)->histograms == NULL)
return;
notes = symbol__annotation(symbol);

pthread_mutex_lock(&notes->lock);

if (notes->src == NULL)
goto out_unlock;

printf("Showing %s for %s\n", event_name(top.sym_evsel), symbol->name);
printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter);

pthread_mutex_lock(&syme->src->lock);
more = symbol__annotate_printf(symbol, syme->map, &syme->src->head,
top.sym_evsel->idx, 0, sym_pcnt_filter,
top.print_entries);
more = symbol__annotate_printf(symbol, syme->map, top.sym_evsel->idx,
0, sym_pcnt_filter, top.print_entries);
if (top.zero)
symbol__annotate_zero_histogram(symbol, top.sym_evsel->idx);
else
symbol__annotate_decay_histogram(symbol, &syme->src->head,
top.sym_evsel->idx);
pthread_mutex_unlock(&syme->src->lock);
symbol__annotate_decay_histogram(symbol, top.sym_evsel->idx);
if (more != 0)
printf("%d lines not displayed, maybe increase display entries [e]\n", more);
out_unlock:
pthread_mutex_unlock(&notes->lock);
}

static const char CONSOLE_CLEAR[] = "";
Expand Down Expand Up @@ -372,10 +377,8 @@ static void prompt_symbol(struct sym_entry **target, const char *msg)

/* zero counters of active symbol */
if (syme) {
pthread_mutex_lock(&syme->src->lock);
__zero_source_counters(syme);
*target = NULL;
pthread_mutex_unlock(&syme->src->lock);
}

fprintf(stdout, "\n%s: ", msg);
Expand Down Expand Up @@ -554,10 +557,8 @@ static void handle_keypress(struct perf_session *session, int c)
else {
struct sym_entry *syme = sym_filter_entry;

pthread_mutex_lock(&syme->src->lock);
sym_filter_entry = NULL;
__zero_source_counters(syme);
pthread_mutex_unlock(&syme->src->lock);
}
break;
case 'U':
Expand Down Expand Up @@ -653,7 +654,7 @@ static int symbol_filter(struct map *map, struct symbol *sym)

syme = symbol__priv(sym);
syme->map = map;
syme->src = NULL;
symbol__annotate_init(map, sym);

if (!sym_filter_entry && sym_filter && !strcmp(name, sym_filter)) {
/* schedule initial sym_filter_entry setup */
Expand Down
Loading

0 comments on commit ce6f4fa

Please sign in to comment.