Preallocate mhash key_tmps vector

Fix os_get_nthreads() so that it starts returning the correct answer
as early as possible.

Change-Id: Id5292262f2c3f521b07ffbe6a9f6748dcc4dcb7d
Signed-off-by: Dave Barach <dave@barachs.net>
diff --git a/src/vlib/threads.c b/src/vlib/threads.c
index 52886df..cb1eb5f 100644
--- a/src/vlib/threads.c
+++ b/src/vlib/threads.c
@@ -169,13 +169,7 @@
 uword
 os_get_nthreads (void)
 {
-  u32 len;
-
-  len = vec_len (vlib_thread_stacks);
-  if (len == 0)
-    return 1;
-  else
-    return len;
+  return vec_len (vlib_thread_stacks);
 }
 
 void
@@ -299,11 +293,8 @@
       pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
     }
 
-  /* as many threads as stacks... */
-  vec_validate_aligned (vlib_worker_threads, vec_len (vlib_thread_stacks) - 1,
-			CLIB_CACHE_LINE_BYTES);
-
-  /* Preallocate thread 0 */
+  /* Set up thread 0 */
+  vec_validate_aligned (vlib_worker_threads, 0, CLIB_CACHE_LINE_BYTES);
   _vec_len (vlib_worker_threads) = 1;
   w = vlib_worker_threads;
   w->thread_mheap = clib_mem_get_heap ();
@@ -358,8 +349,7 @@
 
             avail_cpu = clib_bitmap_set(avail_cpu, c, 0);
           }));
-/* *INDENT-ON* */
-
+          /* *INDENT-ON* */
 	}
       else
 	{
@@ -381,9 +371,14 @@
 
   tm->n_vlib_mains = n_vlib_mains;
 
+  /*
+   * Allocate the remaining worker threads, and thread stack vector slots
+   * from now on, calls to os_get_nthreads() will return the correct
+   * answer.
+   */
   vec_validate_aligned (vlib_worker_threads, first_index - 1,
 			CLIB_CACHE_LINE_BYTES);
-
+  vec_validate (vlib_thread_stacks, vec_len (vlib_worker_threads) - 1);
   return 0;
 }
 
diff --git a/src/vlib/unix/main.c b/src/vlib/unix/main.c
index 82de8ec..8c9bc1b 100755
--- a/src/vlib/unix/main.c
+++ b/src/vlib/unix/main.c
@@ -641,7 +641,7 @@
 u8 *
 vlib_thread_stack_init (uword thread_index)
 {
-  vec_validate (vlib_thread_stacks, thread_index);
+  ASSERT (thread_index < vec_len (vlib_thread_stacks));
   vlib_thread_stacks[thread_index] = clib_mem_alloc_aligned
     (VLIB_THREAD_STACK_SIZE, clib_mem_get_page_size ());
 
@@ -696,6 +696,7 @@
   /* always load symbols, for signal handler and mheap memory get/put backtrace */
   clib_elf_main_init (vm->name);
 
+  vec_validate (vlib_thread_stacks, 0);
   vlib_thread_stack_init (0);
 
   __os_thread_index = 0;
diff --git a/src/vppinfra/mhash.c b/src/vppinfra/mhash.c
index d4d5457..791aa36 100644
--- a/src/vppinfra/mhash.c
+++ b/src/vppinfra/mhash.c
@@ -205,13 +205,7 @@
   clib_memset (h, 0, sizeof (h[0]));
   h->n_key_bytes = n_key_bytes;
 
-#if 0
-  if (h->n_key_bytes > 0)
-    {
-      vec_validate (h->key_tmp, h->n_key_bytes - 1);
-      _vec_len (h->key_tmp) = 0;
-    }
-#endif
+  vec_validate (h->key_tmps, os_get_nthreads () - 1);
 
   ASSERT (n_key_bytes < ARRAY_LEN (t));
   h->hash = hash_create2 ( /* elts */ 0,
@@ -228,7 +222,6 @@
   u8 *key_tmp;
   int my_cpu = os_get_thread_index ();
 
-  vec_validate (h->key_tmps, my_cpu);
   key_tmp = h->key_tmps[my_cpu];
 
   vec_reset_length (key_tmp);