From cda07dafe57633439c67473f7c20b5f83316ba03 Mon Sep 17 00:00:00 2001 From: Alexander Pronchenkov Date: Mon, 30 Oct 2017 05:13:02 -0700 Subject: [PATCH] Remove a few memory allocations in ThreadWheelTimekeeper.after() Summary: This diff reduces number of memory allocation in folly::ThreadWheelTimekeeper.after() method for a bit. * std::shared_ptr(new T) is replaced with std::make_shared() * folly::Promise is stored by value Reviewed By: yfeldblum Differential Revision: D6172017 fbshipit-source-id: 41bf123f10570c76d64eaac1800b7e65fe381110 --- folly/futures/ThreadWheelTimekeeper.cpp | 35 +++++++++++-------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/folly/futures/ThreadWheelTimekeeper.cpp b/folly/futures/ThreadWheelTimekeeper.cpp index a2fd9cf4..fae01f52 100644 --- a/folly/futures/ThreadWheelTimekeeper.cpp +++ b/folly/futures/ThreadWheelTimekeeper.cpp @@ -27,42 +27,40 @@ Singleton timekeeperSingleton_; // Our Callback object for HHWheelTimer struct WTCallback : public std::enable_shared_from_this, public folly::HHWheelTimer::Callback { + struct PrivateConstructorTag {}; + public: + WTCallback(PrivateConstructorTag, EventBase* base) : base_(base) {} + // Only allow creation by this factory, to ensure heap allocation. static std::shared_ptr create(EventBase* base) { // optimization opportunity: memory pool - auto cob = std::shared_ptr(new WTCallback(base)); + auto cob = std::make_shared(PrivateConstructorTag{}, base); // Capture shared_ptr of cob in lambda so that Core inside Promise will // hold a ref count to it. The ref count will be released when Core goes // away which happens when both Promise and Future go away - cob->promise_->setInterruptHandler([cob](const folly::exception_wrapper&) { - cob->interruptHandler(); - }); + cob->promise_.setInterruptHandler( + [cob](const folly::exception_wrapper&) { cob->interruptHandler(); }); return cob; } Future getFuture() { - return promise_->getFuture(); + return promise_.getFuture(); } void releasePromise() { // Don't need promise anymore. Break the circular reference as promise_ // is holding a ref count to us via Core. Core won't go away until both // Promise and Future go away. - promise_.reset(); + promise_ = Promise::makeEmpty(); } protected: EventBase* base_; - std::shared_ptr> promise_; - - explicit WTCallback(EventBase* base) - : base_(base) { - promise_ = std::make_shared>(); - } + Promise promise_; void timeoutExpired() noexcept override { - promise_->setValue(); + promise_.setValue(); // Don't need Promise anymore, break the circular reference releasePromise(); } @@ -73,12 +71,11 @@ struct WTCallback : public std::enable_shared_from_this, // This is not racing with timeoutExpired anymore because this is called // through Future, which means Core is still alive and keeping a ref count // on us, so what timeouExpired is doing won't make the object go away - auto me = shared_from_this(); - base_->runInEventBaseThread([me] { - me->cancelTimeout(); - // Don't need Promise anymore, break the circular reference - me->releasePromise(); - }); + base_->runInEventBaseThread([me = shared_from_this()] { + me->cancelTimeout(); + // Don't need Promise anymore, break the circular reference + me->releasePromise(); + }); } }; -- 2.34.1