/*
 * Copyright (c) 2018 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.
 */

#include <svm/message_queue.h>
#include <vppinfra/mem.h>
#include <vppinfra/format.h>
#include <vppinfra/time.h>
#include <sys/eventfd.h>
#include <sys/socket.h>

static inline svm_msg_q_ring_t *
svm_msg_q_ring_inline (svm_msg_q_t * mq, u32 ring_index)
{
  return vec_elt_at_index (mq->rings, ring_index);
}

svm_msg_q_ring_t *
svm_msg_q_ring (svm_msg_q_t * mq, u32 ring_index)
{
  return svm_msg_q_ring_inline (mq, ring_index);
}

static inline void *
svm_msg_q_ring_data (svm_msg_q_ring_t * ring, u32 elt_index)
{
  ASSERT (elt_index < ring->nitems);
  return (ring->shr->data + elt_index * ring->elsize);
}

static void
svm_msg_q_init_mutex (svm_msg_q_shared_queue_t *sq)
{
  pthread_mutexattr_t attr;
  pthread_condattr_t cattr;

  clib_memset (&attr, 0, sizeof (attr));
  clib_memset (&cattr, 0, sizeof (cattr));

  if (pthread_mutexattr_init (&attr))
    clib_unix_warning ("mutexattr_init");
  if (pthread_mutexattr_setpshared (&attr, PTHREAD_PROCESS_SHARED))
    clib_unix_warning ("pthread_mutexattr_setpshared");
  if (pthread_mutexattr_setrobust (&attr, PTHREAD_MUTEX_ROBUST))
    clib_unix_warning ("setrobust");
  if (pthread_mutex_init (&sq->mutex, &attr))
    clib_unix_warning ("mutex_init");
  if (pthread_mutexattr_destroy (&attr))
    clib_unix_warning ("mutexattr_destroy");
  if (pthread_condattr_init (&cattr))
    clib_unix_warning ("condattr_init");
  if (pthread_condattr_setpshared (&cattr, PTHREAD_PROCESS_SHARED))
    clib_unix_warning ("condattr_setpshared");
  if (pthread_cond_init (&sq->condvar, &cattr))
    clib_unix_warning ("cond_init1");
  if (pthread_condattr_destroy (&cattr))
    clib_unix_warning ("cond_init2");
}

svm_msg_q_shared_t *
svm_msg_q_init (void *base, svm_msg_q_cfg_t *cfg)
{
  svm_msg_q_ring_shared_t *ring;
  svm_msg_q_shared_queue_t *sq;
  svm_msg_q_shared_t *smq;
  u32 q_sz, offset;
  int i;

  q_sz = sizeof (*sq) + cfg->q_nitems * sizeof (svm_msg_q_msg_t);

  smq = (svm_msg_q_shared_t *) base;
  sq = smq->q;
  clib_memset (sq, 0, sizeof (*sq));
  sq->elsize = sizeof (svm_msg_q_msg_t);
  sq->maxsize = cfg->q_nitems;
  smq->n_rings = cfg->n_rings;
  ring = (void *) ((u8 *) smq->q + q_sz);
  for (i = 0; i < cfg->n_rings; i++)
    {
      ring->elsize = cfg->ring_cfgs[i].elsize;
      ring->nitems = cfg->ring_cfgs[i].nitems;
      ring->cursize = ring->head = ring->tail = 0;
      offset = sizeof (*ring) + ring->nitems * ring->elsize;
      ring = (void *) ((u8 *) ring + offset);
    }

  svm_msg_q_init_mutex (sq);

  return smq;
}

uword
svm_msg_q_size_to_alloc (svm_msg_q_cfg_t *cfg)
{
  svm_msg_q_ring_cfg_t *ring_cfg;
  uword rings_sz = 0, mq_sz;
  u32 q_sz;
  int i;

  ASSERT (cfg);

  rings_sz = sizeof (svm_msg_q_ring_shared_t) * cfg->n_rings;
  for (i = 0; i < cfg->n_rings; i++)
    {
      if (cfg->ring_cfgs[i].data)
	continue;
      ring_cfg = &cfg->ring_cfgs[i];
      rings_sz += (uword) ring_cfg->nitems * ring_cfg->elsize;
    }

  q_sz = sizeof (svm_msg_q_shared_queue_t) +
	 cfg->q_nitems * sizeof (svm_msg_q_msg_t);
  mq_sz = sizeof (svm_msg_q_shared_t) + q_sz + rings_sz;

  return mq_sz;
}

svm_msg_q_shared_t *
svm_msg_q_alloc (svm_msg_q_cfg_t *cfg)
{
  uword mq_sz;
  u8 *base;

  mq_sz = svm_msg_q_size_to_alloc (cfg);
  base = clib_mem_alloc_aligned (mq_sz, CLIB_CACHE_LINE_BYTES);
  if (!base)
    return 0;

  return svm_msg_q_init (base, cfg);
}

void
svm_msg_q_attach (svm_msg_q_t *mq, void *smq_base)
{
  svm_msg_q_ring_shared_t *ring;
  svm_msg_q_shared_t *smq;
  u32 i, n_rings, q_sz, offset;

  smq = (svm_msg_q_shared_t *) smq_base;
  mq->q.shr = smq->q;
  mq->q.evtfd = -1;
  n_rings = smq->n_rings;
  vec_validate (mq->rings, n_rings - 1);
  q_sz = sizeof (svm_msg_q_shared_queue_t) +
	 mq->q.shr->maxsize * sizeof (svm_msg_q_msg_t);
  ring = (void *) ((u8 *) smq->q + q_sz);
  for (i = 0; i < n_rings; i++)
    {
      mq->rings[i].nitems = ring->nitems;
      mq->rings[i].elsize = ring->elsize;
      mq->rings[i].shr = ring;
      offset = sizeof (*ring) + ring->nitems * ring->elsize;
      ring = (void *) ((u8 *) ring + offset);
    }
  clib_spinlock_init (&mq->q.lock);
}

void
svm_msg_q_cleanup (svm_msg_q_t *mq)
{
  vec_free (mq->rings);
  clib_spinlock_free (&mq->q.lock);
  if (mq->q.evtfd != -1)
    close (mq->q.evtfd);
}

void
svm_msg_q_free (svm_msg_q_t * mq)
{
  svm_msg_q_cleanup (mq);
  clib_mem_free (mq->q.shr);
  clib_mem_free (mq);
}

static void
svm_msg_q_send_signal (svm_msg_q_t *mq, u8 is_consumer)
{
  if (mq->q.evtfd == -1)
    {
      if (is_consumer)
	{
	  int rv = pthread_mutex_lock (&mq->q.shr->mutex);
	  if (PREDICT_FALSE (rv == EOWNERDEAD))
	    {
	      rv = pthread_mutex_consistent (&mq->q.shr->mutex);
	      return;
	    }
	}

      (void) pthread_cond_broadcast (&mq->q.shr->condvar);

      if (is_consumer)
	pthread_mutex_unlock (&mq->q.shr->mutex);
    }
  else
    {
      int __clib_unused rv;
      u64 data = 1;

      if (mq->q.evtfd < 0)
	return;

      rv = write (mq->q.evtfd, &data, sizeof (data));
      if (PREDICT_FALSE (rv < 0))
	clib_unix_warning ("signal write on %d returned %d", mq->q.evtfd, rv);
    }
}

svm_msg_q_msg_t
svm_msg_q_alloc_msg_w_ring (svm_msg_q_t * mq, u32 ring_index)
{
  svm_msg_q_ring_shared_t *sr;
  svm_msg_q_ring_t *ring;
  svm_msg_q_msg_t msg;

  ring = svm_msg_q_ring_inline (mq, ring_index);
  sr = ring->shr;

  ASSERT (sr->cursize < ring->nitems);
  msg.ring_index = ring - mq->rings;
  msg.elt_index = sr->tail;
  sr->tail = (sr->tail + 1) % ring->nitems;
  clib_atomic_fetch_add_rel (&sr->cursize, 1);
  return msg;
}

int
svm_msg_q_lock_and_alloc_msg_w_ring (svm_msg_q_t * mq, u32 ring_index,
				     u8 noblock, svm_msg_q_msg_t * msg)
{
  if (noblock)
    {
      if (svm_msg_q_try_lock (mq))
	return -1;
      if (PREDICT_FALSE (svm_msg_q_or_ring_is_full (mq, ring_index)))
	{
	  svm_msg_q_unlock (mq);
	  return -2;
	}
      *msg = svm_msg_q_alloc_msg_w_ring (mq, ring_index);
    }
  else
    {
      svm_msg_q_lock (mq);
      while (svm_msg_q_or_ring_is_full (mq, ring_index))
	svm_msg_q_or_ring_wait_prod (mq, ring_index);
      *msg = svm_msg_q_alloc_msg_w_ring (mq, ring_index);
    }
  return 0;
}

svm_msg_q_msg_t
svm_msg_q_alloc_msg (svm_msg_q_t * mq, u32 nbytes)
{
  svm_msg_q_msg_t msg = {.as_u64 = ~0 };
  svm_msg_q_ring_shared_t *sr;
  svm_msg_q_ring_t *ring;

  vec_foreach (ring, mq->rings)
  {
    sr = ring->shr;
    if (ring->elsize < nbytes || sr->cursize == ring->nitems)
      continue;
    msg.ring_index = ring - mq->rings;
    msg.elt_index = sr->tail;
    sr->tail = (sr->tail + 1) % ring->nitems;
    clib_atomic_fetch_add_relax (&sr->cursize, 1);
    break;
  }
  return msg;
}

void *
svm_msg_q_msg_data (svm_msg_q_t * mq, svm_msg_q_msg_t * msg)
{
  svm_msg_q_ring_t *ring = svm_msg_q_ring_inline (mq, msg->ring_index);
  return svm_msg_q_ring_data (ring, msg->elt_index);
}

void
svm_msg_q_free_msg (svm_msg_q_t * mq, svm_msg_q_msg_t * msg)
{
  svm_msg_q_ring_shared_t *sr;
  svm_msg_q_ring_t *ring;
  u32 need_signal;

  ASSERT (vec_len (mq->rings) > msg->ring_index);
  ring = svm_msg_q_ring_inline (mq, msg->ring_index);
  sr = ring->shr;
  if (msg->elt_index == sr->head)
    {
      sr->head = (sr->head + 1) % ring->nitems;
    }
  else
    {
      clib_warning ("message out of order: elt %u head %u ring %u",
		    msg->elt_index, sr->head, msg->ring_index);
      /* for now, expect messages to be processed in order */
      ASSERT (0);
    }

  need_signal = clib_atomic_load_relax_n (&sr->cursize) == ring->nitems;
  clib_atomic_fetch_sub_relax (&sr->cursize, 1);

  if (PREDICT_FALSE (need_signal))
    svm_msg_q_send_signal (mq, 1 /* is consumer */);
}

static int
svm_msq_q_msg_is_valid (svm_msg_q_t * mq, svm_msg_q_msg_t * msg)
{
  u32 dist1, dist2, tail, head;
  svm_msg_q_ring_shared_t *sr;
  svm_msg_q_ring_t *ring;

  if (vec_len (mq->rings) <= msg->ring_index)
    return 0;

  ring = svm_msg_q_ring_inline (mq, msg->ring_index);
  sr = ring->shr;
  tail = sr->tail;
  head = sr->head;

  dist1 = ((ring->nitems + msg->elt_index) - head) % ring->nitems;
  if (tail == head)
    dist2 = (sr->cursize == 0) ? 0 : ring->nitems;
  else
    dist2 = ((ring->nitems + tail) - head) % ring->nitems;
  return (dist1 < dist2);
}

void
svm_msg_q_add_raw (svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
{
  svm_msg_q_shared_queue_t *sq = mq->q.shr;
  i8 *tailp;
  u32 sz;

  tailp = (i8 *) (&sq->data[0] + sq->elsize * sq->tail);
  clib_memcpy_fast (tailp, msg, sq->elsize);

  sq->tail = (sq->tail + 1) % sq->maxsize;

  sz = clib_atomic_fetch_add_rel (&sq->cursize, 1);
  if (!sz)
    svm_msg_q_send_signal (mq, 0 /* is consumer */);
}

int
svm_msg_q_add (svm_msg_q_t * mq, svm_msg_q_msg_t * msg, int nowait)
{
  ASSERT (svm_msq_q_msg_is_valid (mq, msg));

  if (nowait)
    {
      /* zero on success */
      if (svm_msg_q_try_lock (mq))
	{
	  return (-1);
	}
    }
  else
    svm_msg_q_lock (mq);

  if (PREDICT_FALSE (svm_msg_q_is_full (mq)))
    {
      if (nowait)
	return (-2);
      while (svm_msg_q_is_full (mq))
	svm_msg_q_wait_prod (mq);
    }

  svm_msg_q_add_raw (mq, msg);

  svm_msg_q_unlock (mq);

  return 0;
}

void
svm_msg_q_add_and_unlock (svm_msg_q_t * mq, svm_msg_q_msg_t * msg)
{
  ASSERT (svm_msq_q_msg_is_valid (mq, msg));
  svm_msg_q_add_raw (mq, msg);
  svm_msg_q_unlock (mq);
}

int
svm_msg_q_sub_raw (svm_msg_q_t *mq, svm_msg_q_msg_t *elem)
{
  svm_msg_q_shared_queue_t *sq = mq->q.shr;
  i8 *headp;
  u32 sz;

  ASSERT (!svm_msg_q_is_empty (mq));

  headp = (i8 *) (&sq->data[0] + sq->elsize * sq->head);
  clib_memcpy_fast (elem, headp, sq->elsize);

  sq->head = (sq->head + 1) % sq->maxsize;

  sz = clib_atomic_fetch_sub_relax (&sq->cursize, 1);
  if (PREDICT_FALSE (sz == sq->maxsize))
    svm_msg_q_send_signal (mq, 1 /* is consumer */);

  return 0;
}

int
svm_msg_q_sub_raw_batch (svm_msg_q_t *mq, svm_msg_q_msg_t *msg_buf, u32 n_msgs)
{
  svm_msg_q_shared_queue_t *sq = mq->q.shr;
  u32 sz, to_deq;
  i8 *headp;

  sz = svm_msg_q_size (mq);
  ASSERT (sz);
  to_deq = clib_min (sz, n_msgs);

  headp = (i8 *) (&sq->data[0] + sq->elsize * sq->head);

  if (sq->head + to_deq < sq->maxsize)
    {
      clib_memcpy_fast (msg_buf, headp, sq->elsize * to_deq);
      sq->head += to_deq;
    }
  else
    {
      u32 first_batch = sq->maxsize - sq->head;
      clib_memcpy_fast (msg_buf, headp, sq->elsize * first_batch);
      clib_memcpy_fast (msg_buf + first_batch, sq->data,
			sq->elsize * (to_deq - first_batch));
      sq->head = (sq->head + to_deq) % sq->maxsize;
    }

  clib_atomic_fetch_sub_relax (&sq->cursize, to_deq);
  if (PREDICT_FALSE (sz == sq->maxsize))
    svm_msg_q_send_signal (mq, 1 /* is consumer */);

  return to_deq;
}

int
svm_msg_q_sub (svm_msg_q_t *mq, svm_msg_q_msg_t *msg,
	       svm_q_conditional_wait_t cond, u32 time)
{
  int rc = 0;

  if (svm_msg_q_is_empty (mq))
    {
      if (cond == SVM_Q_NOWAIT)
	{
	  return (-2);
	}
      else if (cond == SVM_Q_TIMEDWAIT)
	{
	  if ((rc = svm_msg_q_timedwait (mq, time)))
	    return rc;
	}
      else
	{
	  svm_msg_q_wait (mq, SVM_MQ_WAIT_EMPTY);
	}
    }

  svm_msg_q_sub_raw (mq, msg);

  return 0;
}

void
svm_msg_q_set_eventfd (svm_msg_q_t *mq, int fd)
{
  mq->q.evtfd = fd;
}

int
svm_msg_q_alloc_eventfd (svm_msg_q_t *mq)
{
  int fd;
  if ((fd = eventfd (0, 0)) < 0)
    return -1;
  svm_msg_q_set_eventfd (mq, fd);
  return 0;
}

int
svm_msg_q_wait (svm_msg_q_t *mq, svm_msg_q_wait_type_t type)
{
  u8 (*fn) (svm_msg_q_t *);
  int rv;

  fn = (type == SVM_MQ_WAIT_EMPTY) ? svm_msg_q_is_empty : svm_msg_q_is_full;

  if (mq->q.evtfd == -1)
    {
      rv = pthread_mutex_lock (&mq->q.shr->mutex);
      if (PREDICT_FALSE (rv == EOWNERDEAD))
	{
	  rv = pthread_mutex_consistent (&mq->q.shr->mutex);
	  return rv;
	}

      while (fn (mq))
	pthread_cond_wait (&mq->q.shr->condvar, &mq->q.shr->mutex);

      pthread_mutex_unlock (&mq->q.shr->mutex);
    }
  else
    {
      u64 buf;

      while (fn (mq))
	{
	  while ((rv = read (mq->q.evtfd, &buf, sizeof (buf))) < 0)
	    {
	      if (errno != EAGAIN)
		{
		  clib_unix_warning ("read error");
		  return rv;
		}
	    }
	}
    }

  return 0;
}

int
svm_msg_q_wait_prod (svm_msg_q_t *mq)
{
  if (mq->q.evtfd == -1)
    {
      while (svm_msg_q_is_full (mq))
	pthread_cond_wait (&mq->q.shr->condvar, &mq->q.shr->mutex);
    }
  else
    {
      u64 buf;
      int rv;

      while (svm_msg_q_is_full (mq))
	{
	  while ((rv = read (mq->q.evtfd, &buf, sizeof (buf))) < 0)
	    {
	      if (errno != EAGAIN)
		{
		  clib_unix_warning ("read error");
		  return rv;
		}
	    }
	}
    }

  return 0;
}

int
svm_msg_q_or_ring_wait_prod (svm_msg_q_t *mq, u32 ring_index)
{
  if (mq->q.evtfd == -1)
    {
      while (svm_msg_q_or_ring_is_full (mq, ring_index))
	pthread_cond_wait (&mq->q.shr->condvar, &mq->q.shr->mutex);
    }
  else
    {
      u64 buf;
      int rv;

      while (svm_msg_q_or_ring_is_full (mq, ring_index))
	{
	  while ((rv = read (mq->q.evtfd, &buf, sizeof (buf))) < 0)
	    {
	      if (errno != EAGAIN)
		{
		  clib_unix_warning ("read error");
		  return rv;
		}
	    }
	}
    }

  return 0;
}

int
svm_msg_q_timedwait (svm_msg_q_t *mq, double timeout)
{
  if (mq->q.evtfd == -1)
    {
      svm_msg_q_shared_queue_t *sq = mq->q.shr;
      struct timespec ts;
      u32 sz;
      int rv;

      rv = pthread_mutex_lock (&sq->mutex);
      if (PREDICT_FALSE (rv == EOWNERDEAD))
	{
	  rv = pthread_mutex_consistent (&sq->mutex);
	  return rv;
	}

      /* check if we're still in a signalable state after grabbing lock */
      sz = svm_msg_q_size (mq);
      if (sz != 0 && sz != sq->maxsize)
	{
	  pthread_mutex_unlock (&sq->mutex);
	  return 0;
	}

      ts.tv_sec = unix_time_now () + (u32) timeout;
      ts.tv_nsec = (timeout - (u32) timeout) * 1e9;
      rv = pthread_cond_timedwait (&sq->condvar, &sq->mutex, &ts);

      pthread_mutex_unlock (&sq->mutex);
      return rv;
    }
  else
    {
      struct timeval tv;
      u64 buf;
      int rv;

      tv.tv_sec = (u64) timeout;
      tv.tv_usec = ((u64) timeout - (u64) timeout) * 1e9;
      rv = setsockopt (mq->q.evtfd, SOL_SOCKET, SO_RCVTIMEO,
		       (const char *) &tv, sizeof tv);
      if (rv < 0)
	{
	  clib_unix_warning ("setsockopt");
	  return -1;
	}

      rv = read (mq->q.evtfd, &buf, sizeof (buf));
      if (rv < 0)
	clib_warning ("read %u", errno);

      return rv < 0 ? errno : 0;
    }
}

u8 *
format_svm_msg_q (u8 * s, va_list * args)
{
  svm_msg_q_t *mq = va_arg (*args, svm_msg_q_t *);
  s = format (s, " [Q:%d/%d]", mq->q.shr->cursize, mq->q.shr->maxsize);
  for (u32 i = 0; i < vec_len (mq->rings); i++)
    {
      s = format (s, " [R%d:%d/%d]", i, mq->rings[i].shr->cursize,
		  mq->rings[i].nitems);
    }
  return s;
}

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