From cc7ec3e18d191575c4d94d6f188cada800f51f72 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 8 May 2019 14:09:17 -0400 Subject: [PATCH] common/Finisher: avoid memory re-allocations for finisher queue Since there is only a single thread associated with the Finisher, swap between two queues to avoid the need to re-allocate a new vector for each iteration through the loop. Also replace the condition broadcast with a signal since there is only a single thread to wake up. Signed-off-by: Jason Dillaman --- src/common/Finisher.cc | 14 +++++++------- src/common/Finisher.h | 8 +++++--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/common/Finisher.cc b/src/common/Finisher.cc index 277fe06f197..974241f5719 100644 --- a/src/common/Finisher.cc +++ b/src/common/Finisher.cc @@ -51,23 +51,23 @@ void *Finisher::finisher_thread_entry() // To reduce lock contention, we swap out the queue to process. // This way other threads can submit new contexts to complete // while we are working. - vector> ls; - ls.swap(finisher_queue); + in_progress_queue.swap(finisher_queue); finisher_running = true; ul.unlock(); - ldout(cct, 10) << "finisher_thread doing " << ls << dendl; + ldout(cct, 10) << "finisher_thread doing " << in_progress_queue << dendl; if (logger) { start = ceph_clock_now(); - count = ls.size(); + count = in_progress_queue.size(); } // Now actually process the contexts. - for (auto p : ls) { + for (auto p : in_progress_queue) { p.first->complete(p.second); } - ldout(cct, 10) << "finisher_thread done with " << ls << dendl; - ls.clear(); + ldout(cct, 10) << "finisher_thread done with " << in_progress_queue + << dendl; + in_progress_queue.clear(); if (logger) { logger->dec(l_finisher_queue_len, count); logger->tinc(l_finisher_complete_lat, ceph_clock_now() - start); diff --git a/src/common/Finisher.h b/src/common/Finisher.h index b70b600af6c..6926d8207b4 100644 --- a/src/common/Finisher.h +++ b/src/common/Finisher.h @@ -47,6 +47,7 @@ class Finisher { /// Queue for contexts for which complete(0) will be called. std::vector> finisher_queue; + std::vector> in_progress_queue; std::string thread_name; @@ -66,10 +67,11 @@ class Finisher { /// Add a context to complete, optionally specifying a parameter for the complete function. void queue(Context *c, int r = 0) { std::unique_lock ul(finisher_lock); - if (finisher_queue.empty()) { - finisher_cond.notify_all(); - } + bool was_empty = finisher_queue.empty(); finisher_queue.push_back(std::make_pair(c, r)); + if (was_empty) { + finisher_cond.notify_one(); + } if (logger) logger->inc(l_finisher_queue_len); } -- 2.39.5