[Openmp-commits] [PATCH] D101082: [OpenMP] Fix deadlock for detachable task with child tasks
Joachim Protze via Phabricator via Openmp-commits
openmp-commits at lists.llvm.org
Thu Apr 22 10:05:11 PDT 2021
protze.joachim created this revision.
protze.joachim added reviewers: AndreyChurbanov, hbae.
protze.joachim added a project: OpenMP.
Herald added subscribers: jfb, guansong, yaxunl.
protze.joachim requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added a subscriber: sstefan1.
This patch fixes https://bugs.llvm.org/show_bug.cgi?id=49066.
For detachable tasks, the assumption breaks that the proxy task cannot have remaining child tasks when the proxy completes.
`__kmp_free_task_and_ancestors` takes care of the reference counting and only marks the proxy task for freeing, if there are still child tasks.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D101082
Files:
openmp/runtime/src/kmp_tasking.cpp
openmp/runtime/test/tasking/detach_nested_task.c
Index: openmp/runtime/test/tasking/detach_nested_task.c
===================================================================
--- /dev/null
+++ openmp/runtime/test/tasking/detach_nested_task.c
@@ -0,0 +1,54 @@
+// RUN: %libomp-compile-and-run
+
+// The outer detachable task creates multiple child tasks with dependencies
+// when the last inner task incremented ret, the task calls omp_fulfill_event
+// to release the outer task.
+
+#include <omp.h>
+#include <stdio.h>
+
+int *buf;
+
+int foo(int n)
+{
+ int ret = 0;
+ for (int i = 0; i < n; ++i) {
+ omp_event_handle_t event;
+ #pragma omp task detach(event) firstprivate(i,n,event) shared(ret) default(none)
+ {
+ for (int j = 0; j < n; ++j) {
+ #pragma omp task firstprivate(event,i,j,n) shared(ret) default(none) depend(out:ret)
+ {
+ //printf("Task %i, %i: %i\n", i, j, omp_get_thread_num());
+ #pragma omp atomic
+ ret++;
+#if _OPENMP
+ if (j == n-1) {
+ //printf("Task %i, %i: omp_fulfill_event()\n", i, j);
+ omp_fulfill_event(event);
+ }
+#endif
+ }
+ }
+ }
+ }
+ // the taskwait only guarantees the outer tasks to complete.
+ #pragma omp taskwait
+
+ return ret;
+}
+
+
+int main()
+{
+ int ret;
+#pragma omp parallel
+#pragma omp master
+ {
+ ret = foo(8);
+ }
+ printf("%i\n", ret);
+ //CHECK: 64
+ return 0;
+}
+
Index: openmp/runtime/src/kmp_tasking.cpp
===================================================================
--- openmp/runtime/src/kmp_tasking.cpp
+++ openmp/runtime/src/kmp_tasking.cpp
@@ -3896,8 +3896,9 @@
// We need to wait to make sure the top half is finished
// Spinning here should be ok as this should happen quickly
- while (KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks) > 0)
- ;
+ if (!taskdata->td_flags.detachable)
+ while (KMP_ATOMIC_LD_ACQ(&taskdata->td_incomplete_child_tasks) > 0)
+ ;
__kmp_release_deps(gtid, taskdata);
__kmp_free_task_and_ancestors(gtid, taskdata, thread);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101082.339695.patch
Type: text/x-patch
Size: 2038 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/openmp-commits/attachments/20210422/00e9f580/attachment-0001.bin>
More information about the Openmp-commits
mailing list