/* * Return lttng ht stream and index id node from iterator. */ struct lttng_ht_node_two_u64 *lttng_ht_iter_get_node_two_u64( struct lttng_ht_iter *iter) { struct cds_lfht_node *node; assert(iter); node = cds_lfht_iter_get_node(&iter->iter); if (!node) { return NULL; } return caa_container_of(node, struct lttng_ht_node_two_u64, node); }
/* * Return lttng ht unsigned long node from iterator. */ LTTNG_HIDDEN struct lttng_ht_node_ulong *lttng_ht_iter_get_node_ulong( struct lttng_ht_iter *iter) { struct cds_lfht_node *node; assert(iter); node = cds_lfht_iter_get_node(&iter->iter); if (!node) { return NULL; } return caa_container_of(node, struct lttng_ht_node_ulong, node); }
void UA_NodeStore_iterate(const UA_NodeStore *ns, UA_NodeStore_nodeVisitor visitor) { struct cds_lfht *ht = ns->ht; struct cds_lfht_iter iter; rcu_read_lock(); cds_lfht_first(ht, &iter); while(iter.node != NULL) { struct nodeEntry *found_entry = (struct nodeEntry *)cds_lfht_iter_get_node(&iter); uatomic_inc(&found_entry->refcount); const UA_Node *node = &found_entry->node; rcu_read_unlock(); visitor(node); UA_NodeStore_release((const UA_Node *)node); rcu_read_lock(); cds_lfht_next(ht, &iter); } rcu_read_unlock(); }
const UA_Node * UA_NodeStore_get(const UA_NodeStore *ns, const UA_NodeId *nodeid) { hash_t nhash = hash(nodeid); struct cds_lfht_iter iter; rcu_read_lock(); cds_lfht_lookup(ns->ht, nhash, compare, nodeid, &iter); struct nodeEntry *found_entry = (struct nodeEntry *)cds_lfht_iter_get_node(&iter); if(!found_entry) { rcu_read_unlock(); return NULL; } /* This is done within a read-lock. The node will not be marked dead within a read-lock. */ uatomic_inc(&found_entry->refcount); rcu_read_unlock(); return &found_entry->node; }
void *test_hash_rw_thr_writer(void *_count) { struct lfht_test_node *node; struct cds_lfht_node *ret_node; struct cds_lfht_iter iter; struct wr_count *count = _count; int ret; printf_verbose("thread_begin %s, tid %lu\n", "writer", urcu_get_thread_id()); URCU_TLS(rand_lookup) = urcu_get_thread_id() ^ time(NULL); set_affinity(); rcu_register_thread(); while (!test_go) { } cmm_smp_mb(); for (;;) { if ((addremove == AR_ADD || add_only) || (addremove == AR_RANDOM && rand_r(&URCU_TLS(rand_lookup)) & 1)) { node = malloc(sizeof(struct lfht_test_node)); lfht_test_node_init(node, (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), sizeof(void *)); rcu_read_lock(); if (add_unique) { ret_node = cds_lfht_add_unique(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), test_match, node->key, &node->node); } else { if (add_replace) ret_node = cds_lfht_add_replace(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), test_match, node->key, &node->node); else cds_lfht_add(test_ht, test_hash(node->key, node->key_len, TEST_HASH_SEED), &node->node); } rcu_read_unlock(); if (add_unique && ret_node != &node->node) { free(node); URCU_TLS(nr_addexist)++; } else { if (add_replace && ret_node) { call_rcu(&to_test_node(ret_node)->head, free_node_cb); URCU_TLS(nr_addexist)++; } else { URCU_TLS(nr_add)++; } } } else { /* May delete */ rcu_read_lock(); cds_lfht_test_lookup(test_ht, (void *)(((unsigned long) rand_r(&URCU_TLS(rand_lookup)) % write_pool_size) + write_pool_offset), sizeof(void *), &iter); ret = cds_lfht_del(test_ht, cds_lfht_iter_get_node(&iter)); rcu_read_unlock(); if (ret == 0) { node = cds_lfht_iter_get_test_node(&iter); call_rcu(&node->head, free_node_cb); URCU_TLS(nr_del)++; } else URCU_TLS(nr_delnoent)++; } #if 0 //if (URCU_TLS(nr_writes) % 100000 == 0) { if (URCU_TLS(nr_writes) % 1000 == 0) { rcu_read_lock(); if (rand_r(&URCU_TLS(rand_lookup)) & 1) { ht_resize(test_ht, 1); } else { ht_resize(test_ht, -1); } rcu_read_unlock(); } #endif //0 URCU_TLS(nr_writes)++; if (caa_unlikely(!test_duration_write())) break; if (caa_unlikely(wdelay)) loop_sleep(wdelay); if (caa_unlikely((URCU_TLS(nr_writes) & ((1 << 10) - 1)) == 0)) rcu_quiescent_state(); } rcu_unregister_thread(); printf_verbose("thread_end %s, tid %lu\n", "writer", urcu_get_thread_id()); printf_verbose("info tid %lu: nr_add %lu, nr_addexist %lu, nr_del %lu, " "nr_delnoent %lu\n", urcu_get_thread_id(), URCU_TLS(nr_add), URCU_TLS(nr_addexist), URCU_TLS(nr_del), URCU_TLS(nr_delnoent)); count->update_ops = URCU_TLS(nr_writes); count->add = URCU_TLS(nr_add); count->add_exist = URCU_TLS(nr_addexist); count->remove = URCU_TLS(nr_del); return ((void*)2); }