From c3be80729095f05a052ecbc0de09a44fd39d259e Mon Sep 17 00:00:00 2001 From: Lance Roy Date: Thu, 3 Aug 2017 17:48:59 -0700 Subject: [PATCH] Use boost::compressed_pair for EBO in rcu_obj_base This fixes a discrepancy between nonempty deleters, which will get constructed when the rcu_obj_base is constructed, and empty deleters, which were only getting constructed when retire() is run. Signed-off-by: Lance Roy --- Test/paulmck/rcu.hpp | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/Test/paulmck/rcu.hpp b/Test/paulmck/rcu.hpp index 449c7dd..2d89c98 100644 --- a/Test/paulmck/rcu.hpp +++ b/Test/paulmck/rcu.hpp @@ -3,45 +3,34 @@ #include #include #include +#include #include +#include // Derived-type approach. All RCU-protected data structures using this // approach must derive from std::rcu_obj_base, which in turn derives // from std::rcu_head. No idea what happens in case of multiple inheritance. namespace std { - template, bool E = is_empty::value> - class rcu_obj_base: private rcu_head { - D deleter; - public: - void retire(D d = {}) - { - deleter = std::move(d); - ::call_rcu( - static_cast(this), - [](rcu_head *rhp) { - auto rhdp = static_cast(rhp); - auto obj = static_cast(rhdp); - rhdp->deleter(obj); - } - ); - } - }; + namespace detail { + struct rcu_obj_base_empty_type {}; + } - // Specialization for when D is an empty type. - - template - class rcu_obj_base: private rcu_head { + template> + class rcu_obj_base: + private rcu_head, + private boost::compressed_pair { public: - void retire(D = {}) + void retire(D d = {}) { + this->first() = std::move(d); ::call_rcu( static_cast(this), [](rcu_head *rhp) { auto rhdp = static_cast(rhp); auto obj = static_cast(rhdp); - D()(obj); + rhdp->first()(obj); } ); }