summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugeni Dodonov <eugeni.dodonov@intel.com>2011-09-05 19:41:24 -0300
committerEugeni Dodonov <eugeni.dodonov@intel.com>2011-09-05 19:45:01 -0300
commita483c97d910d18b0626591f770d212ca97e2f7a1 (patch)
tree6ef580bf932725cc9bbf6bb8485fb24166e70468
parentc2983f24e34936fd9e0d513922af70485d579e61 (diff)
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 <eugeni.dodonov@intel.com>
-rw-r--r--man/intel_gpu_top.110
-rw-r--r--tools/intel_gpu_top.c56
2 files changed, 65 insertions, 1 deletions
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 <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,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;
}