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 #pragma once
7 
8 #include "monitoring/statistics.h"
9 #include "port/port.h"
10 #include "rocksdb/env.h"
11 #include "rocksdb/statistics.h"
12 #include "rocksdb/thread_status.h"
13 #include "util/stop_watch.h"
14 
15 namespace ROCKSDB_NAMESPACE {
16 class InstrumentedCondVar;
17 
18 // A wrapper class for port::Mutex that provides additional layer
19 // for collecting stats and instrumentation.
20 class InstrumentedMutex {
21  public:
22   explicit InstrumentedMutex(bool adaptive = false)
mutex_(adaptive)23       : mutex_(adaptive), stats_(nullptr), env_(nullptr),
24         stats_code_(0) {}
25 
26   InstrumentedMutex(
27       Statistics* stats, Env* env,
28       int stats_code, bool adaptive = false)
mutex_(adaptive)29       : mutex_(adaptive), stats_(stats), env_(env),
30         stats_code_(stats_code) {}
31 
32   void Lock();
33 
Unlock()34   void Unlock() {
35     mutex_.Unlock();
36   }
37 
AssertHeld()38   void AssertHeld() {
39     mutex_.AssertHeld();
40   }
41 
42  private:
43   void LockInternal();
44   friend class InstrumentedCondVar;
45   port::Mutex mutex_;
46   Statistics* stats_;
47   Env* env_;
48   int stats_code_;
49 };
50 
51 // A wrapper class for port::Mutex that provides additional layer
52 // for collecting stats and instrumentation.
53 class InstrumentedMutexLock {
54  public:
InstrumentedMutexLock(InstrumentedMutex * mutex)55   explicit InstrumentedMutexLock(InstrumentedMutex* mutex) : mutex_(mutex) {
56     mutex_->Lock();
57   }
58 
~InstrumentedMutexLock()59   ~InstrumentedMutexLock() {
60     mutex_->Unlock();
61   }
62 
63  private:
64   InstrumentedMutex* const mutex_;
65   InstrumentedMutexLock(const InstrumentedMutexLock&) = delete;
66   void operator=(const InstrumentedMutexLock&) = delete;
67 };
68 
69 class InstrumentedCondVar {
70  public:
InstrumentedCondVar(InstrumentedMutex * instrumented_mutex)71   explicit InstrumentedCondVar(InstrumentedMutex* instrumented_mutex)
72       : cond_(&(instrumented_mutex->mutex_)),
73         stats_(instrumented_mutex->stats_),
74         env_(instrumented_mutex->env_),
75         stats_code_(instrumented_mutex->stats_code_) {}
76 
77   void Wait();
78 
79   bool TimedWait(uint64_t abs_time_us);
80 
Signal()81   void Signal() {
82     cond_.Signal();
83   }
84 
SignalAll()85   void SignalAll() {
86     cond_.SignalAll();
87   }
88 
89  private:
90   void WaitInternal();
91   bool TimedWaitInternal(uint64_t abs_time_us);
92   port::CondVar cond_;
93   Statistics* stats_;
94   Env* env_;
95   int stats_code_;
96 };
97 
98 }  // namespace ROCKSDB_NAMESPACE
99