diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-10-11 15:15:39 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-10-11 15:16:54 -0400 |
commit | 900e14a8f5a49e987790b93c7906989b22075f1b (patch) | |
tree | 384fefd278474a1e03ccc68efbf7ea92e393ee6f /tools | |
parent | 7588badafcd762034aa962ec86b82cacd4f42f74 (diff) |
perf hists browser: Recalculate browser pointers after resort/decay
In browsers that access dynamic underlying data structures, like in the
hists browser and its hist_entry rb_tree, we need to revalidate any
reference to the underlying data structure, because they can have gone
away, decayed.
This fixes a problem where after a while the top entries get behind the
top of the screen, i.e. the top_idx stays at 0, which means it is at the
first entry in the rb_tree when in fact it wasn't because the
browser->top didn't got revalidated after the timer ran and the
underlying data structure got updated.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-mhje66qssdko24q67a2lhlho@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/ui/browser.c | 23 | ||||
-rw-r--r-- | tools/perf/util/ui/browser.h | 1 | ||||
-rw-r--r-- | tools/perf/util/ui/browsers/hists.c | 9 |
3 files changed, 26 insertions, 7 deletions
diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c index 611219f80680..5911bba63858 100644 --- a/tools/perf/util/ui/browser.c +++ b/tools/perf/util/ui/browser.c | |||
@@ -230,6 +230,29 @@ int ui_browser__refresh(struct ui_browser *self) | |||
230 | return 0; | 230 | return 0; |
231 | } | 231 | } |
232 | 232 | ||
233 | /* | ||
234 | * Here we're updating nr_entries _after_ we started browsing, i.e. we have to | ||
235 | * forget about any reference to any entry in the underlying data structure, | ||
236 | * that is why we do a SEEK_SET. Think about 'perf top' in the hists browser | ||
237 | * after an output_resort and hist decay. | ||
238 | */ | ||
239 | void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries) | ||
240 | { | ||
241 | off_t offset = nr_entries - browser->nr_entries; | ||
242 | |||
243 | browser->nr_entries = nr_entries; | ||
244 | |||
245 | if (offset < 0) { | ||
246 | if (browser->top_idx < (u64)-offset) | ||
247 | offset = -browser->top_idx; | ||
248 | |||
249 | browser->index += offset; | ||
250 | browser->top_idx += offset; | ||
251 | } | ||
252 | |||
253 | browser->seek(browser, browser->top_idx, SEEK_SET); | ||
254 | } | ||
255 | |||
233 | int ui_browser__run(struct ui_browser *self) | 256 | int ui_browser__run(struct ui_browser *self) |
234 | { | 257 | { |
235 | struct newtExitStruct es; | 258 | struct newtExitStruct es; |
diff --git a/tools/perf/util/ui/browser.h b/tools/perf/util/ui/browser.h index fc63dda10910..d42be43ac0e8 100644 --- a/tools/perf/util/ui/browser.h +++ b/tools/perf/util/ui/browser.h | |||
@@ -41,6 +41,7 @@ int ui_browser__show(struct ui_browser *self, const char *title, | |||
41 | void ui_browser__hide(struct ui_browser *self); | 41 | void ui_browser__hide(struct ui_browser *self); |
42 | int ui_browser__refresh(struct ui_browser *self); | 42 | int ui_browser__refresh(struct ui_browser *self); |
43 | int ui_browser__run(struct ui_browser *self); | 43 | int ui_browser__run(struct ui_browser *self); |
44 | void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries); | ||
44 | 45 | ||
45 | void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence); | 46 | void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence); |
46 | unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self); | 47 | unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self); |
diff --git a/tools/perf/util/ui/browsers/hists.c b/tools/perf/util/ui/browsers/hists.c index e64d9527f14e..9ece84353538 100644 --- a/tools/perf/util/ui/browsers/hists.c +++ b/tools/perf/util/ui/browsers/hists.c | |||
@@ -332,13 +332,7 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name, | |||
332 | case -1: | 332 | case -1: |
333 | /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */ | 333 | /* FIXME we need to check if it was es.reason == NEWT_EXIT_TIMER */ |
334 | timer(arg); | 334 | timer(arg); |
335 | /* | 335 | ui_browser__update_nr_entries(&self->b, self->hists->nr_entries); |
336 | * The timer may have changed the number of entries. | ||
337 | * XXX: Find better way to keep this in synch, probably | ||
338 | * removing this timer function altogether and just sync | ||
339 | * using the hists->lock... | ||
340 | */ | ||
341 | self->b.nr_entries = self->hists->nr_entries; | ||
342 | hists__browser_title(self->hists, title, sizeof(title), | 336 | hists__browser_title(self->hists, title, sizeof(title), |
343 | ev_name, self->dso_filter, | 337 | ev_name, self->dso_filter, |
344 | self->thread_filter); | 338 | self->thread_filter); |
@@ -985,6 +979,7 @@ do_annotate: | |||
985 | 979 | ||
986 | hist_entry__tui_annotate(he, evsel->idx, nr_events, | 980 | hist_entry__tui_annotate(he, evsel->idx, nr_events, |
987 | timer, arg, delay_secs); | 981 | timer, arg, delay_secs); |
982 | ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); | ||
988 | } else if (choice == browse_map) | 983 | } else if (choice == browse_map) |
989 | map__browse(browser->selection->map); | 984 | map__browse(browser->selection->map); |
990 | else if (choice == zoom_dso) { | 985 | else if (choice == zoom_dso) { |