LLVMReactor: Mutex calls to llvm::orc::IRCompileLayer.
TSAN claims there are data races in the compileLayer. Specifically, it takes objection to compileLayer.addModule() being called at the same time as compileLayer.removeModule().
Bug: b/133127573
Change-Id: I19196d0c952bc308c2e47a848c93b092d5eea1ea
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31832
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Reactor/LLVMReactor.cpp b/src/Reactor/LLVMReactor.cpp
index 7df7d8a..81f8e27 100644
--- a/src/Reactor/LLVMReactor.cpp
+++ b/src/Reactor/LLVMReactor.cpp
@@ -76,9 +76,10 @@
#include <unordered_map>
#include <fstream>
+#include <iostream>
+#include <mutex>
#include <numeric>
#include <thread>
-#include <iostream>
#if defined(__i386__) || defined(__x86_64__)
#include <xmmintrin.h>
@@ -599,7 +600,8 @@
std::unique_ptr<llvm::TargetMachine> targetMachine;
const llvm::DataLayout dataLayout;
ObjLayer objLayer;
- CompileLayer compileLayer;
+ CompileLayer compileLayer; // guarded by mutex
+ std::mutex mutex;
size_t emittedFunctionsNum;
public:
@@ -690,22 +692,27 @@
mod->setDataLayout(dataLayout);
auto moduleKey = session.allocateVModule();
- llvm::cantFail(compileLayer.addModule(moduleKey, std::move(mod)));
- funcs = nullptr; // Now points to released memory.
+
+ // Resolve the function symbols - needs to be performed under mutex lock.
+ std::vector<llvm::JITSymbol> symbols;
+ {
+ std::unique_lock<std::mutex> lock(mutex);
+ llvm::cantFail(compileLayer.addModule(moduleKey, std::move(mod)));
+ funcs = nullptr; // Now points to released memory.
+ for (size_t i = 0; i < count; i++)
+ {
+ symbols.push_back(compileLayer.findSymbolIn(moduleKey, mangledNames[i], false));
+ }
+ }
// Resolve the function addresses.
std::vector<void*> addresses(count);
for (size_t i = 0; i < count; i++)
{
- llvm::JITSymbol symbol = compileLayer.findSymbolIn(moduleKey, mangledNames[i], false);
-
- llvm::Expected<llvm::JITTargetAddress> expectAddr = symbol.getAddress();
- if(!expectAddr)
+ if(auto expectAddr = symbols[i].getAddress())
{
- return nullptr;
+ addresses[i] = reinterpret_cast<void *>(static_cast<intptr_t>(expectAddr.get()));
}
-
- addresses[i] = reinterpret_cast<void *>(static_cast<intptr_t>(expectAddr.get()));
}
return new LLVMRoutine(addresses.data(), count, releaseRoutineCallback, this, moduleKey);
@@ -750,6 +757,7 @@
private:
void releaseRoutineModule(llvm::orc::VModuleKey moduleKey)
{
+ std::unique_lock<std::mutex> lock(mutex);
llvm::cantFail(compileLayer.removeModule(moduleKey));
}