/* GLIB sliced memory - fast threaded memory chunk allocator
 * Copyright (C) 2005 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 <string.h>

#define ALIGN(size, base)       ((base) * (gsize) (((size) + (base) - 1) / (base)))

static gdouble parse_memsize (const gchar *cstring);
static void    usage         (void);

static void
fill_memory (guint **mem,
             guint   n,
             guint   val)
{
  guint j, o = 0;
  for (j = 0; j < n; j++)
    mem[j][o] = val;
}

static guint64
access_memory3 (guint  **mema,
                guint  **memb,
                guint  **memd,
                guint    n,
                guint64  repeats)
{
  guint64 accu = 0, i, j;
  const guint o = 0;
  for (i = 0; i < repeats; i++)
    {
      for (j = 1; j < n; j += 2)
        memd[j][o] = mema[j][o] + memb[j][o];
    }
  for (i = 0; i < repeats; i++)
    for (j = 0; j < n; j++)
      accu += memd[j][o];
  return accu;
}

static void
touch_mem (guint64 block_size,
           guint64 n_blocks,
           guint64 repeats)
{
  guint64 j, accu, n = n_blocks;
  GTimer *timer;
  guint **memc;
  guint **memb;
  guint **mema = g_new (guint*, n);
  for (j = 0; j < n; j++)
    mema[j] = g_slice_alloc (block_size);
  memb = g_new (guint*, n);
  for (j = 0; j < n; j++)
    memb[j] = g_slice_alloc (block_size);
  memc = g_new (guint*, n);
  for (j = 0; j < n; j++)
    memc[j] = g_slice_alloc (block_size);

  timer = g_timer_new();
  fill_memory (mema, n, 2);
  fill_memory (memb, n, 3);
  fill_memory (memc, n, 4);
  access_memory3 (mema, memb, memc, n, 3);
  g_timer_start (timer);
  accu = access_memory3 (mema, memb, memc, n, repeats);
  g_timer_stop (timer);

  g_print ("Access-time = %fs\n", g_timer_elapsed (timer, NULL));
  g_assert (accu / repeats == (2 + 3) * n / 2 + 4 * n / 2);

  for (j = 0; j < n; j++)
    {
      g_slice_free1 (block_size, mema[j]);
      g_slice_free1 (block_size, memb[j]);
      g_slice_free1 (block_size, memc[j]);
    }
  g_timer_destroy (timer);
  g_free (mema);
  g_free (memb);
  g_free (memc);
}

static void
usage (void)
{
  g_print ("Usage: slice-color <block-size> [memory-size] [repeats] [colorization]\n");
}

int
main (int   argc,
      char *argv[])
{
  guint64 block_size = 512, area_size = 1024 * 1024, n_blocks, repeats = 1000000;

  if (argc > 1)
    block_size = parse_memsize (argv[1]);
  else
    {
      usage();
      block_size = 512;
    }
  if (argc > 2)
    area_size = parse_memsize (argv[2]);
  if (argc > 3)
    repeats = parse_memsize (argv[3]);
  if (argc > 4)
    g_slice_set_config (G_SLICE_CONFIG_COLOR_INCREMENT, parse_memsize (argv[4]));

  /* figure number of blocks from block and area size.
   * divide area by 3 because touch_mem() allocates 3 areas
   */
  n_blocks = area_size / 3 / ALIGN (block_size, sizeof (gsize) * 2);

  /* basic sanity checks */
  if (!block_size || !n_blocks || block_size >= area_size)
    {
      g_printerr ("Invalid arguments: block-size=%llu memory-size=%llu\n", block_size, area_size);
      usage();
      return 1;
    }

  g_printerr ("Will allocate and touch %llu blocks of %llu bytes (= %llu bytes) %llu times with color increment: 0x%08llx\n",
              n_blocks, block_size, n_blocks * block_size, repeats, g_slice_get_config (G_SLICE_CONFIG_COLOR_INCREMENT));

  touch_mem (block_size, n_blocks, repeats);
  
  return 0;
}

static gdouble
parse_memsize (const gchar *cstring)
{
  gchar *mem = g_strdup (cstring);
  gchar *string = g_strstrip (mem);
  guint l = strlen (string);
  gdouble f = 0;
  gchar *derr = NULL;
  gdouble msize;

  switch (l ? string[l - 1] : 0)
    {
    case 'k':   f = 1000;               break;
    case 'K':   f = 1024;               break;
    case 'm':   f = 1000000;            break;
    case 'M':   f = 1024 * 1024;        break;
    case 'g':   f = 1000000000;         break;
    case 'G':   f = 1024 * 1024 * 1024; break;
    }
  if (f)
    string[l - 1] = 0;
  msize = g_ascii_strtod (string, &derr);
  g_free (mem);
  if (derr && *derr)
    {
      g_printerr ("failed to parse number at: %s\n", derr);
      msize = 0;
    }
  if (f)
    msize *= f;
  return msize;
}
