#undef G_DISABLE_ASSERT
#undef G_LOG_DOMAIN

#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>

#include <glib.h>

static int n_children = 3;
static int n_active_children;
static int n_iters = 10000;
static GMainLoop *loop;

static void
io_pipe (GIOChannel **channels)
{
  int fds[2];

  if (pipe(fds) < 0)
    {
      int errsv = errno;
      fprintf (stderr, "Cannot create pipe %s\n", g_strerror (errsv));
      exit (1);
    }

  channels[0] = g_io_channel_unix_new (fds[0]);
  channels[1] = g_io_channel_unix_new (fds[1]);
}

static gboolean
read_all (GIOChannel *channel, char *buf, gsize len)
{
  gsize bytes_read = 0;
  gsize count;
  GIOError err;

  while (bytes_read < len)
    {
      err = g_io_channel_read (channel, buf + bytes_read, len - bytes_read, &count);
      if (err)
	{
	  if (err != G_IO_ERROR_AGAIN)
	    return FALSE;
	}
      else if (count == 0)
	return FALSE;

      bytes_read += count;
    }

  return TRUE;
}

static gboolean
write_all (GIOChannel *channel, char *buf, gsize len)
{
  gsize bytes_written = 0;
  gsize count;
  GIOError err;

  while (bytes_written < len)
    {
      err = g_io_channel_write (channel, buf + bytes_written, len - bytes_written, &count);
      if (err && err != G_IO_ERROR_AGAIN)
	return FALSE;

      bytes_written += count;
    }

  return TRUE;
}

static void
run_child (GIOChannel *in_channel, GIOChannel *out_channel)
{
  int i;
  int val = 1;
  GTimer *timer = g_timer_new();

  for (i = 0; i < n_iters; i++)
    {
      write_all (out_channel, (char *)&val, sizeof (val));
      read_all (in_channel, (char *)&val, sizeof (val));
    }

  val = 0;
  write_all (out_channel, (char *)&val, sizeof (val));

  val = g_timer_elapsed (timer, NULL) * 1000;
  
  write_all (out_channel, (char *)&val, sizeof (val));
  g_timer_destroy (timer);

  exit (0);
}

static gboolean
input_callback (GIOChannel   *source,
		GIOCondition  condition,
		gpointer      data)
{
  int val;
  GIOChannel *dest = (GIOChannel *)data;
  
  if (!read_all (source, (char *)&val, sizeof(val)))
    {
      fprintf (stderr, "Unexpected EOF\n");
      exit (1);
    }

  if (val)
    {
      write_all (dest, (char *)&val, sizeof(val));
      
      return TRUE;
    }
  else
    {
      g_io_channel_close (source);
      g_io_channel_close (dest);
      
      g_io_channel_unref (source);
      g_io_channel_unref (dest);

      n_active_children--;
      if (n_active_children == 0)
	g_main_loop_quit (loop);
      
      return FALSE;
    }
}

static void
create_child (void)
{
  int pid, errsv;
  GIOChannel *in_channels[2];
  GIOChannel *out_channels[2];
  
  io_pipe (in_channels);
  io_pipe (out_channels);

  pid = fork ();
  errsv = errno;

  if (pid > 0)			/* Parent */
    {
      g_io_channel_close (in_channels[0]);
      g_io_channel_unref (in_channels[0]);
      g_io_channel_close (out_channels[1]);
      g_io_channel_unref (out_channels[1]);

      g_io_add_watch (out_channels[0], G_IO_IN | G_IO_HUP,
		      input_callback, in_channels[1]);
    }
  else if (pid == 0)		/* Child */
    {
      g_io_channel_close (in_channels[1]);
      g_io_channel_close (out_channels[0]);

      setsid ();

      run_child (in_channels[0], out_channels[1]);
    }
  else				/* Error */
    {
      fprintf (stderr, "Cannot fork: %s\n", g_strerror (errsv));
      exit (1);
    }
}

static double 
difftimeval (struct timeval *old, struct timeval *new)
{
  return
    (new->tv_sec - old->tv_sec) * 1000. + (new->tv_usec - old->tv_usec) / 1000;
}

int 
main (int argc, char **argv)
{
  int i;
  struct rusage old_usage;
  struct rusage new_usage;
  
  if (argc > 1)
    n_children = atoi(argv[1]);

  if (argc > 2)
    n_iters = atoi(argv[2]);

  printf ("Children: %d     Iters: %d\n", n_children, n_iters);

  n_active_children = n_children;
  for (i = 0; i < n_children; i++)
    create_child ();

  getrusage (RUSAGE_SELF, &old_usage);
  loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (loop);
  getrusage (RUSAGE_SELF, &new_usage);

  printf ("Elapsed user: %g\n",
	  difftimeval (&old_usage.ru_utime, &new_usage.ru_utime));
  printf ("Elapsed system: %g\n",
	  difftimeval (&old_usage.ru_stime, &new_usage.ru_stime));
  printf ("Elapsed total: %g\n",
	  difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) +	   
	  difftimeval (&old_usage.ru_stime, &new_usage.ru_stime));
  printf ("total / iteration: %g\n",
	  (difftimeval (&old_usage.ru_utime, &new_usage.ru_utime) +	   
	   difftimeval (&old_usage.ru_stime, &new_usage.ru_stime)) /
	  (n_iters * n_children));

  g_main_loop_unref (loop);
  return 0;
}
