/*
 * $Header: /home/gene/library/website/docsrc/wgc/wgcperf/RCS/demo0002.c,v 395.1 2008/04/20 17:25:48 gene Exp $
 *
 * Compare the performances of malloc & Boehm when allocating
 * fixed-sized blocks of memory continuously in a loop.
 *
 * To use Boehm, compile with WITH_BOEHM.  Otherwise, you get
 * malloc/free.
 */

#include "this.h"

struct node
{
  struct node *next;
  char space[32 * 1024];
};

static struct node *
S_MakeList (int length, void *(*alloc) ())
{
  struct node *lst = NULL, *tmp;

  while (length-- > 0) {
    tmp = (struct node *) (*alloc) (sizeof *tmp);
    tmp->next = lst;
    lst = tmp;
  }
  return lst;
}

static struct node *
S_AutoMakeList (int length)
{
  return S_MakeList (length, &GC_malloc);
}

static struct node *
S_ManMakeList (int length) 
{
  return S_MakeList (length, &malloc);
}

static void
S_AutoFreeList (struct node *lst)
{
  /* For Boehm collector, don't bother to free the list. */
}

static void
S_ManFreeList (struct node *lst)
{
  while (lst != NULL) {
    struct node *tmp = lst;
    lst = lst->next;
    free (tmp);
  }
}

static clock_t
S_Loop (struct node *(*alloc) (), void (*free) (), int length, long count)
{
  clock_t start;
  long i;
  struct node *lst;

  start = clock ();
  for (i = 0; i < count; ++i) {
    lst = (*alloc) (length);
    (*free) (lst);
  }
  return clock () - start;
}


int
main ()
{
  int rc = 0;
  int length = 100;
  long count;
  struct node *lst;

  count = Iterations (length * sizeof *lst);
  ReportLine (S_Loop (&S_AutoMakeList, &S_AutoFreeList, length, count),
              S_Loop (&S_ManMakeList, &S_ManFreeList, length, count),
              count,
              "individual lists",
              __FILE__);
  return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

/* --- end of file --- */
