@@ -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;
@@ -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
@@ -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;
@@ -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--;