Improve fifo allocator performance

- add option to preallocate fifos in a segment
- track active fifos with doubly linked list instead of vector
- update udp redirect test code to read fifo pointers from API call
  instead of digging them up from fifo segment header
- input-node based active-open session generator

Change-Id: I804b81e99d95f8690d17e12660c6645995e28a9a
Signed-off-by: Dave Barach <dave@barachs.net>
Signed-off-by: Florin Coras <fcoras@cisco.com>
Signed-off-by: Dave Barach <dbarach@cisco.com>
diff --git a/src/vlibmemory/memory_shared.c b/src/vlibmemory/memory_shared.c
index aea9033..41aa123 100644
--- a/src/vlibmemory/memory_shared.c
+++ b/src/vlibmemory/memory_shared.c
@@ -104,8 +104,17 @@
 	      if (now - rv->gc_mark_timestamp > 10)
 		{
 		  if (CLIB_DEBUG > 0)
-		    clib_warning ("garbage collect pool %d ring %d index %d",
-				  pool, i, q->head);
+		    {
+		      u16 *msg_idp, msg_id;
+		      clib_warning
+			("garbage collect pool %d ring %d index %d", pool, i,
+			 q->head);
+		      msg_idp = (u16 *) (rv->data);
+		      msg_id = clib_net_to_host_u16 (*msg_idp);
+		      if (msg_id < vec_len (api_main.msg_names))
+			clib_warning ("msg id %d name %s", (u32) msg_id,
+				      api_main.msg_names[msg_id]);
+		    }
 		  shmem_hdr->garbage_collects++;
 		  goto collected;
 		}
@@ -330,6 +339,7 @@
   api_main_t *am = &api_main;
   int i;
   struct timespec ts, tsrem;
+  u32 vlib_input_queue_length;
 
   if (is_vlib == 0)
     svm_region_init_chroot (am->root_path);
@@ -449,9 +459,13 @@
   shmem_hdr->version = VL_SHM_VERSION;
 
   /* vlib main input queue */
+  vlib_input_queue_length = 1024;
+  if (am->vlib_input_queue_length)
+    vlib_input_queue_length = am->vlib_input_queue_length;
+
   shmem_hdr->vl_input_queue =
-    unix_shared_memory_queue_init (1024, sizeof (uword), getpid (),
-				   am->vlib_signal);
+    unix_shared_memory_queue_init (vlib_input_queue_length, sizeof (uword),
+				   getpid (), am->vlib_signal);
 
   /* Set up the msg ring allocator */
 #define _(sz,n)                                                 \
diff --git a/src/vlibmemory/memory_vlib.c b/src/vlibmemory/memory_vlib.c
index e5d8873..004a997 100644
--- a/src/vlibmemory/memory_vlib.c
+++ b/src/vlibmemory/memory_vlib.c
@@ -1917,6 +1917,32 @@
 
 VLIB_CONFIG_FUNCTION (api_config_fn, "api-trace");
 
+static clib_error_t *
+api_queue_config_fn (vlib_main_t * vm, unformat_input_t * input)
+{
+  api_main_t *am = &api_main;
+  u32 nitems;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "length %d", &nitems) ||
+	  (unformat (input, "len %d", &nitems)))
+	{
+	  if (nitems >= 1024)
+	    am->vlib_input_queue_length = nitems;
+	  else
+	    clib_warning ("vlib input queue length %d too small, ignored",
+			  nitems);
+	}
+      else
+	return clib_error_return (0, "unknown input `%U'",
+				  format_unformat_error, input);
+    }
+  return 0;
+}
+
+VLIB_CONFIG_FUNCTION (api_queue_config_fn, "api-queue");
+
 /*
  * fd.io coding-style-patch-verification: ON
  *