+ /* Look for communication action matching our needs. We also provide a description of
+ * ourself so that the other side also gets a chance of choosing if it wants to match with us.
+ *
+ * If it is not found then push our communication into the rendez-vous point */
+ smx_action_t other_action = SIMIX_fifo_get_comm(rdv->comm_fifo, SIMIX_COMM_RECEIVE, match_fun, data, this_action);
+
+ if (!other_action) {
+ other_action = this_action;
+
+ if (rdv->permanent_receiver!=NULL){
+ //this mailbox is for small messages, which have to be sent right now
+ other_action->state = SIMIX_READY;
+ other_action->comm.dst_proc=rdv->permanent_receiver;
+ other_action->comm.refcount++;
+ other_action->comm.rdv = rdv;
+ xbt_fifo_push(rdv->done_comm_fifo,other_action);
+ other_action->comm.rdv=rdv;
+ XBT_DEBUG("pushing a message into the permanent receive fifo %p, comm %p \n", rdv, &(other_action->comm));
+
+ }else{
+ SIMIX_rdv_push(rdv, this_action);
+ }
+ } else {
+ XBT_DEBUG("Receive already pushed\n");
+
+ SIMIX_comm_destroy(this_action);
+ --smx_total_comms; // this creation was a pure waste
+
+ other_action->state = SIMIX_READY;
+ other_action->comm.type = SIMIX_COMM_READY;
+
+ }
+ xbt_fifo_push(src_proc->comms, other_action);
+
+ /* if the communication action is detached then decrease the refcount
+ * by one, so it will be eliminated by the receiver's destroy call */
+ if (detached) {
+ other_action->comm.detached = 1;
+ other_action->comm.refcount--;
+ other_action->comm.clean_fun = clean_fun;
+ } else {
+ other_action->comm.clean_fun = NULL;
+ }
+
+ /* Setup the communication action */
+ other_action->comm.src_proc = src_proc;
+ other_action->comm.task_size = task_size;
+ other_action->comm.rate = rate;
+ other_action->comm.src_buff = src_buff;
+ other_action->comm.src_buff_size = src_buff_size;
+ other_action->comm.src_data = data;
+
+ other_action->comm.match_fun = match_fun;
+
+ if (MC_is_active()) {
+ other_action->state = SIMIX_RUNNING;
+ return other_action;
+ }
+
+ SIMIX_comm_start(other_action);
+ return (detached ? NULL : other_action);
+}
+
+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 *data, double timeout){
+ smx_action_t comm = SIMIX_comm_irecv(simcall->issuer, rdv, dst_buff,
+ dst_buff_size, match_fun, data);
+ simcall->mc_value = 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 *data){
+ return SIMIX_comm_irecv(simcall->issuer, rdv, dst_buff, dst_buff_size,
+ match_fun, data);
+}
+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 *data)