static int hist_iter__report_callback(struct hist_entry_iter *iter, struct addr_location *al, bool single, void *arg) { int err = 0; struct report *rep = arg; struct hist_entry *he = iter->he; struct perf_evsel *evsel = iter->evsel; struct perf_sample *sample = iter->sample; struct mem_info *mi; struct branch_info *bi; if (!ui__has_annotation()) return 0; hist__account_cycles(sample->branch_stack, al, sample, rep->nonany_branch_mode); if (sort__mode == SORT_MODE__BRANCH) { bi = he->branch_info; err = addr_map_symbol__inc_samples(&bi->from, sample, evsel); if (err) goto out; err = addr_map_symbol__inc_samples(&bi->to, sample, evsel); } else if (rep->mem_mode) { mi = he->mem_info; err = addr_map_symbol__inc_samples(&mi->daddr, sample, evsel); if (err) goto out; err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr); } else if (symbol_conf.cumulate_callchain) { if (single) err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr); } else { err = hist_entry__inc_addr_samples(he, sample, evsel, al->addr); } out: return err; }
static int perf_session__add_hist_entry(struct perf_session *session, struct addr_location *al, struct perf_sample *sample, struct perf_evsel *evsel) { struct symbol *parent = NULL; int err = 0; struct hist_entry *he; if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { err = perf_session__resolve_callchain(session, al->thread, sample->callchain, &parent); if (err) return err; } he = __hists__add_entry(&evsel->hists, al, parent, sample->period); if (he == NULL) return -ENOMEM; if (symbol_conf.use_callchain) { err = callchain_append(he->callchain, &session->callchain_cursor, sample->period); if (err) return err; } /* * Only in the newt browser we are doing integrated annotation, * so we don't allocated the extra space needed because the stdio * code will not use it. */ if (al->sym != NULL && use_browser > 0) { struct annotation *notes = symbol__annotation(he->ms.sym); assert(evsel != NULL); err = -ENOMEM; if (notes->src == NULL && symbol__alloc_hist(he->ms.sym, session->evlist->nr_entries) < 0) goto out; err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); } evsel->hists.stats.total_period += sample->period; hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); out: return err; }
static void perf_top__record_precise_ip(struct perf_top *top, struct hist_entry *he, struct perf_sample *sample, struct perf_evsel *evsel, u64 ip) { struct annotation *notes; struct symbol *sym = he->ms.sym; int err = 0; if (sym == NULL || (use_browser == 0 && (top->sym_filter_entry == NULL || top->sym_filter_entry->ms.sym != sym))) return; notes = symbol__annotation(sym); if (pthread_mutex_trylock(¬es->lock)) return; err = hist_entry__inc_addr_samples(he, sample, evsel, ip); pthread_mutex_unlock(¬es->lock); if (unlikely(err)) { /* * This function is now called with he->hists->lock held. * Release it before going to sleep. */ pthread_mutex_unlock(&he->hists->lock); if (err == -ERANGE && !he->ms.map->erange_warned) ui__warn_map_erange(he->ms.map, sym, ip); else if (err == -ENOMEM) { pr_err("Not enough memory for annotating '%s' symbol!\n", sym->name); sleep(1); } pthread_mutex_lock(&he->hists->lock); } }