text: /* lnterposition for fork */
  #include "ms_delay.h"
  
  /* Performance parameters */
  /* Maximum delay (in milliseconds) */
  #define MAX_DELAY 100
  
  /* Global data */
  static int max_delay = MAX_DELAY;
  static bool initialized = false;
  
  void set_max_delay(int d) {
      max_delay = d;
  }
  
  static void initialize() {
      if (initialized)
          return;
      srandom(getpid());
      initialized = true;
  }
  
  /* Add more entropy to RNG */
  static void entropy() {
      struct timespec t;
      clock_gettime(CLOCK_REALTIME, &t);
      int n = t.tv_nsec % 25;
      while (n--)
  	random();
  }
  
  /* Hard delay.  Won't get interrupted by a signal */
  void ms_spin(int msecs) {
      struct timespec t;
      long start_ms;
      long curr_ms;
      clock_gettime(CLOCK_REALTIME, &t);
      start_ms = t.tv_sec * 1000 + t.tv_nsec/1000000;
      curr_ms = start_ms;
      while (curr_ms - start_ms < msecs) {
  	clock_gettime(CLOCK_REALTIME, &t);
  	curr_ms = t.tv_sec * 1000 + t.tv_nsec/1000000;
      }
  }
  
  /* Version of sleep that works at millisecond time scale */
  void ms_sleep(int msecs, bool spin) {
      if (msecs == 0)
  	return;
      if (spin) {
  	ms_spin(msecs);
  	return;
      }
  	
      struct timespec req;
      long secs = msecs / 1000;
      long nsecs = (msecs - secs * 1000) * 1000000;
      req.tv_sec = secs;
      req.tv_nsec = nsecs;
      if (nanosleep(&req, NULL) < 0) {
          fprintf(stderr, "Couldn't sleep for %d milliseconds\n", msecs);
      }
  }
  
  /* Uniform random number in [0.0,1.0] */
  static double uniform() {
      initialize();
      return (double) random() / RAND_MAX;
  }
  
  int choose_delay() {
      entropy();
      return (int) (uniform() * max_delay);
  }
  
  bool env_flag(char *name) {
      return getenv(name) != NULL;
  }
  
  bool choose_with_probability(double prob) {
      return uniform() <=  prob;
  }
  