Patchwork [Fortran] Coarray: libcaf patch for _gfortran_caf_deregister

login
register
mail settings
Submitter Tobias Burnus
Date Aug. 26, 2011, 6:51 a.m.
Message ID <4E574279.9080608@net-b.de>
Download mbox | patch
Permalink /patch/111716/
State New
Headers show

Comments

Tobias Burnus - Aug. 26, 2011, 6:51 a.m.
Allocatable coarrays are freed and deregistered via the libcaf function 
_gfortran_caf_deregister. Currently, the front end does not generate 
calls to the that function, however, this patch already implements the 
function.

See http://gcc.gnu.org/wiki/CoarrayLib and 
http://gcc.gnu.org/ml/fortran/2010-04/msg00168.html for details.

The function is called with the coarray token as argument. The token 
identifies the coarray in a way defined by the library. In case of 
single.c, it just contains the address of the allocated memory of the 
coarray. In case of mpi.c, it is an array of memory addresses on all 
images such that token[this_image()-1] is the memory location of the 
current image.

The patch also adds stat= and errmsg= diagnostic.

TODO: Adding calls to the function in code generated by the compiler - 
and testing the function.


Tested by compiling with mpicc and gcc with "-Wall -Wextra -std=c99".
OK for the trunk?

Tobias

Patch

2011-08-26  Tobias Burnus  <burnus@net-b.de>

	* caf/libcaf.h (_gfortran_caf_deregister): Update prototype.
	* caf/mpi.c (_gfortran_caf_deregister): Modify prototype,
	actually free memory and add error diagnostic.
	* caf/single.c (_gfortran_caf_deregister): Ditto.

diff --git a/libgfortran/caf/libcaf.h b/libgfortran/caf/libcaf.h
index 4fe09e4..e6be7ce 100644
--- a/libgfortran/caf/libcaf.h
+++ b/libgfortran/caf/libcaf.h
@@ -69,7 +69,7 @@  void _gfortran_caf_finalize (void);
 
 void * _gfortran_caf_register (ptrdiff_t, caf_register_t, void **, int *,
 			       char *, int);
-int _gfortran_caf_deregister (void **);
+void _gfortran_caf_deregister (void **, int *, char *, int);
 
 
 void _gfortran_caf_sync_all (int *, char *, int);
diff --git a/libgfortran/caf/mpi.c b/libgfortran/caf/mpi.c
index ea4c0f0..711c6ee 100644
--- a/libgfortran/caf/mpi.c
+++ b/libgfortran/caf/mpi.c
@@ -103,7 +103,7 @@  _gfortran_caf_finalize (void)
 {
   while (caf_static_list != NULL)
     {
-      free(caf_static_list->token[caf_this_image-1]);
+      free (caf_static_list->token[caf_this_image-1]);
       caf_static_list = caf_static_list->prev;
     }
 
@@ -187,10 +187,36 @@  error:
 }
 
 
-int
-_gfortran_caf_deregister (void **token __attribute__ ((unused)))
+void
+_gfortran_caf_deregister (void **token, int *stat, char *errmsg, int errmsg_len)
 {
-  return 0;
+  if (unlikely (caf_is_finalized))
+    {
+      const char msg[] = "Failed to deallocate coarray - "
+			  "there are stopped images";
+      if (stat)
+	{
+	  *stat = STAT_STOPPED_IMAGE;
+	
+	  if (errmsg_len > 0)
+	    {
+	      int len = ((int) sizeof (msg) - 1 > errmsg_len)
+			? errmsg_len : (int) sizeof (msg) - 1;
+	      memcpy (errmsg, msg, len);
+	      if (errmsg_len > len)
+		memset (&errmsg[len], ' ', errmsg_len-len);
+	    }
+	  return;
+	}
+      caf_runtime_error (msg);
+    }
+
+  _gfortran_caf_sync_all (NULL, NULL, 0);
+
+  if (stat)
+    *stat = 0;
+
+  free (token[caf_this_image-1]);
 }
 
 
@@ -267,7 +293,7 @@  _gfortran_caf_sync_images (int count, int images[], int *stat, char *errmsg,
     }
 
   /* Handle SYNC IMAGES(*).  */
-  if (unlikely(caf_is_finalized))
+  if (unlikely (caf_is_finalized))
     ierr = STAT_STOPPED_IMAGE;
   else
     ierr = MPI_Barrier (MPI_COMM_WORLD);
diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c
index 09cc62f..50acc3d 100644
--- a/libgfortran/caf/single.c
+++ b/libgfortran/caf/single.c
@@ -121,10 +121,15 @@  _gfortran_caf_register (ptrdiff_t size, caf_register_t type, void **token,
 }
 
 
-int
-_gfortran_caf_deregister (void **token __attribute__ ((unused)))
+void
+_gfortran_caf_deregister (void **token, int *stat,
+			  char *errmsg __attribute__ ((unused)),
+			  int errmsg_len __attribute__ ((unused)))
 {
-  return 0;
+  free (*token);
+
+  if (stat)
+    *stat = 0;
 }