lkml.org 
[lkml]   [2012]   [Aug]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/3] perf tools: Support for events bash completion
    Date
    Add basic bash completion for the -e option in record, top
    and stat subcommands. Only hardware, software and tracepoint
    events are supported.

    Breakpoints, raw events and events grouping completion
    need more thinking.

    Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
    Cc: David Ahern <dsahern@gmail.com>
    Cc: Ingo Molnar <mingo@kernel.org>
    Cc: Jiri Olsa <jolsa@redhat.com>
    Cc: Namhyung Kim <namhyung@gmail.com>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Stephane Eranian <eranian@google.com>
    ---
    tools/perf/bash_completion | 6 +++-
    tools/perf/builtin-list.c | 14 ++++---
    tools/perf/util/parse-events.c | 70 +++++++++++++++++++++++++---------------
    tools/perf/util/parse-events.h | 7 ++--
    4 files changed, 61 insertions(+), 36 deletions(-)

    diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion
    index 9a31fa5..1958fa5 100644
    --- a/tools/perf/bash_completion
    +++ b/tools/perf/bash_completion
    @@ -6,7 +6,7 @@ _perf()
    local cur cmd

    COMPREPLY=()
    - _get_comp_words_by_ref cur
    + _get_comp_words_by_ref cur prev

    cmd=${COMP_WORDS[0]}

    @@ -14,6 +14,10 @@ _perf()
    if [ $COMP_CWORD -eq 1 ]; then
    cmds=$($cmd --list-cmds)
    COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
    + # List possible events for -e option
    + elif [[ $prev == "-e" && "${COMP_WORDS[1]}" == @(record|stat|top) ]]; then
    + cmds=$($cmd list --raw-dump)
    + COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
    # Fall down to list regular files
    else
    _filedir
    diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c
    index 6313b6e..bdcff81 100644
    --- a/tools/perf/builtin-list.c
    +++ b/tools/perf/builtin-list.c
    @@ -19,15 +19,15 @@ int cmd_list(int argc, const char **argv, const char *prefix __used)
    setup_pager();

    if (argc == 1)
    - print_events(NULL);
    + print_events(NULL, false);
    else {
    int i;

    for (i = 1; i < argc; ++i) {
    - if (i > 1)
    + if (i > 2)
    putchar('\n');
    if (strncmp(argv[i], "tracepoint", 10) == 0)
    - print_tracepoint_events(NULL, NULL);
    + print_tracepoint_events(NULL, NULL, false);
    else if (strcmp(argv[i], "hw") == 0 ||
    strcmp(argv[i], "hardware") == 0)
    print_events_type(PERF_TYPE_HARDWARE);
    @@ -36,13 +36,15 @@ int cmd_list(int argc, const char **argv, const char *prefix __used)
    print_events_type(PERF_TYPE_SOFTWARE);
    else if (strcmp(argv[i], "cache") == 0 ||
    strcmp(argv[i], "hwcache") == 0)
    - print_hwcache_events(NULL);
    + print_hwcache_events(NULL, false);
    + else if (strcmp(argv[i], "--raw-dump") == 0)
    + print_events(NULL, true);
    else {
    char *sep = strchr(argv[i], ':'), *s;
    int sep_idx;

    if (sep == NULL) {
    - print_events(argv[i]);
    + print_events(argv[i], false);
    continue;
    }
    sep_idx = sep - argv[i];
    @@ -51,7 +53,7 @@ int cmd_list(int argc, const char **argv, const char *prefix __used)
    return -1;

    s[sep_idx] = '\0';
    - print_tracepoint_events(s, s + sep_idx + 1);
    + print_tracepoint_events(s, s + sep_idx + 1, false);
    free(s);
    }
    }
    diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
    index 8bdfa3e..3ec4bfc 100644
    --- a/tools/perf/util/parse-events.c
    +++ b/tools/perf/util/parse-events.c
    @@ -799,7 +799,8 @@ static const char * const event_type_descriptors[] = {
    * Print the events from <debugfs_mount_point>/tracing/events
    */

    -void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
    +void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
    + bool name_only)
    {
    DIR *sys_dir, *evt_dir;
    struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
    @@ -829,6 +830,11 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob)
    !strglobmatch(evt_dirent.d_name, event_glob))
    continue;

    + if (name_only) {
    + printf("%s:%s ", sys_dirent.d_name, evt_dirent.d_name);
    + continue;
    + }
    +
    snprintf(evt_path, MAXPATHLEN, "%s:%s",
    sys_dirent.d_name, evt_dirent.d_name);
    printf(" %-50s [%s]\n", evt_path,
    @@ -906,7 +912,7 @@ void print_events_type(u8 type)
    __print_events_type(type, event_symbols_hw, PERF_COUNT_HW_MAX);
    }

    -int print_hwcache_events(const char *event_glob)
    +int print_hwcache_events(const char *event_glob, bool name_only)
    {
    unsigned int type, op, i, printed = 0;
    char name[64];
    @@ -923,8 +929,11 @@ int print_hwcache_events(const char *event_glob)
    if (event_glob != NULL && !strglobmatch(name, event_glob))
    continue;

    - printf(" %-50s [%s]\n", name,
    - event_type_descriptors[PERF_TYPE_HW_CACHE]);
    + if (name_only)
    + printf("%s ", name);
    + else
    + printf(" %-50s [%s]\n", name,
    + event_type_descriptors[PERF_TYPE_HW_CACHE]);
    ++printed;
    }
    }
    @@ -934,7 +943,8 @@ int print_hwcache_events(const char *event_glob)
    }

    static void print_symbol_events(const char *event_glob, unsigned type,
    - struct event_symbol *syms, unsigned max)
    + struct event_symbol *syms, unsigned max,
    + bool name_only)
    {
    unsigned i, printed = 0;
    char name[MAX_NAME_LEN];
    @@ -946,6 +956,11 @@ static void print_symbol_events(const char *event_glob, unsigned type,
    (syms->alias && strglobmatch(syms->alias, event_glob))))
    continue;

    + if (name_only) {
    + printf("%s ", syms->symbol);
    + continue;
    + }
    +
    if (strlen(syms->alias))
    snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias);
    else
    @@ -963,39 +978,42 @@ static void print_symbol_events(const char *event_glob, unsigned type,
    /*
    * Print the help text for the event symbols:
    */
    -void print_events(const char *event_glob)
    +void print_events(const char *event_glob, bool name_only)
    {
    -
    - printf("\n");
    - printf("List of pre-defined events (to be used in -e):\n");
    + if (!name_only) {
    + printf("\n");
    + printf("List of pre-defined events (to be used in -e):\n");
    + }

    print_symbol_events(event_glob, PERF_TYPE_HARDWARE,
    - event_symbols_hw, PERF_COUNT_HW_MAX);
    + event_symbols_hw, PERF_COUNT_HW_MAX, name_only);

    print_symbol_events(event_glob, PERF_TYPE_SOFTWARE,
    - event_symbols_sw, PERF_COUNT_SW_MAX);
    + event_symbols_sw, PERF_COUNT_SW_MAX, name_only);

    - print_hwcache_events(event_glob);
    + print_hwcache_events(event_glob, name_only);

    if (event_glob != NULL)
    return;

    - printf("\n");
    - printf(" %-50s [%s]\n",
    - "rNNN",
    - event_type_descriptors[PERF_TYPE_RAW]);
    - printf(" %-50s [%s]\n",
    - "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
    - event_type_descriptors[PERF_TYPE_RAW]);
    - printf(" (see 'perf list --help' on how to encode it)\n");
    - printf("\n");
    -
    - printf(" %-50s [%s]\n",
    - "mem:<addr>[:access]",
    + if (!name_only) {
    + printf("\n");
    + printf(" %-50s [%s]\n",
    + "rNNN",
    + event_type_descriptors[PERF_TYPE_RAW]);
    + printf(" %-50s [%s]\n",
    + "cpu/t1=v1[,t2=v2,t3 ...]/modifier",
    + event_type_descriptors[PERF_TYPE_RAW]);
    + printf(" (see 'perf list --help' on how to encode it)\n");
    + printf("\n");
    +
    + printf(" %-50s [%s]\n",
    + "mem:<addr>[:access]",
    event_type_descriptors[PERF_TYPE_BREAKPOINT]);
    - printf("\n");
    + printf("\n");
    + }

    - print_tracepoint_events(NULL, NULL);
    + print_tracepoint_events(NULL, NULL, name_only);
    }

    int parse_events__is_hardcoded_term(struct parse_events__term *term)
    diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
    index 163aad4..00416d7f 100644
    --- a/tools/perf/util/parse-events.h
    +++ b/tools/perf/util/parse-events.h
    @@ -96,10 +96,11 @@ void parse_events_update_lists(struct list_head *list_event,
    void parse_events_error(void *data, void *scanner, char const *msg);
    int parse_events__test(void);

    -void print_events(const char *event_glob);
    +void print_events(const char *event_glob, bool name_only);
    void print_events_type(u8 type);
    -void print_tracepoint_events(const char *subsys_glob, const char *event_glob);
    -int print_hwcache_events(const char *event_glob);
    +void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
    + bool name_only);
    +int print_hwcache_events(const char *event_glob, bool name_only);
    extern int is_valid_tracepoint(const char *event_string);

    extern int valid_debugfs_mount(const char *debugfs);
    --
    1.7.5.4


    \
     
     \ /
      Last update: 2012-08-09 23:41    [W:4.830 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site