From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> A new -o command switch enables logging to a file. v2: * Support "-o -" for explicit stdout selection. (Chris Wilson) Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> References: https://bugs.freedesktop.org/show_bug.cgi?id=108689 Cc: Eero Tamminen <eero.t.tamminen@xxxxxxxxx> Cc: 3.14pi@xxxxxxx Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Reviewed-by: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> --- man/intel_gpu_top.rst | 19 ++++++++----- tools/intel_gpu_top.c | 63 ++++++++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/man/intel_gpu_top.rst b/man/intel_gpu_top.rst index d5bda093c8e8..d487baca0c63 100644 --- a/man/intel_gpu_top.rst +++ b/man/intel_gpu_top.rst @@ -28,16 +28,21 @@ The tool gathers data using perf performance counters (PMU) exposed by i915 and OPTIONS ======= --s <ms> - Refresh period in milliseconds. +-h + Show help text. + +-J + Output JSON formatted data. -l - List text data to standard out. + List plain text data. --J - Output JSON formatted data to standard output. --h - Show help text. +-o <file path | -> + Output to the specified file instead of standard output. + '-' can also be specified to explicitly select standard output. + +-s <ms> + Refresh period in milliseconds. LIMITATIONS =========== diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index 900979eea7a1..60505a606bfc 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -690,10 +690,11 @@ usage(const char *appname) "Usage: %s [parameters]\n" "\n" "\tThe following parameters are optional:\n\n" - "\t[-s <ms>] Refresh period in milliseconds (default %ums).\n" - "\t[-l] List data to standard out.\n" - "\t[-J] JSON data to standard out.\n" "\t[-h] Show this help text.\n" + "\t[-J] Output JSON formatted data.\n" + "\t[-l] List plain text data.\n" + "\t[-o <file|->] Output to specified file or '-' for standard out.\n" + "\t[-s <ms>] Refresh period in milliseconds (default %ums).\n" "\n", appname, DEFAULT_PERIOD_MS); } @@ -740,6 +741,8 @@ static const char *json_indent[] = { static unsigned int json_prev_struct_members; static unsigned int json_struct_members; +FILE *out; + static void json_open_struct(const char *name) { @@ -749,14 +752,14 @@ json_open_struct(const char *name) json_struct_members = 0; if (name) - printf("%s%s\"%s\": {\n", - json_prev_struct_members ? ",\n" : "", - json_indent[json_indent_level], - name); + fprintf(out, "%s%s\"%s\": {\n", + json_prev_struct_members ? ",\n" : "", + json_indent[json_indent_level], + name); else - printf("%s\n%s{\n", - json_prev_struct_members ? "," : "", - json_indent[json_indent_level]); + fprintf(out, "%s\n%s{\n", + json_prev_struct_members ? "," : "", + json_indent[json_indent_level]); json_indent_level++; } @@ -766,7 +769,7 @@ json_close_struct(void) { assert(json_indent_level > 0); - printf("\n%s}", json_indent[--json_indent_level]); + fprintf(out, "\n%s}", json_indent[--json_indent_level]); if (json_indent_level == 0) fflush(stdout); @@ -778,17 +781,17 @@ json_add_member(const struct cnt_group *parent, struct cnt_item *item, { assert(json_indent_level < ARRAY_SIZE(json_indent)); - printf("%s%s\"%s\": ", + fprintf(out, "%s%s\"%s\": ", json_struct_members ? ",\n" : "", json_indent[json_indent_level], item->name); json_struct_members++; if (!strcmp(item->name, "unit")) - printf("\"%s\"", item->unit); + fprintf(out, "\"%s\"", item->unit); else - printf("%f", - pmu_calc(&item->pmu->val, item->d, item->t, item->s)); + fprintf(out, "%f", + pmu_calc(&item->pmu->val, item->d, item->t, item->s)); return 1; } @@ -811,8 +814,8 @@ stdout_close_struct(void) assert(stdout_level > 0); if (--stdout_level == 0) { stdout_lines++; - printf("\n"); - fflush(stdout); + fputs("\n", out); + fflush(out); } } @@ -844,10 +847,10 @@ stdout_add_member(const struct cnt_group *parent, struct cnt_item *item, grp_tot += 1 + it->fmt_d + (it->fmt_dd ? 1 : 0); } - printf("%*s ", grp_tot - 1, parent->display_name); + fprintf(out, "%*s ", grp_tot - 1, parent->display_name); return 0; } else if (headers == 2) { - printf("%*s ", fmt_tot, item->unit ?: item->name); + fprintf(out, "%*s ", fmt_tot, item->unit ?: item->name); return 0; } @@ -857,7 +860,7 @@ stdout_add_member(const struct cnt_group *parent, struct cnt_item *item, if (len < 0 || len == sizeof(buf)) fill_str(buf, sizeof(buf), 'X', fmt_tot); - len = printf("%s ", buf); + len = fprintf(out, "%s ", buf); return len > 0 ? len : 0; } @@ -1248,13 +1251,17 @@ int main(int argc, char **argv) { unsigned int period_us = DEFAULT_PERIOD_MS * 1000; int con_w = -1, con_h = -1; + char *output_path = NULL; struct engines *engines; unsigned int i; int ret, ch; /* Parse options */ - while ((ch = getopt(argc, argv, "s:Jlh")) != -1) { + while ((ch = getopt(argc, argv, "o:s:Jlh")) != -1) { switch (ch) { + case 'o': + output_path = optarg; + break; case 's': period_us = atoi(optarg) * 1000; break; @@ -1274,9 +1281,21 @@ int main(int argc, char **argv) } } - if (output_mode == INTERACTIVE && isatty(1) != 1) + if (output_mode == INTERACTIVE && (output_path || isatty(1) != 1)) output_mode = STDOUT; + if (output_path && strcmp(output_path, "-")) { + out = fopen(output_path, "w"); + + if (!out) { + fprintf(stderr, "Failed to open output file - '%s'!\n", + strerror(errno)); + exit(1); + } + } else { + out = stdout; + } + if (output_mode != INTERACTIVE) { sighandler_t sig = signal(SIGINT, sigint_handler); -- 2.19.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx