/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-mempool.h Memory pools
 * 
 * Copyright (C) 2002, 2003  Red Hat, Inc.
 *
 * Licensed under the Academic Free License version 2.1
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "dbus-mempool.h"
#include "dbus-internals.h"

/**
 * @defgroup DBusMemPool memory pools
 * @ingroup  DBusInternals
 * @brief DBusMemPool object
 *
 * Types and functions related to DBusMemPool.  A memory pool is used
 * to decrease memory fragmentation/overhead and increase speed for
 * blocks of small uniformly-sized objects. The main point is to avoid
 * the overhead of a malloc block for each small object, speed is
 * secondary.
 */

/**
 * @defgroup DBusMemPoolInternals Memory pool implementation details
 * @ingroup  DBusInternals
 * @brief DBusMemPool implementation details
 *
 * The guts of DBusMemPool.
 *
 * @{
 */

/**
 * typedef so DBusFreedElement struct can refer to itself.
 */
typedef struct DBusFreedElement DBusFreedElement;

/**
 * struct representing an element on the free list.
 * We just cast freed elements to this so we can
 * make a list out of them.
 */
struct DBusFreedElement
{
  DBusFreedElement *next; /**< next element of the free list */
};

/**
 * The dummy size of the variable-length "elements"
 * field in DBusMemBlock
 */
#define ELEMENT_PADDING 4

/**
 * Typedef for DBusMemBlock so the struct can recursively
 * point to itself.
 */
typedef struct DBusMemBlock DBusMemBlock;

/**
 * DBusMemBlock object represents a single malloc()-returned
 * block that gets chunked up into objects in the memory pool.
 */
struct DBusMemBlock
{
  DBusMemBlock *next;  /**< next block in the list, which is already used up;
                        *   only saved so we can free all the blocks
                        *   when we free the mem pool.
                        */

  /* this is a long so that "elements" is aligned */
  long used_so_far;     /**< bytes of this block already allocated as elements. */
  
  unsigned char elements[ELEMENT_PADDING]; /**< the block data, actually allocated to required size */
};

/**
 * Internals fields of DBusMemPool
 */
struct DBusMemPool
{
  int element_size;                /**< size of a single object in the pool */
  int block_size;                  /**< size of most recently allocated block */
  unsigned int zero_elements : 1;  /**< whether to zero-init allocated elements */

  DBusFreedElement *free_elements; /**< a free list of elements to recycle */
  DBusMemBlock *blocks;            /**< blocks of memory from malloc() */
  int allocated_elements;          /**< Count of outstanding allocated elements */
};

/** @} */

/**
 * @addtogroup DBusMemPool
 *
 * @{
 */

/**
 * @typedef DBusMemPool
 *
 * Opaque object representing a memory pool. Memory pools allow
 * avoiding per-malloc-block memory overhead when allocating a lot of
 * small objects that are all the same size. They are slightly
 * faster than calling malloc() also.
 */

/**
 * Creates a new memory pool, or returns #NULL on failure.  Objects in
 * the pool must be at least sizeof(void*) bytes each, due to the way
 * memory pools work. To avoid creating 64 bit problems, this means at
 * least 8 bytes on all platforms, unless you are 4 bytes on 32-bit
 * and 8 bytes on 64-bit.
 *
 * @param element_size size of an element allocated from the pool.
 * @param zero_elements whether to zero-initialize elements
 * @returns the new pool or #NULL
 */
DBusMemPool*
_dbus_mem_pool_new (int element_size,
                    dbus_bool_t zero_elements)
{
  DBusMemPool *pool;

  pool = dbus_new0 (DBusMemPool, 1);
  if (pool == NULL)
    return NULL;

  /* Make the element size at least 8 bytes. */
  if (element_size < 8)
    element_size = 8;
  
  /* these assertions are equivalent but the first is more clear
   * to programmers that see it fail.
   */
  _dbus_assert (element_size >= (int) sizeof (void*));
  _dbus_assert (element_size >= (int) sizeof (DBusFreedElement));

  /* align the element size to a pointer boundary so we won't get bus
   * errors under other architectures.  
   */
  pool->element_size = _DBUS_ALIGN_VALUE (element_size, sizeof (void *));

  pool->zero_elements = zero_elements != FALSE;

  pool->allocated_elements = 0;
  
  /* pick a size for the first block; it increases
   * for each block we need to allocate. This is
   * actually half the initial block size
   * since _dbus_mem_pool_alloc() unconditionally
   * doubles it prior to creating a new block.  */
  pool->block_size = pool->element_size * 8;

  _dbus_assert ((pool->block_size %
                 pool->element_size) == 0);
  
  return pool;
}

/**
 * Frees a memory pool (and all elements allocated from it).
 *
 * @param pool the memory pool.
 */
void
_dbus_mem_pool_free (DBusMemPool *pool)
{
  DBusMemBlock *block;

  block = pool->blocks;
  while (block != NULL)
    {
      DBusMemBlock *next = block->next;

      dbus_free (block);

      block = next;
    }

  dbus_free (pool);
}

/**
 * Allocates an object from the memory pool.
 * The object must be freed with _dbus_mem_pool_dealloc().
 *
 * @param pool the memory pool
 * @returns the allocated object or #NULL if no memory.
 */
void*
_dbus_mem_pool_alloc (DBusMemPool *pool)
{
#ifdef DBUS_BUILD_TESTS
  if (_dbus_disable_mem_pools ())
    {
      DBusMemBlock *block;
      int alloc_size;
      
      /* This is obviously really silly, but it's
       * debug-mode-only code that is compiled out
       * when tests are disabled (_dbus_disable_mem_pools()
       * is a constant expression FALSE so this block
       * should vanish)
       */
      
      alloc_size = sizeof (DBusMemBlock) - ELEMENT_PADDING +
        pool->element_size;
      
      if (pool->zero_elements)
        block = dbus_malloc0 (alloc_size);
      else
        block = dbus_malloc (alloc_size);

      if (block != NULL)
        {
          block->next = pool->blocks;
          pool->blocks = block;
          pool->allocated_elements += 1;

          return (void*) &block->elements[0];
        }
      else
        return NULL;
    }
  else
#endif
    {
      if (_dbus_decrement_fail_alloc_counter ())
        {
          _dbus_verbose (" FAILING mempool alloc\n");
          return NULL;
        }
      else if (pool->free_elements)
        {
          DBusFreedElement *element = pool->free_elements;

          pool->free_elements = pool->free_elements->next;

          if (pool->zero_elements)
            memset (element, '\0', pool->element_size);

          pool->allocated_elements += 1;
          
          return element;
        }
      else
        {
          void *element;
      
          if (pool->blocks == NULL ||
              pool->blocks->used_so_far == pool->block_size)
            {
              /* Need a new block */
              DBusMemBlock *block;
              int alloc_size;
#ifdef DBUS_BUILD_TESTS
              int saved_counter;
#endif
          
              if (pool->block_size <= _DBUS_INT_MAX / 4) /* avoid overflow */
                {
                  /* use a larger block size for our next block */
                  pool->block_size *= 2;
                  _dbus_assert ((pool->block_size %
                                 pool->element_size) == 0);
                }

              alloc_size = sizeof (DBusMemBlock) - ELEMENT_PADDING + pool->block_size;

#ifdef DBUS_BUILD_TESTS
              /* We save/restore the counter, so that memory pools won't
               * cause a given function to have different number of
               * allocations on different invocations. i.e.  when testing
               * we want consistent alloc patterns. So we skip our
               * malloc here for purposes of failed alloc simulation.
               */
              saved_counter = _dbus_get_fail_alloc_counter ();
              _dbus_set_fail_alloc_counter (_DBUS_INT_MAX);
#endif
          
              if (pool->zero_elements)
                block = dbus_malloc0 (alloc_size);
              else
                block = dbus_malloc (alloc_size);

#ifdef DBUS_BUILD_TESTS
              _dbus_set_fail_alloc_counter (saved_counter);
              _dbus_assert (saved_counter == _dbus_get_fail_alloc_counter ());
#endif
          
              if (block == NULL)
                return NULL;

              block->used_so_far = 0;
              block->next = pool->blocks;
              pool->blocks = block;          
            }
      
          element = &pool->blocks->elements[pool->blocks->used_so_far];
          
          pool->blocks->used_so_far += pool->element_size;

          pool->allocated_elements += 1;
          
          return element;
        }
    }
}

/**
 * Deallocates an object previously created with
 * _dbus_mem_pool_alloc(). The previous object
 * must have come from this same pool.
 * @param pool the memory pool
 * @param element the element earlier allocated.
 * @returns #TRUE if there are no remaining allocated elements
 */
dbus_bool_t
_dbus_mem_pool_dealloc (DBusMemPool *pool,
                        void        *element)
{
#ifdef DBUS_BUILD_TESTS
  if (_dbus_disable_mem_pools ())
    {
      DBusMemBlock *block;
      DBusMemBlock *prev;

      /* mmm, fast. ;-) debug-only code, so doesn't matter. */
      
      prev = NULL;
      block = pool->blocks;

      while (block != NULL)
        {
          if (block->elements == (unsigned char*) element)
            {
              if (prev)
                prev->next = block->next;
              else
                pool->blocks = block->next;
              
              dbus_free (block);

              _dbus_assert (pool->allocated_elements > 0);
              pool->allocated_elements -= 1;
              
              if (pool->allocated_elements == 0)
                _dbus_assert (pool->blocks == NULL);
              
              return pool->blocks == NULL;
            }
          prev = block;
          block = block->next;
        }
      
      _dbus_assert_not_reached ("freed nonexistent block");
      return FALSE;
    }
  else
#endif
    {
      DBusFreedElement *freed;
      
      freed = element;
      freed->next = pool->free_elements;
      pool->free_elements = freed;
      
      _dbus_assert (pool->allocated_elements > 0);
      pool->allocated_elements -= 1;
      
      return pool->allocated_elements == 0;
    }
}

/** @} */

#ifdef DBUS_BUILD_TESTS
#include "dbus-test.h"
#include <stdio.h>
#include <time.h>

static void
time_for_size (int size)
{
  int i;
  int j;
  clock_t start;
  clock_t end;
#define FREE_ARRAY_SIZE 512
#define N_ITERATIONS FREE_ARRAY_SIZE * 512
  void *to_free[FREE_ARRAY_SIZE];
  DBusMemPool *pool;

  _dbus_verbose ("Timings for size %d\n", size);
  
  _dbus_verbose (" malloc\n");
  
  start = clock ();
  
  i = 0;
  j = 0;
  while (i < N_ITERATIONS)
    {
      to_free[j] = dbus_malloc (size);
      _dbus_assert (to_free[j] != NULL); /* in a real app of course this is wrong */

      ++j;

      if (j == FREE_ARRAY_SIZE)
        {
          j = 0;
          while (j < FREE_ARRAY_SIZE)
            {
              dbus_free (to_free[j]);
              ++j;
            }

          j = 0;
        }
      
      ++i;
    }

  end = clock ();

  _dbus_verbose ("  created/destroyed %d elements in %g seconds\n",
                 N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC);



  _dbus_verbose (" mempools\n");
  
  start = clock ();

  pool = _dbus_mem_pool_new (size, FALSE);
  
  i = 0;
  j = 0;
  while (i < N_ITERATIONS)
    {
      to_free[j] = _dbus_mem_pool_alloc (pool); 
      _dbus_assert (to_free[j] != NULL);  /* in a real app of course this is wrong */

      ++j;

      if (j == FREE_ARRAY_SIZE)
        {
          j = 0;
          while (j < FREE_ARRAY_SIZE)
            {
              _dbus_mem_pool_dealloc (pool, to_free[j]);
              ++j;
            }

          j = 0;
        }
      
      ++i;
    }

  _dbus_mem_pool_free (pool);
  
  end = clock ();

  _dbus_verbose ("  created/destroyed %d elements in %g seconds\n",
                 N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC);

  _dbus_verbose (" zeroed malloc\n");
    
  start = clock ();
  
  i = 0;
  j = 0;
  while (i < N_ITERATIONS)
    {
      to_free[j] = dbus_malloc0 (size);
      _dbus_assert (to_free[j] != NULL); /* in a real app of course this is wrong */

      ++j;

      if (j == FREE_ARRAY_SIZE)
        {
          j = 0;
          while (j < FREE_ARRAY_SIZE)
            {
              dbus_free (to_free[j]);
              ++j;
            }

          j = 0;
        }
      
      ++i;
    }

  end = clock ();

  _dbus_verbose ("  created/destroyed %d elements in %g seconds\n",
                 N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC);
  
  _dbus_verbose (" zeroed mempools\n");
  
  start = clock ();

  pool = _dbus_mem_pool_new (size, TRUE);
  
  i = 0;
  j = 0;
  while (i < N_ITERATIONS)
    {
      to_free[j] = _dbus_mem_pool_alloc (pool); 
      _dbus_assert (to_free[j] != NULL);  /* in a real app of course this is wrong */

      ++j;

      if (j == FREE_ARRAY_SIZE)
        {
          j = 0;
          while (j < FREE_ARRAY_SIZE)
            {
              _dbus_mem_pool_dealloc (pool, to_free[j]);
              ++j;
            }

          j = 0;
        }
      
      ++i;
    }

  _dbus_mem_pool_free (pool);
  
  end = clock ();

  _dbus_verbose ("  created/destroyed %d elements in %g seconds\n",
                 N_ITERATIONS, (end - start) / (double) CLOCKS_PER_SEC);
}

/**
 * @ingroup DBusMemPoolInternals
 * Unit test for DBusMemPool
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_mem_pool_test (void)
{
  int i;
  int element_sizes[] = { 4, 8, 16, 50, 124 };
  
  i = 0;
  while (i < _DBUS_N_ELEMENTS (element_sizes))
    {
      time_for_size (element_sizes[i]);
      ++i;
    }
  
  return TRUE;
}

#endif /* DBUS_BUILD_TESTS */
