From f0a88ffa1f11cc9484a87965fea408982cf914a8 Mon Sep 17 00:00:00 2001 From: Philippe Canal <pcanal@fnal.gov> Date: Thu, 11 Feb 2021 18:04:40 -0600 Subject: [PATCH] Improve TClass::GetBaseClassOffset parallelism. TClass::GetBaseClassOffset is a 'often' used routine in the I/O. In the fast path (looking up in a cache), rather than taking the global read lock (which is not only global but also 'slower' than a regular mutex), we are now use a instance specific mutex to protect the cache. --- core/metacling/src/TClingClassInfo.cxx | 3 ++- core/metacling/src/TClingClassInfo.h | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/core/metacling/src/TClingClassInfo.cxx b/core/metacling/src/TClingClassInfo.cxx index a6275d495cf..726c2788e9a 100644 --- a/core/metacling/src/TClingClassInfo.cxx +++ b/core/metacling/src/TClingClassInfo.cxx @@ -135,6 +135,7 @@ void TClingClassInfo::AddBaseOffsetValue(const clang::Decl* decl, ptrdiff_t offs // determined by the parameter decl. OffsetPtrFunc_t executableFunc = 0; + std::unique_lock<std::mutex> lock(fOffsetCacheMutex); fOffsetCache[decl] = std::make_pair(offset, executableFunc); } @@ -611,7 +612,7 @@ ptrdiff_t TClingClassInfo::GetBaseOffset(TClingClassInfo* base, void* address, b { { - R__READ_LOCKGUARD(ROOT::gCoreMutex); + std::unique_lock<std::mutex> lock(fOffsetCacheMutex); // Check for the offset in the cache. auto iter = fOffsetCache.find(base->GetDecl()); diff --git a/core/metacling/src/TClingClassInfo.h b/core/metacling/src/TClingClassInfo.h index 32d395b3d14..f89388301a2 100644 --- a/core/metacling/src/TClingClassInfo.h +++ b/core/metacling/src/TClingClassInfo.h @@ -34,6 +34,7 @@ #include <vector> #include <string> #include <utility> +#include <mutex> #include "llvm/ADT/DenseMap.h" @@ -69,6 +70,8 @@ private: std::vector<clang::DeclContext::decl_iterator> fIterStack; // Recursion stack for traversing nested scopes. std::string fTitle; // The meta info for the class. std::string fDeclFileName; // Name of the file where the underlying entity is declared. + + std::mutex fOffsetCacheMutex; llvm::DenseMap<const clang::Decl*, std::pair<ptrdiff_t, OffsetPtrFunc_t> > fOffsetCache; // Functions already generated for offsets. explicit TClingClassInfo() = delete; @@ -82,11 +85,21 @@ public: // Types public: + TClingClassInfo(const TClingClassInfo &rhs) : // Copy all but the mutex + TClingDeclInfo(rhs), + fInterp(rhs.fInterp), fFirstTime(rhs.fFirstTime), fDescend(rhs.fDescend), + fIterAll(rhs.fIterAll), fIsIter(rhs.fIsIter), fIter(rhs.fIter), + fType(rhs.fType), fIterStack(rhs.fIterStack), fTitle(rhs.fTitle), + fDeclFileName(rhs.fDeclFileName), fOffsetCache(rhs.fOffsetCache) + {} explicit TClingClassInfo(cling::Interpreter *, Bool_t all = kTRUE); explicit TClingClassInfo(cling::Interpreter *, const char *classname, bool intantiateTemplate = kTRUE); explicit TClingClassInfo(cling::Interpreter *, const clang::Type &); explicit TClingClassInfo(cling::Interpreter *, const clang::Decl *); - void AddBaseOffsetFunction(const clang::Decl* decl, OffsetPtrFunc_t func) { fOffsetCache[decl] = std::make_pair(0L, func); } + void AddBaseOffsetFunction(const clang::Decl* decl, OffsetPtrFunc_t func) { + std::unique_lock<std::mutex> lock(fOffsetCacheMutex); + fOffsetCache[decl] = std::make_pair(0L, func); + } void AddBaseOffsetValue(const clang::Decl* decl, ptrdiff_t offset); long ClassProperty() const; void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const; -- GitLab