/*
 * linear_allocator.h
 *
 * @copyright Copyright (C) 2016 Sproute Networks, Inc.
 *
 * @author Avneesh Sachdev <avneesh@sproute.com>
 *
 * This file is part of Quagga.
 *
 * Quagga 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, or (at your option) any
 * later version.
 *
 * Quagga 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 Quagga; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

/*
 * Header file for the linear allocator.
 *
 * An allocator that allocates memory by walking down towards the end
 * of a buffer. No attempt is made to reuse blocks that are freed
 * subsequently. The assumption is that the buffer is big enough to
 * cover allocations for a given purpose.
 */
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>

/*
 * Alignment for block allocated by the allocator. Must be a power of 2.
 */
#define LINEAR_ALLOCATOR_ALIGNMENT        8

#define LINEAR_ALLOCATOR_ALIGN(value)					\
  (((value) + LINEAR_ALLOCATOR_ALIGNMENT - 1) & ~(LINEAR_ALLOCATOR_ALIGNMENT - 1));

/*
 * linear_allocator_align_ptr
 */
static inline char *
linear_allocator_align_ptr (char *ptr)
{
  return (char *) LINEAR_ALLOCATOR_ALIGN ((intptr_t) ptr);
}

typedef struct linear_allocator_t_
{
  char *buf;

  /*
   * Current location in the buffer.
   */
  char *cur;

  /*
   * End of buffer.
   */
  char *end;

  /*
   * Version number of the allocator, this is bumped up when the allocator
   * is reset and helps identifies bad frees.
   */
  uint32_t version;

  /*
   * The number of blocks that are currently allocated.
   */
  int num_allocated;
} linear_allocator_t;

/*
 * linear_allocator_block_t
 *
 * Header structure at the begining of each block.
 */
typedef struct linear_allocator_block_t_
{
  uint32_t flags;

  /*
   * The version of the allocator when this block was allocated.
   */
  uint32_t version;
  char data[0];
} linear_allocator_block_t;

#define LINEAR_ALLOCATOR_BLOCK_IN_USE 0x01

#define LINEAR_ALLOCATOR_HDR_SIZE (sizeof(linear_allocator_block_t))

/*
 * linear_allocator_block_size
 *
 * The total amount of space a block will take in the buffer,
 * including the size of the header.
 */
static inline size_t
linear_allocator_block_size (size_t user_size)
{
  return LINEAR_ALLOCATOR_ALIGN (LINEAR_ALLOCATOR_HDR_SIZE + user_size);
}

/*
 * linear_allocator_ptr_to_block
 */
static inline linear_allocator_block_t *
linear_allocator_ptr_to_block (void *ptr)
{
  void *block_ptr;
  block_ptr = ((char *) ptr) - offsetof (linear_allocator_block_t, data);
  return block_ptr;
}

/*
 * linear_allocator_init
 */
static inline void
linear_allocator_init (linear_allocator_t * allocator, char *buf,
		       size_t buf_len)
{
  memset (allocator, 0, sizeof (*allocator));

  assert (linear_allocator_align_ptr (buf) == buf);
  allocator->buf = buf;
  allocator->cur = buf;
  allocator->end = buf + buf_len;
}

/*
 * linear_allocator_reset
 *
 * Prepare an allocator for reuse.
 *
 * *** NOTE ** This implicitly frees all the blocks in the allocator.
 */
static inline void
linear_allocator_reset (linear_allocator_t *allocator)
{
  allocator->num_allocated = 0;
  allocator->version++;
  allocator->cur = allocator->buf;
}

/*
 * linear_allocator_alloc
 */
static inline void *
linear_allocator_alloc (linear_allocator_t *allocator, size_t user_size)
{
  size_t block_size;
  linear_allocator_block_t *block;

  block_size = linear_allocator_block_size (user_size);

  if (allocator->cur + block_size > allocator->end)
    {
      return NULL;
    }

  block = (linear_allocator_block_t *) allocator->cur;
  allocator->cur += block_size;

  block->flags = LINEAR_ALLOCATOR_BLOCK_IN_USE;
  block->version = allocator->version;
  allocator->num_allocated++;
  return block->data;
}

/*
 * linear_allocator_free
 */
static inline void
linear_allocator_free (linear_allocator_t *allocator, void *ptr)
{
  linear_allocator_block_t *block;

  if (((char *) ptr) < allocator->buf || ((char *) ptr) >= allocator->end)
    {
      assert (0);
      return;
    }

  block = linear_allocator_ptr_to_block (ptr);
  if (block->version != allocator->version)
    {
      assert (0);
      return;
    }

  block->flags = block->flags & ~LINEAR_ALLOCATOR_BLOCK_IN_USE;

  if (--allocator->num_allocated < 0)
    {
      assert (0);
    }
}
