/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
  Copyright (c) 2001, 2002, 2003 Eliot Dresselhaus

  Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include <vppinfra/cache.h>	/* for CLIB_CACHE_LINE_BYTES */
#include <vppinfra/mem.h>
#include <vppinfra/hash.h>
#include <vppinfra/vec.h>
#include <vppinfra/heap.h>
#include <vppinfra/error.h>

always_inline heap_elt_t *
elt_at (heap_header_t * h, uword i)
{
  ASSERT (i < vec_len (h->elts));
  return h->elts + i;
}

always_inline heap_elt_t *
last (heap_header_t * h)
{
  return elt_at (h, h->tail);
}

always_inline heap_elt_t *
first (heap_header_t * h)
{
  return elt_at (h, h->head);
}

/* Objects sizes are binned into N_BINS bins.
   Objects with size <= SMALL_BINS have their own bins.
   Larger objects are grouped together in power or 2 sized
   bins.

   Sizes are in units of elt_bytes bytes. */

/* Convert size to bin. */
always_inline uword
size_to_bin (uword size)
{
  uword bin;

  ASSERT (size > 0);

  if (size <= HEAP_SMALL_BINS)
    {
      bin = size - 1;
      if (size == 0)
	bin = 0;
    }
  else
    {
      bin = HEAP_SMALL_BINS + max_log2 (size) - (HEAP_LOG2_SMALL_BINS + 1);
      if (bin >= HEAP_N_BINS)
	bin = HEAP_N_BINS - 1;
    }

  return bin;
}

/* Convert bin to size. */
always_inline __attribute__ ((unused))
     uword bin_to_size (uword bin)
{
  uword size;

  if (bin <= HEAP_SMALL_BINS - 1)
    size = bin + 1;
  else
    size = (uword) 1 << ((bin - HEAP_SMALL_BINS) + HEAP_LOG2_SMALL_BINS + 1);

  return size;
}

static void
elt_delete (heap_header_t * h, heap_elt_t * e)
{
  heap_elt_t *l = vec_end (h->elts) - 1;

  ASSERT (e >= h->elts && e <= l);

  /* Update doubly linked pointers. */
  {
    heap_elt_t *p = heap_prev (e);
    heap_elt_t *n = heap_next (e);

    if (p == e)
      {
	n->prev = 0;
	h->head = n - h->elts;
      }
    else if (n == e)
      {
	p->next = 0;
	h->tail = p - h->elts;
      }
    else
      {
	p->next = n - p;
	n->prev = p - n;
      }
  }

  /* Add to index free list or delete from end. */
  if (e < l)
    vec_add1 (h->free_elts, e - h->elts);
  else
    _vec_len (h->elts)--;
}

/*
  Before: P ... E
  After : P ... NEW ... E
*/
always_inline void
elt_insert_before (heap_header_t * h, heap_elt_t * e, heap_elt_t * new)
{
  heap_elt_t *p = heap_prev (e);

  if (p == e)
    {
      new->prev = 0;
      new->next = e - new;
      p->prev = new - p;
      h->head = new - h->elts;
    }
  else
    {
      new->prev = p - new;
      new->next = e - new;
      e->prev = new - e;
      p->next = new - p;
    }
}

/*
  Before: E ... N
  After : E ... NEW ... N
*/
always_inline void
elt_insert_after (heap_header_t * h, heap_elt_t * e, heap_elt_t * new)
{
  heap_elt_t *n = heap_next (e);

  if (n == e)
    {
      new->next = 0;
      new->prev = e - new;
      e->next = new - e;
      h->tail = new - h->elts;
    }
  else
    {
      new->prev = e - new;
      new->next = n - new;
      e->next = new - e;
      n->prev = new - n;
    }
}

always_inline heap_elt_t *
elt_new (heap_header_t * h)
{
  heap_elt_t *e;
  uword l;
  if ((l = vec_len (h->free_elts)) > 0)
    {
      e = elt_at (h, h->free_elts[l - 1]);
      _vec_len (h->free_elts) -= 1;
    }
  else
    vec_add2 (h->elts, e, 1);
  return e;
}

/* Return pointer to object at given offset.
   Used to write free list index of free objects. */
always_inline u32 *
elt_data (void *v, heap_elt_t * e)
{
  heap_header_t *h = heap_header (v);
  return v + heap_offset (e) * h->elt_bytes;
}

always_inline void
set_free_elt (void *v, heap_elt_t * e, uword fi)
{
  heap_header_t *h = heap_header (v);

  e->offset |= HEAP_ELT_FREE_BIT;
  if (h->elt_bytes >= sizeof (u32))
    {
      *elt_data (v, e) = fi;
    }
  else
    {
      /* For elt_bytes < 4 we must store free index in separate
         vector. */
      uword elt_index = e - h->elts;
      vec_validate (h->small_free_elt_free_index, elt_index);
      h->small_free_elt_free_index[elt_index] = fi;
    }
}

always_inline uword
get_free_elt (void *v, heap_elt_t * e, uword * bin_result)
{
  heap_header_t *h = heap_header (v);
  uword fb, fi;

  ASSERT (heap_is_free (e));
  fb = size_to_bin (heap_elt_size (v, e));

  if (h->elt_bytes >= sizeof (u32))
    {
      fi = *elt_data (v, e);
    }
  else
    {
      uword elt_index = e - h->elts;
      fi = vec_elt (h->small_free_elt_free_index, elt_index);
    }

  *bin_result = fb;
  return fi;
}

always_inline void
remove_free_block (void *v, uword b, uword i)
{
  heap_header_t *h = heap_header (v);
  uword l;

  ASSERT (b < vec_len (h->free_lists));
  ASSERT (i < vec_len (h->free_lists[b]));

  l = vec_len (h->free_lists[b]);

  if (i < l - 1)
    {
      uword t = h->free_lists[b][l - 1];
      h->free_lists[b][i] = t;
      set_free_elt (v, elt_at (h, t), i);
    }
  _vec_len (h->free_lists[b]) = l - 1;
}

static heap_elt_t *
search_free_list (void *v, uword size)
{
  heap_header_t *h = heap_header (v);
  heap_elt_t *f, *u;
  uword b, fb, f_size, f_index;
  word s, l;

  if (!v)
    return 0;

  /* Search free lists for bins >= given size. */
  for (b = size_to_bin (size); b < vec_len (h->free_lists); b++)
    if ((l = vec_len (h->free_lists[b])) > 0)
      {
	/* Find an object that is large enough.
	   Search list in reverse so that more recently freed objects will be
	   allocated again sooner. */
	u8 found = 0;
	do
	  {
	    l--;
	    f_index = h->free_lists[b][l];
	    f = elt_at (h, f_index);
	    f_size = heap_elt_size (v, f);
	    if ((s = f_size - size) >= 0)
	      {
		found = 1;
		break;
	      }
	  }
	while (l > 0);

	/* If we fail to find a large enough object, try the next larger size. */
	if (found == 0)
	  continue;

	ASSERT (heap_is_free (f));

	/* Link in used object (u) after free object (f). */
	if (s == 0)
	  {
	    u = f;
	    fb = HEAP_N_BINS;
	  }
	else
	  {
	    u = elt_new (h);
	    f = elt_at (h, f_index);
	    elt_insert_after (h, f, u);
	    fb = size_to_bin (s);
	  }

	u->offset = heap_offset (f) + s;

	if (fb != b)
	  {
	    if (fb < HEAP_N_BINS)
	      {
		uword i;
		vec_validate (h->free_lists, fb);
		i = vec_len (h->free_lists[fb]);
		vec_add1 (h->free_lists[fb], f - h->elts);
		set_free_elt (v, f, i);
	      }

	    remove_free_block (v, b, l);
	  }

	return u;
      }

  return 0;
}

static void combine_free_blocks (void *v, heap_elt_t * e0, heap_elt_t * e1);

static inline void
dealloc_elt (void *v, heap_elt_t * e)
{
  heap_header_t *h = heap_header (v);
  uword b, l;
  heap_elt_t *n, *p;

  b = size_to_bin (heap_elt_size (v, e));
  vec_validate (h->free_lists, b);
  l = vec_len (h->free_lists[b]);
  vec_add1 (h->free_lists[b], e - h->elts);
  set_free_elt (v, e, l);

  /* See if we can combine the block we just freed with neighboring free blocks. */
  p = heap_prev (e);
  if (!heap_is_free (p))
    p = e;

  n = heap_next (e);
  if (!heap_is_free (n))
    n = e;

  if (p != n)
    combine_free_blocks (v, p, n);
}

void *
_heap_alloc (void *v,
	     uword size,
	     uword align,
	     uword elt_bytes, uword * offset_return, uword * handle_return)
{
  uword offset = 0, align_size;
  heap_header_t *h;
  heap_elt_t *e;

  if (size == 0)
    goto error;

  /* Round up alignment to power of 2. */
  if (align <= 1)
    {
      align = 0;
      align_size = size;
    }
  else
    {
      align = max_pow2 (align);
      align_size = size + align - 1;
    }

  e = search_free_list (v, align_size);

  /* If nothing found on free list, allocate object from end of vector. */
  if (!e)
    {
      uword max_len;

      offset = vec_len (v);
      max_len = heap_get_max_len (v);

      if (max_len && offset + align_size > max_len)
	goto error;

      h = heap_header (v);
      if (!v || !(h->flags & HEAP_IS_STATIC))
	v = _vec_resize (v,
			 align_size,
			 (offset + align_size) * elt_bytes,
			 sizeof (h[0]), HEAP_DATA_ALIGN);
      else
	_vec_len (v) += align_size;

      if (offset == 0)
	{
	  h = heap_header (v);
	  h->elt_bytes = elt_bytes;
	}
    }

  h = heap_header (v);

  /* Add new element to doubly linked chain of elements. */
  if (!e)
    {
      e = elt_new (h);
      e->offset = offset;
      elt_insert_after (h, last (h), e);
    }

  if (align > 0)
    {
      uword e_index;
      uword new_offset, old_offset;

      old_offset = e->offset;
      new_offset = (old_offset + align - 1) & ~(align - 1);
      e->offset = new_offset;
      e_index = e - h->elts;

      /* Free fragments before and after aligned object. */
      if (new_offset > old_offset)
	{
	  heap_elt_t *before_e = elt_new (h);
	  before_e->offset = old_offset;
	  elt_insert_before (h, h->elts + e_index, before_e);
	  dealloc_elt (v, before_e);
	}

      if (new_offset + size < old_offset + align_size)
	{
	  heap_elt_t *after_e = elt_new (h);
	  after_e->offset = new_offset + size;
	  elt_insert_after (h, h->elts + e_index, after_e);
	  dealloc_elt (v, after_e);
	}

      e = h->elts + e_index;
    }

  h->used_count++;

  /* Keep track of used elements when debugging.
     This allows deallocation to check that passed objects are valid. */
  if (CLIB_DEBUG > 0)
    {
      uword handle = e - h->elts;
      ASSERT (!clib_bitmap_get (h->used_elt_bitmap, handle));
      h->used_elt_bitmap = clib_bitmap_ori (h->used_elt_bitmap, handle);
    }

  *offset_return = e->offset;
  *handle_return = e - h->elts;
  return v;

error:
  *offset_return = *handle_return = ~0;
  return v;
}

void
heap_dealloc (void *v, uword handle)
{
  heap_header_t *h = heap_header (v);
  heap_elt_t *e;

  ASSERT (handle < vec_len (h->elts));

  /* For debugging we keep track of indices for valid objects.
     We make sure user is not trying to free object with an invalid index. */
  if (CLIB_DEBUG > 0)
    {
      ASSERT (clib_bitmap_get (h->used_elt_bitmap, handle));
      h->used_elt_bitmap = clib_bitmap_andnoti (h->used_elt_bitmap, handle);
    }

  h->used_count--;

  e = h->elts + handle;
  ASSERT (!heap_is_free (e));

  dealloc_elt (v, e);
}

/* While freeing objects at INDEX we noticed free blocks i0 <= index and
   i1 >= index.  We combine these two or three blocks into one big free block. */
static void
combine_free_blocks (void *v, heap_elt_t * e0, heap_elt_t * e1)
{
  heap_header_t *h = heap_header (v);
  uword total_size, i, b, tb, ti, i_last, g_offset;
  heap_elt_t *e;

  struct
  {
    u32 index;
    u32 bin;
    u32 bin_index;
  } f[3], g;

  /* Compute total size of free objects i0 through i1. */
  total_size = 0;
  for (i = 0, e = e0; 1; e = heap_next (e), i++)
    {
      ASSERT (i < ARRAY_LEN (f));

      ti = get_free_elt (v, e, &tb);

      ASSERT (tb < vec_len (h->free_lists));
      ASSERT (ti < vec_len (h->free_lists[tb]));

      f[i].index = h->free_lists[tb][ti];
      f[i].bin = tb;
      f[i].bin_index = ti;

      total_size += heap_elt_size (v, elt_at (h, f[i].index));

      if (e == e1)
	{
	  i_last = i;
	  break;
	}
    }

  /* Compute combined bin.  See if all objects can be
     combined into existing bin. */
  b = size_to_bin (total_size);
  g.index = g.bin_index = 0;
  for (i = 0; i <= i_last; i++)
    if (b == f[i].bin)
      {
	g = f[i];
	break;
      }

  /* Make sure we found a bin. */
  if (i > i_last)
    {
      g.index = elt_new (h) - h->elts;
      vec_validate (h->free_lists, b);
      g.bin_index = vec_len (h->free_lists[b]);
      vec_add1 (h->free_lists[b], g.index);
      elt_insert_before (h, elt_at (h, f[0].index), elt_at (h, g.index));
    }

  g_offset = elt_at (h, f[0].index)->offset;

  /* Delete unused bins. */
  for (i = 0; i <= i_last; i++)
    if (g.index != f[i].index)
      {
	ti = get_free_elt (v, elt_at (h, f[i].index), &tb);
	remove_free_block (v, tb, ti);
	elt_delete (h, elt_at (h, f[i].index));
      }

  /* Initialize new element. */
  elt_at (h, g.index)->offset = g_offset;
  set_free_elt (v, elt_at (h, g.index), g.bin_index);
}

uword
heap_len (void *v, word handle)
{
  heap_header_t *h = heap_header (v);

  if (CLIB_DEBUG > 0)
    ASSERT (clib_bitmap_get (h->used_elt_bitmap, handle));
  return heap_elt_size (v, elt_at (h, handle));
}

void *
_heap_free (void *v)
{
  heap_header_t *h = heap_header (v);
  uword b;

  if (!v)
    return v;

  clib_bitmap_free (h->used_elt_bitmap);
  for (b = 0; b < vec_len (h->free_lists); b++)
    vec_free (h->free_lists[b]);
  vec_free (h->free_lists);
  vec_free (h->elts);
  vec_free (h->free_elts);
  vec_free (h->small_free_elt_free_index);
  if (!(h->flags & HEAP_IS_STATIC))
    vec_free_h (v, sizeof (h[0]));
  return v;
}

uword
heap_bytes (void *v)
{
  heap_header_t *h = heap_header (v);
  uword bytes, b;

  if (!v)
    return 0;

  bytes = sizeof (h[0]);
  bytes += vec_len (v) * sizeof (h->elt_bytes);
  for (b = 0; b < vec_len (h->free_lists); b++)
    bytes += vec_capacity (h->free_lists[b], 0);
  bytes += vec_bytes (h->free_lists);
  bytes += vec_capacity (h->elts, 0);
  bytes += vec_capacity (h->free_elts, 0);
  bytes += vec_bytes (h->used_elt_bitmap);

  return bytes;
}

static u8 *
debug_elt (u8 * s, void *v, word i, word n)
{
  heap_elt_t *e, *e0, *e1;
  heap_header_t *h = heap_header (v);
  word j;

  if (vec_len (h->elts) == 0)
    return s;

  if (i < 0)
    e0 = first (h);
  else
    {
      e0 = h->elts + i;
      for (j = 0; j < n / 2; j++)
	e0 = heap_prev (e0);
    }

  if (n < 0)
    e1 = h->elts + h->tail;
  else
    {
      e1 = h->elts + i;
      for (j = 0; j < n / 2; j++)
	e1 = heap_next (e1);
    }

  i = -n / 2;
  for (e = e0; 1; e = heap_next (e))
    {
      if (heap_is_free (e))
	s = format (s, "index %4d, free\n", e - h->elts);
      else if (h->format_elt)
	s = format (s, "%U", h->format_elt, v, elt_data (v, e));
      else
	s = format (s, "index %4d, used\n", e - h->elts);
      i++;
      if (e == e1)
	break;
    }

  return s;
}

u8 *
format_heap (u8 * s, va_list * va)
{
  void *v = va_arg (*va, void *);
  uword verbose = va_arg (*va, uword);
  heap_header_t *h = heap_header (v);
  heap_header_t zero;

  clib_memset (&zero, 0, sizeof (zero));

  if (!v)
    h = &zero;

  {
    f64 elt_bytes = vec_len (v) * h->elt_bytes;
    f64 overhead_bytes = heap_bytes (v);

    s = format (s, "heap %p, %6d objects, size %.1fk + overhead %.1fk\n",
		v, h->used_count, elt_bytes / 1024,
		(overhead_bytes - elt_bytes) / 1024);
  }

  if (v && verbose)
    s = debug_elt (s, v, -1, -1);

  return s;
}

void
heap_validate (void *v)
{
  heap_header_t *h = heap_header (v);
  uword i, o, s;
  u8 *free_map;
  heap_elt_t *e, *n;

  uword used_count, total_size;
  uword free_count, free_size;

  ASSERT (h->used_count == clib_bitmap_count_set_bits (h->used_elt_bitmap));

  ASSERT (first (h)->prev == 0);
  ASSERT (last (h)->next == 0);

  /* Validate number of elements and size. */
  free_size = free_count = 0;
  for (i = 0; i < vec_len (h->free_lists); i++)
    {
      free_count += vec_len (h->free_lists[i]);
      for (o = 0; o < vec_len (h->free_lists[i]); o++)
	{
	  e = h->elts + h->free_lists[i][o];
	  s = heap_elt_size (v, e);
	  ASSERT (size_to_bin (s) == i);
	  ASSERT (heap_is_free (e));
	  free_size += s;
	}
    }

  {
    uword elt_free_size, elt_free_count;

    used_count = total_size = elt_free_size = elt_free_count = 0;
    for (e = first (h); 1; e = n)
      {
	int is_free = heap_is_free (e);
	used_count++;
	s = heap_elt_size (v, e);
	total_size += s;
	ASSERT (is_free ==
		!clib_bitmap_get (h->used_elt_bitmap, e - h->elts));
	if (is_free)
	  {
	    elt_free_count++;
	    elt_free_size += s;
	  }
	n = heap_next (e);
	if (e == n)
	  {
	    ASSERT (last (h) == n);
	    break;
	  }

	/* We should never have two free adjacent elements. */
	ASSERT (!(heap_is_free (e) && heap_is_free (n)));
      }

    ASSERT (free_count == elt_free_count);
    ASSERT (free_size == elt_free_size);
    ASSERT (used_count == h->used_count + free_count);
    ASSERT (total_size == vec_len (v));
  }

  free_map = vec_new (u8, used_count);

  e = first (h);
  for (i = o = 0; 1; i++)
    {
      ASSERT (heap_offset (e) == o);
      s = heap_elt_size (v, e);

      if (heap_is_free (e))
	{
	  uword fb, fi;

	  fi = get_free_elt (v, e, &fb);

	  ASSERT (fb < vec_len (h->free_lists));
	  ASSERT (fi < vec_len (h->free_lists[fb]));
	  ASSERT (h->free_lists[fb][fi] == e - h->elts);

	  ASSERT (!free_map[i]);
	  free_map[i] = 1;
	}

      n = heap_next (e);

      if (e == n)
	break;

      ASSERT (heap_prev (n) == e);

      o += s;
      e = n;
    }

  vec_free (free_map);
}

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
