Skip to content

Commit

Permalink
Merge pull request ceph#14363 from majianpeng/finisher-optimize
Browse files Browse the repository at this point in the history
common/Finisher: batch handle perfcounter && only send signal when waiter existed.

Reviewed-by: Sage Weil <[email protected]>
  • Loading branch information
liewegas committed May 4, 2017
2 parents 7e79a4e + fcc7799 commit 813df82
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 19 deletions.
22 changes: 13 additions & 9 deletions src/common/Finisher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ void Finisher::wait_for_empty()
finisher_lock.Lock();
while (!finisher_queue.empty() || finisher_running) {
ldout(cct, 10) << "wait_for_empty waiting" << dendl;
finisher_empty_wait = true;
finisher_empty_cond.Wait(finisher_lock);
}
ldout(cct, 10) << "wait_for_empty empty" << dendl;
finisher_empty_wait = false;
finisher_lock.Unlock();
}

Expand All @@ -44,7 +46,8 @@ void *Finisher::finisher_thread_entry()
finisher_lock.Lock();
ldout(cct, 10) << "finisher_thread start" << dendl;

utime_t start, end;
utime_t start;
uint64_t count;
while (!finisher_stop) {
/// Every time we are woken up, we process the queue until it is empty.
while (!finisher_queue.empty()) {
Expand All @@ -58,8 +61,10 @@ void *Finisher::finisher_thread_entry()
finisher_lock.Unlock();
ldout(cct, 10) << "finisher_thread doing " << ls << dendl;

if (logger)
if (logger) {
start = ceph_clock_now();
count = ls.size();
}

// Now actually process the contexts.
for (vector<Context*>::iterator p = ls.begin();
Expand All @@ -77,21 +82,20 @@ void *Finisher::finisher_thread_entry()
c->complete(ls_rval.front().second);
ls_rval.pop_front();
}
if (logger) {
logger->dec(l_finisher_queue_len);
end = ceph_clock_now();
logger->tinc(l_finisher_complete_lat, end - start);
start = end;
}
}
ldout(cct, 10) << "finisher_thread done with " << ls << dendl;
ls.clear();
if (logger) {
logger->dec(l_finisher_queue_len, count);
logger->tinc(l_finisher_complete_lat, ceph_clock_now() - start);
}

finisher_lock.Lock();
finisher_running = false;
}
ldout(cct, 10) << "finisher_thread empty" << dendl;
finisher_empty_cond.Signal();
if (unlikely(finisher_empty_wait))
finisher_empty_cond.Signal();
if (finisher_stop)
break;

Expand Down
5 changes: 3 additions & 2 deletions src/common/Finisher.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Finisher {
Cond finisher_empty_cond; ///< Signaled when the finisher has nothing more to process.
bool finisher_stop; ///< Set when the finisher should stop.
bool finisher_running; ///< True when the finisher is currently executing contexts.
bool finisher_empty_wait; ///< True mean someone wait finisher empty.
/// Queue for contexts for which complete(0) will be called.
/// NULLs in this queue indicate that an item from finisher_queue_rval
/// should be completed in that place instead.
Expand Down Expand Up @@ -136,14 +137,14 @@ class Finisher {
/// Anonymous finishers do not log their queue length.
explicit Finisher(CephContext *cct_) :
cct(cct_), finisher_lock("Finisher::finisher_lock"),
finisher_stop(false), finisher_running(false),
finisher_stop(false), finisher_running(false), finisher_empty_wait(false),
thread_name("fn_anonymous"), logger(0),
finisher_thread(this) {}

/// Construct a named Finisher that logs its queue length.
Finisher(CephContext *cct_, string name, string tn) :
cct(cct_), finisher_lock("Finisher::" + name),
finisher_stop(false), finisher_running(false),
finisher_stop(false), finisher_running(false), finisher_empty_wait(false),
thread_name(tn), logger(0),
finisher_thread(this) {
PerfCountersBuilder b(cct, string("finisher-") + name,
Expand Down
12 changes: 6 additions & 6 deletions src/common/perf_counters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ uint64_t PerfCounters::get(int idx) const
return data.u64.read();
}

void PerfCounters::tinc(int idx, utime_t amt)
void PerfCounters::tinc(int idx, utime_t amt, uint32_t avgcount)
{
if (!m_cct->_conf->perf)
return;
Expand All @@ -252,15 +252,15 @@ void PerfCounters::tinc(int idx, utime_t amt)
if (!(data.type & PERFCOUNTER_TIME))
return;
if (data.type & PERFCOUNTER_LONGRUNAVG) {
data.avgcount.inc();
data.avgcount.add(avgcount);
data.u64.add(amt.to_nsec());
data.avgcount2.inc();
data.avgcount2.add(avgcount);
} else {
data.u64.add(amt.to_nsec());
}
}

void PerfCounters::tinc(int idx, ceph::timespan amt)
void PerfCounters::tinc(int idx, ceph::timespan amt, uint32_t avgcount)
{
if (!m_cct->_conf->perf)
return;
Expand All @@ -271,9 +271,9 @@ void PerfCounters::tinc(int idx, ceph::timespan amt)
if (!(data.type & PERFCOUNTER_TIME))
return;
if (data.type & PERFCOUNTER_LONGRUNAVG) {
data.avgcount.inc();
data.avgcount.add(avgcount);
data.u64.add(amt.count());
data.avgcount2.inc();
data.avgcount2.add(avgcount);
} else {
data.u64.add(amt.count());
}
Expand Down
4 changes: 2 additions & 2 deletions src/common/perf_counters.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ class PerfCounters
uint64_t get(int idx) const;

void tset(int idx, utime_t v);
void tinc(int idx, utime_t v);
void tinc(int idx, ceph::timespan v);
void tinc(int idx, utime_t v, uint32_t avgcount = 1);
void tinc(int idx, ceph::timespan v, uint32_t avgcount = 1);
utime_t tget(int idx) const;

void hinc(int idx, int64_t x, int64_t y);
Expand Down

0 comments on commit 813df82

Please sign in to comment.