aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-03-26 20:16:22 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-04-02 15:27:55 -0400
commit5f4d3f8816461300ce54505c9117bf85b3044aa0 (patch)
treeb69a6f22792480ab1ee02c67e5f8a650d66f208d /tools
parent7e5e1b1404c30db5f6bc3f5203b6c21c1d244f99 (diff)
perf report: Add progress bars
For when we are processing the events and inserting the entries in the browser. Experimentation here: naming "ui_something" we may be treading into creating a TUI/GUI set of routines that can then be implemented in terms of multiple backends. Also the time it takes for adding things to the "browser" takes, visually (I guess I should do some profiling here ;-) ), more time than for processing the events... That means we probably need to create a custom hist_entry browser, so that we reuse the structures we have in place instead of duplicating them in newt. But progress was made and at least we can see something while long files are being loaded, that must be one of UI 101 bullet points :-) Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-report.c7
-rw-r--r--tools/perf/util/debug.h16
-rw-r--r--tools/perf/util/hist.c5
-rw-r--r--tools/perf/util/hist.h2
-rw-r--r--tools/perf/util/newt.c103
-rw-r--r--tools/perf/util/session.c6
-rw-r--r--tools/perf/util/session.h12
7 files changed, 119 insertions, 32 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 6ab16980dd66..381918515a5c 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -303,13 +303,14 @@ static int __cmd_report(void)
303 next = rb_first(&session->stats_by_id); 303 next = rb_first(&session->stats_by_id);
304 while (next) { 304 while (next) {
305 struct event_stat_id *stats; 305 struct event_stat_id *stats;
306 u64 nr_hists;
306 307
307 stats = rb_entry(next, struct event_stat_id, rb_node); 308 stats = rb_entry(next, struct event_stat_id, rb_node);
308 perf_session__collapse_resort(&stats->hists); 309 perf_session__collapse_resort(&stats->hists);
309 perf_session__output_resort(&stats->hists, stats->stats.total); 310 nr_hists = perf_session__output_resort(&stats->hists,
310 311 stats->stats.total);
311 if (use_browser) 312 if (use_browser)
312 perf_session__browse_hists(&stats->hists, 313 perf_session__browse_hists(&stats->hists, nr_hists,
313 stats->stats.total, help); 314 stats->stats.total, help);
314 else { 315 else {
315 if (rb_first(&session->stats_by_id) == 316 if (rb_first(&session->stats_by_id) ==
diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h
index 0172edf3f153..5cb0a1b1401a 100644
--- a/tools/perf/util/debug.h
+++ b/tools/perf/util/debug.h
@@ -10,13 +10,29 @@ extern int dump_trace;
10int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); 10int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
11void trace_event(event_t *event); 11void trace_event(event_t *event);
12 12
13struct ui_progress;
14
13#ifdef NO_NEWT_SUPPORT 15#ifdef NO_NEWT_SUPPORT
14static inline int browser__show_help(const char *format __used, va_list ap __used) 16static inline int browser__show_help(const char *format __used, va_list ap __used)
15{ 17{
16 return 0; 18 return 0;
17} 19}
20
21static inline struct ui_progress *ui_progress__new(const char *title __used,
22 u64 total __used)
23{
24 return (struct ui_progress *)1;
25}
26
27static inline void ui_progress__update(struct ui_progress *self __used,
28 u64 curr __used) {}
29
30static inline void ui_progress__delete(struct ui_progress *self __used) {}
18#else 31#else
19int browser__show_help(const char *format, va_list ap); 32int browser__show_help(const char *format, va_list ap);
33struct ui_progress *ui_progress__new(const char *title, u64 total);
34void ui_progress__update(struct ui_progress *self, u64 curr);
35void ui_progress__delete(struct ui_progress *self);
20#endif 36#endif
21 37
22#endif /* __PERF_DEBUG_H */ 38#endif /* __PERF_DEBUG_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index de3190102cc8..a46d09332462 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -185,12 +185,13 @@ static void perf_session__insert_output_hist_entry(struct rb_root *root,
185 rb_insert_color(&he->rb_node, root); 185 rb_insert_color(&he->rb_node, root);
186} 186}
187 187
188void perf_session__output_resort(struct rb_root *hists, u64 total_samples) 188u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples)
189{ 189{
190 struct rb_root tmp; 190 struct rb_root tmp;
191 struct rb_node *next; 191 struct rb_node *next;
192 struct hist_entry *n; 192 struct hist_entry *n;
193 u64 min_callchain_hits; 193 u64 min_callchain_hits;
194 u64 nr_hists = 0;
194 195
195 min_callchain_hits = 196 min_callchain_hits =
196 total_samples * (callchain_param.min_percent / 100); 197 total_samples * (callchain_param.min_percent / 100);
@@ -205,9 +206,11 @@ void perf_session__output_resort(struct rb_root *hists, u64 total_samples)
205 rb_erase(&n->rb_node, hists); 206 rb_erase(&n->rb_node, hists);
206 perf_session__insert_output_hist_entry(&tmp, n, 207 perf_session__insert_output_hist_entry(&tmp, n,
207 min_callchain_hits); 208 min_callchain_hits);
209 ++nr_hists;
208 } 210 }
209 211
210 *hists = tmp; 212 *hists = tmp;
213 return nr_hists;
211} 214}
212 215
213static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin) 216static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index fe366ce5db45..da6a8c1320fa 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -25,7 +25,7 @@ size_t hist_entry__fprintf(struct hist_entry *self,
25 u64 session_total); 25 u64 session_total);
26void hist_entry__free(struct hist_entry *); 26void hist_entry__free(struct hist_entry *);
27 27
28void perf_session__output_resort(struct rb_root *hists, u64 total_samples); 28u64 perf_session__output_resort(struct rb_root *hists, u64 total_samples);
29void perf_session__collapse_resort(struct rb_root *hists); 29void perf_session__collapse_resort(struct rb_root *hists);
30size_t perf_session__fprintf_hists(struct rb_root *hists, 30size_t perf_session__fprintf_hists(struct rb_root *hists,
31 struct perf_session *pair, 31 struct perf_session *pair,
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index e99bcc8d1939..b0210ae5b93c 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -12,6 +12,72 @@
12#include "sort.h" 12#include "sort.h"
13#include "symbol.h" 13#include "symbol.h"
14 14
15struct ui_progress {
16 newtComponent form, scale;
17};
18
19struct ui_progress *ui_progress__new(const char *title, u64 total)
20{
21 struct ui_progress *self = malloc(sizeof(*self));
22
23 if (self != NULL) {
24 int cols;
25 newtGetScreenSize(&cols, NULL);
26 cols -= 4;
27 newtCenteredWindow(cols, 1, title);
28 self->form = newtForm(NULL, NULL, 0);
29 if (self->form == NULL)
30 goto out_free_self;
31 self->scale = newtScale(0, 0, cols, total);
32 if (self->scale == NULL)
33 goto out_free_form;
34 newtFormAddComponents(self->form, self->scale, NULL);
35 newtRefresh();
36 }
37
38 return self;
39
40out_free_form:
41 newtFormDestroy(self->form);
42out_free_self:
43 free(self);
44 return NULL;
45}
46
47void ui_progress__update(struct ui_progress *self, u64 curr)
48{
49 newtScaleSet(self->scale, curr);
50 newtRefresh();
51}
52
53void ui_progress__delete(struct ui_progress *self)
54{
55 newtFormDestroy(self->form);
56 newtPopWindow();
57 free(self);
58}
59
60static char browser__last_msg[1024];
61
62int browser__show_help(const char *format, va_list ap)
63{
64 int ret;
65 static int backlog;
66
67 ret = vsnprintf(browser__last_msg + backlog,
68 sizeof(browser__last_msg) - backlog, format, ap);
69 backlog += ret;
70
71 if (browser__last_msg[backlog - 1] == '\n') {
72 newtPopHelpLine();
73 newtPushHelpLine(browser__last_msg);
74 newtRefresh();
75 backlog = 0;
76 }
77
78 return ret;
79}
80
15static void newt_form__set_exit_keys(newtComponent self) 81static void newt_form__set_exit_keys(newtComponent self)
16{ 82{
17 newtFormAddHotKey(self, NEWT_KEY_ESCAPE); 83 newtFormAddHotKey(self, NEWT_KEY_ESCAPE);
@@ -364,8 +430,8 @@ static void perf_session__selection(newtComponent self, void *data)
364 *symbol_ptr = newt__symbol_tree_get_current(self); 430 *symbol_ptr = newt__symbol_tree_get_current(self);
365} 431}
366 432
367void perf_session__browse_hists(struct rb_root *hists, u64 session_total, 433int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
368 const char *helpline) 434 u64 session_total, const char *helpline)
369{ 435{
370 struct sort_entry *se; 436 struct sort_entry *se;
371 struct rb_node *nd; 437 struct rb_node *nd;
@@ -378,6 +444,12 @@ void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
378 newtComponent form, tree; 444 newtComponent form, tree;
379 struct newtExitStruct es; 445 struct newtExitStruct es;
380 const struct map_symbol *selection; 446 const struct map_symbol *selection;
447 u64 curr_hist = 0;
448 struct ui_progress *progress;
449
450 progress = ui_progress__new("Adding entries to the browser...", nr_hists);
451 if (progress == NULL)
452 return -1;
381 453
382 snprintf(str, sizeof(str), "Samples: %Ld", session_total); 454 snprintf(str, sizeof(str), "Samples: %Ld", session_total);
383 newtDrawRootText(0, 0, str); 455 newtDrawRootText(0, 0, str);
@@ -419,8 +491,13 @@ void perf_session__browse_hists(struct rb_root *hists, u64 session_total,
419 max_len = len; 491 max_len = len;
420 if (symbol_conf.use_callchain) 492 if (symbol_conf.use_callchain)
421 hist_entry__append_callchain_browser(h, tree, session_total, idx++); 493 hist_entry__append_callchain_browser(h, tree, session_total, idx++);
494 ++curr_hist;
495 if (curr_hist % 5)
496 ui_progress__update(progress, curr_hist);
422 } 497 }
423 498
499 ui_progress__delete(progress);
500
424 if (max_len > cols) 501 if (max_len > cols)
425 max_len = cols - 3; 502 max_len = cols - 3;
426 503
@@ -480,27 +557,7 @@ do_annotate:
480 557
481 newtFormDestroy(form); 558 newtFormDestroy(form);
482 newtPopWindow(); 559 newtPopWindow();
483} 560 return 0;
484
485static char browser__last_msg[1024];
486
487int browser__show_help(const char *format, va_list ap)
488{
489 int ret;
490 static int backlog;
491
492 ret = vsnprintf(browser__last_msg + backlog,
493 sizeof(browser__last_msg) - backlog, format, ap);
494 backlog += ret;
495
496 if (browser__last_msg[backlog - 1] == '\n') {
497 newtPopHelpLine();
498 newtPushHelpLine(browser__last_msg);
499 newtRefresh();
500 backlog = 0;
501 }
502
503 return ret;
504} 561}
505 562
506void setup_browser(void) 563void setup_browser(void)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 76b4ac689df9..32765cdca058 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -397,6 +397,10 @@ int __perf_session__process_events(struct perf_session *self,
397 event_t *event; 397 event_t *event;
398 uint32_t size; 398 uint32_t size;
399 char *buf; 399 char *buf;
400 struct ui_progress *progress = ui_progress__new("Processing events...",
401 self->size);
402 if (progress == NULL)
403 return -1;
400 404
401 perf_event_ops__fill_defaults(ops); 405 perf_event_ops__fill_defaults(ops);
402 406
@@ -425,6 +429,7 @@ remap:
425 429
426more: 430more:
427 event = (event_t *)(buf + head); 431 event = (event_t *)(buf + head);
432 ui_progress__update(progress, offset);
428 433
429 if (self->header.needs_swap) 434 if (self->header.needs_swap)
430 perf_event_header__bswap(&event->header); 435 perf_event_header__bswap(&event->header);
@@ -475,6 +480,7 @@ more:
475done: 480done:
476 err = 0; 481 err = 0;
477out_err: 482out_err:
483 ui_progress__delete(progress);
478 return err; 484 return err;
479} 485}
480 486
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 631f8157fc17..6a15daeda577 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -88,11 +88,15 @@ static inline struct map *
88} 88}
89 89
90#ifdef NO_NEWT_SUPPORT 90#ifdef NO_NEWT_SUPPORT
91static inline void perf_session__browse_hists(struct rb_root *hists __used, 91static inline int perf_session__browse_hists(struct rb_root *hists __used,
92 u64 nr_hists __used,
92 u64 session_total __used, 93 u64 session_total __used,
93 const char *helpline __used) {} 94 const char *helpline __used)
95{
96 return 0;
97}
94#else 98#else
95void perf_session__browse_hists(struct rb_root *hists, u64 session_total, 99int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
96 const char *helpline); 100 u64 session_total, const char *helpline);
97#endif 101#endif
98#endif /* __PERF_SESSION_H */ 102#endif /* __PERF_SESSION_H */