X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Fcommon%2Fhashtable%2Fhashtable.c;h=8f2f2bf03221944d9297cc89fb4e146e672b58cb;hb=f250226cca7c22ed6d6080cd21f2acbc23ba6deb;hp=8c26ebe15b63d3a71f2efd40398e2781e5ddbb59;hpb=42305b3673038da331e5a65093a803f9a9da9946;p=lttng-tools.git diff --git a/src/common/hashtable/hashtable.c b/src/common/hashtable/hashtable.c index 8c26ebe15..8f2f2bf03 100644 --- a/src/common/hashtable/hashtable.c +++ b/src/common/hashtable/hashtable.c @@ -32,6 +32,13 @@ unsigned long lttng_ht_seed; static unsigned long min_hash_alloc_size = 1; static unsigned long max_hash_buckets_size = 0; +/* + * Getter/lookup functions need to be called with RCU read-side lock + * held. However, modification functions (add, add_unique, replace, del) + * take the RCU lock internally, so it does not matter whether the + * caller hold the RCU lock or not. + */ + /* * Match function for string node. */ @@ -65,6 +72,17 @@ static int match_u64(struct cds_lfht_node *node, const void *key) return hash_match_key_u64(&match_node->key, (void *) key); } +/* + * Match function for two uint64_t node. + */ +static int match_two_u64(struct cds_lfht_node *node, const void *key) +{ + struct lttng_ht_node_two_u64 *match_node = + caa_container_of(node, struct lttng_ht_node_two_u64, node); + + return hash_match_key_two_u64((void *) &match_node->key, (void *) key); +} + /* * Return an allocated lttng hashtable. */ @@ -103,6 +121,10 @@ struct lttng_ht *lttng_ht_new(unsigned long size, int type) ht->match_fct = match_u64; ht->hash_fct = hash_key_u64; break; + case LTTNG_HT_TYPE_TWO_U64: + ht->match_fct = match_two_u64; + ht->hash_fct = hash_key_two_u64; + break; default: ERR("Unknown lttng hashtable type %d", type); lttng_ht_destroy(ht); @@ -164,6 +186,19 @@ void lttng_ht_node_init_u64(struct lttng_ht_node_u64 *node, cds_lfht_node_init(&node->node); } +/* + * Init lttng ht node with two uint64_t. + */ +void lttng_ht_node_init_two_u64(struct lttng_ht_node_two_u64 *node, + uint64_t key1, uint64_t key2) +{ + assert(node); + + node->key.key1 = key1; + node->key.key2 = key2; + cds_lfht_node_init(&node->node); +} + /* * Free lttng ht node string. */ @@ -191,6 +226,15 @@ void lttng_ht_node_free_u64(struct lttng_ht_node_u64 *node) free(node); } +/* + * Free lttng ht node two uint64_t. + */ +void lttng_ht_node_free_two_u64(struct lttng_ht_node_two_u64 *node) +{ + assert(node); + free(node); +} + /* * Lookup function in hashtable. */ @@ -215,11 +259,31 @@ void lttng_ht_add_unique_str(struct lttng_ht *ht, assert(ht->ht); assert(node); + /* RCU read lock protects from ABA. */ + rcu_read_lock(); node_ptr = cds_lfht_add_unique(ht->ht, ht->hash_fct(node->key, lttng_ht_seed), ht->match_fct, node->key, &node->node); + rcu_read_unlock(); assert(node_ptr == &node->node); } +/* + * Add string node to hashtable. + */ +void lttng_ht_add_str(struct lttng_ht *ht, + struct lttng_ht_node_str *node) +{ + assert(ht); + assert(ht->ht); + assert(node); + + /* RCU read lock protects from ABA. */ + rcu_read_lock(); + cds_lfht_add(ht->ht, ht->hash_fct(node->key, lttng_ht_seed), + &node->node); + rcu_read_unlock(); +} + /* * Add unsigned long node to hashtable. */ @@ -229,8 +293,11 @@ void lttng_ht_add_ulong(struct lttng_ht *ht, struct lttng_ht_node_ulong *node) assert(ht->ht); assert(node); + /* RCU read lock protects from ABA. */ + rcu_read_lock(); cds_lfht_add(ht->ht, ht->hash_fct((void *) node->key, lttng_ht_seed), &node->node); + rcu_read_unlock(); } /* @@ -243,8 +310,11 @@ void lttng_ht_add_u64(struct lttng_ht *ht, struct lttng_ht_node_u64 *node) assert(ht->ht); assert(node); + /* RCU read lock protects from ABA. */ + rcu_read_lock(); cds_lfht_add(ht->ht, ht->hash_fct(&node->key, lttng_ht_seed), &node->node); + rcu_read_unlock(); } /* @@ -258,9 +328,12 @@ void lttng_ht_add_unique_ulong(struct lttng_ht *ht, assert(ht->ht); assert(node); + /* RCU read lock protects from ABA. */ + rcu_read_lock(); node_ptr = cds_lfht_add_unique(ht->ht, ht->hash_fct((void *) node->key, lttng_ht_seed), ht->match_fct, (void *) node->key, &node->node); + rcu_read_unlock(); assert(node_ptr == &node->node); } @@ -275,9 +348,32 @@ void lttng_ht_add_unique_u64(struct lttng_ht *ht, assert(ht->ht); assert(node); + /* RCU read lock protects from ABA. */ + rcu_read_lock(); node_ptr = cds_lfht_add_unique(ht->ht, ht->hash_fct(&node->key, lttng_ht_seed), ht->match_fct, &node->key, &node->node); + rcu_read_unlock(); + assert(node_ptr == &node->node); +} + +/* + * Add unique two uint64_t node to hashtable. + */ +void lttng_ht_add_unique_two_u64(struct lttng_ht *ht, + struct lttng_ht_node_two_u64 *node) +{ + struct cds_lfht_node *node_ptr; + assert(ht); + assert(ht->ht); + assert(node); + + /* RCU read lock protects from ABA. */ + rcu_read_lock(); + node_ptr = cds_lfht_add_unique(ht->ht, + ht->hash_fct((void *) &node->key, lttng_ht_seed), ht->match_fct, + (void *) &node->key, &node->node); + rcu_read_unlock(); assert(node_ptr == &node->node); } @@ -292,9 +388,12 @@ struct lttng_ht_node_ulong *lttng_ht_add_replace_ulong(struct lttng_ht *ht, assert(ht->ht); assert(node); + /* RCU read lock protects from ABA. */ + rcu_read_lock(); node_ptr = cds_lfht_add_replace(ht->ht, ht->hash_fct((void *) node->key, lttng_ht_seed), ht->match_fct, (void *) node->key, &node->node); + rcu_read_unlock(); if (!node_ptr) { return NULL; } else { @@ -314,9 +413,12 @@ struct lttng_ht_node_u64 *lttng_ht_add_replace_u64(struct lttng_ht *ht, assert(ht->ht); assert(node); + /* RCU read lock protects from ABA. */ + rcu_read_lock(); node_ptr = cds_lfht_add_replace(ht->ht, ht->hash_fct(&node->key, lttng_ht_seed), ht->match_fct, &node->key, &node->node); + rcu_read_unlock(); if (!node_ptr) { return NULL; } else { @@ -330,11 +432,17 @@ struct lttng_ht_node_u64 *lttng_ht_add_replace_u64(struct lttng_ht *ht, */ int lttng_ht_del(struct lttng_ht *ht, struct lttng_ht_iter *iter) { + int ret; + assert(ht); assert(ht->ht); assert(iter); - return cds_lfht_del(ht->ht, iter->iter.node); + /* RCU read lock protects from ABA. */ + rcu_read_lock(); + ret = cds_lfht_del(ht->ht, iter->iter.node); + rcu_read_unlock(); + return ret; } /* @@ -372,7 +480,10 @@ unsigned long lttng_ht_get_count(struct lttng_ht *ht) assert(ht); assert(ht->ht); + /* RCU read lock protects from ABA and allows RCU traversal. */ + rcu_read_lock(); cds_lfht_count_nodes(ht->ht, &scb, &count, &sca); + rcu_read_unlock(); return count; } @@ -425,6 +536,22 @@ struct lttng_ht_node_u64 *lttng_ht_iter_get_node_u64( return caa_container_of(node, struct lttng_ht_node_u64, node); } +/* + * 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); +} + /* * lib constructor */