aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2010-05-14 13:19:35 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-05-14 13:19:35 -0400
commitc82ee828aa20487d254a5225d256cd422acee459 (patch)
tree6f8132442237bc4f2393e04a5f30b3711a8f91ca /tools
parentcee75ac7ecc27084accdb9d9d6fde65a09f047ae (diff)
perf report: Report number of events, not samples
Number of samples is meaningless after we switched to auto-freq, so report the number of events, i.e. not the sum of the different periods, but the number PERF_RECORD_SAMPLE emitted by the kernel. While doing this I noticed that naming "count" to the sum of all the event periods can be confusing, so rename it to .period, just like in struct sample.data, so that we become more consistent. This helps with the next step, that was to record in struct hist_entry the number of sample events for each instance, we need that because we use it to generate the number of events when applying filters to the tree of hist entries like it is being done in the TUI report browser. Suggested-by: Ingo Molnar <mingo@elte.hu> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-diff.c6
-rw-r--r--tools/perf/builtin-report.c32
-rw-r--r--tools/perf/util/hist.c88
-rw-r--r--tools/perf/util/hist.h2
-rw-r--r--tools/perf/util/newt.c8
-rw-r--r--tools/perf/util/sort.h11
-rw-r--r--tools/perf/util/util.c22
-rw-r--r--tools/perf/util/util.h1
8 files changed, 107 insertions, 63 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 6dd4bdae8a87..a6e2fdc7a04e 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -23,9 +23,9 @@ static bool force;
23static bool show_displacement; 23static bool show_displacement;
24 24
25static int hists__add_entry(struct hists *self, 25static int hists__add_entry(struct hists *self,
26 struct addr_location *al, u64 count) 26 struct addr_location *al, u64 period)
27{ 27{
28 if (__hists__add_entry(self, al, NULL, count) != NULL) 28 if (__hists__add_entry(self, al, NULL, period) != NULL)
29 return 0; 29 return 0;
30 return -ENOMEM; 30 return -ENOMEM;
31} 31}
@@ -50,7 +50,7 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi
50 event__parse_sample(event, session->sample_type, &data); 50 event__parse_sample(event, session->sample_type, &data);
51 51
52 if (hists__add_entry(&session->hists, &al, data.period)) { 52 if (hists__add_entry(&session->hists, &al, data.period)) {
53 pr_warning("problem incrementing symbol count, skipping event\n"); 53 pr_warning("problem incrementing symbol period, skipping event\n");
54 return -1; 54 return -1;
55 } 55 }
56 56
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index b8f47ded6287..68265120ee07 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -188,14 +188,14 @@ static int process_sample_event(event_t *event, struct perf_session *session)
188 return 0; 188 return 0;
189 189
190 if (perf_session__add_hist_entry(session, &al, &data)) { 190 if (perf_session__add_hist_entry(session, &al, &data)) {
191 pr_debug("problem incrementing symbol count, skipping event\n"); 191 pr_debug("problem incrementing symbol period, skipping event\n");
192 return -1; 192 return -1;
193 } 193 }
194 194
195 attr = perf_header__find_attr(data.id, &session->header); 195 attr = perf_header__find_attr(data.id, &session->header);
196 196
197 if (add_event_total(session, &data, attr)) { 197 if (add_event_total(session, &data, attr)) {
198 pr_debug("problem adding event count\n"); 198 pr_debug("problem adding event period\n");
199 return -1; 199 return -1;
200 } 200 }
201 201
@@ -269,11 +269,25 @@ static struct perf_event_ops event_ops = {
269 269
270extern volatile int session_done; 270extern volatile int session_done;
271 271
272static void sig_handler(int sig __attribute__((__unused__))) 272static void sig_handler(int sig __used)
273{ 273{
274 session_done = 1; 274 session_done = 1;
275} 275}
276 276
277static size_t hists__fprintf_nr_sample_events(struct hists *self,
278 const char *evname, FILE *fp)
279{
280 size_t ret;
281 char unit;
282 unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE];
283
284 nr_events = convert_unit(nr_events, &unit);
285 ret = fprintf(fp, "# Events: %lu%c", nr_events, unit);
286 if (evname != NULL)
287 ret += fprintf(fp, " %s", evname);
288 return ret + fprintf(fp, "\n#\n");
289}
290
277static int __cmd_report(void) 291static int __cmd_report(void)
278{ 292{
279 int ret = -EINVAL; 293 int ret = -EINVAL;
@@ -319,14 +333,12 @@ static int __cmd_report(void)
319 if (use_browser) 333 if (use_browser)
320 hists__browse(hists, help, input_name); 334 hists__browse(hists, help, input_name);
321 else { 335 else {
322 if (rb_first(&session->hists.entries) == 336 const char *evname = NULL;
337 if (rb_first(&session->hists.entries) !=
323 rb_last(&session->hists.entries)) 338 rb_last(&session->hists.entries))
324 fprintf(stdout, "# Samples: %Ld\n#\n", 339 evname = __event_name(hists->type, hists->config);
325 hists->stats.total_period); 340
326 else 341 hists__fprintf_nr_sample_events(hists, evname, stdout);
327 fprintf(stdout, "# Samples: %Ld %s\n#\n",
328 hists->stats.total_period,
329 __event_name(hists->type, hists->config));
330 342
331 hists__fprintf(hists, NULL, false, stdout); 343 hists__fprintf(hists, NULL, false, stdout);
332 fprintf(stdout, "\n\n"); 344 fprintf(stdout, "\n\n");
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index c59224518083..f75c5f62401c 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -9,21 +9,21 @@ struct callchain_param callchain_param = {
9 .min_percent = 0.5 9 .min_percent = 0.5
10}; 10};
11 11
12static void hist_entry__add_cpumode_count(struct hist_entry *self, 12static void hist_entry__add_cpumode_period(struct hist_entry *self,
13 unsigned int cpumode, u64 count) 13 unsigned int cpumode, u64 period)
14{ 14{
15 switch (cpumode) { 15 switch (cpumode) {
16 case PERF_RECORD_MISC_KERNEL: 16 case PERF_RECORD_MISC_KERNEL:
17 self->count_sys += count; 17 self->period_sys += period;
18 break; 18 break;
19 case PERF_RECORD_MISC_USER: 19 case PERF_RECORD_MISC_USER:
20 self->count_us += count; 20 self->period_us += period;
21 break; 21 break;
22 case PERF_RECORD_MISC_GUEST_KERNEL: 22 case PERF_RECORD_MISC_GUEST_KERNEL:
23 self->count_guest_sys += count; 23 self->period_guest_sys += period;
24 break; 24 break;
25 case PERF_RECORD_MISC_GUEST_USER: 25 case PERF_RECORD_MISC_GUEST_USER:
26 self->count_guest_us += count; 26 self->period_guest_us += period;
27 break; 27 break;
28 default: 28 default:
29 break; 29 break;
@@ -31,7 +31,7 @@ static void hist_entry__add_cpumode_count(struct hist_entry *self,
31} 31}
32 32
33/* 33/*
34 * histogram, sorted on item, collects counts 34 * histogram, sorted on item, collects periods
35 */ 35 */
36 36
37static struct hist_entry *hist_entry__new(struct hist_entry *template) 37static struct hist_entry *hist_entry__new(struct hist_entry *template)
@@ -41,6 +41,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
41 41
42 if (self != NULL) { 42 if (self != NULL) {
43 *self = *template; 43 *self = *template;
44 self->nr_events = 1;
44 if (symbol_conf.use_callchain) 45 if (symbol_conf.use_callchain)
45 callchain_init(self->callchain); 46 callchain_init(self->callchain);
46 } 47 }
@@ -57,7 +58,7 @@ static void hists__inc_nr_entries(struct hists *self, struct hist_entry *entry)
57 58
58struct hist_entry *__hists__add_entry(struct hists *self, 59struct hist_entry *__hists__add_entry(struct hists *self,
59 struct addr_location *al, 60 struct addr_location *al,
60 struct symbol *sym_parent, u64 count) 61 struct symbol *sym_parent, u64 period)
61{ 62{
62 struct rb_node **p = &self->entries.rb_node; 63 struct rb_node **p = &self->entries.rb_node;
63 struct rb_node *parent = NULL; 64 struct rb_node *parent = NULL;
@@ -70,7 +71,7 @@ struct hist_entry *__hists__add_entry(struct hists *self,
70 }, 71 },
71 .ip = al->addr, 72 .ip = al->addr,
72 .level = al->level, 73 .level = al->level,
73 .count = count, 74 .period = period,
74 .parent = sym_parent, 75 .parent = sym_parent,
75 }; 76 };
76 int cmp; 77 int cmp;
@@ -82,7 +83,8 @@ struct hist_entry *__hists__add_entry(struct hists *self,
82 cmp = hist_entry__cmp(&entry, he); 83 cmp = hist_entry__cmp(&entry, he);
83 84
84 if (!cmp) { 85 if (!cmp) {
85 he->count += count; 86 he->period += period;
87 ++he->nr_events;
86 goto out; 88 goto out;
87 } 89 }
88 90
@@ -99,7 +101,7 @@ struct hist_entry *__hists__add_entry(struct hists *self,
99 rb_insert_color(&he->rb_node, &self->entries); 101 rb_insert_color(&he->rb_node, &self->entries);
100 hists__inc_nr_entries(self, he); 102 hists__inc_nr_entries(self, he);
101out: 103out:
102 hist_entry__add_cpumode_count(he, al->cpumode, count); 104 hist_entry__add_cpumode_period(he, al->cpumode, period);
103 return he; 105 return he;
104} 106}
105 107
@@ -160,7 +162,7 @@ static bool collapse__insert_entry(struct rb_root *root, struct hist_entry *he)
160 cmp = hist_entry__collapse(iter, he); 162 cmp = hist_entry__collapse(iter, he);
161 163
162 if (!cmp) { 164 if (!cmp) {
163 iter->count += he->count; 165 iter->period += he->period;
164 hist_entry__free(he); 166 hist_entry__free(he);
165 return false; 167 return false;
166 } 168 }
@@ -203,7 +205,7 @@ void hists__collapse_resort(struct hists *self)
203} 205}
204 206
205/* 207/*
206 * reverse the map, sort on count. 208 * reverse the map, sort on period.
207 */ 209 */
208 210
209static void __hists__insert_output_entry(struct rb_root *entries, 211static void __hists__insert_output_entry(struct rb_root *entries,
@@ -222,7 +224,7 @@ static void __hists__insert_output_entry(struct rb_root *entries,
222 parent = *p; 224 parent = *p;
223 iter = rb_entry(parent, struct hist_entry, rb_node); 225 iter = rb_entry(parent, struct hist_entry, rb_node);
224 226
225 if (he->count > iter->count) 227 if (he->period > iter->period)
226 p = &(*p)->rb_left; 228 p = &(*p)->rb_left;
227 else 229 else
228 p = &(*p)->rb_right; 230 p = &(*p)->rb_right;
@@ -288,7 +290,7 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
288} 290}
289 291
290static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, 292static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
291 int depth, int depth_mask, int count, 293 int depth, int depth_mask, int period,
292 u64 total_samples, int hits, 294 u64 total_samples, int hits,
293 int left_margin) 295 int left_margin)
294{ 296{
@@ -301,7 +303,7 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
301 ret += fprintf(fp, "|"); 303 ret += fprintf(fp, "|");
302 else 304 else
303 ret += fprintf(fp, " "); 305 ret += fprintf(fp, " ");
304 if (!count && i == depth - 1) { 306 if (!period && i == depth - 1) {
305 double percent; 307 double percent;
306 308
307 percent = hits * 100.0 / total_samples; 309 percent = hits * 100.0 / total_samples;
@@ -516,7 +518,7 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
516 long displacement, bool color, u64 session_total) 518 long displacement, bool color, u64 session_total)
517{ 519{
518 struct sort_entry *se; 520 struct sort_entry *se;
519 u64 count, total, count_sys, count_us, count_guest_sys, count_guest_us; 521 u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
520 const char *sep = symbol_conf.field_sep; 522 const char *sep = symbol_conf.field_sep;
521 int ret; 523 int ret;
522 524
@@ -524,57 +526,57 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
524 return 0; 526 return 0;
525 527
526 if (pair_hists) { 528 if (pair_hists) {
527 count = self->pair ? self->pair->count : 0; 529 period = self->pair ? self->pair->period : 0;
528 total = pair_hists->stats.total_period; 530 total = pair_hists->stats.total_period;
529 count_sys = self->pair ? self->pair->count_sys : 0; 531 period_sys = self->pair ? self->pair->period_sys : 0;
530 count_us = self->pair ? self->pair->count_us : 0; 532 period_us = self->pair ? self->pair->period_us : 0;
531 count_guest_sys = self->pair ? self->pair->count_guest_sys : 0; 533 period_guest_sys = self->pair ? self->pair->period_guest_sys : 0;
532 count_guest_us = self->pair ? self->pair->count_guest_us : 0; 534 period_guest_us = self->pair ? self->pair->period_guest_us : 0;
533 } else { 535 } else {
534 count = self->count; 536 period = self->period;
535 total = session_total; 537 total = session_total;
536 count_sys = self->count_sys; 538 period_sys = self->period_sys;
537 count_us = self->count_us; 539 period_us = self->period_us;
538 count_guest_sys = self->count_guest_sys; 540 period_guest_sys = self->period_guest_sys;
539 count_guest_us = self->count_guest_us; 541 period_guest_us = self->period_guest_us;
540 } 542 }
541 543
542 if (total) { 544 if (total) {
543 if (color) 545 if (color)
544 ret = percent_color_snprintf(s, size, 546 ret = percent_color_snprintf(s, size,
545 sep ? "%.2f" : " %6.2f%%", 547 sep ? "%.2f" : " %6.2f%%",
546 (count * 100.0) / total); 548 (period * 100.0) / total);
547 else 549 else
548 ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%", 550 ret = snprintf(s, size, sep ? "%.2f" : " %6.2f%%",
549 (count * 100.0) / total); 551 (period * 100.0) / total);
550 if (symbol_conf.show_cpu_utilization) { 552 if (symbol_conf.show_cpu_utilization) {
551 ret += percent_color_snprintf(s + ret, size - ret, 553 ret += percent_color_snprintf(s + ret, size - ret,
552 sep ? "%.2f" : " %6.2f%%", 554 sep ? "%.2f" : " %6.2f%%",
553 (count_sys * 100.0) / total); 555 (period_sys * 100.0) / total);
554 ret += percent_color_snprintf(s + ret, size - ret, 556 ret += percent_color_snprintf(s + ret, size - ret,
555 sep ? "%.2f" : " %6.2f%%", 557 sep ? "%.2f" : " %6.2f%%",
556 (count_us * 100.0) / total); 558 (period_us * 100.0) / total);
557 if (perf_guest) { 559 if (perf_guest) {
558 ret += percent_color_snprintf(s + ret, 560 ret += percent_color_snprintf(s + ret,
559 size - ret, 561 size - ret,
560 sep ? "%.2f" : " %6.2f%%", 562 sep ? "%.2f" : " %6.2f%%",
561 (count_guest_sys * 100.0) / 563 (period_guest_sys * 100.0) /
562 total); 564 total);
563 ret += percent_color_snprintf(s + ret, 565 ret += percent_color_snprintf(s + ret,
564 size - ret, 566 size - ret,
565 sep ? "%.2f" : " %6.2f%%", 567 sep ? "%.2f" : " %6.2f%%",
566 (count_guest_us * 100.0) / 568 (period_guest_us * 100.0) /
567 total); 569 total);
568 } 570 }
569 } 571 }
570 } else 572 } else
571 ret = snprintf(s, size, sep ? "%lld" : "%12lld ", count); 573 ret = snprintf(s, size, sep ? "%lld" : "%12lld ", period);
572 574
573 if (symbol_conf.show_nr_samples) { 575 if (symbol_conf.show_nr_samples) {
574 if (sep) 576 if (sep)
575 ret += snprintf(s + ret, size - ret, "%c%lld", *sep, count); 577 ret += snprintf(s + ret, size - ret, "%c%lld", *sep, period);
576 else 578 else
577 ret += snprintf(s + ret, size - ret, "%11lld", count); 579 ret += snprintf(s + ret, size - ret, "%11lld", period);
578 } 580 }
579 581
580 if (pair_hists) { 582 if (pair_hists) {
@@ -582,9 +584,9 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
582 double old_percent = 0, new_percent = 0, diff; 584 double old_percent = 0, new_percent = 0, diff;
583 585
584 if (total > 0) 586 if (total > 0)
585 old_percent = (count * 100.0) / total; 587 old_percent = (period * 100.0) / total;
586 if (session_total > 0) 588 if (session_total > 0)
587 new_percent = (self->count * 100.0) / session_total; 589 new_percent = (self->period * 100.0) / session_total;
588 590
589 diff = new_percent - old_percent; 591 diff = new_percent - old_percent;
590 592
@@ -796,6 +798,7 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso)
796 struct rb_node *nd; 798 struct rb_node *nd;
797 799
798 self->nr_entries = self->stats.total_period = 0; 800 self->nr_entries = self->stats.total_period = 0;
801 self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
799 self->max_sym_namelen = 0; 802 self->max_sym_namelen = 0;
800 803
801 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 804 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
@@ -812,7 +815,8 @@ void hists__filter_by_dso(struct hists *self, const struct dso *dso)
812 h->filtered &= ~(1 << HIST_FILTER__DSO); 815 h->filtered &= ~(1 << HIST_FILTER__DSO);
813 if (!h->filtered) { 816 if (!h->filtered) {
814 ++self->nr_entries; 817 ++self->nr_entries;
815 self->stats.total_period += h->count; 818 self->stats.total_period += h->period;
819 self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
816 if (h->ms.sym && 820 if (h->ms.sym &&
817 self->max_sym_namelen < h->ms.sym->namelen) 821 self->max_sym_namelen < h->ms.sym->namelen)
818 self->max_sym_namelen = h->ms.sym->namelen; 822 self->max_sym_namelen = h->ms.sym->namelen;
@@ -825,6 +829,7 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread)
825 struct rb_node *nd; 829 struct rb_node *nd;
826 830
827 self->nr_entries = self->stats.total_period = 0; 831 self->nr_entries = self->stats.total_period = 0;
832 self->stats.nr_events[PERF_RECORD_SAMPLE] = 0;
828 self->max_sym_namelen = 0; 833 self->max_sym_namelen = 0;
829 834
830 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 835 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
@@ -837,7 +842,8 @@ void hists__filter_by_thread(struct hists *self, const struct thread *thread)
837 h->filtered &= ~(1 << HIST_FILTER__THREAD); 842 h->filtered &= ~(1 << HIST_FILTER__THREAD);
838 if (!h->filtered) { 843 if (!h->filtered) {
839 ++self->nr_entries; 844 ++self->nr_entries;
840 self->stats.total_period += h->count; 845 self->stats.total_period += h->period;
846 self->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
841 if (h->ms.sym && 847 if (h->ms.sym &&
842 self->max_sym_namelen < h->ms.sym->namelen) 848 self->max_sym_namelen < h->ms.sym->namelen)
843 self->max_sym_namelen = h->ms.sym->namelen; 849 self->max_sym_namelen = h->ms.sym->namelen;
@@ -881,7 +887,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip)
881 h->sum++; 887 h->sum++;
882 h->ip[offset]++; 888 h->ip[offset]++;
883 889
884 pr_debug3("%#Lx %s: count++ [ip: %#Lx, %#Lx] => %Ld\n", self->ms.sym->start, 890 pr_debug3("%#Lx %s: period++ [ip: %#Lx, %#Lx] => %Ld\n", self->ms.sym->start,
885 self->ms.sym->name, ip, ip - self->ms.sym->start, h->ip[offset]); 891 self->ms.sym->name, ip, ip - self->ms.sym->start, h->ip[offset]);
886 return 0; 892 return 0;
887} 893}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index da6b84814a50..6f17dcd8412c 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -69,7 +69,7 @@ struct hists {
69 69
70struct hist_entry *__hists__add_entry(struct hists *self, 70struct hist_entry *__hists__add_entry(struct hists *self,
71 struct addr_location *al, 71 struct addr_location *al,
72 struct symbol *parent, u64 count); 72 struct symbol *parent, u64 period);
73extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); 73extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *);
74extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); 74extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *);
75int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists, 75int hist_entry__fprintf(struct hist_entry *self, struct hists *pair_hists,
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index 010bacf40163..3402453812b3 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -680,16 +680,18 @@ static int hist_browser__populate(struct hist_browser *self, struct hists *hists
680 struct ui_progress *progress; 680 struct ui_progress *progress;
681 struct rb_node *nd; 681 struct rb_node *nd;
682 u64 curr_hist = 0; 682 u64 curr_hist = 0;
683 char seq[] = "."; 683 char seq[] = ".", unit;
684 char str[256]; 684 char str[256];
685 unsigned long nr_events = hists->stats.nr_events[PERF_RECORD_SAMPLE];
685 686
686 if (self->form) { 687 if (self->form) {
687 newtFormDestroy(self->form); 688 newtFormDestroy(self->form);
688 newtPopWindow(); 689 newtPopWindow();
689 } 690 }
690 691
691 snprintf(str, sizeof(str), "Samples: %Ld ", 692 nr_events = convert_unit(nr_events, &unit);
692 hists->stats.total_period); 693 snprintf(str, sizeof(str), "Events: %lu%c ",
694 nr_events, unit);
693 newtDrawRootText(0, 0, str); 695 newtDrawRootText(0, 0, str);
694 696
695 newtGetScreenSize(NULL, &rows); 697 newtGetScreenSize(NULL, &rows);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index af301acc461c..eab2e0b3b74e 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -43,14 +43,15 @@ extern enum sort_type sort__first_dimension;
43 43
44struct hist_entry { 44struct hist_entry {
45 struct rb_node rb_node; 45 struct rb_node rb_node;
46 u64 count; 46 u64 period;
47 u64 count_sys; 47 u64 period_sys;
48 u64 count_us; 48 u64 period_us;
49 u64 count_guest_sys; 49 u64 period_guest_sys;
50 u64 count_guest_us; 50 u64 period_guest_us;
51 struct map_symbol ms; 51 struct map_symbol ms;
52 struct thread *thread; 52 struct thread *thread;
53 u64 ip; 53 u64 ip;
54 u32 nr_events;
54 char level; 55 char level;
55 u8 filtered; 56 u8 filtered;
56 struct symbol *parent; 57 struct symbol *parent;
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index f9b890fde681..214265674ddd 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -92,3 +92,25 @@ out_close_from:
92out: 92out:
93 return err; 93 return err;
94} 94}
95
96unsigned long convert_unit(unsigned long value, char *unit)
97{
98 *unit = ' ';
99
100 if (value > 1000) {
101 value /= 1000;
102 *unit = 'K';
103 }
104
105 if (value > 1000) {
106 value /= 1000;
107 *unit = 'M';
108 }
109
110 if (value > 1000) {
111 value /= 1000;
112 *unit = 'G';
113 }
114
115 return value;
116}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index fbf45d1b26f7..0795bf304b19 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -423,6 +423,7 @@ char **argv_split(const char *str, int *argcp);
423void argv_free(char **argv); 423void argv_free(char **argv);
424bool strglobmatch(const char *str, const char *pat); 424bool strglobmatch(const char *str, const char *pat);
425bool strlazymatch(const char *str, const char *pat); 425bool strlazymatch(const char *str, const char *pat);
426unsigned long convert_unit(unsigned long value, char *unit);
426 427
427#define _STR(x) #x 428#define _STR(x) #x
428#define STR(x) _STR(x) 429#define STR(x) _STR(x)