summaryrefslogtreecommitdiff
path: root/tools/perf/builtin-list.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-list.c')
-rw-r--r--tools/perf/builtin-list.c169
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;
}