Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
handle proper cleanup of mpi datatypes with MPI_Type_free with a refcounter
authorAugustin Degomme <degomme@idpann.imag.fr>
Thu, 6 Dec 2012 17:43:06 +0000 (18:43 +0100)
committerAugustin Degomme <degomme@idpann.imag.fr>
Thu, 6 Dec 2012 17:45:43 +0000 (18:45 +0100)
src/smpi/private.h
src/smpi/smpi_base.c
src/smpi/smpi_mpi_dt.c

index 2f0d57d..0fff8ab 100644 (file)
@@ -42,6 +42,7 @@ typedef struct s_smpi_mpi_datatype{
   int flags;
   /* this let us know how to serialize and unserialize*/
   void *substruct;
+  int in_use;
 } s_smpi_mpi_datatype_t;
 
 //*****************************************************************************************
@@ -105,6 +106,9 @@ MPI_Aint smpi_datatype_get_extent(MPI_Datatype datatype);
 int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                        void *recvbuf, int recvcount,
                        MPI_Datatype recvtype);
+void smpi_datatype_use(MPI_Datatype type);
+void smpi_datatype_unuse(MPI_Datatype type);
+
 int smpi_datatype_contiguous(int count, MPI_Datatype old_type,
                        MPI_Datatype* new_type);
 int smpi_datatype_vector(int count, int blocklen, int stride,
index a016c1d..e548adb 100644 (file)
@@ -92,6 +92,8 @@ static MPI_Request build_request(void *buf, int count,
   request->send = 0;
   request->recv = 0;
 #endif
+  if (flags & SEND) smpi_datatype_unuse(datatype);
+
   return request;
 }
 
@@ -174,6 +176,7 @@ void smpi_mpi_start(MPI_Request request)
       mailbox = smpi_process_mailbox();
     // we make a copy here, as the size is modified by simix, and we may reuse the request in another receive later
     request->real_size=request->size;
+    smpi_datatype_use(request->old_type);
     request->action = simcall_comm_irecv(mailbox, request->buf, &request->real_size, &match_recv, request);
     if (request->action)request->action->comm.refcount++;
   } else {
@@ -204,6 +207,7 @@ void smpi_mpi_start(MPI_Request request)
     }
     // we make a copy here, as the size is modified by simix, and we may reuse the request in another receive later
     request->real_size=request->size;
+    smpi_datatype_use(request->old_type);
 
     request->action =
       simcall_comm_isend(mailbox, request->size, -1.0,
@@ -355,7 +359,7 @@ static void finish_wait(MPI_Request * request, MPI_Status * status)
     }
     if(req->detached == 0) free(req->buf);
   }
-
+  smpi_datatype_unuse(datatype);
 
 
   if(req->flags & NON_PERSISTENT) {
@@ -536,6 +540,7 @@ void smpi_mpi_wait(MPI_Request * request, MPI_Status * status)
     simcall_comm_wait((*request)->action, -1.0);
     finish_wait(request, status);
   }
+
   // FIXME for a detached send, finish_wait is not called:
 }
 
index 17e7614..d42e29f 100644 (file)
@@ -295,14 +295,35 @@ void smpi_datatype_create(MPI_Datatype* new_type, int size,int lb, int ub, int h
   new_t->ub = ub;
   new_t->flags = flags;
   new_t->substruct = struct_type;
+  new_t->in_use=0;
   *new_type = new_t;
 }
 
 void smpi_datatype_free(MPI_Datatype* type){
+
+  if((*type)->flags & DT_FLAG_PREDEFINED)return;
+
+  //if still used, mark for deletion
+  if((*type)->in_use!=0){
+      (*type)->flags |=DT_FLAG_DESTROYED;
+      return;
+  }
+
   if ((*type)->has_subtype == 1){
     ((s_smpi_subtype_t *)(*type)->substruct)->subtype_free(type);  
   }
   xbt_free(*type);
+
+}
+
+void smpi_datatype_use(MPI_Datatype type){
+  if(type)type->in_use++;
+}
+
+
+void smpi_datatype_unuse(MPI_Datatype type){
+  if(type && type->in_use-- == 0 && (type->flags & DT_FLAG_DESTROYED))
+    smpi_datatype_free(&type);
 }
 
 int smpi_datatype_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new_type)