mirror of
https://github.com/torvalds/linux.git
synced 2026-06-04 20:46:48 +02:00
perf list: Share print state with JSON output
The JSON print state has only one different field (need_sep). Let's add the default print state to the json state and use it. Then we can use the 'ps' variable to update the state properly. This is a preparation for the next commit. Reviewed-by: Ian Rogers <irogers@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
parent
8cf9cca7f6
commit
58e0a81e76
|
|
@ -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,7 +370,7 @@ 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;
|
||||
|
||||
strbuf_init(&buf, 0);
|
||||
|
|
@ -446,7 +446,7 @@ 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;
|
||||
|
||||
strbuf_init(&buf, 0);
|
||||
|
|
@ -521,10 +521,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 +574,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 +594,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,15 +609,15 @@ 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) {
|
||||
if (!unit_name) {
|
||||
default_ps.metrics = true;
|
||||
default_ps.metricgroups = true;
|
||||
ps->metrics = true;
|
||||
ps->metricgroups = true;
|
||||
}
|
||||
print_events(&print_cb, ps);
|
||||
goto out;
|
||||
|
|
@ -636,57 +639,57 @@ int cmd_list(int argc, const char **argv)
|
|||
default_ps.pmu_glob = old_pmu_glob;
|
||||
} else if (strcmp(argv[i], "hw") == 0 ||
|
||||
strcmp(argv[i], "hardware") == 0) {
|
||||
char *old_event_glob = default_ps.event_glob;
|
||||
char *old_event_glob = ps->event_glob;
|
||||
|
||||
default_ps.event_glob = strdup("legacy hardware");
|
||||
if (!default_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(&default_ps.event_glob);
|
||||
default_ps.event_glob = old_event_glob;
|
||||
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) {
|
||||
char *old_event_glob = default_ps.event_glob;
|
||||
char *old_event_glob = ps->event_glob;
|
||||
|
||||
default_ps.event_glob = strdup("legacy cache");
|
||||
if (!default_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);
|
||||
zfree(&default_ps.event_glob);
|
||||
default_ps.event_glob = old_event_glob;
|
||||
zfree(&ps->event_glob);
|
||||
ps->event_glob = old_event_glob;
|
||||
} else if (strcmp(argv[i], "pmu") == 0) {
|
||||
default_ps.exclude_abi = true;
|
||||
ps->exclude_abi = true;
|
||||
perf_pmus__print_pmu_events(&print_cb, ps);
|
||||
default_ps.exclude_abi = false;
|
||||
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
|
||||
|
|
@ -694,40 +697,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;
|
||||
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);
|
||||
}
|
||||
|
|
@ -735,12 +738,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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user