]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
openmp: Notify team barrier of pending tasks in omp_fulfill_event
authorKwok Cheung Yeung <kcy@codesourcery.com>
Fri, 14 May 2021 16:59:11 +0000 (09:59 -0700)
committerKwok Cheung Yeung <kcy@codesourcery.com>
Mon, 17 May 2021 21:20:08 +0000 (14:20 -0700)
The team barrier should be notified of any new tasks that become runnable
as the result of a completing task, otherwise the barrier threads might
not resume processing available tasks, resulting in a hang.

2021-05-17  Kwok Cheung Yeung  <kcy@codesourcery.com>

libgomp/
* task.c (omp_fulfill_event): Call gomp_team_barrier_set_task_pending
if new tasks generated.
* testsuite/libgomp.c-c++-common/task-detach-13.c: New.

(cherry picked from commit ba886d0c488ebea2eb2df95c2069a3e207704dac)

libgomp/ChangeLog.omp
libgomp/task.c
libgomp/testsuite/libgomp.c-c++-common/task-detach-13.c [new file with mode: 0644]

index 028ddc248413d7e7cf3f050f455d1046be8cfe83..94bc2a48017f9de7517cf315e87895a633fa4145 100644 (file)
@@ -1,3 +1,12 @@
+2021-05-17  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+       Backport from mainline
+       2021-05-17  Kwok Cheung Yeung  <kcy@codesourcery.com>
+
+       * task.c (omp_fulfill_event): Call gomp_team_barrier_set_task_pending
+       if new tasks generated.
+       * testsuite/libgomp.c-c++-common/task-detach-13.c: New.
+
 2021-05-17  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index 1c73c759a8d1a37c4fa5ba5c45b216a2830e44d5..feb4796a3ac87362063221f7c9a2639c64ccb03c 100644 (file)
@@ -2460,6 +2460,7 @@ omp_fulfill_event (omp_event_handle_t event)
   if (new_tasks > 0)
     {
       /* Wake up threads to run new tasks.  */
+      gomp_team_barrier_set_task_pending (&team->barrier);
       do_wake = team->nthreads - team->task_running_count;
       if (do_wake > new_tasks)
        do_wake = new_tasks;
diff --git a/libgomp/testsuite/libgomp.c-c++-common/task-detach-13.c b/libgomp/testsuite/libgomp.c-c++-common/task-detach-13.c
new file mode 100644 (file)
index 0000000..9622fd8
--- /dev/null
@@ -0,0 +1,59 @@
+/* { dg-do run { target *-*-linux* *-*-gnu* *-*-freebsd* } } */
+/* { dg-timeout 10 } */
+
+/* Test that omp_fulfill_event works when called from an external
+   non-OpenMP thread.  */
+
+#include <omp.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdio.h>
+
+int finished = 0;
+int event_pending = 0;
+omp_event_handle_t detach_event;
+
+void *
+fulfill_thread (void *)
+{
+  while (!__atomic_load_n (&finished, __ATOMIC_RELAXED))
+    {
+      if (__atomic_load_n (&event_pending, __ATOMIC_ACQUIRE))
+       {
+         omp_fulfill_event (detach_event);
+         __atomic_store_n (&event_pending, 0, __ATOMIC_RELEASE);
+       }
+
+      sleep(1);
+    }
+
+  return 0;
+}
+
+int
+main (void)
+{
+  pthread_t thr;
+  int dep;
+  pthread_create (&thr, NULL, fulfill_thread, 0);
+
+  #pragma omp parallel
+    #pragma omp single
+    {
+      omp_event_handle_t ev;
+
+      #pragma omp task depend (out: dep) detach (ev)
+      {
+       detach_event = ev;
+       __atomic_store_n (&event_pending, 1, __ATOMIC_RELEASE);
+      }
+
+      #pragma omp task depend (in: dep)
+      {
+       __atomic_store_n (&finished, 1, __ATOMIC_RELAXED);
+      }
+    }
+
+  pthread_join (thr, 0);
+  return 0;
+}