Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
add private (optional) data copy function callback to _send _isend _recv _irecv simcalls
authorAugustin Degomme <degomme@idpann.imag.fr>
Wed, 23 Apr 2014 16:52:38 +0000 (18:52 +0200)
committerAugustin Degomme <degomme@idpann.imag.fr>
Fri, 25 Apr 2014 14:08:27 +0000 (16:08 +0200)
It used to be globally set, but if we want to mix layers of SimGrid (SMPI + MSG calls)
we would want to have different copy functions used during the same simulation

13 files changed:
src/msg/msg_gos.c
src/msg/msg_mailbox.c
src/simix/simcalls.in
src/simix/simcalls_generated_args_getter_setter.h
src/simix/simcalls_generated_body.c
src/simix/simcalls_generated_case.c
src/simix/smx_network.c
src/simix/smx_network_private.h
src/simix/smx_private.h
src/simix/smx_smurf_private.h
src/simix/smx_user.c
src/smpi/private.h
src/smpi/smpi_base.c

index d5d5988..198539f 100644 (file)
@@ -431,7 +431,7 @@ msg_comm_t MSG_task_isend_internal(msg_task_t task, const char *alias,
   /* Send it by calling SIMIX network layer */
   smx_action_t act = simcall_comm_isend(mailbox, t_simdata->message_size,
                                         t_simdata->rate, task, sizeof(void *),
-                                        match_fun, cleanup, match_data,detached);
+                                        match_fun, cleanup, NULL, match_data,detached);
   t_simdata->comm = act; /* FIXME: is the field t_simdata->comm still useful? */
 
   msg_comm_t comm;
@@ -607,7 +607,7 @@ msg_comm_t MSG_task_irecv_bounded(msg_task_t *task, const char *name,
   comm->task_sent = NULL;
   comm->task_received = task;
   comm->status = MSG_OK;
-  comm->s_comm = simcall_comm_irecv(rdv, task, NULL, NULL, NULL, rate);
+  comm->s_comm = simcall_comm_irecv(rdv, task, NULL, NULL, NULL, NULL, rate);
 
   return comm;
 }
index 017472e..f2d79e5 100644 (file)
@@ -130,7 +130,7 @@ MSG_mailbox_get_task_ext_bounded(msg_mailbox_t mailbox, msg_task_t * task,
 
   /* Try to receive it by calling SIMIX network layer */
   TRY {
-    simcall_comm_recv(mailbox, task, NULL, NULL, NULL, timeout, rate);
+    simcall_comm_recv(mailbox, task, NULL, NULL, NULL, NULL, timeout, rate);
     XBT_DEBUG("Got task %s from %p",(*task)->name,mailbox);
     if (msg_global->debug_multiple_use && (*task)->simdata->isused!=0)
       xbt_ex_free(*(xbt_ex_t*)(*task)->simdata->isused);
@@ -209,7 +209,7 @@ MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task,
     smx_action_t comm = NULL; /* MC needs the comm to be set to NULL during the simix call  */
     comm = simcall_comm_isend(mailbox, t_simdata->message_size,
                                   t_simdata->rate, task, sizeof(void *),
-                                  NULL, NULL, task, 0);
+                                  NULL, NULL, NULL, task, 0);
 #ifdef HAVE_TRACING
     if (TRACE_is_enabled()) {
       simcall_set_category(comm, task->category);
index 13a827c..7d1998e 100644 (file)
@@ -76,10 +76,10 @@ rdv_get_head True (void*, smx_action_t) (rdv, void*, smx_rdv_t)
 rdv_set_receiver True (void) (rdv, void*, smx_rdv_t) (receiver, void*, smx_process_t)
 rdv_get_receiver True (void*, smx_process_t) (rdv, void*, smx_rdv_t)
 comm_iprobe True (void*, smx_action_t) (rdv, void*, smx_rdv_t) (src, int) (tag, int) (match_fun, FPtr, simix_match_func_t) (data, void*)
-comm_send False (void) (rdv, void*, smx_rdv_t) (task_size, double) (rate, double) (src_buff, void*) (src_buff_size, size_t) (match_fun, FPtr, simix_match_func_t) (data, void*) (timeout, double)
-comm_isend True (void*, smx_action_t) (rdv, void*, smx_rdv_t) (task_size, double) (rate, double) (src_buff, void*) (src_buff_size, size_t) (match_fun, FPtr, simix_match_func_t) (clean_fun, FPtr, simix_clean_func_t) (data, void*) (detached, int)
-comm_recv False (void) (rdv, void*, smx_rdv_t) (dst_buff, void*) (dst_buff_size, void*, size_t*) (match_fun, FPtr, simix_match_func_t) (data, void*) (timeout, double) (rate, double)
-comm_irecv True (void*, smx_action_t) (rdv, void*, smx_rdv_t) (dst_buff, void*) (dst_buff_size, void*, size_t*) (match_fun, FPtr, simix_match_func_t) (data, void*) (rate, double)
+comm_send False (void) (rdv, void*, smx_rdv_t) (task_size, double) (rate, double) (src_buff, void*) (src_buff_size, size_t) (match_fun, FPtr, simix_match_func_t) (copy_data_fun, FPtr, simix_copy_data_func_t) (data, void*) (timeout, double)
+comm_isend True (void*, smx_action_t) (rdv, void*, smx_rdv_t) (task_size, double) (rate, double) (src_buff, void*) (src_buff_size, size_t) (match_fun, FPtr, simix_match_func_t) (clean_fun, FPtr, simix_clean_func_t) (copy_data_fun, FPtr, simix_copy_data_func_t) (data, void*) (detached, int)
+comm_recv False (void) (rdv, void*, smx_rdv_t) (dst_buff, void*) (dst_buff_size, void*, size_t*) (match_fun, FPtr, simix_match_func_t) (copy_data_fun, FPtr, simix_copy_data_func_t) (data, void*) (timeout, double) (rate, double)
+comm_irecv True (void*, smx_action_t) (rdv, void*, smx_rdv_t) (dst_buff, void*) (dst_buff_size, void*, size_t*) (match_fun, FPtr, simix_match_func_t) (copy_data_fun, FPtr, simix_copy_data_func_t) (data, void*) (rate, double)
 comm_cancel True (void) (comm, void*, smx_action_t)
 comm_waitany False (int) (comms, void*, xbt_dynar_t)
 comm_wait False (void) (comm, void*, smx_action_t) (timeout, double)
index d73a986..bc7a3e2 100644 (file)
@@ -726,17 +726,23 @@ static inline simix_match_func_t simcall_comm_send__get__match_fun(smx_simcall_t
 static inline void simcall_comm_send__set__match_fun(smx_simcall_t simcall, FPtr arg){
     simcall->args[5].fp = arg;
 }
+static inline simix_copy_data_func_t simcall_comm_send__get__copy_data_fun(smx_simcall_t simcall){
+  return (simix_copy_data_func_t) simcall->args[6].fp;
+}
+static inline void simcall_comm_send__set__copy_data_fun(smx_simcall_t simcall, FPtr arg){
+    simcall->args[6].fp = arg;
+}
 static inline void* simcall_comm_send__get__data(smx_simcall_t simcall){
-  return  simcall->args[6].dp;
+  return  simcall->args[7].dp;
 }
 static inline void simcall_comm_send__set__data(smx_simcall_t simcall, void* arg){
-    simcall->args[6].dp = arg;
+    simcall->args[7].dp = arg;
 }
 static inline double simcall_comm_send__get__timeout(smx_simcall_t simcall){
-  return  simcall->args[7].d;
+  return  simcall->args[8].d;
 }
 static inline void simcall_comm_send__set__timeout(smx_simcall_t simcall, double arg){
-    simcall->args[7].d = arg;
+    simcall->args[8].d = arg;
 }
 static inline smx_rdv_t simcall_comm_isend__get__rdv(smx_simcall_t simcall){
   return (smx_rdv_t) simcall->args[0].dp;
@@ -780,17 +786,23 @@ static inline simix_clean_func_t simcall_comm_isend__get__clean_fun(smx_simcall_
 static inline void simcall_comm_isend__set__clean_fun(smx_simcall_t simcall, FPtr arg){
     simcall->args[6].fp = arg;
 }
+static inline simix_copy_data_func_t simcall_comm_isend__get__copy_data_fun(smx_simcall_t simcall){
+  return (simix_copy_data_func_t) simcall->args[7].fp;
+}
+static inline void simcall_comm_isend__set__copy_data_fun(smx_simcall_t simcall, FPtr arg){
+    simcall->args[7].fp = arg;
+}
 static inline void* simcall_comm_isend__get__data(smx_simcall_t simcall){
-  return  simcall->args[7].dp;
+  return  simcall->args[8].dp;
 }
 static inline void simcall_comm_isend__set__data(smx_simcall_t simcall, void* arg){
-    simcall->args[7].dp = arg;
+    simcall->args[8].dp = arg;
 }
 static inline int simcall_comm_isend__get__detached(smx_simcall_t simcall){
-  return  simcall->args[8].i;
+  return  simcall->args[9].i;
 }
 static inline void simcall_comm_isend__set__detached(smx_simcall_t simcall, int arg){
-    simcall->args[8].i = arg;
+    simcall->args[9].i = arg;
 }
 static inline smx_rdv_t simcall_comm_recv__get__rdv(smx_simcall_t simcall){
   return (smx_rdv_t) simcall->args[0].dp;
@@ -816,23 +828,29 @@ static inline simix_match_func_t simcall_comm_recv__get__match_fun(smx_simcall_t
 static inline void simcall_comm_recv__set__match_fun(smx_simcall_t simcall, FPtr arg){
     simcall->args[3].fp = arg;
 }
+static inline simix_copy_data_func_t simcall_comm_recv__get__copy_data_fun(smx_simcall_t simcall){
+  return (simix_copy_data_func_t) simcall->args[4].fp;
+}
+static inline void simcall_comm_recv__set__copy_data_fun(smx_simcall_t simcall, FPtr arg){
+    simcall->args[4].fp = arg;
+}
 static inline void* simcall_comm_recv__get__data(smx_simcall_t simcall){
-  return  simcall->args[4].dp;
+  return  simcall->args[5].dp;
 }
 static inline void simcall_comm_recv__set__data(smx_simcall_t simcall, void* arg){
-    simcall->args[4].dp = arg;
+    simcall->args[5].dp = arg;
 }
 static inline double simcall_comm_recv__get__timeout(smx_simcall_t simcall){
-  return  simcall->args[5].d;
+  return  simcall->args[6].d;
 }
 static inline void simcall_comm_recv__set__timeout(smx_simcall_t simcall, double arg){
-    simcall->args[5].d = arg;
+    simcall->args[6].d = arg;
 }
 static inline double simcall_comm_recv__get__rate(smx_simcall_t simcall){
-  return  simcall->args[6].d;
+  return  simcall->args[7].d;
 }
 static inline void simcall_comm_recv__set__rate(smx_simcall_t simcall, double arg){
-    simcall->args[6].d = arg;
+    simcall->args[7].d = arg;
 }
 static inline smx_rdv_t simcall_comm_irecv__get__rdv(smx_simcall_t simcall){
   return (smx_rdv_t) simcall->args[0].dp;
@@ -858,17 +876,23 @@ static inline simix_match_func_t simcall_comm_irecv__get__match_fun(smx_simcall_
 static inline void simcall_comm_irecv__set__match_fun(smx_simcall_t simcall, FPtr arg){
     simcall->args[3].fp = arg;
 }
+static inline simix_copy_data_func_t simcall_comm_irecv__get__copy_data_fun(smx_simcall_t simcall){
+  return (simix_copy_data_func_t) simcall->args[4].fp;
+}
+static inline void simcall_comm_irecv__set__copy_data_fun(smx_simcall_t simcall, FPtr arg){
+    simcall->args[4].fp = arg;
+}
 static inline void* simcall_comm_irecv__get__data(smx_simcall_t simcall){
-  return  simcall->args[4].dp;
+  return  simcall->args[5].dp;
 }
 static inline void simcall_comm_irecv__set__data(smx_simcall_t simcall, void* arg){
-    simcall->args[4].dp = arg;
+    simcall->args[5].dp = arg;
 }
 static inline double simcall_comm_irecv__get__rate(smx_simcall_t simcall){
-  return  simcall->args[5].d;
+  return  simcall->args[6].d;
 }
 static inline void simcall_comm_irecv__set__rate(smx_simcall_t simcall, double arg){
-    simcall->args[5].d = arg;
+    simcall->args[6].d = arg;
 }
 static inline smx_action_t simcall_comm_cancel__get__comm(smx_simcall_t simcall){
   return (smx_action_t) simcall->args[0].dp;
index c0f636f..7f4189a 100644 (file)
     }    
     return self->simcall.result.dp;
   }
-  inline static void simcall_BODY_comm_send(smx_rdv_t rdv, double task_size, double rate, void* src_buff, size_t src_buff_size, simix_match_func_t match_fun, void* data, double timeout) {
+  inline static void simcall_BODY_comm_send(smx_rdv_t rdv, double task_size, double rate, void* src_buff, size_t src_buff_size, simix_match_func_t match_fun, simix_copy_data_func_t copy_data_fun, void* data, double timeout) {
     smx_process_t self = SIMIX_process_self();
     self->simcall.call = SIMCALL_COMM_SEND;
     memset(&self->simcall.result, 0, sizeof(self->simcall.result));
     self->simcall.args[3].dp = (void*) src_buff;
     self->simcall.args[4].sz = (size_t) src_buff_size;
     self->simcall.args[5].fp = (FPtr) match_fun;
-    self->simcall.args[6].dp = (void*) data;
-    self->simcall.args[7].d = (double) timeout;
+    self->simcall.args[6].fp = (FPtr) copy_data_fun;
+    self->simcall.args[7].dp = (void*) data;
+    self->simcall.args[8].d = (double) timeout;
     if (self != simix_global->maestro_process) {
       XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name,
                 SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
     }    
     
   }
-  inline static smx_action_t simcall_BODY_comm_isend(smx_rdv_t rdv, double task_size, double rate, void* src_buff, size_t src_buff_size, simix_match_func_t match_fun, simix_clean_func_t clean_fun, void* data, int detached) {
+  inline static smx_action_t simcall_BODY_comm_isend(smx_rdv_t rdv, double task_size, double rate, void* src_buff, size_t src_buff_size, simix_match_func_t match_fun, simix_clean_func_t clean_fun, simix_copy_data_func_t copy_data_fun, void* data, int detached) {
     smx_process_t self = SIMIX_process_self();
     self->simcall.call = SIMCALL_COMM_ISEND;
     memset(&self->simcall.result, 0, sizeof(self->simcall.result));
     self->simcall.args[4].sz = (size_t) src_buff_size;
     self->simcall.args[5].fp = (FPtr) match_fun;
     self->simcall.args[6].fp = (FPtr) clean_fun;
-    self->simcall.args[7].dp = (void*) data;
-    self->simcall.args[8].i = (int) detached;
+    self->simcall.args[7].fp = (FPtr) copy_data_fun;
+    self->simcall.args[8].dp = (void*) data;
+    self->simcall.args[9].i = (int) detached;
     if (self != simix_global->maestro_process) {
       XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name,
                 SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
     }    
     return self->simcall.result.dp;
   }
-  inline static void simcall_BODY_comm_recv(smx_rdv_t rdv, void* dst_buff, size_t* dst_buff_size, simix_match_func_t match_fun, void* data, double timeout, double rate) {
+  inline static void simcall_BODY_comm_recv(smx_rdv_t rdv, void* dst_buff, size_t* dst_buff_size, simix_match_func_t match_fun, simix_copy_data_func_t copy_data_fun, void* data, double timeout, double rate) {
     smx_process_t self = SIMIX_process_self();
     self->simcall.call = SIMCALL_COMM_RECV;
     memset(&self->simcall.result, 0, sizeof(self->simcall.result));
     self->simcall.args[1].dp = (void*) dst_buff;
     self->simcall.args[2].dp = (void*) dst_buff_size;
     self->simcall.args[3].fp = (FPtr) match_fun;
-    self->simcall.args[4].dp = (void*) data;
-    self->simcall.args[5].d = (double) timeout;
-    self->simcall.args[6].d = (double) rate;
+    self->simcall.args[4].fp = (FPtr) copy_data_fun;
+    self->simcall.args[5].dp = (void*) data;
+    self->simcall.args[6].d = (double) timeout;
+    self->simcall.args[7].d = (double) rate;
     if (self != simix_global->maestro_process) {
       XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name,
                 SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
     }    
     
   }
-  inline static smx_action_t simcall_BODY_comm_irecv(smx_rdv_t rdv, void* dst_buff, size_t* dst_buff_size, simix_match_func_t match_fun, void* data, double rate) {
+  inline static smx_action_t simcall_BODY_comm_irecv(smx_rdv_t rdv, void* dst_buff, size_t* dst_buff_size, simix_match_func_t match_fun, simix_copy_data_func_t copy_data_fun, void* data, double rate) {
     smx_process_t self = SIMIX_process_self();
     self->simcall.call = SIMCALL_COMM_IRECV;
     memset(&self->simcall.result, 0, sizeof(self->simcall.result));
     self->simcall.args[1].dp = (void*) dst_buff;
     self->simcall.args[2].dp = (void*) dst_buff_size;
     self->simcall.args[3].fp = (FPtr) match_fun;
-    self->simcall.args[4].dp = (void*) data;
-    self->simcall.args[5].d = (double) rate;
+    self->simcall.args[4].fp = (FPtr) copy_data_fun;
+    self->simcall.args[5].dp = (void*) data;
+    self->simcall.args[6].d = (double) rate;
     if (self != simix_global->maestro_process) {
       XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name,
                 SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
index 73abff2..9966f2e 100644 (file)
@@ -352,20 +352,20 @@ case SIMCALL_COMM_IPROBE:
       break;  
 
 case SIMCALL_COMM_SEND:
-       SIMIX_pre_comm_send(simcall , (smx_rdv_t) simcall->args[0].dp,  simcall->args[1].d,  simcall->args[2].d,  simcall->args[3].dp,  simcall->args[4].sz, (simix_match_func_t) simcall->args[5].fp,  simcall->args[6].dp,  simcall->args[7].d);
+       SIMIX_pre_comm_send(simcall , (smx_rdv_t) simcall->args[0].dp,  simcall->args[1].d,  simcall->args[2].d,  simcall->args[3].dp,  simcall->args[4].sz, (simix_match_func_t) simcall->args[5].fp, (simix_copy_data_func_t) simcall->args[6].fp,  simcall->args[7].dp,  simcall->args[8].d);
        break;  
 
 case SIMCALL_COMM_ISEND:
-      simcall->result.dp = SIMIX_pre_comm_isend(simcall , (smx_rdv_t) simcall->args[0].dp,  simcall->args[1].d,  simcall->args[2].d,  simcall->args[3].dp,  simcall->args[4].sz, (simix_match_func_t) simcall->args[5].fp, (simix_clean_func_t) simcall->args[6].fp,  simcall->args[7].dp,  simcall->args[8].i);
+      simcall->result.dp = SIMIX_pre_comm_isend(simcall , (smx_rdv_t) simcall->args[0].dp,  simcall->args[1].d,  simcall->args[2].d,  simcall->args[3].dp,  simcall->args[4].sz, (simix_match_func_t) simcall->args[5].fp, (simix_clean_func_t) simcall->args[6].fp, (simix_copy_data_func_t) simcall->args[7].fp,  simcall->args[8].dp,  simcall->args[9].i);
       SIMIX_simcall_answer(simcall);
       break;  
 
 case SIMCALL_COMM_RECV:
-       SIMIX_pre_comm_recv(simcall , (smx_rdv_t) simcall->args[0].dp,  simcall->args[1].dp, (size_t*) simcall->args[2].dp, (simix_match_func_t) simcall->args[3].fp,  simcall->args[4].dp,  simcall->args[5].d,  simcall->args[6].d);
+       SIMIX_pre_comm_recv(simcall , (smx_rdv_t) simcall->args[0].dp,  simcall->args[1].dp, (size_t*) simcall->args[2].dp, (simix_match_func_t) simcall->args[3].fp, (simix_copy_data_func_t) simcall->args[4].fp,  simcall->args[5].dp,  simcall->args[6].d,  simcall->args[7].d);
        break;  
 
 case SIMCALL_COMM_IRECV:
-      simcall->result.dp = SIMIX_pre_comm_irecv(simcall , (smx_rdv_t) simcall->args[0].dp,  simcall->args[1].dp, (size_t*) simcall->args[2].dp, (simix_match_func_t) simcall->args[3].fp,  simcall->args[4].dp,  simcall->args[5].d);
+      simcall->result.dp = SIMIX_pre_comm_irecv(simcall , (smx_rdv_t) simcall->args[0].dp,  simcall->args[1].dp, (size_t*) simcall->args[2].dp, (simix_match_func_t) simcall->args[3].fp, (simix_copy_data_func_t) simcall->args[4].fp,  simcall->args[5].dp,  simcall->args[6].d);
       SIMIX_simcall_answer(simcall);
       break;  
 
index b6c5e60..f613a51 100644 (file)
@@ -355,9 +355,10 @@ void SIMIX_pre_comm_send(smx_simcall_t simcall, smx_rdv_t rdv,
                                   double task_size, double rate,
                                   void *src_buff, size_t src_buff_size,
                                   int (*match_fun)(void *, void *,smx_action_t),
+                                  void (*copy_data_fun)(smx_action_t, void*, size_t),
                                  void *data, double timeout){
   smx_action_t comm = SIMIX_comm_isend(simcall->issuer, rdv, task_size, rate,
-                                      src_buff, src_buff_size, match_fun, NULL,
+                                      src_buff, src_buff_size, match_fun, NULL, copy_data_fun,
                                       data, 0);
   SIMCALL_SET_MC_VALUE(simcall, 0);
   SIMIX_pre_comm_wait(simcall, comm, timeout);
@@ -367,9 +368,10 @@ smx_action_t SIMIX_pre_comm_isend(smx_simcall_t simcall, smx_rdv_t rdv,
                                   void *src_buff, size_t src_buff_size,
                                   int (*match_fun)(void *, void *,smx_action_t),
                                   void (*clean_fun)(void *), 
+                                  void (*copy_data_fun)(smx_action_t, void*, size_t),
                                  void *data, int detached){
   return SIMIX_comm_isend(simcall->issuer, rdv, task_size, rate, src_buff,
-                         src_buff_size, match_fun, clean_fun, data, detached);
+                         src_buff_size, match_fun, clean_fun, copy_data_fun, data, detached);
 
 }
 smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
@@ -377,6 +379,7 @@ smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
                               void *src_buff, size_t src_buff_size,
                               int (*match_fun)(void *, void *,smx_action_t),
                               void (*clean_fun)(void *), // used to free the action in case of problem after a detached send
+                              void (*copy_data_fun)(smx_action_t, void*, size_t), // used to copy data if not default one
                               void *data,
                               int detached)
 {
@@ -437,6 +440,8 @@ smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
   other_action->comm.src_data = data;
 
   other_action->comm.match_fun = match_fun;
+  other_action->comm.copy_data_fun = copy_data_fun;
+
 
   if (MC_is_active()) {
     other_action->state = SIMIX_RUNNING;
@@ -450,10 +455,11 @@ smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
 void SIMIX_pre_comm_recv(smx_simcall_t simcall, smx_rdv_t rdv,
                          void *dst_buff, size_t *dst_buff_size,
                          int (*match_fun)(void *, void *, smx_action_t),
+                         void (*copy_data_fun)(smx_action_t, void*, size_t),
                          void *data, double timeout, double rate)
 {
   smx_action_t comm = SIMIX_comm_irecv(simcall->issuer, rdv, dst_buff,
-                                      dst_buff_size, match_fun, data, rate);
+                                      dst_buff_size, match_fun, copy_data_fun, data, rate);
   SIMCALL_SET_MC_VALUE(simcall, 0);
   SIMIX_pre_comm_wait(simcall, comm, timeout);
 }
@@ -461,15 +467,17 @@ void SIMIX_pre_comm_recv(smx_simcall_t simcall, smx_rdv_t rdv,
 smx_action_t SIMIX_pre_comm_irecv(smx_simcall_t simcall, smx_rdv_t rdv,
                                   void *dst_buff, size_t *dst_buff_size,
                                   int (*match_fun)(void *, void *, smx_action_t),
+                                  void (*copy_data_fun)(smx_action_t, void*, size_t),
                                  void *data, double rate)
 {
   return SIMIX_comm_irecv(simcall->issuer, rdv, dst_buff, dst_buff_size,
-                         match_fun, data, rate);
+                         match_fun, copy_data_fun, data, rate);
 }
 
 smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
                               void *dst_buff, size_t *dst_buff_size,
                               int (*match_fun)(void *, void *, smx_action_t),
+                              void (*copy_data_fun)(smx_action_t, void*, size_t), // used to copy data if not default one
                               void *data, double rate)
 {
   XBT_DEBUG("recv from %p %p\n", rdv, rdv->comm_fifo);
@@ -541,6 +549,7 @@ smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
     other_action->comm.rate = rate;
 
   other_action->comm.match_fun = match_fun;
+  other_action->comm.copy_data_fun = copy_data_fun;
 
 
   /*if(already_received)//do the actual copy, because the first one after the comm didn't have all the info
@@ -1170,8 +1179,13 @@ void SIMIX_comm_copy_data(smx_action_t comm)
   if (comm->comm.dst_buff_size)
     *comm->comm.dst_buff_size = buff_size;
 
-  if (buff_size > 0)
-    SIMIX_comm_copy_data_callback (comm, comm->comm.src_buff, buff_size);
+  if (buff_size > 0){
+      if(comm->comm.copy_data_fun)
+        comm->comm.copy_data_fun (comm, comm->comm.src_buff, buff_size);
+      else
+        SIMIX_comm_copy_data_callback (comm, comm->comm.src_buff, buff_size);
+  }
+
 
   /* Set the copied flag so we copy data only once */
   /* (this function might be called from both communication ends) */
index e85cf58..d0c6967 100644 (file)
@@ -39,11 +39,13 @@ smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
                               void *src_buff, size_t src_buff_size,
                               int (*match_fun)(void *, void *, smx_action_t),
                               void (*clean_fun)(void *), // used to free the action in case of problem after a detached send
+                              void (*copy_data_fun)(smx_action_t, void*, size_t),
                               void *data,
                               int detached);
 smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
                               void *dst_buff, size_t *dst_buff_size,
                               int (*)(void *, void *, smx_action_t),
+                              void (*copy_data_fun)(smx_action_t, void*, size_t),
                               void *data, double rate);
 void SIMIX_comm_destroy(smx_action_t action);
 void SIMIX_comm_destroy_internal_actions(smx_action_t action);
@@ -79,20 +81,24 @@ void SIMIX_pre_comm_send(smx_simcall_t simcall, smx_rdv_t rdv,
                                   double task_size, double rate,
                                   void *src_buff, size_t src_buff_size,
                                   int (*match_fun)(void *, void *,smx_action_t),
+                                  void (*copy_data_fun)(smx_action_t, void*, size_t),
                                  void *data, double timeout);
 smx_action_t SIMIX_pre_comm_isend(smx_simcall_t simcall, smx_rdv_t rdv,
                                   double task_size, double rate,
                                   void *src_buff, size_t src_buff_size,
                                   int (*match_fun)(void *, void *,smx_action_t),
                                   void (*clean_fun)(void *), 
+                                  void (*copy_data_fun)(smx_action_t, void*, size_t),
                                  void *data, int detached);
 void SIMIX_pre_comm_recv(smx_simcall_t simcall, smx_rdv_t rdv,
                          void *dst_buff, size_t *dst_buff_size,
                          int (*match_fun)(void *, void *, smx_action_t),
+                         void (*copy_data_fun)(smx_action_t, void*, size_t),
                          void *data, double timeout, double rate);
 smx_action_t SIMIX_pre_comm_irecv(smx_simcall_t simcall, smx_rdv_t rdv,
                                   void *dst_buff, size_t *dst_buff_size,
                                   int (*match_fun)(void *, void *, smx_action_t),
+                                  void (*copy_data_fun)(smx_action_t, void*, size_t),
                                  void *data, double rate);
 void SIMIX_pre_comm_cancel(smx_simcall_t simcall, smx_action_t action);
 double SIMIX_pre_comm_get_remains(smx_simcall_t simcall, smx_action_t action);
index 1e5f1c1..495ba7a 100644 (file)
@@ -155,6 +155,7 @@ typedef struct s_smx_action {
       int (*match_fun)(void*,void*,smx_action_t);  /* Filter function used by the other side. It is used when
                                          looking if a given communication matches my needs. For that, myself must match the
                                          expectations of the other side, too. See  */
+      void (*copy_data_fun) (smx_action_t, void*, size_t);
 
       /* Surf action data */
       surf_action_t surf_comm;        /* The Surf communication action encapsulated */
index dbd5f92..ee9131a 100644 (file)
@@ -29,6 +29,7 @@ NUM_SIMCALLS
 } e_smx_simcall_t;
 
 typedef int (*simix_match_func_t)(void *, void *, smx_action_t);
+typedef void (*simix_copy_data_func_t)(smx_action_t, void*, size_t);
 typedef void (*simix_clean_func_t)(void *);
 typedef void (*FPtr)(void); // Hide the ugliness
 
index 453c741..700e2e3 100644 (file)
@@ -935,7 +935,8 @@ smx_process_t simcall_rdv_get_receiver(smx_rdv_t rdv)
  */
 void simcall_comm_send(smx_rdv_t rdv, double task_size, double rate,
                          void *src_buff, size_t src_buff_size,
-                         int (*match_fun)(void *, void *, smx_action_t), void *data,
+                         int (*match_fun)(void *, void *, smx_action_t),
+                         void (*copy_data_fun)(smx_action_t, void*, size_t), void *data,
                          double timeout)
 {
   /* checking for infinite values */
@@ -949,13 +950,13 @@ void simcall_comm_send(smx_rdv_t rdv, double task_size, double rate,
     /* the model-checker wants two separate simcalls */
     smx_action_t comm = NULL; /* MC needs the comm to be set to NULL during the simcall */
     comm = simcall_comm_isend(rdv, task_size, rate,
-        src_buff, src_buff_size, match_fun, NULL, data, 0);
+        src_buff, src_buff_size, match_fun, NULL, copy_data_fun, data, 0);
     simcall_comm_wait(comm, timeout);
     comm = NULL;
   }
   else {
     simcall_BODY_comm_send(rdv, task_size, rate, src_buff, src_buff_size,
-                         match_fun, data, timeout);
+                         match_fun, copy_data_fun, data, timeout);
   }
 }
 
@@ -966,6 +967,7 @@ smx_action_t simcall_comm_isend(smx_rdv_t rdv, double task_size, double rate,
                               void *src_buff, size_t src_buff_size,
                               int (*match_fun)(void *, void *, smx_action_t),
                               void (*clean_fun)(void *),
+                              void (*copy_data_fun)(smx_action_t, void*, size_t),
                               void *data,
                               int detached)
 {
@@ -977,7 +979,7 @@ smx_action_t simcall_comm_isend(smx_rdv_t rdv, double task_size, double rate,
 
   return simcall_BODY_comm_isend(rdv, task_size, rate, src_buff,
                                  src_buff_size, match_fun,
-                                 clean_fun, data, detached);
+                                 clean_fun, copy_data_fun, data, detached);
 }
 
 /**
@@ -985,6 +987,7 @@ smx_action_t simcall_comm_isend(smx_rdv_t rdv, double task_size, double rate,
  */
 void simcall_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
                        int (*match_fun)(void *, void *, smx_action_t),
+                       void (*copy_data_fun)(smx_action_t, void*, size_t),
                        void *data, double timeout, double rate)
 {
   xbt_assert(isfinite(timeout), "timeout is not finite!");
@@ -994,13 +997,13 @@ void simcall_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
     /* the model-checker wants two separate simcalls */
     smx_action_t comm = NULL; /* MC needs the comm to be set to NULL during the simcall */
     comm = simcall_comm_irecv(rdv, dst_buff, dst_buff_size,
-                              match_fun, data, rate);
+                              match_fun, copy_data_fun, data, rate);
     simcall_comm_wait(comm, timeout);
     comm = NULL;
   }
   else {
     simcall_BODY_comm_recv(rdv, dst_buff, dst_buff_size,
-                           match_fun, data, timeout, rate);
+                           match_fun, copy_data_fun, data, timeout, rate);
   }
 }
 /**
@@ -1008,12 +1011,13 @@ void simcall_comm_recv(smx_rdv_t rdv, void *dst_buff, size_t * dst_buff_size,
  */
 smx_action_t simcall_comm_irecv(smx_rdv_t rdv, void *dst_buff, size_t *dst_buff_size,
                                 int (*match_fun)(void *, void *, smx_action_t),
+                                void (*copy_data_fun)(smx_action_t, void*, size_t),
                                 void *data, double rate)
 {
   xbt_assert(rdv, "No rendez-vous point defined for irecv");
 
   return simcall_BODY_comm_irecv(rdv, dst_buff, dst_buff_size,
-                                 match_fun, data, rate);
+                                 match_fun, copy_data_fun, data, rate);
 }
 
 /**
index 38331fa..2d3fd06 100644 (file)
@@ -139,6 +139,9 @@ double smpi_process_simulated_elapsed(void);
 void smpi_process_set_sampling(int s);
 int smpi_process_get_sampling(void);
 
+void smpi_comm_copy_buffer_callback(smx_action_t comm,
+                                           void *buff, size_t buff_size);
+
 void print_request(const char *message, MPI_Request request);
 
 void smpi_global_init(void);
index f2085f2..4b5fe09 100644 (file)
@@ -335,7 +335,7 @@ void smpi_mpi_start(MPI_Request request)
     smpi_datatype_use(request->old_type);
     smpi_comm_use(request->comm);
     request->action = simcall_comm_irecv(mailbox, request->buf,
-                                         &request->real_size, &match_recv,
+                                         &request->real_size, &match_recv, &smpi_comm_copy_buffer_callback,
                                          request, -1.0);
 
     //integrate pseudo-timing for buffering of small messages, do not bother to execute the simcall if 0
@@ -411,6 +411,7 @@ void smpi_mpi_start(MPI_Request request)
                          buf, request->real_size,
                          &match_send,
                          &xbt_free, // how to free the userdata if a detached send fails
+                         &smpi_comm_copy_buffer_callback,
                          request,
                          // detach if msg size < eager/rdv switch limit
                          request->detached);