[PATCH 1/7] perf hists: Separate out hist print functions

2012-08-19 Thread Namhyung Kim
From: Namhyung Kim 

Separate out those functions into ui/stdio/hist.c. This is required
for upcoming changes.

Signed-off-by: Namhyung Kim 
---
 tools/perf/Makefile|   3 +-
 tools/perf/ui/stdio/hist.c | 648 +++
 tools/perf/util/hist.c | 677 ++---
 tools/perf/util/hist.h |   2 +
 4 files changed, 669 insertions(+), 661 deletions(-)
 create mode 100644 tools/perf/ui/stdio/hist.c

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 75af93dc52ad..cb18b047c9c9 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -404,11 +404,10 @@ LIB_OBJS += $(OUTPUT)util/target.o
 LIB_OBJS += $(OUTPUT)util/rblist.o
 LIB_OBJS += $(OUTPUT)util/intlist.o
 LIB_OBJS += $(OUTPUT)ui/helpline.o
+LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
 
 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
-
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
-
 # Benchmark modules
 BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
 BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
new file mode 100644
index ..7881d625e17a
--- /dev/null
+++ b/tools/perf/ui/stdio/hist.c
@@ -0,0 +1,648 @@
+#include 
+#include 
+
+#include "../../util/util.h"
+#include "../../util/hist.h"
+#include "../../util/sort.h"
+
+
+static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
+{
+   int i;
+   int ret = fprintf(fp, "");
+
+   for (i = 0; i < left_margin; i++)
+   ret += fprintf(fp, " ");
+
+   return ret;
+}
+
+static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
+ int left_margin)
+{
+   int i;
+   size_t ret = callchain__fprintf_left_margin(fp, left_margin);
+
+   for (i = 0; i < depth; i++)
+   if (depth_mask & (1 << i))
+   ret += fprintf(fp, "|  ");
+   else
+   ret += fprintf(fp, "   ");
+
+   ret += fprintf(fp, "\n");
+
+   return ret;
+}
+
+static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
+int depth, int depth_mask, int period,
+u64 total_samples, u64 hits,
+int left_margin)
+{
+   int i;
+   size_t ret = 0;
+
+   ret += callchain__fprintf_left_margin(fp, left_margin);
+   for (i = 0; i < depth; i++) {
+   if (depth_mask & (1 << i))
+   ret += fprintf(fp, "|");
+   else
+   ret += fprintf(fp, " ");
+   if (!period && i == depth - 1) {
+   double percent;
+
+   percent = hits * 100.0 / total_samples;
+   ret += percent_color_fprintf(fp, "--%2.2f%%-- ", 
percent);
+   } else
+   ret += fprintf(fp, "%s", "  ");
+   }
+   if (chain->ms.sym)
+   ret += fprintf(fp, "%s\n", chain->ms.sym->name);
+   else
+   ret += fprintf(fp, "0x%0" PRIx64 "\n", chain->ip);
+
+   return ret;
+}
+
+static struct symbol *rem_sq_bracket;
+static struct callchain_list rem_hits;
+
+static void init_rem_hits(void)
+{
+   rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
+   if (!rem_sq_bracket) {
+   fprintf(stderr, "Not enough memory to display remaining 
hits\n");
+   return;
+   }
+
+   strcpy(rem_sq_bracket->name, "[...]");
+   rem_hits.ms.sym = rem_sq_bracket;
+}
+
+static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
+u64 total_samples, int depth,
+int depth_mask, int left_margin)
+{
+   struct rb_node *node, *next;
+   struct callchain_node *child;
+   struct callchain_list *chain;
+   int new_depth_mask = depth_mask;
+   u64 remaining;
+   size_t ret = 0;
+   int i;
+   uint entries_printed = 0;
+
+   remaining = total_samples;
+
+   node = rb_first(root);
+   while (node) {
+   u64 new_total;
+   u64 cumul;
+
+   child = rb_entry(node, struct callchain_node, rb_node);
+   cumul = callchain_cumul_hits(child);
+   remaining -= cumul;
+
+   /*
+* The depth mask manages the output of pipes that show
+* the depth. We don't want to keep the pipes of the current
+* level for the last child of this depth.
+* Except if we have remaining filtered hits. They will
+* supersede the last child
+*/
+   next = rb_next(node);
+   if (!next && (callchain_param.mode != CHAIN_GRAPH_REL || 
!remaining))
+   new_depth_mask &= ~(1 << (depth - 1));
+
+ 

[PATCH 1/7] perf hists: Separate out hist print functions

2012-08-19 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Separate out those functions into ui/stdio/hist.c. This is required
for upcoming changes.

Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/Makefile|   3 +-
 tools/perf/ui/stdio/hist.c | 648 +++
 tools/perf/util/hist.c | 677 ++---
 tools/perf/util/hist.h |   2 +
 4 files changed, 669 insertions(+), 661 deletions(-)
 create mode 100644 tools/perf/ui/stdio/hist.c

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 75af93dc52ad..cb18b047c9c9 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -404,11 +404,10 @@ LIB_OBJS += $(OUTPUT)util/target.o
 LIB_OBJS += $(OUTPUT)util/rblist.o
 LIB_OBJS += $(OUTPUT)util/intlist.o
 LIB_OBJS += $(OUTPUT)ui/helpline.o
+LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
 
 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
-
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
-
 # Benchmark modules
 BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
 BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
new file mode 100644
index ..7881d625e17a
--- /dev/null
+++ b/tools/perf/ui/stdio/hist.c
@@ -0,0 +1,648 @@
+#include stdio.h
+#include math.h
+
+#include ../../util/util.h
+#include ../../util/hist.h
+#include ../../util/sort.h
+
+
+static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
+{
+   int i;
+   int ret = fprintf(fp, );
+
+   for (i = 0; i  left_margin; i++)
+   ret += fprintf(fp,  );
+
+   return ret;
+}
+
+static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
+ int left_margin)
+{
+   int i;
+   size_t ret = callchain__fprintf_left_margin(fp, left_margin);
+
+   for (i = 0; i  depth; i++)
+   if (depth_mask  (1  i))
+   ret += fprintf(fp, |  );
+   else
+   ret += fprintf(fp,);
+
+   ret += fprintf(fp, \n);
+
+   return ret;
+}
+
+static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
+int depth, int depth_mask, int period,
+u64 total_samples, u64 hits,
+int left_margin)
+{
+   int i;
+   size_t ret = 0;
+
+   ret += callchain__fprintf_left_margin(fp, left_margin);
+   for (i = 0; i  depth; i++) {
+   if (depth_mask  (1  i))
+   ret += fprintf(fp, |);
+   else
+   ret += fprintf(fp,  );
+   if (!period  i == depth - 1) {
+   double percent;
+
+   percent = hits * 100.0 / total_samples;
+   ret += percent_color_fprintf(fp, --%2.2f%%-- , 
percent);
+   } else
+   ret += fprintf(fp, %s,   );
+   }
+   if (chain-ms.sym)
+   ret += fprintf(fp, %s\n, chain-ms.sym-name);
+   else
+   ret += fprintf(fp, 0x%0 PRIx64 \n, chain-ip);
+
+   return ret;
+}
+
+static struct symbol *rem_sq_bracket;
+static struct callchain_list rem_hits;
+
+static void init_rem_hits(void)
+{
+   rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
+   if (!rem_sq_bracket) {
+   fprintf(stderr, Not enough memory to display remaining 
hits\n);
+   return;
+   }
+
+   strcpy(rem_sq_bracket-name, [...]);
+   rem_hits.ms.sym = rem_sq_bracket;
+}
+
+static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
+u64 total_samples, int depth,
+int depth_mask, int left_margin)
+{
+   struct rb_node *node, *next;
+   struct callchain_node *child;
+   struct callchain_list *chain;
+   int new_depth_mask = depth_mask;
+   u64 remaining;
+   size_t ret = 0;
+   int i;
+   uint entries_printed = 0;
+
+   remaining = total_samples;
+
+   node = rb_first(root);
+   while (node) {
+   u64 new_total;
+   u64 cumul;
+
+   child = rb_entry(node, struct callchain_node, rb_node);
+   cumul = callchain_cumul_hits(child);
+   remaining -= cumul;
+
+   /*
+* The depth mask manages the output of pipes that show
+* the depth. We don't want to keep the pipes of the current
+* level for the last child of this depth.
+* Except if we have remaining filtered hits. They will
+* supersede the last child
+*/
+   next = rb_next(node);
+   if (!next  (callchain_param.mode != CHAIN_GRAPH_REL || 
!remaining))
+   new_depth_mask = ~(1  (depth - 1));
+
+   /*

Re: [PATCH 1/7] perf hists: Separate out hist print functions

2012-08-09 Thread Namhyung Kim
Hi, Arnaldo

On Thu, 9 Aug 2012 16:18:27 -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Aug 06, 2012 at 05:57:36PM +0900, Namhyung Kim escreveu:
>> From: Namhyung Kim 
>> 
>> Separate out those functions into ui/hist.c. This is required for
>> upcoming changes.
>
> Isn't it better to further separate it by introducing the ui/stdio/
> directory since these functions use fprintf?
>
Maybe. I agree that general ui code reside on ui/ and front-end
specifics should go to their subdirectories. But not sure for the stdio
case since they'll have very simple code only.

For this case, most of functions would be converted to manipulate a
string buffer like scnprintf and shared by all front-end's as long as
possible - callchain print code needs some more working. But if you
want, I'll separate out actual fprintf's to ui/stdio/.

Thanks,
Namhyung

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/7] perf hists: Separate out hist print functions

2012-08-09 Thread Arnaldo Carvalho de Melo
Em Mon, Aug 06, 2012 at 05:57:36PM +0900, Namhyung Kim escreveu:
> From: Namhyung Kim 
> 
> Separate out those functions into ui/hist.c. This is required for
> upcoming changes.

Isn't it better to further separate it by introducing the ui/stdio/
directory since these functions use fprintf?

- Arnaldo
 
> Signed-off-by: Namhyung Kim 
> ---
>  tools/perf/Makefile|   4 +-
>  tools/perf/ui/hist.c   | 648 ++
>  tools/perf/util/hist.c | 677 
> ++---
>  tools/perf/util/hist.h |   2 +
>  4 files changed, 670 insertions(+), 661 deletions(-)
>  create mode 100644 tools/perf/ui/hist.c
> 
> diff --git a/tools/perf/Makefile b/tools/perf/Makefile
> index 35655c3a7b7a..49cff288ac24 100644
> --- a/tools/perf/Makefile
> +++ b/tools/perf/Makefile
> @@ -388,10 +388,10 @@ LIB_OBJS += $(OUTPUT)util/target.o
>  LIB_OBJS += $(OUTPUT)util/rblist.o
>  LIB_OBJS += $(OUTPUT)util/intlist.o
>  
> -BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
> +LIB_OBJS += $(OUTPUT)ui/hist.o
>  
> +BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
>  BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
> -
>  # Benchmark modules
>  BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
>  BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
> diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
> new file mode 100644
> index ..b7936dc6271f
> --- /dev/null
> +++ b/tools/perf/ui/hist.c
> @@ -0,0 +1,648 @@
> +#include 
> +#include 
> +
> +#include "../util/util.h"
> +#include "../util/hist.h"
> +#include "../util/sort.h"
> +
> +
> +static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
> +{
> + int i;
> + int ret = fprintf(fp, "");
> +
> + for (i = 0; i < left_margin; i++)
> + ret += fprintf(fp, " ");
> +
> + return ret;
> +}
> +
> +static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int 
> depth_mask,
> +   int left_margin)
> +{
> + int i;
> + size_t ret = callchain__fprintf_left_margin(fp, left_margin);
> +
> + for (i = 0; i < depth; i++)
> + if (depth_mask & (1 << i))
> + ret += fprintf(fp, "|  ");
> + else
> + ret += fprintf(fp, "   ");
> +
> + ret += fprintf(fp, "\n");
> +
> + return ret;
> +}
> +
> +static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
> +  int depth, int depth_mask, int period,
> +  u64 total_samples, u64 hits,
> +  int left_margin)
> +{
> + int i;
> + size_t ret = 0;
> +
> + ret += callchain__fprintf_left_margin(fp, left_margin);
> + for (i = 0; i < depth; i++) {
> + if (depth_mask & (1 << i))
> + ret += fprintf(fp, "|");
> + else
> + ret += fprintf(fp, " ");
> + if (!period && i == depth - 1) {
> + double percent;
> +
> + percent = hits * 100.0 / total_samples;
> + ret += percent_color_fprintf(fp, "--%2.2f%%-- ", 
> percent);
> + } else
> + ret += fprintf(fp, "%s", "  ");
> + }
> + if (chain->ms.sym)
> + ret += fprintf(fp, "%s\n", chain->ms.sym->name);
> + else
> + ret += fprintf(fp, "0x%0" PRIx64 "\n", chain->ip);
> +
> + return ret;
> +}
> +
> +static struct symbol *rem_sq_bracket;
> +static struct callchain_list rem_hits;
> +
> +static void init_rem_hits(void)
> +{
> + rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
> + if (!rem_sq_bracket) {
> + fprintf(stderr, "Not enough memory to display remaining 
> hits\n");
> + return;
> + }
> +
> + strcpy(rem_sq_bracket->name, "[...]");
> + rem_hits.ms.sym = rem_sq_bracket;
> +}
> +
> +static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
> +  u64 total_samples, int depth,
> +  int depth_mask, int left_margin)
> +{
> + struct rb_node *node, *next;
> + struct callchain_node *child;
> + struct callchain_list *chain;
> + int new_depth_mask = depth_mask;
> + u64 remaining;
> + size_t ret = 0;
> + int i;
> + uint entries_printed = 0;
> +
> + remaining = total_samples;
> +
> + node = rb_first(root);
> + while (node) {
> + u64 new_total;
> + u64 cumul;
> +
> + child = rb_entry(node, struct callchain_node, rb_node);
> + cumul = callchain_cumul_hits(child);
> + remaining -= cumul;
> +
> + /*
> +  * The depth mask manages the output of pipes that show
> +  * the depth. We don't want to keep the pipes of the current
> +  * level for the last child of this depth.
> +  * Except 

Re: [PATCH 1/7] perf hists: Separate out hist print functions

2012-08-09 Thread Arnaldo Carvalho de Melo
Em Mon, Aug 06, 2012 at 05:57:36PM +0900, Namhyung Kim escreveu:
 From: Namhyung Kim namhyung@lge.com
 
 Separate out those functions into ui/hist.c. This is required for
 upcoming changes.

Isn't it better to further separate it by introducing the ui/stdio/
directory since these functions use fprintf?

- Arnaldo
 
 Signed-off-by: Namhyung Kim namhy...@kernel.org
 ---
  tools/perf/Makefile|   4 +-
  tools/perf/ui/hist.c   | 648 ++
  tools/perf/util/hist.c | 677 
 ++---
  tools/perf/util/hist.h |   2 +
  4 files changed, 670 insertions(+), 661 deletions(-)
  create mode 100644 tools/perf/ui/hist.c
 
 diff --git a/tools/perf/Makefile b/tools/perf/Makefile
 index 35655c3a7b7a..49cff288ac24 100644
 --- a/tools/perf/Makefile
 +++ b/tools/perf/Makefile
 @@ -388,10 +388,10 @@ LIB_OBJS += $(OUTPUT)util/target.o
  LIB_OBJS += $(OUTPUT)util/rblist.o
  LIB_OBJS += $(OUTPUT)util/intlist.o
  
 -BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 +LIB_OBJS += $(OUTPUT)ui/hist.o
  
 +BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
  BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
 -
  # Benchmark modules
  BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
  BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
 diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
 new file mode 100644
 index ..b7936dc6271f
 --- /dev/null
 +++ b/tools/perf/ui/hist.c
 @@ -0,0 +1,648 @@
 +#include stdio.h
 +#include math.h
 +
 +#include ../util/util.h
 +#include ../util/hist.h
 +#include ../util/sort.h
 +
 +
 +static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
 +{
 + int i;
 + int ret = fprintf(fp, );
 +
 + for (i = 0; i  left_margin; i++)
 + ret += fprintf(fp,  );
 +
 + return ret;
 +}
 +
 +static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int 
 depth_mask,
 +   int left_margin)
 +{
 + int i;
 + size_t ret = callchain__fprintf_left_margin(fp, left_margin);
 +
 + for (i = 0; i  depth; i++)
 + if (depth_mask  (1  i))
 + ret += fprintf(fp, |  );
 + else
 + ret += fprintf(fp,);
 +
 + ret += fprintf(fp, \n);
 +
 + return ret;
 +}
 +
 +static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
 +  int depth, int depth_mask, int period,
 +  u64 total_samples, u64 hits,
 +  int left_margin)
 +{
 + int i;
 + size_t ret = 0;
 +
 + ret += callchain__fprintf_left_margin(fp, left_margin);
 + for (i = 0; i  depth; i++) {
 + if (depth_mask  (1  i))
 + ret += fprintf(fp, |);
 + else
 + ret += fprintf(fp,  );
 + if (!period  i == depth - 1) {
 + double percent;
 +
 + percent = hits * 100.0 / total_samples;
 + ret += percent_color_fprintf(fp, --%2.2f%%-- , 
 percent);
 + } else
 + ret += fprintf(fp, %s,   );
 + }
 + if (chain-ms.sym)
 + ret += fprintf(fp, %s\n, chain-ms.sym-name);
 + else
 + ret += fprintf(fp, 0x%0 PRIx64 \n, chain-ip);
 +
 + return ret;
 +}
 +
 +static struct symbol *rem_sq_bracket;
 +static struct callchain_list rem_hits;
 +
 +static void init_rem_hits(void)
 +{
 + rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
 + if (!rem_sq_bracket) {
 + fprintf(stderr, Not enough memory to display remaining 
 hits\n);
 + return;
 + }
 +
 + strcpy(rem_sq_bracket-name, [...]);
 + rem_hits.ms.sym = rem_sq_bracket;
 +}
 +
 +static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
 +  u64 total_samples, int depth,
 +  int depth_mask, int left_margin)
 +{
 + struct rb_node *node, *next;
 + struct callchain_node *child;
 + struct callchain_list *chain;
 + int new_depth_mask = depth_mask;
 + u64 remaining;
 + size_t ret = 0;
 + int i;
 + uint entries_printed = 0;
 +
 + remaining = total_samples;
 +
 + node = rb_first(root);
 + while (node) {
 + u64 new_total;
 + u64 cumul;
 +
 + child = rb_entry(node, struct callchain_node, rb_node);
 + cumul = callchain_cumul_hits(child);
 + remaining -= cumul;
 +
 + /*
 +  * The depth mask manages the output of pipes that show
 +  * the depth. We don't want to keep the pipes of the current
 +  * level for the last child of this depth.
 +  * Except if we have remaining filtered hits. They will
 +  * supersede the last child
 +  */
 + next = rb_next(node);
 + 

Re: [PATCH 1/7] perf hists: Separate out hist print functions

2012-08-09 Thread Namhyung Kim
Hi, Arnaldo

On Thu, 9 Aug 2012 16:18:27 -0300, Arnaldo Carvalho de Melo wrote:
 Em Mon, Aug 06, 2012 at 05:57:36PM +0900, Namhyung Kim escreveu:
 From: Namhyung Kim namhyung@lge.com
 
 Separate out those functions into ui/hist.c. This is required for
 upcoming changes.

 Isn't it better to further separate it by introducing the ui/stdio/
 directory since these functions use fprintf?

Maybe. I agree that general ui code reside on ui/ and front-end
specifics should go to their subdirectories. But not sure for the stdio
case since they'll have very simple code only.

For this case, most of functions would be converted to manipulate a
string buffer like scnprintf and shared by all front-end's as long as
possible - callchain print code needs some more working. But if you
want, I'll separate out actual fprintf's to ui/stdio/.

Thanks,
Namhyung

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/7] perf hists: Separate out hist print functions

2012-08-06 Thread Namhyung Kim
From: Namhyung Kim 

Separate out those functions into ui/hist.c. This is required for
upcoming changes.

Signed-off-by: Namhyung Kim 
---
 tools/perf/Makefile|   4 +-
 tools/perf/ui/hist.c   | 648 ++
 tools/perf/util/hist.c | 677 ++---
 tools/perf/util/hist.h |   2 +
 4 files changed, 670 insertions(+), 661 deletions(-)
 create mode 100644 tools/perf/ui/hist.c

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 35655c3a7b7a..49cff288ac24 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -388,10 +388,10 @@ LIB_OBJS += $(OUTPUT)util/target.o
 LIB_OBJS += $(OUTPUT)util/rblist.o
 LIB_OBJS += $(OUTPUT)util/intlist.o
 
-BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
+LIB_OBJS += $(OUTPUT)ui/hist.o
 
+BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
-
 # Benchmark modules
 BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
 BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
new file mode 100644
index ..b7936dc6271f
--- /dev/null
+++ b/tools/perf/ui/hist.c
@@ -0,0 +1,648 @@
+#include 
+#include 
+
+#include "../util/util.h"
+#include "../util/hist.h"
+#include "../util/sort.h"
+
+
+static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
+{
+   int i;
+   int ret = fprintf(fp, "");
+
+   for (i = 0; i < left_margin; i++)
+   ret += fprintf(fp, " ");
+
+   return ret;
+}
+
+static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
+ int left_margin)
+{
+   int i;
+   size_t ret = callchain__fprintf_left_margin(fp, left_margin);
+
+   for (i = 0; i < depth; i++)
+   if (depth_mask & (1 << i))
+   ret += fprintf(fp, "|  ");
+   else
+   ret += fprintf(fp, "   ");
+
+   ret += fprintf(fp, "\n");
+
+   return ret;
+}
+
+static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
+int depth, int depth_mask, int period,
+u64 total_samples, u64 hits,
+int left_margin)
+{
+   int i;
+   size_t ret = 0;
+
+   ret += callchain__fprintf_left_margin(fp, left_margin);
+   for (i = 0; i < depth; i++) {
+   if (depth_mask & (1 << i))
+   ret += fprintf(fp, "|");
+   else
+   ret += fprintf(fp, " ");
+   if (!period && i == depth - 1) {
+   double percent;
+
+   percent = hits * 100.0 / total_samples;
+   ret += percent_color_fprintf(fp, "--%2.2f%%-- ", 
percent);
+   } else
+   ret += fprintf(fp, "%s", "  ");
+   }
+   if (chain->ms.sym)
+   ret += fprintf(fp, "%s\n", chain->ms.sym->name);
+   else
+   ret += fprintf(fp, "0x%0" PRIx64 "\n", chain->ip);
+
+   return ret;
+}
+
+static struct symbol *rem_sq_bracket;
+static struct callchain_list rem_hits;
+
+static void init_rem_hits(void)
+{
+   rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
+   if (!rem_sq_bracket) {
+   fprintf(stderr, "Not enough memory to display remaining 
hits\n");
+   return;
+   }
+
+   strcpy(rem_sq_bracket->name, "[...]");
+   rem_hits.ms.sym = rem_sq_bracket;
+}
+
+static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
+u64 total_samples, int depth,
+int depth_mask, int left_margin)
+{
+   struct rb_node *node, *next;
+   struct callchain_node *child;
+   struct callchain_list *chain;
+   int new_depth_mask = depth_mask;
+   u64 remaining;
+   size_t ret = 0;
+   int i;
+   uint entries_printed = 0;
+
+   remaining = total_samples;
+
+   node = rb_first(root);
+   while (node) {
+   u64 new_total;
+   u64 cumul;
+
+   child = rb_entry(node, struct callchain_node, rb_node);
+   cumul = callchain_cumul_hits(child);
+   remaining -= cumul;
+
+   /*
+* The depth mask manages the output of pipes that show
+* the depth. We don't want to keep the pipes of the current
+* level for the last child of this depth.
+* Except if we have remaining filtered hits. They will
+* supersede the last child
+*/
+   next = rb_next(node);
+   if (!next && (callchain_param.mode != CHAIN_GRAPH_REL || 
!remaining))
+   new_depth_mask &= ~(1 << (depth - 1));
+
+   /*
+* But we keep the 

[PATCH 1/7] perf hists: Separate out hist print functions

2012-08-06 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Separate out those functions into ui/hist.c. This is required for
upcoming changes.

Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/Makefile|   4 +-
 tools/perf/ui/hist.c   | 648 ++
 tools/perf/util/hist.c | 677 ++---
 tools/perf/util/hist.h |   2 +
 4 files changed, 670 insertions(+), 661 deletions(-)
 create mode 100644 tools/perf/ui/hist.c

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 35655c3a7b7a..49cff288ac24 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -388,10 +388,10 @@ LIB_OBJS += $(OUTPUT)util/target.o
 LIB_OBJS += $(OUTPUT)util/rblist.o
 LIB_OBJS += $(OUTPUT)util/intlist.o
 
-BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
+LIB_OBJS += $(OUTPUT)ui/hist.o
 
+BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
-
 # Benchmark modules
 BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
 BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
new file mode 100644
index ..b7936dc6271f
--- /dev/null
+++ b/tools/perf/ui/hist.c
@@ -0,0 +1,648 @@
+#include stdio.h
+#include math.h
+
+#include ../util/util.h
+#include ../util/hist.h
+#include ../util/sort.h
+
+
+static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
+{
+   int i;
+   int ret = fprintf(fp, );
+
+   for (i = 0; i  left_margin; i++)
+   ret += fprintf(fp,  );
+
+   return ret;
+}
+
+static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
+ int left_margin)
+{
+   int i;
+   size_t ret = callchain__fprintf_left_margin(fp, left_margin);
+
+   for (i = 0; i  depth; i++)
+   if (depth_mask  (1  i))
+   ret += fprintf(fp, |  );
+   else
+   ret += fprintf(fp,);
+
+   ret += fprintf(fp, \n);
+
+   return ret;
+}
+
+static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
+int depth, int depth_mask, int period,
+u64 total_samples, u64 hits,
+int left_margin)
+{
+   int i;
+   size_t ret = 0;
+
+   ret += callchain__fprintf_left_margin(fp, left_margin);
+   for (i = 0; i  depth; i++) {
+   if (depth_mask  (1  i))
+   ret += fprintf(fp, |);
+   else
+   ret += fprintf(fp,  );
+   if (!period  i == depth - 1) {
+   double percent;
+
+   percent = hits * 100.0 / total_samples;
+   ret += percent_color_fprintf(fp, --%2.2f%%-- , 
percent);
+   } else
+   ret += fprintf(fp, %s,   );
+   }
+   if (chain-ms.sym)
+   ret += fprintf(fp, %s\n, chain-ms.sym-name);
+   else
+   ret += fprintf(fp, 0x%0 PRIx64 \n, chain-ip);
+
+   return ret;
+}
+
+static struct symbol *rem_sq_bracket;
+static struct callchain_list rem_hits;
+
+static void init_rem_hits(void)
+{
+   rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
+   if (!rem_sq_bracket) {
+   fprintf(stderr, Not enough memory to display remaining 
hits\n);
+   return;
+   }
+
+   strcpy(rem_sq_bracket-name, [...]);
+   rem_hits.ms.sym = rem_sq_bracket;
+}
+
+static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
+u64 total_samples, int depth,
+int depth_mask, int left_margin)
+{
+   struct rb_node *node, *next;
+   struct callchain_node *child;
+   struct callchain_list *chain;
+   int new_depth_mask = depth_mask;
+   u64 remaining;
+   size_t ret = 0;
+   int i;
+   uint entries_printed = 0;
+
+   remaining = total_samples;
+
+   node = rb_first(root);
+   while (node) {
+   u64 new_total;
+   u64 cumul;
+
+   child = rb_entry(node, struct callchain_node, rb_node);
+   cumul = callchain_cumul_hits(child);
+   remaining -= cumul;
+
+   /*
+* The depth mask manages the output of pipes that show
+* the depth. We don't want to keep the pipes of the current
+* level for the last child of this depth.
+* Except if we have remaining filtered hits. They will
+* supersede the last child
+*/
+   next = rb_next(node);
+   if (!next  (callchain_param.mode != CHAIN_GRAPH_REL || 
!remaining))
+   new_depth_mask = ~(1  (depth - 1));
+
+   /*
+* But we keep the older