#include "glib.h"

#include <stdlib.h>
#include <stdio.h>

#define NUM (1000L * 1000L * 10L)
#define ATOM_SIZE 8
#define AREA_SIZE ATOM_SIZE * 1024
#define MAX_AT_A_TIME 10

int main (int argc, char *argv[])
{
  int j, count;
  long i;
  GPtrArray *atoms;
  GTimer *timer = g_timer_new ();
  
  atoms = g_ptr_array_sized_new (MAX_AT_A_TIME * 100);

  printf ("timing %ld random malloc()/free() calls...", NUM);
  g_timer_start (timer);
  for (i = 0; i < NUM; i += count)
  {
    count = g_random_int_range (1, MAX_AT_A_TIME);
    if (atoms->len == 0 || g_random_int () % 2)
    {
      for (j = 0; j < count; j++)
        g_ptr_array_add (atoms, malloc (ATOM_SIZE));
    }
    else
    {
      if (count > atoms->len)
        count = atoms->len;
      for (j = 0; j < count; j++)
        free (g_ptr_array_remove_index_fast (atoms,
                                             g_random_int() % atoms->len));
    }
  }
  g_timer_stop (timer);
  printf ("%g seconds\n", g_timer_elapsed (timer, NULL));
  while (atoms->len > 0)
    free (g_ptr_array_remove_index_fast (atoms, 0));

  GMemChunk *memchunk = g_mem_chunk_new ("test memory",
                                         ATOM_SIZE, AREA_SIZE,
                                         G_ALLOC_AND_FREE);

  printf ("timing %ld random memchunk alloc()/free() calls...", NUM);
  g_timer_start (timer);
  
  for (i = 0; i < NUM; i += count)
  {
    count = g_random_int_range (1, MAX_AT_A_TIME);
    if (atoms->len == 0 || g_random_int () % 2)
    {
      for (j = 0; j < count; j++)
        g_ptr_array_add (atoms, g_mem_chunk_alloc (memchunk));
    }
    else
    {
      if (count > atoms->len)
        count = atoms->len;
      for (j = 0; j < count; j++)
        g_mem_chunk_free (memchunk,
                          g_ptr_array_remove_index_fast (atoms,
                                                         g_random_int() % atoms->len));
    }
  }
  printf ("%g seconds\n", g_timer_elapsed (timer, NULL));
  
  return 0;
}
