diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/igt_aux.c | 38 | ||||
-rw-r--r-- | lib/igt_aux.h | 2 | ||||
-rw-r--r-- | lib/igt_core.c | 16 |
3 files changed, 56 insertions, 0 deletions
diff --git a/lib/igt_aux.c b/lib/igt_aux.c index fa6594c3..8dde9a12 100644 --- a/lib/igt_aux.c +++ b/lib/igt_aux.c @@ -350,6 +350,44 @@ void igt_stop_signal_helper(void) sig_stat = 0; } +/** + * igt_suspend_signal_helper: + * + * Suspends the child process spawned with igt_fork_signal_helper(). This + * should be called before a critical section of code that has difficulty to + * make progress if interrupted frequently, like the clone() syscall called + * from a largish executable. igt_resume_signal_helper() must be called after + * the critical section to restart interruptions for the test. + */ +void igt_suspend_signal_helper(void) +{ + int status; + + if (!signal_helper.running) + return; + + kill(signal_helper.pid, SIGSTOP); + while (waitpid(signal_helper.pid, &status, WUNTRACED) == -1 && + errno == EINTR) + ; +} + +/** + * igt_resume_signal_helper: + * + * Resumes the child process spawned with igt_fork_signal_helper(). + * + * This should be paired with igt_suspend_signal_helper() and called after the + * problematic code sensitive to signals. + */ +void igt_resume_signal_helper(void) +{ + if (!signal_helper.running) + return; + + kill(signal_helper.pid, SIGCONT); +} + static struct igt_helper_process shrink_helper; static void __attribute__((noreturn)) shrink_helper_process(int fd, pid_t pid) { diff --git a/lib/igt_aux.h b/lib/igt_aux.h index 499a1679..688ad1b8 100644 --- a/lib/igt_aux.h +++ b/lib/igt_aux.h @@ -55,6 +55,8 @@ extern int num_trash_bos; /* generally useful helpers */ void igt_fork_signal_helper(void); void igt_stop_signal_helper(void); +void igt_suspend_signal_helper(void); +void igt_resume_signal_helper(void); void igt_fork_shrink_helper(int fd); void igt_stop_shrink_helper(void); diff --git a/lib/igt_core.c b/lib/igt_core.c index 950ea9b0..538a4472 100644 --- a/lib/igt_core.c +++ b/lib/igt_core.c @@ -2282,6 +2282,13 @@ int igt_system(const char *command) if (pipe(errpipe) < 0) goto err; + /* + * The clone() system call called from a largish executable has + * difficulty to make progress if interrupted too frequently, so + * suspend the signal helper for the time of the syscall. + */ + igt_suspend_signal_helper(); + igt_fork_helper(&process) { close(outpipe[0]); close(errpipe[0]); @@ -2298,6 +2305,8 @@ int igt_system(const char *command) exit(EXIT_FAILURE); } + igt_resume_signal_helper(); + close(outpipe[1]); close(errpipe[1]); @@ -2340,9 +2349,14 @@ int igt_system_quiet(const char *command) if (dup2(nullfd, STDERR_FILENO) == -1) goto err; + /* See igt_system() for the reason for suspending the signal helper. */ + igt_suspend_signal_helper(); + if ((status = system(command)) == -1) goto err; + igt_resume_signal_helper(); + /* restore */ if (dup2(stdout_fd_copy, STDOUT_FILENO) == -1) goto err; @@ -2355,6 +2369,8 @@ int igt_system_quiet(const char *command) return WEXITSTATUS(status); err: + igt_resume_signal_helper(); + close(stderr_fd_copy); close(stdout_fd_copy); close(nullfd); |