aboutsummaryrefslogtreecommitdiff
path: root/libgomp/oacc-mem.c
diff options
context:
space:
mode:
authorThomas Schwinge <thomas@codesourcery.com>2020-05-29 15:22:42 +0200
committerThomas Schwinge <thomas@codesourcery.com>2020-06-04 18:56:37 +0200
commit06ec61726d192659cd446e59a91e78745037f0fd (patch)
treebde7c01eee6a9dc75814531320d8d6e3f9c452b6 /libgomp/oacc-mem.c
parent2112d3242f413979931e371423dcead9d19440e7 (diff)
[OpenACC] Repair/restore 'is_tgt_unmapped' checking
libgomp/ * oacc-mem.c (goacc_exit_datum): Repair 'is_tgt_unmapped' checking. (acc_unmap_data, goacc_exit_data_internal): Restore 'is_tgt_unmapped' checking. * testsuite/libgomp.oacc-c-c++-common/struct-refcount-1.c: New file. * testsuite/libgomp.oacc-fortran/deep-copy-6.f90: Adjust. * testsuite/libgomp.oacc-fortran/mdc-refcount-1-1-1.f90: Likewise. * testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-1.f90: Likewise. * testsuite/libgomp.oacc-fortran/mdc-refcount-1-2-2.f90: Likewise. * testsuite/libgomp.oacc-fortran/mdc-refcount-1-3-1.f90: Likewise. * testsuite/libgomp.oacc-fortran/mdc-refcount-1-4-1.f90: Likewise. Co-Authored-By: Julian Brown <julian@codesourcery.com>
Diffstat (limited to 'libgomp/oacc-mem.c')
-rw-r--r--libgomp/oacc-mem.c60
1 files changed, 56 insertions, 4 deletions
diff --git a/libgomp/oacc-mem.c b/libgomp/oacc-mem.c
index 8e8c7c3093d..b7c85cf5976 100644
--- a/libgomp/oacc-mem.c
+++ b/libgomp/oacc-mem.c
@@ -485,7 +485,8 @@ acc_unmap_data (void *h)
tgt->tgt_end = 0;
tgt->to_free = NULL;
- gomp_remove_var (acc_dev, n);
+ bool is_tgt_unmapped = gomp_remove_var (acc_dev, n);
+ assert (is_tgt_unmapped);
gomp_mutex_unlock (&acc_dev->lock);
@@ -727,8 +728,16 @@ goacc_exit_datum (void *h, size_t s, unsigned short kind, int async)
gomp_remove_var_async (acc_dev, n, aq);
else
{
+ size_t num_mappings = 0;
+ /* If the target_mem_desc represents a single data mapping, we can
+ check that it is freed when this splay tree key's refcount reaches
+ zero. Otherwise (e.g. for a 'GOMP_MAP_STRUCT' mapping with
+ multiple members), fall back to skipping the test. */
+ for (size_t l_i = 0; l_i < n->tgt->list_count; ++l_i)
+ if (n->tgt->list[l_i].key)
+ ++num_mappings;
bool is_tgt_unmapped = gomp_remove_var (acc_dev, n);
- assert (is_tgt_unmapped);
+ assert (is_tgt_unmapped || num_mappings > 1);
}
}
@@ -1145,7 +1154,28 @@ goacc_exit_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum,
cur_node.host_end - cur_node.host_start);
if (n->refcount == 0)
- gomp_remove_var_async (acc_dev, n, aq);
+ {
+ if (aq)
+ /* TODO We can't do the 'is_tgt_unmapped' checking -- see the
+ 'gomp_unref_tgt' comment in
+ <http://mid.mail-archive.com/878snl36eu.fsf@euler.schwinge.homeip.net>;
+ PR92881. */
+ gomp_remove_var_async (acc_dev, n, aq);
+ else
+ {
+ size_t num_mappings = 0;
+ /* If the target_mem_desc represents a single data mapping,
+ we can check that it is freed when this splay tree key's
+ refcount reaches zero. Otherwise (e.g. for a
+ 'GOMP_MAP_STRUCT' mapping with multiple members), fall
+ back to skipping the test. */
+ for (size_t l_i = 0; l_i < n->tgt->list_count; ++l_i)
+ if (n->tgt->list[l_i].key)
+ ++num_mappings;
+ bool is_tgt_unmapped = gomp_remove_var (acc_dev, n);
+ assert (is_tgt_unmapped || num_mappings > 1);
+ }
+ }
}
break;
@@ -1177,7 +1207,29 @@ goacc_exit_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum,
&& str->refcount != REFCOUNT_INFINITY)
str->refcount--;
if (str->refcount == 0)
- gomp_remove_var_async (acc_dev, str, aq);
+ {
+ if (aq)
+ /* TODO We can't do the 'is_tgt_unmapped' checking --
+ see the 'gomp_unref_tgt' comment in
+ <http://mid.mail-archive.com/878snl36eu.fsf@euler.schwinge.homeip.net>;
+ PR92881. */
+ gomp_remove_var_async (acc_dev, str, aq);
+ else
+ {
+ size_t num_mappings = 0;
+ /* If the target_mem_desc represents a single data
+ mapping, we can check that it is freed when this
+ splay tree key's refcount reaches zero.
+ Otherwise (e.g. for a 'GOMP_MAP_STRUCT' mapping
+ with multiple members), fall back to skipping
+ the test. */
+ for (size_t l_i = 0; l_i < str->tgt->list_count; ++l_i)
+ if (str->tgt->list[l_i].key)
+ ++num_mappings;
+ bool is_tgt_unmapped = gomp_remove_var (acc_dev, str);
+ assert (is_tgt_unmapped || num_mappings > 1);
+ }
+ }
}
}
i += elems;