From: Augustin Degomme Date: Wed, 23 Apr 2014 16:52:38 +0000 (+0200) Subject: add private (optional) data copy function callback to _send _isend _recv _irecv simcalls X-Git-Tag: v3_11~98^2~40 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/dd5a646d37996bd34b2e5896b50a6f3d64779a45 add private (optional) data copy function callback to _send _isend _recv _irecv simcalls 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 --- diff --git a/src/msg/msg_gos.c b/src/msg/msg_gos.c index d5d5988c61..198539f668 100644 --- a/src/msg/msg_gos.c +++ b/src/msg/msg_gos.c @@ -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; } diff --git a/src/msg/msg_mailbox.c b/src/msg/msg_mailbox.c index 017472ee56..f2d79e5a22 100644 --- a/src/msg/msg_mailbox.c +++ b/src/msg/msg_mailbox.c @@ -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); diff --git a/src/simix/simcalls.in b/src/simix/simcalls.in index 13a827c960..7d1998e12f 100644 --- a/src/simix/simcalls.in +++ b/src/simix/simcalls.in @@ -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) diff --git a/src/simix/simcalls_generated_args_getter_setter.h b/src/simix/simcalls_generated_args_getter_setter.h index d73a986fd8..bc7a3e29d3 100644 --- a/src/simix/simcalls_generated_args_getter_setter.h +++ b/src/simix/simcalls_generated_args_getter_setter.h @@ -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; diff --git a/src/simix/simcalls_generated_body.c b/src/simix/simcalls_generated_body.c index c0f636f2dd..7f4189a1e3 100644 --- a/src/simix/simcalls_generated_body.c +++ b/src/simix/simcalls_generated_body.c @@ -1100,7 +1100,7 @@ } 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)); @@ -1111,8 +1111,9 @@ 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); @@ -1122,7 +1123,7 @@ } } - 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)); @@ -1134,8 +1135,9 @@ 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); @@ -1145,7 +1147,7 @@ } 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)); @@ -1154,9 +1156,10 @@ 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); @@ -1166,7 +1169,7 @@ } } - 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)); @@ -1175,8 +1178,9 @@ 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); diff --git a/src/simix/simcalls_generated_case.c b/src/simix/simcalls_generated_case.c index 73abff28c2..9966f2e097 100644 --- a/src/simix/simcalls_generated_case.c +++ b/src/simix/simcalls_generated_case.c @@ -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; diff --git a/src/simix/smx_network.c b/src/simix/smx_network.c index b6c5e60d28..f613a519b2 100644 --- a/src/simix/smx_network.c +++ b/src/simix/smx_network.c @@ -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) */ diff --git a/src/simix/smx_network_private.h b/src/simix/smx_network_private.h index e85cf584f8..d0c69678eb 100644 --- a/src/simix/smx_network_private.h +++ b/src/simix/smx_network_private.h @@ -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); diff --git a/src/simix/smx_private.h b/src/simix/smx_private.h index 1e5f1c137b..495ba7a795 100644 --- a/src/simix/smx_private.h +++ b/src/simix/smx_private.h @@ -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 */ diff --git a/src/simix/smx_smurf_private.h b/src/simix/smx_smurf_private.h index dbd5f92907..ee9131a899 100644 --- a/src/simix/smx_smurf_private.h +++ b/src/simix/smx_smurf_private.h @@ -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 diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index 453c7410bb..700e2e3c4b 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -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); } /** diff --git a/src/smpi/private.h b/src/smpi/private.h index 38331fabb5..2d3fd06a0e 100644 --- a/src/smpi/private.h +++ b/src/smpi/private.h @@ -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); diff --git a/src/smpi/smpi_base.c b/src/smpi/smpi_base.c index f2085f2041..4b5fe095d1 100644 --- a/src/smpi/smpi_base.c +++ b/src/smpi/smpi_base.c @@ -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);