| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- #pragma once
- #include "monitoring/statistics_impl.h"
- #include "port/port.h"
- #include "rocksdb/statistics.h"
- #include "rocksdb/system_clock.h"
- #include "rocksdb/thread_status.h"
- #include "util/stop_watch.h"
- namespace ROCKSDB_NAMESPACE {
- class InstrumentedCondVar;
- // A wrapper class for port::Mutex that provides additional layer
- // for collecting stats and instrumentation.
- class InstrumentedMutex {
- public:
- explicit InstrumentedMutex(bool adaptive = false)
- : mutex_(adaptive), stats_(nullptr), clock_(nullptr), stats_code_(0) {}
- explicit InstrumentedMutex(SystemClock* clock, bool adaptive = false)
- : mutex_(adaptive), stats_(nullptr), clock_(clock), stats_code_(0) {}
- InstrumentedMutex(Statistics* stats, SystemClock* clock, int stats_code,
- bool adaptive = false)
- : mutex_(adaptive),
- stats_(stats),
- clock_(clock),
- stats_code_(stats_code) {}
- #ifdef COERCE_CONTEXT_SWITCH
- InstrumentedMutex(Statistics* stats, SystemClock* clock, int stats_code,
- InstrumentedCondVar* bg_cv, bool adaptive = false)
- : mutex_(adaptive),
- stats_(stats),
- clock_(clock),
- stats_code_(stats_code),
- bg_cv_(bg_cv) {}
- #endif
- void Lock();
- void Unlock() { mutex_.Unlock(); }
- void AssertHeld() const { mutex_.AssertHeld(); }
- private:
- void LockInternal();
- friend class InstrumentedCondVar;
- port::Mutex mutex_;
- Statistics* stats_;
- SystemClock* clock_;
- int stats_code_;
- #ifdef COERCE_CONTEXT_SWITCH
- InstrumentedCondVar* bg_cv_ = nullptr;
- #endif
- };
- class ALIGN_AS(CACHE_LINE_SIZE) CacheAlignedInstrumentedMutex
- : public InstrumentedMutex {
- using InstrumentedMutex::InstrumentedMutex;
- };
- static_assert(alignof(CacheAlignedInstrumentedMutex) != CACHE_LINE_SIZE ||
- sizeof(CacheAlignedInstrumentedMutex) % CACHE_LINE_SIZE == 0);
- // RAII wrapper for InstrumentedMutex
- class InstrumentedMutexLock {
- public:
- explicit InstrumentedMutexLock(InstrumentedMutex* mutex) : mutex_(mutex) {
- mutex_->Lock();
- }
- ~InstrumentedMutexLock() { mutex_->Unlock(); }
- private:
- InstrumentedMutex* const mutex_;
- InstrumentedMutexLock(const InstrumentedMutexLock&) = delete;
- void operator=(const InstrumentedMutexLock&) = delete;
- };
- // RAII wrapper for temporary releasing InstrumentedMutex inside
- // InstrumentedMutexLock
- class InstrumentedMutexUnlock {
- public:
- explicit InstrumentedMutexUnlock(InstrumentedMutex* mutex) : mutex_(mutex) {
- mutex_->Unlock();
- }
- ~InstrumentedMutexUnlock() { mutex_->Lock(); }
- private:
- InstrumentedMutex* const mutex_;
- InstrumentedMutexUnlock(const InstrumentedMutexUnlock&) = delete;
- void operator=(const InstrumentedMutexUnlock&) = delete;
- };
- class InstrumentedCondVar {
- public:
- explicit InstrumentedCondVar(InstrumentedMutex* instrumented_mutex)
- : cond_(&(instrumented_mutex->mutex_)),
- stats_(instrumented_mutex->stats_),
- clock_(instrumented_mutex->clock_),
- stats_code_(instrumented_mutex->stats_code_) {}
- void Wait();
- bool TimedWait(uint64_t abs_time_us);
- void Signal() { cond_.Signal(); }
- void SignalAll() { cond_.SignalAll(); }
- private:
- void WaitInternal();
- bool TimedWaitInternal(uint64_t abs_time_us);
- port::CondVar cond_;
- Statistics* stats_;
- SystemClock* clock_;
- int stats_code_;
- };
- } // namespace ROCKSDB_NAMESPACE
|