===================================================================
@@ -35,7 +35,10 @@
Note: For performance reasons -fcoarry=single should be used
rather than this library. */
+/* Global variables. */
+caf_static_t *caf_static_list = NULL;
+
void
_gfortran_caf_init (int *argc __attribute__ ((unused)),
char ***argv __attribute__ ((unused)),
@@ -49,16 +52,31 @@
void
_gfortran_caf_finalize (void)
{
+ while (caf_static_list != NULL)
+ {
+ free(caf_static_list->token[0]);
+ caf_static_list = caf_static_list->prev;
+ }
}
void *
-_gfortran_caf_register (ptrdiff_t size,
- caf_register_t type __attribute__ ((unused)),
+_gfortran_caf_register (ptrdiff_t size, caf_register_t type,
void **token)
{
- *token = NULL;
- return malloc (size);
+ void *local;
+
+ local = malloc (size);
+ token = malloc (sizeof (void*) * 1);
+
+ if (type == CAF_REGTYPE_COARRAY_STATIC)
+ {
+ caf_static_t *tmp = malloc (sizeof (caf_static_t));
+ tmp->prev = caf_static_list;
+ tmp->token = token;
+ caf_static_list = tmp;
+ }
+ return local;
}
===================================================================
@@ -38,15 +38,23 @@
#define STAT_LOCKED_OTHER_IMAGE 2
#define STAT_STOPPED_IMAGE 3
-
+/* Describes what type of array we are registerring. */
typedef enum caf_register_t {
- CAF_REGTYPE_COARRAY,
+ CAF_REGTYPE_COARRAY_STATIC,
+ CAF_REGTYPE_COARRAY_ALLOC,
CAF_REGTYPE_LOCK,
CAF_REGTYPE_LOCK_COMP
}
caf_register_t;
+/* Linked list of static coarrays registered. */
+typedef struct caf_static_t {
+ void **token;
+ struct caf_static_t *prev;
+}
+caf_static_t;
+
void _gfortran_caf_init (int *, char ***, int *, int *);
void _gfortran_caf_finalize (void);
===================================================================
@@ -42,7 +42,10 @@
static int caf_this_image;
static int caf_num_images;
+caf_static_t *caf_static_list = NULL;
+
+
/* Initialize coarray program. This routine assumes that no other
MPI initialization happened before; otherwise MPI_Initialized
had to be used. As the MPI library might modify the command-line
@@ -52,36 +55,68 @@
void
_gfortran_caf_init (int *argc, char ***argv, int *this_image, int *num_images)
{
- /* caf_mpi_initialized is only true if the main program is not written in
- Fortran. */
- MPI_Initialized (&caf_mpi_initialized);
- if (!caf_mpi_initialized)
- MPI_Init (argc, argv);
+ if (caf_num_images == 0)
+ {
+ /* caf_mpi_initialized is only true if the main program is
+ not written in Fortran. */
+ MPI_Initialized (&caf_mpi_initialized);
+ if (!caf_mpi_initialized)
+ MPI_Init (argc, argv);
- MPI_Comm_rank (MPI_COMM_WORLD, &caf_this_image);
- *this_image = ++caf_this_image;
- MPI_Comm_size (MPI_COMM_WORLD, &caf_num_images);
- *num_images = caf_num_images;
+ MPI_Comm_size (MPI_COMM_WORLD, &caf_num_images);
+ MPI_Comm_rank (MPI_COMM_WORLD, &caf_this_image);
+ caf_this_image++;
+ }
+
+ if (this_image)
+ this_image = caf_this_image;
+ if (num_images)
+ num_images = caf_num_images;
}
+
/* Finalize coarray program. */
void
_gfortran_caf_finalize (void)
{
+ while (caf_static_list != NULL)
+ {
+ free(caf_static_list->token[caf_this_image-1]);
+ caf_static_list = caf_static_list->prev;
+ }
+
if (!caf_mpi_initialized)
MPI_Finalize ();
}
void *
-_gfortran_caf_register (ptrdiff_t size,
- caf_register_t type __attribute__ ((unused)),
+_gfortran_caf_register (ptrdiff_t size, caf_register_t type,
void **token)
{
- *token = NULL;
- return malloc (size);
+ void *local;
+
+ local = malloc (size);
+ token = malloc (sizeof (void*) * caf_num_images);
+
+ /* Start MPI if not already started. */
+ if (caf_num_images == 0)
+ _gfortran_caf_init (NULL, NULL, NULL, NULL);
+
+ /* token[img-1] is the address of the token in image "img". */
+ MPI_Allgather (local, sizeof (void*), MPI_BYTE,
+ token[0], sizeof (void*), MPI_BYTE, MPI_COMM_WORLD);
+
+ if (type == CAF_REGTYPE_COARRAY_STATIC)
+ {
+ caf_static_t *tmp = malloc (sizeof (caf_static_t));
+ tmp->prev = caf_static_list;
+ tmp->token = token;
+ caf_static_list = tmp;
+ }
+ return local;
}