diff --git a/llvm/include/llvm/ADT/ConcurrentHashtable.h b/llvm/include/llvm/ADT/ConcurrentHashtable.h --- a/llvm/include/llvm/ADT/ConcurrentHashtable.h +++ b/llvm/include/llvm/ADT/ConcurrentHashtable.h @@ -175,8 +175,10 @@ Bucket &CurBucket = BucketsArray[getBucketIdx(Hash)]; uint32_t ExtHashBits = getExtHashBits(Hash); +#if LLVM_ENABLE_THREADS // Lock bucket. CurBucket.Guard.lock(); +#endif HashesPtr BucketHashes = CurBucket.Hashes; DataPtr BucketEntries = CurBucket.Entries; @@ -194,7 +196,9 @@ CurBucket.NumberOfEntries++; RehashBucket(CurBucket); +#if LLVM_ENABLE_THREADS CurBucket.Guard.unlock(); +#endif return {NewData, true}; } @@ -204,7 +208,9 @@ KeyDataTy *EntryData = BucketEntries[CurEntryIdx]; if (Info::isEqual(Info::getKey(*EntryData), NewValue)) { // Already existed entry matched with inserted data is found. +#if LLVM_ENABLE_THREADS CurBucket.Guard.unlock(); +#endif return {EntryData, false}; } @@ -283,8 +289,10 @@ // [Size] entries. DataPtr Entries = nullptr; +#if LLVM_ENABLE_THREADS // Mutex for this bucket. std::mutex Guard; +#endif }; // Reallocate and rehash bucket if this is full enough. diff --git a/llvm/include/llvm/DWARFLinkerParallel/StringPool.h b/llvm/include/llvm/DWARFLinkerParallel/StringPool.h --- a/llvm/include/llvm/DWARFLinkerParallel/StringPool.h +++ b/llvm/include/llvm/DWARFLinkerParallel/StringPool.h @@ -22,19 +22,26 @@ /// and a string body which is placed right after StringEntry. using StringEntry = StringMapEntry; -class PerThreadStringAllocator - : public AllocatorBase { +class SimpleStringAllocator : public AllocatorBase { public: inline LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) { - return ThreadLocalAllocator.Allocate(Size, Align(Alignment)); +#if LLVM_ENABLE_THREADS + std::lock_guard Guard(AllocatorMutex); +#endif + + return Allocator.Allocate(Size, Align(Alignment)); } // Pull in base class overloads. - using AllocatorBase::Allocate; + using AllocatorBase::Allocate; private: - static thread_local BumpPtrAllocator ThreadLocalAllocator; +#if LLVM_ENABLE_THREADS + std::mutex AllocatorMutex; +#endif + + BumpPtrAllocator Allocator; }; class StringPoolEntryInfo { @@ -56,29 +63,27 @@ /// \returns newly created object of KeyDataTy type. static inline StringEntry *create(const StringRef &Key, - PerThreadStringAllocator &Allocator) { + SimpleStringAllocator &Allocator) { return StringEntry::create(Key, Allocator); } }; -class StringPool : public ConcurrentHashTableByPtr { +class StringPool + : public ConcurrentHashTableByPtr< + StringRef, StringEntry, SimpleStringAllocator, StringPoolEntryInfo> { public: StringPool() - : ConcurrentHashTableByPtr( - Allocator) {} + : ConcurrentHashTableByPtr(Allocator) {} StringPool(size_t InitialSize) - : ConcurrentHashTableByPtr( - Allocator, InitialSize) {} + : ConcurrentHashTableByPtr(Allocator, InitialSize) {} - PerThreadStringAllocator &getAllocatorRef() { return Allocator; } + SimpleStringAllocator &getAllocatorRef() { return Allocator; } private: - PerThreadStringAllocator Allocator; + SimpleStringAllocator Allocator; }; } // end of namespace dwarflinker_parallel diff --git a/llvm/lib/DWARFLinkerParallel/StringPool.cpp b/llvm/lib/DWARFLinkerParallel/StringPool.cpp --- a/llvm/lib/DWARFLinkerParallel/StringPool.cpp +++ b/llvm/lib/DWARFLinkerParallel/StringPool.cpp @@ -7,6 +7,3 @@ //===----------------------------------------------------------------------===// #include "llvm/DWARFLinkerParallel/StringPool.h" - -thread_local llvm::BumpPtrAllocator - llvm::dwarflinker_parallel::PerThreadStringAllocator::ThreadLocalAllocator; diff --git a/llvm/unittests/ADT/ConcurrentHashtableTest.cpp b/llvm/unittests/ADT/ConcurrentHashtableTest.cpp --- a/llvm/unittests/ADT/ConcurrentHashtableTest.cpp +++ b/llvm/unittests/ADT/ConcurrentHashtableTest.cpp @@ -36,25 +36,38 @@ std::array ExtraData; }; -static thread_local BumpPtrAllocator ThreadLocalAllocator; -class PerThreadAllocator : public AllocatorBase { +class SimpleAllocator : public AllocatorBase { public: inline LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) { - return ThreadLocalAllocator.Allocate(Size, Align(Alignment)); +#if LLVM_ENABLE_THREADS + std::lock_guard Guard(AllocatorMutex); +#endif + + return Allocator.Allocate(Size, Align(Alignment)); } - inline size_t getBytesAllocated() const { - return ThreadLocalAllocator.getBytesAllocated(); + inline size_t getBytesAllocated() { +#if LLVM_ENABLE_THREADS + std::lock_guard Guard(AllocatorMutex); +#endif + + return Allocator.getBytesAllocated(); } // Pull in base class overloads. - using AllocatorBase::Allocate; + using AllocatorBase::Allocate; + +protected: +#if LLVM_ENABLE_THREADS + std::mutex AllocatorMutex; +#endif + BumpPtrAllocator Allocator; } Allocator; TEST(ConcurrentHashTableTest, AddStringEntries) { ConcurrentHashTableByPtr< - std::string, String, PerThreadAllocator, - ConcurrentHashTableInfoByPtr> + std::string, String, SimpleAllocator, + ConcurrentHashTableInfoByPtr> HashTable(Allocator, 10); size_t AllocatedBytesAtStart = Allocator.getBytesAllocated(); @@ -102,8 +115,8 @@ TEST(ConcurrentHashTableTest, AddStringMultiplueEntries) { const size_t NumElements = 10000; ConcurrentHashTableByPtr< - std::string, String, PerThreadAllocator, - ConcurrentHashTableInfoByPtr> + std::string, String, SimpleAllocator, + ConcurrentHashTableInfoByPtr> HashTable(Allocator); // Check insertion. @@ -147,8 +160,8 @@ // Number of elements exceeds original size, thus hashtable should be resized. const size_t NumElements = 20000; ConcurrentHashTableByPtr< - std::string, String, PerThreadAllocator, - ConcurrentHashTableInfoByPtr> + std::string, String, SimpleAllocator, + ConcurrentHashTableInfoByPtr> HashTable(Allocator, 100); // Check insertion. @@ -191,8 +204,8 @@ TEST(ConcurrentHashTableTest, AddStringEntriesParallel) { const size_t NumElements = 10000; ConcurrentHashTableByPtr< - std::string, String, PerThreadAllocator, - ConcurrentHashTableInfoByPtr> + std::string, String, SimpleAllocator, + ConcurrentHashTableInfoByPtr> HashTable(Allocator); // Check parallel insertion. @@ -235,8 +248,8 @@ TEST(ConcurrentHashTableTest, AddStringEntriesParallelWithResize) { const size_t NumElements = 20000; ConcurrentHashTableByPtr< - std::string, String, PerThreadAllocator, - ConcurrentHashTableInfoByPtr> + std::string, String, SimpleAllocator, + ConcurrentHashTableInfoByPtr> HashTable(Allocator, 100); // Check parallel insertion.