diff options
author | Eugene Zhulenev <ezhulenev@google.com> | 2021-01-27 04:27:21 -0800 |
---|---|---|
committer | Eugene Zhulenev <ezhulenev@google.com> | 2021-01-27 05:08:53 -0800 |
commit | f63f28ed54e724128e61fb22185ce6b167b29de0 (patch) | |
tree | 45cb6ee523561965ee57952b3647ed4e1be9906f | |
parent | e2a1a718bbe406289adb695348d2cf8085dfaf25 (diff) | |
download | llvm-f63f28ed54e724128e61fb22185ce6b167b29de0.zip llvm-f63f28ed54e724128e61fb22185ce6b167b29de0.tar.gz llvm-f63f28ed54e724128e61fb22185ce6b167b29de0.tar.bz2 |
[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
-rw-r--r-- | mlir/lib/ExecutionEngine/AsyncRuntime.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/mlir/lib/ExecutionEngine/AsyncRuntime.cpp b/mlir/lib/ExecutionEngine/AsyncRuntime.cpp index e38ebf9..c5978eb 100644 --- a/mlir/lib/ExecutionEngine/AsyncRuntime.cpp +++ b/mlir/lib/ExecutionEngine/AsyncRuntime.cpp @@ -320,10 +320,11 @@ extern "C" void mlirAsyncRuntimeAwaitTokenAndExecute(AsyncToken *token, CoroHandle handle, CoroResume resume) { auto execute = [handle, resume]() { (*resume)(handle); }; + std::unique_lock<std::mutex> lock(token->mu); if (token->ready) { + lock.unlock(); execute(); } else { - std::unique_lock<std::mutex> lock(token->mu); token->awaiters.push_back([execute]() { execute(); }); } } @@ -332,10 +333,11 @@ extern "C" void mlirAsyncRuntimeAwaitValueAndExecute(AsyncValue *value, CoroHandle handle, CoroResume resume) { auto execute = [handle, resume]() { (*resume)(handle); }; + std::unique_lock<std::mutex> lock(value->mu); if (value->ready) { + lock.unlock(); execute(); } else { - std::unique_lock<std::mutex> lock(value->mu); value->awaiters.push_back([execute]() { execute(); }); } } @@ -344,10 +346,11 @@ extern "C" void mlirAsyncRuntimeAwaitAllInGroupAndExecute(AsyncGroup *group, CoroHandle handle, CoroResume resume) { auto execute = [handle, resume]() { (*resume)(handle); }; + std::unique_lock<std::mutex> lock(group->mu); if (group->pendingTokens == 0) { + lock.unlock(); execute(); } else { - std::unique_lock<std::mutex> lock(group->mu); group->awaiters.push_back([execute]() { execute(); }); } } |