int rte_hash_lookup_bulk(const struct rte_hash *h, const void **keys, uint32_t num_keys, int32_t *positions) { uint32_t i, j, bucket_index; hash_sig_t sigs[RTE_HASH_LOOKUP_BULK_MAX]; RETURN_IF_TRUE(((h == NULL) || (keys == NULL) || (num_keys == 0) || (num_keys > RTE_HASH_LOOKUP_BULK_MAX) || (positions == NULL)), -EINVAL); /* Get the hash signature and bucket index */ for (i = 0; i < num_keys; i++) { sigs[i] = h->hash_func(keys[i], h->key_len, h->hash_func_init_val) | h->sig_msb; bucket_index = sigs[i] & h->bucket_bitmask; /* Pre-fetch relevant buckets */ rte_prefetch1((void *) get_sig_tbl_bucket(h, bucket_index)); rte_prefetch1((void *) get_key_tbl_bucket(h, bucket_index)); } /* Check if key is already present in the hash */ for (i = 0; i < num_keys; i++) { bucket_index = sigs[i] & h->bucket_bitmask; hash_sig_t *sig_bucket = get_sig_tbl_bucket(h, bucket_index); uint8_t *key_bucket = get_key_tbl_bucket(h, bucket_index); positions[i] = -ENOENT; for (j = 0; j < h->bucket_entries; j++) { if ((sigs[i] == sig_bucket[j]) && likely(memcmp(keys[i], get_key_from_bucket(h, key_bucket, j), h->key_len) == 0)) { positions[i] = bucket_index * h->bucket_entries + j; break; } } } return 0; }
int test_prefetch(void) { int a; rte_prefetch0(&a); rte_prefetch1(&a); rte_prefetch2(&a); return 0; }