/* test for gslice cross thread allocation/free
 * Copyright (C) 2006 Stefan Westerfeld
 * Copyright (C) 2007 Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#include <glib.h>
#include <stdlib.h>
#include <unistd.h>

#define N_THREADS	8
#define N_ALLOCS	50000
#define MAX_BLOCK_SIZE  64

struct ThreadData
{
  int	   thread_id;
  GThread* gthread;

  GMutex   to_free_mutex;
  void*    to_free [N_THREADS * N_ALLOCS];
  int      bytes_to_free [N_THREADS * N_ALLOCS];
  int      n_to_free;
  int      n_freed;
} tdata[N_THREADS];

void*
thread_func (void *arg)
{
  struct ThreadData *td = arg;
  int i;
/*   g_print ("Thread %d starting\n", td->thread_id); */
  for (i = 0; i < N_ALLOCS; i++)
    {
      if (rand() % (N_ALLOCS / 20) == 0)
	g_print ("%c", 'a' - 1 + td->thread_id);

      /* allocate block of random size and randomly fill */
      int   bytes = rand() % MAX_BLOCK_SIZE + 1;
      char *mem = g_slice_alloc (bytes);
      int f;
      for (f = 0; f < bytes; f++)
	mem[f] = rand();

      /* associate block with random thread */
      int t = rand() % N_THREADS;
      g_mutex_lock (&tdata[t].to_free_mutex);
      tdata[t].to_free[tdata[t].n_to_free] = mem;
      tdata[t].bytes_to_free[tdata[t].n_to_free] = bytes;
      tdata[t].n_to_free++;
      g_mutex_unlock (&tdata[t].to_free_mutex);

      /* shuffle thread execution order every once in a while */
      if (rand() % 97 == 0)
        {
          if (rand() % 2)
            g_thread_yield();   /* concurrent shuffling for single core */
          else
            g_usleep (1000);    /* concurrent shuffling for multi core */
        }

      /* free a block associated with this thread */
      g_mutex_lock (&td->to_free_mutex);
      if (td->n_to_free > 0)
	{
	  td->n_to_free--;
	  g_slice_free1 (td->bytes_to_free[td->n_to_free], td->to_free[td->n_to_free]);
	  td->n_freed++;
	}
      g_mutex_unlock (&td->to_free_mutex);
    }

  return NULL;
}

int
main()
{
  int t;

  for (t = 0; t < N_THREADS; t++)
    {
      tdata[t].thread_id = t + 1;
      tdata[t].n_to_free = 0;
      tdata[t].n_freed = 0;
    }
  g_print ("Starting %d threads for concurrent GSlice usage...\n", N_THREADS);
  for (t = 0; t < N_THREADS; t++)
    {
      tdata[t].gthread   = g_thread_create (thread_func, &tdata[t], TRUE, NULL);
      g_assert (tdata[t].gthread != NULL);
    }
  for (t = 0; t < N_THREADS; t++)
    {
      g_thread_join (tdata[t].gthread);
    }
  g_print ("\n");
  for (t = 0; t < N_THREADS; t++)
    {
      g_print ("Thread %d: %d blocks freed, %d blocks not freed\n",
		    tdata[t].thread_id, tdata[t].n_freed, tdata[t].n_to_free);
    }
  return 0;
}
