From a483c97d910d18b0626591f770d212ca97e2f7a1 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Mon, 5 Sep 2011 19:41:24 -0300 Subject: intel_gpu_top: support profiling user-specified commands This patch adds support for running intel_gpu_top to profile specific commands. The required command will be carried out in separate process, and main intel_gpu_top will leave when the child process will exit. Signed-off-by: Eugeni Dodonov --- man/intel_gpu_top.1 | 10 +++++++++ tools/intel_gpu_top.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/man/intel_gpu_top.1 b/man/intel_gpu_top.1 index bca83f0d..db2f362e 100644 --- a/man/intel_gpu_top.1 +++ b/man/intel_gpu_top.1 @@ -19,8 +19,18 @@ number of samples to acquire per second .B -o [output file] run non-interactively and collect usage statistics to [file] .TP +.B -e ["command to profile"] +execute a command, and leave when it is finished. Note that the entire command +with all parameters should be included as one parameter. +.TP .B -h show usage notes +.SH EXAMPLES +.TP +intel_gpu_top -o "cairo-trace-gvim.log" -s 100 -e "cairo-perf-trace /tmp/gvim" +will run cairo-perf-trace with /tmp/gvim trace, non-interactively, saving the +statistics into cairo-trace-gvim.log file, and collecting 100 samples per +second. .PP Note that idle units are not displayed, so an entirely idle GPU will only display the ring status and diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c index f7ea6dba..2e277fea 100644 --- a/tools/intel_gpu_top.c +++ b/tools/intel_gpu_top.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include "intel_gpu_tools.h" #include "instdone.h" @@ -447,11 +449,16 @@ int main(int argc, char **argv) FILE *output = stdout; double elapsed_time=0; int print_headers=1; + pid_t child_pid=-1; + int child_stat; + char *cmd=NULL; /* Parse options? */ - while ((ch = getopt(argc, argv, "s:o:h")) != -1) + while ((ch = getopt(argc, argv, "s:o:e:h")) != -1) { switch (ch) { + case 'e': cmd = strdup(optarg); + break; case 's': samples_per_sec = atoi(optarg); if (samples_per_sec < 100) { fprintf(stderr, "Error: samples per second must be >= 100\n"); @@ -479,6 +486,37 @@ int main(int argc, char **argv) argc -= optind; argv += optind; + /* Do we have a command to run? */ + if (cmd != NULL) + { + if (output != stdout) { + fprintf(output, "# Profiling: %s\n", cmd); + fflush(output); + } + child_pid = fork(); + if (child_pid < 0) + { + perror("fork"); + exit(1); + } + else if (child_pid == 0) { + int res; + res = system(cmd); + free(cmd); + if (res < 0) + perror("running command"); + if (output != stdout) { + fflush(output); + fprintf(output, "# %s exited with status %d\n", cmd, res); + fflush(output); + } + exit(0); + } + else { + free(cmd); + } + } + pci_dev = intel_get_pci_device(); devid = pci_dev->device_id; intel_get_mmio(pci_dev); @@ -671,7 +709,23 @@ int main(int argc, char **argv) if (i < STATS_COUNT) last_stats[i] = stats[i]; } + + /* Check if child has gone */ + if (child_pid > 0) + { + int res; + if ((res = waitpid(child_pid, &child_stat, WNOHANG)) == -1) { + perror("waitpid"); + exit(1); + } + if (res == 0) + continue; + if (WIFEXITED(child_stat)) + break; + } } + fclose(output); + return 0; } -- cgit v1.2.3