diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2020-05-29 15:22:42 +0200 |
---|---|---|
committer | Thomas Schwinge <thomas@codesourcery.com> | 2020-06-04 18:56:37 +0200 |
commit | 06ec61726d192659cd446e59a91e78745037f0fd (patch) | |
tree | bde7c01eee6a9dc75814531320d8d6e3f9c452b6 /libgomp/oacc-mem.c | |
parent | 2112d3242f413979931e371423dcead9d19440e7 (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.c | 60 |
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; |