aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-10-11 15:15:39 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-10-11 15:16:54 -0400
commit900e14a8f5a49e987790b93c7906989b22075f1b (patch)
tree384fefd278474a1e03ccc68efbf7ea92e393ee6f /tools
parent7588badafcd762034aa962ec86b82cacd4f42f74 (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.c23
-rw-r--r--tools/perf/util/ui/browser.h1
-rw-r--r--tools/perf/util/ui/browsers/hists.c9
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 */
239void 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
233int ui_browser__run(struct ui_browser *self) 256int 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,
41void ui_browser__hide(struct ui_browser *self); 41void ui_browser__hide(struct ui_browser *self);
42int ui_browser__refresh(struct ui_browser *self); 42int ui_browser__refresh(struct ui_browser *self);
43int ui_browser__run(struct ui_browser *self); 43int ui_browser__run(struct ui_browser *self);
44void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries);
44 45
45void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence); 46void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence);
46unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self); 47unsigned 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) {