aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r--tools/perf/builtin-top.c76
1 files changed, 41 insertions, 35 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 12e2e1227e47..b1cb5f589ade 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -196,6 +196,12 @@ static void perf_top__record_precise_ip(struct perf_top *top,
196 196
197 pthread_mutex_unlock(&notes->lock); 197 pthread_mutex_unlock(&notes->lock);
198 198
199 /*
200 * This function is now called with he->hists->lock held.
201 * Release it before going to sleep.
202 */
203 pthread_mutex_unlock(&he->hists->lock);
204
199 if (err == -ERANGE && !he->ms.map->erange_warned) 205 if (err == -ERANGE && !he->ms.map->erange_warned)
200 ui__warn_map_erange(he->ms.map, sym, ip); 206 ui__warn_map_erange(he->ms.map, sym, ip);
201 else if (err == -ENOMEM) { 207 else if (err == -ENOMEM) {
@@ -203,6 +209,8 @@ static void perf_top__record_precise_ip(struct perf_top *top,
203 sym->name); 209 sym->name);
204 sleep(1); 210 sleep(1);
205 } 211 }
212
213 pthread_mutex_lock(&he->hists->lock);
206} 214}
207 215
208static void perf_top__show_details(struct perf_top *top) 216static void perf_top__show_details(struct perf_top *top)
@@ -238,24 +246,6 @@ out_unlock:
238 pthread_mutex_unlock(&notes->lock); 246 pthread_mutex_unlock(&notes->lock);
239} 247}
240 248
241static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
242 struct addr_location *al,
243 struct perf_sample *sample)
244{
245 struct hist_entry *he;
246
247 pthread_mutex_lock(&evsel->hists.lock);
248 he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL,
249 sample->period, sample->weight,
250 sample->transaction, true);
251 pthread_mutex_unlock(&evsel->hists.lock);
252 if (he == NULL)
253 return NULL;
254
255 hists__inc_nr_samples(&evsel->hists, he->filtered);
256 return he;
257}
258
259static void perf_top__print_sym_table(struct perf_top *top) 249static void perf_top__print_sym_table(struct perf_top *top)
260{ 250{
261 char bf[160]; 251 char bf[160];
@@ -659,6 +649,26 @@ static int symbol_filter(struct map *map __maybe_unused, struct symbol *sym)
659 return 0; 649 return 0;
660} 650}
661 651
652static int hist_iter__top_callback(struct hist_entry_iter *iter,
653 struct addr_location *al, bool single,
654 void *arg)
655{
656 struct perf_top *top = arg;
657 struct hist_entry *he = iter->he;
658 struct perf_evsel *evsel = iter->evsel;
659
660 if (sort__has_sym && single) {
661 u64 ip = al->addr;
662
663 if (al->map)
664 ip = al->map->unmap_ip(al->map, ip);
665
666 perf_top__record_precise_ip(top, he, evsel->idx, ip);
667 }
668
669 return 0;
670}
671
662static void perf_event__process_sample(struct perf_tool *tool, 672static void perf_event__process_sample(struct perf_tool *tool,
663 const union perf_event *event, 673 const union perf_event *event,
664 struct perf_evsel *evsel, 674 struct perf_evsel *evsel,
@@ -666,8 +676,6 @@ static void perf_event__process_sample(struct perf_tool *tool,
666 struct machine *machine) 676 struct machine *machine)
667{ 677{
668 struct perf_top *top = container_of(tool, struct perf_top, tool); 678 struct perf_top *top = container_of(tool, struct perf_top, tool);
669 struct symbol *parent = NULL;
670 u64 ip = sample->ip;
671 struct addr_location al; 679 struct addr_location al;
672 int err; 680 int err;
673 681
@@ -742,25 +750,23 @@ static void perf_event__process_sample(struct perf_tool *tool,
742 } 750 }
743 751
744 if (al.sym == NULL || !al.sym->ignore) { 752 if (al.sym == NULL || !al.sym->ignore) {
745 struct hist_entry *he; 753 struct hist_entry_iter iter = {
754 .add_entry_cb = hist_iter__top_callback,
755 };
746 756
747 err = sample__resolve_callchain(sample, &parent, evsel, &al, 757 if (symbol_conf.cumulate_callchain)
748 top->max_stack); 758 iter.ops = &hist_iter_cumulative;
749 if (err) 759 else
750 return; 760 iter.ops = &hist_iter_normal;
751 761
752 he = perf_evsel__add_hist_entry(evsel, &al, sample); 762 pthread_mutex_lock(&evsel->hists.lock);
753 if (he == NULL) {
754 pr_err("Problem incrementing symbol period, skipping event\n");
755 return;
756 }
757 763
758 err = hist_entry__append_callchain(he, sample); 764 err = hist_entry_iter__add(&iter, &al, evsel, sample,
759 if (err) 765 top->max_stack, top);
760 return; 766 if (err < 0)
767 pr_err("Problem incrementing symbol period, skipping event\n");
761 768
762 if (sort__has_sym) 769 pthread_mutex_unlock(&evsel->hists.lock);
763 perf_top__record_precise_ip(top, he, evsel->idx, ip);
764 } 770 }
765 771
766 return; 772 return;