// (found in the LICENSE.Apache file in the root directory).
#include "monitoring/instrumented_mutex.h"
+
#include "monitoring/perf_context_imp.h"
#include "monitoring/thread_status_util.h"
+#include "rocksdb/system_clock.h"
#include "test_util/sync_point.h"
namespace ROCKSDB_NAMESPACE {
namespace {
#ifndef NPERF_CONTEXT
-Statistics* stats_for_report(Env* env, Statistics* stats) {
- if (env != nullptr && stats != nullptr &&
+Statistics* stats_for_report(SystemClock* clock, Statistics* stats) {
+ if (clock != nullptr && stats != nullptr &&
stats->get_stats_level() > kExceptTimeForMutex) {
return stats;
} else {
void InstrumentedMutex::Lock() {
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(
db_mutex_lock_nanos, stats_code_ == DB_MUTEX_WAIT_MICROS,
- stats_for_report(env_, stats_), stats_code_);
+ stats_for_report(clock_, stats_), stats_code_);
LockInternal();
}
void InstrumentedMutex::LockInternal() {
#ifndef NDEBUG
ThreadStatusUtil::TEST_StateDelay(ThreadStatus::STATE_MUTEX_WAIT);
+#endif
+#ifdef COERCE_CONTEXT_SWITCH
+ if (stats_code_ == DB_MUTEX_WAIT_MICROS) {
+ thread_local Random rnd(301);
+ if (rnd.OneIn(2)) {
+ if (bg_cv_) {
+ bg_cv_->SignalAll();
+ }
+ sched_yield();
+ } else {
+ uint32_t sleep_us = rnd.Uniform(11) * 1000;
+ if (bg_cv_) {
+ bg_cv_->SignalAll();
+ }
+ SystemClock::Default()->SleepForMicroseconds(sleep_us);
+ }
+ }
#endif
mutex_.Lock();
}
void InstrumentedCondVar::Wait() {
PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD(
db_condition_wait_nanos, stats_code_ == DB_MUTEX_WAIT_MICROS,
- stats_for_report(env_, stats_), stats_code_);
+ stats_for_report(clock_, stats_), stats_code_);
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,
- stats_for_report(env_, stats_), stats_code_);
+ stats_for_report(clock_, stats_), stats_code_);
return TimedWaitInternal(abs_time_us);
}