/* * rfork.c - Wrapper for fork() that introduces non-determinism * in the order that the parent and child are executed */ /* $begin rfork */ #include #include #include #include #include /* Sleep for a random period between [0, MAX_SLEEP] us */ #define MAX_SLEEP 100000 /* Macro that maps val into the range [0, RAND_MAX] */ #define CONVERT(val) (((double)val)/(double)RAND_MAX) pid_t Fork(void) { static struct timeval time; unsigned bool, secs; pid_t pid; /* Generate a different seed each time the function is called */ gettimeofday(&time, NULL); srand(time.tv_usec); /* Determine whether to sleep in parent of child and for how long */ bool = (unsigned)(CONVERT(rand()) + 0.5); secs = (unsigned)(CONVERT(rand()) * MAX_SLEEP); /* Call the real fork function */ if ((pid = fork()) < 0) return pid; /* Randomly decide to sleep in the parent or the child */ if (pid == 0) { /* Child */ if(bool) { usleep(secs); } } else { /* Parent */ if (!bool) { usleep(secs); } } /* Return the PID like a normal fork call */ return pid; } /* $end rfork */