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