[llvm] [ORC] Fix synchronization in CoreAPIsTest. (PR #144556)

Jameson Nash via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 29 08:45:52 PDT 2025


https://github.com/vtjnash updated https://github.com/llvm/llvm-project/pull/144556

>From a6a03299759538bbcc876723aaa41dec5fd184d7 Mon Sep 17 00:00:00 2001
From: Jameson Nash <vtjnash at gmail.com>
Date: Tue, 17 Jun 2025 15:54:29 +0000
Subject: [PATCH] [ORC] Fix synchronization in CoreAPIsTest.

The code previously appeared to have a (benign?) race condition on
`WorkThreads.size`, since it was being accessed outside of the mutex
lock that protected it on the threads. This is usually okay since
1a1d6e6f98738be249b20994bcfed48dccac59e3, but doesn't seem reliable in
general, so fix this code to express the intent more accurately. This
relies on the same general principles as ref-counting, where each
existing reference (thread) can add new references (threads) because
they already have a reference themselves (until joined).
---
 .../ExecutionEngine/Orc/CoreAPIsTest.cpp       | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
index 4a05a293fa51f..080f257ad8dac 100644
--- a/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
+++ b/llvm/unittests/ExecutionEngine/Orc/CoreAPIsTest.cpp
@@ -1559,16 +1559,11 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
 #if LLVM_ENABLE_THREADS
 
   std::mutex WorkThreadsMutex;
-  std::vector<std::thread> WorkThreads;
+  SmallVector<std::thread, 0> WorkThreads;
   DispatchOverride = [&](std::unique_ptr<Task> T) {
-    std::promise<void> WaitP;
     std::lock_guard<std::mutex> Lock(WorkThreadsMutex);
     WorkThreads.push_back(
-        std::thread([T = std::move(T), WaitF = WaitP.get_future()]() mutable {
-          WaitF.get();
-          T->run();
-        }));
-    WaitP.set_value();
+        std::thread([T = std::move(T)]() mutable { T->run(); }));
   };
 
   cantFail(JD.define(absoluteSymbols({{Foo, FooSym}})));
@@ -1580,8 +1575,15 @@ TEST_F(CoreAPIsStandardTest, TestLookupWithThreadedMaterialization) {
   EXPECT_EQ(FooLookupResult.getFlags(), FooSym.getFlags())
       << "lookup returned incorrect flags";
 
-  for (auto &WT : WorkThreads)
+  std::unique_lock Lock(WorkThreadsMutex);
+  // This works because every child thread that is allowed to use WorkThreads
+  // must either be in WorkThreads or its parent must be in WorkThreads.
+  while (!WorkThreads.empty()) {
+    auto WT = WorkThreads.pop_back_val();
+    Lock.unlock();
     WT.join();
+    Lock.lock();
+  }
 #endif
 }
 



More information about the llvm-commits mailing list