X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=tests%2Ftest_urcu_hash.c;h=8c6f0dac218a44f30b6bd16211fd0156e8fc3943;hb=caf3653dbe9dec81dc37c8e81267f27d3163dd19;hp=87c4ad13781393a1d3aeb522f0e8c4406e52d037;hpb=04db56f85e2cd2abb05e4ef14990e99a1058d0df;p=urcu.git diff --git a/tests/test_urcu_hash.c b/tests/test_urcu_hash.c index 87c4ad1..8c6f0da 100644 --- a/tests/test_urcu_hash.c +++ b/tests/test_urcu_hash.c @@ -147,9 +147,11 @@ static unsigned long rduration; static unsigned long init_hash_size = DEFAULT_HASH_SIZE; static unsigned long min_hash_alloc_size = DEFAULT_MIN_ALLOC_SIZE; +static unsigned long max_hash_buckets_size = (1UL << 20); static unsigned long init_populate; static int opt_auto_resize; static int add_only, add_unique, add_replace; +static const struct cds_lfht_mm_type *memory_backend; static unsigned long init_pool_offset, lookup_pool_offset, write_pool_offset; static unsigned long init_pool_size = DEFAULT_RAND_POOL, @@ -384,7 +386,7 @@ void hashword2( #if (CAA_BITS_PER_LONG == 32) static -unsigned long test_hash(void *_key, size_t length, unsigned long seed) +unsigned long test_hash(const void *_key, size_t length, unsigned long seed) { unsigned int key = (unsigned int) _key; @@ -393,7 +395,7 @@ unsigned long test_hash(void *_key, size_t length, unsigned long seed) } #else static -unsigned long test_hash(void *_key, size_t length, unsigned long seed) +unsigned long test_hash(const void *_key, size_t length, unsigned long seed) { union { uint64_t v64; @@ -413,8 +415,8 @@ unsigned long test_hash(void *_key, size_t length, unsigned long seed) #endif static -unsigned long test_compare(void *key1, size_t key1_len, - void *key2, size_t key2_len) +unsigned long test_compare(const void *key1, size_t key1_len, + const void *key2, size_t key2_len) { if (caa_unlikely(key1_len != key2_len)) return -1; @@ -426,7 +428,7 @@ unsigned long test_compare(void *key1, size_t key1_len, } static -int test_match(struct cds_lfht_node *node, void *key) +int test_match(struct cds_lfht_node *node, const void *key) { struct lfht_test_node *test_node = to_test_node(node); @@ -434,15 +436,14 @@ int test_match(struct cds_lfht_node *node, void *key) key, sizeof(unsigned long)); } -static +static inline void cds_lfht_test_lookup(struct cds_lfht *ht, void *key, size_t key_len, struct cds_lfht_iter *iter) { assert(key_len == sizeof(unsigned long)); - cds_lfht_lookup(ht, test_match, - test_hash(key, key_len, TEST_HASH_SEED), - key, iter); + cds_lfht_lookup(ht, test_hash(key, key_len, TEST_HASH_SEED), + test_match, key, iter); } void *thr_count(void *arg) @@ -453,7 +454,7 @@ void *thr_count(void *arg) rcu_register_thread(); for (;;) { - unsigned long count, removed; + unsigned long count; long approx_before, approx_after; ssize_t len; char buf[1]; @@ -469,15 +470,15 @@ void *thr_count(void *arg) printf("Counting nodes... "); fflush(stdout); rcu_read_lock(); - cds_lfht_count_nodes(test_ht, &approx_before, &count, &removed, + cds_lfht_count_nodes(test_ht, &approx_before, &count, &approx_after); rcu_read_unlock(); printf("done.\n"); printf("Approximation before node accounting: %ld nodes.\n", approx_before); printf("Accounting of nodes in the hash table: " - "%lu nodes + %lu logically removed.\n", - count, removed); + "%lu nodes.\n", + count); printf("Approximation after node accounting: %ld nodes.\n", approx_after); } @@ -577,14 +578,14 @@ void *thr_writer(void *_count) sizeof(void *)); rcu_read_lock(); if (add_unique) { - ret_node = cds_lfht_add_unique(test_ht, test_match, node->key, + ret_node = cds_lfht_add_unique(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), - &node->node); + test_match, node->key, &node->node); } else { if (add_replace) - ret_node = cds_lfht_add_replace(test_ht, test_match, node->key, + ret_node = cds_lfht_add_replace(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), - &node->node); + test_match, node->key, &node->node); else cds_lfht_add(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), @@ -674,14 +675,14 @@ static int populate_hash(void) sizeof(void *)); rcu_read_lock(); if (add_unique) { - ret_node = cds_lfht_add_unique(test_ht, test_match, node->key, + ret_node = cds_lfht_add_unique(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), - &node->node); + test_match, node->key, &node->node); } else { if (add_replace) - ret_node = cds_lfht_add_replace(test_ht, test_match, node->key, + ret_node = cds_lfht_add_replace(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), - &node->node); + test_match, node->key, &node->node); else cds_lfht_add(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), @@ -711,14 +712,12 @@ void test_delete_all_nodes(struct cds_lfht *ht) struct lfht_test_node *node; unsigned long count = 0; - cds_lfht_first(ht, &iter); - while ((node = cds_lfht_iter_get_test_node(&iter)) != NULL) { + cds_lfht_for_each_entry(ht, &iter, node, node) { int ret; ret = cds_lfht_del(test_ht, &iter); assert(!ret); call_rcu(&node->head, free_node_cb); - cds_lfht_next(ht, &iter); count++; } printf("deleted %lu nodes.\n", count); @@ -734,14 +733,16 @@ void show_usage(int argc, char **argv) printf(" [-c duration] (reader C.S. duration (in loops))\n"); printf(" [-v] (verbose output)\n"); printf(" [-a cpu#] [-a cpu#]... (affinity)\n"); - printf(" [-h size] (initial hash table size)\n"); - printf(" [-m size] (minimum hash alloc size)\n"); + printf(" [-h size] (initial number of buckets)\n"); + printf(" [-m size] (minimum number of allocated buckets)\n"); + printf(" [-n size] (maximum number of buckets)\n"); printf(" [not -u nor -s] Add entries (supports redundant keys).\n"); printf(" [-u] Uniquify add (no redundant keys).\n"); printf(" [-s] Replace (swap) entries.\n"); printf(" [-i] Add only (no removal).\n"); printf(" [-k nr_nodes] Number of nodes to insert initially.\n"); printf(" [-A] Automatically resize hash table.\n"); + printf(" [-B order|chunk|mmap] Specify the memory backend.\n"); printf(" [-R offset] Lookup pool offset.\n"); printf(" [-S offset] Write pool offset.\n"); printf(" [-T offset] Init pool offset.\n"); @@ -762,7 +763,7 @@ int main(int argc, char **argv) struct wr_count *count_writer; unsigned long long tot_reads = 0, tot_writes = 0, tot_add = 0, tot_add_exist = 0, tot_remove = 0; - unsigned long count, removed; + unsigned long count; long approx_before, approx_after; int i, a, ret; struct sigaction act; @@ -844,6 +845,13 @@ int main(int argc, char **argv) } min_hash_alloc_size = atol(argv[++i]); break; + case 'n': + if (argc < i + 2) { + show_usage(argc, argv); + return -1; + } + max_hash_buckets_size = atol(argv[++i]); + break; case 'u': if (add_replace) { printf("Please specify at most one of -s or -u.\n"); @@ -867,6 +875,23 @@ int main(int argc, char **argv) case 'A': opt_auto_resize = 1; break; + case 'B': + if (argc < i + 2) { + show_usage(argc, argv); + return -1; + } + i++; + if (!strcmp("order", argv[i])) + memory_backend = &cds_lfht_mm_order; + else if (!strcmp("chunk", argv[i])) + memory_backend = &cds_lfht_mm_chunk; + else if (!strcmp("mmap", argv[i])) + memory_backend = &cds_lfht_mm_mmap; + else { + printf("Please specify memory backend with order|chunk|mmap.\n"); + exit(-1); + } + break; case 'R': lookup_pool_offset = atol(argv[++i]); break; @@ -894,17 +919,23 @@ int main(int argc, char **argv) /* Check if hash size is power of 2 */ if (init_hash_size && init_hash_size & (init_hash_size - 1)) { - printf("Error: Hash table size %lu is not a power of 2.\n", + printf("Error: Initial number of buckets (%lu) is not a power of 2.\n", init_hash_size); return -1; } - if (min_hash_alloc_size && min_hash_alloc_size * (min_hash_alloc_size - 1)) { - printf("Error: Min hash alloc size %lu is not a power of 2.\n", + if (min_hash_alloc_size && min_hash_alloc_size & (min_hash_alloc_size - 1)) { + printf("Error: Minimum number of allocated buckets (%lu) is not a power of 2.\n", min_hash_alloc_size); return -1; } + if (max_hash_buckets_size && max_hash_buckets_size & (max_hash_buckets_size - 1)) { + printf("Error: Maximum number of buckets (%lu) is not a power of 2.\n", + max_hash_buckets_size); + return -1; + } + memset(&act, 0, sizeof(act)); ret = sigemptyset(&act.sa_mask); if (ret == -1) { @@ -946,8 +977,9 @@ int main(int argc, char **argv) printf_verbose("Mode:%s%s.\n", add_only ? " add only" : " add/remove", add_unique ? " uniquify" : ( add_replace ? " replace" : " insert")); - printf_verbose("Initial hash table size: %lu buckets.\n", init_hash_size); - printf_verbose("Minimum hash alloc size: %lu buckets.\n", min_hash_alloc_size); + printf_verbose("Initial number of buckets: %lu buckets.\n", init_hash_size); + printf_verbose("Minimum number of allocated buckets: %lu buckets.\n", min_hash_alloc_size); + printf_verbose("Maximum number of buckets: %lu buckets.\n", max_hash_buckets_size); printf_verbose("Init pool size offset %lu size %lu.\n", init_pool_offset, init_pool_size); printf_verbose("Lookup pool size offset %lu size %lu.\n", @@ -965,14 +997,24 @@ int main(int argc, char **argv) err = create_all_cpu_call_rcu_data(0); assert(!err); + if (memory_backend) { + test_ht = _cds_lfht_new(init_hash_size, min_hash_alloc_size, + max_hash_buckets_size, + (opt_auto_resize ? CDS_LFHT_AUTO_RESIZE : 0) | + CDS_LFHT_ACCOUNTING, memory_backend, + &rcu_flavor, NULL); + } else { + test_ht = cds_lfht_new(init_hash_size, min_hash_alloc_size, + max_hash_buckets_size, + (opt_auto_resize ? CDS_LFHT_AUTO_RESIZE : 0) | + CDS_LFHT_ACCOUNTING, NULL); + } + /* - * Hash creation and population needs to be seen as a RCU reader + * Hash Population needs to be seen as a RCU reader * thread from the point of view of resize. */ rcu_register_thread(); - test_ht = cds_lfht_new(init_hash_size, min_hash_alloc_size, - (opt_auto_resize ? CDS_LFHT_AUTO_RESIZE : 0) | - CDS_LFHT_ACCOUNTING, NULL); ret = populate_hash(); assert(!ret); @@ -1044,18 +1086,17 @@ int main(int argc, char **argv) rcu_thread_online(); rcu_read_lock(); printf("Counting nodes... "); - cds_lfht_count_nodes(test_ht, &approx_before, &count, &removed, - &approx_after); + cds_lfht_count_nodes(test_ht, &approx_before, &count, &approx_after); printf("done.\n"); test_delete_all_nodes(test_ht); rcu_read_unlock(); rcu_thread_offline(); - if (count || removed) { + if (count) { printf("Approximation before node accounting: %ld nodes.\n", approx_before); printf("Nodes deleted from hash table before destroy: " - "%lu nodes + %lu logically removed.\n", - count, removed); + "%lu nodes.\n", + count); printf("Approximation after node accounting: %ld nodes.\n", approx_after); }