In instrumented mutex, take timing once for both of perf_context and statistics

Summary: Closes https://github.com/facebook/rocksdb/pull/3427

Differential Revision: D6827236

Pulled By: siying

fbshipit-source-id: d8a2cc525c90df625510565669f2659014259a8a
This commit is contained in:
Siying Dong 2018-05-17 12:46:23 -07:00 committed by Facebook Github Bot
parent 8bf555f487
commit 7ccb35f653
3 changed files with 48 additions and 53 deletions

View File

@ -10,26 +10,22 @@
namespace rocksdb {
namespace {
bool ShouldReportToStats(Env* env, Statistics* stats) {
return env != nullptr && stats != nullptr &&
stats->stats_level_ > kExceptTimeForMutex;
Statistics* stats_for_report(Env* env, Statistics* stats) {
if (env != nullptr && stats != nullptr &&
stats->stats_level_ > kExceptTimeForMutex) {
return stats;
} else {
return nullptr;
}
}
} // namespace
void InstrumentedMutex::Lock() {
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(db_mutex_lock_nanos,
stats_code_ == DB_MUTEX_WAIT_MICROS);
uint64_t wait_time_micros = 0;
if (ShouldReportToStats(env_, stats_)) {
{
StopWatch sw(env_, nullptr, 0, &wait_time_micros);
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(
db_mutex_lock_nanos, stats_code_ == DB_MUTEX_WAIT_MICROS,
stats_for_report(env_, stats_), stats_code_);
LockInternal();
}
RecordTick(stats_, stats_code_, wait_time_micros);
} else {
LockInternal();
}
}
void InstrumentedMutex::LockInternal() {
#ifndef NDEBUG
@ -39,19 +35,11 @@ void InstrumentedMutex::LockInternal() {
}
void InstrumentedCondVar::Wait() {
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(db_condition_wait_nanos,
stats_code_ == DB_MUTEX_WAIT_MICROS);
uint64_t wait_time_micros = 0;
if (ShouldReportToStats(env_, stats_)) {
{
StopWatch sw(env_, nullptr, 0, &wait_time_micros);
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(
db_condition_wait_nanos, stats_code_ == DB_MUTEX_WAIT_MICROS,
stats_for_report(env_, stats_), stats_code_);
WaitInternal();
}
RecordTick(stats_, stats_code_, wait_time_micros);
} else {
WaitInternal();
}
}
void InstrumentedCondVar::WaitInternal() {
#ifndef NDEBUG
@ -61,20 +49,10 @@ void InstrumentedCondVar::WaitInternal() {
}
bool InstrumentedCondVar::TimedWait(uint64_t abs_time_us) {
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(db_condition_wait_nanos,
stats_code_ == DB_MUTEX_WAIT_MICROS);
uint64_t wait_time_micros = 0;
bool result = false;
if (ShouldReportToStats(env_, stats_)) {
{
StopWatch sw(env_, nullptr, 0, &wait_time_micros);
result = TimedWaitInternal(abs_time_us);
}
RecordTick(stats_, stats_code_, wait_time_micros);
} else {
result = TimedWaitInternal(abs_time_us);
}
return result;
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(
db_condition_wait_nanos, stats_code_ == DB_MUTEX_WAIT_MICROS,
stats_for_report(env_, stats_), stats_code_);
return TimedWaitInternal(abs_time_us);
}
bool InstrumentedCondVar::TimedWaitInternal(uint64_t abs_time_us) {

View File

@ -41,8 +41,10 @@ extern __thread PerfContext perf_context;
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric)); \
perf_step_timer_##metric.Start();
#define PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(metric, condition) \
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), true); \
#define PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(metric, condition, stats, \
ticker_type) \
PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), true, stats, \
ticker_type); \
if (condition) { \
perf_step_timer_##metric.Start(); \
}

View File

@ -12,19 +12,25 @@ namespace rocksdb {
class PerfStepTimer {
public:
explicit PerfStepTimer(uint64_t* metric, bool for_mutex = false)
: enabled_(perf_level >= PerfLevel::kEnableTime ||
explicit PerfStepTimer(uint64_t* metric, bool for_mutex = false,
Statistics* statistics = nullptr,
uint32_t ticker_type = 0)
: perf_counter_enabled_(
perf_level >= PerfLevel::kEnableTime ||
(!for_mutex && perf_level >= kEnableTimeExceptForMutex)),
env_(enabled_ ? Env::Default() : nullptr),
env_((perf_counter_enabled_ || statistics != nullptr) ? Env::Default()
: nullptr),
start_(0),
metric_(metric) {}
metric_(metric),
statistics_(statistics),
ticker_type_(ticker_type) {}
~PerfStepTimer() {
Stop();
}
void Start() {
if (enabled_) {
if (perf_counter_enabled_ || statistics_ != nullptr) {
start_ = env_->NowNanos();
}
}
@ -39,16 +45,25 @@ class PerfStepTimer {
void Stop() {
if (start_) {
*metric_ += env_->NowNanos() - start_;
uint64_t duration = env_->NowNanos() - start_;
if (perf_counter_enabled_) {
*metric_ += duration;
}
if (statistics_ != nullptr) {
RecordTick(statistics_, ticker_type_, duration);
}
start_ = 0;
}
}
private:
const bool enabled_;
const bool perf_counter_enabled_;
Env* const env_;
uint64_t start_;
uint64_t* metric_;
Statistics* statistics_;
uint32_t ticker_type_;
};
} // namespace rocksdb