+ return 1;
+ } else {
+ if (!fork_generation)
+ perror("fork");
+ return -1;
+ }
+}
+
+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,
+ call_rcu_after_fork_parent,
+ call_rcu_after_fork_child);
+ if (ret) {
+ errno = ret;
+ perror("pthread_atfork");
+ exit(EXIT_FAILURE);
+ }
+#endif
+
+restart:
+ for (i = 0; i < NR_FORK; i++) {
+ int ret;
+
+ test_rcu();
+ synchronize_rcu();
+ ret = do_fork(argv[0]);
+ if (!fork_generation) {
+ ok(ret >= 0, "child status %d", ret);
+ }
+ if (ret == 0) { /* child */
+ goto restart;
+ } else if (ret < 0) {
+ goto error;
+ } else {
+ /* else parent, continue. */
+ }
+ }
+ if (!fork_generation) {
+ return exit_status();
+ } else {
+ exit(EXIT_SUCCESS);
+ }
+
+error:
+ if (!fork_generation) {
+ return exit_status();