/*
 * Copyright (c) 2016-2019 Cisco and/or its affiliates.
 * Copyright (c) 2019 Arm Limited
 * Copyright (c) 2010-2017 Intel Corporation and/or its affiliates.
 * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
 * Inspired from DPDK rte_ring.h (SPSC only) (derived from freebsd bufring.h).
 * 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.
 */

#include <svm/svm_fifo.h>
#include <svm/fifo_segment.h>
#include <vppinfra/cpu.h>

CLIB_MARCH_FN (svm_fifo_copy_to_chunk, void, svm_fifo_t * f,
	       svm_fifo_chunk_t * c, u32 tail_idx, const u8 * src, u32 len,
	       svm_fifo_chunk_t ** last)
{
  u32 n_chunk;

  ASSERT (f_pos_geq (tail_idx, c->start_byte)
	  && f_pos_lt (tail_idx, c->start_byte + c->length));

  tail_idx -= c->start_byte;
  n_chunk = c->length - tail_idx;
  if (n_chunk <= len)
    {
      u32 to_copy = len;
      clib_memcpy_fast (&c->data[tail_idx], src, n_chunk);
      c = c->next;
      while ((to_copy -= n_chunk))
	{
	  n_chunk = clib_min (c->length, to_copy);
	  clib_memcpy_fast (&c->data[0], src + (len - to_copy), n_chunk);
	  c = c->length <= to_copy ? c->next : c;
	}
      if (*last)
	*last = c;
    }
  else
    {
      clib_memcpy_fast (&c->data[tail_idx], src, len);
    }
}

CLIB_MARCH_FN (svm_fifo_copy_from_chunk, void, svm_fifo_t * f,
	       svm_fifo_chunk_t * c, u32 head_idx, u8 * dst, u32 len,
	       svm_fifo_chunk_t ** last)
{
  u32 n_chunk;

  ASSERT (f_pos_geq (head_idx, c->start_byte)
	  && f_pos_lt (head_idx, c->start_byte + c->length));

  head_idx -= c->start_byte;
  n_chunk = c->length - head_idx;
  if (n_chunk <= len)
    {
      u32 to_copy = len;
      clib_memcpy_fast (dst, &c->data[head_idx], n_chunk);
      c = c->next;
      while ((to_copy -= n_chunk))
	{
	  n_chunk = clib_min (c->length, to_copy);
	  clib_memcpy_fast (dst + (len - to_copy), &c->data[0], n_chunk);
	  c = c->length <= to_copy ? c->next : c;
	}
      if (*last)
	*last = c;
    }
  else
    {
      clib_memcpy_fast (dst, &c->data[head_idx], len);
    }
}

#ifndef CLIB_MARCH_VARIANT

static inline void
svm_fifo_copy_to_chunk (svm_fifo_t * f, svm_fifo_chunk_t * c, u32 tail_idx,
			const u8 * src, u32 len, svm_fifo_chunk_t ** last)
{
  CLIB_MARCH_FN_SELECT (svm_fifo_copy_to_chunk) (f, c, tail_idx, src, len,
						 last);
}

static inline void
svm_fifo_copy_from_chunk (svm_fifo_t * f, svm_fifo_chunk_t * c, u32 head_idx,
			  u8 * dst, u32 len, svm_fifo_chunk_t ** last)
{
  CLIB_MARCH_FN_SELECT (svm_fifo_copy_from_chunk) (f, c, head_idx, dst, len,
						   last);
}

static inline u32
ooo_segment_end_pos (ooo_segment_t * s)
{
  return (s->start + s->length);
}

void
svm_fifo_free_ooo_data (svm_fifo_t * f)
{
  pool_free (f->ooo_segments);
}

static inline ooo_segment_t *
ooo_segment_prev (svm_fifo_t * f, ooo_segment_t * s)
{
  if (s->prev == OOO_SEGMENT_INVALID_INDEX)
    return 0;
  return pool_elt_at_index (f->ooo_segments, s->prev);
}

static inline ooo_segment_t *
ooo_segment_next (svm_fifo_t * f, ooo_segment_t * s)
{
  if (s->next == OOO_SEGMENT_INVALID_INDEX)
    return 0;
  return pool_elt_at_index (f->ooo_segments, s->next);
}

static inline ooo_segment_t *
ooo_segment_alloc (svm_fifo_t * f, u32 start, u32 length)
{
  ooo_segment_t *s;

  pool_get (f->ooo_segments, s);

  s->start = start;
  s->length = length;
  s->prev = s->next = OOO_SEGMENT_INVALID_INDEX;

  return s;
}

static inline void
ooo_segment_free (svm_fifo_t * f, u32 index)
{
  ooo_segment_t *cur, *prev = 0, *next = 0;
  cur = pool_elt_at_index (f->ooo_segments, index);

  if (cur->next != OOO_SEGMENT_INVALID_INDEX)
    {
      next = pool_elt_at_index (f->ooo_segments, cur->next);
      next->prev = cur->prev;
    }

  if (cur->prev != OOO_SEGMENT_INVALID_INDEX)
    {
      prev = pool_elt_at_index (f->ooo_segments, cur->prev);
      prev->next = cur->next;
    }
  else
    {
      f->ooos_list_head = cur->next;
    }

  pool_put (f->ooo_segments, cur);
}

/**
 * Add segment to fifo's out-of-order segment list. Takes care of merging
 * adjacent segments and removing overlapping ones.
 */
static void
ooo_segment_add (svm_fifo_t * f, u32 offset, u32 head, u32 tail, u32 length)
{
  ooo_segment_t *s, *new_s, *prev, *next, *it;
  u32 new_index, s_end_pos, s_index;
  u32 offset_pos, offset_end_pos;

  ASSERT (offset + length <= f_free_count (f, head, tail));

  offset_pos = tail + offset;
  offset_end_pos = tail + offset + length;

  f->ooos_newest = OOO_SEGMENT_INVALID_INDEX;

  if (f->ooos_list_head == OOO_SEGMENT_INVALID_INDEX)
    {
      s = ooo_segment_alloc (f, offset_pos, length);
      f->ooos_list_head = s - f->ooo_segments;
      f->ooos_newest = f->ooos_list_head;
      return;
    }

  /* Find first segment that starts after new segment */
  s = pool_elt_at_index (f->ooo_segments, f->ooos_list_head);
  while (s->next != OOO_SEGMENT_INVALID_INDEX
	 && f_pos_lt (s->start, offset_pos))
    s = pool_elt_at_index (f->ooo_segments, s->next);

  /* If we have a previous and we overlap it, use it as starting point */
  prev = ooo_segment_prev (f, s);
  if (prev && f_pos_leq (offset_pos, ooo_segment_end_pos (prev)))
    {
      s = prev;
      s_end_pos = ooo_segment_end_pos (s);

      /* Since we have previous, offset start position cannot be smaller
       * than prev->start. Check tail */
      ASSERT (f_pos_lt (s->start, offset_pos));
      goto check_tail;
    }

  s_index = s - f->ooo_segments;
  s_end_pos = ooo_segment_end_pos (s);

  /* No overlap, add before current segment */
  if (f_pos_lt (offset_end_pos, s->start))
    {
      new_s = ooo_segment_alloc (f, offset_pos, length);
      new_index = new_s - f->ooo_segments;

      /* Pool might've moved, get segment again */
      s = pool_elt_at_index (f->ooo_segments, s_index);
      if (s->prev != OOO_SEGMENT_INVALID_INDEX)
	{
	  new_s->prev = s->prev;
	  prev = pool_elt_at_index (f->ooo_segments, new_s->prev);
	  prev->next = new_index;
	}
      else
	{
	  /* New head */
	  f->ooos_list_head = new_index;
	}

      new_s->next = s_index;
      s->prev = new_index;
      f->ooos_newest = new_index;
      return;
    }
  /* No overlap, add after current segment */
  else if (f_pos_gt (offset_pos, s_end_pos))
    {
      new_s = ooo_segment_alloc (f, offset_pos, length);
      new_index = new_s - f->ooo_segments;

      /* Pool might've moved, get segment again */
      s = pool_elt_at_index (f->ooo_segments, s_index);

      /* Needs to be last */
      ASSERT (s->next == OOO_SEGMENT_INVALID_INDEX);

      new_s->prev = s_index;
      s->next = new_index;
      f->ooos_newest = new_index;

      return;
    }

  /*
   * Merge needed
   */

  /* Merge at head */
  if (f_pos_lt (offset_pos, s->start))
    {
      s->start = offset_pos;
      s->length = s_end_pos - s->start;
      f->ooos_newest = s - f->ooo_segments;
    }

check_tail:

  /* Overlapping tail */
  if (f_pos_gt (offset_end_pos, s_end_pos))
    {
      s->length = offset_end_pos - s->start;

      /* Remove the completely overlapped segments in the tail */
      it = ooo_segment_next (f, s);
      while (it && f_pos_leq (ooo_segment_end_pos (it), offset_end_pos))
	{
	  next = ooo_segment_next (f, it);
	  ooo_segment_free (f, it - f->ooo_segments);
	  it = next;
	}

      /* If partial overlap with last, merge */
      if (it && f_pos_leq (it->start, offset_end_pos))
	{
	  s->length = ooo_segment_end_pos (it) - s->start;
	  ooo_segment_free (f, it - f->ooo_segments);
	}
      f->ooos_newest = s - f->ooo_segments;
    }
}

/**
 * Removes segments that can now be enqueued because the fifo's tail has
 * advanced. Returns the number of bytes added to tail.
 */
static int
ooo_segment_try_collect (svm_fifo_t * f, u32 n_bytes_enqueued, u32 * tail)
{
  u32 s_index, bytes = 0;
  ooo_segment_t *s;
  i32 diff;

  s = pool_elt_at_index (f->ooo_segments, f->ooos_list_head);
  diff = *tail - s->start;

  ASSERT (diff != n_bytes_enqueued);

  if (diff > n_bytes_enqueued)
    return 0;

  /* If last tail update overlaps one/multiple ooo segments, remove them */
  while (0 <= diff && diff < n_bytes_enqueued)
    {
      s_index = s - f->ooo_segments;

      /* Segment end is beyond the tail. Advance tail and remove segment */
      if (s->length > diff)
	{
	  bytes = s->length - diff;
	  *tail = *tail + bytes;
	  ooo_segment_free (f, s_index);
	  break;
	}

      /* If we have next go on */
      if (s->next != OOO_SEGMENT_INVALID_INDEX)
	{
	  s = pool_elt_at_index (f->ooo_segments, s->next);
	  diff = *tail - s->start;
	  ooo_segment_free (f, s_index);
	}
      /* End of search */
      else
	{
	  ooo_segment_free (f, s_index);
	  break;
	}
    }

  ASSERT (bytes <= f->size);
  return bytes;
}

__clib_unused static ooo_segment_t *
ooo_segment_last (svm_fifo_t * f)
{
  ooo_segment_t *s;

  if (f->ooos_list_head == OOO_SEGMENT_INVALID_INDEX)
    return 0;

  s = svm_fifo_first_ooo_segment (f);
  while (s->next != OOO_SEGMENT_INVALID_INDEX)
    s = pool_elt_at_index (f->ooo_segments, s->next);
  return s;
}

void
svm_fifo_init (svm_fifo_t * f, u32 size)
{
  svm_fifo_chunk_t *c, *prev;
  u32 min_alloc;

  f->size = size;
  f->ooos_list_head = OOO_SEGMENT_INVALID_INDEX;
  f->segment_index = SVM_FIFO_INVALID_INDEX;
  f->refcnt = 1;
  f->head = f->tail = f->flags = 0;
  f->head_chunk = f->tail_chunk = f->start_chunk;
  f->ooo_deq = f->ooo_enq = 0;

  min_alloc = size > 32 << 10 ? size >> 3 : 4096;
  min_alloc = clib_min (min_alloc, 64 << 10);
  f->min_alloc = min_alloc;

  /*
   * Initialize chunks
   */
  f->start_chunk->start_byte = 0;
  prev = f->start_chunk;
  c = prev->next;

  while (c)
    {
      c->start_byte = prev->start_byte + prev->length;
      prev = c;
      c = c->next;
    }
}

void
svm_fifo_init_ooo_lookup (svm_fifo_t * f, u8 ooo_type)
{
  if (ooo_type == 0)
    {
      ASSERT (!rb_tree_is_init (&f->ooo_enq_lookup));
      rb_tree_init (&f->ooo_enq_lookup);
    }
  else
    {
      ASSERT (!rb_tree_is_init (&f->ooo_deq_lookup));
      rb_tree_init (&f->ooo_deq_lookup);
    }
}

/**
 * Creates a fifo in the current heap. Fails vs blow up the process
 */
svm_fifo_t *
svm_fifo_alloc (u32 data_size_in_bytes)
{
  u32 rounded_data_size;
  svm_fifo_chunk_t *c;
  svm_fifo_t *f;

  f = clib_mem_alloc_aligned_or_null (sizeof (*f), CLIB_CACHE_LINE_BYTES);
  if (f == 0)
    return 0;

  clib_memset (f, 0, sizeof (*f));

  /* always round fifo data size to the next highest power-of-two */
  rounded_data_size = (1 << (max_log2 (data_size_in_bytes)));
  c = clib_mem_alloc_aligned_or_null (sizeof (*c) + rounded_data_size,
				      CLIB_CACHE_LINE_BYTES);
  if (!c)
    {
      clib_mem_free (f);
      return 0;
    }

  clib_memset (c, 0, sizeof (*c));
  c->start_byte = 0;
  c->length = data_size_in_bytes;
  c->enq_rb_index = RBTREE_TNIL_INDEX;
  c->deq_rb_index = RBTREE_TNIL_INDEX;
  f->start_chunk = f->end_chunk = c;

  return f;
}

/**
 * Creates a fifo chunk in the current heap
 */
svm_fifo_chunk_t *
svm_fifo_chunk_alloc (u32 size)
{
  svm_fifo_chunk_t *c;
  u32 rounded_size;

  /* round chunk size to the next highest power-of-two */
  rounded_size = (1 << (max_log2 (size)));
  c = clib_mem_alloc_aligned_or_null (sizeof (*c) + rounded_size,
				      CLIB_CACHE_LINE_BYTES);
  if (c == 0)
    return 0;

  clib_memset (c, 0, sizeof (*c));
  c->length = rounded_size;
  return c;
}

/**
 * Find chunk for given byte position
 *
 * @param f	fifo
 * @param pos	normalized position in fifo
 *
 * @return chunk that includes given position or 0
 */
static svm_fifo_chunk_t *
svm_fifo_find_chunk (svm_fifo_t * f, u32 pos)
{
  svm_fifo_chunk_t *c;

  c = f->start_chunk;
  while (c && !f_chunk_includes_pos (c, pos))
    c = c->next;

  return c;
}

static svm_fifo_chunk_t *
svm_fifo_find_next_chunk (svm_fifo_t * f, svm_fifo_chunk_t * start, u32 pos)
{
  svm_fifo_chunk_t *c;

  ASSERT (start != 0);

  c = start;
  while (c && !f_chunk_includes_pos (c, pos))
    c = c->next;

  return c;
}

u32
svm_fifo_max_read_chunk (svm_fifo_t * f)
{
  u32 head, tail, end_chunk;

  f_load_head_tail_cons (f, &head, &tail);
  ASSERT (!f->head_chunk || f_chunk_includes_pos (f->head_chunk, head));

  if (!f->head_chunk)
    {
      f->head_chunk = svm_fifo_find_chunk (f, head);
      if (PREDICT_FALSE (!f->head_chunk))
	return 0;
    }

  end_chunk = f_chunk_end (f->head_chunk);

  return f_pos_lt (end_chunk, tail) ? end_chunk - head : tail - head;
}

u32
svm_fifo_max_write_chunk (svm_fifo_t * f)
{
  u32 head, tail;

  f_load_head_tail_prod (f, &head, &tail);
  ASSERT (!f->tail_chunk || f_chunk_includes_pos (f->tail_chunk, tail));

  return f->tail_chunk ? f_chunk_end (f->tail_chunk) - tail : 0;
}

static rb_node_t *
f_find_node_rbtree (rb_tree_t * rt, u32 pos)
{
  rb_node_t *cur, *prev;

  cur = rb_node (rt, rt->root);
  if (PREDICT_FALSE (rb_node_is_tnil (rt, cur)))
    return 0;

  while (pos != cur->key)
    {
      prev = cur;
      if (f_pos_lt (pos, cur->key))
	{
	  cur = rb_node_left (rt, cur);
	  if (rb_node_is_tnil (rt, cur))
	    {
	      cur = rb_tree_predecessor (rt, prev);
	      break;
	    }
	}
      else
	{
	  cur = rb_node_right (rt, cur);
	  if (rb_node_is_tnil (rt, cur))
	    {
	      cur = prev;
	      break;
	    }
	}
    }

  if (rb_node_is_tnil (rt, cur))
    return 0;

  return cur;
}

static svm_fifo_chunk_t *
f_find_chunk_rbtree (rb_tree_t * rt, u32 pos)
{
  svm_fifo_chunk_t *c;
  rb_node_t *n;

  if (!rb_tree_is_init (rt))
    return 0;

  n = f_find_node_rbtree (rt, pos);
  if (!n)
    return 0;
  c = uword_to_pointer (n->opaque, svm_fifo_chunk_t *);
  if (f_chunk_includes_pos (c, pos))
    return c;

  return 0;
}

static void
f_update_ooo_enq (svm_fifo_t * f, u32 start_pos, u32 end_pos)
{
  rb_tree_t *rt = &f->ooo_enq_lookup;
  svm_fifo_chunk_t *c;
  rb_node_t *cur;

  /* Use linear search if rbtree is not initialized */
  if (PREDICT_FALSE (!rb_tree_is_init (rt)))
    {
      f->ooo_enq = svm_fifo_find_next_chunk (f, f->tail_chunk, start_pos);
      return;
    }

  if (rt->root == RBTREE_TNIL_INDEX)
    {
      c = f->tail_chunk;
      ASSERT (c->enq_rb_index == RBTREE_TNIL_INDEX);
      c->enq_rb_index = rb_tree_add_custom (rt, c->start_byte,
					    pointer_to_uword (c), f_pos_lt);
    }
  else
    {
      cur = f_find_node_rbtree (rt, start_pos);
      c = uword_to_pointer (cur->opaque, svm_fifo_chunk_t *);
      ASSERT (f_pos_leq (c->start_byte, start_pos));
    }

  if (f_chunk_includes_pos (c, start_pos))
    f->ooo_enq = c;

  if (f_chunk_includes_pos (c, end_pos))
    return;

  do
    {
      c = c->next;
      if (!c || c->enq_rb_index != RBTREE_TNIL_INDEX)
	break;

      c->enq_rb_index = rb_tree_add_custom (rt, c->start_byte,
					    pointer_to_uword (c), f_pos_lt);

      if (f_chunk_includes_pos (c, start_pos))
	f->ooo_enq = c;
    }
  while (!f_chunk_includes_pos (c, end_pos));
}

static void
f_update_ooo_deq (svm_fifo_t * f, u32 start_pos, u32 end_pos)
{
  rb_tree_t *rt = &f->ooo_deq_lookup;
  rb_node_t *cur;
  svm_fifo_chunk_t *c;

  /* Use linear search if rbtree is not initialized  */
  if (PREDICT_FALSE (!rb_tree_is_init (rt)))
    {
      f->ooo_deq = svm_fifo_find_chunk (f, start_pos);
      return;
    }

  if (rt->root == RBTREE_TNIL_INDEX)
    {
      c = f->start_chunk;
      ASSERT (c->deq_rb_index == RBTREE_TNIL_INDEX);
      c->deq_rb_index = rb_tree_add_custom (rt, c->start_byte,
					    pointer_to_uword (c), f_pos_lt);
    }
  else
    {
      cur = f_find_node_rbtree (rt, start_pos);
      c = uword_to_pointer (cur->opaque, svm_fifo_chunk_t *);
      ASSERT (f_pos_leq (c->start_byte, start_pos));
    }

  if (f_chunk_includes_pos (c, start_pos))
    f->ooo_deq = c;

  if (f_chunk_includes_pos (c, end_pos))
    return;

  do
    {
      c = c->next;
      if (!c || c->deq_rb_index != RBTREE_TNIL_INDEX)
	break;

      c->deq_rb_index = rb_tree_add_custom (rt, c->start_byte,
					    pointer_to_uword (c), f_pos_lt);

      if (f_chunk_includes_pos (c, start_pos))
	f->ooo_deq = c;
    }
  while (!f_chunk_includes_pos (c, end_pos));
}

static svm_fifo_chunk_t *
f_lookup_clear_enq_chunks (svm_fifo_t * f, svm_fifo_chunk_t * start,
			   u32 end_pos)
{
  rb_tree_t *rt = &f->ooo_enq_lookup;
  svm_fifo_chunk_t *c;
  rb_node_t *n;

  c = start;
  while (c && !f_chunk_includes_pos (c, end_pos))
    {
      if (c->enq_rb_index != RBTREE_TNIL_INDEX)
	{
	  n = rb_node (rt, c->enq_rb_index);
	  rb_tree_del_node (rt, n);
	  c->enq_rb_index = RBTREE_TNIL_INDEX;
	}

      c = c->next;
    }

  /* No ooo segments left, so make sure the current chunk
   * is not tracked in the enq rbtree */
  if (f->ooos_list_head == OOO_SEGMENT_INVALID_INDEX
      && c && c->enq_rb_index != RBTREE_TNIL_INDEX)
    {
      n = rb_node (rt, c->enq_rb_index);
      rb_tree_del_node (rt, n);
      c->enq_rb_index = RBTREE_TNIL_INDEX;
    }

  return c;
}

static svm_fifo_chunk_t *
f_lookup_clear_deq_chunks (svm_fifo_t * f, svm_fifo_chunk_t * start,
			   u32 end_pos)
{
  rb_tree_t *rt = &f->ooo_deq_lookup;
  svm_fifo_chunk_t *c;
  rb_node_t *n;

  c = start;
  while (c && !f_chunk_includes_pos (c, end_pos))
    {
      if (c->deq_rb_index != RBTREE_TNIL_INDEX)
	{
	  n = rb_node (rt, c->deq_rb_index);
	  rb_tree_del_node (rt, n);
	  c->deq_rb_index = RBTREE_TNIL_INDEX;
	}

      c = c->next;
    }

  return c;
}

void
svm_fifo_free_chunk_lookup (svm_fifo_t * f)
{
  rb_tree_free_nodes (&f->ooo_enq_lookup);
  rb_tree_free_nodes (&f->ooo_deq_lookup);
}

void
svm_fifo_free (svm_fifo_t * f)
{
  ASSERT (f->refcnt > 0);

  if (--f->refcnt == 0)
    {
      /* ooo data is not allocated on segment heap */
      svm_fifo_free_chunk_lookup (f);
      clib_mem_free (f);
    }
}

void
svm_fifo_overwrite_head (svm_fifo_t * f, u8 * src, u32 len)
{
  u32 n_chunk;
  u32 head, tail, head_idx;
  svm_fifo_chunk_t *c;

  ASSERT (len <= f->size);

  f_load_head_tail_cons (f, &head, &tail);

  if (!f->head_chunk)
    f->head_chunk = svm_fifo_find_chunk (f, head);

  c = f->head_chunk;
  head_idx = head - c->start_byte;
  n_chunk = c->length - head_idx;
  if (len <= n_chunk)
    clib_memcpy_fast (&c->data[head_idx], src, len);
  else
    {
      ASSERT (len - n_chunk <= c->next->length);
      clib_memcpy_fast (&c->data[head_idx], src, n_chunk);
      clib_memcpy_fast (&c->next->data[0], src + n_chunk, len - n_chunk);
    }
}

static int
f_try_chunk_alloc (svm_fifo_t * f, u32 head, u32 tail, u32 len)
{
  svm_fifo_chunk_t *c, *cur, *prev;
  u32 alloc_size, free_alloced;

  free_alloced = f_chunk_end (f->end_chunk) - tail;

  alloc_size = clib_min (f->min_alloc, f->size - (tail - head));
  alloc_size = clib_max (alloc_size, len - free_alloced);

  c = fsh_alloc_chunk (f->fs_hdr, f->slice_index, alloc_size);
  if (PREDICT_FALSE (!c))
    return -1;

  cur = c;
  prev = f->end_chunk;

  while (cur)
    {
      cur->start_byte = prev->start_byte + prev->length;
      cur->enq_rb_index = RBTREE_TNIL_INDEX;
      cur->deq_rb_index = RBTREE_TNIL_INDEX;

      prev = cur;
      cur = cur->next;
    }

  prev->next = 0;
  f->end_chunk->next = c;
  f->end_chunk = prev;

  if (!f->tail_chunk)
    f->tail_chunk = c;

  return 0;
}

int
svm_fifo_enqueue (svm_fifo_t * f, u32 len, const u8 * src)
{
  u32 tail, head, free_count;
  svm_fifo_chunk_t *old_tail_c;

  f->ooos_newest = OOO_SEGMENT_INVALID_INDEX;

  f_load_head_tail_prod (f, &head, &tail);

  /* free space in fifo can only increase during enqueue: SPSC */
  free_count = f_free_count (f, head, tail);

  if (PREDICT_FALSE (free_count == 0))
    return SVM_FIFO_EFULL;

  /* number of bytes we're going to copy */
  len = clib_min (free_count, len);

  if (f_pos_gt (tail + len, f_chunk_end (f->end_chunk)))
    {
      if (PREDICT_FALSE (f_try_chunk_alloc (f, head, tail, len)))
	{
	  len = f_chunk_end (f->end_chunk) - tail;
	  if (!len)
	    return SVM_FIFO_EGROW;
	}
    }

  old_tail_c = f->tail_chunk;

  svm_fifo_copy_to_chunk (f, f->tail_chunk, tail, src, len, &f->tail_chunk);
  tail = tail + len;

  svm_fifo_trace_add (f, head, len, 2);

  /* collect out-of-order segments */
  if (PREDICT_FALSE (f->ooos_list_head != OOO_SEGMENT_INVALID_INDEX))
    {
      len += ooo_segment_try_collect (f, len, &tail);
      /* Tail chunk might've changed even if nothing was collected */
      f->tail_chunk = f_lookup_clear_enq_chunks (f, old_tail_c, tail);
      f->ooo_enq = 0;
    }

  /* store-rel: producer owned index (paired with load-acq in consumer) */
  clib_atomic_store_rel_n (&f->tail, tail);

  return len;
}

/**
 * Enqueue a future segment.
 *
 * Two choices: either copies the entire segment, or copies nothing
 * Returns 0 of the entire segment was copied
 * Returns -1 if none of the segment was copied due to lack of space
 */
int
svm_fifo_enqueue_with_offset (svm_fifo_t * f, u32 offset, u32 len, u8 * src)
{
  u32 tail, head, free_count, enq_pos;

  f_load_head_tail_prod (f, &head, &tail);

  /* free space in fifo can only increase during enqueue: SPSC */
  free_count = f_free_count (f, head, tail);
  f->ooos_newest = OOO_SEGMENT_INVALID_INDEX;

  /* will this request fit? */
  if ((len + offset) > free_count)
    return SVM_FIFO_EFULL;

  enq_pos = tail + offset;

  if (f_pos_gt (enq_pos + len, f_chunk_end (f->end_chunk)))
    {
      if (PREDICT_FALSE (f_try_chunk_alloc (f, head, tail, offset + len)))
	return SVM_FIFO_EGROW;
    }

  svm_fifo_trace_add (f, offset, len, 1);
  ooo_segment_add (f, offset, head, tail, len);

  if (!f->ooo_enq || !f_chunk_includes_pos (f->ooo_enq, enq_pos))
    f_update_ooo_enq (f, enq_pos, enq_pos + len);

  svm_fifo_copy_to_chunk (f, f->ooo_enq, enq_pos, src, len, &f->ooo_enq);

  return 0;
}

/**
 * Advance tail
 */
void
svm_fifo_enqueue_nocopy (svm_fifo_t * f, u32 len)
{
  u32 tail;

  ASSERT (len <= svm_fifo_max_enqueue_prod (f));
  /* load-relaxed: producer owned index */
  tail = f->tail;
  tail = tail + len;

  if (rb_tree_is_init (&f->ooo_enq_lookup))
    {
      f->tail_chunk = f_lookup_clear_enq_chunks (f, f->tail_chunk, tail);
      f->ooo_enq = 0;
    }
  else
    {
      f->tail_chunk = svm_fifo_find_next_chunk (f, f->tail_chunk, tail);
    }

  /* store-rel: producer owned index (paired with load-acq in consumer) */
  clib_atomic_store_rel_n (&f->tail, tail);
}

always_inline svm_fifo_chunk_t *
f_unlink_chunks (svm_fifo_t * f, u32 end_pos, u8 maybe_ooo)
{
  svm_fifo_chunk_t *start, *prev = 0, *c;
  rb_tree_t *rt;
  rb_node_t *n;

  ASSERT (!f_chunk_includes_pos (f->start_chunk, end_pos));

  if (maybe_ooo)
    rt = &f->ooo_deq_lookup;

  c = f->start_chunk;

  do
    {
      if (maybe_ooo && c->deq_rb_index != RBTREE_TNIL_INDEX)
	{
	  n = rb_node (rt, c->deq_rb_index);
	  ASSERT (n == f_find_node_rbtree (rt, c->start_byte));
	  rb_tree_del_node (rt, n);
	  c->deq_rb_index = RBTREE_TNIL_INDEX;
	}
      if (!c->next)
	break;
      prev = c;
      c = c->next;
    }
  while (!f_chunk_includes_pos (c, end_pos));

  if (maybe_ooo)
    {
      if (f->ooo_deq && f_pos_lt (f->ooo_deq->start_byte, f_chunk_end (c)))
	f->ooo_deq = 0;
    }
  else
    {
      if (PREDICT_FALSE (f->ooo_deq != 0))
	f->ooo_deq = 0;
    }

  /* Avoid unlinking the last chunk */
  if (!prev)
    return 0;

  prev->next = 0;
  start = f->start_chunk;
  f->start_chunk = c;

  return start;
}

int
svm_fifo_dequeue (svm_fifo_t * f, u32 len, u8 * dst)
{
  u32 tail, head, cursize;

  f_load_head_tail_cons (f, &head, &tail);

  /* current size of fifo can only increase during dequeue: SPSC */
  cursize = f_cursize (f, head, tail);

  if (PREDICT_FALSE (cursize == 0))
    return SVM_FIFO_EEMPTY;

  len = clib_min (cursize, len);

  if (!f->head_chunk)
    f->head_chunk = svm_fifo_find_chunk (f, head);

  svm_fifo_copy_from_chunk (f, f->head_chunk, head, dst, len, &f->head_chunk);
  head = head + len;

  /* In order dequeues are not supported in combination with ooo peeking.
   * Use svm_fifo_dequeue_drop instead. */
  ASSERT (rb_tree_n_nodes (&f->ooo_deq_lookup) <= 1);

  if (f_pos_geq (head, f_chunk_end (f->start_chunk)))
    fsh_collect_chunks (f->fs_hdr, f->slice_index,
			f_unlink_chunks (f, head, 0));

  /* store-rel: consumer owned index (paired with load-acq in producer) */
  clib_atomic_store_rel_n (&f->head, head);

  return len;
}

int
svm_fifo_peek (svm_fifo_t * f, u32 offset, u32 len, u8 * dst)
{
  u32 tail, head, cursize, head_idx;

  f_load_head_tail_cons (f, &head, &tail);

  /* current size of fifo can only increase during peek: SPSC */
  cursize = f_cursize (f, head, tail);

  if (PREDICT_FALSE (cursize < offset))
    return SVM_FIFO_EEMPTY;

  len = clib_min (cursize - offset, len);
  head_idx = head + offset;

  if (!f->ooo_deq || !f_chunk_includes_pos (f->ooo_deq, head_idx))
    f_update_ooo_deq (f, head_idx, head_idx + len);

  svm_fifo_copy_from_chunk (f, f->ooo_deq, head_idx, dst, len, &f->ooo_deq);
  return len;
}

int
svm_fifo_dequeue_drop (svm_fifo_t * f, u32 len)
{
  u32 total_drop_bytes, tail, head, cursize;

  f_load_head_tail_cons (f, &head, &tail);

  /* number of bytes available */
  cursize = f_cursize (f, head, tail);
  if (PREDICT_FALSE (cursize == 0))
    return SVM_FIFO_EEMPTY;

  /* number of bytes we're going to drop */
  total_drop_bytes = clib_min (cursize, len);

  svm_fifo_trace_add (f, tail, total_drop_bytes, 3);

  /* move head */
  head = head + total_drop_bytes;

  if (f_pos_geq (head, f_chunk_end (f->start_chunk)))
    {
      fsh_collect_chunks (f->fs_hdr, f->slice_index,
			  f_unlink_chunks (f, head, 1));
      f->head_chunk =
	f_chunk_includes_pos (f->start_chunk, head) ? f->start_chunk : 0;
    }

  /* store-rel: consumer owned index (paired with load-acq in producer) */
  clib_atomic_store_rel_n (&f->head, head);

  return total_drop_bytes;
}

/**
 * Drop all data from fifo
 *
 */
void
svm_fifo_dequeue_drop_all (svm_fifo_t * f)
{
  u32 head, tail;

  f_load_head_tail_all_acq (f, &head, &tail);

  if (!f->head_chunk || !f_chunk_includes_pos (f->head_chunk, head))
    f->head_chunk = svm_fifo_find_chunk (f, head);

  f->head_chunk = f_lookup_clear_deq_chunks (f, f->head_chunk, tail);

  if (f_pos_geq (tail, f_chunk_end (f->start_chunk)))
    fsh_collect_chunks (f->fs_hdr, f->slice_index,
			f_unlink_chunks (f, tail, 0));

  /* store-rel: consumer owned index (paired with load-acq in producer) */
  clib_atomic_store_rel_n (&f->head, tail);
}

int
svm_fifo_fill_chunk_list (svm_fifo_t * f)
{
  u32 head, tail;

  f_load_head_tail_prod (f, &head, &tail);

  if (f_chunk_end (f->end_chunk) - head >= f->size)
    return 0;

  if (f_try_chunk_alloc (f, head, tail, f->size - (tail - head)))
    return SVM_FIFO_EGROW;

  return 0;
}

int
svm_fifo_segments (svm_fifo_t * f, svm_fifo_seg_t * fs)
{
  u32 cursize, head, tail, head_idx;

  f_load_head_tail_cons (f, &head, &tail);

  /* consumer function, cursize can only increase while we're working */
  cursize = f_cursize (f, head, tail);

  if (PREDICT_FALSE (cursize == 0))
    return SVM_FIFO_EEMPTY;

  head_idx = head;

  if (tail < head)
    {
      fs[0].len = f->size - head_idx;
      fs[0].data = f->head_chunk->data + head_idx;
      fs[1].len = cursize - fs[0].len;
      fs[1].data = f->head_chunk->data;
    }
  else
    {
      fs[0].len = cursize;
      fs[0].data = f->head_chunk->data + head_idx;
      fs[1].len = 0;
      fs[1].data = 0;
    }
  return cursize;
}

void
svm_fifo_segments_free (svm_fifo_t * f, svm_fifo_seg_t * fs)
{
  u32 head;

  /* consumer owned index */
  head = f->head;

  ASSERT (fs[0].data == f->head_chunk->data + head);
  head = (head + fs[0].len + fs[1].len);
  /* store-rel: consumer owned index (paired with load-acq in producer) */
  clib_atomic_store_rel_n (&f->head, head);
}

/**
 * Clones fifo
 *
 * Assumptions:
 * - no prod and cons are accessing either dest or src fifo
 * - fifo is not multi chunk
 */
void
svm_fifo_clone (svm_fifo_t * df, svm_fifo_t * sf)
{
  u32 head, tail;

  /* Support only single chunk clones for now */
  ASSERT (svm_fifo_n_chunks (sf) == 1);

  clib_memcpy_fast (df->head_chunk->data, sf->head_chunk->data, sf->size);

  f_load_head_tail_all_acq (sf, &head, &tail);
  clib_atomic_store_rel_n (&df->head, head);
  clib_atomic_store_rel_n (&df->tail, tail);
}

u32
svm_fifo_n_ooo_segments (svm_fifo_t * f)
{
  return pool_elts (f->ooo_segments);
}

ooo_segment_t *
svm_fifo_first_ooo_segment (svm_fifo_t * f)
{
  return pool_elt_at_index (f->ooo_segments, f->ooos_list_head);
}

/**
 * Set fifo pointers to requested offset
 */
void
svm_fifo_init_pointers (svm_fifo_t * f, u32 head, u32 tail)
{
  svm_fifo_chunk_t *c;

  clib_atomic_store_rel_n (&f->head, head);
  clib_atomic_store_rel_n (&f->tail, tail);

  c = svm_fifo_find_chunk (f, head);
  ASSERT (c != 0);
  f->head_chunk = f->ooo_deq = c;
  c = svm_fifo_find_chunk (f, tail);
  ASSERT (c != 0);
  f->tail_chunk = f->ooo_enq = c;
}

void
svm_fifo_add_subscriber (svm_fifo_t * f, u8 subscriber)
{
  if (f->n_subscribers >= SVM_FIFO_MAX_EVT_SUBSCRIBERS)
    return;
  f->subscribers[f->n_subscribers++] = subscriber;
}

void
svm_fifo_del_subscriber (svm_fifo_t * f, u8 subscriber)
{
  int i;

  for (i = 0; i < f->n_subscribers; i++)
    {
      if (f->subscribers[i] != subscriber)
	continue;
      f->subscribers[i] = f->subscribers[f->n_subscribers - 1];
      f->n_subscribers--;
      break;
    }
}

u8
svm_fifo_is_sane (svm_fifo_t * f)
{
  svm_fifo_chunk_t *tmp;

  if (f->head_chunk && !f_chunk_includes_pos (f->head_chunk, f->head))
    return 0;
  if (f->tail_chunk && !f_chunk_includes_pos (f->tail_chunk, f->tail))
    return 0;
  if (f->ooo_deq)
    {
      if (rb_tree_is_init (&f->ooo_deq_lookup))
	{
	  if (f_pos_lt (f->ooo_deq->start_byte, f->start_chunk->start_byte)
	      || f_pos_gt (f->ooo_deq->start_byte,
			   f_chunk_end (f->end_chunk)))
	    return 0;

	  tmp = f_find_chunk_rbtree (&f->ooo_deq_lookup,
				     f->ooo_deq->start_byte);
	}
      else
	tmp = svm_fifo_find_chunk (f, f->ooo_deq->start_byte);
      if (tmp != f->ooo_deq)
	return 0;
    }
  if (f->ooo_enq)
    {
      if (rb_tree_is_init (&f->ooo_enq_lookup))
	{
	  if (f_pos_lt (f->ooo_enq->start_byte, f->start_chunk->start_byte)
	      || f_pos_gt (f->ooo_enq->start_byte,
			   f_chunk_end (f->end_chunk)))
	    return 0;

	  tmp = f_find_chunk_rbtree (&f->ooo_enq_lookup,
				     f->ooo_enq->start_byte);
	}
      else
	{
	  tmp = svm_fifo_find_next_chunk (f, f->tail_chunk,
					  f->ooo_enq->start_byte);
	}
      if (tmp != f->ooo_enq)
	return 0;
    }

  if (f->start_chunk->next)
    {
      svm_fifo_chunk_t *c, *prev = 0, *tmp;
      u32 chunks_bytes = 0;

      c = f->start_chunk;
      do
	{
	  tmp = svm_fifo_find_chunk (f, c->start_byte);
	  if (tmp != c)
	    return 0;
	  if (prev && (prev->start_byte + prev->length != c->start_byte))
	    return 0;

	  if (c->enq_rb_index != RBTREE_TNIL_INDEX)
	    {
	      tmp = f_find_chunk_rbtree (&f->ooo_enq_lookup, c->start_byte);
	      if (tmp)
		{
		  if (tmp != c)
		    return 0;
		}
	    }
	  if (c->deq_rb_index != RBTREE_TNIL_INDEX)
	    {
	      tmp = f_find_chunk_rbtree (&f->ooo_deq_lookup, c->start_byte);
	      if (tmp)
		{
		  if (tmp != c)
		    return 0;
		}
	    }

	  chunks_bytes += c->length;
	  prev = c;
	  c = c->next;
	}
      while (c);

      if (chunks_bytes < f->tail - f->head)
	return 0;
    }

  return 1;
}

u32
svm_fifo_n_chunks (svm_fifo_t * f)
{
  svm_fifo_chunk_t *c;
  int n_chunks = 0;

  c = f->start_chunk;
  while (c)
    {
      n_chunks++;
      c = c->next;
    }

  return n_chunks;
}

u8 *
format_ooo_segment (u8 * s, va_list * args)
{
  svm_fifo_t __clib_unused *f = va_arg (*args, svm_fifo_t *);
  ooo_segment_t *seg = va_arg (*args, ooo_segment_t *);
  s = format (s, "[%u, %u], len %u, next %d, prev %d", seg->start,
	      seg->start + seg->length, seg->length, seg->next, seg->prev);
  return s;
}

u8 *
svm_fifo_dump_trace (u8 * s, svm_fifo_t * f)
{
#if SVM_FIFO_TRACE
  svm_fifo_trace_elem_t *seg = 0;
  int i = 0;

  if (f->trace)
    {
      vec_foreach (seg, f->trace)
      {
	s = format (s, "{%u, %u, %u}, ", seg->offset, seg->len, seg->action);
	i++;
	if (i % 5 == 0)
	  s = format (s, "\n");
      }
      s = format (s, "\n");
    }
  return s;
#else
  return 0;
#endif
}

u8 *
svm_fifo_replay (u8 * s, svm_fifo_t * f, u8 no_read, u8 verbose)
{
  int i, trace_len;
  u8 *data = 0;
  svm_fifo_trace_elem_t *trace;
  u32 offset;
  svm_fifo_t *placeholder_fifo;

  if (!f)
    return s;

#if SVM_FIFO_TRACE
  trace = f->trace;
  trace_len = vec_len (trace);
#else
  trace = 0;
  trace_len = 0;
#endif

  placeholder_fifo = svm_fifo_alloc (f->size);
  svm_fifo_init (f, f->size);
  clib_memset (f->head_chunk->data, 0xFF, f->size);
  vec_validate (data, f->size);
  for (i = 0; i < vec_len (data); i++)
    data[i] = i;

  for (i = 0; i < trace_len; i++)
    {
      offset = trace[i].offset;
      if (trace[i].action == 1)
	{
	  if (verbose)
	    s = format (s, "adding [%u, %u]:", trace[i].offset,
			(trace[i].offset + trace[i].len));
	  svm_fifo_enqueue_with_offset (placeholder_fifo, trace[i].offset,
					trace[i].len, &data[offset]);
	}
      else if (trace[i].action == 2)
	{
	  if (verbose)
	    s = format (s, "adding [%u, %u]:", 0, trace[i].len);
	  svm_fifo_enqueue (placeholder_fifo, trace[i].len, &data[offset]);
	}
      else if (!no_read)
	{
	  if (verbose)
	    s = format (s, "read: %u", trace[i].len);
	  svm_fifo_dequeue_drop (placeholder_fifo, trace[i].len);
	}
      if (verbose)
	s = format (s, "%U", format_svm_fifo, placeholder_fifo, 1);
    }

  s = format (s, "result: %U", format_svm_fifo, placeholder_fifo, 1);

  return s;
}

u8 *
format_ooo_list (u8 * s, va_list * args)
{
  svm_fifo_t *f = va_arg (*args, svm_fifo_t *);
  u32 indent = va_arg (*args, u32);
  u32 ooo_segment_index = f->ooos_list_head;
  ooo_segment_t *seg;

  while (ooo_segment_index != OOO_SEGMENT_INVALID_INDEX)
    {
      seg = pool_elt_at_index (f->ooo_segments, ooo_segment_index);
      s = format (s, "%U%U\n", format_white_space, indent, format_ooo_segment,
		  f, seg);
      ooo_segment_index = seg->next;
    }

  return s;
}

u8 *
format_svm_fifo (u8 * s, va_list * args)
{
  svm_fifo_t *f = va_arg (*args, svm_fifo_t *);
  int verbose = va_arg (*args, int);
  u32 indent;

  if (!s)
    return s;

  indent = format_get_indent (s);
  s = format (s, "cursize %u nitems %u has_event %d min_alloc %u\n",
	      svm_fifo_max_dequeue (f), f->size, f->has_event, f->min_alloc);
  s = format (s, "%Uhead %u tail %u segment manager %u\n", format_white_space,
	      indent, f->head, f->tail, f->segment_manager);

  if (verbose > 1)
    s = format (s, "%Uvpp session %d thread %d app session %d thread %d\n",
		format_white_space, indent, f->master_session_index,
		f->master_thread_index, f->client_session_index,
		f->client_thread_index);

  if (verbose)
    {
      s = format (s, "%Uooo pool %d active elts newest %u\n",
		  format_white_space, indent, pool_elts (f->ooo_segments),
		  f->ooos_newest);
      if (svm_fifo_has_ooo_data (f))
	s = format (s, " %U", format_ooo_list, f, indent, verbose);
    }
  return s;
}

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