+ XBT_DEBUG("Really free communication %p; refcount is now %d", action,
+ action->comm.refcount);
+
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+ action->latency_limited = SIMIX_comm_is_latency_bounded( action ) ;
+#endif
+
+ xbt_free(action->name);
+ SIMIX_comm_destroy_internal_actions(action);
+
+ if (action->comm.detached && action->state != SIMIX_DONE) {
+ /* the communication has failed and was detached:
+ * we have to free the buffer */
+ if (action->comm.clean_fun) {
+ action->comm.clean_fun(action->comm.src_buff);
+ }
+ action->comm.src_buff = NULL;
+ }
+
+ xbt_mallocator_release(simix_global->action_mallocator, action);
+}
+
+void SIMIX_comm_destroy_internal_actions(smx_action_t action)
+{
+ if (action->comm.surf_comm){
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+ action->latency_limited = SIMIX_comm_is_latency_bounded(action);
+#endif
+ action->comm.surf_comm->model_type->action_unref(action->comm.surf_comm);
+ action->comm.surf_comm = NULL;
+ }
+
+ if (action->comm.src_timeout){
+ action->comm.src_timeout->model_type->action_unref(action->comm.src_timeout);
+ action->comm.src_timeout = NULL;
+ }
+
+ if (action->comm.dst_timeout){
+ action->comm.dst_timeout->model_type->action_unref(action->comm.dst_timeout);
+ action->comm.dst_timeout = NULL;
+ }
+}
+
+smx_action_t SIMIX_comm_isend(smx_process_t src_proc, 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 *), // used to free the action in case of problem after a detached send
+ void *data,
+ int detached)
+{
+ XBT_DEBUG("send from %p\n", rdv);
+
+ /* Prepare an action describing us, so that it gets passed to the user-provided filter of other side */
+ smx_action_t this_action = SIMIX_comm_new(SIMIX_COMM_SEND);
+
+ /* 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;