diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-09-03 14:50:28 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-10-09 10:09:28 -0400 |
commit | 1f115cb72e44391fac3ab1c562a77b421469ac2d (patch) | |
tree | acf52c04c0b16f74b32cf67d9ea8d9e50fd85dee /tools/perf/builtin-trace.c | |
parent | 01533e9720c8527faf0bc6e476c4c911a488e268 (diff) |
perf trace: Allow passing parms to arg formatters
So that we can have generic formatters that act upon specific
parameters.
Start using them with a simple string table that assumes entries
will be indexes to a string table, like with the 'which' parm
for the set and getitimer syscalls
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-r0dqhapr8j6150v1wctgg340@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-trace.c')
-rw-r--r-- | tools/perf/builtin-trace.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 939426c7dbde..386ca2058ee7 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -35,10 +35,35 @@ | |||
35 | 35 | ||
36 | struct syscall_arg { | 36 | struct syscall_arg { |
37 | unsigned long val; | 37 | unsigned long val; |
38 | void *parm; | ||
38 | u8 idx; | 39 | u8 idx; |
39 | u8 mask; | 40 | u8 mask; |
40 | }; | 41 | }; |
41 | 42 | ||
43 | struct strarray { | ||
44 | int nr_entries; | ||
45 | const char **entries; | ||
46 | }; | ||
47 | |||
48 | #define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \ | ||
49 | .nr_entries = ARRAY_SIZE(array), \ | ||
50 | .entries = array, \ | ||
51 | } | ||
52 | |||
53 | static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, | ||
54 | struct syscall_arg *arg) | ||
55 | { | ||
56 | int idx = arg->val; | ||
57 | struct strarray *sa = arg->parm; | ||
58 | |||
59 | if (idx < 0 || idx >= sa->nr_entries) | ||
60 | return scnprintf(bf, size, "%d", idx); | ||
61 | |||
62 | return scnprintf(bf, size, "%s", sa->entries[idx]); | ||
63 | } | ||
64 | |||
65 | #define SCA_STRARRAY syscall_arg__scnprintf_strarray | ||
66 | |||
42 | static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, | 67 | static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, |
43 | struct syscall_arg *arg) | 68 | struct syscall_arg *arg) |
44 | { | 69 | { |
@@ -229,6 +254,9 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct sysc | |||
229 | return printed; | 254 | return printed; |
230 | } | 255 | } |
231 | 256 | ||
257 | static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", }; | ||
258 | static DEFINE_STRARRAY(itimers); | ||
259 | |||
232 | #define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op | 260 | #define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op |
233 | 261 | ||
234 | static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, | 262 | static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, |
@@ -291,6 +319,7 @@ static struct syscall_fmt { | |||
291 | const char *name; | 319 | const char *name; |
292 | const char *alias; | 320 | const char *alias; |
293 | size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg); | 321 | size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg); |
322 | void *arg_parm[6]; | ||
294 | bool errmsg; | 323 | bool errmsg; |
295 | bool timeout; | 324 | bool timeout; |
296 | bool hexret; | 325 | bool hexret; |
@@ -305,6 +334,9 @@ static struct syscall_fmt { | |||
305 | { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, | 334 | { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, |
306 | { .name = "futex", .errmsg = true, | 335 | { .name = "futex", .errmsg = true, |
307 | .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, }, | 336 | .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, }, |
337 | { .name = "getitimer", .errmsg = true, | ||
338 | .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, | ||
339 | .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, | ||
308 | { .name = "ioctl", .errmsg = true, | 340 | { .name = "ioctl", .errmsg = true, |
309 | .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, }, | 341 | .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, }, |
310 | { .name = "lseek", .errmsg = true, | 342 | { .name = "lseek", .errmsg = true, |
@@ -338,6 +370,9 @@ static struct syscall_fmt { | |||
338 | { .name = "read", .errmsg = true, }, | 370 | { .name = "read", .errmsg = true, }, |
339 | { .name = "recvfrom", .errmsg = true, }, | 371 | { .name = "recvfrom", .errmsg = true, }, |
340 | { .name = "select", .errmsg = true, .timeout = true, }, | 372 | { .name = "select", .errmsg = true, .timeout = true, }, |
373 | { .name = "setitimer", .errmsg = true, | ||
374 | .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, | ||
375 | .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, | ||
341 | { .name = "socket", .errmsg = true, }, | 376 | { .name = "socket", .errmsg = true, }, |
342 | { .name = "stat", .errmsg = true, .alias = "newstat", }, | 377 | { .name = "stat", .errmsg = true, .alias = "newstat", }, |
343 | { .name = "uname", .errmsg = true, .alias = "newuname", }, | 378 | { .name = "uname", .errmsg = true, .alias = "newuname", }, |
@@ -361,6 +396,7 @@ struct syscall { | |||
361 | bool filtered; | 396 | bool filtered; |
362 | struct syscall_fmt *fmt; | 397 | struct syscall_fmt *fmt; |
363 | size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); | 398 | size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); |
399 | void **arg_parm; | ||
364 | }; | 400 | }; |
365 | 401 | ||
366 | static size_t fprintf_duration(unsigned long t, FILE *fp) | 402 | static size_t fprintf_duration(unsigned long t, FILE *fp) |
@@ -528,6 +564,9 @@ static int syscall__set_arg_fmts(struct syscall *sc) | |||
528 | if (sc->arg_scnprintf == NULL) | 564 | if (sc->arg_scnprintf == NULL) |
529 | return -1; | 565 | return -1; |
530 | 566 | ||
567 | if (sc->fmt) | ||
568 | sc->arg_parm = sc->fmt->arg_parm; | ||
569 | |||
531 | for (field = sc->tp_format->format.fields->next; field; field = field->next) { | 570 | for (field = sc->tp_format->format.fields->next; field; field = field->next) { |
532 | if (sc->fmt && sc->fmt->arg_scnprintf[idx]) | 571 | if (sc->fmt && sc->fmt->arg_scnprintf[idx]) |
533 | sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; | 572 | sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; |
@@ -619,6 +658,8 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, | |||
619 | "%s%s: ", printed ? ", " : "", field->name); | 658 | "%s%s: ", printed ? ", " : "", field->name); |
620 | if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) { | 659 | if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) { |
621 | arg.val = args[arg.idx]; | 660 | arg.val = args[arg.idx]; |
661 | if (sc->arg_parm) | ||
662 | arg.parm = sc->arg_parm[arg.idx]; | ||
622 | printed += sc->arg_scnprintf[arg.idx](bf + printed, | 663 | printed += sc->arg_scnprintf[arg.idx](bf + printed, |
623 | size - printed, &arg); | 664 | size - printed, &arg); |
624 | } else { | 665 | } else { |