#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
+#define REMOVED_FLAG (1UL << 0)
+#define FLAGS_MASK ((1UL << 1) - 1)
+
struct rcu_table {
unsigned long size; /* always a power of 2 */
unsigned long resize_target;
static
struct rcu_ht_node *clear_flag(struct rcu_ht_node *node)
{
- return (struct rcu_ht_node *) (((unsigned long) node) & ~0x1);
+ return (struct rcu_ht_node *) (((unsigned long) node) & ~FLAGS_MASK);
}
static
int is_removed(struct rcu_ht_node *node)
{
- return ((unsigned long) node) & 0x1;
+ return ((unsigned long) node) & REMOVED_FLAG;
}
static
struct rcu_ht_node *flag_removed(struct rcu_ht_node *node)
{
- return (struct rcu_ht_node *) (((unsigned long) node) | 0x1);
+ return (struct rcu_ht_node *) (((unsigned long) node) | REMOVED_FLAG);
}
static
iter = rcu_dereference(iter_prev->p.next);
assert(iter_prev->p.reverse_hash <= node->p.reverse_hash);
for (;;) {
- if (unlikely(!iter))
+ if (unlikely(!clear_flag(iter)))
return;
if (clear_flag(iter)->p.reverse_hash > node->p.reverse_hash)
return;
iter = rcu_dereference(iter_prev->p.next);
assert(iter_prev->p.reverse_hash <= node->p.reverse_hash);
for (;;) {
- if (unlikely(!iter))
+ if (unlikely(!clear_flag(iter)))
goto insert;
if (clear_flag(iter)->p.reverse_hash > node->p.reverse_hash)
goto insert;
return -EPERM;
node = node->p.next;
assert(!is_removed(node));
- } while (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);