mirror of
https://github.com/ceph/ceph
synced 2025-04-01 00:26:47 +00:00
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 <dillaman@redhat.com>
This commit is contained in:
parent
99826fbe75
commit
cc7ec3e18d
@ -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<pair<Context*,int>> 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);
|
||||
|
@ -47,6 +47,7 @@ class Finisher {
|
||||
|
||||
/// Queue for contexts for which complete(0) will be called.
|
||||
std::vector<std::pair<Context*,int>> finisher_queue;
|
||||
std::vector<std::pair<Context*,int>> 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user