[PATCH 05/12] perf diff: Refactor stdio ui data columns output
From: Jiri Olsa
Date: Thu Sep 06 2012 - 11:51:29 EST
Currently for any of the data columns (like Overhead/Period..) in
stdio ui, there's separate code to print header/dots/value scattered
along the display code path.
Adding hists_stdio_column struct to centralize all info needed
to print column header/dots/value.
This change eases up addition for new columns, which is now mostly
matter only of adding new hists_stdio_column struct.
Cc: Arnaldo Carvalho de Melo <acme@xxxxxxxxxxxxxxxxxx>
Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxx>
Cc: Paul Mackerras <paulus@xxxxxxxxx>
Cc: Corey Ashford <cjashfor@xxxxxxxxxxxxxxxxxx>
Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Paul E. McKenney <paulmck@xxxxxxxxxxxxxxxxxx>
Cc: Andi Kleen <andi@xxxxxxxxxxxxxx>
Cc: David Ahern <dsahern@xxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
Signed-off-by: Jiri Olsa <jolsa@xxxxxxxxxx>
---
tools/perf/builtin-diff.c | 14 +-
tools/perf/builtin-report.c | 6 +-
tools/perf/builtin-top.c | 6 +-
tools/perf/ui/stdio/hist.c | 506 +++++++++++++++++++++++++-------------------
tools/perf/ui/stdio/hist.h | 19 ++
tools/perf/util/hist.c | 5 +-
tools/perf/util/hist.h | 19 +-
7 files changed, 345 insertions(+), 230 deletions(-)
create mode 100644 tools/perf/ui/stdio/hist.h
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 4e63979..282fd5e 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -16,6 +16,7 @@
#include "util/sort.h"
#include "util/symbol.h"
#include "util/util.h"
+#include "ui/stdio/hist.h"
#include <stdlib.h>
@@ -214,8 +215,7 @@ static int __cmd_diff(void)
first = false;
hists__match(&evsel_old->hists, &evsel->hists);
- hists__fprintf(&evsel->hists, &evsel_old->hists,
- show_displacement, true, 0, 0, stdout);
+ hists__fprintf(&evsel->hists, true, 0, 0, stdout);
}
out_delete:
@@ -257,6 +257,15 @@ static const struct option options[] = {
OPT_END()
};
+static void setup_ui_stdio(void)
+{
+ hists_stdio_column__register_idx(HISTC_BASELINE);
+ hists_stdio_column__register_global();
+ hists_stdio_column__register_idx(HISTC_DELTA);
+ if (show_displacement)
+ hists_stdio_column__register_idx(HISTC_DISPLACEMENT);
+}
+
int cmd_diff(int argc, const char **argv, const char *prefix __used)
{
sort_order = diff__default_sort_order;
@@ -280,6 +289,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __used)
return -1;
setup_sorting(diff_usage, options);
+ setup_ui_stdio();
setup_pager();
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", NULL);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index d618253..c855c9a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -33,6 +33,7 @@
#include "util/thread.h"
#include "util/sort.h"
#include "util/hist.h"
+#include "ui/stdio/hist.h"
#include <linux/bitmap.h>
@@ -315,12 +316,15 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
{
struct perf_evsel *pos;
+ hists_stdio_column__register_idx(HISTC_OVERHEAD);
+ hists_stdio_column__register_global();
+
list_for_each_entry(pos, &evlist->entries, node) {
struct hists *hists = &pos->hists;
const char *evname = perf_evsel__name(pos);
hists__fprintf_nr_sample_events(hists, evname, stdout);
- hists__fprintf(hists, NULL, false, true, 0, 0, stdout);
+ hists__fprintf(hists, true, 0, 0, stdout);
fprintf(stdout, "\n\n");
}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 0513aaa..26da442 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -41,6 +41,7 @@
#include "util/intlist.h"
#include "util/debug.h"
+#include "ui/stdio/hist.h"
#include <assert.h>
#include <elf.h>
@@ -315,7 +316,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
hists__output_recalc_col_len(&top->sym_evsel->hists,
top->winsize.ws_row - 3);
putchar('\n');
- hists__fprintf(&top->sym_evsel->hists, NULL, false, false,
+ hists__fprintf(&top->sym_evsel->hists, false,
top->winsize.ws_row - 4 - printed, win_width, stdout);
}
@@ -607,6 +608,9 @@ static void *display_thread(void *arg)
struct perf_top *top = arg;
int delay_msecs, c;
+ hists_stdio_column__register_idx(HISTC_OVERHEAD);
+ hists_stdio_column__register_global();
+
tcgetattr(0, &save);
tc = save;
tc.c_lflag &= ~(ICANON | ECHO);
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 4ae9ee5..48fb0b3 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -1,10 +1,180 @@
#include <stdio.h>
#include <math.h>
+#include "hist.h"
#include "../../util/util.h"
#include "../../util/hist.h"
#include "../../util/sort.h"
+static double get_period_percent(struct hist_entry *he, u64 period)
+{
+ u64 total = he->hists->stats.total_period;
+ return (period * 100.0) / total;
+}
+
+static int
+hists_stdio_column__delta_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ struct hist_entry *pair = he->pair;
+ double new_percent = get_period_percent(he, he->period);
+ double old_percent = pair ? get_period_percent(pair, pair->period) : 0.0;
+ double diff = new_percent - old_percent;
+ int ret;
+
+ if (fabs(diff) >= 0.01)
+ ret = percent_color_snprintf(bf, size, "%+7.2F%%", diff);
+ else
+ ret = scnprintf(bf, size, "%8s", " ");
+
+ return ret;
+}
+
+static int
+hists_stdio_column__baseline_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ struct hist_entry *pair = he->pair;
+ double percent = pair ? get_period_percent(pair, pair->period) : 0.0;
+
+ return percent_color_snprintf(bf, size, "%7.2F%%", percent);
+}
+
+static int
+hists_stdio_column__overhead_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ double percent = get_period_percent(he, he->period);
+ return percent_color_snprintf(bf, size, "%7.2f%%", percent);
+}
+
+static int
+hists_stdio_column__nr_samples_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ return scnprintf(bf, size, "%12" PRIu64, he->nr_events);
+}
+
+static int
+hists_stdio_column__total_period_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ return scnprintf(bf, size , "%12" PRIu64, he->period);
+}
+
+static int
+hists_stdio_column__cpu_sys_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ double percent = get_period_percent(he, he->period_sys);
+ return percent_color_snprintf(bf, size, "%7.2f%%", percent);
+}
+
+static int
+hists_stdio_column__cpu_us_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ double percent = get_period_percent(he, he->period_us);
+ return percent_color_snprintf(bf, size, "%7.2f%%", percent);
+}
+
+static int
+hists_stdio_column__cpu_guest_sys_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ double percent = get_period_percent(he, he->period_guest_sys);
+ return percent_color_snprintf(bf, size, "%8.2f%%", percent);
+}
+
+static int
+hists_stdio_column__cpu_guest_us_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ double percent = get_period_percent(he, he->period_guest_us);
+ return percent_color_snprintf(bf, size, "%7.2f%%", percent);
+}
+
+static int
+hists_stdio_column__displacement_snprintf(struct hist_entry *he, char *bf,
+ size_t size, unsigned int width __used)
+{
+ struct hist_entry *pair = he->pair;
+ unsigned long displ = pair ? pair->position - he->position : 0;
+ return scnprintf(bf, size, displ ? "%+5ld" : " ", displ);
+}
+
+LIST_HEAD(hists_stdio_column__list);
+
+#define DEF_COLUMN(name, c, w, h) \
+[ c ] = { \
+ .list = LIST_HEAD_INIT((hists_stdio_column__array[ c ]).list),\
+ .header = h, \
+ .snprintf = hists_stdio_column__ ## name ## _snprintf, \
+ .col_idx = c, \
+ .col_width = w, \
+},
+
+struct hists_stdio_column hists_stdio_column__array[HISTC_STDIO_NR_COLS] = {
+DEF_COLUMN(overhead, HISTC_OVERHEAD, 8, "Overhead")
+DEF_COLUMN(baseline, HISTC_BASELINE, 8, "Baseline")
+DEF_COLUMN(cpu_sys, HISTC_CPU_UTILIZATION_SYS, 8, "sys")
+DEF_COLUMN(cpu_us, HISTC_CPU_UTILIZATION_US, 8, "us")
+DEF_COLUMN(cpu_guest_sys, HISTC_CPU_UTILIZATION_GUEST_SYS, 8, "guest sys")
+DEF_COLUMN(cpu_guest_us, HISTC_CPU_UTILIZATION_GUEST_US, 8, "guest us")
+DEF_COLUMN(nr_samples, HISTC_NR_SAMPLES, 12, "Samples")
+DEF_COLUMN(total_period, HISTC_TOTAL_PERIOD, 12, "Period")
+DEF_COLUMN(delta, HISTC_DELTA, 8, "Delta")
+DEF_COLUMN(displacement, HISTC_DISPLACEMENT, 5, "Displ")
+};
+
+int hists_stdio_column__register_idx(int idx)
+{
+ struct hists_stdio_column *col;
+
+ if (idx >= HISTC_STDIO_NR_COLS)
+ return -EINVAL;
+
+ col = &hists_stdio_column__array[idx];
+
+ if (!list_empty(&col->list))
+ return -EBUSY;
+
+ list_add_tail(&col->list, &hists_stdio_column__list);
+ return 0;
+}
+
+void hists_stdio_column__set_width(struct hists *hists)
+{
+ struct hists_stdio_column *col;
+ unsigned i;
+
+ for (i = 0; i < HISTC_STDIO_NR_COLS; i++) {
+ col = &hists_stdio_column__array[i];
+ hists__set_col_len(hists, i, col->col_width);
+ }
+}
+
+void hists_stdio_column__register_global(void)
+{
+#define reg(idx) hists_stdio_column__register_idx(idx)
+
+ if (symbol_conf.show_cpu_utilization) {
+ reg(HISTC_CPU_UTILIZATION_SYS);
+ reg(HISTC_CPU_UTILIZATION_US);
+ }
+
+ if (perf_guest) {
+ reg(HISTC_CPU_UTILIZATION_GUEST_SYS);
+ reg(HISTC_CPU_UTILIZATION_GUEST_US);
+ }
+
+ if (symbol_conf.show_nr_samples)
+ reg(HISTC_NR_SAMPLES);
+
+ if (symbol_conf.show_total_period)
+ reg(HISTC_TOTAL_PERIOD);
+#undef reg
+}
static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
{
@@ -291,114 +461,20 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
return 0;
}
-static int hist_entry__period_snprintf(struct hist_entry *he, char *s,
- size_t size, struct hists *pair_hists,
- bool show_displacement, long displacement,
- bool color, u64 total_period)
+static int
+hists_stdio_column__snprintf(struct hist_entry *he, char *s, size_t size,
+ struct hists *hists)
{
- u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us;
- u64 nr_events;
const char *sep = symbol_conf.field_sep;
- int ret;
-
- if (symbol_conf.exclude_other && !he->parent)
- return 0;
-
- if (pair_hists) {
- period = he->pair ? he->pair->period : 0;
- nr_events = he->pair ? he->pair->nr_events : 0;
- total = pair_hists->stats.total_period;
- period_sys = he->pair ? he->pair->period_sys : 0;
- period_us = he->pair ? he->pair->period_us : 0;
- period_guest_sys = he->pair ? he->pair->period_guest_sys : 0;
- period_guest_us = he->pair ? he->pair->period_guest_us : 0;
- } else {
- period = he->period;
- nr_events = he->nr_events;
- total = total_period;
- period_sys = he->period_sys;
- period_us = he->period_us;
- period_guest_sys = he->period_guest_sys;
- period_guest_us = he->period_guest_us;
- }
-
- if (total) {
- if (color)
- ret = percent_color_snprintf(s, size,
- sep ? "%.2f" : " %6.2f%%",
- (period * 100.0) / total);
- else
- ret = scnprintf(s, size, sep ? "%.2f" : " %6.2f%%",
- (period * 100.0) / total);
- if (symbol_conf.show_cpu_utilization) {
- ret += percent_color_snprintf(s + ret, size - ret,
- sep ? "%.2f" : " %6.2f%%",
- (period_sys * 100.0) / total);
- ret += percent_color_snprintf(s + ret, size - ret,
- sep ? "%.2f" : " %6.2f%%",
- (period_us * 100.0) / total);
- if (perf_guest) {
- ret += percent_color_snprintf(s + ret,
- size - ret,
- sep ? "%.2f" : " %6.2f%%",
- (period_guest_sys * 100.0) /
- total);
- ret += percent_color_snprintf(s + ret,
- size - ret,
- sep ? "%.2f" : " %6.2f%%",
- (period_guest_us * 100.0) /
- total);
- }
- }
- } else
- ret = scnprintf(s, size, sep ? "%" PRIu64 : "%12" PRIu64 " ", period);
-
- if (symbol_conf.show_nr_samples) {
- if (sep)
- ret += scnprintf(s + ret, size - ret, "%c%" PRIu64, *sep, nr_events);
- else
- ret += scnprintf(s + ret, size - ret, "%11" PRIu64, nr_events);
- }
-
- if (symbol_conf.show_total_period) {
- if (sep)
- ret += scnprintf(s + ret, size - ret, "%c%" PRIu64, *sep, period);
- else
- ret += scnprintf(s + ret, size - ret, " %12" PRIu64, period);
- }
-
- if (pair_hists) {
- char bf[32];
- double old_percent = 0, new_percent = 0, diff;
-
- if (total > 0)
- old_percent = (period * 100.0) / total;
- if (total_period > 0)
- new_percent = (he->period * 100.0) / total_period;
-
- diff = new_percent - old_percent;
-
- if (fabs(diff) >= 0.01)
- scnprintf(bf, sizeof(bf), "%+4.2F%%", diff);
- else
- scnprintf(bf, sizeof(bf), " ");
-
- if (sep)
- ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf);
- else
- ret += scnprintf(s + ret, size - ret, "%11.11s", bf);
+ struct hists_stdio_column *col;
+ int ret = 0;
- if (show_displacement) {
- if (displacement)
- scnprintf(bf, sizeof(bf), "%+4ld", displacement);
- else
- scnprintf(bf, sizeof(bf), " ");
+ ret = snprintf(s, size, " ");
- if (sep)
- ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf);
- else
- ret += scnprintf(s + ret, size - ret, "%6.6s", bf);
- }
+ list_for_each_entry(col, &hists_stdio_column__list, list) {
+ ret += scnprintf(s + ret, size - ret, "%s", sep ?: " ");
+ ret += col->snprintf(he, s + ret, size - ret,
+ hists__col_len(hists, col->col_idx));
}
return ret;
@@ -440,9 +516,8 @@ static size_t hist_entry__callchain_fprintf(struct hist_entry *he,
}
static int hist_entry__fprintf(struct hist_entry *he, size_t size,
- struct hists *hists, struct hists *pair_hists,
- bool show_displacement, long displacement,
- u64 total_period, FILE *fp)
+ struct hists *hists, u64 total_period,
+ FILE *fp)
{
char bf[512];
int ret;
@@ -450,9 +525,8 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
if (size == 0 || size > sizeof(bf))
size = sizeof(bf);
- ret = hist_entry__period_snprintf(he, bf, size, pair_hists,
- show_displacement, displacement,
- true, total_period);
+ ret = hists_stdio_column__snprintf(he, bf, size, hists);
+
hist_entry__sort_snprintf(he, bf + ret, size - ret, hists);
ret = fprintf(fp, "%s\n", bf);
@@ -464,138 +538,117 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
return ret;
}
-size_t hists__fprintf(struct hists *hists, struct hists *pair,
- bool show_displacement, bool show_header, int max_rows,
- int max_cols, FILE *fp)
+static void fprintf_header(FILE *fp, struct hists *hists,
+ const char *header, int col)
{
- struct sort_entry *se;
- struct rb_node *nd;
- size_t ret = 0;
- u64 total_period;
- long displacement = 0;
- unsigned int width;
- const char *sep = symbol_conf.field_sep;
const char *col_width = symbol_conf.col_width_list_str;
- int nr_rows = 0;
-
- init_rem_hits();
-
- if (!show_header)
- goto print_entries;
+ const char *sep = symbol_conf.field_sep;
+ unsigned int width;
- fprintf(fp, "# %s", pair ? "Baseline" : "Overhead");
+ if (sep) {
+ fprintf(fp, "%c%s", *sep, header);
+ return;
+ }
- if (symbol_conf.show_cpu_utilization) {
- if (sep) {
- ret += fprintf(fp, "%csys", *sep);
- ret += fprintf(fp, "%cus", *sep);
- if (perf_guest) {
- ret += fprintf(fp, "%cguest sys", *sep);
- ret += fprintf(fp, "%cguest us", *sep);
- }
- } else {
- ret += fprintf(fp, " sys ");
- ret += fprintf(fp, " us ");
- if (perf_guest) {
- ret += fprintf(fp, " guest sys ");
- ret += fprintf(fp, " guest us ");
- }
+ width = strlen(header);
+ if (symbol_conf.col_width_list_str) {
+ if (col_width) {
+ hists__set_col_len(hists, col,
+ atoi(col_width));
+ col_width = strchr(col_width, ',');
+ if (col_width)
+ ++col_width;
}
}
- if (symbol_conf.show_nr_samples) {
- if (sep)
- fprintf(fp, "%cSamples", *sep);
- else
- fputs(" Samples ", fp);
- }
+ if (!hists__new_col_len(hists, col, width))
+ width = hists__col_len(hists, col);
- if (symbol_conf.show_total_period) {
- if (sep)
- ret += fprintf(fp, "%cPeriod", *sep);
- else
- ret += fprintf(fp, " Period ");
- }
+ fprintf(fp, " %*s", width, header);
+}
- if (pair) {
- if (sep)
- ret += fprintf(fp, "%cDelta", *sep);
- else
- ret += fprintf(fp, " Delta ");
+static void fprintf_dots(FILE *fp, struct hists *hists,
+ const char *header, int col)
+{
+ unsigned int width;
+ unsigned int i;
- if (show_displacement) {
- if (sep)
- ret += fprintf(fp, "%cDisplacement", *sep);
- else
- ret += fprintf(fp, " Displ");
- }
- }
+ fprintf(fp, " ");
+ width = hists__col_len(hists, col);
+
+ if (width == 0)
+ width = strlen(header);
+
+ for (i = 0; i < width; i++)
+ fprintf(fp, ".");
+}
+
+static int hists__fprintf_header(struct hists *hists, FILE *fp,
+ int max_rows, int max_cols __used)
+{
+ struct sort_entry *se;
+ struct hists_stdio_column *col;
+ int nr_rows = 0;
+
+ /*
+ * TODO Both fprintf_header and fprintf_dots should take
+ * max_cols and output data appropriatelly. Seems there was
+ * no need so far ;)
+ */
+
+ /* First line - headers */
+ fprintf(fp, "# ");
+
+ list_for_each_entry(col, &hists_stdio_column__list, list)
+ fprintf_header(fp, hists, col->header, col->col_idx);
list_for_each_entry(se, &hist_entry__sort_list, list) {
if (se->elide)
continue;
- if (sep) {
- fprintf(fp, "%c%s", *sep, se->se_header);
- continue;
- }
- width = strlen(se->se_header);
- if (symbol_conf.col_width_list_str) {
- if (col_width) {
- hists__set_col_len(hists, se->se_width_idx,
- atoi(col_width));
- col_width = strchr(col_width, ',');
- if (col_width)
- ++col_width;
- }
- }
- if (!hists__new_col_len(hists, se->se_width_idx, width))
- width = hists__col_len(hists, se->se_width_idx);
- fprintf(fp, " %*s", width, se->se_header);
+
+ fprintf_header(fp, hists, se->se_header, se->se_width_idx);
}
fprintf(fp, "\n");
+
if (max_rows && ++nr_rows >= max_rows)
- goto out;
+ return nr_rows;
- if (sep)
- goto print_entries;
+ if (symbol_conf.field_sep)
+ return nr_rows;
- fprintf(fp, "# ........");
- if (symbol_conf.show_cpu_utilization)
- fprintf(fp, " ....... .......");
- if (symbol_conf.show_nr_samples)
- fprintf(fp, " ..........");
- if (symbol_conf.show_total_period)
- fprintf(fp, " ............");
- if (pair) {
- fprintf(fp, " ..........");
- if (show_displacement)
- fprintf(fp, " .....");
- }
- list_for_each_entry(se, &hist_entry__sort_list, list) {
- unsigned int i;
+ /* Second line - dots */
+ fprintf(fp, "# ");
+
+ list_for_each_entry(col, &hists_stdio_column__list, list)
+ fprintf_dots(fp, hists, col->header, col->col_idx);
+ list_for_each_entry(se, &hist_entry__sort_list, list) {
if (se->elide)
continue;
- fprintf(fp, " ");
- width = hists__col_len(hists, se->se_width_idx);
- if (width == 0)
- width = strlen(se->se_header);
- for (i = 0; i < width; i++)
- fprintf(fp, ".");
+ fprintf_dots(fp, hists, se->se_header, se->se_width_idx);
}
fprintf(fp, "\n");
if (max_rows && ++nr_rows >= max_rows)
- goto out;
+ return nr_rows;
fprintf(fp, "#\n");
- if (max_rows && ++nr_rows >= max_rows)
- goto out;
+ if (max_rows)
+ ++nr_rows;
-print_entries:
- total_period = hists->stats.total_period;
+ return nr_rows;
+}
+
+static size_t
+hists__fprint_data(struct hists *hists, FILE *fp, int nr_rows,
+ int max_rows, int max_cols)
+{
+ struct rb_node *nd;
+ size_t ret = 0;
+
+ init_rem_hits();
for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
@@ -603,18 +656,12 @@ print_entries:
if (h->filtered)
continue;
- if (show_displacement) {
- if (h->pair != NULL)
- displacement = ((long)h->pair->position -
- (long)h->position);
- else
- displacement = 0;
- }
- ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement,
- displacement, total_period, fp);
+ ret += hist_entry__fprintf(h, max_cols, hists,
+ hists->stats.total_period,
+ fp);
if (max_rows && ++nr_rows >= max_rows)
- goto out;
+ break;
if (h->ms.map == NULL && verbose > 1) {
__map_groups__fprintf_maps(&h->thread->mg,
@@ -622,12 +669,25 @@ print_entries:
fprintf(fp, "%.10s end\n", graph_dotted_line);
}
}
-out:
- free(rem_sq_bracket);
+ free(rem_sq_bracket);
return ret;
}
+size_t hists__fprintf(struct hists *hists, bool show_header,
+ int max_rows, int max_cols, FILE *fp)
+{
+ int nr_rows = 0;
+
+ if (show_header)
+ nr_rows = hists__fprintf_header(hists, fp, max_rows, max_cols);
+
+ if (max_rows && nr_rows >= max_rows)
+ return 0;
+
+ return hists__fprint_data(hists, fp, nr_rows, max_rows, max_cols);
+}
+
size_t hists__fprintf_nr_events(struct hists *hists, FILE *fp)
{
int i;
diff --git a/tools/perf/ui/stdio/hist.h b/tools/perf/ui/stdio/hist.h
new file mode 100644
index 0000000..8e15d88
--- /dev/null
+++ b/tools/perf/ui/stdio/hist.h
@@ -0,0 +1,19 @@
+#ifndef __PERF_UI_STDIO_HIST_H
+#define __PERF_UI_STDIO_HIST_H
+
+#include <linux/list.h>
+#include "../../util/hist.h"
+
+struct hists_stdio_column {
+ struct list_head list;
+ const char *header;
+ int col_idx;
+ int col_width;
+ int (*snprintf)(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width);
+};
+
+int hists_stdio_column__register_idx(int idx);
+void hists_stdio_column__register_global(void);
+void hists_stdio_column__set_width(struct hists *hists);
+#endif /* __PERF_UI_STDIO_HIST_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 0ed0683..5fb5cd8 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -5,6 +5,7 @@
#include "session.h"
#include "sort.h"
#include <math.h>
+#include "../ui/stdio/hist.h"
static bool hists__filter_entry_by_dso(struct hists *hists,
struct hist_entry *he);
@@ -49,7 +50,9 @@ void hists__reset_col_len(struct hists *hists)
{
enum hist_column col;
- for (col = 0; col < HISTC_NR_COLS; ++col)
+ hists_stdio_column__set_width(hists);
+
+ for (col = HISTC_SYMBOL; col < HISTC_NR_COLS; ++col)
hists__set_col_len(hists, col, 0);
}
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 2e650ff..36ff4c5 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -36,6 +36,19 @@ struct events_stats {
};
enum hist_column {
+ /* stdio (hists_stdio_column__list) */
+ HISTC_OVERHEAD,
+ HISTC_BASELINE,
+ HISTC_CPU_UTILIZATION_SYS,
+ HISTC_CPU_UTILIZATION_US,
+ HISTC_CPU_UTILIZATION_GUEST_SYS,
+ HISTC_CPU_UTILIZATION_GUEST_US,
+ HISTC_NR_SAMPLES,
+ HISTC_TOTAL_PERIOD,
+ HISTC_DELTA,
+ HISTC_DISPLACEMENT,
+
+ /* sorted (hist_entry__sort_list) */
HISTC_SYMBOL,
HISTC_DSO,
HISTC_THREAD,
@@ -49,6 +62,9 @@ enum hist_column {
HISTC_DSO_TO,
HISTC_SRCLINE,
HISTC_NR_COLS, /* Last entry */
+
+ /* Last stdio ui data column */
+ HISTC_STDIO_NR_COLS = HISTC_DISPLACEMENT + 1,
};
struct thread;
@@ -98,8 +114,7 @@ void hists__output_recalc_col_len(struct hists *hists, int max_rows);
void hists__inc_nr_events(struct hists *self, u32 type);
size_t hists__fprintf_nr_events(struct hists *self, FILE *fp);
-size_t hists__fprintf(struct hists *self, struct hists *pair,
- bool show_displacement, bool show_header,
+size_t hists__fprintf(struct hists *self, bool show_header,
int max_rows, int max_cols, FILE *fp);
int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
--
1.7.11.4
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/