Commit d88b27da by Julian Brown Committed by Julian Brown

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 <ams@codesourcery.com>

From-SVN: r278517
parent 8d2f4ddf
2019-11-20 Julian Brown <julian@codesourcery.com> 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. * plugin/plugin-gcn.c (hsa_memory_copy_wrapper): New.
(copy_data, GOMP_OFFLOAD_host2dev): Use above function. (copy_data, GOMP_OFFLOAD_host2dev): Use above function.
(GOMP_OFFLOAD_dev2host, GOMP_OFFLOAD_dev2dev): Check hsa_memory_copy (GOMP_OFFLOAD_dev2host, GOMP_OFFLOAD_dev2dev): Check hsa_memory_copy
......
...@@ -2725,20 +2725,17 @@ drain_queue_synchronous (struct goacc_asyncqueue *aq) ...@@ -2725,20 +2725,17 @@ drain_queue_synchronous (struct goacc_asyncqueue *aq)
pthread_mutex_unlock (&aq->mutex); 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 static void
wait_for_queue_nonfull (struct goacc_asyncqueue *aq) wait_for_queue_nonfull (struct goacc_asyncqueue *aq)
{ {
if (aq->queue_n == ASYNC_QUEUE_SIZE) if (aq->queue_n == ASYNC_QUEUE_SIZE)
{ {
pthread_mutex_lock (&aq->mutex);
/* Queue is full. Wait for it to not be full. */ /* Queue is full. Wait for it to not be full. */
while (aq->queue_n == ASYNC_QUEUE_SIZE) while (aq->queue_n == ASYNC_QUEUE_SIZE)
pthread_cond_wait (&aq->queue_cond_out, &aq->mutex); 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, ...@@ -2752,10 +2749,10 @@ queue_push_launch (struct goacc_asyncqueue *aq, struct kernel_info *kernel,
{ {
assert (aq->agent == kernel->agent); assert (aq->agent == kernel->agent);
wait_for_queue_nonfull (aq);
pthread_mutex_lock (&aq->mutex); pthread_mutex_lock (&aq->mutex);
wait_for_queue_nonfull (aq);
int queue_last = ((aq->queue_first + aq->queue_n) int queue_last = ((aq->queue_first + aq->queue_n)
% ASYNC_QUEUE_SIZE); % ASYNC_QUEUE_SIZE);
if (DEBUG_QUEUES) if (DEBUG_QUEUES)
...@@ -2785,10 +2782,10 @@ static void ...@@ -2785,10 +2782,10 @@ static void
queue_push_callback (struct goacc_asyncqueue *aq, void (*fn)(void *), queue_push_callback (struct goacc_asyncqueue *aq, void (*fn)(void *),
void *data) void *data)
{ {
wait_for_queue_nonfull (aq);
pthread_mutex_lock (&aq->mutex); pthread_mutex_lock (&aq->mutex);
wait_for_queue_nonfull (aq);
int queue_last = ((aq->queue_first + aq->queue_n) int queue_last = ((aq->queue_first + aq->queue_n)
% ASYNC_QUEUE_SIZE); % ASYNC_QUEUE_SIZE);
if (DEBUG_QUEUES) if (DEBUG_QUEUES)
...@@ -2818,10 +2815,10 @@ static void ...@@ -2818,10 +2815,10 @@ static void
queue_push_asyncwait (struct goacc_asyncqueue *aq, queue_push_asyncwait (struct goacc_asyncqueue *aq,
struct placeholder *placeholderp) struct placeholder *placeholderp)
{ {
wait_for_queue_nonfull (aq);
pthread_mutex_lock (&aq->mutex); pthread_mutex_lock (&aq->mutex);
wait_for_queue_nonfull (aq);
int queue_last = ((aq->queue_first + aq->queue_n) % ASYNC_QUEUE_SIZE); int queue_last = ((aq->queue_first + aq->queue_n) % ASYNC_QUEUE_SIZE);
if (DEBUG_QUEUES) if (DEBUG_QUEUES)
GCN_DEBUG ("queue_push_asyncwait %d:%d: at %i\n", aq->agent->device_id, 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) ...@@ -2849,10 +2846,10 @@ queue_push_placeholder (struct goacc_asyncqueue *aq)
{ {
struct placeholder *placeholderp; struct placeholder *placeholderp;
wait_for_queue_nonfull (aq);
pthread_mutex_lock (&aq->mutex); pthread_mutex_lock (&aq->mutex);
wait_for_queue_nonfull (aq);
int queue_last = ((aq->queue_first + aq->queue_n) % ASYNC_QUEUE_SIZE); int queue_last = ((aq->queue_first + aq->queue_n) % ASYNC_QUEUE_SIZE);
if (DEBUG_QUEUES) if (DEBUG_QUEUES)
GCN_DEBUG ("queue_push_placeholder %d:%d: at %i\n", aq->agent->device_id, GCN_DEBUG ("queue_push_placeholder %d:%d: at %i\n", aq->agent->device_id,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment