part 2: rely on the flag for check.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
unsigned long hash;
if (!t->size) {
unsigned long hash;
if (!t->size) {
assert(dummy);
node->p.next = flag_dummy(NULL);
return node; /* Initial first add (head) */
assert(dummy);
node->p.next = flag_dummy(NULL);
return node; /* Initial first add (head) */
if (is_removed(next))
goto gc_node;
if (unique
if (is_removed(next))
goto gc_node;
if (unique
- && !clear_flag(iter)->p.dummy
&& !ht->compare_fct(node->key, node->key_len,
clear_flag(iter)->key,
clear_flag(iter)->key_len))
&& !ht->compare_fct(node->key, node->key_len,
clear_flag(iter)->key,
clear_flag(iter)->key_len))
assert(!is_removed(iter_prev));
assert(iter_prev != node);
if (!dummy)
assert(!is_removed(iter_prev));
assert(iter_prev != node);
if (!dummy)
+ node->p.next = clear_flag(iter);
- node->p.next = flag_dummy(iter);
+ node->p.next = flag_dummy(clear_flag(iter));
if (is_dummy(iter))
new_node = flag_dummy(node);
else
if (is_dummy(iter))
new_node = flag_dummy(node);
else
next = old;
if (is_removed(next))
goto end;
next = old;
if (is_removed(next))
goto end;
- assert(!node->p.dummy);
+ assert(!is_dummy(next));
old = uatomic_cmpxchg(&node->p.next, next,
flag_removed(next));
} while (old != next);
old = uatomic_cmpxchg(&node->p.next, next,
flag_removed(next));
} while (old != next);
if (i != 0 && !(i & (i - 1)))
t->size = i;
t->tbl[i] = calloc(1, sizeof(struct _rcu_ht_node));
if (i != 0 && !(i & (i - 1)))
t->size = i;
t->tbl[i] = calloc(1, sizeof(struct _rcu_ht_node));
- t->tbl[i]->p.dummy = 1;
t->tbl[i]->p.reverse_hash = bit_reverse_ulong(i);
(void) _ht_add(ht, t, t->tbl[i], 0, 1);
}
t->tbl[i]->p.reverse_hash = bit_reverse_ulong(i);
(void) _ht_add(ht, t, t->tbl[i], 0, 1);
}
struct rcu_ht_node *ht_lookup(struct rcu_ht *ht, void *key, size_t key_len)
{
struct rcu_table *t;
struct rcu_ht_node *ht_lookup(struct rcu_ht *ht, void *key, size_t key_len)
{
struct rcu_table *t;
- struct rcu_ht_node *node;
+ struct rcu_ht_node *node, *next;
unsigned long hash, reverse_hash;
hash = ht->hash_fct(key, key_len, ht->hash_seed);
unsigned long hash, reverse_hash;
hash = ht->hash_fct(key, key_len, ht->hash_seed);
- if (likely(!is_removed(rcu_dereference(node->p.next)))
- && !node->p.dummy
+ next = rcu_dereference(node->p.next);
+ if (likely(!is_removed(next))
+ && !is_dummy(next)
&& likely(!ht->compare_fct(node->key, node->key_len, key, key_len))) {
break;
}
&& likely(!ht->compare_fct(node->key, node->key_len, key, key_len))) {
break;
}
- node = clear_flag(rcu_dereference(node->p.next));
+ node = clear_flag(next);
- assert(!node || !node->p.dummy);
+ assert(!node || !is_dummy(rcu_dereference(node->p.next)));
/* Check that the table is empty */
node = t->tbl[0];
do {
/* Check that the table is empty */
node = t->tbl[0];
do {
+ node = clear_flag(node)->p.next;
+ if (!is_dummy(node))
assert(!is_removed(node));
} while (clear_flag(node));
/* Internal sanity check: all nodes left should be dummy */
for (i = 0; i < t->size; i++) {
assert(!is_removed(node));
} while (clear_flag(node));
/* Internal sanity check: all nodes left should be dummy */
for (i = 0; i < t->size; i++) {
- assert(t->tbl[i]->p.dummy);
+ assert(is_dummy(t->tbl[i]->p.next));
free(t->tbl[i]);
}
return 0;
free(t->tbl[i]);
}
return 0;
do {
next = rcu_dereference(node->p.next);
if (is_removed(next)) {
do {
next = rcu_dereference(node->p.next);
if (is_removed(next)) {
- assert(!node->p.dummy);
+ assert(!is_dummy(next));
- } else if (!node->p.dummy)
+ } else if (!is_dummy(next))
(*count)++;
node = clear_flag(next);
} while (node);
(*count)++;
node = clear_flag(next);
} while (node);
struct _rcu_ht_node {
struct rcu_ht_node *next;
unsigned long reverse_hash;
struct _rcu_ht_node {
struct rcu_ht_node *next;
unsigned long reverse_hash;
{
node->key = key;
node->key_len = key_len;
{
node->key = key;
node->key_len = key_len;