* Ensure we cover the scenario where there is an empty node due to allocation
* failures - Move the gap wherever it can go and free this node.
*/
+static inline void mas_rebalance(struct ma_state *mas);
static inline void mas_may_move_gap(struct ma_state *mas)
{
unsigned char end;
unsigned char new_end;
unsigned char slot = mas_get_slot(mas);
+ struct maple_enode *mn = NULL;
void *entry = NULL;
void *next_entry = NULL;
bool empty = false;
mas_ascend(&parent);
mte_set_rcu_slot(parent.node, slot, next.node);
mas_set_safe_pivot(&parent, slot, next.max);
+ mn = parent.node;
next.min = curr.min;
curr.max = curr.min;
mas_shift_pivot(&curr, &next, next.max);
mas_update_gap(&next, false);
}
-
slot = mte_parent_slot(next.node);
mas_dup_state(&parent, &next);
mas_ascend(&parent);
- mte_set_rcu_slot(parent.node, slot, XA_RETRY_ENTRY);
+ mte_set_rcu_slot(parent.node, slot, XA_SKIP_ENTRY); // relocated.
+ mte_set_parent(next.node, mn, mte_parent_slot(curr.node));
mte_free(curr.node);
+ mas_rebalance(&parent);
mas_dup_state(mas, &next);
}
set[i+2]);
while (!mas_is_none(&mas_start) &&
(mas_start.last != e_max) ) {
- if (s_entry) {
+ if (mas_retry(&mas, s_entry))
+ continue;
+ if (s_entry)
cnt++;
- }
+
s_entry = mas_next(&mas_start,
set[i+2]);
}
MT_BUG_ON(mt, entry != NULL);
else
MT_BUG_ON(mt, xa_mk_value(i) != entry);
- mas.index = mas.max = i;
}
rcu_read_unlock();
mtree_destroy(mt);
entry = mas_next(&mas, ULONG_MAX);
MT_BUG_ON(mt, entry != xa_mk_value(index + 3));
mn2 = mas.node;
- MT_BUG_ON(mt, mn1 == mn2);
+ MT_BUG_ON(mt, mn1 == mn2); // test the test.
// At this point, there is a gap of 2 in either 1 or 2 nodes. Find a
// gap of size 2 from 100 down to 50.
/* Clear out the tree */
mtree_destroy(&tree);
+
mtree_init(&tree, 0);
check_erase_testset(&tree);
mtree_destroy(&tree);