From: Radoslaw Zarzynski Date: Fri, 12 Jul 2019 13:44:38 +0000 (-0400) Subject: common, crypto: give names to OpenSSL's mutexes. X-Git-Tag: v15.1.0~2183^2~3 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=c466a625f7d7a022d3b0f4e0dfc42405f67ed408;p=ceph-ci.git common, crypto: give names to OpenSSL's mutexes. Fixes: http://tracker.ceph.com/issues/40698 Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/common/ceph_crypto.cc b/src/common/ceph_crypto.cc index f63f39a3bbd..b89632c00c2 100644 --- a/src/common/ceph_crypto.cc +++ b/src/common/ceph_crypto.cc @@ -32,9 +32,13 @@ namespace ceph::crypto::ssl { #if OPENSSL_VERSION_NUMBER < 0x10100000L static std::atomic_uint32_t crypto_refs; -static std::vector ssl_mutexes { - static_cast(std::max(CRYPTO_num_locks(), 0)) -}; + +static auto ssl_mutexes = ceph::make_lock_container( + static_cast(std::max(CRYPTO_num_locks(), 0)), + [](const size_t i) { + return ceph::make_shared_mutex( + std::string("ssl-mutex-") + std::to_string(i)); + }); static struct { // we could use e.g. unordered_set instead at the price of providing diff --git a/src/common/ceph_mutex.h b/src/common/ceph_mutex.h index 13667870eef..5f340561eb2 100644 --- a/src/common/ceph_mutex.h +++ b/src/common/ceph_mutex.h @@ -3,6 +3,9 @@ #pragma once +#include +#include "common/containers.h" + // What and why // ============ // @@ -44,6 +47,11 @@ namespace ceph { return {}; } + template + shared_mutex make_shared_mutex(Args&& ...args) { + return {}; + } + #define ceph_mutex_is_locked(m) true #define ceph_mutex_is_locked_by_me(m) true } @@ -135,3 +143,21 @@ namespace ceph { #endif // CEPH_DEBUG_MUTEX #endif // WITH_SEASTAR + +namespace ceph { + +template +ceph::containers::tiny_vector make_lock_container( + const std::size_t num_instances, + LockFactoryT&& lock_factory) +{ + return { + num_instances, [&](const std::size_t i, auto emplacer) { + // this will be called `num_instances` times + new (emplacer.data()) LockT {lock_factory(i)}; + } + }; +} +} // namespace ceph + diff --git a/src/common/containers.h b/src/common/containers.h index a52f43f49d7..c0aa835445b 100644 --- a/src/common/containers.h +++ b/src/common/containers.h @@ -53,7 +53,7 @@ namespace ceph::containers { // 4. std::unique_ptr: extra indirection together with memory // fragmentation. -template +template class tiny_vector { // NOTE: to avoid false sharing consider aligning to cache line using storage_unit_t = \ @@ -97,6 +97,17 @@ public: // } // } // ``` + // + // For the sake of supporting the ceph::make_mutex() family of + // factories, which relies on C++17's guaranteed copy elision, + // the emplacer provides `data()` to retrieve the location for + // constructing the instance with placement-new. This is handy + // as the `emplace()` depends on perfect forwarding, and thus + // interfere with the elision for cases like: + // ``` + // emplacer.emplace(ceph::make_mutex("mtx-name")); + // ``` + // See: https://stackoverflow.com/a/52498826 class emplacer { friend class tiny_vector; @@ -107,13 +118,17 @@ public: } public: + void* data() { + void* const ret = &parent->data[parent->_size++]; + parent = nullptr; + return ret; + } + template void emplace(Args&&... args) { - if (!parent) { - return; + if (parent) { + new (data()) Value(std::forward(args)...); } - new (&parent->data[parent->_size++]) Value(std::forward(args)...); - parent = nullptr; } };