From cfe516ddd1ef9b8759d25de872c0b8dee73e5da9 Mon Sep 17 00:00:00 2001 From: Augustin Degomme Date: Thu, 6 Dec 2012 18:43:06 +0100 Subject: [PATCH] handle proper cleanup of mpi datatypes with MPI_Type_free with a refcounter --- src/smpi/private.h | 4 ++++ src/smpi/smpi_base.c | 7 ++++++- src/smpi/smpi_mpi_dt.c | 21 +++++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/smpi/private.h b/src/smpi/private.h index 2f0d57d221..0fff8ab303 100644 --- a/src/smpi/private.h +++ b/src/smpi/private.h @@ -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, diff --git a/src/smpi/smpi_base.c b/src/smpi/smpi_base.c index a016c1dafa..e548adb854 100644 --- a/src/smpi/smpi_base.c +++ b/src/smpi/smpi_base.c @@ -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: } diff --git a/src/smpi/smpi_mpi_dt.c b/src/smpi/smpi_mpi_dt.c index 17e7614d6b..d42e29f030 100644 --- a/src/smpi/smpi_mpi_dt.c +++ b/src/smpi/smpi_mpi_dt.c @@ -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) -- 2.20.1