projects
/
urcu.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
cds_lfht_replace: add checks for old/new node hash/value match
[urcu.git]
/
rculfhash.c
diff --git
a/rculfhash.c
b/rculfhash.c
index 8f2d8e4480fda449fbe6dd9de2bb69a2659d8643..1eda2dd858981477041fcdcee252c78d224127c2 100644
(file)
--- a/
rculfhash.c
+++ b/
rculfhash.c
@@
-1517,25
+1517,36
@@
struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht,
}
}
}
}
-int cds_lfht_replace(struct cds_lfht *ht, struct cds_lfht_iter *old_iter,
+int cds_lfht_replace(struct cds_lfht *ht,
+ struct cds_lfht_iter *old_iter,
+ unsigned long hash,
+ cds_lfht_match_fct match,
+ const void *key,
struct cds_lfht_node *new_node)
{
unsigned long size;
struct cds_lfht_node *new_node)
{
unsigned long size;
+ new_node->reverse_hash = bit_reverse_ulong((unsigned long) hash);
+ if (!old_iter->node)
+ return -ENOENT;
+ if (caa_unlikely(old_iter->node->reverse_hash != new_node->reverse_hash))
+ return -EINVAL;
+ if (caa_unlikely(!match(old_iter->node, key)))
+ return -EINVAL;
size = rcu_dereference(ht->size);
return _cds_lfht_replace(ht, size, old_iter->node, old_iter->next,
new_node);
}
size = rcu_dereference(ht->size);
return _cds_lfht_replace(ht, size, old_iter->node, old_iter->next,
new_node);
}
-int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_
iter *iter
)
+int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_
node *node
)
{
unsigned long size, hash;
int ret;
size = rcu_dereference(ht->size);
{
unsigned long size, hash;
int ret;
size = rcu_dereference(ht->size);
- ret = _cds_lfht_del(ht, size,
iter->
node);
+ ret = _cds_lfht_del(ht, size, node);
if (!ret) {
if (!ret) {
- hash = bit_reverse_ulong(
iter->
node->reverse_hash);
+ hash = bit_reverse_ulong(node->reverse_hash);
ht_count_del(ht, size, hash);
}
return ret;
ht_count_del(ht, size, hash);
}
return ret;
@@
-1600,11
+1611,10
@@
int cds_lfht_destroy(struct cds_lfht *ht, pthread_attr_t **attr)
void cds_lfht_count_nodes(struct cds_lfht *ht,
long *approx_before,
unsigned long *count,
void cds_lfht_count_nodes(struct cds_lfht *ht,
long *approx_before,
unsigned long *count,
- unsigned long *removed,
long *approx_after)
{
struct cds_lfht_node *node, *next;
long *approx_after)
{
struct cds_lfht_node *node, *next;
- unsigned long nr_bucket = 0;
+ unsigned long nr_bucket = 0
, nr_removed = 0
;
*approx_before = 0;
if (ht->split_count) {
*approx_before = 0;
if (ht->split_count) {
@@
-1617,7
+1627,6
@@
void cds_lfht_count_nodes(struct cds_lfht *ht,
}
*count = 0;
}
*count = 0;
- *removed = 0;
/* Count non-bucket nodes in the table */
node = bucket_at(ht, 0);
/* Count non-bucket nodes in the table */
node = bucket_at(ht, 0);
@@
-1625,7
+1634,7
@@
void cds_lfht_count_nodes(struct cds_lfht *ht,
next = rcu_dereference(node->next);
if (is_removed(next)) {
if (!is_bucket(next))
next = rcu_dereference(node->next);
if (is_removed(next)) {
if (!is_bucket(next))
- (
*
removed)++;
+ (
nr_
removed)++;
else
(nr_bucket)++;
} else if (!is_bucket(next))
else
(nr_bucket)++;
} else if (!is_bucket(next))
@@
-1634,6
+1643,7
@@
void cds_lfht_count_nodes(struct cds_lfht *ht,
(nr_bucket)++;
node = clear_flag(next);
} while (!is_end(node));
(nr_bucket)++;
node = clear_flag(next);
} while (!is_end(node));
+ dbg_printf("number of logically removed nodes: %lu\n", nr_removed);
dbg_printf("number of bucket nodes: %lu\n", nr_bucket);
*approx_after = 0;
if (ht->split_count) {
dbg_printf("number of bucket nodes: %lu\n", nr_bucket);
*approx_after = 0;
if (ht->split_count) {
This page took
0.027302 seconds
and
4
git commands to generate.