/src/rocksdb/monitoring/instrumented_mutex.cc
Line | Count | Source |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under both the GPLv2 (found in the |
3 | | // COPYING file in the root directory) and Apache 2.0 License |
4 | | // (found in the LICENSE.Apache file in the root directory). |
5 | | |
6 | | #include "monitoring/instrumented_mutex.h" |
7 | | |
8 | | #include "monitoring/perf_context_imp.h" |
9 | | #include "monitoring/thread_status_util.h" |
10 | | #include "rocksdb/system_clock.h" |
11 | | #include "test_util/sync_point.h" |
12 | | |
13 | | namespace ROCKSDB_NAMESPACE { |
14 | | namespace { |
15 | | #ifndef NPERF_CONTEXT |
16 | 1.44M | Statistics* stats_for_report(SystemClock* clock, Statistics* stats) { |
17 | 1.44M | if (clock != nullptr && stats != nullptr && |
18 | 0 | stats->get_stats_level() > kExceptTimeForMutex) { |
19 | 0 | return stats; |
20 | 1.44M | } else { |
21 | 1.44M | return nullptr; |
22 | 1.44M | } |
23 | 1.44M | } |
24 | | #endif // NPERF_CONTEXT |
25 | | } // namespace |
26 | | |
27 | 1.42M | void InstrumentedMutex::Lock() { |
28 | 1.42M | PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD( |
29 | 1.42M | db_mutex_lock_nanos, stats_code_ == DB_MUTEX_WAIT_MICROS, |
30 | 1.42M | stats_for_report(clock_, stats_), stats_code_); |
31 | 1.42M | LockInternal(); |
32 | 1.42M | } |
33 | | |
34 | 1.42M | void InstrumentedMutex::LockInternal() { |
35 | | #ifndef NDEBUG |
36 | | ThreadStatusUtil::TEST_StateDelay(ThreadStatus::STATE_MUTEX_WAIT); |
37 | | #endif |
38 | | #ifdef COERCE_CONTEXT_SWITCH |
39 | | if (stats_code_ == DB_MUTEX_WAIT_MICROS) { |
40 | | thread_local Random rnd(301); |
41 | | if (rnd.OneIn(2)) { |
42 | | if (bg_cv_) { |
43 | | bg_cv_->SignalAll(); |
44 | | } |
45 | | sched_yield(); |
46 | | } else { |
47 | | uint32_t sleep_us = rnd.Uniform(11) * 1000; |
48 | | if (bg_cv_) { |
49 | | bg_cv_->SignalAll(); |
50 | | } |
51 | | SystemClock::Default()->SleepForMicroseconds(sleep_us); |
52 | | } |
53 | | } |
54 | | #endif |
55 | 1.42M | mutex_.Lock(); |
56 | 1.42M | } |
57 | | |
58 | 4.27k | void InstrumentedCondVar::Wait() { |
59 | 4.27k | PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD( |
60 | 4.27k | db_condition_wait_nanos, stats_code_ == DB_MUTEX_WAIT_MICROS, |
61 | 4.27k | stats_for_report(clock_, stats_), stats_code_); |
62 | 4.27k | WaitInternal(); |
63 | 4.27k | } |
64 | | |
65 | 4.27k | void InstrumentedCondVar::WaitInternal() { |
66 | | #ifndef NDEBUG |
67 | | ThreadStatusUtil::TEST_StateDelay(ThreadStatus::STATE_MUTEX_WAIT); |
68 | | #endif |
69 | 4.27k | cond_.Wait(); |
70 | 4.27k | } |
71 | | |
72 | 16.1k | bool InstrumentedCondVar::TimedWait(uint64_t abs_time_us) { |
73 | 16.1k | PERF_CONDITIONAL_TIMER_FOR_MUTEX_GUARD( |
74 | 16.1k | db_condition_wait_nanos, stats_code_ == DB_MUTEX_WAIT_MICROS, |
75 | 16.1k | stats_for_report(clock_, stats_), stats_code_); |
76 | 16.1k | return TimedWaitInternal(abs_time_us); |
77 | 16.1k | } |
78 | | |
79 | 16.1k | bool InstrumentedCondVar::TimedWaitInternal(uint64_t abs_time_us) { |
80 | | #ifndef NDEBUG |
81 | | ThreadStatusUtil::TEST_StateDelay(ThreadStatus::STATE_MUTEX_WAIT); |
82 | | #endif |
83 | | |
84 | 16.1k | TEST_SYNC_POINT_CALLBACK("InstrumentedCondVar::TimedWaitInternal", |
85 | 16.1k | &abs_time_us); |
86 | | |
87 | 16.1k | return cond_.TimedWait(abs_time_us); |
88 | 16.1k | } |
89 | | |
90 | | } // namespace ROCKSDB_NAMESPACE |