From: Eugeni Dodonov <eugeni.dodo...@intel.com>

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 <eugeni.dodo...@intel.com>
---
 man/intel_gpu_top.1   |   10 ++++++++
 tools/intel_gpu_top.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 65 insertions(+), 1 deletions(-)

diff --git a/man/intel_gpu_top.1 b/man/intel_gpu_top.1
index bca83f0..db2f362 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 88f7157..3619d1b 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -33,6 +33,8 @@
 #include <err.h>
 #include <sys/ioctl.h>
 #include <sys/time.h>
+#include <sys/wait.h>
+#include <string.h>
 #include "intel_gpu_tools.h"
 #include "instdone.h"
 
@@ -447,12 +449,17 @@ 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");
@@ -481,6 +488,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);
@@ -673,7 +711,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;
 }
-- 
1.7.6.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to