* [PATCH] perf: Make printing table easily
@ 2010-03-08 7:55 Hitoshi Mitake
2010-03-11 12:51 ` Ingo Molnar
0 siblings, 1 reply; 5+ messages in thread
From: Hitoshi Mitake @ 2010-03-08 7:55 UTC (permalink / raw)
To: Ingo Molnar
Cc: linux-kernel, mitake, h.mitake, Peter Zijlstra, Paul Mackerras,
Frederic Weisbecker
Hi,
Making table of matrix by printf is painful work,
but it can be found in perf here and there.
So I'd like to propose semi-automation of making table.
New files util/table.c provides stuffs for easy table printing.
At first, user has to allocate struct table like this:
struct table *t = table_new();
Then, user can define columns by table_add_fixed() for stuffs
registers can contain or table_add_string() for string.
table_add_fixed(t, "%p", SIZE_OF_ADDR);
table_add_string(t, "%30s", 30);
First argument is pointer to struct table.
Second one is format specifier.
Third argument for table_add_fixed() is size of objects in rows.
Third one for table_add_string() is maximum length of
printing string. If it is 0, no truncate will be done.
After making columns, user can print each rows like this:
table_printf(t, table_test, 2501, "one");
Example of use:
| /* program */
| static void table_test(void)
| {
| struct table *t = table_new();
|
| table_add_fixed(t, "%p", SIZE_OF_ADDR);
| table_add_fixed(t, "%10d", sizeof(int));
| table_add_string(t, "%30s", 30);
|
| table_printf(t, table_test, 2501, "one");
| table_printf(t, t, 0x2501, "two");
| table_printf(t, table_printf, 42, "Answer to the Ultimate Question of "
| "Life, the Universe, and Everything");
|
| table_free(t);
| }
|
| int main(void)
| {
| table_test();
| }
| /* output */
| 0x420340 2501 one
| 0xc9c080 9473 two
| 0x450e90 42 Answer to the Ultimate Questi~ <- Third argument is truncated
Current util/table.c is too weak, but this can be a basic start point.
I think this is useful, how do you think?
Signed-off-by: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
---
tools/perf/Makefile | 2 +
tools/perf/util/table.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/table.h | 32 ++++++++++
3 files changed, 191 insertions(+), 0 deletions(-)
create mode 100644 tools/perf/util/table.c
create mode 100644 tools/perf/util/table.h
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 54a5b50..93ecf09 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -387,6 +387,7 @@ LIB_H += util/thread.h
LIB_H += util/trace-event.h
LIB_H += util/probe-finder.h
LIB_H += util/probe-event.h
+LIB_H += util/table.h
LIB_OBJS += util/abspath.o
LIB_OBJS += util/alias.o
@@ -433,6 +434,7 @@ LIB_OBJS += util/sort.o
LIB_OBJS += util/hist.o
LIB_OBJS += util/probe-event.o
LIB_OBJS += util/util.o
+LIB_OBJS += util/table.o
BUILTIN_OBJS += builtin-annotate.o
diff --git a/tools/perf/util/table.c b/tools/perf/util/table.c
new file mode 100644
index 0000000..a8b770d
--- /dev/null
+++ b/tools/perf/util/table.c
@@ -0,0 +1,157 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <linux/kernel.h>
+
+#include "util.h"
+#include "table.h"
+
+struct table *table_new(void)
+{
+ struct table *new;
+
+ new = zalloc(sizeof(struct table));
+ new->column_formats.next = &new->column_formats;
+ new->column_formats.prev = &new->column_formats;
+ return new;
+}
+
+void table_free(struct table *t)
+{
+ struct list_head *l;
+
+ list_for_each_prev(l, &t->column_formats) {
+ struct column_format *fmt
+ = container_of(l, struct column_format, formats);
+ free(fmt);
+ }
+
+ free(t);
+}
+
+static void table_add_column(struct table *t, struct column_format *new)
+{
+ list_add_tail(&new->formats, &t->column_formats);
+}
+
+void table_add_fixed(struct table *t, const char *spec, int size)
+{
+ struct column_format *fmt;
+
+ fmt = zalloc(sizeof(struct column_format));
+ fmt->spec = spec;
+ fmt->size = size;
+ table_add_column(t, fmt);
+}
+
+void table_add_string(struct table *t, const char *spec, int trunc)
+{
+ struct column_format *fmt;
+
+ BUG_ON(trunc < 0);
+
+ fmt = zalloc(sizeof(struct column_format));
+ fmt->spec = spec;
+ fmt->size = SIZE_OF_ADDR;
+ fmt->attr |= TABLE_ATTR_STRING;
+ fmt->trunc = trunc;
+ table_add_column(t, fmt);
+}
+
+void table_printf(struct table *t, ...)
+{
+ va_list ap;
+ struct list_head *l;
+
+ unsigned char byte = 0;
+ unsigned short word = 0;
+ unsigned long dword = 0;
+ unsigned long long qword = 0;
+ char *str = NULL;
+
+ va_start(ap, t);
+
+ list_for_each(l, &t->column_formats) {
+ struct column_format *fmt
+ = container_of(l, struct column_format, formats);
+
+ if (fmt->attr & TABLE_ATTR_STRING) {
+ BUG_ON(fmt->size != SIZE_OF_ADDR);
+
+ str = va_arg(ap, char *);
+
+ if (!fmt->trunc || (strlen(str) < fmt->trunc)) {
+ printf(fmt->spec, str);
+ } else {
+ char *trunced = zalloc(fmt->trunc + 1);
+ memcpy(trunced, str, fmt->trunc);
+ trunced[fmt->trunc - 1] = '~';
+ printf(fmt->spec, trunced);
+ }
+ } else {
+ switch (fmt->size) {
+ case 1:
+ byte = (unsigned char)va_arg(ap, unsigned int);
+ printf(fmt->spec, byte);
+ break;
+ case 2:
+ word = (unsigned short)va_arg(ap, unsigned int);
+ printf(fmt->spec, word);
+ break;
+ case 4:
+ dword = va_arg(ap, unsigned long);
+ printf(fmt->spec, dword);
+ break;
+ case 8:
+ qword = va_arg(ap, unsigned long long);
+ printf(fmt->spec, qword);
+ break;
+ default:
+ die("table_printf(): unknown size:%d\n",
+ fmt->size);
+ break;
+ }
+ }
+
+ if (l->next != &t->column_formats)
+ printf(" ");
+ }
+
+ printf("\n");
+ va_end(ap);
+}
+
+#if 0
+/* usage sample */
+
+/* program */
+static void table_test(void)
+{
+ struct table *t = table_new();
+
+ table_add_fixed(t, "%p", SIZE_OF_ADDR);
+ table_add_fixed(t, "%10d", sizeof(int));
+ table_add_string(t, "%30s", 30);
+
+ table_printf(t, table_test, 2501, "one");
+ table_printf(t, t, 0x2501, "two");
+ table_printf(t, table_printf, 42, "Answer to the Ultimate Question of "
+ "Life, the Universe, and Everything");
+
+ table_free(t);
+}
+
+int main(void)
+{
+ table_test();
+}
+
+/* output */
+0x420340 2501 one
+0xc9c080 9473 two
+0x450e90 42 Answer to the Ultimate Questi~
+
+#endif
diff --git a/tools/perf/util/table.h b/tools/perf/util/table.h
new file mode 100644
index 0000000..8a7c7d8
--- /dev/null
+++ b/tools/perf/util/table.h
@@ -0,0 +1,32 @@
+
+#ifndef __PERF_TABLE_H
+#define __PERF_TABLE_H
+
+#include <linux/list.h>
+
+#define SIZE_OF_ADDR sizeof(void *)
+
+#define TABLE_ATTR_STRING 0x00000001
+
+struct column_format {
+ struct list_head formats;
+
+ const char *spec;
+ int size;
+ int attr;
+ unsigned int trunc;
+};
+
+struct table {
+ int columns;
+ struct list_head column_formats;
+};
+
+struct table *table_new(void);
+void table_free(struct table *t);
+void table_printf(struct table *t, ...);
+
+void table_add_fixed(struct table *t, const char *spec, int size);
+void table_add_string(struct table *t, const char *spec, int trunc);
+
+#endif /* __PERF_TABLE_H */
--
1.6.5.2
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH] perf: Make printing table easily
2010-03-08 7:55 [PATCH] perf: Make printing table easily Hitoshi Mitake
@ 2010-03-11 12:51 ` Ingo Molnar
2010-03-11 14:06 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 5+ messages in thread
From: Ingo Molnar @ 2010-03-11 12:51 UTC (permalink / raw)
To: Hitoshi Mitake
Cc: linux-kernel, h.mitake, Peter Zijlstra, Paul Mackerras,
Frederic Weisbecker, Arnaldo Carvalho de Melo
* Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> wrote:
> Hi,
>
> Making table of matrix by printf is painful work,
> but it can be found in perf here and there.
> So I'd like to propose semi-automation of making table.
> New files util/table.c provides stuffs for easy table printing.
Looks quite reasonable in theory. I suspect it would be useful to see a few
table printing places converted to this facility, to see the simplification
factor in practice.
Ingo
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] perf: Make printing table easily
2010-03-11 12:51 ` Ingo Molnar
@ 2010-03-11 14:06 ` Arnaldo Carvalho de Melo
2010-03-17 7:50 ` Hitoshi Mitake
0 siblings, 1 reply; 5+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-03-11 14:06 UTC (permalink / raw)
To: Ingo Molnar
Cc: Hitoshi Mitake, linux-kernel, h.mitake, Peter Zijlstra,
Paul Mackerras, Frederic Weisbecker
Em Thu, Mar 11, 2010 at 01:51:26PM +0100, Ingo Molnar escreveu:
>
> * Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> wrote:
>
> > Hi,
> >
> > Making table of matrix by printf is painful work,
> > but it can be found in perf here and there.
> > So I'd like to propose semi-automation of making table.
> > New files util/table.c provides stuffs for easy table printing.
>
> Looks quite reasonable in theory. I suspect it would be useful to see a few
> table printing places converted to this facility, to see the simplification
> factor in practice.
I'm going thru the printing routines now to get them usable by TUI/GUIs,
starting with a libnewt based browser integrating initially report and
annotate, after I get the first patch in shape for merging I'll revisit
this table class of yours :-)
- Arnaldo
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] perf: Make printing table easily
2010-03-11 14:06 ` Arnaldo Carvalho de Melo
@ 2010-03-17 7:50 ` Hitoshi Mitake
2010-03-17 7:59 ` Hitoshi Mitake
0 siblings, 1 reply; 5+ messages in thread
From: Hitoshi Mitake @ 2010-03-17 7:50 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, linux-kernel, h.mitake, Peter Zijlstra,
Paul Mackerras, Frederic Weisbecker
On 03/11/10 23:06, Arnaldo Carvalho de Melo wrote:
> Em Thu, Mar 11, 2010 at 01:51:26PM +0100, Ingo Molnar escreveu:
>>
>> * Hitoshi Mitake<mitake@dcl.info.waseda.ac.jp> wrote:
>>
>>> Hi,
>>>
>>> Making table of matrix by printf is painful work,
>>> but it can be found in perf here and there.
>>> So I'd like to propose semi-automation of making table.
>>> New files util/table.c provides stuffs for easy table printing.
>>
>> Looks quite reasonable in theory. I suspect it would be useful to
see a few
>> table printing places converted to this facility, to see the
simplification
>> factor in practice.
>
> I'm going thru the printing routines now to get them usable by TUI/GUIs,
> starting with a libnewt based browser integrating initially report and
> annotate, after I get the first patch in shape for merging I'll revisit
> this table class of yours :-)
Thanks Arnaldo!
But I noticed fatal weak point of table.c.
User of table.c can reduce the cost of specifying
format specifier for printf, but like this case:
table_add_fixed(t, "%p", SIZE_OF_ADDR);
if (some_cond1)
table_add_fixed(t, "%10d", sizeof(int));
if (some_cond2)
table_add_string(t, "%30s", 30);
table_printf() may produces a lot of if-branch like this:
if (some_cond1 && some_cond2)
table_printf(t, table_test, 2501, "one");
else if (!some_cond1 && some_cond2)
table_printf(t, table_test, "one");
else if (some_cond1 && !some_cond2)
table_printf(t, table_test, 2501);
It is not so good, as Ingo told, at least table of this style
is not useful in real world...
But, how about this style?
First, user declare column with name like this:
table_add_column(t, "num1", "%10d", sizeof(int));
Then, user can add values with name,
table_add_field(t, "num1", 2501);
Finally, flush stored column
table_flush_line(t);
This way will be good for making title of table.
How about this?
Thanks,
Hitoshi
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] perf: Make printing table easily
2010-03-17 7:50 ` Hitoshi Mitake
@ 2010-03-17 7:59 ` Hitoshi Mitake
0 siblings, 0 replies; 5+ messages in thread
From: Hitoshi Mitake @ 2010-03-17 7:59 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, linux-kernel, h.mitake, Peter Zijlstra,
Paul Mackerras, Frederic Weisbecker
On 03/17/10 16:50, Hitoshi Mitake wrote:
> On 03/11/10 23:06, Arnaldo Carvalho de Melo wrote:
> > Em Thu, Mar 11, 2010 at 01:51:26PM +0100, Ingo Molnar escreveu:
> >>
> >> * Hitoshi Mitake<mitake@dcl.info.waseda.ac.jp> wrote:
> >>
> >>> Hi,
> >>>
> >>> Making table of matrix by printf is painful work,
> >>> but it can be found in perf here and there.
> >>> So I'd like to propose semi-automation of making table.
> >>> New files util/table.c provides stuffs for easy table printing.
> >>
> >> Looks quite reasonable in theory. I suspect it would be useful to
> see a few
> >> table printing places converted to this facility, to see the
> simplification
> >> factor in practice.
> >
> > I'm going thru the printing routines now to get them usable by
TUI/GUIs,
> > starting with a libnewt based browser integrating initially report and
> > annotate, after I get the first patch in shape for merging I'll
revisit
> > this table class of yours :-)
>
> Thanks Arnaldo!
>
> But I noticed fatal weak point of table.c.
>
> User of table.c can reduce the cost of specifying
> format specifier for printf, but like this case:
>
> table_add_fixed(t, "%p", SIZE_OF_ADDR);
> if (some_cond1)
> table_add_fixed(t, "%10d", sizeof(int));
> if (some_cond2)
> table_add_string(t, "%30s", 30);
>
> table_printf() may produces a lot of if-branch like this:
>
> if (some_cond1 && some_cond2)
> table_printf(t, table_test, 2501, "one");
> else if (!some_cond1 && some_cond2)
> table_printf(t, table_test, "one");
> else if (some_cond1 && !some_cond2)
> table_printf(t, table_test, 2501);
>
> It is not so good, as Ingo told, at least table of this style
> is not useful in real world...
>
> But, how about this style?
>
> First, user declare column with name like this:
> table_add_column(t, "num1", "%10d", sizeof(int));
>
> Then, user can add values with name,
> table_add_field(t, "num1", 2501);
>
> Finally, flush stored column
> table_flush_line(t);
>
Another suggestion:
If table_add_column() returns "column ID",
table_add_field() can specify tha column with it
and duplication of string can be reduced.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-03-17 7:59 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-08 7:55 [PATCH] perf: Make printing table easily Hitoshi Mitake
2010-03-11 12:51 ` Ingo Molnar
2010-03-11 14:06 ` Arnaldo Carvalho de Melo
2010-03-17 7:50 ` Hitoshi Mitake
2010-03-17 7:59 ` Hitoshi Mitake
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox