Commit cda07daf authored by Alexander Pronchenkov's avatar Alexander Pronchenkov Committed by Facebook Github Bot

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<T>()
 * folly::Promise is stored by value

Reviewed By: yfeldblum

Differential Revision: D6172017

fbshipit-source-id: 41bf123f10570c76d64eaac1800b7e65fe381110
parent 017cae98
...@@ -27,42 +27,40 @@ Singleton<ThreadWheelTimekeeper> timekeeperSingleton_; ...@@ -27,42 +27,40 @@ Singleton<ThreadWheelTimekeeper> timekeeperSingleton_;
// Our Callback object for HHWheelTimer // Our Callback object for HHWheelTimer
struct WTCallback : public std::enable_shared_from_this<WTCallback>, struct WTCallback : public std::enable_shared_from_this<WTCallback>,
public folly::HHWheelTimer::Callback { public folly::HHWheelTimer::Callback {
struct PrivateConstructorTag {};
public: public:
WTCallback(PrivateConstructorTag, EventBase* base) : base_(base) {}
// Only allow creation by this factory, to ensure heap allocation. // Only allow creation by this factory, to ensure heap allocation.
static std::shared_ptr<WTCallback> create(EventBase* base) { static std::shared_ptr<WTCallback> create(EventBase* base) {
// optimization opportunity: memory pool // optimization opportunity: memory pool
auto cob = std::shared_ptr<WTCallback>(new WTCallback(base)); auto cob = std::make_shared<WTCallback>(PrivateConstructorTag{}, base);
// Capture shared_ptr of cob in lambda so that Core inside Promise will // 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 // 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 // away which happens when both Promise and Future go away
cob->promise_->setInterruptHandler([cob](const folly::exception_wrapper&) { cob->promise_.setInterruptHandler(
cob->interruptHandler(); [cob](const folly::exception_wrapper&) { cob->interruptHandler(); });
});
return cob; return cob;
} }
Future<Unit> getFuture() { Future<Unit> getFuture() {
return promise_->getFuture(); return promise_.getFuture();
} }
void releasePromise() { void releasePromise() {
// Don't need promise anymore. Break the circular reference as promise_ // 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 // is holding a ref count to us via Core. Core won't go away until both
// Promise and Future go away. // Promise and Future go away.
promise_.reset(); promise_ = Promise<Unit>::makeEmpty();
} }
protected: protected:
EventBase* base_; EventBase* base_;
std::shared_ptr<Promise<Unit>> promise_; Promise<Unit> promise_;
explicit WTCallback(EventBase* base)
: base_(base) {
promise_ = std::make_shared<Promise<Unit>>();
}
void timeoutExpired() noexcept override { void timeoutExpired() noexcept override {
promise_->setValue(); promise_.setValue();
// Don't need Promise anymore, break the circular reference // Don't need Promise anymore, break the circular reference
releasePromise(); releasePromise();
} }
...@@ -73,12 +71,11 @@ struct WTCallback : public std::enable_shared_from_this<WTCallback>, ...@@ -73,12 +71,11 @@ struct WTCallback : public std::enable_shared_from_this<WTCallback>,
// This is not racing with timeoutExpired anymore because this is called // This is not racing with timeoutExpired anymore because this is called
// through Future, which means Core is still alive and keeping a ref count // 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 // on us, so what timeouExpired is doing won't make the object go away
auto me = shared_from_this(); base_->runInEventBaseThread([me = shared_from_this()] {
base_->runInEventBaseThread([me] { me->cancelTimeout();
me->cancelTimeout(); // Don't need Promise anymore, break the circular reference
// Don't need Promise anymore, break the circular reference me->releasePromise();
me->releasePromise(); });
});
} }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment