Skip to content

Commit f63f28e

Browse files
committed
[mlir:async] Fix deadlock in async runtime await-and-execute functions
`emplace???` functions running concurrently can set the ready flag and then pending awaiter will never be executed Differential Revision: https://reviews.llvm.org/D95517
1 parent e2a1a71 commit f63f28e

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

mlir/lib/ExecutionEngine/AsyncRuntime.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,11 @@ extern "C" void mlirAsyncRuntimeAwaitTokenAndExecute(AsyncToken *token,
320320
CoroHandle handle,
321321
CoroResume resume) {
322322
auto execute = [handle, resume]() { (*resume)(handle); };
323+
std::unique_lock<std::mutex> lock(token->mu);
323324
if (token->ready) {
325+
lock.unlock();
324326
execute();
325327
} else {
326-
std::unique_lock<std::mutex> lock(token->mu);
327328
token->awaiters.push_back([execute]() { execute(); });
328329
}
329330
}
@@ -332,10 +333,11 @@ extern "C" void mlirAsyncRuntimeAwaitValueAndExecute(AsyncValue *value,
332333
CoroHandle handle,
333334
CoroResume resume) {
334335
auto execute = [handle, resume]() { (*resume)(handle); };
336+
std::unique_lock<std::mutex> lock(value->mu);
335337
if (value->ready) {
338+
lock.unlock();
336339
execute();
337340
} else {
338-
std::unique_lock<std::mutex> lock(value->mu);
339341
value->awaiters.push_back([execute]() { execute(); });
340342
}
341343
}
@@ -344,10 +346,11 @@ extern "C" void mlirAsyncRuntimeAwaitAllInGroupAndExecute(AsyncGroup *group,
344346
CoroHandle handle,
345347
CoroResume resume) {
346348
auto execute = [handle, resume]() { (*resume)(handle); };
349+
std::unique_lock<std::mutex> lock(group->mu);
347350
if (group->pendingTokens == 0) {
351+
lock.unlock();
348352
execute();
349353
} else {
350-
std::unique_lock<std::mutex> lock(group->mu);
351354
group->awaiters.push_back([execute]() { execute(); });
352355
}
353356
}

0 commit comments

Comments
 (0)