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
/* 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;
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;
}
/* 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);
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);
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)
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;
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;
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;
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;
}
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);
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;
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);
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,
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)
{
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;
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);
}
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);
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
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) */
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);
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);
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 */
} 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
*/
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 */
/* 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);
}
}
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 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);
}
/**
*/
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!");
/* 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);
}
}
/**
*/
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);
}
/**
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);
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
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);