X-Git-Url: https://git.lttng.org/?p=urcu.git;a=blobdiff_plain;f=tests%2Fregression%2Ftest_urcu_fork.c;h=f61420168b9005c92226760bf2a7c98356de5f77;hp=06786b0cc3285b988e225b1bb74c0f0522c76d36;hb=ad46005890368f9c306f0c510b3d4b08c47b66f8;hpb=9ee07024d322512ce099acb16774cec2766ab09f diff --git a/tests/regression/test_urcu_fork.c b/tests/regression/test_urcu_fork.c index 06786b0..f614201 100644 --- a/tests/regression/test_urcu_fork.c +++ b/tests/regression/test_urcu_fork.c @@ -44,13 +44,27 @@ #endif #include +#include "tap.h" + /* We generate children 3 levels deep */ #define FORK_DEPTH 3 /* Each generation spawns 10 children */ #define NR_FORK 10 +#define NR_TESTS NR_FORK + static int fork_generation; +/* + * Only print diagnostic for top level parent process, else the console + * has trouble formatting the tap output. + */ +#define diag_gen0(...) \ + do { \ + if (!fork_generation) \ + diag(__VA_ARGS__); \ + } while (0) + struct test_node { int somedata; struct rcu_head head; @@ -60,8 +74,7 @@ static void cb(struct rcu_head *head) { struct test_node *node; - fprintf(stderr, "rcu callback invoked in pid: %d\n", - (int) getpid()); + diag_gen0("rcu callback invoked in pid: %d", (int) getpid()); node = caa_container_of(head, struct test_node, head); free(node); } @@ -94,7 +107,7 @@ static int do_fork(const char *execname) { pid_t pid; - fprintf(stderr, "%s parent pid: %d, before fork\n", + diag_gen0("%s parent pid: %d, before fork", execname, (int) getpid()); call_rcu_before_fork(); @@ -102,12 +115,13 @@ static int do_fork(const char *execname) if (pid == 0) { /* child */ fork_generation++; + tap_disable(); call_rcu_after_fork_child(); - fprintf(stderr, "%s child pid: %d, after fork\n", + diag_gen0("%s child pid: %d, after fork", execname, (int) getpid()); test_rcu(); - fprintf(stderr, "%s child pid: %d, after rcu test\n", + diag_gen0("%s child pid: %d, after rcu test", execname, (int) getpid()); if (fork_generation >= FORK_DEPTH) exit(EXIT_SUCCESS); @@ -117,25 +131,26 @@ static int do_fork(const char *execname) /* parent */ call_rcu_after_fork_parent(); - fprintf(stderr, "%s parent pid: %d, after fork\n", + diag_gen0("%s parent pid: %d, after fork", execname, (int) getpid()); test_rcu(); - fprintf(stderr, "%s parent pid: %d, after rcu test\n", + diag_gen0("%s parent pid: %d, after rcu test", execname, (int) getpid()); for (;;) { pid = wait(&status); if (pid < 0) { - perror("wait"); + if (!fork_generation) + perror("wait"); return -1; } if (WIFEXITED(status)) { - fprintf(stderr, "child %u exited normally with status %u\n", + diag_gen0("child %u exited normally with status %u", pid, WEXITSTATUS(status)); if (WEXITSTATUS(status)) return -1; break; } else if (WIFSIGNALED(status)) { - fprintf(stderr, "child %u was terminated by signal %u\n", + diag_gen0("child %u was terminated by signal %u", pid, WTERMSIG(status)); return -1; } else { @@ -144,7 +159,8 @@ static int do_fork(const char *execname) } return 1; } else { - perror("fork"); + if (!fork_generation) + perror("fork"); return -1; } } @@ -153,6 +169,8 @@ int main(int argc, char **argv) { unsigned int i; + plan_tests(NR_TESTS); + #if 0 /* pthread_atfork does not work with malloc/free in callbacks */ ret = pthread_atfork(call_rcu_before_fork, @@ -172,14 +190,27 @@ restart: test_rcu(); synchronize_rcu(); ret = do_fork(argv[0]); - if (ret == 0) /* child */ + if (!fork_generation) { + ok(ret >= 0, "child status %d", ret); + } + if (ret == 0) { /* child */ goto restart; - else if (ret < 0) + } else if (ret < 0) { goto error; - /* else parent, continue. */ + } else { + /* else parent, continue. */ + } + } + if (!fork_generation) { + return exit_status(); + } else { + exit(EXIT_SUCCESS); } - exit(EXIT_SUCCESS); error: - exit(EXIT_FAILURE); + if (!fork_generation) { + return exit_status(); + } else { + exit(EXIT_FAILURE); + } }