[gcc/devel/omp/gcc-16] In 'libgomp/target.c:gomp_unmap_vars_internal', defer 'gomp_remove_var'

Sandra Loosemore via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:8562181c5c16190edc1cc7193c7df5ff45dc74ae

commit 8562181c5c16190edc1cc7193c7df5ff45dc74ae
Author: Thomas Schwinge <[email protected]>
Date:   Sat Apr 19 20:52:08 2025 +0000

    In 'libgomp/target.c:gomp_unmap_vars_internal', defer 'gomp_remove_var'
    
    An upcoming change requires that 'gomp_remove_var' be deferred until after all
    'gomp_copy_dev2host' calls have been handled.
    
    Do this likewise to how commit 275c736e732d29934e4d22e8f030d5aae8c12a52
    "libgomp: Structure element mapping for OpenMP 5.0" changed 'gomp_exit_data'.
    
            libgomp/
            * target.c (gomp_unmap_vars_internal): Queue splay-tree keys for
            removal after main loop.

Diff:
---
 libgomp/target.c | 36 ++++++++++++++++++++----------------
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/libgomp/target.c b/libgomp/target.c
index 8d1a786a44bb..a3195db11b65 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -2608,6 +2608,9 @@ gomp_unmap_vars_internal (struct target_mem_desc *tgt, bool do_copyfrom,
 			     false, NULL);
     }
 
+  size_t nrmvars = 0;
+  splay_tree_key remove_vars[tgt->list_count];
+
   for (i = 0; i < tgt->list_count; i++)
     {
       splay_tree_key k = tgt->list[i].key;
@@ -2629,17 +2632,22 @@ gomp_unmap_vars_internal (struct target_mem_desc *tgt, bool do_copyfrom,
 			    (void *) (k->tgt->tgt_start + k->tgt_offset
 				      + tgt->list[i].offset),
 			    tgt->list[i].length);
+      /* Queue all removals together for processing below.
+	 See also 'gomp_exit_data'.  */
       if (do_remove)
-	{
-	  struct target_mem_desc *k_tgt __attribute__((unused)) = k->tgt;
-	  bool is_tgt_unmapped __attribute__((unused))
-	    = gomp_remove_var (devicep, k);
-	  /* It would be bad if TGT got unmapped while we're still iterating
-	     over its LIST_COUNT, and also expect to use it in the following
-	     code.  */
-	  assert (!is_tgt_unmapped
-		  || k_tgt != tgt);
-	}
+	remove_vars[nrmvars++] = k;
+    }
+
+  for (i = 0; i < nrmvars; i++)
+    {
+      splay_tree_key k = remove_vars[i];
+      struct target_mem_desc *k_tgt __attribute__((unused)) = k->tgt;
+      bool is_tgt_unmapped __attribute__((unused))
+	= gomp_remove_var (devicep, k);
+      /* It would be bad if TGT got unmapped while we're still iterating over
+	 its LIST_COUNT, and also expect to use it in the following code.  */
+      assert (!is_tgt_unmapped
+	      || k_tgt != tgt);
     }
 
   if (aq)
@@ -4642,7 +4650,7 @@ gomp_exit_data (struct gomp_device_descr *devicep, size_t mapnum,
 			       false, NULL);
       }
 
-  int nrmvars = 0;
+  size_t nrmvars = 0;
   splay_tree_key remove_vars[mapnum];
 
   for (i = 0; i < mapnum; i++)
@@ -4705,10 +4713,6 @@ gomp_exit_data (struct gomp_device_descr *devicep, size_t mapnum,
 	     errors if we still have following element siblings to copy back.
 	     While we're at it, it also seems more disciplined to simply
 	     queue all removals together for processing below.
-
-	     Structured block unmapping (i.e. gomp_unmap_vars_internal) should
-	     not have this problem, since they maintain an additional
-	     tgt->refcount = 1 reference to the target_mem_desc to start with.
 	  */
 	  if (do_remove)
 	    remove_vars[nrmvars++] = k;
@@ -4723,7 +4727,7 @@ gomp_exit_data (struct gomp_device_descr *devicep, size_t mapnum,
 	}
     }
 
-  for (int i = 0; i < nrmvars; i++)
+  for (i = 0; i < nrmvars; i++)
     gomp_remove_var (devicep, remove_vars[i]);
 
   gomp_mutex_unlock (&devicep->lock);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.