diff mbox

[v4,i-g-t,3/3] aubdump: add --command option to stream aubdump to another program

Message ID 20161006151635.28573-3-lionel.g.landwerlin@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Lionel Landwerlin Oct. 6, 2016, 3:16 p.m. UTC
This comes handy if you want to look at your application output without
having to save it into a file. For example, use this with aubinator from
Mesa :

$ intel_aubdump -c '/path/to/aubinator --gen=hsw' my_gl_app

v2: Fix handling empty command line option

v3: Fix command line concatenation (again...)

v4: Use execvp (Petri)
    Indentation (Petri)
    Allow recording to a file and stream to an external application (Lionel)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: Sirisha Gandikota <Sirisha.Gandikota@intel.com>
---
 tools/aubdump.c        | 81 ++++++++++++++++++++++++++++++++++++++++++++------
 tools/intel_aubdump.in | 26 +++++++++++++++-
 2 files changed, 97 insertions(+), 10 deletions(-)

--
2.9.3

Comments

Gandikota, Sirisha Oct. 6, 2016, 9:41 p.m. UTC | #1
>-----Original Message-----

>From: Intel-gfx [mailto:intel-gfx-bounces@lists.freedesktop.org] On Behalf Of

>Lionel Landwerlin

>Sent: Thursday, October 06, 2016 8:17 AM

>To: intel-gfx@lists.freedesktop.org

>Cc: Gandikota, Sirisha <sirisha.gandikota@intel.com>

>Subject: [Intel-gfx] [PATCH v4 i-g-t 3/3] aubdump: add --command option to

>stream aubdump to another program

>

>This comes handy if you want to look at your application output without having

>to save it into a file. For example, use this with aubinator from Mesa :

>

>$ intel_aubdump -c '/path/to/aubinator --gen=hsw' my_gl_app

>

>v2: Fix handling empty command line option

>

>v3: Fix command line concatenation (again...)

>

>v4: Use execvp (Petri)

>    Indentation (Petri)

>    Allow recording to a file and stream to an external application (Lionel)

>

>Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

>Cc: Sirisha Gandikota <Sirisha.Gandikota@intel.com>

>---

> tools/aubdump.c        | 81

>++++++++++++++++++++++++++++++++++++++++++++------

> tools/intel_aubdump.in | 26 +++++++++++++++-

> 2 files changed, 97 insertions(+), 10 deletions(-)

>

>diff --git a/tools/aubdump.c b/tools/aubdump.c index e82b514..61aa83c 100644

>--- a/tools/aubdump.c

>+++ b/tools/aubdump.c

>@@ -43,6 +43,10 @@

> #include "intel_aub.h"

> #include "intel_chipset.h"

>

>+#ifndef ARRAY_SIZE

>+#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) #endif

>+

> static int close_init_helper(int fd);

> static int ioctl_init_helper(int fd, unsigned long request, ...);

>

>@@ -50,8 +54,8 @@ static int (*libc_close)(int fd) = close_init_helper;  static int

>(*libc_ioctl)(int fd, unsigned long request, ...) = ioctl_init_helper;

>

> static int drm_fd = -1;

>-static char *filename;

>-static FILE *file;

>+static char *filename = NULL;

>+static FILE *files[2] = { NULL, NULL };

> static int gen = 0;

> static int verbose = 0;

> static const uint32_t gtt_size = 0x10000; @@ -140,13 +144,28 @@

>align_u64(uint64_t v, uint64_t a)  static void  dword_out(uint32_t data)  {

>-	fwrite(&data, 1, 4, file);

>+	for (int i = 0; i < ARRAY_SIZE (files); i++) {

>+		if (files[i] == NULL)

>+			continue;

>+

>+		fail_if(fwrite(&data, 1, 4, files[i]) == 0,

>+			"Writing to output failed\n");

>+	}

> }

>

> static void

> data_out(const void *data, size_t size)  {

>-	fwrite(data, 1, size, file);

>+	if (size == 0)

>+		return;

>+

>+	for (int i = 0; i < ARRAY_SIZE (files); i++) {

>+		if (files[i] == NULL)

>+			continue;

>+

>+		fail_if(fwrite(data, 1, size, files[i]) == 0,

>+			"Writing to output failed\n");

>+	}

> }

>

> static void

>@@ -393,7 +412,10 @@ dump_execbuffer2(int fd, struct

>drm_i915_gem_execbuffer2 *execbuffer2)

> 	aub_dump_ringbuffer(batch_bo->offset + execbuffer2-

>>batch_start_offset,

> 			    offset, ring_flag);

>

>-	fflush(file);

>+	for (int i = 0; i < ARRAY_SIZE(files); i++) {

>+		if (files[i] != NULL)

>+			fflush(files[i]);

>+	}

> }

>

> static void

>@@ -426,6 +448,40 @@ close(int fd)

> 	return libc_close(fd);

> }

>

>+static FILE *

>+launch_command(char *command)

>+{

>+	int i = 0, fds[2];

>+	char **args = calloc(strlen(command), sizeof(char *));

>+	char *iter = command;

>+

>+	args[i++] = iter = command;

>+

>+	while ((iter = strstr(iter, ",")) != NULL) {

>+		*iter = '\0';

>+		iter += 1;

>+		args[i++] = iter;

>+	}

>+

>+	if (pipe(fds) == -1)

>+		return NULL;

>+

>+	switch (fork()) {

>+	case 0:

>+		dup2(fds[0], 0);

>+		fail_if(execvp(args[0], args) == -1,

>+			"intel_aubdump: failed to launch child command\n");

>+		return NULL;

>+

>+	default:

>+		free(args);

>+		return fdopen(fds[1], "w");

>+

>+	case -1:

>+		return NULL;

>+	}

>+}

>+

> static void

> maybe_init(void)

> {

>@@ -447,10 +503,15 @@ maybe_init(void)

> 			device_override = true;

> 		} else if (!strcmp(key, "file")) {

> 			filename = value;

>-			file = fopen(filename, "w+");

>-			fail_if(file == NULL,

>+			files[0] = fopen(filename, "w+");

>+			fail_if(files[0] == NULL,

> 				"intel_aubdump: failed to open file '%s'\n",

> 				filename);

>+		} else if (!strcmp(key,  "command")) {

>+			files[1] = launch_command(value);

>+			fail_if(files[1] == NULL,

>+				"intel_aubdump: failed to launch command

>'%s'\n",

>+				value);

> 		} else {

> 			fprintf(stderr, "intel_aubdump: unknown option '%s'\n",

>key);

> 		}

>@@ -621,7 +682,9 @@ static void __attribute__ ((destructor))

> fini(void)

> {

> 	free(filename);

>-	if (file)

>-		fclose(file);

>+	for (int i = 0; i < ARRAY_SIZE(files); i++) {

>+		if (files[i] != NULL)

>+			fclose(files[i]);

>+	}

> 	free(bos);

> }

>diff --git a/tools/intel_aubdump.in b/tools/intel_aubdump.in index

>445b60f..a8e96d6 100644

>--- a/tools/intel_aubdump.in

>+++ b/tools/intel_aubdump.in

>@@ -10,6 +10,9 @@ contents and execution of the GEM application.

>

>   -o, --output=FILE  Name of AUB file. Defaults to COMMAND.aub

>

>+  -c, --command=CMD  Execute CMD and write the AUB file's content to its

>+                     standard input

>+

>       --device=ID    Override PCI ID of the reported device

>

>   -v                 Enable verbose output

>@@ -30,6 +33,17 @@ function add_arg() {

>     args="$args$arg\n"

> }

>

>+function build_command () {

>+      command=""

>+      for i in $1; do

>+	  if [ -z $command ]; then

>+	      command=$i

>+	  else

>+	      command="$command,$i"

>+	  fi;

>+      done

>+}

>+

> while true; do

>       case "$1" in

> 	  -o)

>@@ -51,6 +65,16 @@ while true; do

> 	      add_arg "file=${file:-$(basename ${file}).aub}"

> 	      shift

> 	      ;;

>+	  -c)

>+	      build_command "$2"

>+	      add_arg "command=$command"

>+	      shift 2

>+	      ;;

>+	  --command=*)

>+	      build_command "${1##--command=}"

>+	      add_arg "command=$command"

>+	      shift

>+	      ;;

> 	  --device=*)

> 	      add_arg "device=${1##--device=}"

> 	      shift

>@@ -75,7 +99,7 @@ done

>

> [ -z $1 ] && show_help

>

>-[ -z $file ] && add_arg "file=intel.aub"

>+[ -z $file ] && [ -z $command ] && add_arg "file=intel.aub"

>

> prefix=@prefix@

> exec_prefix=@exec_prefix@

>--

>2.9.3


 [SG]  Works for me.
Reviewed-by Sirisha Gandikota <sirisha.gandikota@intel.com>
>_______________________________________________

>Intel-gfx mailing list

>Intel-gfx@lists.freedesktop.org

>https://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff mbox

Patch

diff --git a/tools/aubdump.c b/tools/aubdump.c
index e82b514..61aa83c 100644
--- a/tools/aubdump.c
+++ b/tools/aubdump.c
@@ -43,6 +43,10 @@ 
 #include "intel_aub.h"
 #include "intel_chipset.h"

+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+#endif
+
 static int close_init_helper(int fd);
 static int ioctl_init_helper(int fd, unsigned long request, ...);

@@ -50,8 +54,8 @@  static int (*libc_close)(int fd) = close_init_helper;
 static int (*libc_ioctl)(int fd, unsigned long request, ...) = ioctl_init_helper;

 static int drm_fd = -1;
-static char *filename;
-static FILE *file;
+static char *filename = NULL;
+static FILE *files[2] = { NULL, NULL };
 static int gen = 0;
 static int verbose = 0;
 static const uint32_t gtt_size = 0x10000;
@@ -140,13 +144,28 @@  align_u64(uint64_t v, uint64_t a)
 static void
 dword_out(uint32_t data)
 {
-	fwrite(&data, 1, 4, file);
+	for (int i = 0; i < ARRAY_SIZE (files); i++) {
+		if (files[i] == NULL)
+			continue;
+
+		fail_if(fwrite(&data, 1, 4, files[i]) == 0,
+			"Writing to output failed\n");
+	}
 }

 static void
 data_out(const void *data, size_t size)
 {
-	fwrite(data, 1, size, file);
+	if (size == 0)
+		return;
+
+	for (int i = 0; i < ARRAY_SIZE (files); i++) {
+		if (files[i] == NULL)
+			continue;
+
+		fail_if(fwrite(data, 1, size, files[i]) == 0,
+			"Writing to output failed\n");
+	}
 }

 static void
@@ -393,7 +412,10 @@  dump_execbuffer2(int fd, struct drm_i915_gem_execbuffer2 *execbuffer2)
 	aub_dump_ringbuffer(batch_bo->offset + execbuffer2->batch_start_offset,
 			    offset, ring_flag);

-	fflush(file);
+	for (int i = 0; i < ARRAY_SIZE(files); i++) {
+		if (files[i] != NULL)
+			fflush(files[i]);
+	}
 }

 static void
@@ -426,6 +448,40 @@  close(int fd)
 	return libc_close(fd);
 }

+static FILE *
+launch_command(char *command)
+{
+	int i = 0, fds[2];
+	char **args = calloc(strlen(command), sizeof(char *));
+	char *iter = command;
+
+	args[i++] = iter = command;
+
+	while ((iter = strstr(iter, ",")) != NULL) {
+		*iter = '\0';
+		iter += 1;
+		args[i++] = iter;
+	}
+
+	if (pipe(fds) == -1)
+		return NULL;
+
+	switch (fork()) {
+	case 0:
+		dup2(fds[0], 0);
+		fail_if(execvp(args[0], args) == -1,
+			"intel_aubdump: failed to launch child command\n");
+		return NULL;
+
+	default:
+		free(args);
+		return fdopen(fds[1], "w");
+
+	case -1:
+		return NULL;
+	}
+}
+
 static void
 maybe_init(void)
 {
@@ -447,10 +503,15 @@  maybe_init(void)
 			device_override = true;
 		} else if (!strcmp(key, "file")) {
 			filename = value;
-			file = fopen(filename, "w+");
-			fail_if(file == NULL,
+			files[0] = fopen(filename, "w+");
+			fail_if(files[0] == NULL,
 				"intel_aubdump: failed to open file '%s'\n",
 				filename);
+		} else if (!strcmp(key,  "command")) {
+			files[1] = launch_command(value);
+			fail_if(files[1] == NULL,
+				"intel_aubdump: failed to launch command '%s'\n",
+				value);
 		} else {
 			fprintf(stderr, "intel_aubdump: unknown option '%s'\n", key);
 		}
@@ -621,7 +682,9 @@  static void __attribute__ ((destructor))
 fini(void)
 {
 	free(filename);
-	if (file)
-		fclose(file);
+	for (int i = 0; i < ARRAY_SIZE(files); i++) {
+		if (files[i] != NULL)
+			fclose(files[i]);
+	}
 	free(bos);
 }
diff --git a/tools/intel_aubdump.in b/tools/intel_aubdump.in
index 445b60f..a8e96d6 100644
--- a/tools/intel_aubdump.in
+++ b/tools/intel_aubdump.in
@@ -10,6 +10,9 @@  contents and execution of the GEM application.

   -o, --output=FILE  Name of AUB file. Defaults to COMMAND.aub

+  -c, --command=CMD  Execute CMD and write the AUB file's content to its
+                     standard input
+
       --device=ID    Override PCI ID of the reported device

   -v                 Enable verbose output
@@ -30,6 +33,17 @@  function add_arg() {
     args="$args$arg\n"
 }

+function build_command () {
+      command=""
+      for i in $1; do
+	  if [ -z $command ]; then
+	      command=$i
+	  else
+	      command="$command,$i"
+	  fi;
+      done
+}
+
 while true; do
       case "$1" in
 	  -o)
@@ -51,6 +65,16 @@  while true; do
 	      add_arg "file=${file:-$(basename ${file}).aub}"
 	      shift
 	      ;;
+	  -c)
+	      build_command "$2"
+	      add_arg "command=$command"
+	      shift 2
+	      ;;
+	  --command=*)
+	      build_command "${1##--command=}"
+	      add_arg "command=$command"
+	      shift
+	      ;;
 	  --device=*)
 	      add_arg "device=${1##--device=}"
 	      shift
@@ -75,7 +99,7 @@  done

 [ -z $1 ] && show_help

-[ -z $file ] && add_arg "file=intel.aub"
+[ -z $file ] && [ -z $command ] && add_arg "file=intel.aub"

 prefix=@prefix@
 exec_prefix=@exec_prefix@