
#include <libpq-fe.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>

void
test(char *query, int niter)
{
  PGconn	*conn;
  PGresult	*result;
  int		 i;

  conn = PQconnectdb("host=/tmp dbname=postgres");
  if (PQstatus(conn) != CONNECTION_OK)
    {
      fprintf(stderr, "connection failed!\n");
      exit(1);
    }

  result = PQprepare(conn, "", query, 0, NULL);
  if (PQresultStatus(result) != PGRES_COMMAND_OK)
    {
      fprintf(stderr, "PREPARE failed: %s", PQerrorMessage(conn));
      PQclear(result);
      exit(1);
    }
  PQclear(result);

  for (i = 0; i < niter; i++)
    {
      result = PQexecPrepared(conn, "", 0, NULL, NULL, NULL, 0);
      if (PQresultStatus(result) != PGRES_TUPLES_OK)
	{
	  fprintf(stderr, "EXECUTE PREPARED failed: %s\n", PQerrorMessage(conn));
	  PQclear(result);
	  exit(1);
	}
      PQclear(result);
    }

  PQfinish(conn);
}

int
main(int argc, char *argv[])
{
  int	 niter;
  int	 nprocs;
  char	*query = "SELECT COUNT(*) FROM foo";
  int	 i;
  pid_t *procs;
  struct timeval tv1, tv2;

  if (argc != 3)
    {
      fprintf(stderr, "expected 3 arguments, got %d\n", argc);
      exit(1);
    }

  nprocs = atoi(argv[1]);
  niter = atoi(argv[2]);

  procs = malloc(sizeof(pid_t) * nprocs);

  gettimeofday(&tv1, NULL);

  for (i = 0; i < nprocs; i++)
    {
      pid_t pid = fork();
      if (pid == 0)
	{
	  test(query, niter);
	  exit(0);
	}
      else
	{
	  procs[i] = pid;
	}
    }

  for (i = 0; i < nprocs; i++)
    {
      int status;
      waitpid(procs[i], &status, 0);
      if (!WIFEXITED(status))
	{
	  fprintf(stderr, "child did not exit!\n", argc);
	  exit(1);
	}
      if (WEXITSTATUS(status) != 0)
	{
	  fprintf(stderr, "child exited with status %d\n", WEXITSTATUS(status));
	  exit(1);
	}
    }

  gettimeofday(&tv2, NULL);

  free(procs);

  if (tv2.tv_usec < tv1.tv_usec)
    {
      tv2.tv_usec += 1000000;
      tv2.tv_sec--;
    }
  

  printf("%03d.%06d\n",
	 (int) (tv2.tv_sec - tv1.tv_sec),
	 (int) (tv2.tv_usec - tv1.tv_usec));
}
