/*
 * 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);
}

__clib_export 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;
}

__clib_export 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);
}

__clib_export 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));
}

__clib_export 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;
}

__clib_export 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;
}

__clib_export 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:
 */
