Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
better handling of blocking simcalls in the generated popping
[simgrid.git] / src / simix / smx_network.c
index 2cd4c1d..7c0b9ff 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010. The SimGrid Team.
+/* Copyright (c) 2009-2014. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -8,12 +8,14 @@
 #include "xbt/log.h"
 #include "mc/mc.h"
 #include "xbt/dict.h"
+#include "smpi/private.h"
+
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_network, simix,
                                 "Logging specific to SIMIX (network)");
 
 static xbt_dict_t rdv_points = NULL;
-XBT_PUBLIC(unsigned long int) smx_total_comms = 0;
+XBT_EXPORT_NO_IMPORT(unsigned long int) smx_total_comms = 0;
 
 static void SIMIX_waitany_remove_simcall_from_actions(smx_simcall_t simcall);
 static void SIMIX_comm_copy_data(smx_action_t comm);
@@ -26,12 +28,11 @@ static smx_action_t SIMIX_fifo_get_comm(xbt_fifo_t fifo, e_smx_comm_type_t type,
                                         int (*match_fun)(void *, void *,smx_action_t),
                                         void *user_data, smx_action_t my_action);
 static void SIMIX_rdv_free(void *data);
+static void SIMIX_comm_start(smx_action_t action);
 
 void SIMIX_network_init(void)
 {
   rdv_points = xbt_dict_new_homogeneous(SIMIX_rdv_free);
-  if(MC_is_active())
-    MC_ignore_data_bss(&smx_total_comms, sizeof(smx_total_comms));
 }
 
 void SIMIX_network_exit(void)
@@ -43,7 +44,7 @@ void SIMIX_network_exit(void)
 /*                           Rendez-Vous Points                               */
 /******************************************************************************/
 
-smx_rdv_t SIMIX_pre_rdv_create(smx_simcall_t simcall, const char *name){
+smx_rdv_t simcall_HANDLER_rdv_create(smx_simcall_t simcall, const char *name){
   return SIMIX_rdv_create(name);
 }
 smx_rdv_t SIMIX_rdv_create(const char *name)
@@ -58,7 +59,7 @@ smx_rdv_t SIMIX_rdv_create(const char *name)
     rdv->done_comm_fifo = xbt_fifo_new();
     rdv->permanent_receiver=NULL;
 
-    XBT_DEBUG("Creating a mailbox at %p with name %s\n", rdv, name);
+    XBT_DEBUG("Creating a mailbox at %p with name %s", rdv, name);
 
     if (rdv->name)
       xbt_dict_set(rdv_points, rdv->name, rdv, NULL);
@@ -66,7 +67,7 @@ smx_rdv_t SIMIX_rdv_create(const char *name)
   return rdv;
 }
 
-void SIMIX_pre_rdv_destroy(smx_simcall_t simcall, smx_rdv_t rdv){
+void simcall_HANDLER_rdv_destroy(smx_simcall_t simcall, smx_rdv_t rdv){
   return SIMIX_rdv_destroy(rdv);
 }
 void SIMIX_rdv_destroy(smx_rdv_t rdv)
@@ -83,7 +84,7 @@ void SIMIX_rdv_free(void *data)
   xbt_fifo_free(rdv->comm_fifo);
   xbt_fifo_free(rdv->done_comm_fifo);
 
-  xbt_free(rdv);  
+  xbt_free(rdv);
 }
 
 xbt_dict_t SIMIX_get_rdv_points()
@@ -91,15 +92,12 @@ xbt_dict_t SIMIX_get_rdv_points()
   return rdv_points;
 }
 
-smx_rdv_t SIMIX_pre_rdv_get_by_name(smx_simcall_t simcall, const char *name){
-  return SIMIX_rdv_get_by_name(name);
-}
 smx_rdv_t SIMIX_rdv_get_by_name(const char *name)
 {
   return xbt_dict_get_or_null(rdv_points, name);
 }
 
-int SIMIX_pre_rdv_comm_count_by_host(smx_simcall_t simcall, smx_rdv_t rdv, smx_host_t host){
+unsigned int simcall_HANDLER_rdv_comm_count_by_host(smx_simcall_t simcall, smx_rdv_t rdv, smx_host_t host){
   return SIMIX_rdv_comm_count_by_host(rdv, host);
 }
 int SIMIX_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host)
@@ -116,7 +114,7 @@ int SIMIX_rdv_comm_count_by_host(smx_rdv_t rdv, smx_host_t host)
   return count;
 }
 
-smx_action_t SIMIX_pre_rdv_get_head(smx_simcall_t simcall, smx_rdv_t rdv){
+smx_action_t simcall_HANDLER_rdv_get_head(smx_simcall_t simcall, smx_rdv_t rdv){
   return SIMIX_rdv_get_head(rdv);
 }
 smx_action_t SIMIX_rdv_get_head(smx_rdv_t rdv)
@@ -124,7 +122,7 @@ smx_action_t SIMIX_rdv_get_head(smx_rdv_t rdv)
   return xbt_fifo_get_item_content(xbt_fifo_get_first_item(rdv->comm_fifo));
 }
 
-smx_process_t SIMIX_pre_rdv_get_receiver(smx_simcall_t simcall, smx_rdv_t rdv){
+smx_process_t simcall_HANDLER_rdv_get_receiver(smx_simcall_t simcall, smx_rdv_t rdv){
   return SIMIX_rdv_get_receiver(rdv);
 }
 /**
@@ -137,7 +135,7 @@ smx_process_t SIMIX_rdv_get_receiver(smx_rdv_t rdv)
   return rdv->permanent_receiver;
 }
 
-void SIMIX_pre_rdv_set_receiver(smx_simcall_t simcall, smx_rdv_t rdv,
+void simcall_HANDLER_rdv_set_receiver(smx_simcall_t simcall, smx_rdv_t rdv,
                            smx_process_t process){
   SIMIX_rdv_set_receiver(rdv, process);
 }
@@ -199,6 +197,9 @@ smx_action_t SIMIX_fifo_get_comm(xbt_fifo_t fifo, e_smx_comm_type_t type,
       xbt_fifo_remove_item(fifo, item);
       xbt_fifo_free_item(item);
       action->comm.refcount++;
+#ifdef HAVE_MC
+      action->comm.rdv_cpy = action->comm.rdv;
+#endif
       action->comm.rdv = NULL;
       return action;
     }
@@ -286,9 +287,6 @@ smx_action_t SIMIX_comm_new(e_smx_comm_type_t type)
   return act;
 }
 
-void SIMIX_pre_comm_destroy(smx_simcall_t simcall, smx_action_t action){
-  SIMIX_comm_destroy(action);
-}
 /**
  *  \brief Destroy a communicate action
  *  \param action The communicate action to be destroyed
@@ -337,40 +335,42 @@ void SIMIX_comm_destroy_internal_actions(smx_action_t action)
 #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);
+    surf_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);
+    surf_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);
+    surf_action_unref(action->comm.dst_timeout);
     action->comm.dst_timeout = NULL;
   }
 }
 
-void SIMIX_pre_comm_send(smx_simcall_t simcall, smx_rdv_t rdv,
+void simcall_HANDLER_comm_send(smx_simcall_t simcall, smx_process_t src, 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,
+  smx_action_t comm = SIMIX_comm_isend(src, rdv, task_size, rate,
+                                      src_buff, src_buff_size, match_fun, NULL, copy_data_fun,
                                       data, 0);
-  simcall->mc_value = 0;
-  SIMIX_pre_comm_wait(simcall, comm, timeout);
+  SIMCALL_SET_MC_VALUE(simcall, 0);
+  simcall_HANDLER_comm_wait(simcall, comm, timeout);
 }
-smx_action_t SIMIX_pre_comm_isend(smx_simcall_t simcall, smx_rdv_t rdv,
+smx_action_t simcall_HANDLER_comm_isend(smx_simcall_t simcall, smx_process_t src, 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 (*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);
+  return SIMIX_comm_isend(src, rdv, task_size, rate, src_buff,
+                         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,
@@ -378,10 +378,11 @@ 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)
 {
-  XBT_DEBUG("send from %p\n", rdv);
+  XBT_DEBUG("send from %p", 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);
@@ -400,16 +401,15 @@ smx_action_t SIMIX_comm_isend(smx_process_t src_proc, smx_rdv_t rdv,
       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));
+      XBT_DEBUG("pushing a message into the permanent receive fifo %p, comm %p", rdv, &(other_action->comm));
 
     }else{
       SIMIX_rdv_push(rdv, this_action);
     }
   } else {
-    XBT_DEBUG("Receive already pushed\n");
+    XBT_DEBUG("Receive already pushed");
 
     SIMIX_comm_destroy(this_action);
     --smx_total_comms; // this creation was a pure waste
@@ -439,37 +439,47 @@ 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;
-    return other_action;
+    return (detached ? NULL : 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){
+void simcall_HANDLER_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);
-  simcall->mc_value = 0;
-  SIMIX_pre_comm_wait(simcall, comm, timeout);
+                                      dst_buff_size, match_fun, copy_data_fun, data, rate);
+  SIMCALL_SET_MC_VALUE(simcall, 0);
+  simcall_HANDLER_comm_wait(simcall, comm, timeout);
 }
-smx_action_t SIMIX_pre_comm_irecv(smx_simcall_t simcall, smx_rdv_t rdv,
+
+smx_action_t simcall_HANDLER_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){
+                                  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);
+                         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 *data)
+                              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);
+  XBT_DEBUG("recv from %p %p", rdv, rdv->comm_fifo);
   smx_action_t this_action = SIMIX_comm_new(SIMIX_COMM_RECEIVE);
 
   smx_action_t other_action;
@@ -478,27 +488,23 @@ smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
   //int already_received=0;
   if(rdv->permanent_receiver && xbt_fifo_size(rdv->done_comm_fifo)!=0){
 
-    XBT_DEBUG("We have a comm that has probably already been received, trying to match it, to skip the communication\n");
+    XBT_DEBUG("We have a comm that has probably already been received, trying to match it, to skip the communication");
     //find a match in the already received fifo
     other_action = SIMIX_fifo_get_comm(rdv->done_comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
     //if not found, assume the receiver came first, register it to the mailbox in the classical way
     if (!other_action)  {
-      XBT_DEBUG("We have messages in the permanent receive list, but not the one we are looking for, pushing request into fifo\n");
+      XBT_DEBUG("We have messages in the permanent receive list, but not the one we are looking for, pushing request into fifo");
       other_action = this_action;
       SIMIX_rdv_push(rdv, this_action);
     }else{
       if(other_action->comm.surf_comm &&       SIMIX_comm_get_remains(other_action)==0.0)
       {
-        XBT_DEBUG("comm %p has been already sent, and is finished, destroy it\n",&(other_action->comm));
+        XBT_DEBUG("comm %p has been already sent, and is finished, destroy it",&(other_action->comm));
         other_action->state = SIMIX_DONE;
         other_action->comm.type = SIMIX_COMM_DONE;
         other_action->comm.rdv = NULL;
-        //SIMIX_comm_destroy(this_action);
-        //--smx_total_comms; // this creation was a pure waste
-        //already_received=1;
-        //other_action->comm.refcount--;
       }/*else{
-         XBT_DEBUG("Not yet finished, we have to wait %d\n", xbt_fifo_size(rdv->comm_fifo));
+         XBT_DEBUG("Not yet finished, we have to wait %d", xbt_fifo_size(rdv->comm_fifo));
          }*/
       other_action->comm.refcount--;
       SIMIX_comm_destroy(this_action);
@@ -514,7 +520,7 @@ smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
     other_action = SIMIX_fifo_get_comm(rdv->comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
 
     if (!other_action) {
-      XBT_DEBUG("Receive pushed first %d\n", xbt_fifo_size(rdv->comm_fifo));
+      XBT_DEBUG("Receive pushed first %d", xbt_fifo_size(rdv->comm_fifo));
       other_action = this_action;
       SIMIX_rdv_push(rdv, this_action);
     } else {
@@ -533,7 +539,12 @@ smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
   other_action->comm.dst_buff_size = dst_buff_size;
   other_action->comm.dst_data = data;
 
+  if (rate != -1.0 &&
+      (other_action->comm.rate == -1.0 || rate < other_action->comm.rate))
+    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
@@ -550,30 +561,37 @@ smx_action_t SIMIX_comm_irecv(smx_process_t dst_proc, smx_rdv_t rdv,
   return other_action;
 }
 
-smx_action_t SIMIX_pre_comm_iprobe(smx_simcall_t simcall, smx_rdv_t rdv,
-                                   int src, int tag,
+smx_action_t simcall_HANDLER_comm_iprobe(smx_simcall_t simcall, smx_rdv_t rdv,
+                                   int type, int src, int tag,
                                    int (*match_fun)(void *, void *, smx_action_t),
                                    void *data){
-  return SIMIX_comm_iprobe(simcall->issuer, rdv, src, tag, match_fun, data);
+  return SIMIX_comm_iprobe(simcall->issuer, rdv, type, src, tag, match_fun, data);
 }
 
-smx_action_t SIMIX_comm_iprobe(smx_process_t dst_proc, smx_rdv_t rdv, int src,
+smx_action_t SIMIX_comm_iprobe(smx_process_t dst_proc, smx_rdv_t rdv, int type, int src,
                               int tag, int (*match_fun)(void *, void *, smx_action_t), void *data)
 {
-  XBT_DEBUG("iprobe from %p %p\n", rdv, rdv->comm_fifo);
-  smx_action_t this_action = SIMIX_comm_new(SIMIX_COMM_RECEIVE);
-
+  XBT_DEBUG("iprobe from %p %p", rdv, rdv->comm_fifo);
+  smx_action_t this_action;
+  int smx_type;
+  if(type == 1){
+    this_action=SIMIX_comm_new(SIMIX_COMM_SEND);
+    smx_type = SIMIX_COMM_RECEIVE;
+  } else{
+    this_action=SIMIX_comm_new(SIMIX_COMM_RECEIVE);
+    smx_type = SIMIX_COMM_SEND;
+  } 
   smx_action_t other_action=NULL;
   if(rdv->permanent_receiver && xbt_fifo_size(rdv->done_comm_fifo)!=0){
     //find a match in the already received fifo
-      XBT_DEBUG("first try in the perm recv mailbox \n");
+      XBT_DEBUG("first try in the perm recv mailbox");
 
-    other_action = SIMIX_fifo_probe_comm(rdv->done_comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
+    other_action = SIMIX_fifo_probe_comm(rdv->done_comm_fifo, smx_type, match_fun, data, this_action);
   }
  // }else{
     if(!other_action){
-        XBT_DEBUG("second try in the other mailbox");
-        other_action = SIMIX_fifo_probe_comm(rdv->comm_fifo, SIMIX_COMM_SEND, match_fun, data, this_action);
+        XBT_DEBUG("try in the normal mailbox");
+        other_action = SIMIX_fifo_probe_comm(rdv->comm_fifo, smx_type, match_fun, data, this_action);
     }
 //  }
   if(other_action)other_action->comm.refcount--;
@@ -583,19 +601,19 @@ smx_action_t SIMIX_comm_iprobe(smx_process_t dst_proc, smx_rdv_t rdv, int src,
   return other_action;
 }
 
-void SIMIX_pre_comm_wait(smx_simcall_t simcall, smx_action_t action, double timeout)
+void simcall_HANDLER_comm_wait(smx_simcall_t simcall, smx_action_t action, double timeout)
 {
-  int idx = simcall->mc_value;
   /* the simcall may be a wait, a send or a recv */
   surf_action_t sleep;
 
   /* Associate this simcall to the wait action */
-  XBT_DEBUG("SIMIX_pre_comm_wait, %p", action);
+  XBT_DEBUG("simcall_HANDLER_comm_wait, %p", action);
 
   xbt_fifo_push(action->simcalls, simcall);
   simcall->issuer->waiting_action = action;
 
   if (MC_is_active()) {
+    int idx = SIMCALL_GET_MC_VALUE(simcall);
     if (idx == 0) {
       action->state = SIMIX_DONE;
     } else {
@@ -619,8 +637,8 @@ void SIMIX_pre_comm_wait(smx_simcall_t simcall, smx_action_t action, double time
   if (action->state != SIMIX_WAITING && action->state != SIMIX_RUNNING) {
     SIMIX_comm_finish(action);
   } else { /* if (timeout >= 0) { we need a surf sleep action even when there is no timeout, otherwise surf won't tell us when the host fails */
-    sleep = surf_workstation_model->extension.workstation.sleep(simcall->issuer->smx_host, timeout);
-    surf_workstation_model->action_data_set(sleep, action);
+    sleep = surf_workstation_sleep(simcall->issuer->smx_host, timeout);
+    surf_action_set_data(sleep, action);
 
     if (simcall->issuer == action->comm.src_proc)
       action->comm.src_timeout = sleep;
@@ -629,7 +647,7 @@ void SIMIX_pre_comm_wait(smx_simcall_t simcall, smx_action_t action, double time
   }
 }
 
-void SIMIX_pre_comm_test(smx_simcall_t simcall, smx_action_t action)
+void simcall_HANDLER_comm_test(smx_simcall_t simcall, smx_action_t action)
 {
   if(MC_is_active()){
     simcall_comm_test__set__result(simcall, action->comm.src_proc && action->comm.dst_proc);
@@ -652,14 +670,14 @@ void SIMIX_pre_comm_test(smx_simcall_t simcall, smx_action_t action)
   }
 }
 
-void SIMIX_pre_comm_testany(smx_simcall_t simcall, xbt_dynar_t actions)
+void simcall_HANDLER_comm_testany(smx_simcall_t simcall, xbt_dynar_t actions)
 {
-  int idx = simcall->mc_value;
   unsigned int cursor;
   smx_action_t action;
   simcall_comm_testany__set__result(simcall, -1);
 
   if (MC_is_active()){
+    int idx = SIMCALL_GET_MC_VALUE(simcall);
     if(idx == -1){
       SIMIX_simcall_answer(simcall);
     }else{
@@ -683,13 +701,13 @@ void SIMIX_pre_comm_testany(smx_simcall_t simcall, xbt_dynar_t actions)
   SIMIX_simcall_answer(simcall);
 }
 
-void SIMIX_pre_comm_waitany(smx_simcall_t simcall, xbt_dynar_t actions)
+void simcall_HANDLER_comm_waitany(smx_simcall_t simcall, xbt_dynar_t actions)
 {
-  int idx = simcall->mc_value;
   smx_action_t action;
   unsigned int cursor = 0;
 
   if (MC_is_active()){
+    int idx = SIMCALL_GET_MC_VALUE(simcall);
     action = xbt_dynar_get_as(actions, idx, smx_action_t);
     xbt_fifo_push(action->simcalls, simcall);
     simcall_comm_waitany__set__result(simcall, idx);
@@ -725,7 +743,7 @@ void SIMIX_waitany_remove_simcall_from_actions(smx_simcall_t simcall)
  *  \brief Starts the simulation of a communication action.
  *  \param action the communication action
  */
-XBT_INLINE void SIMIX_comm_start(smx_action_t action)
+static XBT_INLINE void SIMIX_comm_start(smx_action_t action)
 {
   /* If both the sender and the receiver are already there, start the communication */
   if (action->state == SIMIX_READY) {
@@ -736,15 +754,16 @@ XBT_INLINE void SIMIX_comm_start(smx_action_t action)
     XBT_DEBUG("Starting communication %p from '%s' to '%s'", action,
               SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
 
-    action->comm.surf_comm = surf_workstation_model->extension.workstation.
-      communicate(sender, receiver, action->comm.task_size, action->comm.rate);
+    action->comm.surf_comm = surf_workstation_model_communicate(surf_workstation_model,
+                                                                   sender, receiver,
+                                                                   action->comm.task_size, action->comm.rate);
 
-    surf_workstation_model->action_data_set(action->comm.surf_comm, action);
+    surf_action_set_data(action->comm.surf_comm, action);
 
     action->state = SIMIX_RUNNING;
 
     /* If a link is failed, detect it immediately */
-    if (surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+    if (surf_action_get_state(action->comm.surf_comm) == SURF_ACTION_FAILED) {
       XBT_DEBUG("Communication from '%s' to '%s' failed to start because of a link failure",
                 SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
       action->state = SIMIX_LINK_FAILURE;
@@ -764,7 +783,7 @@ XBT_INLINE void SIMIX_comm_start(smx_action_t action)
         XBT_DEBUG("The communication is suspended on startup because dst (%s:%s) were suspended since it initiated the communication",
                   SIMIX_host_get_name(action->comm.dst_proc->smx_host), action->comm.dst_proc->name);
 
-      surf_workstation_model->suspend(action->comm.surf_comm);
+      surf_action_suspend(action->comm.surf_comm);
 
     }
   }
@@ -779,12 +798,16 @@ void SIMIX_comm_finish(smx_action_t action)
   unsigned int destroy_count = 0;
   smx_simcall_t simcall;
 
+
   while ((simcall = xbt_fifo_shift(action->simcalls))) {
 
     /* If a waitany simcall is waiting for this action to finish, then remove
        it from the other actions in the waitany list. Afterwards, get the
        position of the actual action in the waitany dynar and
        return it as the result of the simcall */
+
+    if (simcall->call == SIMCALL_NONE) //FIXME: maybe a better way to handle this case
+      continue; // if process handling comm is killed
     if (simcall->call == SIMCALL_COMM_WAITANY) {
       SIMIX_waitany_remove_simcall_from_actions(simcall);
       if (!MC_is_active())
@@ -870,8 +893,7 @@ void SIMIX_comm_finish(smx_action_t action)
       }
     }
 
-    if (surf_workstation_model->extension.
-        workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+    if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
       simcall->issuer->context->iwannadie = 1;
     }
 
@@ -903,19 +925,19 @@ void SIMIX_post_comm(smx_action_t action)
 {
   /* Update action state */
   if (action->comm.src_timeout &&
-      surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_DONE)
+      surf_action_get_state(action->comm.src_timeout) == SURF_ACTION_DONE)
     action->state = SIMIX_SRC_TIMEOUT;
   else if (action->comm.dst_timeout &&
-           surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_DONE)
+         surf_action_get_state(action->comm.dst_timeout) == SURF_ACTION_DONE)
     action->state = SIMIX_DST_TIMEOUT;
   else if (action->comm.src_timeout &&
-           surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_FAILED)
+         surf_action_get_state(action->comm.src_timeout) == SURF_ACTION_FAILED)
     action->state = SIMIX_SRC_HOST_FAILURE;
   else if (action->comm.dst_timeout &&
-           surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_FAILED)
+      surf_action_get_state(action->comm.dst_timeout) == SURF_ACTION_FAILED)
     action->state = SIMIX_DST_HOST_FAILURE;
   else if (action->comm.surf_comm &&
-           surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+         surf_action_get_state(action->comm.surf_comm) == SURF_ACTION_FAILED) {
     XBT_DEBUG("Puta madre. Surf says that the link broke");
     action->state = SIMIX_LINK_FAILURE;
   } else
@@ -927,22 +949,13 @@ void SIMIX_post_comm(smx_action_t action)
   /* destroy the surf actions associated with the Simix communication */
   SIMIX_comm_destroy_internal_actions(action);
 
-  /* remove the communication action from the list of pending communications
-   * of both processes (if they still exist) */
-  if (action->comm.src_proc) {
-    xbt_fifo_remove(action->comm.src_proc->comms, action);
-  }
-  if (action->comm.dst_proc) {
-    xbt_fifo_remove(action->comm.dst_proc->comms, action);
-  }
-
   /* if there are simcalls associated with the action, then answer them */
   if (xbt_fifo_size(action->simcalls)) {
     SIMIX_comm_finish(action);
   }
 }
 
-void SIMIX_pre_comm_cancel(smx_simcall_t simcall, smx_action_t action){
+void simcall_HANDLER_comm_cancel(smx_simcall_t simcall, smx_action_t action){
   SIMIX_comm_cancel(action);
 }
 void SIMIX_comm_cancel(smx_action_t action)
@@ -956,7 +969,7 @@ void SIMIX_comm_cancel(smx_action_t action)
   else if (!MC_is_active() /* when running the MC there are no surf actions */
            && (action->state == SIMIX_READY || action->state == SIMIX_RUNNING)) {
 
-    surf_workstation_model->action_cancel(action->comm.surf_comm);
+    surf_action_cancel(action->comm.surf_comm);
   }
 }
 
@@ -964,7 +977,7 @@ void SIMIX_comm_suspend(smx_action_t action)
 {
   /*FIXME: shall we suspend also the timeout actions? */
   if (action->comm.surf_comm)
-    surf_workstation_model->suspend(action->comm.surf_comm);
+    surf_action_suspend(action->comm.surf_comm);
   /* in the other case, the action will be suspended on creation, in SIMIX_comm_start() */
 }
 
@@ -972,14 +985,14 @@ void SIMIX_comm_resume(smx_action_t action)
 {
   /*FIXME: check what happen with the timeouts */
   if (action->comm.surf_comm)
-    surf_workstation_model->resume(action->comm.surf_comm);
+    surf_action_resume(action->comm.surf_comm);
   /* in the other case, the action were not really suspended yet, see SIMIX_comm_suspend() and SIMIX_comm_start() */
 }
 
 
 /************* Action Getters **************/
 
-double SIMIX_pre_comm_get_remains(smx_simcall_t simcall, smx_action_t action){
+double simcall_HANDLER_comm_get_remains(smx_simcall_t simcall, smx_action_t action){
   return SIMIX_comm_get_remains(action);
 }
 /**
@@ -997,7 +1010,7 @@ double SIMIX_comm_get_remains(smx_action_t action)
   switch (action->state) {
 
   case SIMIX_RUNNING:
-    remains = surf_workstation_model->get_remains(action->comm.surf_comm);
+    remains = surf_action_get_remains(action->comm.surf_comm);
     break;
 
   case SIMIX_WAITING:
@@ -1012,7 +1025,7 @@ double SIMIX_comm_get_remains(smx_action_t action)
   return remains;
 }
 
-e_smx_state_t SIMIX_pre_comm_get_state(smx_simcall_t simcall, smx_action_t action){
+e_smx_state_t simcall_HANDLER_comm_get_state(smx_simcall_t simcall, smx_action_t action){
   return SIMIX_comm_get_state(action);
 }
 e_smx_state_t SIMIX_comm_get_state(smx_action_t action)
@@ -1020,7 +1033,7 @@ e_smx_state_t SIMIX_comm_get_state(smx_action_t action)
   return action->state;
 }
 
-void* SIMIX_pre_comm_get_src_data(smx_simcall_t simcall, smx_action_t action){
+void* simcall_HANDLER_comm_get_src_data(smx_simcall_t simcall, smx_action_t action){
   return SIMIX_comm_get_src_data(action);
 }
 /**
@@ -1033,7 +1046,7 @@ void* SIMIX_comm_get_src_data(smx_action_t action)
   return action->comm.src_data;
 }
 
-void* SIMIX_pre_comm_get_dst_data(smx_simcall_t simcall, smx_action_t action){
+void* simcall_HANDLER_comm_get_dst_data(smx_simcall_t simcall, smx_action_t action){
   return SIMIX_comm_get_dst_data(action);
 }
 /**
@@ -1046,7 +1059,7 @@ void* SIMIX_comm_get_dst_data(smx_action_t action)
   return action->comm.dst_data;
 }
 
-smx_process_t SIMIX_pre_comm_get_src_proc(smx_simcall_t simcall, smx_action_t action){
+smx_process_t simcall_HANDLER_comm_get_src_proc(smx_simcall_t simcall, smx_action_t action){
   return SIMIX_comm_get_src_proc(action);
 }
 smx_process_t SIMIX_comm_get_src_proc(smx_action_t action)
@@ -1054,7 +1067,7 @@ smx_process_t SIMIX_comm_get_src_proc(smx_action_t action)
   return action->comm.src_proc;
 }
 
-smx_process_t SIMIX_pre_comm_get_dst_proc(smx_simcall_t simcall, smx_action_t action){
+smx_process_t simcall_HANDLER_comm_get_dst_proc(smx_simcall_t simcall, smx_action_t action){
   return SIMIX_comm_get_dst_proc(action);
 }
 smx_process_t SIMIX_comm_get_dst_proc(smx_action_t action)
@@ -1063,18 +1076,23 @@ smx_process_t SIMIX_comm_get_dst_proc(smx_action_t action)
 }
 
 #ifdef HAVE_LATENCY_BOUND_TRACKING
+int simcall_HANDLER_comm_is_latency_bounded(smx_simcall_t simcall, smx_action_t action)
+{
+  return SIMIX_comm_is_latency_bounded(action);
+}
+
 /**
  *  \brief verify if communication is latency bounded
  *  \param comm The communication
  */
-XBT_INLINE int SIMIX_comm_is_latency_bounded(smx_action_t action)
+int SIMIX_comm_is_latency_bounded(smx_action_t action)
 {
   if(!action){
     return 0;
   }
   if (action->comm.surf_comm){
     XBT_DEBUG("Getting latency limited for surf_action (%p)", action->comm.surf_comm);
-    action->latency_limited = surf_workstation_model->get_latency_limited(action->comm.surf_comm);
+    action->latency_limited = surf_network_action_get_latency_limited(action->comm.surf_comm);
     XBT_DEBUG("Action limited is %d", action->latency_limited);
   }
   return action->latency_limited;
@@ -1137,8 +1155,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) */