aboutsummaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2019-11-20 17:56:30 +0000
committerJulian Brown <julian@codesourcery.com>2019-11-20 17:56:30 +0000
commita5284c8b5f0a3200b5eae71f3288001afdcfb1bd (patch)
tree233fabd58e81614607b30bf5495b268343080f72 /libgomp
parenta52ee1727738e17b4ad70b681b388c03619cf879 (diff)
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> git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@278517 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgomp')
-rw-r--r--libgomp/ChangeLog10
-rw-r--r--libgomp/plugin/plugin-gcn.c23
2 files changed, 20 insertions, 13 deletions
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index eb51462bb3f..c739b4179be 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,5 +1,15 @@
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.
(copy_data, GOMP_OFFLOAD_host2dev): Use above function.
(GOMP_OFFLOAD_dev2host, GOMP_OFFLOAD_dev2dev): Check hsa_memory_copy
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,