VPP-1574: minimize RPC barrier sync calls

Grab the thread barrier across a set of RPCs, to greatly increase
efficiency. Avoids running afoul of the barrier sync holddown
timer.

Change-Id: I782dfdb1bed398b290169c83266681c9edd57a3f
Signed-off-by: Dave Barach <dave@barachs.net>
diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c
index 1727c28..9fc26b9 100644
--- a/src/vlibmemory/memory_api.c
+++ b/src/vlibmemory/memory_api.c
@@ -735,11 +735,28 @@
   vm->pending_rpc_requests = tmp;
   clib_spinlock_unlock_if_init (&vm->pending_rpc_lock);
 
-  for (i = 0; i < vec_len (vm->processing_rpc_requests); i++)
+  /*
+   * RPCs are used to reflect function calls to thread 0
+   * when the underlying code is not thread-safe.
+   *
+   * Grabbing the thread barrier across a set of RPCs
+   * greatly increases efficiency, and avoids
+   * running afoul of the barrier sync holddown timer.
+   * The barrier sync code supports recursive locking.
+   *
+   * We really need to rewrite RPC-based code...
+   */
+  if (PREDICT_TRUE (vec_len (vm->processing_rpc_requests)))
     {
-      mp = vm->processing_rpc_requests[i];
-      vl_msg_api_handler_with_vm_node (am, (void *) mp, vm, node);
+      vl_msg_api_barrier_sync ();
+      for (i = 0; i < vec_len (vm->processing_rpc_requests); i++)
+	{
+	  mp = vm->processing_rpc_requests[i];
+	  vl_msg_api_handler_with_vm_node (am, (void *) mp, vm, node);
+	}
+      vl_msg_api_barrier_release ();
     }
+
   return 0;
 }