diff --git a/HISTORY.md b/HISTORY.md index f721b7c1c..4cc2bac27 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,9 @@ # Rocksdb Change Log +## Unreleased +### Public API Changes +* Add a new perf context level between kEnableCount and kEnableTime. Level 2 now doesn't include timers for mutexes. + ## 4.4.0 (1/14/2016) ### Public API Changes * Change names in CompactionPri and add a new one. diff --git a/db/perf_context_test.cc b/db/perf_context_test.cc index 00065dc92..72b52f6e8 100644 --- a/db/perf_context_test.cc +++ b/db/perf_context_test.cc @@ -543,28 +543,31 @@ TEST_F(PerfContextTest, SeekKeyComparison) { } TEST_F(PerfContextTest, DBMutexLockCounter) { - SetPerfLevel(kEnableTime); int stats_code[] = {0, static_cast(DB_MUTEX_WAIT_MICROS)}; - for (int c = 0; c < 2; ++c) { + for (PerfLevel perf_level : + {PerfLevel::kEnableTimeExceptForMutex, PerfLevel::kEnableTime}) { + for (int c = 0; c < 2; ++c) { InstrumentedMutex mutex(nullptr, Env::Default(), stats_code[c]); mutex.Lock(); std::thread child_thread([&] { - SetPerfLevel(kEnableTime); + SetPerfLevel(perf_level); perf_context.Reset(); ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0); mutex.Lock(); mutex.Unlock(); - if (stats_code[c] == DB_MUTEX_WAIT_MICROS) { + if (perf_level == PerfLevel::kEnableTimeExceptForMutex || + stats_code[c] != DB_MUTEX_WAIT_MICROS) { + ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0); + } else { // increment the counter only when it's a DB Mutex ASSERT_GT(perf_context.db_mutex_lock_nanos, 0); - } else { - ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0); } }); Env::Default()->SleepForMicroseconds(100); mutex.Unlock(); child_thread.join(); } + } } TEST_F(PerfContextTest, FalseDBMutexWait) { diff --git a/include/rocksdb/perf_level.h b/include/rocksdb/perf_level.h index fee8ce1c4..cd7480097 100644 --- a/include/rocksdb/perf_level.h +++ b/include/rocksdb/perf_level.h @@ -14,9 +14,11 @@ namespace rocksdb { // How much perf stats to collect. Affects perf_context and iostats_context. enum PerfLevel { - kDisable = 0, // disable perf stats - kEnableCount = 1, // enable only count stats - kEnableTime = 2 // enable time stats too + kDisable = 0, // disable perf stats + kEnableCount = 1, // enable only count stats + kEnableTimeExceptForMutex = 2, // Other than count stats, also enable time + // stats except for mutexes + kEnableTime = 3 // enable count and time stats }; // set the perf stats level for current thread diff --git a/util/instrumented_mutex.cc b/util/instrumented_mutex.cc index bfb989a1d..e5c6527be 100644 --- a/util/instrumented_mutex.cc +++ b/util/instrumented_mutex.cc @@ -9,8 +9,8 @@ namespace rocksdb { void InstrumentedMutex::Lock() { - PERF_CONDITIONAL_TIMER_GUARD(db_mutex_lock_nanos, - stats_code_ == DB_MUTEX_WAIT_MICROS); + PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(db_mutex_lock_nanos, + stats_code_ == DB_MUTEX_WAIT_MICROS); uint64_t wait_time_micros = 0; if (env_ != nullptr && stats_ != nullptr) { { @@ -31,8 +31,8 @@ void InstrumentedMutex::LockInternal() { } void InstrumentedCondVar::Wait() { - PERF_CONDITIONAL_TIMER_GUARD(db_condition_wait_nanos, - stats_code_ == DB_MUTEX_WAIT_MICROS); + PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(db_condition_wait_nanos, + stats_code_ == DB_MUTEX_WAIT_MICROS); uint64_t wait_time_micros = 0; if (env_ != nullptr && stats_ != nullptr) { { @@ -53,8 +53,8 @@ void InstrumentedCondVar::WaitInternal() { } bool InstrumentedCondVar::TimedWait(uint64_t abs_time_us) { - PERF_CONDITIONAL_TIMER_GUARD(db_condition_wait_nanos, - stats_code_ == DB_MUTEX_WAIT_MICROS); + 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 (env_ != nullptr && stats_ != nullptr) { diff --git a/util/perf_context_imp.h b/util/perf_context_imp.h index a5c4c39d9..d28b55179 100644 --- a/util/perf_context_imp.h +++ b/util/perf_context_imp.h @@ -33,10 +33,10 @@ namespace rocksdb { PerfStepTimer perf_step_timer_ ## metric(&(perf_context.metric)); \ perf_step_timer_ ## metric.Start(); -#define PERF_CONDITIONAL_TIMER_GUARD(metric, condition) \ - PerfStepTimer perf_step_timer_##metric(&(perf_context.metric)); \ - if ((condition)) { \ - perf_step_timer_##metric.Start(); \ +#define PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(metric, condition) \ + PerfStepTimer perf_step_timer_##metric(&(perf_context.metric), true); \ + if ((condition)) { \ + perf_step_timer_##metric.Start(); \ } // Update metric with time elapsed since last START. start time is reset diff --git a/util/perf_step_timer.h b/util/perf_step_timer.h index 950258345..631cd317c 100644 --- a/util/perf_step_timer.h +++ b/util/perf_step_timer.h @@ -12,12 +12,12 @@ namespace rocksdb { class PerfStepTimer { public: - PerfStepTimer(uint64_t* metric) - : enabled_(perf_level >= PerfLevel::kEnableTime), - env_(enabled_ ? Env::Default() : nullptr), - start_(0), - metric_(metric) { - } + explicit PerfStepTimer(uint64_t* metric, bool for_mutex = false) + : enabled_(perf_level >= PerfLevel::kEnableTime || + (!for_mutex && perf_level >= kEnableTimeExceptForMutex)), + env_(enabled_ ? Env::Default() : nullptr), + start_(0), + metric_(metric) {} ~PerfStepTimer() { Stop();