AMD GCN libgomp plugin queue-full condition locking fix
authorJulian Brown <julian@codesourcery.com>
Wed, 20 Nov 2019 17:56:30 +0000 (17:56 +0000)
committerJulian Brown <jules@gcc.gnu.org>
Wed, 20 Nov 2019 17:56:30 +0000 (17:56 +0000)
libgomp/
* plugin/plugin-gcn.c (wait_for_queue_nonfull): Don't lock/unlock
aq->mutex here.
(queue_push_launch): Lock aq->mutex before calling
wait_for_queue_nonfull.
(queue_push_callback): Likewise.
(queue_push_asyncwait): Likewise.
(queue_push_placeholder): Likewise.

Reviewed-by: Andrew Stubbs <ams@codesourcery.com>
From-SVN: r278517

libgomp/ChangeLog
libgomp/plugin/plugin-gcn.c

index eb51462bb3fc8d196aac0032c9af71f021a967dd..c739b4179be1962bef4e85aac7969d70142759ac 100644 (file)
@@ -1,3 +1,13 @@
+2019-11-20  Julian Brown  <julian@codesourcery.com>
+
+       * plugin/plugin-gcn.c (wait_for_queue_nonfull): Don't lock/unlock
+       aq->mutex here.
+       (queue_push_launch): Lock aq->mutex before calling
+       wait_for_queue_nonfull.
+       (queue_push_callback): Likewise.
+       (queue_push_asyncwait): Likewise.
+       (queue_push_placeholder): Likewise.
+
 2019-11-20  Julian Brown  <julian@codesourcery.com>
 
        * plugin/plugin-gcn.c (hsa_memory_copy_wrapper): New.
index 392a0eeca95f95adce03fbc5f3af996cf24dc3bb..9287e27e022163496aaecc8163404e338151a013 100644 (file)
@@ -2725,20 +2725,17 @@ drain_queue_synchronous (struct goacc_asyncqueue *aq)
   pthread_mutex_unlock (&aq->mutex);
 }
 
-/* Block the current thread until an async queue is writable.  */
+/* Block the current thread until an async queue is writable.  The aq->mutex
+   lock should be held on entry, and remains locked on exit.  */
 
 static void
 wait_for_queue_nonfull (struct goacc_asyncqueue *aq)
 {
   if (aq->queue_n == ASYNC_QUEUE_SIZE)
     {
-      pthread_mutex_lock (&aq->mutex);
-
       /* Queue is full.  Wait for it to not be full.  */
       while (aq->queue_n == ASYNC_QUEUE_SIZE)
        pthread_cond_wait (&aq->queue_cond_out, &aq->mutex);
-
-      pthread_mutex_unlock (&aq->mutex);
     }
 }
 
@@ -2752,10 +2749,10 @@ queue_push_launch (struct goacc_asyncqueue *aq, struct kernel_info *kernel,
 {
   assert (aq->agent == kernel->agent);
 
-  wait_for_queue_nonfull (aq);
-
   pthread_mutex_lock (&aq->mutex);
 
+  wait_for_queue_nonfull (aq);
+
   int queue_last = ((aq->queue_first + aq->queue_n)
                    % ASYNC_QUEUE_SIZE);
   if (DEBUG_QUEUES)
@@ -2785,10 +2782,10 @@ static void
 queue_push_callback (struct goacc_asyncqueue *aq, void (*fn)(void *),
                     void *data)
 {
-  wait_for_queue_nonfull (aq);
-
   pthread_mutex_lock (&aq->mutex);
 
+  wait_for_queue_nonfull (aq);
+
   int queue_last = ((aq->queue_first + aq->queue_n)
                    % ASYNC_QUEUE_SIZE);
   if (DEBUG_QUEUES)
@@ -2818,10 +2815,10 @@ static void
 queue_push_asyncwait (struct goacc_asyncqueue *aq,
                      struct placeholder *placeholderp)
 {
-  wait_for_queue_nonfull (aq);
-
   pthread_mutex_lock (&aq->mutex);
 
+  wait_for_queue_nonfull (aq);
+
   int queue_last = ((aq->queue_first + aq->queue_n) % ASYNC_QUEUE_SIZE);
   if (DEBUG_QUEUES)
     GCN_DEBUG ("queue_push_asyncwait %d:%d: at %i\n", aq->agent->device_id,
@@ -2849,10 +2846,10 @@ queue_push_placeholder (struct goacc_asyncqueue *aq)
 {
   struct placeholder *placeholderp;
 
-  wait_for_queue_nonfull (aq);
-
   pthread_mutex_lock (&aq->mutex);
 
+  wait_for_queue_nonfull (aq);
+
   int queue_last = ((aq->queue_first + aq->queue_n) % ASYNC_QUEUE_SIZE);
   if (DEBUG_QUEUES)
     GCN_DEBUG ("queue_push_placeholder %d:%d: at %i\n", aq->agent->device_id,