]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
common/async: Completion uses asio::recycling_allocator by default
authorCasey Bodley <cbodley@redhat.com>
Mon, 14 Oct 2024 18:12:13 +0000 (14:12 -0400)
committerCasey Bodley <cbodley@redhat.com>
Mon, 14 Oct 2024 19:33:09 +0000 (15:33 -0400)
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<void> 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 <cbodley@redhat.com>
src/common/async/completion.h

index d8065934e016bbd758adfe43de693803e256ede2..3c310d7f833082157aa1ad1f3524d146130e07f3 100644 (file)
@@ -21,6 +21,7 @@
 #include <boost/asio/defer.hpp>
 #include <boost/asio/dispatch.hpp>
 #include <boost/asio/executor_work_guard.hpp>
+#include <boost/asio/recycling_allocator.hpp>
 #include <boost/asio/post.hpp>
 
 #include "bind_handler.h"
@@ -173,7 +174,8 @@ class CompletionImpl final : public Completion<void(Args...), T> {
   Handler handler;
 
   // use Handler's associated allocator
-  using Alloc2 = boost::asio::associated_allocator_t<Handler>;
+  using DefaultAlloc = boost::asio::recycling_allocator<void>;
+  using Alloc2 = boost::asio::associated_allocator_t<Handler, DefaultAlloc>;
   using Traits2 = std::allocator_traits<Alloc2>;
   using RebindAlloc2 = typename Traits2::template rebind_alloc<CompletionImpl>;
   using RebindTraits2 = std::allocator_traits<RebindAlloc2>;
@@ -196,7 +198,7 @@ class CompletionImpl final : public Completion<void(Args...), T> {
   void destroy_defer(std::tuple<Args...>&& 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(Args...), T> {
   void destroy_dispatch(std::tuple<Args...>&& 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(Args...), T> {
   void destroy_post(std::tuple<Args...>&& 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<void(Args...), T> {
  public:
   template <typename ...TArgs>
   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<CompletionImpl>;
     return Ptr{new (alloc2) CompletionImpl(ex, std::move(handler),
                                            std::forward<TArgs>(args)...)};