diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-07-11 10:15:19 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2014-07-11 10:41:28 +0100 |
commit | f47ee31dd5d5a5099ed6f5d4a59a12a2f83c8cae (patch) | |
tree | 8e36f42d42e9a50df109f47fe2e99c078edff487 /lib | |
parent | 3777d42303cf9d285a5337d71623d52402cb3021 (diff) |
Wait for any pid in order to reap failure quicker
When waiting for the forked tests, we can respond quicker to a failure
(such as oom) by waiting for any child to exit rather than waiting for
each child in order. Then when we see that a test failed, we can kill
all other children before aborting.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/igt_core.c | 42 |
1 files changed, 31 insertions, 11 deletions
diff --git a/lib/igt_core.c b/lib/igt_core.c index bdeeb599..26b360f2 100644 --- a/lib/igt_core.c +++ b/lib/igt_core.c @@ -925,32 +925,52 @@ bool __igt_fork(void) */ void igt_waitchildren(void) { + int err = 0; + int count; + assert(!test_child); - for (int nc = 0; nc < num_test_children; nc++) { + count = 0; + while (count < num_test_children) { int status = -1; - while (waitpid(test_children[nc], &status, 0) == -1 && - errno == EINTR) - ; + pid_t pid; + int c; - if (status != 0) { + pid = wait(&status); + if (pid == -1) + continue; + + for (c = 0; c < num_test_children; c++) + if (pid == test_children[c]) + break; + if (c == num_test_children) + continue; + + if (err == 0 && status != 0) { if (WIFEXITED(status)) { printf("child %i failed with exit status %i\n", - nc, WEXITSTATUS(status)); - igt_fail(WEXITSTATUS(status)); + c, WEXITSTATUS(status)); + err = WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { printf("child %i died with signal %i, %s\n", - nc, WTERMSIG(status), + c, WTERMSIG(status), strsignal(WTERMSIG(status))); - igt_fail(99); + err = 128 + WTERMSIG(status); } else { - printf("Unhandled failure in child %i\n", nc); - abort(); + printf("Unhandled failure [%d] in child %i\n", status, c); + err = 256; } + + for (c = 0; c < num_test_children; c++) + kill(test_children[c], SIGKILL); } + + count++; } num_test_children = 0; + if (err) + igt_fail(err); } /* exit handler code */ |