return calloc(1, sizeof(struct rcu_rbtree_node));
}
-void rbtree_free(void *node)
+void rbtree_free(struct rcu_head *head)
{
+ struct rcu_rbtree_node *node =
+ caa_container_of(head, struct rcu_rbtree_node, head);
free(node);
}
set_affinity();
- rcu_defer_register_thread();
+ rcu_register_thread();
while (!test_go)
{
node = rcu_rbtree_search(&rbtree, rbtree.root, key[i]);
assert(!rcu_rbtree_is_nil(node));
rcu_rbtree_remove(&rbtree, node);
- defer_rcu((void (*)(void *))rbtree_free, node);
+ call_rcu(&node->head, rbtree_free);
}
rcu_read_unlock();
loop_sleep(wdelay);
}
- rcu_defer_unregister_thread();
+ rcu_unregister_thread();
printf_verbose("thread_end %s, thread id : %lx, tid %lu\n",
"writer", pthread_self(), (unsigned long)gettid());
#include <urcu/rcurbtree.h>
#include <urcu-pointer.h>
-#include <urcu-defer.h>
+#include <urcu-call-rcu.h>
#define DEBUG
memcpy(xc, x, sizeof(struct rcu_rbtree_node));
xc->decay_next = NULL;
set_decay(x, xc);
- defer_rcu(rbtree->rbfree, x);
+ call_rcu(&x->head, rbtree->rbfree);
return xc;
}
{
dbg_printf("transplant %p\n", v->key);
- if (rcu_rbtree_is_nil(u->p))
- rbtree->root = v;
- else if (u == u->p->left) {
- u->p->left = v;
+ if (!rcu_rbtree_is_nil(v))
+ v = dup_decay_node(rbtree, v);
+
+ if (rcu_rbtree_is_nil(u->p)) {
+ v->p = u->p;
+ cmm_smp_wmb(); /* write into node before publish */
+ _CMM_STORE_SHARED(rbtree->root, v);
+ } else if (u == u->p->left) {
v->pos = IS_LEFT;
+ v->p = u->p;
+ cmm_smp_wmb(); /* write into node before publish */
+ _CMM_STORE_SHARED(u->p->left, v);
} else {
- u->p->right = v;
v->pos = IS_RIGHT;
+ v->p = u->p;
+ cmm_smp_wmb(); /* write into node before publish */
+ _CMM_STORE_SHARED(u->p->right, v);
+ }
+ /* Set children parent to new node */
+ if (!rcu_rbtree_is_nil(v)) {
+ v->right->p = v;
+ v->left->p = v;
}
- v->p = u->p;
assert(!is_decay(rbtree->root));
}
dbg_printf("remove fixup %p\n", x->key);
while (x != rbtree->root && x->color == COLOR_BLACK) {
+ assert(!is_decay(x->p));
+ assert(!is_decay(x->p->left));
if (x == x->p->left) {
struct rcu_rbtree_node *w;
&& w->right->color == COLOR_BLACK) {
w->color = COLOR_RED;
x = x->p;
+ assert(!is_decay(rbtree->root));
+ assert(!is_decay(x));
} else {
if (w->right->color == COLOR_BLACK) {
w->left->color = COLOR_BLACK;
w->color = COLOR_RED;
right_rotate(rbtree, w);
+ assert(!is_decay(rbtree->root));
x = get_decay(x);
w = x->p->right;
}
w->color = COLOR_BLACK;
x->p->color = COLOR_RED;
right_rotate(rbtree, x->p);
+ assert(!is_decay(rbtree->root));
x = get_decay(x);
w = x->p->left;
}
&& w->left->color == COLOR_BLACK) {
w->color = COLOR_RED;
x = x->p;
+ assert(!is_decay(rbtree->root));
+ assert(!is_decay(x));
} else {
if (w->left->color == COLOR_BLACK) {
w->right->color = COLOR_BLACK;
x->p->color = COLOR_BLACK;
w->left->color = COLOR_BLACK;
right_rotate(rbtree, x->p);
+ assert(!is_decay(rbtree->root));
x = rbtree->root;
}
}
dbg_printf("remove nonil %p\n", z->key);
show_tree(rbtree);
+ assert(!is_decay(z));
+ assert(!is_decay(y));
+ assert(!is_decay(y->right));
+ assert(!is_decay(y->p));
x = y->right;
+ assert(!is_decay(x));
if (y->p == z)
x->p = y;
else {
rcu_rbtree_transplant(rbtree, y, y->right);
assert(!is_decay(y));
assert(!is_decay(z));
+ assert(!is_decay(z->right));
y->right = z->right;
y->right->p = y;
}
rcu_rbtree_transplant(rbtree, z, y);
- assert(!is_decay(y));
+ y = get_decay(y);
assert(!is_decay(z));
+ assert(!is_decay(z->left));
y->left = z->left;
y->left->p = y;
y->color = z->color;
dbg_printf("remove %p\n", z->key);
show_tree(rbtree);
+ assert(!is_decay(z));
y = z;
y_original_color = y->color;
if (rcu_rbtree_is_nil(z->left)) {
rcu_rbtree_transplant(rbtree, z, z->right);
assert(!is_decay(z));
- x = z->right;
+ x = get_decay(z->right);
show_tree(rbtree);
} else if (rcu_rbtree_is_nil(z->right)) {
rcu_rbtree_transplant(rbtree, z, z->left);
assert(!is_decay(z));
- x = z->left;
+ x = get_decay(z->left);
show_tree(rbtree);
} else {
y = rcu_rbtree_min(rbtree, z->right);
+ assert(!is_decay(y));
y_original_color = y->color;
rcu_rbtree_remove_nonil(rbtree, z, y);
- assert(!is_decay(y));
- x = y->right;
+ x = get_decay(y->right);
show_tree(rbtree);
}
if (y_original_color == COLOR_BLACK)