This patch provides support for distinguishing target_mem_descs introduced via structured data lifetimes from those arising from dynamic data lifetimes. This is a prerequisite for the following reference-count self-checking patch.
This patch (and those following it) are not vital for this patch series, but are "nice-to-have" additions. OK? Julian libgomp/ * libgomp.h (struct target_mem_desc): Update comment on prev field. * oacc-int.h (goacc_mark_dynamic, goacc_marked_dynamic_p): Add prototypes. * oacc-mem.c (dyn_tgt_sentinel): New. (goacc_mark_dynamic, goacc_marked_dynamic_p): New functions. (goacc_enter_datum): Call goacc_mark_dynamic. (goacc_enter_data_internal): Likewise. * target.c (gomp_unmap_vars_internal): Convert a target_mem_desc from a structural mapping to dynamic when appropriate. --- libgomp/libgomp.h | 3 ++- libgomp/oacc-int.h | 3 +++ libgomp/oacc-mem.c | 28 ++++++++++++++++++++++++++++ libgomp/target.c | 8 +++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h index 7b52ce7d5c2..0d1978ffb13 100644 --- a/libgomp/libgomp.h +++ b/libgomp/libgomp.h @@ -971,7 +971,8 @@ struct target_mem_desc { uintptr_t tgt_end; /* Handle to free. */ void *to_free; - /* Previous target_mem_desc. */ + /* Previous target_mem_desc. Also used in OpenACC to indicate that this + target_mem_desc is used only for an "enter data" mapping. */ struct target_mem_desc *prev; /* Number of items in following list. */ size_t list_count; diff --git a/libgomp/oacc-int.h b/libgomp/oacc-int.h index 3c2c9b84b2f..2d8d3eb5a4b 100644 --- a/libgomp/oacc-int.h +++ b/libgomp/oacc-int.h @@ -165,6 +165,9 @@ bool _goacc_profiling_setup_p (struct goacc_thread *, void goacc_profiling_dispatch (acc_prof_info *, acc_event_info *, acc_api_info *); +extern void goacc_mark_dynamic (struct target_mem_desc *); +extern bool goacc_marked_dynamic_p (struct target_mem_desc *tgt); + #ifdef HAVE_ATTRIBUTE_VISIBILITY # pragma GCC visibility pop #endif diff --git a/libgomp/oacc-mem.c b/libgomp/oacc-mem.c index c2b4a131a5f..038ab68e8a2 100644 --- a/libgomp/oacc-mem.c +++ b/libgomp/oacc-mem.c @@ -497,6 +497,30 @@ acc_unmap_data (void *h) } } +/* Indicate (via storing its address in the "prev" field) a target_mem_desc + that is used for an "enter data" mapping. */ +const static struct target_mem_desc dyn_tgt_sentinel; + +attribute_hidden void +goacc_mark_dynamic (struct target_mem_desc *tgt) +{ + tgt->prev = (struct target_mem_desc *) &dyn_tgt_sentinel; +} + +attribute_hidden bool +goacc_marked_dynamic_p (struct target_mem_desc *tgt) +{ + return tgt->prev == (struct target_mem_desc *) &dyn_tgt_sentinel; +} /* Enter dynamic mapping for a single datum. Return the device pointer. */ @@ -563,6 +587,8 @@ goacc_enter_datum (void **hostaddrs, size_t *sizes, unsigned short kind, = gomp_map_vars_async (acc_dev, aq, mapnum, hostaddrs, NULL, sizes, &kind, true, GOMP_MAP_VARS_ENTER_DATA); assert (tgt); + goacc_mark_dynamic (tgt); + assert (tgt->list_count == 1); n = tgt->list[0].key; assert (n); @@ -1122,6 +1148,8 @@ goacc_enter_data_internal (struct gomp_device_descr *acc_dev, size_t mapnum, &sizes[i], &kinds[i], true, GOMP_MAP_VARS_ENTER_DATA); assert (tgt); + goacc_mark_dynamic (tgt); + for (size_t j = 0; j < tgt->list_count; j++) { n = tgt->list[j].key; diff --git a/libgomp/target.c b/libgomp/target.c index 3f2becdae0e..1d60d0cb573 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -1447,7 +1447,13 @@ gomp_unmap_vars_internal (struct target_mem_desc *tgt, bool do_copyfrom, bool do_unmap = false; if (k->refcount > 1 && k->refcount != REFCOUNT_INFINITY) - k->refcount--; + { + k->refcount--; + /* If we only have dynamic references left, mark the tgt_mem_desc + appropriately. */ + if (k->refcount == k->dynamic_refcount) + goacc_mark_dynamic (k->tgt); + } else if (k->refcount == 1) { k->refcount--; -- 2.23.0