From: Casey Bodley Date: Mon, 14 Oct 2024 18:12:13 +0000 (-0400) Subject: common/async: Completion uses asio::recycling_allocator by default X-Git-Tag: v20.0.0~574^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=71ed54ba77262465fa3e3a01f4bd73279777b3ac;p=ceph.git common/async: Completion uses asio::recycling_allocator by default ceph::async::Completion<> already respects the wrapped Handler's associated allocator, but defaults to std::allocator when there isn't one associated copy other asio primitives like asio::any_completion_handler<> (which satisfies very similar use case to our Completion) by instead choosing asio::recycling_allocator as the default handler allocator from https://www.boost.org/doc/libs/1_85_0/doc/html/boost_asio/reference/recycling_allocator.html: > The recycling_allocator uses a simple strategy where a limited number > of small memory blocks are cached in thread-local storage, if the > current thread is running an io_context or is part of a thread_pool. Signed-off-by: Casey Bodley --- diff --git a/src/common/async/completion.h b/src/common/async/completion.h index d8065934e016..3c310d7f8330 100644 --- a/src/common/async/completion.h +++ b/src/common/async/completion.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "bind_handler.h" @@ -173,7 +174,8 @@ class CompletionImpl final : public Completion { Handler handler; // use Handler's associated allocator - using Alloc2 = boost::asio::associated_allocator_t; + using DefaultAlloc = boost::asio::recycling_allocator; + using Alloc2 = boost::asio::associated_allocator_t; using Traits2 = std::allocator_traits; using RebindAlloc2 = typename Traits2::template rebind_alloc; using RebindTraits2 = std::allocator_traits; @@ -196,7 +198,7 @@ class CompletionImpl final : public Completion { void destroy_defer(std::tuple&& args) override { auto w = std::move(work); auto ex2 = w.second.get_executor(); - RebindAlloc2 alloc2 = boost::asio::get_associated_allocator(handler); + RebindAlloc2 alloc2 = boost::asio::get_associated_allocator(handler, DefaultAlloc{}); auto f = bind_and_forward(ex2, std::move(handler), std::move(args)); RebindTraits2::destroy(alloc2, this); RebindTraits2::deallocate(alloc2, this, 1); @@ -205,7 +207,7 @@ class CompletionImpl final : public Completion { void destroy_dispatch(std::tuple&& args) override { auto w = std::move(work); auto ex2 = w.second.get_executor(); - RebindAlloc2 alloc2 = boost::asio::get_associated_allocator(handler); + RebindAlloc2 alloc2 = boost::asio::get_associated_allocator(handler, DefaultAlloc{}); auto f = bind_and_forward(ex2, std::move(handler), std::move(args)); RebindTraits2::destroy(alloc2, this); RebindTraits2::deallocate(alloc2, this, 1); @@ -214,14 +216,14 @@ class CompletionImpl final : public Completion { void destroy_post(std::tuple&& args) override { auto w = std::move(work); auto ex2 = w.second.get_executor(); - RebindAlloc2 alloc2 = boost::asio::get_associated_allocator(handler); + RebindAlloc2 alloc2 = boost::asio::get_associated_allocator(handler, DefaultAlloc{}); auto f = bind_and_forward(ex2, std::move(handler), std::move(args)); RebindTraits2::destroy(alloc2, this); RebindTraits2::deallocate(alloc2, this, 1); boost::asio::post(std::move(f)); } void destroy() override { - RebindAlloc2 alloc2 = boost::asio::get_associated_allocator(handler); + RebindAlloc2 alloc2 = boost::asio::get_associated_allocator(handler, DefaultAlloc{}); RebindTraits2::destroy(alloc2, this); RebindTraits2::deallocate(alloc2, this, 1); } @@ -238,7 +240,7 @@ class CompletionImpl final : public Completion { public: template static auto create(const Executor1& ex, Handler&& handler, TArgs&& ...args) { - auto alloc2 = boost::asio::get_associated_allocator(handler); + auto alloc2 = boost::asio::get_associated_allocator(handler, DefaultAlloc{}); using Ptr = std::unique_ptr; return Ptr{new (alloc2) CompletionImpl(ex, std::move(handler), std::forward(args)...)};