Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into hypervisor
authoralebre <adrien.lebre@inria.fr>
Tue, 2 Apr 2013 13:26:47 +0000 (15:26 +0200)
committeralebre <adrien.lebre@inria.fr>
Tue, 2 Apr 2013 13:26:47 +0000 (15:26 +0200)
15 files changed:
1  2 
buildtools/Cmake/DefinePackages.cmake
include/msg/msg.h
include/simgrid/platf.h
include/simgrid/simix.h
include/xbt/ex.h
src/simdag/sd_global.c
src/simgrid/sg_config.c
src/simix/smx_global.c
src/simix/smx_network.c
src/simix/smx_process.c
src/simix/smx_smurf_private.h
src/simix/smx_user.c
src/surf/network.c
src/surf/storage.c
src/surf/workstation_ptask_L07.c

@@@ -35,6 -35,8 +35,8 @@@ set(EXTRA_DIS
    src/simix/smx_smurf_private.h
    src/simix/smx_synchro_private.h
    src/smpi/README
+   src/smpi/colls/COPYRIGHTS
+   src/smpi/colls/colls.h
    src/smpi/private.h
    src/smpi/smpi_mpi_dt_private.h
    src/surf/cpu_ti_private.h
@@@ -107,6 -109,73 +109,73 @@@ set(SMPI_SR
    src/smpi/smpi_mpi_dt.c
    src/smpi/smpi_pmpi.c
    src/smpi/smpi_replay.c
+   #src/smpi/colls/allgather-2dmesh.c
+   #src/smpi/colls/allgather-3dmesh.c
+   #src/smpi/colls/allgather-bruck.c
+   src/smpi/colls/allgather-GB.c
+   src/smpi/colls/allgather-loosely-lr.c
+   src/smpi/colls/allgather-lr.c
+   src/smpi/colls/allgather-NTSLR.c
+   src/smpi/colls/allgather-NTSLR-NB.c
+   src/smpi/colls/allgather-pair.c
+   src/smpi/colls/allgather-rdb.c
+   src/smpi/colls/allgather-RDB.c
+   src/smpi/colls/allgather-rhv.c
+   src/smpi/colls/allgather-ring.c
+   src/smpi/colls/allgather-SMP-NTS.c
+   src/smpi/colls/allgather-smp-simple.c
+   src/smpi/colls/allgather-SMP-simple.c
+   src/smpi/colls/allgather-spreading-simple.c
+   src/smpi/colls/allreduce-lr.c
+   src/smpi/colls/allreduce-NTS.c
+   src/smpi/colls/allreduce-rab1.c
+   src/smpi/colls/allreduce-rab2.c
+   #src/smpi/colls/allreduce-rab-rdb.c
+   #src/smpi/colls/allreduce-rab-reduce-scatter.c
+   src/smpi/colls/allreduce-rab-rsag.c
+   src/smpi/colls/allreduce-rdb.c
+   src/smpi/colls/allreduce-redbcast.c
+   src/smpi/colls/allreduce-smp-binomial.c
+   #src/smpi/colls/allreduce-smp-binomial-pipeline.c
+   src/smpi/colls/allreduce-smp-rdb.c
+   src/smpi/colls/allreduce-smp-rsag.c
+   src/smpi/colls/allreduce-smp-rsag-lr.c
+   src/smpi/colls/allreduce-smp-rsag-rab.c
+   src/smpi/colls/alltoall-2dmesh.c
+   src/smpi/colls/alltoall-3dmesh.c
+   #src/smpi/colls/alltoall-bruck.c
+   src/smpi/colls/alltoall-pair.c
+   src/smpi/colls/alltoall-pair-light-barrier.c
+   src/smpi/colls/alltoall-pair-mpi-barrier.c
+   src/smpi/colls/alltoall-pair-one-barrier.c
+   src/smpi/colls/alltoall-rdb.c
+   src/smpi/colls/alltoall-ring.c
+   src/smpi/colls/alltoall-ring-light-barrier.c
+   src/smpi/colls/alltoall-ring-mpi-barrier.c
+   src/smpi/colls/alltoall-ring-one-barrier.c
+   src/smpi/colls/alltoall-simple.c
+   src/smpi/colls/bcast-arrival-nb.c
+   src/smpi/colls/bcast-arrival-pattern-aware.c
+   src/smpi/colls/bcast-arrival-pattern-aware-wait.c
+   src/smpi/colls/bcast-arrival-scatter.c
+   src/smpi/colls/bcast-binomial-tree.c
+   src/smpi/colls/bcast-flattree.c
+   src/smpi/colls/bcast-flattree-pipeline.c
+   src/smpi/colls/bcast-NTSB.c
+   src/smpi/colls/bcast-NTSL.c
+   src/smpi/colls/bcast-NTSL-Isend.c
+   src/smpi/colls/bcast-scatter-LR-allgather.c
+   src/smpi/colls/bcast-scatter-rdb-allgather.c
+   src/smpi/colls/bcast-SMP-binary.c
+   src/smpi/colls/bcast-SMP-binomial.c
+   src/smpi/colls/bcast-SMP-linear.c
+   src/smpi/colls/bcast-TSB.c
+   src/smpi/colls/reduce-arrival-pattern-aware.c
+   src/smpi/colls/reduce-binomial.c
+   src/smpi/colls/reduce-flat-tree.c
+   src/smpi/colls/reduce-NTSL.c
+   src/smpi/colls/reduce-scatter-gather.c
+   src/smpi/colls/star-reduction.c
    )
  
  if(SMPI_F2C)
@@@ -216,7 -285,6 +285,7 @@@ set(SURF_SR
    src/surf/trace_mgr.c
    src/surf/workstation.c
    src/surf/workstation_ptask_L07.c
 +  src/surf/vm_workstation.c
    src/xbt/xbt_sg_stubs.c
    )
  
@@@ -234,7 -302,6 +303,7 @@@ set(SIMIX_SR
    src/simix/smx_smurf.c
    src/simix/smx_synchro.c
    src/simix/smx_user.c
 +  src/simix/smx_vm.c
    )
  
  set(SIMGRID_SRC
@@@ -425,6 -492,7 +494,7 @@@ set(MC_SR
    src/mc/mc_request.c
    src/mc/mc_state.c
    src/mc/memory_map.c
+   src/mc/mc_pair.c
    )
  
  set(headers_to_install
@@@ -554,6 -622,13 +624,13 @@@ else(
      )
  endif()
  
+ if(enable_smpi)
+   set(simgrid_sources
+     ${simgrid_sources}
+     ${SMPI_SRC}
+     )
+ endif()
  if(${HAVE_TRACING})
    set(simgrid_sources
      ${simgrid_sources}
@@@ -643,6 -718,7 +720,7 @@@ set(DOC_SOURCE
    doc/doxygen/module-sd.doc
    doc/doxygen/module-simix.doc
    doc/doxygen/module-surf.doc
+   doc/doxygen/module-smpi.doc
    doc/doxygen/module-trace.doc
    doc/doxygen/module-xbt.doc
    doc/doxygen/modules.doc
diff --combined include/msg/msg.h
@@@ -95,8 -95,7 +95,8 @@@ XBT_PUBLIC(int) MSG_get_host_msgload(ms
  /* int MSG_get_msgload(void); This function lacks specification; discard it */
  XBT_PUBLIC(double) MSG_get_host_speed(msg_host_t h);
  XBT_PUBLIC(int) MSG_host_is_avail(msg_host_t h);
 -XBT_PUBLIC(void) __MSG_host_destroy(msg_host_priv_t host);
 +XBT_PUBLIC(void) __MSG_host_priv_free(msg_host_priv_t priv);
 +XBT_PUBLIC(void) __MSG_host_destroy(msg_host_t host);
  
  /*property handlers*/
  XBT_PUBLIC(xbt_dict_t) MSG_host_get_properties(msg_host_t host);
@@@ -113,9 -112,6 +113,9 @@@ XBT_PUBLIC(msg_host_t) MSG_get_host_by_
  XBT_PUBLIC(xbt_dynar_t) MSG_hosts_as_dynar(void);
  XBT_PUBLIC(int) MSG_get_host_number(void);
  
 +XBT_PUBLIC(void) MSG_host_get_params(msg_host_t ind_pm, ws_params_t params);
 +XBT_PUBLIC(void) MSG_host_set_params(msg_host_t ind_pm, ws_params_t params);
 +
  /************************** Process handling *********************************/
  XBT_PUBLIC(msg_process_t) MSG_process_create(const char *name,
                                             xbt_main_func_t code,
@@@ -304,7 -300,7 +304,7 @@@ XBT_PUBLIC(msg_error_t
      MSG_mailbox_put_with_timeout(msg_mailbox_t mailbox, msg_task_t task,
                               double timeout);
  
void MSG_mailbox_set_async(const char *alias);
XBT_PUBLIC(void) MSG_mailbox_set_async(const char *alias);
  
  
  /************************** Action handling **********************************/
@@@ -366,38 -362,29 +366,38 @@@ XBT_PUBLIC(int) MSG_get_channel_number(
   *
   */
  /* This function should not be called directly, but rather from MSG_vm_start_from_template that does not exist yet*/
 -XBT_PUBLIC(msg_vm_t) MSG_vm_start(msg_host_t location, const char *name, int coreAmount);
 +
 +// TODO add VDI later
 +XBT_PUBLIC(msg_vm_t) MSG_vm_create_core(msg_host_t location, const char *name);
 +XBT_PUBLIC(msg_vm_t) MSG_vm_create(msg_host_t ind_pm, const char *name,
 +    int core_nb, int mem_cap, int net_cap, char *disk_path, int disk_size);
 +
 +XBT_PUBLIC(void) MSG_vm_start(msg_vm_t);
  
  XBT_PUBLIC(int) MSG_vm_is_suspended(msg_vm_t);
  XBT_PUBLIC(int) MSG_vm_is_running(msg_vm_t);
  
 -XBT_PUBLIC(void) MSG_vm_bind(msg_vm_t vm, msg_process_t process);
 -XBT_PUBLIC(void) MSG_vm_unbind(msg_vm_t vm, msg_process_t process); // simple wrapper over process_kill
 +XBT_PUBLIC(const char*) MSG_vm_get_name(msg_vm_t);
  
  XBT_PUBLIC(void) MSG_vm_migrate(msg_vm_t vm, msg_host_t destination);
  
 +/* Suspend the execution of the VM, but keep its state on memory. */
  XBT_PUBLIC(void) MSG_vm_suspend(msg_vm_t vm);
 -  // \forall p in VM, MSG_process_suspend(p) // Freeze the processes
 +XBT_PUBLIC(void) MSG_vm_resume(msg_vm_t vm);
  
 -XBT_PUBLIC(void) MSG_vm_resume(msg_vm_t vm);  // Simulate the fact of reading the processes from disk and resuming them
 -  // \forall p in VM, MSG_process_resume(p) // unfreeze them
 +/* Save the VM state to a disk. */
 +XBT_PUBLIC(void) MSG_vm_save(msg_vm_t vm);
 +XBT_PUBLIC(void) MSG_vm_restore(msg_vm_t vm);
  
 -XBT_PUBLIC(void) MSG_vm_shutdown(msg_vm_t vm); // killall
 -
 -XBT_PUBLIC(void) MSG_vm_reboot(msg_vm_t vm);
 +/* Shutdown the guest operating system. */
 +XBT_PUBLIC(void) MSG_vm_shutdown(msg_vm_t vm);
  
  XBT_PUBLIC(void) MSG_vm_destroy(msg_vm_t vm);
  
 -XBT_PUBLIC(xbt_dynar_t) MSG_vms_as_dynar(void);
 +msg_host_t MSG_vm_get_pm(msg_vm_t vm);
 +
 +/* TODO: do we need this? */
 +// XBT_PUBLIC(xbt_dynar_t) MSG_vms_as_dynar(void);
  
  /*
  void* MSG_process_get_property(msg_process_t, char* key)
diff --combined include/simgrid/platf.h
@@@ -41,39 -41,6 +41,39 @@@ typedef enum 
  } e_surf_process_on_failure_t;
  
  
 +/* FIXME: Where should the VM state be defined? */
 +typedef enum {
 +  /* created, but not yet started */
 +  SURF_VM_STATE_CREATED,
 +
 +  SURF_VM_STATE_RUNNING,
 +  // SURF_VM_STATE_MIGRATING,
 +
 +  /* Suspend/resume does not involve disk I/O, so we assume there is no transition states. */
 +  SURF_VM_STATE_SUSPENDED,
 +
 +  /* Save/restore involves disk I/O, so there should be transition states. */
 +  SURF_VM_STATE_SAVING,
 +  SURF_VM_STATE_SAVED,
 +  SURF_VM_STATE_RESTORING,
 +
 +} e_surf_vm_state_t;
 +
 +typedef struct ws_params {
 +  int ncpus;
 +  long ramsize;
 +  int overcommit;
 +
 +  /* The size of other states than memory pages, which is out-of-scope of dirty
 +   * page tracking. */
 +  long devsize;
 +  int skip_stage2;
 +  double max_downtime;
 +
 +  double dp_rate;
 +  double dp_cap;
 +} s_ws_params_t, *ws_params_t;
 +
  typedef struct tmgr_trace *tmgr_trace_t; /**< Opaque structure defining an availability trace */
  
  /** opaque structure defining a event generator for availability based on a probability distribution */
@@@ -220,6 -187,9 +220,9 @@@ typedef struct s_sg_platf_cluster_cbar
    double lat;
    double bb_bw;
    double bb_lat;
+   double loopback_bw;
+   double loopback_lat;
+   double limiter_link;
    const char* router_id;
    e_surf_link_sharing_policy_t sharing_policy;
    e_surf_link_sharing_policy_t bb_sharing_policy;
diff --combined include/simgrid/simix.h
@@@ -15,8 -15,6 +15,8 @@@
  #include "xbt/parmap.h"
  #include "xbt/swag.h"
  
 +#include "simgrid/platf.h" // ws_params_t
 +
  SG_BEGIN_DECL()
  
  /**************************** Scalar Values **********************************/
@@@ -321,22 -319,7 +321,22 @@@ XBT_PUBLIC(double) simcall_host_executi
  XBT_PUBLIC(e_smx_state_t) simcall_host_execution_get_state(smx_action_t execution);
  XBT_PUBLIC(void) simcall_host_execution_set_priority(smx_action_t execution, double priority);
  XBT_PUBLIC(e_smx_state_t) simcall_host_execution_wait(smx_action_t execution);
 -
 +XBT_PUBLIC(void) simcall_host_get_params(smx_host_t vm, ws_params_t param);
 +XBT_PUBLIC(void) simcall_host_set_params(smx_host_t vm, ws_params_t param);
 +
 +/******************************* VM simcalls ********************************/
 +// Create the vm_workstation at the SURF level
 +XBT_PUBLIC(void*) simcall_vm_create(const char *name, smx_host_t host);
 +XBT_PUBLIC(int) simcall_vm_get_state(smx_host_t vm);
 +XBT_PUBLIC(void) simcall_vm_start(smx_host_t vm);
 +XBT_PUBLIC(void) simcall_vm_migrate(smx_host_t vm, smx_host_t dst_pm);
 +XBT_PUBLIC(void *) simcall_vm_get_pm(smx_host_t vm);
 +XBT_PUBLIC(void) simcall_vm_resume(smx_host_t vm);
 +XBT_PUBLIC(void) simcall_vm_save(smx_host_t vm);
 +XBT_PUBLIC(void) simcall_vm_restore(smx_host_t vm);
 +XBT_PUBLIC(void) simcall_vm_suspend(smx_host_t vm);
 +XBT_PUBLIC(void) simcall_vm_destroy(smx_host_t vm);
 +XBT_PUBLIC(void) simcall_vm_shutdown(smx_host_t vm);
  
  /**************************** Process simcalls ********************************/
  /* Constructor and Destructor */
@@@ -495,6 -478,7 +495,7 @@@ XBT_PUBLIC(xbt_dict_t) simcall_asr_get_
  /************************** MC simcalls   **********************************/
  XBT_PUBLIC(void *) simcall_mc_snapshot(void);
  XBT_PUBLIC(int) simcall_mc_compare_snapshots(void *s1, void *s2);
+ XBT_PUBLIC(int) simcall_mc_random(void);
  
  /************************** New API simcalls **********************************/
  /* TUTORIAL: New API                                                          */
diff --combined include/xbt/ex.h
@@@ -262,8 -262,7 +262,8 @@@ typedef enum 
    thread_error,                 /**< error while [un]locking */
    host_error,                   /**< host failed */
    tracing_error,                /**< error during the simulation tracing */
 -  io_error                      /**< disk or file error */
 +  io_error,                      /**< disk or file error */
 +  vm_error                      /**< vm  error */
  } xbt_errcat_t;
  
  XBT_PUBLIC(const char *) xbt_ex_catname(xbt_errcat_t cat);
@@@ -482,6 -481,8 +482,8 @@@ XBT_PUBLIC(int) xbt_backtrace_no_malloc
  XBT_PUBLIC(void) xbt_backtrace_current(xbt_ex_t * e);
  /** @brief Display a previously captured backtrace */
  XBT_PUBLIC(void) xbt_backtrace_display(xbt_ex_t * e);
+ /** @brief Get current backtrace with libunwind */
+ XBT_PUBLIC(int) xbt_libunwind_backtrace(void *bt[XBT_BACKTRACE_SIZE], int size);
  
  #ifdef XBT_USE_DEPRECATED
  
diff --combined src/simdag/sd_global.c
@@@ -284,7 -284,6 +284,7 @@@ xbt_swag_t SD_simulate_swag(double how_
      if (elapsed_time > 0.0)
        total_time += elapsed_time;
  
 +    /* FIXME: shoud look at model_list or model_list_invoke? */
      /* let's see which tasks are done */
      xbt_dynar_foreach(model_list, iter, model) {
        while ((action = xbt_swag_extract(model->states.done_action_set))) {
@@@ -439,14 -438,15 +439,15 @@@ void SD_exit(void
    TRACE_end();
  #endif
  
-   XBT_DEBUG("Exiting Surf...");
-   surf_exit();
    xbt_free(sd_global);
    sd_global = NULL;
  
  #ifdef HAVE_JEDULE
    jedule_sd_dump();
    jedule_sd_cleanup();
+   jedule_sd_exit();
  #endif
+   XBT_DEBUG("Exiting Surf...");
+   surf_exit();
  }
diff --combined src/simgrid/sg_config.c
@@@ -21,7 -21,6 +21,7 @@@
  #include "smpi/smpi_interface.h"
  #include "mc/mc.h"
  #include "instr/instr.h"
 +#include "surf/vm_workstation_private.h"
  
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_config, surf,
                                  "About the configuration of simgrid");
@@@ -227,6 -226,48 +227,48 @@@ static void _sg_cfg_cb__weight_S(const 
    sg_weight_S_parameter = xbt_cfg_get_double(_sg_cfg_set, name);
  }
  
+ #ifdef HAVE_SMPI
+ /* callback of the mpi collectives */
+ static void _sg_cfg_cb__coll(const char *category,
+                            s_mpi_coll_description_t * table,
+                            const char *name, int pos)
+ {
+   char *val;
+   xbt_assert(_sg_init_status == 1,
+               "Cannot change the model after the initialization");
+   val = xbt_cfg_get_string(_sg_cfg_set, name);
+   if (!strcmp(val, "help")) {
+     coll_help(category, table);
+     exit(0);
+   }
+   /* New Module missing */
+   find_coll_description(table, val);
+ }
+ static void _sg_cfg_cb__coll_allgather(const char *name, int pos){
+   _sg_cfg_cb__coll("allgather", mpi_coll_allgather_description, name, pos);
+ }
+ static void _sg_cfg_cb__coll_allreduce(const char *name, int pos)
+ {
+   _sg_cfg_cb__coll("allreduce", mpi_coll_allreduce_description, name, pos);  
+ }
+ static void _sg_cfg_cb__coll_alltoall(const char *name, int pos)
+ {
+   _sg_cfg_cb__coll("alltoall", mpi_coll_alltoall_description, name, pos);  
+ }
+ static void _sg_cfg_cb__coll_bcast(const char *name, int pos)
+ {
+   _sg_cfg_cb__coll("bcast", mpi_coll_bcast_description, name, pos);  
+ }
+ static void _sg_cfg_cb__coll_reduce(const char *name, int pos)
+ {
+   _sg_cfg_cb__coll("reduce", mpi_coll_reduce_description, name, pos);  
+ }
+ #endif
  /* callback of the inclusion path */
  static void _sg_cfg_cb__surf_path(const char *name, int pos)
  {
@@@ -478,7 -519,7 +520,7 @@@ void sg_config_init(int *argc, char **a
                       _sg_cfg_cb__bandwidth_factor, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "network/weight_S",
-                      "Correction factor to apply to the weight of competing streams(default value set by network model)",
+                      "Correction factor to apply to the weight of competing streams (default value set by network model)",
                       xbt_cfgelm_double, NULL, 1, 1, /* default is set in network.c */
                       _sg_cfg_cb__weight_S, NULL);
  
                       xbt_cfgelm_int, NULL, 0, 1,
                       _mc_cfg_cb_visited, NULL);
      xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
+     /* Set file name for dot output of graph state */
+     xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
+                      "Specify the name of dot file corresponding to graph state",
+                      xbt_cfgelm_string, NULL, 0, 1,
+                      _mc_cfg_cb_dot_output, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
  #endif
  
      /* do verbose-exit */
      xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
  #endif
  
//SMPI
#ifdef HAVE_SMPI
      double default_reference_speed = 20000.0;
      xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
                       "Power of the host running the simulation (in flop/s). Used to bench the operations.",
                       NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
  
+     default_value = xbt_strdup("default");
+     xbt_cfg_register(&_sg_cfg_set, "smpi/allgather",
+                    "Which collective to use for allgather",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_allgather,
+                    NULL);
+     default_value = xbt_strdup("default");
+     xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
+                    "Which collective to use for allreduce",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_allreduce,
+                    NULL);
+     default_value = xbt_strdup("ompi");
+     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
+                    "Which collective to use for alltoall",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_alltoall,
+                    NULL);
  
-     //END SMPI
  
+     default_value = xbt_strdup("default");
+     xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
+                    "Which collective to use for bcast",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_bcast,
+                    NULL);
+     default_value = xbt_strdup("default");
+     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
+                    "Which collective to use for reduce",
+                    xbt_cfgelm_string, &default_value, 1, 1, &_sg_cfg_cb__coll_reduce,
+                    NULL);
+ #endif // HAVE_SMPI
  
      if (!surf_path) {
        /* retrieves the current directory of the        current process */
@@@ -798,9 -875,6 +876,9 @@@ void surf_config_models_setup(
    XBT_DEBUG("Call workstation_model_init");
    surf_workstation_model_description[workstation_id].model_init_preparse();
  
 +  XBT_DEBUG("Call vm_workstation_model_init");
 +  surf_vm_workstation_model_init();
 +
    XBT_DEBUG("Call storage_model_init");
    storage_id = find_model_description(surf_storage_model_description, storage_model_name);
    surf_storage_model_description[storage_id].model_init_preparse();
diff --combined src/simix/smx_global.c
@@@ -315,6 -315,7 +315,7 @@@ void SIMIX_run(void
         timer = xbt_heap_pop(simix_timers);
         if (timer->func)
           ((void (*)(void*))timer->func)(timer->args);
+        xbt_free(timer);
      }
      /* Wake up all processes waiting for a Surf action to finish */
      xbt_dynar_foreach(model_list, iter, model) {
        while ((action = xbt_swag_extract(set)))
          SIMIX_simcall_post((smx_action_t) action->data);
        set = model->states.done_action_set;
 -      while ((action = xbt_swag_extract(set)))
 -        SIMIX_simcall_post((smx_action_t) action->data);
 +
 +      while ((action = xbt_swag_extract(set))) {
 +        if (action->data == NULL)
 +          XBT_DEBUG("probably vcpu's action %p, skip", action);
 +        else
 +          SIMIX_simcall_post((smx_action_t) action->data);
 +      }
      }
  
      /* Clean processes to destroy */
      SIMIX_process_empty_trash();
  
 +
 +    XBT_DEBUG("### time %f, empty %d", time, xbt_dynar_is_empty(simix_global->process_to_run));
 +    // !(time == -1.0 && xbt_dynar_is_empty()) 
 +
 +
    } while (time != -1.0 || !xbt_dynar_is_empty(simix_global->process_to_run));
  
    if (xbt_swag_size(simix_global->process_list) != 0) {
diff --combined src/simix/smx_network.c
@@@ -337,17 -337,17 +337,17 @@@ void SIMIX_comm_destroy_internal_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);
 +    action->comm.surf_comm->model_obj->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->model_obj->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->model_obj->action_unref(action->comm.dst_timeout);
      action->comm.dst_timeout = NULL;
    }
  }
@@@ -1171,6 -1171,11 +1171,11 @@@ smx_process_t SIMIX_comm_get_dst_proc(s
  }
  
  #ifdef HAVE_LATENCY_BOUND_TRACKING
+ int SIMIX_pre_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
diff --combined src/simix/smx_process.c
@@@ -275,6 -275,10 +275,10 @@@ void SIMIX_process_create(smx_process_
      (*process)->running_ctx = xbt_new(xbt_running_ctx_t, 1);
      XBT_RUNNING_CTX_INITIALIZE((*process)->running_ctx);
  
+     if(MC_is_active()){
+       MC_ignore_heap((*process)->running_ctx, sizeof(*(*process)->running_ctx));
+     }
      /* Add properties */
      (*process)->properties = properties;
  
@@@ -685,10 -689,9 +689,10 @@@ smx_action_t SIMIX_process_sleep(smx_pr
  {
    smx_action_t action;
    smx_host_t host = process->smx_host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
  
    /* check if the host is active */
 -  if (surf_workstation_model->extension.
 +  if (ws_model->extension.
        workstation.get_state(host) != SURF_RESOURCE_ON) {
      THROWF(host_error, 0, "Host %s failed, you cannot call this function",
             sg_host_name(host));
  
    action->sleep.host = host;
    action->sleep.surf_sleep =
 -      surf_workstation_model->extension.workstation.sleep(host, duration);
 +      ws_model->extension.workstation.sleep(host, duration);
  
 -  surf_workstation_model->action_data_set(action->sleep.surf_sleep, action);
 +  ws_model->action_data_set(action->sleep.surf_sleep, action);
    XBT_DEBUG("Create sleep action %p", action);
  
    return action;
@@@ -716,13 -719,9 +720,13 @@@ void SIMIX_post_process_sleep(smx_actio
    smx_simcall_t simcall;
    e_smx_state_t state;
  
 +  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
 +  smx_host_t host = action->sleep.host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +
    while ((simcall = xbt_fifo_shift(action->simcalls))) {
  
 -    switch(surf_workstation_model->action_state_get(action->sleep.surf_sleep)){
 +    switch(ws_model->action_state_get(action->sleep.surf_sleep)){
        case SURF_ACTION_FAILED:
          simcall->issuer->context->iwannadie = 1;
          //SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
          THROW_IMPOSSIBLE;
          break;
      }
 -    if (surf_workstation_model->extension.
 +    if (ws_model->extension.
          workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
        simcall->issuer->context->iwannadie = 1;
      }
  void SIMIX_process_sleep_destroy(smx_action_t action)
  {
    XBT_DEBUG("Destroy action %p", action);
 +  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
 +  smx_host_t host = action->sleep.host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +
    if (action->sleep.surf_sleep)
 -    action->sleep.surf_sleep->model_type->action_unref(action->sleep.surf_sleep);
 +    action->sleep.surf_sleep->model_obj->action_unref(action->sleep.surf_sleep);
    xbt_mallocator_release(simix_global->action_mallocator, action);
  }
  
  void SIMIX_process_sleep_suspend(smx_action_t action)
  {
 -  surf_workstation_model->suspend(action->sleep.surf_sleep);
 +  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
 +  smx_host_t host = action->sleep.host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +
 +  ws_model->suspend(action->sleep.surf_sleep);
  }
  
  void SIMIX_process_sleep_resume(smx_action_t action)
  {
 -  surf_workstation_model->resume(action->sleep.surf_sleep);
 +  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
 +  smx_host_t host = action->sleep.host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +  XBT_DEBUG("%p ws_model", ws_model);
 +
 +  ws_model->resume(action->sleep.surf_sleep);
  }
  
  /** 
@@@ -275,20 -275,6 +275,20 @@@ ACTION(SIMCALL_HOST_EXECUTION_GET_REMAI
  ACTION(SIMCALL_HOST_EXECUTION_GET_STATE, host_execution_get_state, WITH_ANSWER, TINT(result), TSPEC(execution, smx_action_t)) sep \
  ACTION(SIMCALL_HOST_EXECUTION_SET_PRIORITY, host_execution_set_priority, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t), TDOUBLE(priority)) sep \
  ACTION(SIMCALL_HOST_EXECUTION_WAIT, host_execution_wait, WITHOUT_ANSWER, TINT(result), TSPEC(execution, smx_action_t)) sep \
 +ACTION(SIMCALL_HOST_GET_PARAMS, host_get_params, WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TSPEC(params, ws_params_t)) sep \
 +ACTION(SIMCALL_HOST_SET_PARAMS, host_set_params, WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TSPEC(params, ws_params_t)) sep \
 +ACTION(SIMCALL_VM_CREATE,    vm_create,    WITH_ANSWER,    TPTR(result),  TSTRING(name), TSPEC(ind_pm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_START,     vm_start,     WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_SET_STATE, vm_set_state, WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TINT(state)) sep \
 +ACTION(SIMCALL_VM_GET_STATE, vm_get_state, WITH_ANSWER,    TINT(result),  TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_MIGRATE,   vm_migrate,   WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TSPEC(ind_dst_pm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_GET_PM,    vm_get_pm,    WITH_ANSWER,    TPTR(result),  TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_DESTROY,   vm_destroy,   WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_SUSPEND,   vm_suspend,   WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_RESUME,    vm_resume,    WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_SHUTDOWN,  vm_shutdown,  WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_SAVE,      vm_save,      WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_RESTORE,   vm_restore,   WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
  ACTION(SIMCALL_PROCESS_CREATE, process_create, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t*), TSTRING(name), TSPEC(code, xbt_main_func_t), TPTR(data), TSTRING(hostname), TDOUBLE(kill_time), TINT(argc), TSPEC(argv, char**), TSPEC(properties, xbt_dict_t), TINT(auto_restart)) sep \
  ACTION(SIMCALL_PROCESS_KILL, process_kill, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \
  ACTION(SIMCALL_PROCESS_KILLALL, process_killall, WITH_ANSWER, TVOID(result), TINT(reset_pid)) sep \
@@@ -381,7 -367,8 +381,8 @@@ ACTION(SIMCALL_SET_CATEGORY, set_catego
  #ifdef HAVE_MC
  #define SIMCALL_LIST4(ACTION, sep) \
  ACTION(SIMCALL_MC_SNAPSHOT, mc_snapshot, WITH_ANSWER, TPTR(result)) sep \
- ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TPTR(s1), TPTR(s2)) sep 
+ ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TPTR(s1), TPTR(s2)) sep \
+ ACTION(SIMCALL_MC_RANDOM, mc_random, WITH_ANSWER, TINT(result)) sep
  #else
  #define SIMCALL_LIST4(ACTION, sep)
  #endif
diff --combined src/simix/smx_user.c
@@@ -274,157 -274,6 +274,157 @@@ e_smx_state_t simcall_host_execution_wa
    return simcall_BODY_host_execution_wait(execution);
  }
  
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Create a VM on the given physical host.
 + *
 + * \param name VM name
 + * \param host Physical host
 + *
 + * \return The host object of the VM
 + */
 +void* simcall_vm_create(const char *name, smx_host_t phys_host){
 +  /* will jump to SIMIX_pre_vm_create() in src/simix/smx_smurf_private.h */
 +  return simcall_BODY_vm_create(name, phys_host);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Start the given VM to the given physical host
 + *
 + * \param vm VM
 + */
 +void simcall_vm_start(smx_host_t vm)
 +{
 +  /* will jump to SIMIX_pre_vm_start in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_start(vm);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Get the state of the given VM
 + *
 + * \param vm VM
 + * \return The state of the VM
 + */
 +int simcall_vm_get_state(smx_host_t vm)
 +{
 +  /* will jump to SIMIX_pre_vm_get_state in src/simix/smx_smurf_private.h */
 +  return simcall_BODY_vm_get_state(vm);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Get the name of the physical host on which the given VM runs.
 + *
 + * \param vm VM
 + * \return The name of the physical host
 + */
 +void *simcall_vm_get_pm(smx_host_t vm)
 +{
 +  /* will jump to SIMIX_pre_vm_migrate in src/simix/smx_smurf_private.h */
 +  return simcall_BODY_vm_get_pm(vm);
 +}
 +
 +void simcall_host_get_params(smx_host_t vm, ws_params_t params)
 +{
 +  /* will jump to SIMIX_pre_host_get_params in src/simix/smx_smurf_private.h */
 +  simcall_BODY_host_get_params(vm, params);
 +}
 +
 +void simcall_host_set_params(smx_host_t vm, ws_params_t params)
 +{
 +  /* will jump to SIMIX_pre_host_set_params in src/simix/smx_smurf_private.h */
 +  simcall_BODY_host_set_params(vm, params);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Migrate the given VM to the given physical host
 + *
 + * \param vm VM
 + * \param host Destination physical host
 + */
 +void simcall_vm_migrate(smx_host_t vm, smx_host_t host)
 +{
 +  /* will jump to SIMIX_pre_vm_migrate in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_migrate(vm, host);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Suspend the given VM
 + *
 + * \param vm VM
 + */
 +void simcall_vm_suspend(smx_host_t vm)
 +{
 +  /* will jump to SIMIX_pre_vm_suspend in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_suspend(vm);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Resume the given VM
 + *
 + * \param vm VM
 + */
 +void simcall_vm_resume(smx_host_t vm)
 +{
 +  /* will jump to SIMIX_pre_vm_resume in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_resume(vm);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Save the given VM
 + *
 + * \param vm VM
 + */
 +void simcall_vm_save(smx_host_t vm)
 +{
 +  /* will jump to SIMIX_pre_vm_save in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_save(vm);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Restore the given VM
 + *
 + * \param vm VM
 + */
 +void simcall_vm_restore(smx_host_t vm)
 +{
 +  /* will jump to SIMIX_pre_vm_restore in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_restore(vm);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Shutdown the given VM
 + *
 + * \param vm VM
 + */
 +void simcall_vm_shutdown(smx_host_t vm)
 +{
 +  /* will jump to SIMIX_pre_vm_shutdown in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_shutdown(vm);
 +}
 +
 +/**
 + * \ingroup simix_vm_management
 + * \brief Destroy the given VM
 + *
 + * \param vm VM
 + */
 +void simcall_vm_destroy(smx_host_t vm)
 +{
 +   /* will jump to SIMIX_pre_vm_destroy in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_destroy(vm);
 +}
 +
 +
  /**
   * \ingroup simix_process_management
   * \brief Creates and runs a new SIMIX process.
@@@ -1312,6 -1161,12 +1312,12 @@@ int simcall_mc_compare_snapshots(void *
    return simcall_BODY_mc_compare_snapshots(s1, s2);
  }
  
+ int simcall_mc_random(void)
+ {
+   return simcall_BODY_mc_random();
+ }
  #endif /* HAVE_MC */
  
  /* ****************************************************************************************** */
diff --combined src/surf/network.c
@@@ -325,18 -325,18 +325,18 @@@ int net_get_link_latency_limited(surf_a
  }
  #endif
  
 -static double net_share_resources_full(double now)
 +static double net_share_resources_full(surf_model_t network_model, double now)
  {
    s_surf_action_lmm_t s_action;
    surf_action_network_CM02_t action = NULL;
    xbt_swag_t running_actions =
 -      surf_network_model->states.running_action_set;
 +      network_model->states.running_action_set;
    double min;
  
    min = generic_maxmin_share_resources(running_actions,
                                         xbt_swag_offset(s_action,
                                                         variable),
 -                                                       surf_network_model->model_private->maxmin_system,
 +                                                       network_model->model_private->maxmin_system,
                                         network_solve);
  
  #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + xbt_swag_offset(s_action, variable)  )))
    return min;
  }
  
 -static double net_share_resources_lazy(double now)
 +static double net_share_resources_lazy(surf_model_t network_model, double now)
  {
 -  return generic_share_resources_lazy(now, surf_network_model);
 +  return generic_share_resources_lazy(now, network_model);
  }
  
 -static void net_update_actions_state_full(double now, double delta)
 +static void net_update_actions_state_full(surf_model_t network_model, double now, double delta)
  {
 -  generic_update_actions_state_full(now, delta, surf_network_model);
 +  generic_update_actions_state_full(now, delta, network_model);
  }
  
 -static void net_update_actions_state_lazy(double now, double delta)
 +static void net_update_actions_state_lazy(surf_model_t network_model, double now, double delta)
  {
 -  generic_update_actions_state_lazy(now, delta, surf_network_model);
 +  generic_update_actions_state_lazy(now, delta, network_model);
  }
  
  static void net_update_resource_state(void *id,
@@@ -652,23 -652,22 +652,22 @@@ static int net_link_shared(const void *
        lmm_constraint_is_shared(((surf_resource_lmm_t) link)->constraint);
  }
  
 -static void net_finalize(void)
 +static void net_finalize(surf_model_t network_model)
  {
 -  lmm_system_free(surf_network_model->model_private->maxmin_system);
 -  surf_network_model->model_private->maxmin_system = NULL;
 +  lmm_system_free(network_model->model_private->maxmin_system);
 +  network_model->model_private->maxmin_system = NULL;
  
 -  if (surf_network_model->model_private->update_mechanism == UM_LAZY) {
 -    xbt_heap_free(surf_network_model->model_private->action_heap);
 -    xbt_swag_free(surf_network_model->model_private->modified_set);
 +  if (network_model->model_private->update_mechanism == UM_LAZY) {
 +    xbt_heap_free(network_model->model_private->action_heap);
 +    xbt_swag_free(network_model->model_private->modified_set);
    }
  
 -  surf_model_exit(surf_network_model);
 -  surf_network_model = NULL;
 +  surf_model_exit(network_model);
 +  network_model = NULL;
  
-   if (smpi_bw_factor)
-     xbt_dynar_free(&smpi_bw_factor);
-   if (smpi_lat_factor)
-     xbt_dynar_free(&smpi_lat_factor);
+   xbt_dict_free(&gap_lookup);
+   xbt_dynar_free(&smpi_bw_factor);
+   xbt_dynar_free(&smpi_lat_factor);
  }
  
  static void smpi_gap_append(double size, const link_CM02_t link,
@@@ -763,7 -762,6 +762,7 @@@ static void surf_network_model_init_int
    set_update_mechanism();
  
    surf_network_model->name = "network";
 +  surf_network_model->type = SURF_MODEL_TYPE_NETWORK;
    surf_network_model->action_unref = surf_action_unref;
    surf_network_model->action_cancel = surf_action_cancel;
    surf_network_model->action_recycle = net_action_recycle;
    surf_network_model->suspend = surf_action_suspend;
    surf_network_model->resume = surf_action_resume;
    surf_network_model->is_suspended = surf_action_is_suspended;
 -  surf_cpu_model->set_max_duration = surf_action_set_max_duration;
 +
 +  xbt_assert(surf_cpu_model_pm);
 +  xbt_assert(surf_cpu_model_vm);
 +  surf_cpu_model_pm->set_max_duration = surf_action_set_max_duration;
 +  surf_cpu_model_vm->set_max_duration = surf_action_set_max_duration;
  
    surf_network_model->extension.network.communicate = net_communicate;
    surf_network_model->extension.network.get_route = net_get_route;
diff --combined src/surf/storage.c
@@@ -103,7 -103,6 +103,6 @@@ static surf_action_t storage_action_unl
    xbt_dict_remove(content_dict,stream->name);
  
    free(stream->name);
-   stream->content = NULL;
    xbt_free(stream);
  
    return action;
@@@ -152,7 -151,6 +151,6 @@@ static surf_action_t storage_action_clo
    }
  
    free(fp->name);
-   fp->content = NULL;
    xbt_free(fp);
    surf_action_t action = storage_action_execute(storage,0, CLOSE);
    return action;
@@@ -269,27 -267,26 +267,26 @@@ static void* storage_create_resource(co
    return storage;
  }
  
 -static void storage_finalize(void)
 +static void storage_finalize(surf_model_t storage_model)
  {
    lmm_system_free(storage_maxmin_system);
    storage_maxmin_system = NULL;
  
 -  surf_model_exit(surf_storage_model);
 -  surf_storage_model = NULL;
 +  surf_model_exit(storage_model);
 +  storage_model = NULL;
  
-   if(storage_list)
-     xbt_dynar_free(&storage_list);
+   xbt_dynar_free(&storage_list);
  
    xbt_swag_free
        (storage_running_action_set_that_does_not_need_being_checked);
    storage_running_action_set_that_does_not_need_being_checked = NULL;
  }
  
 -static void storage_update_actions_state(double now, double delta)
 +static void storage_update_actions_state(surf_model_t storage_model, double now, double delta)
  {
    surf_action_storage_t action = NULL;
    surf_action_storage_t next_action = NULL;
 -  xbt_swag_t running_actions = surf_storage_model->states.running_action_set;
 +  xbt_swag_t running_actions = storage_model->states.running_action_set;
  
    // Update the disk usage
    // Update the file size
    return;
  }
  
 -static double storage_share_resources(double NOW)
 +static double storage_share_resources(surf_model_t storage_model, double NOW)
  {
    XBT_DEBUG("storage_share_resources %f",NOW);
    s_surf_action_storage_t action;
    storage_t storage;
    surf_action_storage_t write_action;
  
 -  double min_completion = generic_maxmin_share_resources(surf_storage_model->states.running_action_set,
 +  double min_completion = generic_maxmin_share_resources(storage_model->states.running_action_set,
        xbt_swag_offset(action, generic_lmm_action.variable),
        storage_maxmin_system, lmm_solve);
  
@@@ -495,7 -492,6 +492,7 @@@ static void surf_storage_model_init_int
        xbt_swag_new(xbt_swag_offset(action, state_hookup));
  
    surf_storage_model->name = "Storage";
 +  surf_storage_model->type = SURF_MODEL_TYPE_STORAGE;
    surf_storage_model->action_unref = storage_action_unref;
    surf_storage_model->action_cancel = storage_action_cancel;
    surf_storage_model->action_state_set = storage_action_state_set;
@@@ -613,8 -609,7 +610,7 @@@ static xbt_dict_t parse_storage_content
        }
      }
    }
-   if (line)
-       free(line);
+   free(line);
    fclose(file);
    return parse_content;
  }
@@@ -134,6 -134,9 +134,9 @@@ static int ptask_action_unref(surf_acti
      free(((surf_action_workstation_L07_t) action)->workstation_list);
      free(((surf_action_workstation_L07_t) action)->communication_amount);
      free(((surf_action_workstation_L07_t) action)->computation_amount);
+ #ifdef HAVE_TRACING
+     xbt_free(action->category);
+ #endif
      surf_action_free(&action);
      return 1;
    }
@@@ -216,13 -219,13 +219,13 @@@ static int ptask_resource_used(void *re
  
  }
  
 -static double ptask_share_resources(double now)
 +static double ptask_share_resources(surf_model_t workstation_model, double now)
  {
    s_surf_action_workstation_L07_t s_action;
    surf_action_workstation_L07_t action = NULL;
  
    xbt_swag_t running_actions =
 -      surf_workstation_model->states.running_action_set;
 +      workstation_model->states.running_action_set;
    double min = generic_maxmin_share_resources(running_actions,
                                                xbt_swag_offset(s_action,
                                                                variable),
    return min;
  }
  
 -static void ptask_update_actions_state(double now, double delta)
 +static void ptask_update_actions_state(surf_model_t workstation_model, double now, double delta)
  {
    double deltap = 0.0;
    surf_action_workstation_L07_t action = NULL;
    surf_action_workstation_L07_t next_action = NULL;
    xbt_swag_t running_actions =
 -      surf_workstation_model->states.running_action_set;
 +      workstation_model->states.running_action_set;
  
    xbt_swag_foreach_safe(action, next_action, running_actions) {
      deltap = delta;
@@@ -407,12 -410,12 +410,12 @@@ static void ptask_update_resource_state
    return;
  }
  
 -static void ptask_finalize(void)
 +static void ptask_finalize(surf_model_t workstation_model)
  {
    xbt_dict_free(&ptask_parallel_task_link_set);
  
 -  surf_model_exit(surf_workstation_model);
 -  surf_workstation_model = NULL;
 +  surf_model_exit(workstation_model);
 +  workstation_model = NULL;
    surf_model_exit(surf_network_model);
    surf_network_model = NULL;
  
@@@ -856,7 -859,6 +859,7 @@@ static void ptask_model_init_internal(v
    surf_workstation_model->set_priority = ptask_action_set_priority;
    surf_workstation_model->get_remains = ptask_action_get_remains;
    surf_workstation_model->name = "Workstation ptask_L07";
 +  surf_workstation_model->type = SURF_MODEL_TYPE_WORKSTATION;
  
    surf_workstation_model->model_private->resource_used =
        ptask_resource_used;
  void surf_workstation_model_init_ptask_L07(void)
  {
    XBT_INFO("surf_workstation_model_init_ptask_L07");
 -  xbt_assert(!surf_cpu_model, "CPU model type already defined");
 +  xbt_assert(!surf_cpu_model_pm, "CPU model type already defined");
    xbt_assert(!surf_network_model, "network model type already defined");
    ptask_define_callbacks();
    ptask_model_init_internal();