From be939a80db584aecf94fc83305cd1529f4ddb51d Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 5 Oct 2017 17:36:44 +0200 Subject: Clang: Improve locking of string cache The string cache is only very seldom written but very often read. To improve thread scaling it is faster to lock it only for write operations. So we use a shared mutex which is locked in shared mode for read operations and locked exclusively for write operations. Change-Id: I2cc742d1b9cc15c162be40ab339fa8310640bc44 Reviewed-by: Tim Jenssen --- src/libs/clangsupport/filepathcache.h | 4 +- src/libs/clangsupport/stringcache.h | 77 +++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/libs/clangsupport/filepathcache.h b/src/libs/clangsupport/filepathcache.h index 61e8680965..553aed61f7 100644 --- a/src/libs/clangsupport/filepathcache.h +++ b/src/libs/clangsupport/filepathcache.h @@ -67,12 +67,12 @@ class FilePathCache final : private FilePathCacheBase { using DirectoryPathCache = StringCache; using FileNameCache = StringCache; public: diff --git a/src/libs/clangsupport/stringcache.h b/src/libs/clangsupport/stringcache.h index d3de7fe4dd..c09fd199c1 100644 --- a/src/libs/clangsupport/stringcache.h +++ b/src/libs/clangsupport/stringcache.h @@ -33,7 +33,7 @@ #include #include -#include +#include #include namespace ClangBackEnd { @@ -54,6 +54,8 @@ public: NonLockingMutex& operator=(const NonLockingMutex&) = delete; void lock() {} void unlock() {} + void lock_shared() {} + void unlock_shared() {} }; template @@ -122,23 +124,34 @@ public: IndexType stringId(Utils::SmallStringView stringView) { - std::lock_guard lock(m_mutex); + std::shared_lock sharedLock(m_mutex); + Found found = find(stringView); + + if (found.wasFound) + return found.iterator->id; + + sharedLock.unlock(); + std::lock_guard exclusiveLock(m_mutex); - return ungardedStringId(stringView); + found = find(stringView); + if (!found.wasFound) { + IndexType index = insertString(found.iterator, stringView, IndexType(m_indices.size())); + found.iterator = m_strings.begin() + index;; + } + + return found.iterator->id; } template std::vector stringIds(const Container &strings) { - std::lock_guard lock(m_mutex); - std::vector ids; ids.reserve(strings.size()); std::transform(strings.begin(), strings.end(), std::back_inserter(ids), - [&] (const auto &string) { return this->ungardedStringId(string); }); + [&] (const auto &string) { return this->stringId(string); }); return ids; } @@ -150,7 +163,7 @@ public: StringType string(IndexType id) const { - std::lock_guard lock(m_mutex); + std::shared_lock sharedLock(m_mutex); return m_strings.at(m_indices.at(id)).string; } @@ -158,28 +171,25 @@ public: template StringType string(IndexType id, Function storageFunction) { - std::lock_guard lock(m_mutex); + std::shared_lock sharedLock(m_mutex); - IndexType index; + if (IndexType(m_indices.size()) > id && m_indices.at(id) >= 0) + return m_strings.at(m_indices.at(id)).string; - if (IndexType(m_indices.size()) <= id) { - StringType string{storageFunction(id)}; - index = insertString(find(string).iterator, string, id); - } else { - index = m_indices.at(id); - if (index < 0) { - StringType string{storageFunction(id)}; - index = insertString(find(string).iterator, string, id); - } - } + sharedLock.unlock(); + std::lock_guard exclusiveLock(m_mutex); + IndexType index; + + StringType string{storageFunction(id)}; + index = insertString(find(string).iterator, string, id); - return m_strings.at(index).string; + return m_strings[index].string; } std::vector strings(const std::vector &ids) const { - std::lock_guard lock(m_mutex); + std::shared_lock sharedLock(m_mutex); std::vector strings; strings.reserve(ids.size()); @@ -200,12 +210,21 @@ public: template IndexType stringId(Utils::SmallStringView stringView, Function storageFunction) { - std::lock_guard lock(m_mutex); + std::shared_lock sharedLock(m_mutex); Found found = find(stringView); - if (!found.wasFound) - insertString(found.iterator, stringView, storageFunction(stringView)); + if (found.wasFound) + return found.iterator->id; + + sharedLock.unlock(); + std::lock_guard exclusiveLock(m_mutex); + + found = find(stringView); + if (!found.wasFound) { + IndexType index = insertString(found.iterator, stringView, storageFunction(stringView)); + found.iterator = m_strings.begin() + index; + } return found.iterator->id; } @@ -216,16 +235,6 @@ public: } private: - IndexType ungardedStringId(Utils::SmallStringView stringView) - { - Found found = find(stringView); - - if (!found.wasFound) - insertString(found.iterator, stringView, IndexType(m_indices.size())); - - return found.iterator->id; - } - Found find(Utils::SmallStringView stringView) { return findInSorted(m_strings.cbegin(), m_strings.cend(), stringView, compare); -- cgit v1.2.1