From b2901a450fa33618583f0e6a24c67bd50d1a3b19 Mon Sep 17 00:00:00 2001 From: Matt Klein Date: Mon, 14 Nov 2016 14:23:06 -0800 Subject: [PATCH] perf: use lock free event base The only place we need the lock is when we do post(). Just run a timer every 100ms and check for posted items to avoid acquiring and releasing the lock everywhere where we don't need it. --- source/common/event/dispatcher_impl.cc | 32 +++++++++++--------------- source/common/event/dispatcher_impl.h | 1 + 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/source/common/event/dispatcher_impl.cc b/source/common/event/dispatcher_impl.cc index b54897a4b131..9a544c8bf828 100644 --- a/source/common/event/dispatcher_impl.cc +++ b/source/common/event/dispatcher_impl.cc @@ -17,10 +17,16 @@ namespace Event { -DispatcherImpl::DispatcherImpl() - : base_(event_base_new()), - deferred_delete_timer_(createTimer([this]() -> void { clearDeferredDeleteList(); })), - current_to_delete_(&to_delete_1_) {} +DispatcherImpl::DispatcherImpl() : current_to_delete_(&to_delete_1_) { + + event_config* config = event_config_new(); + event_config_set_flag(config, EVENT_BASE_FLAG_NOLOCK); + base_.reset(event_base_new_with_config(config)); + event_config_free(config); + + deferred_delete_timer_ = createTimer([this]() -> void { clearDeferredDeleteList(); }); + post_timer_ = createTimer([this]() -> void { runPostCallbacks(); }); +} DispatcherImpl::~DispatcherImpl() {} @@ -110,20 +116,8 @@ SignalEventPtr DispatcherImpl::listenForSignal(int signal_num, SignalCb cb) { } void DispatcherImpl::post(std::function callback) { - bool do_post; - { - std::unique_lock lock(post_lock_); - do_post = post_callbacks_.empty(); - post_callbacks_.push_back(callback); - } - - if (do_post) { - // If the dispatcher shuts down before this runs, we will leak. This never happens during - // normal operation so its not a big deal. - event_base_once(base_.get(), -1, EV_TIMEOUT, [](evutil_socket_t, short, void* arg) -> void { - static_cast(arg)->runPostCallbacks(); - }, this, nullptr); - } + std::unique_lock lock(post_lock_); + post_callbacks_.push_back(callback); } void DispatcherImpl::run(RunType type) { @@ -146,6 +140,8 @@ void DispatcherImpl::runPostCallbacks() { callback(); lock.lock(); } + + post_timer_->enableTimer(std::chrono::milliseconds(100)); } } // Event diff --git a/source/common/event/dispatcher_impl.h b/source/common/event/dispatcher_impl.h index 396297275a24..4e53f3943eb4 100644 --- a/source/common/event/dispatcher_impl.h +++ b/source/common/event/dispatcher_impl.h @@ -47,6 +47,7 @@ class DispatcherImpl : Logger::Loggable, public Dispatcher { Libevent::BasePtr base_; TimerPtr deferred_delete_timer_; + TimerPtr post_timer_; std::vector to_delete_1_; std::vector to_delete_2_; std::vector* current_to_delete_;