gem_stress: Add an option to test handling of signals
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 2 Jul 2011 07:59:32 +0000 (08:59 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Sat, 2 Jul 2011 08:13:20 +0000 (09:13 +0100)
As signals cause the syscalls to be interrupted, we often need to clean
up partial state before returning to userspace. Often a source of
unamusing bugs, so encourage gem_stress to provoke them.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
tests/gem_stress.c
tests/gem_stress.h

index 3bc538a..a4a5edf 100644 (file)
@@ -51,6 +51,8 @@
 
 #include "gem_stress.h"
 
+#include <signal.h>
+
 #define CMD_POLY_STIPPLE_OFFSET       0x7906
 
 /** TODO:
@@ -100,6 +102,29 @@ struct {
        unsigned max_failed_reads;
 } stats;
 
+static void signal_helper_process(pid_t pid)
+{
+       /* Interrupt the parent process at 500Hz, just to be annoying */
+       while (1) {
+               usleep(1000 * 1000 / 500);
+               if (kill(pid, SIGUSR1)) /* Parent has died, so must we. */
+                       exit(0);
+       }
+}
+
+static pid_t fork_signal_helper(void)
+{
+       pid_t pid;
+
+       pid = fork();
+       if (pid == 0) {
+               signal_helper_process(getppid());
+               return -1;
+       }
+
+       return pid;
+}
+
 static void tile2xy(struct scratch_buf *buf, unsigned tile, unsigned *x, unsigned *y)
 {
        assert(tile < buf->num_tiles);
@@ -651,6 +676,7 @@ static void parse_options(int argc, char **argv)
                {"no-hw", 0, 0, 'd'},
                {"buf-size", 1, 0, 's'},
                {"gpu-busy-load", 1, 0, 'g'},
+               {"no-signals", 0, 0, 'S'},
                {"buffer-count", 1, 0, 'c'},
                {"trace-tile", 1, 0, 't'},
                {"disable-blt", 0, 0, 'b'},
@@ -671,6 +697,7 @@ static void parse_options(int argc, char **argv)
 
        options.scratch_buf_size = 256*4096;
        options.no_hw = 0;
+       options.use_signal_helper = 1;
        options.gpu_busy_load = 0;
        options.num_buffers = 0;
        options.trace_tile = -1;
@@ -692,6 +719,10 @@ static void parse_options(int argc, char **argv)
                        options.no_hw = 1;
                        printf("no-hw debug mode\n");
                        break;
+               case 'S':
+                       options.use_signal_helper = 0;
+                       printf("disabling that pesky nuisance who keeps interrupting us\n");
+                       break;
                case 's':
                        tmp = atoi(optarg);
                        if (tmp < options.tile_size*8192)
@@ -881,12 +912,18 @@ int main(int argc, char **argv)
 {
        int i, j;
        unsigned *current_permutation, *tmp_permutation;
+       pid_t signal_helper = -1;
 
        drm_fd = drm_open_any();
        devid = intel_get_drm_devid(drm_fd);
 
        parse_options(argc, argv);
 
+       /* start our little helper early before too may allocations occur */
+       signal(SIGUSR1, SIG_IGN);
+       if (options.use_signal_helper)
+               signal_helper = fork_signal_helper();
+
        init();
 
        check_render_copyfunc();
@@ -935,5 +972,8 @@ int main(int argc, char **argv)
 
        close(drm_fd);
 
+       if (signal_helper != -1)
+               kill(signal_helper, SIGQUIT);
+
        return 0;
 }
index 759a529..f44773d 100644 (file)
@@ -42,6 +42,7 @@ struct option_struct {
     int ducttape;
     int tile_size;
     int check_render_cpyfn;
+    int use_signal_helper;
 };
 
 extern struct option_struct options;