提交 0e9d895b 创建 作者: David Benjamin's avatar David Benjamin

Move cleanup to radix_node destructor

When large chunks of tree get RCU-freed, we'll detach them and only gc_delayed() the root.
上级 eae77331
......@@ -114,6 +114,8 @@ public:
assert(is_node());
return reinterpret_cast<radix_node*>(ptr());
}
void release();
private:
uptr value_;
};
......@@ -151,8 +153,8 @@ struct radix_node : public rcu_freed {
radix_ptr child[1 << bits_per_level];
radix_node() : rcu_freed("radix_node") {
}
~radix_node();
void delete_tree(u32 level);
virtual void do_gc() { delete this; }
NEW_DELETE_OPS(radix_node)
......
......@@ -55,27 +55,26 @@ descend(u64 key, radix_ptr *n, u32 level, CB cb, bool create)
}
void
radix_node::delete_tree(u32 level)
radix_entry::release()
{
if (is_null()) return;
if (is_node()) {
node()->do_gc();
} else {
elem()->decref();
}
}
radix_node::~radix_node()
{
// FIXME: Put this in the destructor and stuff. Maybe even make the
// dispatch a method of radix_entry. Could even make radix_entry a
// unique_ptr-type of thing, but that's probably a bit much.
for (int i = 0; i < (1<<bits_per_level); i++) {
radix_entry entry = child[i].load();
if (!entry.is_null()) {
if (entry.is_node())
entry.node()->delete_tree(level-1);
else
entry.elem()->decref();
}
child[i].load().release();
}
do_gc();
}
radix::~radix()
{
// FIXME: See above
root_.load().node()->delete_tree(radix_levels);
root_.load().release();
}
radix_elem*
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论