Skip to content

Commit 126bcc9

Browse files
[OutputBackend] Make adding outputs to HashingOutputBackend thread-safe
Make adding outputs to `HashingOutputBackend` thread-safe. This is needed when compiler can write multiple outputs at the same time to the output backend and StringMap can lose output or crash during rehashing. Iterating and checking the hashing outputs still requires synchronization and is not thread-safe.
1 parent 75361c3 commit 126bcc9

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

llvm/include/llvm/Support/HashingOutputBackend.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
#include "llvm/ADT/StringExtras.h"
1313
#include "llvm/ADT/StringMap.h"
14-
#include "llvm/Support/Endian.h"
1514
#include "llvm/Support/HashBuilder.h"
1615
#include "llvm/Support/VirtualOutputBackend.h"
1716
#include "llvm/Support/VirtualOutputConfig.h"
1817
#include "llvm/Support/raw_ostream.h"
18+
#include <mutex>
1919

2020
namespace llvm {
2121
namespace vfs {
@@ -56,6 +56,7 @@ template <typename HasherT> class HashingOutputBackend : public OutputBackend {
5656
private:
5757
friend class HashingOutputFile<HasherT>;
5858
void addOutputFile(StringRef Path, StringRef Hash) {
59+
std::lock_guard<std::mutex> Lock(OutputHashLock);
5960
OutputHashes[Path] = std::string(Hash);
6061
}
6162

@@ -83,6 +84,7 @@ template <typename HasherT> class HashingOutputBackend : public OutputBackend {
8384
}
8485

8586
private:
87+
std::mutex OutputHashLock;
8688
StringMap<std::string> OutputHashes;
8789
};
8890

llvm/unittests/Support/VirtualOutputBackendsTest.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "llvm/Support/BLAKE3.h"
1212
#include "llvm/Support/HashingOutputBackend.h"
1313
#include "llvm/Support/MemoryBuffer.h"
14+
#include "llvm/Support/ThreadPool.h"
15+
#include "llvm/Support/raw_ostream.h"
1416
#include "llvm/Testing/Support/Error.h"
1517
#include "gtest/gtest.h"
1618

@@ -883,4 +885,33 @@ TEST(HashingBackendTest, HashOutput) {
883885
Backend.getHashValueForFile("file5"));
884886
}
885887

888+
TEST(HashingBackendTest, ParallelHashOutput) {
889+
const unsigned NumFile = 20;
890+
DefaultThreadPool Pool;
891+
HashingOutputBackend<BLAKE3> Backend;
892+
auto getFileName = [](unsigned Idx) -> std::string {
893+
std::string Name;
894+
raw_string_ostream OS(Name);
895+
OS << "file" << Idx;
896+
return Name;
897+
};
898+
for (unsigned I = 0; I < NumFile; ++I) {
899+
Pool.async(
900+
[&](unsigned Idx) {
901+
OutputFile O;
902+
auto Name = getFileName(Idx);
903+
EXPECT_THAT_ERROR(Backend.createFile(Name).moveInto(O), Succeeded());
904+
O << "some data" << Idx;
905+
EXPECT_THAT_ERROR(O.keep(), Succeeded());
906+
},
907+
I);
908+
}
909+
Pool.wait();
910+
911+
for (unsigned I = 0; I < NumFile; ++I) {
912+
auto Name = getFileName(I);
913+
auto Hash = Backend.getHashValueForFile(Name);
914+
EXPECT_TRUE(Hash);
915+
}
916+
}
886917
} // end namespace

0 commit comments

Comments
 (0)