Skip to content

Commit 145ce28

Browse files
committed
some cleanup, race condition fix
1 parent 05052ba commit 145ce28

File tree

2 files changed

+48
-5
lines changed

2 files changed

+48
-5
lines changed

llvm/include/llvm/ExecutionEngine/Orc/TaskDispatch.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,46 @@ class promise {
266266
std::shared_ptr<typename future<T>::state> state_;
267267
};
268268

269+
/// Specialization of future<void>
270+
template <> class future<void> : public future_base {
271+
public:
272+
using state = future_base::state_base;
273+
274+
future() = default;
275+
future(const future &) = delete;
276+
future &operator=(const future &) = delete;
277+
future(future &&) = default;
278+
future &operator=(future &&) = default;
279+
280+
/// Get the value (void), helping with task dispatch while waiting.
281+
void get(TaskDispatcher &D) { wait(D); }
282+
283+
private:
284+
friend class promise<void>;
285+
286+
explicit future(std::shared_ptr<state> state) : future_base(state) {}
287+
};
288+
289+
/// Specialization of promise<void>
290+
template <> class promise<void> {
291+
friend class future<void>;
292+
293+
public:
294+
promise() : state_(std::make_shared<future<void>::state>()) {}
295+
promise(const promise &) = delete;
296+
promise &operator=(const promise &) = delete;
297+
promise(promise &&) = default;
298+
promise &operator=(promise &&) = default;
299+
300+
/// Get the associated future
301+
future<void> get_future() { return future<void>(state_); }
302+
303+
/// Set the value (void)
304+
void set_value() { state_->status_.store(1, std::memory_order_release); }
305+
306+
private:
307+
std::shared_ptr<future<void>::state> state_;
308+
};
269309

270310
} // End namespace orc
271311
} // End namespace llvm

llvm/lib/ExecutionEngine/Orc/Core.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,16 +1463,19 @@ Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
14631463

14641464
DenseMap<JITDylib *, SymbolMap> CompoundResult;
14651465
Error CompoundErr = Error::success();
1466+
orc::promise<void> ResultReady;
1467+
auto ReadyF = ResultReady.get_future();
14661468
std::mutex LookupMutex;
1467-
std::condition_variable CV;
1468-
uint64_t Count = InitSyms.size();
1469+
volatile uint64_t Count = InitSyms.size();
14691470

14701471
LLVM_DEBUG({
14711472
dbgs() << "Issuing init-symbol lookup:\n";
14721473
for (auto &KV : InitSyms)
14731474
dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";
14741475
});
14751476

1477+
if (Count == 0)
1478+
ResultReady.set_value();
14761479
for (auto &KV : InitSyms) {
14771480
auto *JD = KV.first;
14781481
auto Names = std::move(KV.second);
@@ -1491,14 +1494,14 @@ Expected<DenseMap<JITDylib *, SymbolMap>> Platform::lookupInitSymbols(
14911494
} else
14921495
CompoundErr =
14931496
joinErrors(std::move(CompoundErr), Result.takeError());
1497+
if (Count == 0)
1498+
ResultReady.set_value();
14941499
}
1495-
CV.notify_one();
14961500
},
14971501
NoDependenciesToRegister);
14981502
}
14991503

1500-
std::unique_lock<std::mutex> Lock(LookupMutex);
1501-
CV.wait(Lock, [&] { return Count == 0; });
1504+
ReadyF.get(ES.getExecutorProcessControl().getDispatcher());
15021505

15031506
if (CompoundErr)
15041507
return std::move(CompoundErr);

0 commit comments

Comments
 (0)