diff --git a/cache/lru_cache.cc b/cache/lru_cache.cc index e11ac6ddb..fdcbb4e86 100644 --- a/cache/lru_cache.cc +++ b/cache/lru_cache.cc @@ -100,14 +100,16 @@ void LRUHandleTable::Resize() { } LRUCacheShard::LRUCacheShard(size_t capacity, bool strict_capacity_limit, - double high_pri_pool_ratio) + double high_pri_pool_ratio, + bool use_adaptive_mutex) : capacity_(0), high_pri_pool_usage_(0), strict_capacity_limit_(strict_capacity_limit), high_pri_pool_ratio_(high_pri_pool_ratio), high_pri_pool_capacity_(0), usage_(0), - lru_usage_(0) { + lru_usage_(0), + mutex_(use_adaptive_mutex) { // Make empty circular linked list lru_.next = &lru_; lru_.prev = &lru_; @@ -462,7 +464,8 @@ std::string LRUCacheShard::GetPrintableOptions() const { LRUCache::LRUCache(size_t capacity, int num_shard_bits, bool strict_capacity_limit, double high_pri_pool_ratio, - std::shared_ptr allocator) + std::shared_ptr allocator, + bool use_adaptive_mutex) : ShardedCache(capacity, num_shard_bits, strict_capacity_limit, std::move(allocator)) { num_shards_ = 1 << num_shard_bits; @@ -471,7 +474,8 @@ LRUCache::LRUCache(size_t capacity, int num_shard_bits, size_t per_shard = (capacity + (num_shards_ - 1)) / num_shards_; for (int i = 0; i < num_shards_; i++) { new (&shards_[i]) - LRUCacheShard(per_shard, strict_capacity_limit, high_pri_pool_ratio); + LRUCacheShard(per_shard, strict_capacity_limit, high_pri_pool_ratio, + use_adaptive_mutex); } } @@ -540,13 +544,15 @@ std::shared_ptr NewLRUCache(const LRUCacheOptions& cache_opts) { return NewLRUCache(cache_opts.capacity, cache_opts.num_shard_bits, cache_opts.strict_capacity_limit, cache_opts.high_pri_pool_ratio, - cache_opts.memory_allocator); + cache_opts.memory_allocator, + cache_opts.use_adaptive_mutex); } std::shared_ptr NewLRUCache( size_t capacity, int num_shard_bits, bool strict_capacity_limit, double high_pri_pool_ratio, - std::shared_ptr memory_allocator) { + std::shared_ptr memory_allocator, + bool use_adaptive_mutex) { if (num_shard_bits >= 20) { return nullptr; // the cache cannot be sharded into too many fine pieces } @@ -559,7 +565,8 @@ std::shared_ptr NewLRUCache( } return std::make_shared(capacity, num_shard_bits, strict_capacity_limit, high_pri_pool_ratio, - std::move(memory_allocator)); + std::move(memory_allocator), + use_adaptive_mutex); } } // namespace rocksdb diff --git a/cache/lru_cache.h b/cache/lru_cache.h index 7f8878a44..665a97a5c 100644 --- a/cache/lru_cache.h +++ b/cache/lru_cache.h @@ -168,7 +168,7 @@ class LRUHandleTable { class ALIGN_AS(CACHE_LINE_SIZE) LRUCacheShard : public CacheShard { public: LRUCacheShard(size_t capacity, bool strict_capacity_limit, - double high_pri_pool_ratio); + double high_pri_pool_ratio, bool use_adaptive_mutex); virtual ~LRUCacheShard(); // Separate from constructor so caller can easily make an array of LRUCache @@ -288,7 +288,8 @@ class LRUCache : public ShardedCache { public: LRUCache(size_t capacity, int num_shard_bits, bool strict_capacity_limit, double high_pri_pool_ratio, - std::shared_ptr memory_allocator = nullptr); + std::shared_ptr memory_allocator = nullptr, + bool use_adaptive_mutex = kDefaultToAdaptiveMutex); virtual ~LRUCache(); virtual const char* Name() const override { return "LRUCache"; } virtual CacheShard* GetShard(int shard) override; diff --git a/cache/lru_cache_test.cc b/cache/lru_cache_test.cc index 16c798fb0..9980dd72b 100644 --- a/cache/lru_cache_test.cc +++ b/cache/lru_cache_test.cc @@ -25,12 +25,13 @@ class LRUCacheTest : public testing::Test { } } - void NewCache(size_t capacity, double high_pri_pool_ratio = 0.0) { + void NewCache(size_t capacity, double high_pri_pool_ratio = 0.0, + bool use_adaptive_mutex = kDefaultToAdaptiveMutex) { DeleteCache(); cache_ = reinterpret_cast( port::cacheline_aligned_alloc(sizeof(LRUCacheShard))); new (cache_) LRUCacheShard(capacity, false /*strict_capcity_limit*/, - high_pri_pool_ratio); + high_pri_pool_ratio, use_adaptive_mutex); } void Insert(const std::string& key, diff --git a/include/rocksdb/cache.h b/include/rocksdb/cache.h index 190112b37..ed7790aeb 100644 --- a/include/rocksdb/cache.h +++ b/include/rocksdb/cache.h @@ -34,6 +34,8 @@ namespace rocksdb { class Cache; +extern const bool kDefaultToAdaptiveMutex; + struct LRUCacheOptions { // Capacity of the cache. size_t capacity = 0; @@ -68,15 +70,23 @@ struct LRUCacheOptions { // internally (currently only XPRESS). std::shared_ptr memory_allocator; + // Whether to use adaptive mutexes for cache shards. Note that adaptive + // mutexes need to be supported by the platform in order for this to have any + // effect. The default value is true if RocksDB is compiled with + // -DROCKSDB_DEFAULT_TO_ADAPTIVE_MUTEX, false otherwise. + bool use_adaptive_mutex = kDefaultToAdaptiveMutex; + LRUCacheOptions() {} LRUCacheOptions(size_t _capacity, int _num_shard_bits, bool _strict_capacity_limit, double _high_pri_pool_ratio, - std::shared_ptr _memory_allocator = nullptr) + std::shared_ptr _memory_allocator = nullptr, + bool _use_adaptive_mutex = kDefaultToAdaptiveMutex) : capacity(_capacity), num_shard_bits(_num_shard_bits), strict_capacity_limit(_strict_capacity_limit), high_pri_pool_ratio(_high_pri_pool_ratio), - memory_allocator(std::move(_memory_allocator)) {} + memory_allocator(std::move(_memory_allocator)), + use_adaptive_mutex(_use_adaptive_mutex) {} }; // Create a new cache with a fixed size capacity. The cache is sharded @@ -90,7 +100,8 @@ struct LRUCacheOptions { extern std::shared_ptr NewLRUCache( size_t capacity, int num_shard_bits = -1, bool strict_capacity_limit = false, double high_pri_pool_ratio = 0.0, - std::shared_ptr memory_allocator = nullptr); + std::shared_ptr memory_allocator = nullptr, + bool use_adaptive_mutex = kDefaultToAdaptiveMutex); extern std::shared_ptr NewLRUCache(const LRUCacheOptions& cache_opts); diff --git a/port/port_posix.cc b/port/port_posix.cc index 0377d448f..80081e480 100644 --- a/port/port_posix.cc +++ b/port/port_posix.cc @@ -25,6 +25,21 @@ #include "util/logging.h" namespace rocksdb { + +// We want to give users opportunity to default all the mutexes to adaptive if +// not specified otherwise. This enables a quick way to conduct various +// performance related experiements. +// +// NB! Support for adaptive mutexes is turned on by definining +// ROCKSDB_PTHREAD_ADAPTIVE_MUTEX during the compilation. If you use RocksDB +// build environment then this happens automatically; otherwise it's up to the +// consumer to define the identifier. +#ifdef ROCKSDB_DEFAULT_TO_ADAPTIVE_MUTEX +extern const bool kDefaultToAdaptiveMutex = true; +#else +extern const bool kDefaultToAdaptiveMutex = false; +#endif + namespace port { static int PthreadCall(const char* label, int result) { diff --git a/port/port_posix.h b/port/port_posix.h index c53a640e9..63d7239fe 100644 --- a/port/port_posix.h +++ b/port/port_posix.h @@ -82,6 +82,9 @@ #endif namespace rocksdb { + +extern const bool kDefaultToAdaptiveMutex; + namespace port { // For use at db/file_indexer.h kLevelMaxIndex @@ -100,19 +103,7 @@ class CondVar; class Mutex { public: -// We want to give users opportunity to default all the mutexes to adaptive if -// not specified otherwise. This enables a quick way to conduct various -// performance related experiements. -// -// NB! Support for adaptive mutexes is turned on by definining -// ROCKSDB_PTHREAD_ADAPTIVE_MUTEX during the compilation. If you use RocksDB -// build environment then this happens automatically; otherwise it's up to the -// consumer to define the identifier. -#ifdef ROCKSDB_DEFAULT_TO_ADAPTIVE_MUTEX - explicit Mutex(bool adaptive = true); -#else - explicit Mutex(bool adaptive = false); -#endif + explicit Mutex(bool adaptive = kDefaultToAdaptiveMutex); ~Mutex(); void Lock(); diff --git a/port/win/port_win.cc b/port/win/port_win.cc index 6ca5bba3b..9b9a5f1bb 100644 --- a/port/win/port_win.cc +++ b/port/win/port_win.cc @@ -36,6 +36,9 @@ #include "util/logging.h" namespace rocksdb { + +extern const bool kDefaultToAdaptiveMutex = false; + namespace port { #ifdef ROCKSDB_WINDOWS_UTF8_FILENAMES diff --git a/port/win/port_win.h b/port/win/port_win.h index 8f579c984..de41cdc7f 100644 --- a/port/win/port_win.h +++ b/port/win/port_win.h @@ -78,6 +78,8 @@ namespace rocksdb { #define PREFETCH(addr, rw, locality) +extern const bool kDefaultToAdaptiveMutex; + namespace port { // VS < 2015 @@ -127,7 +129,7 @@ class CondVar; class Mutex { public: - /* implicit */ Mutex(bool adaptive = false) + /* implicit */ Mutex(bool adaptive = kDefaultToAdaptiveMutex) #ifndef NDEBUG : locked_(false) #endif