task.c (GOMP_task, [...]): Comment.
authorAlan Modra <amodra@gmail.com>
Fri, 1 Feb 2013 12:52:41 +0000 (23:22 +1030)
committerAlan Modra <amodra@gcc.gnu.org>
Fri, 1 Feb 2013 12:52:41 +0000 (23:22 +1030)
* task.c (GOMP_task, GOMP_taskwait): Comment.

From-SVN: r195647

libgomp/ChangeLog
libgomp/task.c

index d765f8a25ae13e1df275bee633607a13d070ff12..2bbb789c1a49882e2454c4d7a58050f32e12cfe9 100644 (file)
@@ -1,3 +1,7 @@
+2013-02-01  Alan Modra  <amodra@gmail.com>
+
+       * task.c (GOMP_task, GOMP_taskwait): Comment.
+
 2013-01-31  Dmitry Vyukov  <dvyukov@gcc.gnu.org>
            Joost VandeVondele  <Joost.VandeVondele@mat.ethz.ch>
 
index 937f266cef375be99d4cca193d518eba9926f280..7de650a43f1457edcf093b1b6c24835a4167b10d 100644 (file)
@@ -116,6 +116,15 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *),
        }
       else
        fn (data);
+      /* Access to "children" is normally done inside a task_lock
+        mutex region, but the only way this particular task.children
+        can be set is if this thread's task work function (fn)
+        creates children.  So since the setter is *this* thread, we
+        need no barriers here when testing for non-NULL.  We can have
+        task.children set by the current thread then changed by a
+        child thread, but seeing a stale non-NULL value is not a
+        problem.  Once past the task_lock acquisition, this thread
+        will see the real value of task.children.  */
       if (task.children != NULL)
        {
          gomp_mutex_lock (&team->task_lock);
@@ -296,6 +305,12 @@ GOMP_taskwait (void)
   struct gomp_task *child_task = NULL;
   struct gomp_task *to_free = NULL;
 
+  /* The acquire barrier on load of task->children here synchronizes
+     with the write of a NULL in gomp_barrier_handle_tasks.  It is
+     not necessary that we synchronize with other non-NULL writes at
+     this point, but we must ensure that all writes to memory by a
+     child thread task work function are seen before we exit from
+     GOMP_taskwait.  */
   if (task == NULL
       || __atomic_load_n (&task->children, MEMMODEL_ACQUIRE) == NULL)
     return;