From: Julian Brown Date: Wed, 20 Nov 2019 17:56:30 +0000 (+0000) Subject: AMD GCN libgomp plugin queue-full condition locking fix X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d88b27daa164c87af447cc2243bf18d9a3543ff3;p=gcc.git AMD GCN libgomp plugin queue-full condition locking fix 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 From-SVN: r278517 --- diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index eb51462bb3f..c739b4179be 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,13 @@ +2019-11-20 Julian Brown + + * 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 * plugin/plugin-gcn.c (hsa_memory_copy_wrapper): New. diff --git a/libgomp/plugin/plugin-gcn.c b/libgomp/plugin/plugin-gcn.c index 392a0eeca95..9287e27e022 100644 --- a/libgomp/plugin/plugin-gcn.c +++ b/libgomp/plugin/plugin-gcn.c @@ -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,