aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2014-01-07 03:41:03 -0500
committerJiri Olsa <jolsa@kernel.org>2014-06-01 08:35:06 -0400
commit7c50391f536ea6ed1e75b0f4d90922a2606da3de (patch)
tree68c13d77f8b5e0afa1e025d84df5f43a73ed2ba8 /tools
parent9d3c02d7188866299eebe3c4a652c08140a71f40 (diff)
perf top: Convert to hist_entry_iter
Reuse hist_entry_iter__add() function to share the similar code with perf report. Note that it needs to be called with hists.lock so tweak some internal functions not to deadlock or hold the lock too long. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Tested-by: Arun Sharma <asharma@fb.com> Tested-by: Rodrigo Campos <rodrigo@sdfg.com.ar> Link: http://lkml.kernel.org/r/1401335910-16832-20-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Diffstat (limited to 'tools')
-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;