Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fix a memory leak happening with smpi_replay
[simgrid.git] / src / smpi / smpi_base.c
index d29b237..5192ca3 100644 (file)
@@ -5,10 +5,11 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "private.h"
-#include "xbt/time.h"
+#include "xbt/virtu.h"
 #include "mc/mc.h"
 #include "xbt/replay.h"
 #include <errno.h>
+#include "simix/smx_private.h"
 #include "surf/surf.h"
 
 
@@ -70,6 +71,7 @@ static MPI_Request build_request(void *buf, int count,
   request->comm = comm;
   request->action = NULL;
   request->flags = flags;
+  request->detached = 0;
 #ifdef HAVE_TRACING
   request->send = 0;
   request->recv = 0;
@@ -145,13 +147,12 @@ MPI_Request smpi_mpi_recv_init(void *buf, int count, MPI_Datatype datatype,
 void smpi_mpi_start(MPI_Request request)
 {
   smx_rdv_t mailbox;
-  int detached = 0;
 
   xbt_assert(!request->action,
              "Cannot (re)start a non-finished communication");
   if(request->flags & RECV) {
     print_request("New recv", request);
-    if (request->size < xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres"))
+    if (request->size < surf_cfg_get_int("smpi/async_small_thres"))
       mailbox = smpi_process_mailbox_small();
     else
       mailbox = smpi_process_mailbox();
@@ -161,23 +162,27 @@ void smpi_mpi_start(MPI_Request request)
   } else {
 
     int receiver = smpi_group_index(smpi_comm_group(request->comm), request->dst);
-    if(receiver == MPI_UNDEFINED) {
-      XBT_WARN("Trying to send a message to a wrong rank");
-      return;
-    }
+/*    if(receiver == MPI_UNDEFINED) {*/
+/*      XBT_WARN("Trying to send a message to a wrong rank");*/
+/*      return;*/
+/*    }*/
     print_request("New send", request);
-    if (request->size < xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres")) { // eager mode
+    if (request->size < surf_cfg_get_int("smpi/async_small_thres")) { // eager mode
       mailbox = smpi_process_remote_mailbox_small(receiver);
     }else{
       XBT_DEBUG("Send request %p is not in the permanent receive mailbox (buf: %p)",request,request->buf);
       mailbox = smpi_process_remote_mailbox(receiver);
     }
     if (request->size < 64*1024 ) { //(FIXME: this limit should be configurable)
-      void *oldbuf = request->buf;
-      detached = 1;
-      request->buf = malloc(request->size);
-      if (oldbuf)
-        memcpy(request->buf,oldbuf,request->size);
+      void *oldbuf = NULL;
+      if(request->old_type->has_subtype == 0){
+        oldbuf = request->buf;
+        request->detached = 1;
+        if (oldbuf){
+          request->buf = malloc(request->size);
+          memcpy(request->buf,oldbuf,request->size);
+        }
+      }
       XBT_DEBUG("Send request %p is detached; buf %p copied into %p",request,oldbuf,request->buf);
     }
 
@@ -188,7 +193,7 @@ void smpi_mpi_start(MPI_Request request)
                          &smpi_mpi_request_free_voidp, // how to free the userdata if a detached send fails
                          request,
                          // detach if msg size < eager/rdv switch limit
-                         detached);
+                         request->detached);
 
 #ifdef HAVE_TRACING
     /* FIXME: detached sends are not traceable (request->action == NULL) */
@@ -302,6 +307,7 @@ static void finish_wait(MPI_Request * request, MPI_Status * status)
 {
   MPI_Request req = *request;
   // if we have a sender, we should use its data, and not the data from the receive
+  //FIXME : mail fail if req->action has already been freed, the pointer being invalid
   if((req->action)&&
      (req->src==MPI_ANY_SOURCE || req->tag== MPI_ANY_TAG))
     req = (MPI_Request)SIMIX_comm_get_src_data((*request)->action);
@@ -309,7 +315,10 @@ static void finish_wait(MPI_Request * request, MPI_Status * status)
   if(status != MPI_STATUS_IGNORE) {
     status->MPI_SOURCE = req->src;
     status->MPI_TAG = req->tag;
+    //if((*request)->action && ((MPI_Request)SIMIX_comm_get_src_data((*request)->action))->size == (*request)->size)
     status->MPI_ERROR = MPI_SUCCESS;
+    //else status->MPI_ERROR = MPI_ERR_TRUNCATE;
+    // this handles the case were size in receive differs from size in send
     // FIXME: really this should just contain the count of receive-type blocks,
     // right?
     status->count = req->size;
@@ -325,9 +334,7 @@ static void finish_wait(MPI_Request * request, MPI_Status * status)
     if(req->flags & RECV) {
       subtype->unserialize(req->buf, req->old_buf, req->size/smpi_datatype_size(datatype) , datatype->substruct);
     }
-    //FIXME: I am not sure that if the send is detached we have to free
-    //the sender buffer thus I do it only for the reciever
-    if(req->flags & RECV) free(req->buf);
+    if(req->detached == 0) free(req->buf);
   }
 
   if(req->flags & NON_PERSISTENT) {
@@ -438,7 +445,7 @@ void smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status*
 
   print_request("New iprobe", request);
   // We have to test both mailboxes as we don't know if we will receive one one or another
-    if (xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres")>0){
+    if (surf_cfg_get_int("smpi/async_small_thres")>0){
         mailbox = smpi_process_mailbox_small();
         XBT_DEBUG("trying to probe the perm recv mailbox");
         request->action = simcall_comm_iprobe(mailbox, request->src, request->tag, &match_recv, (void*)request);
@@ -451,7 +458,7 @@ void smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status*
 
   if(request->action){
     MPI_Request req = (MPI_Request)SIMIX_comm_get_src_data(request->action);
-    *flag=true;
+    *flag = 1;
     if(status != MPI_STATUS_IGNORE) {
       status->MPI_SOURCE = req->src;
       status->MPI_TAG = req->tag;
@@ -459,7 +466,7 @@ void smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status*
       status->count = req->size;
     }
   }
-  else *flag=false;
+  else *flag = 0;
   smpi_mpi_request_free(&request);
 
   return;
@@ -516,12 +523,13 @@ int smpi_mpi_waitany(int count, MPI_Request requests[],
   return index;
 }
 
-void smpi_mpi_waitall(int count, MPI_Request requests[],
+int smpi_mpi_waitall(int count, MPI_Request requests[],
                       MPI_Status status[])
 {
   int  index, c;
   MPI_Status stat;
   MPI_Status *pstat = status == MPI_STATUSES_IGNORE ? MPI_STATUS_IGNORE : &stat;
+  int retvalue=MPI_SUCCESS;
   //tag invalid requests in the set
   for(c = 0; c < count; c++) {
     if(requests[c]==MPI_REQUEST_NULL || requests[c]->dst == MPI_PROC_NULL ){
@@ -536,7 +544,7 @@ void smpi_mpi_waitall(int count, MPI_Request requests[],
   }
 
   for(c = 0; c < count; c++) {
-      if(MC_IS_ENABLED) {
+      if(MC_is_active()) {
         smpi_mpi_wait(&requests[c], pstat);
         index = c;
       } else {
@@ -546,10 +554,12 @@ void smpi_mpi_waitall(int count, MPI_Request requests[],
        }
       if(status != MPI_STATUSES_IGNORE) {
         memcpy(&status[index], pstat, sizeof(*pstat));
+        if(status[index].MPI_ERROR==MPI_ERR_TRUNCATE)retvalue=MPI_ERR_IN_STATUS;
 
       }
     }
   }
+  return retvalue;
 }
 
 int smpi_mpi_waitsome(int incount, MPI_Request requests[], int *indices,