X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vppinfra%2Fvppinfra%2Fpfhash.h;h=e054c668f3b68eceda2f99a086a2c285250d3c15;hb=9876520f9ba746ed4d9923f392911c4f1888a105;hp=a2ca300f7c5c55e2691fa1e47bb51a73d2735f5c;hpb=cb9cadad578297ffd78fa8a33670bdf1ab669e7e;p=vpp.git diff --git a/vppinfra/vppinfra/pfhash.h b/vppinfra/vppinfra/pfhash.h index a2ca300f7c5..e054c668f3b 100644 --- a/vppinfra/vppinfra/pfhash.h +++ b/vppinfra/vppinfra/pfhash.h @@ -24,20 +24,24 @@ #if defined(CLIB_HAVE_VEC128) && ! defined (__ALTIVEC__) -typedef struct { +typedef struct +{ /* 3 x 16 = 48 key bytes */ - union { + union + { u32x4 k_u32x4[3]; - u64 k_u64[6]; + u64 k_u64[6]; } kb; /* 3 x 4 = 12 value bytes */ u32 values[3]; u32 pad; } pfhash_kv_16_t; -typedef struct { +typedef struct +{ /* 5 x 8 = 40 key bytes */ - union { + union + { u64 k_u64[5]; } kb; @@ -46,9 +50,11 @@ typedef struct { u32 pad; } pfhash_kv_8_t; -typedef struct { +typedef struct +{ /* 4 x 8 = 32 key bytes */ - union { + union + { u64 k_u64[4]; } kb; @@ -56,9 +62,11 @@ typedef struct { u64 values[4]; } pfhash_kv_8v8_t; -typedef struct { +typedef struct +{ /* 8 x 4 = 32 key bytes */ - union { + union + { u32x4 k_u32x4[2]; u32 kb[8]; } kb; @@ -67,26 +75,28 @@ typedef struct { u32 values[8]; } pfhash_kv_4_t; -typedef union { +typedef union +{ pfhash_kv_16_t kv16; pfhash_kv_8_t kv8; pfhash_kv_8v8_t kv8v8; pfhash_kv_4_t kv4; } pfhash_kv_t; -typedef struct { +typedef struct +{ /* Bucket vector */ - u32 * buckets; + u32 *buckets; #define PFHASH_BUCKET_OVERFLOW (u32)~0 /* Pool of key/value pairs */ - pfhash_kv_t * kvp; - + pfhash_kv_t *kvp; + /* overflow plain-o-hash */ - uword * overflow_hash; + uword *overflow_hash; /* Pretty-print name */ - u8 * name; + u8 *name; u32 key_size; u32 value_size; @@ -96,19 +106,23 @@ typedef struct { u32 nitems_in_overflow; } pfhash_t; -void pfhash_init (pfhash_t * p, char * name, u32 key_size, u32 value_size, - u32 nbuckets); +void pfhash_init (pfhash_t * p, char *name, u32 key_size, u32 value_size, + u32 nbuckets); void pfhash_free (pfhash_t * p); -u64 pfhash_get (pfhash_t * p, u32 bucket, void * key); -void pfhash_set (pfhash_t * p, u32 bucket, void * key, void * value); -void pfhash_unset (pfhash_t * p, u32 bucket, void * key); +u64 pfhash_get (pfhash_t * p, u32 bucket, void *key); +void pfhash_set (pfhash_t * p, u32 bucket, void *key, void *value); +void pfhash_unset (pfhash_t * p, u32 bucket, void *key); format_function_t format_pfhash; -static inline void pfhash_prefetch_bucket (pfhash_t * p, u32 bucket) -{ CLIB_PREFETCH (&p->buckets[bucket], CLIB_CACHE_LINE_BYTES, LOAD); } +static inline void +pfhash_prefetch_bucket (pfhash_t * p, u32 bucket) +{ + CLIB_PREFETCH (&p->buckets[bucket], CLIB_CACHE_LINE_BYTES, LOAD); +} -static inline u32 pfhash_read_bucket_prefetch_kv (pfhash_t * p, u32 bucket) +static inline u32 +pfhash_read_bucket_prefetch_kv (pfhash_t * p, u32 bucket) { u32 bucket_contents = p->buckets[bucket]; if (PREDICT_TRUE ((bucket_contents & PFHASH_BUCKET_OVERFLOW) == 0)) @@ -116,17 +130,17 @@ static inline u32 pfhash_read_bucket_prefetch_kv (pfhash_t * p, u32 bucket) return bucket_contents; } -/* +/* * pfhash_search_kv_16 * See if the supplied 16-byte key matches one of three 16-byte (key,value) pairs. * Return the indicated value, or ~0 if no match - * + * * Note: including the overflow test, the fast path is 35 instrs * on x86_64. Elves will steal your keyboard in the middle of the night if * you "improve" it without checking the generated code! */ -static inline u32 pfhash_search_kv_16 (pfhash_t * p, u32 bucket_contents, - u32x4 * key) +static inline u32 +pfhash_search_kv_16 (pfhash_t * p, u32 bucket_contents, u32x4 * key) { u32x4 diff0, diff1, diff2; u32 is_equal0, is_equal1, is_equal2; @@ -136,11 +150,11 @@ static inline u32 pfhash_search_kv_16 (pfhash_t * p, u32 bucket_contents, if (PREDICT_FALSE (bucket_contents == PFHASH_BUCKET_OVERFLOW)) { - uword * hp; + uword *hp; hp = hash_get_mem (p->overflow_hash, key); if (hp) - return hp[0]; - return (u32)~0; + return hp[0]; + return (u32) ~ 0; } kv = &p->kvp[bucket_contents].kv16; @@ -148,7 +162,7 @@ static inline u32 pfhash_search_kv_16 (pfhash_t * p, u32 bucket_contents, diff0 = u32x4_sub (kv->kb.k_u32x4[0], key[0]); diff1 = u32x4_sub (kv->kb.k_u32x4[1], key[0]); diff2 = u32x4_sub (kv->kb.k_u32x4[2], key[0]); - + no_match = is_equal0 = (i16) u32x4_zero_byte_mask (diff0); is_equal1 = (i16) u32x4_zero_byte_mask (diff1); no_match |= is_equal1; @@ -156,101 +170,107 @@ static inline u32 pfhash_search_kv_16 (pfhash_t * p, u32 bucket_contents, no_match |= is_equal2; /* If any of the three items matched, no_match will be zero after this line */ no_match = ~no_match; - - rv = (is_equal0 & kv->values[0]) - |(is_equal1 & kv->values[1]) - | (is_equal2 & kv->values[2]) - | no_match; - + + rv = (is_equal0 & kv->values[0]) + | (is_equal1 & kv->values[1]) | (is_equal2 & kv->values[2]) | no_match; + return rv; } -static inline u32 pfhash_search_kv_8 (pfhash_t * p, u32 bucket_contents, - u64 * key) +static inline u32 +pfhash_search_kv_8 (pfhash_t * p, u32 bucket_contents, u64 * key) { pfhash_kv_8_t *kv; - u32 rv = (u32)~0; - + u32 rv = (u32) ~ 0; + if (PREDICT_FALSE (bucket_contents == PFHASH_BUCKET_OVERFLOW)) { - uword * hp; + uword *hp; hp = hash_get_mem (p->overflow_hash, key); if (hp) - return hp[0]; - return (u32)~0; + return hp[0]; + return (u32) ~ 0; } - + kv = &p->kvp[bucket_contents].kv8; - + rv = (kv->kb.k_u64[0] == key[0]) ? kv->values[0] : rv; rv = (kv->kb.k_u64[1] == key[0]) ? kv->values[1] : rv; rv = (kv->kb.k_u64[2] == key[0]) ? kv->values[2] : rv; rv = (kv->kb.k_u64[3] == key[0]) ? kv->values[3] : rv; rv = (kv->kb.k_u64[4] == key[0]) ? kv->values[4] : rv; - + return rv; } -static inline u64 pfhash_search_kv_8v8 (pfhash_t * p, u32 bucket_contents, - u64 * key) +static inline u64 +pfhash_search_kv_8v8 (pfhash_t * p, u32 bucket_contents, u64 * key) { pfhash_kv_8v8_t *kv; - u64 rv = (u64)~0; - + u64 rv = (u64) ~ 0; + if (PREDICT_FALSE (bucket_contents == PFHASH_BUCKET_OVERFLOW)) { - uword * hp; + uword *hp; hp = hash_get_mem (p->overflow_hash, key); if (hp) - return hp[0]; - return (u64)~0; + return hp[0]; + return (u64) ~ 0; } - + kv = &p->kvp[bucket_contents].kv8v8; - + rv = (kv->kb.k_u64[0] == key[0]) ? kv->values[0] : rv; rv = (kv->kb.k_u64[1] == key[0]) ? kv->values[1] : rv; rv = (kv->kb.k_u64[2] == key[0]) ? kv->values[2] : rv; rv = (kv->kb.k_u64[3] == key[0]) ? kv->values[3] : rv; - + return rv; } -static inline u32 pfhash_search_kv_4 (pfhash_t * p, u32 bucket_contents, - u32 * key) +static inline u32 +pfhash_search_kv_4 (pfhash_t * p, u32 bucket_contents, u32 * key) { u32x4 vector_key; u32x4 is_equal[2]; u32 zbm[2], winner_index; pfhash_kv_4_t *kv; - + if (PREDICT_FALSE (bucket_contents == PFHASH_BUCKET_OVERFLOW)) { - uword * hp; + uword *hp; hp = hash_get_mem (p->overflow_hash, key); if (hp) - return hp[0]; - return (u32)~0; + return hp[0]; + return (u32) ~ 0; } - + kv = &p->kvp[bucket_contents].kv4; - + vector_key = u32x4_splat (key[0]); - + is_equal[0] = u32x4_is_equal (kv->kb.k_u32x4[0], vector_key); is_equal[1] = u32x4_is_equal (kv->kb.k_u32x4[1], vector_key); zbm[0] = ~u32x4_zero_byte_mask (is_equal[0]) & 0xFFFF; zbm[1] = ~u32x4_zero_byte_mask (is_equal[1]) & 0xFFFF; - - if (PREDICT_FALSE((zbm[0] == 0) && (zbm[1] == 0))) - return (u32)~0; - - winner_index = min_log2 (zbm[0])>>2; - winner_index = zbm[1] ? (4 + (min_log2 (zbm[1])>>2)) : winner_index; - + + if (PREDICT_FALSE ((zbm[0] == 0) && (zbm[1] == 0))) + return (u32) ~ 0; + + winner_index = min_log2 (zbm[0]) >> 2; + winner_index = zbm[1] ? (4 + (min_log2 (zbm[1]) >> 2)) : winner_index; + return kv->values[winner_index]; } #endif /* CLIB_HAVE_VEC128 */ #endif /* included_clib_pfhash_h */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */