Mesa (master): aco/tests: Fix deadlock for too large test lists

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Dec 29 19:05:36 UTC 2020


Module: Mesa
Branch: master
Commit: 6a246f5c6d51db1a91f4419871051f81d4b552d9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6a246f5c6d51db1a91f4419871051f81d4b552d9

Author: Tony Wasserka <tony.wasserka at gmx.de>
Date:   Thu Nov  5 16:21:49 2020 +0100

aco/tests: Fix deadlock for too large test lists

The write() to the communication pipe shared with check_output.py would block
for large test output streams since the pipe's consumer wouldn't be launched
until the write already completed.

Reviewed-by: Daniel Schürmann <daniel at schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7461>

---

 src/amd/compiler/tests/main.cpp | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/amd/compiler/tests/main.cpp b/src/amd/compiler/tests/main.cpp
index cb646e2dd30..b1980217ff2 100644
--- a/src/amd/compiler/tests/main.cpp
+++ b/src/amd/compiler/tests/main.cpp
@@ -173,14 +173,28 @@ int check_output(char **argv)
    int stdin_pipe[2];
    pipe(stdin_pipe);
 
-   write(stdin_pipe[1], checker_stdin_data, checker_stdin_size);
-   close(stdin_pipe[1]);
-   dup2(stdin_pipe[0], STDIN_FILENO);
-
-   execlp(ACO_TEST_PYTHON_BIN, ACO_TEST_PYTHON_BIN, ACO_TEST_SOURCE_DIR "/check_output.py", NULL);
-
-   fprintf(stderr, "%s: execl() failed: %s\n", argv[0], strerror(errno));
-   return 99;
+   pid_t child_pid = fork();
+   if (child_pid == -1) {
+      fprintf(stderr, "%s: fork() failed: %s\n", argv[0], strerror(errno));
+      return 99;
+   } else if (child_pid != 0) {
+      /* Evaluate test output externally using Python */
+      dup2(stdin_pipe[0], STDIN_FILENO);
+      close(stdin_pipe[0]);
+      close(stdin_pipe[1]);
+
+      execlp(ACO_TEST_PYTHON_BIN, ACO_TEST_PYTHON_BIN, ACO_TEST_SOURCE_DIR "/check_output.py", NULL);
+      fprintf(stderr, "%s: execlp() failed: %s\n", argv[0], strerror(errno));
+      return 99;
+   } else {
+      /* Feed input data to the Python process. Writing large streams to
+       * stdin will block eventually, so this is done in a forked process
+       * to let the test checker process chunks of data as they arrive */
+      write(stdin_pipe[1], checker_stdin_data, checker_stdin_size);
+      close(stdin_pipe[0]);
+      close(stdin_pipe[1]);
+      exit(0);
+   }
 }
 
 bool match_test(std::string name, std::string pattern)



More information about the mesa-commit mailing list