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

Reply via email to