Remove c-11 memcpy checks from perf-critical code
[vpp.git] / src / vppinfra / hash.h
index 21986ea..59dbf8c 100644 (file)
@@ -77,6 +77,7 @@ typedef struct hash_header
 #define KEY_FUNC_POINTER_UWORD (1)     /*< sum = *(uword *) key */
 #define KEY_FUNC_POINTER_U32   (2)     /*< sum = *(u32 *) key */
 #define KEY_FUNC_STRING         (3)    /*< sum = string_key_sum, etc. */
+#define KEY_FUNC_MEM           (4)     /*< sum = mem_key_sum */
 
   /* key comparison function */
   hash_key_equal_function_t *key_equal;
@@ -273,13 +274,13 @@ uword hash_bytes (void *v);
 /* Public macro to set (key, value) for pointer key */
 #define hash_set_mem(h,key,value) hash_set3 (h, pointer_to_uword (key), (value), 0)
 
-/* Public inline funcion allocate and copy key to use in hash for pointer key */
+/* Public inline function allocate and copy key to use in hash for pointer key */
 always_inline void
 hash_set_mem_alloc (uword ** h, void *key, uword v)
 {
   size_t ksz = hash_header (*h)->user;
   void *copy = clib_mem_alloc (ksz);
-  clib_memcpy (copy, key, ksz);
+  clib_memcpy_fast (copy, key, ksz);
   hash_set_mem (*h, copy, v);
 }
 
@@ -289,7 +290,7 @@ hash_set_mem_alloc (uword ** h, void *key, uword v)
 /* Public macro to unset (key, value) for pointer key */
 #define hash_unset_mem(h,key)    ((h) = _hash_unset ((h), pointer_to_uword (key),0))
 
-/* Public inline funcion to unset pointer key and then free the key memory */
+/* Public inline function to unset pointer key and then free the key memory */
 always_inline void
 hash_unset_mem_free (uword ** h, void *key)
 {
@@ -310,7 +311,7 @@ extern void *_hash_free (void *v);
 
 clib_error_t *hash_validate (void *v);
 
-/* Public inline funcion to get the number of value bytes for a hash table */
+/* Public inline function to get the number of value bytes for a hash table */
 always_inline uword
 hash_value_bytes (hash_t * h)
 {
@@ -318,7 +319,7 @@ hash_value_bytes (hash_t * h)
   return (sizeof (p->value[0]) << h->log2_pair_size) - sizeof (p->key);
 }
 
-/* Public inline funcion to get log2(size of a (key,value) pair) */
+/* Public inline function to get log2(size of a (key,value) pair) */
 always_inline uword
 hash_pair_log2_bytes (hash_t * h)
 {
@@ -331,21 +332,21 @@ hash_pair_log2_bytes (hash_t * h)
   return log2_bytes;
 }
 
-/* Public inline funcion to get size of a (key,value) pair */
+/* Public inline function to get size of a (key,value) pair */
 always_inline uword
 hash_pair_bytes (hash_t * h)
 {
   return (uword) 1 << hash_pair_log2_bytes (h);
 }
 
-/* Public inline funcion to advance a pointer past one (key,value) pair */
+/* Public inline function to advance a pointer past one (key,value) pair */
 always_inline void *
 hash_forward1 (hash_t * h, void *v)
 {
   return (u8 *) v + hash_pair_bytes (h);
 }
 
-/* Public inline funcion to advance a pointer past N (key,value) pairs */
+/* Public inline function to advance a pointer past N (key,value) pairs */
 always_inline void *
 hash_forward (hash_t * h, void *v, uword n)
 {
@@ -437,7 +438,7 @@ do {                                                                        \
 
     calls body with each active hash pair
 */
-/* Iteratate over key/value pairs. */
+/* Iterate over key/value pairs. */
 #define hash_foreach(key_var,value_var,h,body)                 \
 do {                                                           \
   hash_pair_t * _r;                                            \
@@ -495,7 +496,7 @@ hash_set_value_bytes (hash_t * h, uword value_bytes)
                      _format_pair,_format_pair_arg)          \
 ({                                                          \
   hash_t _h;                                                \
-  memset (&_h, 0, sizeof (_h));                                     \
+  clib_memset (&_h, 0, sizeof (_h));                                \
   _h.user = (_user);                                        \
   _h.key_sum   = (hash_key_sum_function_t *) (_key_sum);     \
   _h.key_equal = (_key_equal);                              \
@@ -672,6 +673,20 @@ extern uword string_key_sum (hash_t * h, uword key);
 extern uword string_key_equal (hash_t * h, uword key1, uword key2);
 extern u8 *string_key_format_pair (u8 * s, va_list * args);
 
+/*
+ * Note: if you plan to put a hash into shared memory,
+ * the key sum and key equal functions MUST be set to magic constants!
+ * PIC means that whichever process sets up the hash won't have
+ * the actual key sum functions at the same place, leading to
+ * very hard-to-find bugs...
+ */
+
+#define hash_create_shmem(elts,key_bytes,value_bytes)           \
+  hash_create2((elts),(key_bytes),(value_bytes),                \
+               (hash_key_sum_function_t *) KEY_FUNC_MEM,        \
+               (hash_key_equal_function_t *)KEY_FUNC_MEM,       \
+               0, 0)
+
 #define hash_create_string(elts,value_bytes)                    \
   hash_create2((elts),0,(value_bytes),                          \
                (hash_key_sum_function_t *) KEY_FUNC_STRING,     \