re PR libgomp/51376 (libgomp taskwait failure)
authorAlan Modra <amodra@gmail.com>
Tue, 22 Jan 2013 11:41:53 +0000 (22:11 +1030)
committerAlan Modra <amodra@gcc.gnu.org>
Tue, 22 Jan 2013 11:41:53 +0000 (22:11 +1030)
PR libgomp/51376
PR libgomp/56073
* task.c (GOMP_task): Revert 2011-12-09 change.
(GOMP_taskwait): Likewise.  Instead use atomic load with acquire
barrier to read task->children..
(gomp_barrier_handle_tasks): ..and matching atomic store with
release barrier here when setting parent->children to NULL.

From-SVN: r195370

libgomp/ChangeLog
libgomp/task.c

index 3bc553ace81591f8d79ae5416c7ba4f215769a60..266a66e7b8f1567a4e44d16e09b5a08956991499 100644 (file)
@@ -1,3 +1,13 @@
+2013-01-22  Alan Modra  <amodra@gmail.com>
+
+       PR libgomp/51376
+       PR libgomp/56073
+       * task.c (GOMP_task): Revert 2011-12-09 change.
+       (GOMP_taskwait): Likewise.  Instead use atomic load with acquire
+       barrier to read task->children..
+       (gomp_barrier_handle_tasks): ..and matching atomic store with
+       release barrier here when setting parent->children to NULL.
+
 2013-01-16  Jakub Jelinek  <jakub@redhat.com>
            Tobias Burnus  <burnus@net-b.de>
 
index be8b431c9acbd36cb3d14e2d674e1d8b46911d0d..937f266cef375be99d4cca193d518eba9926f280 100644 (file)
@@ -116,11 +116,10 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
        }
       else
        fn (data);
-      if (team != NULL)
+      if (task.children != NULL)
        {
          gomp_mutex_lock (&team->task_lock);
-         if (task.children != NULL)
-           gomp_clear_parent (task.children);
+         gomp_clear_parent (task.children);
          gomp_mutex_unlock (&team->task_lock);
        }
       gomp_end_task ();
@@ -258,7 +257,13 @@ gomp_barrier_handle_tasks (gomp_barrier_state_t state)
                    parent->children = child_task->next_child;
                  else
                    {
-                     parent->children = NULL;
+                     /* We access task->children in GOMP_taskwait
+                        outside of the task lock mutex region, so
+                        need a release barrier here to ensure memory
+                        written by child_task->fn above is flushed
+                        before the NULL is written.  */
+                     __atomic_store_n (&parent->children, NULL,
+                                       MEMMODEL_RELEASE);
                      if (parent->in_taskwait)
                        gomp_sem_post (&parent->taskwait_sem);
                    }
@@ -291,7 +296,8 @@ GOMP_taskwait (void)
   struct gomp_task *child_task = NULL;
   struct gomp_task *to_free = NULL;
 
-  if (task == NULL || team == NULL)
+  if (task == NULL
+      || __atomic_load_n (&task->children, MEMMODEL_ACQUIRE) == NULL)
     return;
 
   gomp_mutex_lock (&team->task_lock);