api: use string type for strings in memclnt.api
[vpp.git] / src / vlibmemory / vlib_api.c
index 15a0ba8..7d7ed3e 100644 (file)
@@ -56,10 +56,12 @@ static inline void *
 vl_api_trace_plugin_msg_ids_t_print (vl_api_trace_plugin_msg_ids_t * a,
                                     void *handle)
 {
-  vl_print (handle, "vl_api_trace_plugin_msg_ids: %s first %u last %u\n",
-           a->plugin_name,
+  u8 *plugin_name = vl_api_from_api_to_vec (&a->plugin_name);
+  vl_print (handle, "vl_api_trace_plugin_msg_ids: %v first %u last %u\n",
+           plugin_name,
            clib_host_to_net_u16 (a->first_msg_id),
            clib_host_to_net_u16 (a->last_msg_id));
+  vec_free (plugin_name);
   return handle;
 }
 
@@ -68,29 +70,6 @@ vl_api_trace_plugin_msg_ids_t_print (vl_api_trace_plugin_msg_ids_t * a,
 #include <vlibmemory/vl_memory_api_h.h>
 #undef vl_endianfun
 
-u8 *
-vl_api_serialize_message_table (api_main_t * am, u8 * vector)
-{
-  serialize_main_t _sm, *sm = &_sm;
-  hash_pair_t *hp;
-  u32 nmsg = hash_elts (am->msg_index_by_name_and_crc);
-
-  serialize_open_vector (sm, vector);
-
-  /* serialize the count */
-  serialize_integer (sm, nmsg, sizeof (u32));
-
-  /* *INDENT-OFF* */
-  hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
-  ({
-    serialize_likely_small_unsigned_integer (sm, hp->value[0]);
-    serialize_cstring (sm, (char *) hp->key);
-  }));
-  /* *INDENT-ON* */
-
-  return serialize_close_vector (sm);
-}
-
 static void
 vl_api_get_first_msg_id_t_handler (vl_api_get_first_msg_id_t * mp)
 {
@@ -99,7 +78,6 @@ vl_api_get_first_msg_id_t_handler (vl_api_get_first_msg_id_t * mp)
   uword *p;
   api_main_t *am = &api_main;
   vl_api_msg_range_t *rp;
-  u8 name[64];
   u16 first_msg_id = ~0;
   int rv = -7;                 /* VNET_API_ERROR_INVALID_VALUE */
 
@@ -107,10 +85,11 @@ vl_api_get_first_msg_id_t_handler (vl_api_get_first_msg_id_t * mp)
   if (!regp)
     return;
 
+  u8 *name = vl_api_from_api_to_vec (&mp->name);
+
   if (am->msg_range_by_name == 0)
     goto out;
-  strncpy ((char *) name, (char *) mp->name, ARRAY_LEN (name));
-  name[ARRAY_LEN (name) - 1] = '\0';
+
   p = hash_get_mem (am->msg_range_by_name, name);
   if (p == 0)
     goto out;
@@ -120,6 +99,7 @@ vl_api_get_first_msg_id_t_handler (vl_api_get_first_msg_id_t * mp)
   rv = 0;
 
 out:
+  vec_free (name);
   rmp = vl_msg_api_alloc (sizeof (*rmp));
   rmp->_vl_msg_id = ntohs (VL_API_GET_FIRST_MSG_ID_REPLY);
   rmp->context = mp->context;
@@ -143,7 +123,7 @@ vl_api_api_versions_t_handler (vl_api_api_versions_t * mp)
     return;
 
   rmp = vl_msg_api_alloc (msg_size);
-  memset (rmp, 0, msg_size);
+  clib_memset (rmp, 0, msg_size);
   rmp->_vl_msg_id = ntohs (VL_API_API_VERSIONS_REPLY);
 
   /* fill in the message */
@@ -156,10 +136,8 @@ vl_api_api_versions_t_handler (vl_api_api_versions_t * mp)
       rmp->api_versions[i].major = htonl (vl->major);
       rmp->api_versions[i].minor = htonl (vl->minor);
       rmp->api_versions[i].patch = htonl (vl->patch);
-      strncpy ((char *) rmp->api_versions[i].name, vl->name,
-              ARRAY_LEN (rmp->api_versions[i].name));
-      rmp->api_versions[i].name[ARRAY_LEN (rmp->api_versions[i].name) - 1] =
-       '\0';
+      vl_api_to_api_string (strnlen (vl->name, 64), vl->name,
+                           &rmp->api_versions[i].name);
     }
 
   vl_api_send_msg (reg, (u8 *) rmp);
@@ -178,7 +156,7 @@ vlib_api_init (void)
   vl_msg_api_msg_config_t cfg;
   vl_msg_api_msg_config_t *c = &cfg;
 
-  memset (c, 0, sizeof (*c));
+  clib_memset (c, 0, sizeof (*c));
 
 #define _(N,n) do {                                             \
     c->id = VL_API_##N;                                         \
@@ -213,11 +191,11 @@ send_one_plugin_msg_ids_msg (u8 * name, u16 first_msg_id, u16 last_msg_id)
   svm_queue_t *q;
 
   mp = vl_msg_api_alloc_as_if_client (sizeof (*mp));
-  memset (mp, 0, sizeof (*mp));
+  clib_memset (mp, 0, sizeof (*mp));
 
   mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_TRACE_PLUGIN_MSG_IDS);
-  strncpy ((char *) mp->plugin_name, (char *) name,
-          sizeof (mp->plugin_name) - 1);
+  vl_api_to_api_string (strnlen_s ((char *) name, 64), (char *) name,
+                       &mp->plugin_name);
   mp->first_msg_id = clib_host_to_net_u16 (first_msg_id);
   mp->last_msg_id = clib_host_to_net_u16 (last_msg_id);
 
@@ -306,7 +284,7 @@ vl_api_clnt_process (vlib_main_t * vm, vlib_node_runtime_t * node,
   q = shm->vl_input_queue;
 
   e = vlib_call_init_exit_functions
-    (vm, vm->api_init_function_registrations, 1 /* call_once */ );
+    (vm, &vm->api_init_function_registrations, 1 /* call_once */ );
   if (e)
     clib_error_report (e);
 
@@ -346,7 +324,8 @@ vl_api_clnt_process (vlib_main_t * vm, vlib_node_runtime_t * node,
       start_time = vlib_time_now (vm);
       while (1)
        {
-         if (vl_mem_api_handle_msg_main (vm, node))
+         if (vl_mem_api_handle_rpc (vm, node)
+             || vl_mem_api_handle_msg_main (vm, node))
            {
              vm->api_queue_nonempty = 0;
              VL_MEM_API_LOG_Q_LEN ("q-underflow: len %d", 0);
@@ -463,7 +442,7 @@ api_rx_from_node (vlib_main_t * vm,
 
   vec_validate (long_msg, 4095);
   n_left_from = frame->n_vectors;
-  from = vlib_frame_args (frame);
+  from = vlib_frame_vector_args (frame);
 
   while (n_left_from > 0)
     {
@@ -497,7 +476,7 @@ api_rx_from_node (vlib_main_t * vm,
     }
 
   /* Free what we've been given. */
-  vlib_buffer_free (vm, vlib_frame_args (frame), n_packets);
+  vlib_buffer_free (vm, vlib_frame_vector_args (frame), n_packets);
 
   return n_packets;
 }
@@ -564,36 +543,14 @@ vl_api_rpc_call_reply_t_handler (vl_api_rpc_call_reply_t * mp)
 void
 vl_api_send_pending_rpc_requests (vlib_main_t * vm)
 {
-  api_main_t *am = &api_main;
-  vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr;
-  svm_queue_t *q;
-  int i;
-
-  /*
-   * Use the "normal" control-plane mechanism for the main thread.
-   * Well, almost. if the main input queue is full, we cannot
-   * block. Otherwise, we can expect a barrier sync timeout.
-   */
-  q = shmem_hdr->vl_input_queue;
-
-  for (i = 0; i < vec_len (vm->pending_rpc_requests); i++)
-    {
-      while (pthread_mutex_trylock (&q->mutex))
-       vlib_worker_thread_barrier_check ();
-
-      while (PREDICT_FALSE (svm_queue_is_full (q)))
-       {
-         pthread_mutex_unlock (&q->mutex);
-         vlib_worker_thread_barrier_check ();
-         while (pthread_mutex_trylock (&q->mutex))
-           vlib_worker_thread_barrier_check ();
-       }
+  vlib_main_t *vm_global = &vlib_global_main;
 
-      vl_msg_api_send_shmem_nolock (q, (u8 *) (vm->pending_rpc_requests + i));
+  ASSERT (vm != vm_global);
 
-      pthread_mutex_unlock (&q->mutex);
-    }
-  _vec_len (vm->pending_rpc_requests) = 0;
+  clib_spinlock_lock_if_init (&vm_global->pending_rpc_lock);
+  vec_append (vm_global->pending_rpc_requests, vm->pending_rpc_requests);
+  vec_reset_length (vm->pending_rpc_requests);
+  clib_spinlock_unlock_if_init (&vm_global->pending_rpc_lock);
 }
 
 always_inline void
@@ -601,6 +558,7 @@ vl_api_rpc_call_main_thread_inline (void *fp, u8 * data, u32 data_length,
                                    u8 force_rpc)
 {
   vl_api_rpc_call_t *mp;
+  vlib_main_t *vm_global = &vlib_global_main;
   vlib_main_t *vm = vlib_get_main ();
 
   /* Main thread and not a forced RPC: call the function directly */
@@ -620,13 +578,18 @@ vl_api_rpc_call_main_thread_inline (void *fp, u8 * data, u32 data_length,
   /* Otherwise, actually do an RPC */
   mp = vl_msg_api_alloc_as_if_client (sizeof (*mp) + data_length);
 
-  memset (mp, 0, sizeof (*mp));
-  clib_memcpy (mp->data, data, data_length);
+  clib_memset (mp, 0, sizeof (*mp));
+  clib_memcpy_fast (mp->data, data, data_length);
   mp->_vl_msg_id = ntohs (VL_API_RPC_CALL);
   mp->function = pointer_to_uword (fp);
   mp->need_barrier_sync = 1;
 
+  /* Add to the pending vector. Thread 0 requires locking. */
+  if (vm == vm_global)
+    clib_spinlock_lock_if_init (&vm_global->pending_rpc_lock);
   vec_add1 (vm->pending_rpc_requests, (uword) mp);
+  if (vm == vm_global)
+    clib_spinlock_unlock_if_init (&vm_global->pending_rpc_lock);
 }
 
 /*
@@ -663,11 +626,14 @@ vl_api_trace_plugin_msg_ids_t_handler (vl_api_trace_plugin_msg_ids_t * mp)
   if (am->replay_in_progress == 0)
     return;
 
-  p = hash_get_mem (am->msg_range_by_name, mp->plugin_name);
+  u8 *plugin_name = vl_api_from_api_to_vec (&mp->plugin_name);
+  vec_add1 (plugin_name, 0);
+
+  p = hash_get_mem (am->msg_range_by_name, plugin_name);
   if (p == 0)
     {
       clib_warning ("WARNING: traced plugin '%s' not in current image",
-                   mp->plugin_name);
+                   plugin_name);
       return;
     }
 
@@ -675,16 +641,17 @@ vl_api_trace_plugin_msg_ids_t_handler (vl_api_trace_plugin_msg_ids_t * mp)
   if (rp->first_msg_id != clib_net_to_host_u16 (mp->first_msg_id))
     {
       clib_warning ("WARNING: traced plugin '%s' first message id %d not %d",
-                   mp->plugin_name, clib_net_to_host_u16 (mp->first_msg_id),
+                   plugin_name, clib_net_to_host_u16 (mp->first_msg_id),
                    rp->first_msg_id);
     }
 
   if (rp->last_msg_id != clib_net_to_host_u16 (mp->last_msg_id))
     {
       clib_warning ("WARNING: traced plugin '%s' last message id %d not %d",
-                   mp->plugin_name, clib_net_to_host_u16 (mp->last_msg_id),
+                   plugin_name, clib_net_to_host_u16 (mp->last_msg_id),
                    rp->last_msg_id);
     }
+  vec_free (plugin_name);
 }
 
 #define foreach_rpc_api_msg                     \