diff options
Diffstat (limited to 'tools/perf/builtin-list.c')
| -rw-r--r-- | tools/perf/builtin-list.c | 169 |
1 files changed, 106 insertions, 63 deletions
diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index caf42276bd0f..5cbca0bacd35 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -130,7 +130,7 @@ static void default_print_event(void *ps, const char *topic, if (deprecated && !print_state->deprecated) return; - if (print_state->pmu_glob && pmu_name && !strglobmatch(pmu_name, print_state->pmu_glob)) + if (print_state->pmu_glob && (!pmu_name || !strglobmatch(pmu_name, print_state->pmu_glob))) return; if (print_state->exclude_abi && pmu_type < PERF_TYPE_MAX && pmu_type != PERF_TYPE_RAW) @@ -283,8 +283,8 @@ static void default_print_metric(void *ps, } struct json_print_state { - /** @fp: File to write output to. */ - FILE *fp; + /** The shared print_state */ + struct print_state common; /** Should a separator be printed prior to the next item? */ bool need_sep; }; @@ -292,7 +292,7 @@ struct json_print_state { static void json_print_start(void *ps) { struct json_print_state *print_state = ps; - FILE *fp = print_state->fp; + FILE *fp = print_state->common.fp; fprintf(fp, "[\n"); } @@ -300,7 +300,7 @@ static void json_print_start(void *ps) static void json_print_end(void *ps) { struct json_print_state *print_state = ps; - FILE *fp = print_state->fp; + FILE *fp = print_state->common.fp; fprintf(fp, "%s]\n", print_state->need_sep ? "\n" : ""); } @@ -370,9 +370,26 @@ static void json_print_event(void *ps, const char *topic, { struct json_print_state *print_state = ps; bool need_sep = false; - FILE *fp = print_state->fp; + FILE *fp = print_state->common.fp; struct strbuf buf; + if (deprecated && !print_state->common.deprecated) + return; + + if (print_state->common.pmu_glob && + (!pmu_name || !strglobmatch(pmu_name, print_state->common.pmu_glob))) + return; + + if (print_state->common.exclude_abi && pmu_type < PERF_TYPE_MAX && + pmu_type != PERF_TYPE_RAW) + return; + + if (print_state->common.event_glob && + (!event_name || !strglobmatch(event_name, print_state->common.event_glob)) && + (!event_alias || !strglobmatch(event_alias, print_state->common.event_glob)) && + (!topic || !strglobmatch_nocase(topic, print_state->common.event_glob))) + return; + strbuf_init(&buf, 0); fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : ""); print_state->need_sep = true; @@ -446,9 +463,16 @@ static void json_print_metric(void *ps __maybe_unused, const char *group, { struct json_print_state *print_state = ps; bool need_sep = false; - FILE *fp = print_state->fp; + FILE *fp = print_state->common.fp; struct strbuf buf; + if (print_state->common.event_glob && + (!print_state->common.metrics || !name || + !strglobmatch(name, print_state->common.event_glob)) && + (!print_state->common.metricgroups || !group || + !strglobmatch(group, print_state->common.event_glob))) + return; + strbuf_init(&buf, 0); fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : ""); print_state->need_sep = true; @@ -521,10 +545,12 @@ int cmd_list(int argc, const char **argv) .fp = stdout, .desc = true, }; - struct print_state json_ps = { - .fp = stdout, + struct json_print_state json_ps = { + .common = { + .fp = stdout, + }, }; - void *ps = &default_ps; + struct print_state *ps = &default_ps; struct print_callbacks print_cb = { .print_start = default_print_start, .print_end = default_print_end, @@ -572,9 +598,11 @@ int cmd_list(int argc, const char **argv) argc = parse_options(argc, argv, list_options, list_usage, PARSE_OPT_STOP_AT_NON_OPTION); + if (json) + ps = &json_ps.common; + if (output_path) { - default_ps.fp = fopen(output_path, "w"); - json_ps.fp = default_ps.fp; + ps->fp = fopen(output_path, "w"); } setup_pager(); @@ -590,14 +618,13 @@ int cmd_list(int argc, const char **argv) .print_metric = json_print_metric, .skip_duplicate_pmus = json_skip_duplicate_pmus, }; - ps = &json_ps; } else { - default_ps.last_topic = strdup(""); - assert(default_ps.last_topic); - default_ps.visited_metrics = strlist__new(NULL, NULL); - assert(default_ps.visited_metrics); + ps->last_topic = strdup(""); + assert(ps->last_topic); + ps->visited_metrics = strlist__new(NULL, NULL); + assert(ps->visited_metrics); if (unit_name) - default_ps.pmu_glob = strdup(unit_name); + ps->pmu_glob = strdup(unit_name); else if (cputype) { const struct perf_pmu *pmu = perf_pmus__pmu_for_pmu_filter(cputype); @@ -606,14 +633,16 @@ int cmd_list(int argc, const char **argv) ret = -1; goto out; } - default_ps.pmu_glob = strdup(pmu->name); + ps->pmu_glob = strdup(pmu->name); } } print_cb.print_start(ps); if (argc == 0) { - default_ps.metrics = true; - default_ps.metricgroups = true; + if (!unit_name) { + ps->metrics = true; + ps->metricgroups = true; + } print_events(&print_cb, ps); goto out; } @@ -633,41 +662,58 @@ int cmd_list(int argc, const char **argv) zfree(&default_ps.pmu_glob); default_ps.pmu_glob = old_pmu_glob; } else if (strcmp(argv[i], "hw") == 0 || - strcmp(argv[i], "hardware") == 0) - print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX); - else if (strcmp(argv[i], "sw") == 0 || + strcmp(argv[i], "hardware") == 0) { + char *old_event_glob = ps->event_glob; + + ps->event_glob = strdup("legacy hardware"); + if (!ps->event_glob) { + ret = -1; + goto out; + } + perf_pmus__print_pmu_events(&print_cb, ps); + zfree(&ps->event_glob); + ps->event_glob = old_event_glob; + } else if (strcmp(argv[i], "sw") == 0 || strcmp(argv[i], "software") == 0) { - char *old_pmu_glob = default_ps.pmu_glob; + char *old_pmu_glob = ps->pmu_glob; static const char * const sw_globs[] = { "software", "tool" }; for (size_t j = 0; j < ARRAY_SIZE(sw_globs); j++) { - default_ps.pmu_glob = strdup(sw_globs[j]); - if (!default_ps.pmu_glob) { + ps->pmu_glob = strdup(sw_globs[j]); + if (!ps->pmu_glob) { ret = -1; goto out; } perf_pmus__print_pmu_events(&print_cb, ps); - zfree(&default_ps.pmu_glob); + zfree(&ps->pmu_glob); } - default_ps.pmu_glob = old_pmu_glob; + ps->pmu_glob = old_pmu_glob; } else if (strcmp(argv[i], "cache") == 0 || - strcmp(argv[i], "hwcache") == 0) - print_hwcache_events(&print_cb, ps); - else if (strcmp(argv[i], "pmu") == 0) { - default_ps.exclude_abi = true; + strcmp(argv[i], "hwcache") == 0) { + char *old_event_glob = ps->event_glob; + + ps->event_glob = strdup("legacy cache"); + if (!ps->event_glob) { + ret = -1; + goto out; + } perf_pmus__print_pmu_events(&print_cb, ps); - default_ps.exclude_abi = false; + zfree(&ps->event_glob); + ps->event_glob = old_event_glob; + } else if (strcmp(argv[i], "pmu") == 0) { + ps->exclude_abi = true; + perf_pmus__print_pmu_events(&print_cb, ps); + ps->exclude_abi = false; } else if (strcmp(argv[i], "sdt") == 0) print_sdt_events(&print_cb, ps); else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) { - default_ps.metricgroups = false; - default_ps.metrics = true; + ps->metricgroups = false; + ps->metrics = true; metricgroup__print(&print_cb, ps); } else if (strcmp(argv[i], "metricgroup") == 0 || strcmp(argv[i], "metricgroups") == 0) { - default_ps.metricgroups = true; - default_ps.metrics = false; + ps->metricgroups = true; + ps->metrics = false; metricgroup__print(&print_cb, ps); } #ifdef HAVE_LIBPFM @@ -675,43 +721,40 @@ int cmd_list(int argc, const char **argv) print_libpfm_events(&print_cb, ps); #endif else if ((sep = strchr(argv[i], ':')) != NULL) { - char *old_pmu_glob = default_ps.pmu_glob; - char *old_event_glob = default_ps.event_glob; + char *old_pmu_glob = ps->pmu_glob; + char *old_event_glob = ps->event_glob; - default_ps.event_glob = strdup(argv[i]); - if (!default_ps.event_glob) { + ps->event_glob = strdup(argv[i]); + if (!ps->event_glob) { ret = -1; goto out; } - default_ps.pmu_glob = strdup("tracepoint"); - if (!default_ps.pmu_glob) { - zfree(&default_ps.event_glob); + ps->pmu_glob = strdup("tracepoint"); + if (!ps->pmu_glob) { + zfree(&ps->event_glob); ret = -1; goto out; } perf_pmus__print_pmu_events(&print_cb, ps); - zfree(&default_ps.pmu_glob); - default_ps.pmu_glob = old_pmu_glob; + zfree(&ps->pmu_glob); + ps->pmu_glob = old_pmu_glob; print_sdt_events(&print_cb, ps); - default_ps.metrics = true; - default_ps.metricgroups = true; + ps->metrics = true; + ps->metricgroups = true; metricgroup__print(&print_cb, ps); - zfree(&default_ps.event_glob); - default_ps.event_glob = old_event_glob; + zfree(&ps->event_glob); + ps->event_glob = old_event_glob; } else { if (asprintf(&s, "*%s*", argv[i]) < 0) { printf("Critical: Not enough memory! Trying to continue...\n"); continue; } - default_ps.event_glob = s; - print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX); - print_hwcache_events(&print_cb, ps); + ps->event_glob = s; perf_pmus__print_pmu_events(&print_cb, ps); print_sdt_events(&print_cb, ps); - default_ps.metrics = true; - default_ps.metricgroups = true; + ps->metrics = true; + ps->metricgroups = true; metricgroup__print(&print_cb, ps); free(s); } @@ -719,12 +762,12 @@ int cmd_list(int argc, const char **argv) out: print_cb.print_end(ps); - free(default_ps.pmu_glob); - free(default_ps.last_topic); - free(default_ps.last_metricgroups); - strlist__delete(default_ps.visited_metrics); + free(ps->pmu_glob); + free(ps->last_topic); + free(ps->last_metricgroups); + strlist__delete(ps->visited_metrics); if (output_path) - fclose(default_ps.fp); + fclose(ps->fp); return ret; } |
