/* * TODO: slab should be freed when entries in the slab drop to zero, * or as an alternative, have a free list for slabs so they can be * reused if new fi_av_insert operations are performed. */ static int map_remove(struct gnix_fid_av *av_priv, fi_addr_t *fi_addr, size_t count, uint64_t flags) { int i,ret = FI_SUCCESS; struct gnix_av_addr_entry *the_entry = NULL; gnix_ht_key_t key; for (i = 0; i < count; i++) { key = *(gnix_ht_key_t *)&fi_addr[i]; /* * first see if we have this entry in the hash * TODO: is there a race condition here for multi-threaded? */ the_entry = _gnix_ht_lookup(av_priv->map_ht, key); if (the_entry == NULL) return -FI_ENOENT; ret = _gnix_ht_remove(av_priv->map_ht, key); } return ret; }
Test(gnix_hashtable_locked, iterate) { int ret, i; gnix_test_element_t test_elements[1024]; gnix_test_element_t *item; char test_elements_found[1024] = {0}; srand(time(NULL)); for (i = 0; i < 1024; ++i) { item = &test_elements[i]; item->key = i; item->val = rand() % (1024 * 1024); item->magic = __GNIX_MAGIC_VALUE; } for (i = 0; i < 1024; ++i) { item = &test_elements[i]; ret = _gnix_ht_insert(test_ht, item->key, item); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == (i + 1)); } { GNIX_HASHTABLE_ITERATOR(test_ht, iter); for (i = 0; i < 1024; ++i) { item = (gnix_test_element_t *) _gnix_ht_iterator_next(&iter); cr_assert(item); cr_assert(!test_elements_found[item->key]); test_elements_found[item->key] = 1; } } for (i = 1023; i >= 0; --i) { item = &test_elements[i]; cr_assert(i == item->key); ret = _gnix_ht_remove(test_ht, item->key); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == i); } cr_assert(atomic_get(&test_ht->ht_elements) == 0); }
Test(gnix_hashtable_advanced, insert_1_remove_1) { int ret; srand(time(NULL)); ret = _gnix_ht_insert(test_ht, simple_element->key, simple_element); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == 1); ret = _gnix_ht_remove(test_ht, simple_element->key); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == 0); }
Test(gnix_hashtable_advanced, insert_2048_remove_all_resize_down) { int ret, i; int nelem = 2048; gnix_test_element_t test_elements[2048]; gnix_test_element_t *item; srand(time(NULL)); for (i = 0; i < nelem; ++i) { item = &test_elements[i]; item->key = i; item->val = rand() % (1024 * 1024); item->magic = __GNIX_MAGIC_VALUE; } for (i = 0; i < nelem; ++i) { item = &test_elements[i]; ret = _gnix_ht_insert(test_ht, item->key, item); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == (i + 1)); } cr_assert(test_ht->ht_size > test_ht->ht_attr.ht_initial_size); for (i = nelem - 1; i >= 0; --i) { item = &test_elements[i]; cr_assert(i == item->key); ret = _gnix_ht_remove(test_ht, item->key); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == i); } cr_assert(atomic_get(&test_ht->ht_elements) == 0); /* on default settings, the hash table should resize to initial on * removal of all elements */ cr_assert(test_ht->ht_size == test_ht->ht_attr.ht_initial_size); }
Test(gnix_hashtable_advanced, insert_1024_remove_1024) { int ret, i; gnix_test_element_t test_elements[1024]; gnix_test_element_t *item; srand(time(NULL)); for (i = 0; i < 1024; ++i) { item = &test_elements[i]; item->key = i; item->val = rand() % (1024 * 1024); item->magic = __GNIX_MAGIC_VALUE; } for (i = 0; i < 1024; ++i) { item = &test_elements[i]; ret = _gnix_ht_insert(test_ht, item->key, item); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == (i + 1)); } for (i = 1023; i >= 0; --i) { item = &test_elements[i]; cr_assert(i == item->key); ret = _gnix_ht_remove(test_ht, item->key); cr_assert(ret == 0); cr_assert(atomic_get(&test_ht->ht_elements) == i); } cr_assert(atomic_get(&test_ht->ht_elements) == 0); }
static void __ep_destruct(void *obj) { int __attribute__((unused)) ret; struct gnix_fid_domain *domain; struct gnix_nic *nic; struct gnix_fid_av *av; struct gnix_cm_nic *cm_nic; gnix_ht_key_t *key_ptr; struct gnix_fid_ep *ep = (struct gnix_fid_ep *) obj; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); /* * clean up any vc hash table or vector, * remove entry from addr_to_ep ht. * any outstanding GNI internal requests on * the VC's will be completed prior to * destroying the VC entries in the ht. */ if (ep->type == FI_EP_RDM) { key_ptr = (gnix_ht_key_t *)&ep->my_name.gnix_addr; ret = _gnix_ht_remove(ep->cm_nic->addr_to_ep_ht, *key_ptr); if (ep->vc_ht != NULL) { ret = _gnix_ht_destroy(ep->vc_ht); if (ret == FI_SUCCESS) { free(ep->vc_ht); ep->vc_ht = NULL; } else { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_ht_destroy returned %s\n", fi_strerror(-ret)); } } } if (ep->send_cq) { _gnix_cq_poll_nic_rem(ep->send_cq, ep->nic); _gnix_ref_put(ep->send_cq); } if (ep->recv_cq) { _gnix_cq_poll_nic_rem(ep->recv_cq, ep->nic); _gnix_ref_put(ep->recv_cq); } if (ep->send_cntr) { _gnix_cntr_poll_nic_rem(ep->send_cntr, ep->nic); _gnix_ref_put(ep->send_cntr); } if (ep->recv_cntr) { _gnix_cntr_poll_nic_rem(ep->recv_cntr, ep->nic); _gnix_ref_put(ep->recv_cntr); } if (ep->read_cntr) { _gnix_cntr_poll_nic_rem(ep->read_cntr, ep->nic); _gnix_ref_put(ep->read_cntr); } if (ep->write_cntr) { _gnix_cntr_poll_nic_rem(ep->write_cntr, ep->nic); _gnix_ref_put(ep->write_cntr); } if (ep->stx_ctx) _gnix_ref_put(ep->stx_ctx); domain = ep->domain; assert(domain != NULL); _gnix_ref_put(domain); cm_nic = ep->cm_nic; assert(cm_nic != NULL); nic = ep->nic; assert(nic != NULL); av = ep->av; if (av != NULL) _gnix_ref_put(av); /* There is no other choice here, we need to assert if we can't free */ ret = _gnix_nic_free(nic); assert(ret == FI_SUCCESS); ep->nic = NULL; /* This currently always returns FI_SUCCESS */ ret = _gnix_cm_nic_free(cm_nic); assert(ret == FI_SUCCESS); /* * Free fab_reqs */ __fr_freelist_destroy(ep); free(ep); }