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)); }