Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into hypervisor
authorPaul Bédaride <paul.bedaride@gmail.com>
Wed, 19 Jun 2013 11:42:14 +0000 (13:42 +0200)
committerPaul Bédaride <paul.bedaride@gmail.com>
Wed, 19 Jun 2013 11:42:14 +0000 (13:42 +0200)
Conflicts:
src/bindings/java/jmsg_synchro.c
src/bindings/java/org/simgrid/msg/Host.java
src/include/surf/surf.h
src/smpi/colls/allgather-RDB.c
src/smpi/colls/allgather-SMP-simple.c
src/surf/cpu_cas01.c
src/surf/surf.c
src/surf/surf_routing.c
src/surf/workstation.c

24 files changed:
1  2 
buildtools/Cmake/DefinePackages.cmake
include/msg/datatypes.h
include/msg/msg.h
include/simgrid/platf.h
include/simgrid/simix.h
src/bindings/java/org/simgrid/msg/Host.java
src/include/surf/surf.h
src/msg/msg_host.c
src/msg/msg_process.c
src/simgrid/sg_config.c
src/simix/smx_global.c
src/simix/smx_host.c
src/simix/smx_host_private.h
src/simix/smx_io.c
src/simix/smx_network.c
src/simix/smx_smurf_private.h
src/simix/smx_synchro.c
src/simix/smx_user.c
src/surf/cpu_cas01.c
src/surf/network.c
src/surf/new_model.c
src/surf/storage.c
src/surf/surf.c
src/surf/workstation.c

@@@ -37,6 -37,8 +37,8 @@@ set(EXTRA_DIS
    src/smpi/README
    src/smpi/colls/COPYRIGHTS
    src/smpi/colls/colls.h
+   src/smpi/colls/colls_private.h
+   src/smpi/colls/coll_tuned_topo.h
    src/smpi/private.h
    src/smpi/smpi_mpi_dt_private.h
    src/surf/cpu_ti_private.h
@@@ -109,9 -111,12 +111,12 @@@ 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/smpi_openmpi_selector.c
+   src/smpi/colls/smpi_mpich_selector.c
+   src/smpi/colls/colls_global.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-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/allgather-ompi-neighborexchange.c
+   src/smpi/colls/allgatherv-GB.c  
+   src/smpi/colls/allgatherv-pair.c
+   src/smpi/colls/allgatherv-ring.c
+   src/smpi/colls/allgatherv-ompi-neighborexchange.c
+   src/smpi/colls/allgatherv-ompi-bruck.c
+   src/smpi/colls/allgatherv-mpich-rdb.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-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-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/allreduce-ompi-ring-segmented.c
    src/smpi/colls/alltoall-2dmesh.c
    src/smpi/colls/alltoall-3dmesh.c
    #src/smpi/colls/alltoall-bruck.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/alltoallv-pair.c   
+   src/smpi/colls/alltoallv-pair-light-barrier.c
+   src/smpi/colls/alltoallv-pair-mpi-barrier.c
+   src/smpi/colls/alltoallv-pair-one-barrier.c 
+   src/smpi/colls/alltoallv-ring.c
+   src/smpi/colls/alltoallv-ring-light-barrier.c
+   src/smpi/colls/alltoallv-ring-mpi-barrier.c
+   src/smpi/colls/alltoallv-ring-one-barrier.c
+   src/smpi/colls/alltoallv-bruck.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-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/coll_tuned_topo.c
+   src/smpi/colls/bcast-ompi-split-bintree.c
+   src/smpi/colls/bcast-ompi-pipeline.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
+   src/smpi/colls/reduce-ompi.c
+   src/smpi/colls/gather-ompi.c
+   src/smpi/colls/reduce_scatter-ompi.c
+   src/smpi/colls/reduce_scatter-mpich.c
+   src/smpi/colls/scatter-ompi.c
+   src/smpi/colls/barrier-ompi.c
    )
  
  if(SMPI_F2C)
@@@ -278,14 -305,12 +305,13 @@@ set(SURF_SR
    src/surf/surf_routing_full.c
    src/surf/surf_routing_generic.c
    src/surf/surf_routing_none.c
-   src/surf/surf_routing_rulebased.c
    src/surf/surf_routing_vivaldi.c
    src/surf/surfxml_parse.c
    src/surf/surfxml_parseplatf.c
    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
    )
  
@@@ -303,7 -328,6 +329,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
@@@ -530,7 -554,6 +556,6 @@@ set(headers_to_instal
    include/xbt/dynar.h
    include/xbt/ex.h
    include/xbt/fifo.h
-   include/xbt/file_stat.h
    include/xbt/function_types.h
    include/xbt/graph.h
    include/xbt/graphxml.h
@@@ -613,7 -636,6 +638,6 @@@ set(simgrid_source
    ${SIMGRID_SRC}
    ${SIMIX_SRC}
    ${SURF_SRC}
-   ${TRACING_SRC}
    ${XBT_SRC}
    )
  
@@@ -700,7 -722,6 +724,6 @@@ set(DOC_SOURCE
  
    doc/HelloWorld/CMakeLists.txt
    doc/HelloWorld/HelloWorld.c
-   doc/HelloWorld/FindPcreWin.cmake
    doc/HelloWorld/README
  
    doc/doxygen/FAQ.doc
@@@ -836,6 -857,7 +859,7 @@@ set(EXAMPLES_CMAKEFILES_TX
    examples/msg/CMakeLists.txt
    examples/msg/actions/CMakeLists.txt
    examples/msg/bittorrent/CMakeLists.txt
+   examples/msg/chainsend/CMakeLists.txt
    examples/msg/chord/CMakeLists.txt
    examples/msg/cloud/CMakeLists.txt
    examples/msg/gpu/CMakeLists.txt
    examples/msg/migration/CMakeLists.txt
    examples/msg/ns3/CMakeLists.txt
    examples/msg/parallel_task/CMakeLists.txt
+   examples/msg/pastry/CMakeLists.txt
    examples/msg/pmm/CMakeLists.txt
    examples/msg/priority/CMakeLists.txt
    examples/msg/properties/CMakeLists.txt
+   examples/msg/semaphores/CMakeLists.txt
    examples/msg/sendrecv/CMakeLists.txt
-   examples/msg/chainsend/CMakeLists.txt
    examples/msg/start_kill_time/CMakeLists.txt
    examples/msg/suspend/CMakeLists.txt
    examples/msg/token_ring/CMakeLists.txt
    examples/msg/tracing/CMakeLists.txt
+   examples/scala/CMakeLists.txt
+   examples/scala/master_slave_bypass/CMakeLists.txt
+   examples/scala/master_slave_kill/CMakeLists.txt
+   examples/scala/masterslave/CMakeLists.txt
    examples/simdag/CMakeLists.txt
    examples/simdag/dax/CMakeLists.txt
    examples/simdag/dot/CMakeLists.txt
@@@ -874,20 -901,20 +903,20 @@@ set(TESHSUITE_CMAKEFILES_TX
    teshsuite/msg/CMakeLists.txt
    teshsuite/msg/trace/CMakeLists.txt
    teshsuite/simdag/CMakeLists.txt
+   teshsuite/simdag/availability/CMakeLists.txt
    teshsuite/simdag/network/CMakeLists.txt
    teshsuite/simdag/network/mxn/CMakeLists.txt
    teshsuite/simdag/network/p2p/CMakeLists.txt
    teshsuite/simdag/partask/CMakeLists.txt
    teshsuite/simdag/platforms/CMakeLists.txt
-   teshsuite/simdag/availability/CMakeLists.txt
-   teshsuite/xbt/CMakeLists.txt
    teshsuite/smpi/CMakeLists.txt
    teshsuite/smpi/mpich-test/CMakeLists.txt
-   teshsuite/smpi/mpich-test/env/CMakeLists.txt
    teshsuite/smpi/mpich-test/coll/CMakeLists.txt
    teshsuite/smpi/mpich-test/context/CMakeLists.txt
+   teshsuite/smpi/mpich-test/env/CMakeLists.txt
    teshsuite/smpi/mpich-test/profile/CMakeLists.txt
    teshsuite/smpi/mpich-test/pt2pt/CMakeLists.txt
+   teshsuite/xbt/CMakeLists.txt
    )
  
  set(TOOLS_CMAKEFILES_TXT
@@@ -923,10 -950,9 +952,9 @@@ set(CMAKE_SOURCE_FILE
    buildtools/Cmake/Modules/FindLibunwind.cmake
    buildtools/Cmake/Modules/FindLua51Simgrid.cmake
    buildtools/Cmake/Modules/FindNS3.cmake
-   buildtools/Cmake/Modules/FindPCRE.cmake
-   buildtools/Cmake/Modules/FindPcreWin.cmake
    buildtools/Cmake/Modules/FindRngStream.cmake
    buildtools/Cmake/Modules/FindRubySimgrid.cmake
+   buildtools/Cmake/Modules/FindScala.cmake
    buildtools/Cmake/Modules/FindSimGrid.cmake
    buildtools/Cmake/Modules/FindValgrind.cmake
    buildtools/Cmake/Option.cmake
@@@ -968,7 -994,6 +996,6 @@@ set(PLATFORMS_EXAMPLE
    examples/platforms/cluster.xml
    examples/platforms/cluster_and_one_host.xml
    examples/platforms/cluster_no_backbone.xml
-   examples/platforms/cluster_routing_rulebased.xml
    examples/platforms/clusters_routing_full.xml
    examples/platforms/conf/gridpp_grid_2004.conf
    examples/platforms/conf/gridpp_grid_2004.xml
diff --combined include/msg/datatypes.h
@@@ -6,7 -6,6 +6,6 @@@
  #ifndef MSG_DATATYPE_H
  #define MSG_DATATYPE_H
  #include "xbt/misc.h"
- #include "xbt/file_stat.h"
  #include "xbt/lib.h"
  #include "simgrid/simix.h"
  #include "simgrid_config.h"     // for HAVE_TRACING
@@@ -48,10 -47,7 +47,10 @@@ typedef xbt_dictelm_t msg_host_t
  typedef s_xbt_dictelm_t s_msg_host_t;
  
  typedef struct msg_host_priv {
 -  xbt_swag_t vms;
 +  int        dp_enabled;
 +  xbt_dict_t dp_objs;
 +  double     dp_updated_by_deleted_tasks;
 +
  #ifdef MSG_USE_DEPRECATED
    msg_mailbox_t *mailboxes;     /**< the channels  */
  #endif
@@@ -86,19 -82,29 +85,20 @@@ typedef struct msg_task 
   */
  typedef struct msg_task *msg_task_t;
  
 -/* ********************************  VM ************************************* */
 -typedef struct msg_vm *msg_vm_t;
 -
 -typedef enum {
 -  msg_vm_state_suspended, msg_vm_state_running, msg_vm_state_migrating
 -} e_msg_vm_state_t;
 -
 -typedef struct msg_vm {
 -  char *name;
 -  s_xbt_swag_hookup_t all_vms_hookup;
 -  s_xbt_swag_hookup_t host_vms_hookup;
 -  xbt_dynar_t processes;
 -  e_msg_vm_state_t state;
 -  msg_host_t location;
 -  int coreAmount;
 -} s_msg_vm_t;
 +/* ******************************** VM ************************************* */
 +typedef msg_host_t msg_vm_t;
 +typedef msg_host_priv_t msg_vm_priv_t;
 +
 +static inline msg_vm_priv_t MSG_vm_priv(msg_vm_t vm){
 +  return xbt_lib_get_level(vm, MSG_HOST_LEVEL);
 +}
  
  /* ******************************** File ************************************ */
  typedef struct simdata_file *simdata_file_t;
  
  typedef struct msg_file {
    char *name;                   /**< @brief file name */
+   size_t size;
    simdata_file_t simdata;                /**< @brief simulator data  */
    void *data;                   /**< @brief user data */
  } s_msg_file_t;
   */
  typedef struct msg_file *msg_file_t;
  
- /** @brief File datatype.
-     @ingroup msg_file_management
-     You should consider this as an opaque object.
-  */
- typedef s_file_stat_t s_msg_stat_t, *msg_stat_t;
  /*************** Begin GPU ***************/
  typedef struct simdata_gpu_task *simdata_gpu_task_t;
  
diff --combined include/msg/msg.h
@@@ -78,12 -78,11 +78,11 @@@ XBT_PUBLIC(const char *) MSG_environmen
  XBT_PUBLIC(xbt_dynar_t) MSG_environment_as_get_hosts(msg_as_t as);
  
  /************************** File handling ***********************************/
- XBT_PUBLIC(double) MSG_file_read(void* ptr, size_t size, size_t nmemb, msg_file_t stream);
- XBT_PUBLIC(size_t) MSG_file_write(const void* ptr, size_t size, size_t nmemb, msg_file_t stream);
- XBT_PUBLIC(msg_file_t) MSG_file_open(const char* mount, const char* path, const char* mode);
- XBT_PUBLIC(int) MSG_file_close(msg_file_t fp);
- XBT_PUBLIC(int) MSG_file_stat(msg_file_t fd, s_msg_stat_t *buf);
- XBT_PUBLIC(void) MSG_file_free_stat(s_msg_stat_t *stat);
+ XBT_PUBLIC(size_t) MSG_file_read(void* ptr, size_t size, msg_file_t fd);
+ XBT_PUBLIC(size_t) MSG_file_write(const void* ptr, size_t size, msg_file_t fd);
+ XBT_PUBLIC(msg_file_t) MSG_file_open(const char* mount, const char* path);
+ XBT_PUBLIC(int) MSG_file_close(msg_file_t fd);
+ XBT_PUBLIC(size_t) MSG_file_get_size(msg_file_t fd);
  
  XBT_PUBLIC(int) MSG_file_unlink(msg_file_t fd);
  XBT_PUBLIC(xbt_dict_t) MSG_file_ls(const char *mount, const char *path);
@@@ -97,15 -96,13 +96,16 @@@ XBT_PUBLIC(void) MSG_as_router_set_prop
  XBT_PUBLIC(msg_error_t) MSG_host_set_data(msg_host_t host, void *data);
  XBT_PUBLIC(void *) MSG_host_get_data(msg_host_t host);
  XBT_PUBLIC(const char *) MSG_host_get_name(msg_host_t host);
 +XBT_PUBLIC(void) MSG_host_on(msg_host_t host);
 +XBT_PUBLIC(void) MSG_host_off(msg_host_t host);
  XBT_PUBLIC(msg_host_t) MSG_host_self(void);
  XBT_PUBLIC(int) MSG_get_host_msgload(msg_host_t host);
  /* 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_get_host_core(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);
@@@ -122,9 -119,6 +122,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,
@@@ -214,7 -208,6 +214,7 @@@ XBT_PUBLIC(msg_error_t) MSG_task_receiv
  XBT_PUBLIC(msg_error_t) MSG_task_execute(msg_task_t task);
  XBT_PUBLIC(msg_error_t) MSG_parallel_task_execute(msg_task_t task);
  XBT_PUBLIC(void) MSG_task_set_priority(msg_task_t task, double priority);
 +XBT_PUBLIC(void) MSG_task_set_bound(msg_task_t task, double bound);
  
  XBT_PUBLIC(msg_error_t) MSG_process_sleep(double nb_sec);
  
@@@ -388,46 -381,30 +388,46 @@@ XBT_PUBLIC(int) MSG_sem_would_block(msg
   * Usual lack of guaranty of any kind applies here, and is even increased.
   *
   */
 -/* 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);
  
 -XBT_PUBLIC(int) MSG_vm_is_suspended(msg_vm_t);
 +XBT_PUBLIC(int) MSG_vm_is_created(msg_vm_t);
  XBT_PUBLIC(int) MSG_vm_is_running(msg_vm_t);
 +XBT_PUBLIC(int) MSG_vm_is_migrating(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(int) MSG_vm_is_suspended(msg_vm_t);
 +XBT_PUBLIC(int) MSG_vm_is_saving(msg_vm_t);
 +XBT_PUBLIC(int) MSG_vm_is_saved(msg_vm_t);
 +XBT_PUBLIC(int) MSG_vm_is_restoring(msg_vm_t);
  
 -XBT_PUBLIC(void) MSG_vm_migrate(msg_vm_t vm, msg_host_t destination);
  
 -XBT_PUBLIC(void) MSG_vm_suspend(msg_vm_t vm);
 -  // \forall p in VM, MSG_process_suspend(p) // Freeze the processes
 +XBT_PUBLIC(const char*) MSG_vm_get_name(msg_vm_t);
  
 -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
 +// 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, long mem_cap, long net_cap, char *disk_path, long disk_size);
  
 -XBT_PUBLIC(void) MSG_vm_shutdown(msg_vm_t vm); // killall
 +XBT_PUBLIC(void) MSG_vm_destroy(msg_vm_t vm);
  
 -XBT_PUBLIC(void) MSG_vm_reboot(msg_vm_t vm);
 +XBT_PUBLIC(void) MSG_vm_start(msg_vm_t);
  
 -XBT_PUBLIC(void) MSG_vm_destroy(msg_vm_t vm);
 +/* Shutdown the guest operating system. */
 +XBT_PUBLIC(void) MSG_vm_shutdown(msg_vm_t vm);
 +
 +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);
 +XBT_PUBLIC(void) MSG_vm_resume(msg_vm_t vm);
 +
 +/* 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(msg_host_t) MSG_vm_get_pm(msg_vm_t vm);
 +XBT_PUBLIC(void) MSG_vm_set_bound(msg_vm_t vm, double bound);
  
 -XBT_PUBLIC(xbt_dynar_t) MSG_vms_as_dynar(void);
 +/* 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,46 -41,6 +41,46 @@@ 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_stage1;
 +  int skip_stage2;
 +  double max_downtime;
 +
 +  double dp_rate;
 +  double dp_cap; /* bytes per 1 flop execution */
 +
 +  double xfer_cpu_overhead;
 +  double dpt_cpu_overhead;
 +
 +  /* set migration speed */
 +  double mig_speed;
 +} 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 */
@@@ -230,6 -190,7 +230,7 @@@ typedef struct s_sg_platf_cluster_cbar
    double loopback_bw;
    double loopback_lat;
    double limiter_link;
+   xbt_dict_t properties;
    const char* router_id;
    e_surf_link_sharing_policy_t sharing_policy;
    e_surf_link_sharing_policy_t bb_sharing_policy;
  } s_sg_platf_cluster_cbarg_t;
  
  #define SG_PLATF_CLUSTER_INITIALIZER {NULL,NULL,NULL,NULL,NULL,NULL \
-   ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
+   ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}
  
  typedef struct s_sg_platf_cabinet_cbarg *sg_platf_cabinet_cbarg_t;
  typedef struct s_sg_platf_cabinet_cbarg {
diff --combined include/simgrid/simix.h
  #include "xbt/misc.h"
  #include "xbt/fifo.h"
  #include "xbt/dict.h"
- #include "xbt/file_stat.h"
  #include "xbt/function_types.h"
  #include "xbt/parmap.h"
  #include "xbt/swag.h"
  
 +#include "simgrid/platf.h" // ws_params_t
 +
  SG_BEGIN_DECL()
  
  /**************************** Scalar Values **********************************/
@@@ -72,7 -69,6 +71,6 @@@ typedef struct s_smx_sem *smx_sem_t
  
  /********************************** File *************************************/
  typedef struct s_smx_file *smx_file_t;
- typedef struct s_smx_stat *smx_stat_t;
  
  /********************************** Action *************************************/
  typedef struct s_smx_action *smx_action_t; /* FIXME: replace by specialized action handlers */
@@@ -258,6 -254,6 +256,8 @@@ XBT_PUBLIC(smx_host_t) SIMIX_host_get_b
  XBT_PUBLIC(smx_host_t) SIMIX_host_self(void);
  XBT_PUBLIC(const char*) SIMIX_host_self_get_name(void);
  XBT_PUBLIC(const char*) SIMIX_host_get_name(smx_host_t host); /* FIXME: make private: only the name of SIMIX_host_self() should be public without request */
++XBT_PUBLIC(void) SIMIX_host_on(smx_host_t host);
++XBT_PUBLIC(void) SIMIX_host_off(smx_host_t host);
  XBT_PUBLIC(void) SIMIX_host_self_set_data(void *data);
  XBT_PUBLIC(void*) SIMIX_host_self_get_data(void);
  XBT_PUBLIC(void*) SIMIX_host_get_data(smx_host_t host);
@@@ -297,6 -293,7 +297,9 @@@ XBT_PUBLIC(void) SIMIX_comm_finish(smx_
  XBT_PUBLIC(smx_host_t) simcall_host_get_by_name(const char *name);
  XBT_PUBLIC(const char *) simcall_host_get_name(smx_host_t host);
  XBT_PUBLIC(xbt_dict_t) simcall_host_get_properties(smx_host_t host);
++XBT_PUBLIC(void) simcall_host_on(smx_host_t host);
++XBT_PUBLIC(void) simcall_host_off(smx_host_t host);
+ XBT_PUBLIC(int) simcall_host_get_core(smx_host_t host);
  XBT_PUBLIC(double) simcall_host_get_speed(smx_host_t host);
  XBT_PUBLIC(double) simcall_host_get_available_speed(smx_host_t host);
  /* Two possible states, 1 - CPU ON and 0 CPU OFF */
@@@ -307,7 -304,7 +310,7 @@@ XBT_PUBLIC(void) simcall_host_set_data(
  
  XBT_PUBLIC(smx_action_t) simcall_host_execute(const char *name, smx_host_t host,
                                                  double computation_amount,
 -                                                double priority);
 +                                                double priority, double bound);
  XBT_PUBLIC(smx_action_t) simcall_host_parallel_execute(const char *name,
                                                       int host_nb,
                                                       smx_host_t *host_list,
@@@ -320,25 -317,8 +323,25 @@@ XBT_PUBLIC(void) simcall_host_execution
  XBT_PUBLIC(double) simcall_host_execution_get_remains(smx_action_t execution);
  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(void) simcall_host_execution_set_bound(smx_action_t execution, double bound);
  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_set_bound(smx_host_t vm, double bound);
 +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 */
@@@ -478,16 -458,17 +481,17 @@@ XBT_PUBLIC(void) simcall_sem_release(sm
  XBT_PUBLIC(int) simcall_sem_would_block(smx_sem_t sem);
  XBT_PUBLIC(void) simcall_sem_acquire(smx_sem_t sem);
  XBT_PUBLIC(void) simcall_sem_acquire_timeout(smx_sem_t sem,
-                                            double max_duration);
+                                              double max_duration);
  XBT_PUBLIC(int) simcall_sem_get_capacity(smx_sem_t sem);
  
- XBT_PUBLIC(double) simcall_file_read(void* ptr, size_t size, size_t nmemb, smx_file_t stream);
- XBT_PUBLIC(size_t) simcall_file_write(const void* ptr, size_t size, size_t nmemb, smx_file_t stream);
XBT_PUBLIC(smx_file_t) simcall_file_open(const char* storage, const char* path, const char* mode);
- XBT_PUBLIC(int) simcall_file_close(smx_file_t fp);
- XBT_PUBLIC(int) simcall_file_stat(smx_file_t fd, s_file_stat_t *buf);
+ XBT_PUBLIC(size_t) simcall_file_read(void* ptr, size_t size, smx_file_t fd);
+ XBT_PUBLIC(size_t) simcall_file_write(const void* ptr, size_t size,
                                      smx_file_t fd);
+ XBT_PUBLIC(smx_file_t) simcall_file_open(const char* storage, const char* path);
+ XBT_PUBLIC(int) simcall_file_close(smx_file_t fd);
  XBT_PUBLIC(int) simcall_file_unlink(smx_file_t fd);
  XBT_PUBLIC(xbt_dict_t) simcall_file_ls(const char* mount, const char* path);
+ XBT_PUBLIC(size_t) simcall_file_get_size(smx_file_t fd);
  
  /************************** AS router   **********************************/
  XBT_PUBLIC(xbt_dict_t) SIMIX_asr_get_properties(const char *name);
@@@ -53,7 -53,7 +53,7 @@@ public class Host 
        /**
         * Host name
         */
 -      private String name;
 +      protected String name;
  
        /**
         * User data.
                this.bind = 0;
                this.data = null;
        };
 +      
 +      public String toString (){
 +              return this.name; 
 +              
 +      }
  
        /**
         * This static method gets an host instance associated with a native
         */ 
        public native static Host[] all();
  
+     /** 
+      * This static method sets a mailbox to receive in asynchronous mode.
+      * 
+      * All messages sent to this mailbox will be transferred to 
+      * the receiver without waiting for the receive call. 
+      * The receive call will still be necessary to use the received data.
+      * If there is a need to receive some messages asynchronously, and some not, 
+      * two different mailboxes should be used.
+      *
+      * @param mailboxName The name of the mailbox
+      */
+     public static native void setAsyncMailbox(String mailboxName);
        /**
         * This method returns the name of a host.
         * @return                      The name of the host.
         *
         */ 
        public native double getSpeed();
-       
+       /**
+        * This method returns the number of core of a host.
+        *
+        * @return                      The speed of the processor of the host in flops.
+        *
+        */ 
+       public native double getCore();
        /**
         * Returns the value of a given host property. 
         */
        public native String getProperty(String name);
 +      
        /**
         * Change the value of a given host property. 
         */
        public native void setProperty(String name, String value);
 -    /** This method tests if a host is available.
 +    
 +      /** This method tests if a host is available.
       * @return True if the host is available.
       */
        public native boolean isAvail();
diff --combined src/include/surf/surf.h
@@@ -12,7 -12,6 +12,6 @@@
  #include "xbt/dict.h"
  #include "xbt/graph.h"
  #include "xbt/misc.h"
- #include "xbt/file_stat.h"
  #include "portable.h"
  #include "xbt/config.h"
  #include "surf/datatypes.h"
@@@ -80,13 -79,6 +79,13 @@@ enum heap_action_type
    NOTSET
  };
  
 +
 +typedef struct surf_resource {
 +  surf_model_t model;
 +  char *name;
 +  xbt_dict_t properties;
 +} s_surf_resource_t, *surf_resource_t;
 +
  /** \ingroup SURF_actions
   *  \brief Action structure
   *
@@@ -100,7 -92,6 +99,7 @@@ typedef struct surf_action 
    xbt_swag_t state_set;
    double cost;                  /**< cost        */
    double priority;              /**< priority (1.0 by default) */
 +  double bound;              /**< the capping of the CPU use  */
    double max_duration;          /**< max_duration (may fluctuate until
             the task is completed) */
    double remains;               /**< How much of that cost remains to
           * and fluctuates until the task is completed */
    void *data;                   /**< for your convenience */
    int refcount;
 -  surf_model_t model_type;
 +
 +  /* The previous name was model_type. For VM support, we have to distinguish a
 +   * model type and its model object. Thus, we use model_obj here. The type of
 +   * a model object is available by looking at the inside of the model object. */
 +  surf_model_t model_obj;       /**< the surf model object */
 +
  #ifdef HAVE_TRACING
    char *category;               /**< tracing category for categorized resource utilization monitoring */
  #endif
    surf_file_t file;        /**< surf_file_t for storage model */
-   s_file_stat_t stat;        /**< surf_file_t for storage model */
    xbt_dict_t ls_dict;
  } s_surf_action_t;
  
@@@ -208,8 -193,7 +206,9 @@@ typedef struct surf_cpu_model_extension
    surf_action_t(*execute) (void *cpu, double size);
    surf_action_t(*sleep) (void *cpu, double duration);
    e_surf_resource_state_t(*get_state) (void *cpu);
 +  void(*set_state) (void *cpu, e_surf_resource_state_t state);
 +
+   int (*get_core) (void *cpu);
    double (*get_speed) (void *cpu, double load);
    double (*get_available_speed) (void *cpu);
    void (*add_traces) (void);
@@@ -242,29 -226,27 +241,31 @@@ typedef struct surf_network_model_exten
   */
  
  typedef struct surf_storage_model_extension_public {
-   surf_action_t(*open) (void *storage, const char* mount, const char* path, const char* mode);
-   surf_action_t(*close) (void *storage, surf_file_t fp);
-   surf_action_t(*read) (void *storage, void* ptr, double size, size_t nmemb, surf_file_t stream);
-   surf_action_t(*write) (void *storage, const void* ptr, size_t size, size_t nmemb, surf_file_t stream);
-   surf_action_t(*stat) (void *storage, surf_file_t stream);
-   surf_action_t(*unlink) (void *storage, surf_file_t stream);
+   surf_action_t(*open) (void *storage, const char* mount, const char* path);
+   surf_action_t(*close) (void *storage, surf_file_t fd);
+   surf_action_t(*read) (void *storage, void* ptr, size_t size,
+                         surf_file_t fd);
+   surf_action_t(*write) (void *storage, const void* ptr, size_t size,
+                          surf_file_t fd);
+   surf_action_t(*stat) (void *storage, surf_file_t fd);
    surf_action_t(*ls) (void *storage, const char *path);
  } s_surf_model_extension_storage_t;
  
 -     /** \ingroup SURF_models
 -      *  \brief Workstation model extension public
 -      *
 -      *  Public functions specific to the workstation model.
 -      */
 +/** \ingroup SURF_models
 + *  \brief Workstation model extension public
 + *
 + *  Public functions specific to the workstation model.
 + */
  typedef struct surf_workstation_model_extension_public {
 +  /* This points to the surf cpu model object bound to the workstation model. */
 +  surf_model_t cpu_model;
 +
    surf_action_t(*execute) (void *workstation, double size);                                /**< Execute a computation amount on a workstation
                                        and create the corresponding action */
    surf_action_t(*sleep) (void *workstation, double duration);                              /**< Make a workstation sleep during a given duration */
    e_surf_resource_state_t(*get_state) (void *workstation);                                      /**< Return the CPU state of a workstation */
 +  void(*set_state) (void *workstation, e_surf_resource_state_t state);
+   int (*get_core) (void *workstation); 
    double (*get_speed) (void *workstation, double load);                                    /**< Return the speed of a workstation */
    double (*get_available_speed) (void *workstation);                                       /**< Return tha available speed of a workstation */
     surf_action_t(*communicate) (void *workstation_src,                                     /**< Execute a communication amount between two workstations */
                                            double rate);
    double (*get_link_bandwidth) (const void *link);                                         /**< Return the current bandwidth of a network link */
    double (*get_link_latency) (const void *link);                                           /**< Return the current latency of a network link */
-   surf_action_t(*open) (void *workstation, const char* storage, const char* path, const char* mode);
-   surf_action_t(*close) (void *workstation, surf_file_t fp);
-   surf_action_t(*read) (void *workstation, void* ptr, size_t size, size_t nmemb, surf_file_t stream);
-   surf_action_t(*write) (void *workstation, const void* ptr, size_t size, size_t nmemb, surf_file_t stream);
-   surf_action_t(*stat) (void *workstation, surf_file_t stream);
-   surf_action_t(*unlink) (void *workstation, surf_file_t stream);
+   surf_action_t(*open) (void *workstation, const char* storage,
+                         const char* path);
+   surf_action_t(*close) (void *workstation, surf_file_t fd);
+   surf_action_t(*read) (void *workstation, void* ptr, size_t size,
+                         surf_file_t fd);
+   surf_action_t(*write) (void *workstation, const void* ptr, size_t size,
+                          surf_file_t fd);
+   surf_action_t(*stat) (void *workstation, surf_file_t fd);
+   int(*unlink) (void *workstation, surf_file_t fd);
    surf_action_t(*ls) (void *workstation, const char* mount, const char *path);
+   size_t (*get_size) (void *workstation, surf_file_t fd);
  
    int (*link_shared) (const void *link);
     xbt_dict_t(*get_properties) (const void *resource);
    void (*add_traces) (void);
  
 +  void (*get_params) (void *ind_vm_ws, ws_params_t param);
 +  void (*set_params) (void *ind_vm_ws, ws_params_t param);
 +  xbt_dynar_t (*get_vms) (void *ind_vm_ws);
 +
  } s_surf_model_extension_workstation_t;
  
 +typedef struct surf_vm_workstation_model_extension_public {
 +  /* The vm workstation model object has all members of the physical machine
 +   * workstation model object. If these members are correctly initialized also
 +   * in the vm workstation model object, we can access the vm workstation model
 +   * object as if it is the pm workstatoin model object.
 +   *
 +   * But, it's not so clean. Think it again later.
 +   * */
 +  s_surf_model_extension_workstation_t basic;
 +
 +  // start does not appear here as it corresponds to turn the state from created to running (see smx_vm.c)
 +
 +  void   (*create)  (const char *name, void *ind_phys_workstation); // First operation of the VM model
 +  void   (*destroy) (void *ind_vm_ws); // will be vm_ws_destroy(), which destroies the vm-workstation-specific data
 +
 +  void   (*suspend) (void *ind_vm_ws);
 +  void   (*resume)  (void *ind_vm_ws);
 +
 +  void   (*save)    (void *ind_vm_ws);
 +  void   (*restore) (void *ind_vm_ws);
 +
 +  void   (*migrate) (void *ind_vm_ws, void *ind_vm_ws_dest); // will be vm_ws_migrate()
 +
 +  int    (*get_state) (void *ind_vm_ws);
 +  void   (*set_state) (void *ind_vm_ws, int state);
 +
 +  void * (*get_pm) (void *ind_vm_ws); // will be vm_ws_get_pm()
  
 +  void   (*set_vm_bound) (void *ind_vm_ws, double bound); // will be vm_ws_set_vm_bound()
  
 +} s_surf_model_extension_vm_workstation_t;
 +
 +/** \ingroup SURF_models
 + *  \brief Model types
 + *
 + *  The type of the model object. For example, we will have two model objects
 + *  of the surf cpu model. One is for physical machines, and the other is for
 + *  virtual machines.
 + *
 + */
 +typedef enum {
 +  SURF_MODEL_TYPE_CPU = 0,
 +  SURF_MODEL_TYPE_NETWORK,
 +  SURF_MODEL_TYPE_STORAGE,
 +  SURF_MODEL_TYPE_WORKSTATION,
 +  SURF_MODEL_TYPE_VM_WORKSTATION,
 +  SURF_MODEL_TYPE_NEW_MODEL
 +} e_surf_model_type_t;
  
  /** \ingroup SURF_models
   *  \brief Model datatype
@@@ -357,9 -293,7 +362,9 @@@ typedef struct surf_model 
    const char *name;     /**< Name of this model */
    s_surf_action_state_t states;      /**< Any living action on this model */
  
 -   e_surf_action_state_t(*action_state_get) (surf_action_t action);
 +  e_surf_model_type_t type; /**< See e_surf_model_type_t */
 +
 +  e_surf_action_state_t(*action_state_get) (surf_action_t action);
                                                                         /**< Return the state of an action */
    void (*action_state_set) (surf_action_t action,
                              e_surf_action_state_t state);
    int (*is_suspended) (surf_action_t action);     /**< Return whether an action is suspended */
    void (*set_max_duration) (surf_action_t action, double duration);     /**< Set the max duration of an action*/
    void (*set_priority) (surf_action_t action, double priority);     /**< Set the priority of an action */
 +  void (*set_bound) (surf_action_t action, double bound);     /**< Set the bound (the maximum CPU utilization) of an action */
  #ifdef HAVE_TRACING
    void (*set_category) (surf_action_t action, const char *category); /**< Set the category of an action */
  #endif
      s_surf_model_extension_network_t network;
      s_surf_model_extension_storage_t storage;
      s_surf_model_extension_workstation_t workstation;
 +    // TODO Implement the corresponding model
 +    s_surf_model_extension_vm_workstation_t vm_workstation;
      /*******************************************/
      /* TUTORIAL: New model                     */
      s_surf_model_extension_new_model_t new_model;
@@@ -426,14 -357,11 +431,14 @@@ static inline void *surf_storage_resour
    return xbt_lib_get_elm_or_null(storage_lib, name);
  }
  
 -typedef struct surf_resource {
 -  surf_model_t model;
 -  char *name;
 -  xbt_dict_t properties;
 -} s_surf_resource_t, *surf_resource_t;
 +static inline surf_model_t surf_resource_model(const void *host, int level) {
 +  /* If level is SURF_WKS_LEVEL, ws is a workstation_CLM03 object. It has
 +   * surf_resource at the generic_resource field. */
 +  surf_resource_t ws = xbt_lib_get_level((void *) host, level);
 +  return ws->model;
 +}
 +
 +
  
  /**
   * Resource which have a metric handled by a maxmin system
@@@ -458,14 -386,9 +463,14 @@@ typedef struct surf_resource_lmm 
  
  
  /** \ingroup SURF_models
 - *  \brief The CPU model
 + *  \brief The CPU model object for the physical machine layer
 + */
 +XBT_PUBLIC_DATA(surf_model_t) surf_cpu_model_pm;
 +
 +/** \ingroup SURF_models
 + *  \brief The CPU model object for the virtual machine layer
   */
 -XBT_PUBLIC_DATA(surf_model_t) surf_cpu_model;
 +XBT_PUBLIC_DATA(surf_model_t) surf_cpu_model_vm;
  
  /** \ingroup SURF_models
   *  \brief Initializes the CPU model with the model Cas01
@@@ -484,7 -407,7 +489,7 @@@ XBT_PUBLIC(void) surf_cpu_model_init_Ca
   *
   *  You shouldn't have to call it by yourself.
   */
 -XBT_PUBLIC(void) surf_cpu_model_init_ti(void);
 +XBT_PUBLIC(surf_model_t) surf_cpu_model_init_ti(void);
  
  /** \ingroup SURF_models
   *  \brief The list of all available optimization modes (both for cpu and networks).
@@@ -656,16 -579,6 +661,16 @@@ XBT_PUBLIC_DATA(s_surf_model_descriptio
   */
  XBT_PUBLIC_DATA(surf_model_t) surf_workstation_model;
  
 +/** \ingroup SURF_models
 + *  \brief The vm_workstation model
 + *
 + *  Note that when you create an API on top of SURF,
 + *  the vm_workstation model should be the only one you use
 + *  because depending on the platform model, the network model and the CPU model
 + *  may not exist.
 + */
 +XBT_PUBLIC_DATA(surf_model_t) surf_vm_workstation_model;
 +
  /** \ingroup SURF_models
   *  \brief Initializes the platform with a compound workstation model
   *
@@@ -714,7 -627,6 +719,7 @@@ XBT_PUBLIC_DATA(s_surf_model_descriptio
   *  \brief List of initialized models
   */
  XBT_PUBLIC_DATA(xbt_dynar_t) model_list;
 +XBT_PUBLIC_DATA(xbt_dynar_t) model_list_invoke;
  
  /*******************************************/
  /*** SURF Platform *************************/
diff --combined src/msg/msg_host.c
@@@ -29,30 -29,28 +29,30 @@@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(msg)
  msg_host_t __MSG_host_create(smx_host_t workstation)
  {
    const char *name = SIMIX_host_get_name(workstation);
 -  msg_host_priv_t host = xbt_new0(s_msg_host_priv_t, 1);
 -  s_msg_vm_t vm; // simply to compute the offset
 -
 -  host->vms = xbt_swag_new(xbt_swag_offset(vm,host_vms_hookup));
 +  msg_host_priv_t priv = xbt_new0(s_msg_host_priv_t, 1);
  
  #ifdef MSG_USE_DEPRECATED
    int i;
    char alias[MAX_ALIAS_NAME + 1] = { 0 };       /* buffer used to build the key of the mailbox */
  
    if (msg_global->max_channel > 0)
 -    host->mailboxes = xbt_new0(msg_mailbox_t, msg_global->max_channel);
 +    priv->mailboxes = xbt_new0(msg_mailbox_t, msg_global->max_channel);
  
    for (i = 0; i < msg_global->max_channel; i++) {
      sprintf(alias, "%s:%d", name, i);
  
      /* the key of the mailbox (in this case) is build from the name of the host and the channel number */
 -    host->mailboxes[i] = MSG_mailbox_new(alias);
 +    priv->mailboxes[i] = MSG_mailbox_new(alias);
      memset(alias, 0, MAX_ALIAS_NAME + 1);
    }
  #endif
  
 -  xbt_lib_set(host_lib,name,MSG_HOST_LEVEL,host);
 +
 +  priv->dp_objs = xbt_dict_new();
 +  priv->dp_enabled = 0;
 +  priv->dp_updated_by_deleted_tasks = 0;
 +
 +  xbt_lib_set(host_lib, name, MSG_HOST_LEVEL, priv);
    
    return xbt_lib_get_elm_or_null(host_lib, name);
  }
@@@ -116,53 -114,20 +116,53 @@@ msg_host_t MSG_host_self(void
    return MSG_process_get_host(NULL);
  }
  
 +
  /*
 - * \brief Destroys a host (internal call only)
 + * \brief Start the host if it is off
   */
 -void __MSG_host_destroy(msg_host_priv_t host) {
 +void MSG_host_on(msg_host_t host)
 +{
 +  simcall_host_on(host);
 +}
 +
 +/*
 + * \brief Stop the host if it is on
 + */
 +void MSG_host_off(msg_host_t host)
 +{ 
 +  simcall_host_off(host);
 +}
 +
 +/*
 + * \brief Frees private data of a host (internal call only)
 + */
 +void __MSG_host_priv_free(msg_host_priv_t priv)
 +{
 +  unsigned int size = xbt_dict_size(priv->dp_objs);
 +  if (size > 0)
 +    XBT_WARN("dp_objs: %u pending task?", size);
 +  xbt_dict_free(&priv->dp_objs);
  
  #ifdef MSG_USE_DEPRECATED
    if (msg_global->max_channel > 0)
 -    free(host->mailboxes);
 +    free(priv->mailboxes);
  #endif
 -  if (xbt_swag_size(host->vms) > 0 ) {
 -    XBT_VERB("Host shut down, but it still hosts %d VMs. They will be leaked.",xbt_swag_size(host->vms));
 -  }
 -  xbt_swag_free(host->vms);
 -  free(host);
 +
 +  free(priv);
 +}
 +
 +/*
 + * \brief Destroys a host (internal call only)
 + */
 +void __MSG_host_destroy(msg_host_t host)
 +{
 +  const char *name = MSG_host_get_name(host);
 +  /* TODO:
 +   * What happens if VMs still remain on this host?
 +   * Revisit here after the surf layer gets stable.
 +   **/
 +
 +  xbt_lib_unset(host_lib, name, MSG_HOST_LEVEL, 1);
  }
  
  /** \ingroup m_host_management
@@@ -237,6 -202,17 +237,17 @@@ double MSG_get_host_speed(msg_host_t h
    return (simcall_host_get_speed(h));
  }
  
+ /** \ingroup m_host_management
+  * \brief Return the number of core.
+  */
+ int MSG_get_host_core(msg_host_t h)
+ {
+   xbt_assert((h != NULL), "Invalid parameters");
+   return (simcall_host_get_core(h));
+ }
  /** \ingroup m_host_management
   * \brief Returns the value of a given host property
   *
@@@ -287,25 -263,3 +298,25 @@@ int MSG_host_is_avail(msg_host_t host
    xbt_assert((host != NULL), "Invalid parameters (host is NULL)");
    return (simcall_host_get_state(host));
  }
 +
 +/** \ingroup m_host_management
 + * \brief Set the parameters of a given host
 + *
 + * \param host a host
 + * \param params a prameter object
 + */
 +void MSG_host_set_params(msg_host_t ind_pm, ws_params_t params)
 +{
 +  simcall_host_set_params(ind_pm, params);
 +}
 +
 +/** \ingroup m_host_management
 + * \brief Get the parameters of a given host
 + *
 + * \param host a host
 + * \param params a prameter object
 + */
 +void MSG_host_get_params(msg_host_t ind_pm, ws_params_t params)
 +{
 +  simcall_host_get_params(ind_pm, params);
 +}
diff --combined src/msg/msg_process.c
@@@ -50,6 -50,12 +50,6 @@@ void MSG_process_cleanup_from_SIMIX(smx
      msg_global->process_data_cleanup(msg_proc->data);
    }
  
 -  // remove the process from its virtual machine
 -  if (msg_proc->vm) {
 -    int pos = xbt_dynar_search(msg_proc->vm->processes,&smx_proc);
 -    xbt_dynar_remove_at(msg_proc->vm->processes,pos, NULL);
 -  }
 -
    // free the MSG process
    xbt_free(msg_proc);
  }
@@@ -140,7 -146,7 +140,7 @@@ msg_process_t MSG_process_create_with_a
     be retrieved with the function \ref MSG_process_get_data.
   * \param host the location where the new process is executed.
   * \param argc first argument passed to \a code
-  * \param argv second argument passed to \a code
+  * \param argv second argument passed to \a code. WARNING, these strings are freed by the SimGrid kernel when the process exits, so they cannot be static nor shared between several processes.
   * \param properties list a properties defined for this process
   * \see msg_process_t
   * \return The new corresponding object.
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");
@@@ -248,17 -247,27 +248,27 @@@ static void _sg_cfg_cb__coll(const cha
    /* New Module missing */
    find_coll_description(table, val);
  }
+ static void _sg_cfg_cb__coll_gather(const char *name, int pos){
+   _sg_cfg_cb__coll("gather", mpi_coll_gather_description, name, pos);
+ }
  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_allgatherv(const char *name, int pos){
+   _sg_cfg_cb__coll("allgatherv", mpi_coll_allgatherv_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);  
+   _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_alltoallv(const char *name, int pos)
+ {
+   _sg_cfg_cb__coll("alltoallv", mpi_coll_alltoallv_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);  
@@@ -267,6 -276,15 +277,15 @@@ static void _sg_cfg_cb__coll_reduce(con
  {
    _sg_cfg_cb__coll("reduce", mpi_coll_reduce_description, name, pos);  
  }
+ static void _sg_cfg_cb__coll_reduce_scatter(const char *name, int pos){
+   _sg_cfg_cb__coll("reduce_scatter", mpi_coll_reduce_scatter_description, name, pos);
+ }
+ static void _sg_cfg_cb__coll_scatter(const char *name, int pos){
+   _sg_cfg_cb__coll("scatter", mpi_coll_scatter_description, name, pos);
+ }
+ static void _sg_cfg_cb__coll_barrier(const char *name, int pos){
+   _sg_cfg_cb__coll("barrier", mpi_coll_barrier_description, name, pos);
+ }
  #endif
  
  /* callback of the inclusion path */
@@@ -285,9 -303,9 +304,9 @@@ extern int _sg_do_model_check;   /* thi
  static void _sg_cfg_cb_model_check(const char *name, int pos)
  {
  #ifdef HAVE_MC
-   _sg_do_model_check = xbt_cfg_get_int(_sg_cfg_set, name);
+   _sg_do_model_check = xbt_cfg_get_boolean(_sg_cfg_set, name);
  #else
-   if (xbt_cfg_get_int(_sg_cfg_set, name)) {
+   if (xbt_cfg_get_boolean(_sg_cfg_set, name)) {
      xbt_die("You tried to activate the model-checking from the command line, but it was not compiled in. Change your settings in cmake, recompile and try again");
    }
  #endif
@@@ -297,7 -315,7 +316,7 @@@ extern int _sg_do_verbose_exit
  
  static void _sg_cfg_cb_verbose_exit(const char *name, int pos)
  {
-   _sg_do_verbose_exit = xbt_cfg_get_int(_sg_cfg_set, name);
+   _sg_do_verbose_exit = xbt_cfg_get_boolean(_sg_cfg_set, name);
  }
  
  
@@@ -342,29 -360,21 +361,21 @@@ static void _sg_cfg_cb_contexts_paralle
  static void _sg_cfg_cb__surf_network_coordinates(const char *name,
                                                     int pos)
  {
-   char *val = xbt_cfg_get_string(_sg_cfg_set, name);
-   if (!strcmp(val, "yes")) {
+   int val = xbt_cfg_get_boolean(_sg_cfg_set, name);
+   if (val) {
      if (!COORD_HOST_LEVEL) {
        COORD_HOST_LEVEL = xbt_lib_add_level(host_lib,xbt_dynar_free_voidp);
        COORD_ASR_LEVEL  = xbt_lib_add_level(as_router_lib,xbt_dynar_free_voidp);
      }
-   } else if (!strcmp(val, "no")) {
+   } else
      if (COORD_HOST_LEVEL)
        xbt_die("Setting of whether to use coordinate cannot be disabled once set.");
-   } else {
-     xbt_die("Command line setting of whether to use coordinates must be either \"yes\" or \"no\"");
-   }
- }
- static void _sg_cfg_cb_surf_nthreads(const char *name, int pos)
- {
-   surf_set_nthreads(xbt_cfg_get_int(_sg_cfg_set, name));
  }
  
  static void _sg_cfg_cb__surf_network_crosstraffic(const char *name,
                                                    int pos)
  {
-   sg_network_crosstraffic = xbt_cfg_get_int(_sg_cfg_set, name);
+   sg_network_crosstraffic = xbt_cfg_get_boolean(_sg_cfg_set, name);
  }
  
  #ifdef HAVE_GTNETS
@@@ -530,32 -540,34 +541,34 @@@ void sg_config_init(int *argc, char **a
                       xbt_cfgelm_string, NULL, 0, 0,
                       _sg_cfg_cb__surf_path, NULL);
  
-     default_value_int = 0;
+     default_value = xbt_strdup("off");
      xbt_cfg_register(&_sg_cfg_set, "cpu/maxmin_selective_update",
-                      "Update the constraint set propagating recursively to others constraints (1 by default when optim is set to lazy)",
-                      xbt_cfgelm_int, &default_value_int, 0, 1,
+                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
+                      xbt_cfgelm_boolean, &default_value, 0, 1,
                       NULL, NULL);
-     default_value_int = 0;
+     default_value = xbt_strdup("off");
      xbt_cfg_register(&_sg_cfg_set, "network/maxmin_selective_update",
-                      "Update the constraint set propagating recursively to others constraints (1 by default when optim is set to lazy)",
-                      xbt_cfgelm_int, &default_value_int, 0, 1,
+                      "Update the constraint set propagating recursively to others constraints (off by default when optim is set to lazy)",
+                      xbt_cfgelm_boolean, &default_value, 0, 1,
                       NULL, NULL);
  
  #ifdef HAVE_MC
      /* do model-checking */
+     default_value = xbt_strdup("off");
      xbt_cfg_register(&_sg_cfg_set, "model-check",
                       "Verify the system through model-checking instead of simulating it (EXPERIMENTAL)",
-                      xbt_cfgelm_int, NULL, 0, 1,
+                      xbt_cfgelm_boolean, NULL, 0, 1,
                       _sg_cfg_cb_model_check, NULL);
-     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check", 0);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", default_value);
  
      /* do stateful model-checking */
+     default_value = xbt_strdup("off");
      xbt_cfg_register(&_sg_cfg_set, "model-check/checkpoint",
-                      "Specify the amount of steps between checkpoints during stateful model-checking (default: 0 => stateless verification). "
-                      "If value=1, one checkpoint is saved for each step => faster verification, but huge memory consumption; higher values are good compromises between speed and memory consumption.",
-                      xbt_cfgelm_int, NULL, 0, 1,
+                      "Specify the amount of steps between checkpoints during stateful model-checking (default: off => stateless verification). "
+                      "If value=on, one checkpoint is saved for each step => faster verification, but huge memory consumption; higher values are good compromises between speed and memory consumption.",
+                      xbt_cfgelm_boolean, NULL, 0, 1,
                       _mc_cfg_cb_checkpoint, NULL);
-     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/checkpoint", default_value);
      
      /* do liveness model-checking */
      xbt_cfg_register(&_sg_cfg_set, "model-check/property",
      xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/reduction", "dpor");
  
      /* Enable/disable timeout for wait requests with model-checking */
+     default_value = xbt_strdup("off");
      xbt_cfg_register(&_sg_cfg_set, "model-check/timeout",
                       "Enable/Disable timeout for wait requests",
-                      xbt_cfgelm_int, NULL, 0, 1,
+                      xbt_cfgelm_boolean, NULL, 0, 1,
                       _mc_cfg_cb_timeout, NULL);
-     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/timeout", 0);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", default_value);
  
      /* Set max depth exploration */
      xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
  #endif
  
      /* do verbose-exit */
-     default_value_int = 1;
+     default_value = xbt_strdup("on");
      xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
                       "Activate the \"do nothing\" mode in Ctrl-C",
-                      xbt_cfgelm_int, &default_value_int, 0, 1,
+                      xbt_cfgelm_boolean, &default_value, 0, 1,
                       _sg_cfg_cb_verbose_exit, NULL);
      
      
          xbt_cfgelm_string, &default_value, 1, 1,
          _sg_cfg_cb_contexts_parallel_mode, NULL);
  
-     /* number of parallel threads for Surf */
-     default_value_int = surf_get_nthreads();
-     xbt_cfg_register(&_sg_cfg_set, "surf/nthreads",
-                      "Number of parallel threads used to update Surf models",
-                      xbt_cfgelm_int, &default_value_int, 1, 1,
-                      _sg_cfg_cb_surf_nthreads, NULL);
      default_value = xbt_strdup("no");
      xbt_cfg_register(&_sg_cfg_set, "network/coordinates",
                       "\"yes\" or \"no\", specifying whether we use a coordinate-based routing (as Vivaldi)",
-                      xbt_cfgelm_string, &default_value, 1, 1,
+                      xbt_cfgelm_boolean, &default_value, 1, 1,
                       _sg_cfg_cb__surf_network_coordinates, NULL);
-     xbt_cfg_setdefault_string(_sg_cfg_set, "network/coordinates", default_value);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", default_value);
  
-     default_value_int = 0;
+     default_value = xbt_strdup("no");
      xbt_cfg_register(&_sg_cfg_set, "network/crosstraffic",
                       "Activate the interferences between uploads and downloads for fluid max-min models (LV08, CM02)",
-                      xbt_cfgelm_int, &default_value_int, 0, 1,
+                      xbt_cfgelm_boolean, &default_value, 0, 1,
                       _sg_cfg_cb__surf_network_crosstraffic, NULL);
-     xbt_cfg_setdefault_int(_sg_cfg_set, "network/crosstraffic", default_value_int);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", default_value);
  
  #ifdef HAVE_GTNETS
      xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter",
                       xbt_cfgelm_double, &default_reference_speed, 1, 1, NULL,
                       NULL);
  
-     int default_display_timing = 0;
+     default_value = xbt_strdup("no");
      xbt_cfg_register(&_sg_cfg_set, "smpi/display_timing",
                       "Boolean indicating whether we should display the timing after simulation.",
-                      xbt_cfgelm_int, &default_display_timing, 1, 1, NULL,
+                      xbt_cfgelm_boolean, &default_value, 1, 1, NULL,
                       NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", default_value);
  
      double default_threshold = 1e-6;
      xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold",
                       xbt_cfgelm_string, NULL, 1, 1, NULL,
                       NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/or", "1:0:0:0:0");
+     double default_iprobe_time = 1e-4;
+     xbt_cfg_register(&_sg_cfg_set, "smpi/iprobe",
+                      "Minimum time to inject inside a call to MPI_Iprobe",
+                      xbt_cfgelm_double, &default_iprobe_time, 1, 1, NULL,
+                      NULL);
      default_value = xbt_strdup("default");
+     xbt_cfg_register(&_sg_cfg_set, "smpi/coll_selector",
+                    "Which collective selector to use",
+                    xbt_cfgelm_string, &default_value, 1, 1, NULL,
+                    NULL);
+                    
+               xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
+                    "Which collective to use for gather",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_gather,
+                    NULL);
+                    
      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,
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_allgather,
+                    NULL);
+     xbt_cfg_register(&_sg_cfg_set, "smpi/barrier",
+                    "Which collective to use for barrier",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_barrier,
+                    NULL);
+     xbt_cfg_register(&_sg_cfg_set, "smpi/reduce_scatter",
+                    "Which collective to use for reduce_scatter",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_reduce_scatter,
+                    NULL);
+     xbt_cfg_register(&_sg_cfg_set, "smpi/scatter",
+                    "Which collective to use for scatter",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_scatter,
+                    NULL);
+     xbt_cfg_register(&_sg_cfg_set, "smpi/allgatherv",
+                    "Which collective to use for allgatherv",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_allgatherv,
                     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,
+                    xbt_cfgelm_string, NULL, 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,
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_alltoall,
                     NULL);
  
+     xbt_cfg_register(&_sg_cfg_set, "smpi/alltoallv",
+                    "Which collective to use for alltoallv",
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_alltoallv,
+                    NULL);
  
-     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,
+                    xbt_cfgelm_string, NULL, 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,
+                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_reduce,
                     NULL);
  #endif // HAVE_SMPI
  
@@@ -876,9 -916,6 +917,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();
@@@ -906,6 -943,10 +947,10 @@@ char* sg_cfg_get_string(const char* nam
  {
        return xbt_cfg_get_string(_sg_cfg_set,name);
  }
+ int sg_cfg_get_boolean(const char* name)
+ {
+       return xbt_cfg_get_boolean(_sg_cfg_set,name);
+ }
  void sg_cfg_get_peer(const char *name, char **peer, int *port)
  {
        xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
diff --combined src/simix/smx_global.c
@@@ -64,7 -64,7 +64,7 @@@ void SIMIX_global_init(int *argc, char 
  #ifdef TIME_BENCH_AMDAHL
      simix_global->timer_seq = xbt_os_timer_new();
      simix_global->timer_par = xbt_os_timer_new();
-     xbt_os_timer_start(simix_global->timer_seq);
+     xbt_os_cputimer_start(simix_global->timer_seq);
  #endif
      simix_global->process_to_run = xbt_dynar_new(sizeof(smx_process_t), NULL);
      simix_global->process_that_ran = xbt_dynar_new(sizeof(smx_process_t), NULL);
@@@ -156,7 -156,7 +156,7 @@@ static void SIMIX_clean(void
    surf_exit();
  
  #ifdef TIME_BENCH_AMDAHL
-   xbt_os_timer_stop(simix_global->timer_seq);
+   xbt_os_cputimer_stop(simix_global->timer_seq);
    XBT_INFO("Amdhal timing informations. Sequential time: %lf; Parallel time: %lf",
             xbt_os_timer_elapsed(simix_global->timer_seq),
             xbt_os_timer_elapsed(simix_global->timer_par));
@@@ -226,13 -226,13 +226,13 @@@ void SIMIX_run(void
  
        /* Run all processes that are ready to run, possibly in parallel */
  #ifdef TIME_BENCH_AMDAHL
-       xbt_os_timer_stop(simix_global->timer_seq);
-       xbt_os_timer_resume(simix_global->timer_par);
+       xbt_os_cputimer_stop(simix_global->timer_seq);
+       xbt_os_cputimer_resume(simix_global->timer_par);
  #endif
        SIMIX_process_runall();
  #ifdef TIME_BENCH_AMDAHL
-       xbt_os_timer_stop(simix_global->timer_par);
-       xbt_os_timer_resume(simix_global->timer_seq);
+       xbt_os_cputimer_stop(simix_global->timer_par);
+       xbt_os_cputimer_resume(simix_global->timer_seq);
  #endif
  
        /* Move all killing processes to the end of the list, because killing a process that have an ongoing simcall is a bad idea */
        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_host.c
@@@ -38,62 -38,6 +38,62 @@@ smx_host_t SIMIX_host_create(const cha
    return xbt_lib_get_elm_or_null(host_lib, name);
  }
  
- void SIMIX_pre_host_on(smx_host_t h)
++void SIMIX_pre_host_on(smx_simcall_t simcall, smx_host_t h)
 +{
 +  SIMIX_host_on(h);
 +}
 +
 +/**
 + * \brief Start the host if it is off
 + *
 + */
 +void SIMIX_host_on(smx_host_t h)
 +{
 +  smx_host_priv_t host = (smx_host_priv_t) h;
 +
 +  xbt_assert((host != NULL), "Invalid parameters");
 +  
 +  surf_model_t ws_model = surf_resource_model(h, SURF_WKS_LEVEL);
 +  ws_model->extension.workstation.set_state(host, SURF_RESOURCE_ON);
 +
 +  SIMIX_host_restart_processes(h);
 +}
 +
- void SIMIX_pre_host_off(smx_host_t h)
++void SIMIX_pre_host_off(smx_simcall_t simcall, smx_host_t h)
 +{
 +  SIMIX_host_off(h);
 +}
 +
 +/**
 + * \brief Stop the host if it is on
 + *
 + */
 +void SIMIX_host_off(smx_host_t h)
 +{
 +  smx_host_priv_t host = (smx_host_priv_t) h;
 +
 +  xbt_assert((host != NULL), "Invalid parameters");
 +
 +  /* Clean Simulator data */
 +  if (xbt_swag_size(host->process_list) != 0) {
 +    char *msg = xbt_strdup("Shutting down host, but it's not empty:");
 +    char *tmp;
 +    smx_process_t process = NULL;
 +
 +    xbt_swag_foreach(process, host->process_list) {
 +      tmp = bprintf("%s\n\t%s", msg, process->name);
 +      free(msg);
 +      msg = tmp;
 +    }
 +    SIMIX_display_process_status();
 +    THROWF(arg_error, 0, "%s", msg);
 +  }
 +  xbt_swag_free(host->process_list);
 +
 +  surf_model_t ws_model = surf_resource_model(h, SURF_WKS_LEVEL);
 +  ws_model->extension.workstation.set_state(host, SURF_RESOURCE_OFF);
 +}
 +
  /**
   * \brief Internal function to destroy a SIMIX host.
   *
@@@ -191,8 -135,7 +191,8 @@@ xbt_dict_t SIMIX_pre_host_get_propertie
  xbt_dict_t SIMIX_host_get_properties(smx_host_t host){
    xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
  
 -  return surf_workstation_model->extension.workstation.get_properties(host);
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +  return ws_model->extension.workstation.get_properties(host);
  }
  
  double SIMIX_pre_host_get_speed(smx_simcall_t simcall, smx_host_t host){
  double SIMIX_host_get_speed(smx_host_t host){
    xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
  
 -  return surf_workstation_model->extension.workstation.
 -      get_speed(host, 1.0);
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +  return ws_model->extension.workstation.get_speed(host, 1.0);
  }
  
+ int SIMIX_pre_host_get_core(smx_simcall_t simcall, smx_host_t host){
+   return SIMIX_host_get_core(host);
+ }
+ int SIMIX_host_get_core(smx_host_t host){
+   xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+   return surf_workstation_model->extension.workstation.
+       get_core(host);
+ }
  double SIMIX_pre_host_get_available_speed(smx_simcall_t simcall, smx_host_t host){
    return SIMIX_host_get_available_speed(host);
  }
  double SIMIX_host_get_available_speed(smx_host_t host){
    xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
  
 -  return surf_workstation_model->extension.workstation.
 -      get_available_speed(host);
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +  return ws_model->extension.workstation.get_available_speed(host);
  }
  
  int SIMIX_pre_host_get_state(smx_simcall_t simcall, smx_host_t host){
  int SIMIX_host_get_state(smx_host_t host){
    xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
  
 -  return surf_workstation_model->extension.workstation.
 -      get_state(host);
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +  return ws_model->extension.workstation.get_state(host);
  }
  
  void* SIMIX_pre_host_self_get_data(smx_simcall_t simcall){
@@@ -361,11 -316,11 +373,11 @@@ void SIMIX_host_set_data(smx_host_t hos
  }
  
  smx_action_t SIMIX_pre_host_execute(smx_simcall_t simcall,const char *name,
 -    smx_host_t host, double computation_amount, double priority){
 -  return SIMIX_host_execute(name, host, computation_amount, priority);
 +    smx_host_t host, double computation_amount, double priority, double bound){
 +  return SIMIX_host_execute(name, host, computation_amount, priority, bound);
  }
  smx_action_t SIMIX_host_execute(const char *name,
 -    smx_host_t host, double computation_amount, double priority){
 +    smx_host_t host, double computation_amount, double priority, double bound){
  
    /* alloc structures and initialize */
    smx_action_t action = xbt_mallocator_get(simix_global->action_mallocator);
    action->category = NULL;
  #endif
  
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
    /* set surf's action */
    if (!MC_is_active()) {
 -    action->execution.surf_exec =
 -      surf_workstation_model->extension.workstation.execute(host,
 -    computation_amount);
 -    surf_workstation_model->action_data_set(action->execution.surf_exec, action);
 -    surf_workstation_model->set_priority(action->execution.surf_exec, priority);
 +    action->execution.surf_exec = ws_model->extension.workstation.execute(host, computation_amount);
 +    ws_model->action_data_set(action->execution.surf_exec, action);
 +    ws_model->set_priority(action->execution.surf_exec, priority);
 +    ws_model->set_bound(action->execution.surf_exec, bound);
    }
  
    XBT_DEBUG("Create execute action %p", action);
@@@ -423,54 -378,28 +435,54 @@@ smx_action_t SIMIX_host_parallel_execut
    for (i = 0; i < host_nb; i++)
      workstation_list[i] = host_list[i];
  
 +
 +  /* FIXME: what happens if host_list contains VMs and PMs. If
 +   * execute_parallel_task() does not change the state of the model, we can mix
 +   * them. */
 +  surf_model_t ws_model = surf_resource_model(host_list[0], SURF_WKS_LEVEL);
 +  for (i = 1; i < host_nb; i++) {
 +    surf_model_t ws_model_tmp = surf_resource_model(host_list[i], SURF_WKS_LEVEL);
 +    if (ws_model_tmp != ws_model) {
 +      XBT_CRITICAL("mixing VMs and PMs is not supported");
 +      DIE_IMPOSSIBLE;
 +    }
 +  }
 +
    /* set surf's action */
    if (!MC_is_active()) {
      action->execution.surf_exec =
 -      surf_workstation_model->extension.workstation.
 +      ws_model->extension.workstation.
        execute_parallel_task(host_nb, workstation_list, computation_amount,
                        communication_amount, rate);
  
 -    surf_workstation_model->action_data_set(action->execution.surf_exec, action);
 +    ws_model->action_data_set(action->execution.surf_exec, action);
    }
    XBT_DEBUG("Create parallel execute action %p", action);
  
    return action;
  }
  
 +static surf_model_t get_ws_model_from_action(smx_action_t action)
 +{
 +  xbt_assert(action->type == SIMIX_ACTION_EXECUTE);
 +  smx_host_t host = action->execution.host;
 +  surf_model_t model = surf_resource_model(host, SURF_WKS_LEVEL);
 +
 +  xbt_assert((model == surf_workstation_model) || (model == surf_vm_workstation_model));
 +
 +  return model;
 +}
 +
  void SIMIX_pre_host_execution_destroy(smx_simcall_t simcall, smx_action_t action){
    SIMIX_host_execution_destroy(action);
  }
  void SIMIX_host_execution_destroy(smx_action_t action){
    XBT_DEBUG("Destroy action %p", action);
  
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
    if (action->execution.surf_exec) {
 -    surf_workstation_model->action_unref(action->execution.surf_exec);
 +    ws_model->action_unref(action->execution.surf_exec);
      action->execution.surf_exec = NULL;
    }
    xbt_free(action->name);
@@@ -483,10 -412,8 +495,10 @@@ void SIMIX_pre_host_execution_cancel(sm
  void SIMIX_host_execution_cancel(smx_action_t action){
    XBT_DEBUG("Cancel action %p", action);
  
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
    if (action->execution.surf_exec)
 -    surf_workstation_model->action_cancel(action->execution.surf_exec);
 +    ws_model->action_cancel(action->execution.surf_exec);
  }
  
  double SIMIX_pre_host_execution_get_remains(smx_simcall_t simcall, smx_action_t action){
  }
  double SIMIX_host_execution_get_remains(smx_action_t action){
    double result = 0.0;
 +  surf_model_t ws_model = get_ws_model_from_action(action);
  
    if (action->state == SIMIX_RUNNING)
 -    result = surf_workstation_model->get_remains(action->execution.surf_exec);
 +    result = ws_model->get_remains(action->execution.surf_exec);
  
    return result;
  }
@@@ -511,24 -437,11 +523,24 @@@ e_smx_state_t SIMIX_host_execution_get_
  
  void SIMIX_pre_host_execution_set_priority(smx_simcall_t simcall, smx_action_t action,
                                        double priority){
 -  return SIMIX_host_execution_set_priority(action, priority);
 +  SIMIX_host_execution_set_priority(action, priority);
  }
  void SIMIX_host_execution_set_priority(smx_action_t action, double priority){
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
 +  if(action->execution.surf_exec)
 +    ws_model->set_priority(action->execution.surf_exec, priority);
 +}
 +
 +void SIMIX_pre_host_execution_set_bound(smx_simcall_t simcall, smx_action_t action,
 +                                      double bound){
 +  SIMIX_host_execution_set_bound(action, bound);
 +}
 +void SIMIX_host_execution_set_bound(smx_action_t action, double bound){
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
    if(action->execution.surf_exec)
 -    surf_workstation_model->set_priority(action->execution.surf_exec, priority);
 +    ws_model->set_bound(action->execution.surf_exec, bound);
  }
  
  void SIMIX_pre_host_execution_wait(smx_simcall_t simcall, smx_action_t action){
  
  void SIMIX_host_execution_suspend(smx_action_t action)
  {
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
    if(action->execution.surf_exec)
 -    surf_workstation_model->suspend(action->execution.surf_exec);
 +    ws_model->suspend(action->execution.surf_exec);
  }
  
  void SIMIX_host_execution_resume(smx_action_t action)
  {
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
    if(action->execution.surf_exec)
 -    surf_workstation_model->resume(action->execution.surf_exec);
 +    ws_model->resume(action->execution.surf_exec);
  }
  
  void SIMIX_execution_finish(smx_action_t action)
  {
    xbt_fifo_item_t item;
    smx_simcall_t simcall;
 +  surf_model_t ws_model = get_ws_model_from_action(action);
  
    xbt_fifo_foreach(action->simcalls, item, simcall, smx_simcall_t) {
  
              (int)action->state);
      }
      /* check if the host is down */
 -    if (surf_workstation_model->extension.
 -        workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
 +    if (ws_model->extension.workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
        simcall->issuer->context->iwannadie = 1;
      }
  
    SIMIX_host_execution_destroy(action);
  }
  
 +
  void SIMIX_post_host_execute(smx_action_t action)
  {
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
    if (action->type == SIMIX_ACTION_EXECUTE && /* FIMXE: handle resource failure
                                                 * for parallel tasks too */
 -      surf_workstation_model->extension.workstation.get_state(action->execution.host) == SURF_RESOURCE_OFF) {
 +      ws_model->extension.workstation.get_state(action->execution.host) == SURF_RESOURCE_OFF) {
      /* If the host running the action failed, notice it so that the asking
       * process can be killed if it runs on that host itself */
      action->state = SIMIX_FAILED;
 -  } else if (surf_workstation_model->action_state_get(action->execution.surf_exec) == SURF_ACTION_FAILED) {
 +  } else if (ws_model->action_state_get(action->execution.surf_exec) == SURF_ACTION_FAILED) {
      /* If the host running the action didn't fail, then the action was
       * canceled */
      action->state = SIMIX_CANCELED;
    }
  
    if (action->execution.surf_exec) {
 -    surf_workstation_model->action_unref(action->execution.surf_exec);
 +    ws_model->action_unref(action->execution.surf_exec);
      action->execution.surf_exec = NULL;
    }
  
@@@ -649,44 -555,12 +661,44 @@@ void SIMIX_pre_set_category(smx_simcall
  }
  void SIMIX_set_category(smx_action_t action, const char *category)
  {
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
    if (action->state != SIMIX_RUNNING) return;
    if (action->type == SIMIX_ACTION_EXECUTE){
 -    surf_workstation_model->set_category(action->execution.surf_exec, category);
 +    ws_model->set_category(action->execution.surf_exec, category);
    }else if (action->type == SIMIX_ACTION_COMMUNICATE){
 -    surf_workstation_model->set_category(action->comm.surf_comm, category);
 +    ws_model->set_category(action->comm.surf_comm, category);
    }
  }
  #endif
  
 +
 +/**
 + * \brief Function to get the parameters of the given the SIMIX host.
 + *
 + * \param host the host to get_phys_host (a smx_host_t)
 + * \param param the parameter object space to be overwritten (a ws_params_t)
 + */
 +void SIMIX_host_get_params(smx_host_t ind_vm, ws_params_t params)
 +{
 +  /* jump to ws_get_params(). */
 +  surf_workstation_model->extension.workstation.get_params(ind_vm, params);
 +}
 +
 +void SIMIX_pre_host_get_params(smx_simcall_t simcall, smx_host_t ind_vm, ws_params_t params)
 +{
 +  SIMIX_host_get_params(ind_vm, params);
 +  SIMIX_simcall_answer(simcall);
 +}
 +
 +void SIMIX_host_set_params(smx_host_t ind_vm, ws_params_t params)
 +{
 +  /* jump to ws_set_params(). */
 +  surf_workstation_model->extension.workstation.set_params(ind_vm, params);
 +}
 +
 +void SIMIX_pre_host_set_params(smx_simcall_t simcall, smx_host_t ind_vm, ws_params_t params)
 +{
 +  SIMIX_host_set_params(ind_vm, params);
 +  SIMIX_simcall_answer(simcall);
 +}
@@@ -38,11 -38,12 +38,14 @@@ void SIMIX_host_add_auto_restart_proces
  void SIMIX_host_restart_processes(smx_host_t host);
  void SIMIX_host_autorestart(smx_host_t host);
  xbt_dict_t SIMIX_host_get_properties(smx_host_t host);
+ int SIMIX_host_get_core(smx_host_t host);
  double SIMIX_host_get_speed(smx_host_t host);
  double SIMIX_host_get_available_speed(smx_host_t host);
  int SIMIX_host_get_state(smx_host_t host);
++void SIMIX_host_on(smx_host_t host);
++void SIMIX_host_off(smx_host_t host);
  smx_action_t SIMIX_host_execute(const char *name,
 -    smx_host_t host, double computation_amount, double priority);
 +    smx_host_t host, double computation_amount, double priority, double bound);
  smx_action_t SIMIX_host_parallel_execute(const char *name,
      int host_nb, smx_host_t *host_list,
      double *computation_amount, double *communication_amount,
@@@ -52,21 -53,21 +55,24 @@@ void SIMIX_host_execution_cancel(smx_ac
  double SIMIX_host_execution_get_remains(smx_action_t action);
  e_smx_state_t SIMIX_host_execution_get_state(smx_action_t action);
  void SIMIX_host_execution_set_priority(smx_action_t action, double priority);
 +void SIMIX_host_execution_set_bound(smx_action_t action, double bound);
  void SIMIX_pre_host_execution_wait(smx_simcall_t simcall, smx_action_t action);
  
  // pre prototypes
  smx_host_t SIMIX_pre_host_get_by_name(smx_simcall_t, const char*);
  const char* SIMIX_pre_host_self_get_name(smx_simcall_t);
  const char* SIMIX_pre_host_get_name(smx_simcall_t, smx_host_t);
++void SIMIX_pre_host_on(smx_simcall_t, smx_host_t host);
++void SIMIX_pre_host_off(smx_simcall_t, smx_host_t host);
  xbt_dict_t SIMIX_pre_host_get_properties(smx_simcall_t, smx_host_t);
+ int SIMIX_pre_host_get_core(smx_simcall_t, smx_host_t);
  double SIMIX_pre_host_get_speed(smx_simcall_t, smx_host_t);
  double SIMIX_pre_host_get_available_speed(smx_simcall_t, smx_host_t);
  int SIMIX_pre_host_get_state(smx_simcall_t, smx_host_t);
  void* SIMIX_pre_host_self_get_data(smx_simcall_t);
  void* SIMIX_pre_host_get_data(smx_simcall_t, smx_host_t);
  void SIMIX_pre_host_set_data(smx_simcall_t, smx_host_t, void*);
 -smx_action_t SIMIX_pre_host_execute(smx_simcall_t, const char*, smx_host_t, double, double);
 +smx_action_t SIMIX_pre_host_execute(smx_simcall_t, const char*, smx_host_t, double, double, double);
  smx_action_t SIMIX_pre_host_parallel_execute(smx_simcall_t, const char*, int, smx_host_t*,
                                               double*, double*, double, double);
  void SIMIX_pre_host_execution_destroy(smx_simcall_t, smx_action_t);
@@@ -74,7 -75,6 +80,7 @@@ void SIMIX_pre_host_execution_cancel(sm
  double SIMIX_pre_host_execution_get_remains(smx_simcall_t, smx_action_t);
  e_smx_state_t SIMIX_pre_host_execution_get_state(smx_simcall_t, smx_action_t);
  void SIMIX_pre_host_execution_set_priority(smx_simcall_t, smx_action_t, double);
 +void SIMIX_pre_host_execution_set_bound(smx_simcall_t simcall, smx_action_t action, double bound);
  
  void SIMIX_host_execution_suspend(smx_action_t action);
  void SIMIX_host_execution_resume(smx_action_t action);
@@@ -87,53 -87,5 +93,53 @@@ void SIMIX_pre_set_category(smx_simcall
  void SIMIX_set_category(smx_action_t action, const char *category);
  #endif
  
 +
 +
 +/* vm related stuff */
 +smx_host_t SIMIX_vm_create(const char *name, smx_host_t ind_phys_host);
 +smx_host_t SIMIX_pre_vm_create(smx_simcall_t simcall, const char *name, smx_host_t ind_phys_host);
 +
 +void SIMIX_vm_destroy(smx_host_t ind_vm);
 +void SIMIX_pre_vm_destroy(smx_simcall_t simcall, smx_host_t ind_vm);
 +// --
 +void SIMIX_vm_resume(smx_host_t ind_vm, smx_process_t issuer);
 +void SIMIX_pre_vm_resume(smx_simcall_t simcall, smx_host_t ind_vm);
 +
 +void SIMIX_vm_suspend(smx_host_t ind_vm, smx_process_t issuer);
 +void SIMIX_pre_vm_suspend(smx_simcall_t simcall, smx_host_t ind_vm);
 +// --
 +void SIMIX_vm_save(smx_host_t ind_vm, smx_process_t issuer);
 +void SIMIX_pre_vm_save(smx_simcall_t simcall, smx_host_t ind_vm);
 +
 +void SIMIX_vm_restore(smx_host_t ind_vm, smx_process_t issuer);
 +void SIMIX_pre_vm_restore(smx_simcall_t simcall, smx_host_t ind_vm);
 +// --
 +void SIMIX_vm_start(smx_host_t ind_vm);
 +void SIMIX_pre_vm_start(smx_simcall_t simcall, smx_host_t ind_vm);
 +
 +void SIMIX_vm_shutdown(smx_host_t ind_vm, smx_process_t issuer);
 +void SIMIX_pre_vm_shutdown(smx_simcall_t simcall, smx_host_t ind_vm);
 +// --
 +void SIMIX_vm_set_state(smx_host_t ind_vm, int state);
 +void SIMIX_pre_vm_set_state(smx_simcall_t simcall, smx_host_t ind_vm, int state);
 +
 +int SIMIX_vm_get_state(smx_host_t ind_vm);
 +int SIMIX_pre_vm_get_state(smx_simcall_t simcall, smx_host_t ind_vm);
 +// --
 +void SIMIX_vm_migrate(smx_host_t ind_vm, smx_host_t ind_dst_pm);
 +void SIMIX_pre_vm_migrate(smx_simcall_t simcall, smx_host_t ind_vm, smx_host_t ind_dst_pm);
 +
 +void *SIMIX_vm_get_pm(smx_host_t ind_vm);
 +void *SIMIX_pre_vm_get_pm(smx_simcall_t simcall, smx_host_t ind_vm);
 +
 +void SIMIX_vm_set_bound(smx_host_t ind_vm, double bound);
 +void SIMIX_pre_vm_set_bound(smx_simcall_t simcall, smx_host_t ind_vm, double bound);
 +
 +void SIMIX_host_get_params(smx_host_t ind_vm, ws_params_t params);
 +void SIMIX_pre_host_get_params(smx_simcall_t simcall, smx_host_t ind_vm, ws_params_t params);
 +
 +void SIMIX_host_set_params(smx_host_t ind_vm, ws_params_t params);
 +void SIMIX_pre_host_set_params(smx_simcall_t simcall, smx_host_t ind_vm, ws_params_t params);
 +
  #endif
  
diff --combined src/simix/smx_io.c
@@@ -5,6 -5,7 +5,7 @@@
   * under the terms of the license (GNU LGPL) which comes with this package. */
  
  #include "smx_private.h"
+ #include "surf/storage_private.h"
  #include "xbt/sysdep.h"
  #include "xbt/log.h"
  #include "xbt/dict.h"
@@@ -16,14 -17,15 +17,15 @@@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_i
  
  //SIMIX FILE READ
  void SIMIX_pre_file_read(smx_simcall_t simcall, void *ptr, size_t size,
-                        size_t nmemb, smx_file_t stream)
+                       smx_file_t fd)
  {
-   smx_action_t action = SIMIX_file_read(simcall->issuer, ptr, size, nmemb, stream);
+   smx_action_t action = SIMIX_file_read(simcall->issuer, ptr, size, fd);
    xbt_fifo_push(action->simcalls, simcall);
    simcall->issuer->waiting_action = action;
  }
  
- smx_action_t SIMIX_file_read(smx_process_t process, void* ptr, size_t size, size_t nmemb, smx_file_t stream)
+ smx_action_t SIMIX_file_read(smx_process_t process, void* ptr, size_t size,
+                              smx_file_t fd)
  {
    smx_action_t action;
    smx_host_t host = process->smx_host;
@@@ -43,7 -45,9 +45,9 @@@
  #endif
  
    action->io.host = host;
-   action->io.surf_io = surf_workstation_model->extension.workstation.read(host, ptr, size, nmemb, stream->surf_file);
+   action->io.surf_io =
+       surf_workstation_model->extension.workstation.read(host, ptr, size,
+                                                          fd->surf_file);
  
    surf_workstation_model->action_data_set(action->io.surf_io, action);
    XBT_DEBUG("Create io action %p", action);
  
  //SIMIX FILE WRITE
  void SIMIX_pre_file_write(smx_simcall_t simcall, const void *ptr, size_t size,
-                         size_t nmemb, smx_file_t stream)
+                         smx_file_t fd)
  {
-   smx_action_t action = SIMIX_file_write(simcall->issuer, ptr, size, nmemb, stream);
+   smx_action_t action = SIMIX_file_write(simcall->issuer, ptr, size, fd);
    xbt_fifo_push(action->simcalls, simcall);
    simcall->issuer->waiting_action = action;
  }
  
- smx_action_t SIMIX_file_write(smx_process_t process, const void* ptr, size_t size, size_t nmemb, smx_file_t stream)
+ smx_action_t SIMIX_file_write(smx_process_t process, const void* ptr,
+                               size_t size, smx_file_t fd)
  {
    smx_action_t action;
    smx_host_t host = process->smx_host;
@@@ -80,7 -85,9 +85,9 @@@
  #endif
  
    action->io.host = host;
-   action->io.surf_io = surf_workstation_model->extension.workstation.write(host, ptr, size, nmemb, stream->surf_file);
+   action->io.surf_io =
+       surf_workstation_model->extension.workstation.write(host, ptr, size,
+                                                           fd->surf_file);
  
    surf_workstation_model->action_data_set(action->io.surf_io, action);
    XBT_DEBUG("Create io action %p", action);
  
  //SIMIX FILE OPEN
  void SIMIX_pre_file_open(smx_simcall_t simcall, const char* mount,
-                        const char* path, const char* mode)
+                          const char* path)
  {
-   smx_action_t action = SIMIX_file_open(simcall->issuer, mount, path, mode);
+   smx_action_t action = SIMIX_file_open(simcall->issuer, mount, path);
    xbt_fifo_push(action->simcalls, simcall);
    simcall->issuer->waiting_action = action;
  }
  
- smx_action_t SIMIX_file_open(smx_process_t process ,const char* mount, const char* path, const char* mode)
+ smx_action_t SIMIX_file_open(smx_process_t process ,const char* mount,
+                              const char* path)
  {
    smx_action_t action;
    smx_host_t host = process->smx_host;
  #endif
  
    action->io.host = host;
-   action->io.surf_io = surf_workstation_model->extension.workstation.open(host, mount, path, mode);
+   action->io.surf_io =
+       surf_workstation_model->extension.workstation.open(host, mount, path);
  
    surf_workstation_model->action_data_set(action->io.surf_io, action);
    XBT_DEBUG("Create io action %p", action);
  }
  
  //SIMIX FILE CLOSE
- void SIMIX_pre_file_close(smx_simcall_t simcall, smx_file_t fp)
+ void SIMIX_pre_file_close(smx_simcall_t simcall, smx_file_t fd)
  {
-   smx_action_t action = SIMIX_file_close(simcall->issuer, fp);
+   smx_action_t action = SIMIX_file_close(simcall->issuer, fd);
    xbt_fifo_push(action->simcalls, simcall);
    simcall->issuer->waiting_action = action;
  }
  
- smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fp)
+ smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fd)
  {
    smx_action_t action;
    smx_host_t host = process->smx_host;
  #endif
  
    action->io.host = host;
-   action->io.surf_io = surf_workstation_model->extension.workstation.close(host, fp->surf_file);
+   action->io.surf_io = surf_workstation_model->extension.workstation.close(host, fd->surf_file);
  
    surf_workstation_model->action_data_set(action->io.surf_io, action);
    XBT_DEBUG("Create io action %p", action);
    return action;
  }
  
- //SIMIX FILE STAT
- void SIMIX_pre_file_stat(smx_simcall_t simcall, smx_file_t fd, s_file_stat_t *buf)
- {
-   smx_action_t action = SIMIX_file_stat(simcall->issuer, fd, *buf);
-   xbt_fifo_push(action->simcalls, simcall);
-   simcall->issuer->waiting_action = action;
- }
- smx_action_t SIMIX_file_stat(smx_process_t process, smx_file_t fd, s_file_stat_t buf)
- {
-   smx_action_t action;
-   smx_host_t host = process->smx_host;
-   /* check if the host is active */
-   if (surf_workstation_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 = xbt_mallocator_get(simix_global->action_mallocator);
-   action->type = SIMIX_ACTION_IO;
-   action->name = NULL;
- #ifdef HAVE_TRACING
-   action->category = NULL;
- #endif
-   action->io.host = host;
-   action->io.surf_io = surf_workstation_model->extension.workstation.stat(host, fd->surf_file);
-   surf_workstation_model->action_data_set(action->io.surf_io, action);
-   XBT_DEBUG("Create io action %p", action);
-   return action;
- }
  
  //SIMIX FILE UNLINK
void SIMIX_pre_file_unlink(smx_simcall_t simcall, smx_file_t fd)
int SIMIX_pre_file_unlink(smx_simcall_t simcall, smx_file_t fd)
  {
-   smx_action_t action = SIMIX_file_unlink(simcall->issuer, fd);
-   xbt_fifo_push(action->simcalls, simcall);
-   simcall->issuer->waiting_action = action;
+   return SIMIX_file_unlink(simcall->issuer, fd);
  }
  
smx_action_t SIMIX_file_unlink(smx_process_t process, smx_file_t fd)
int SIMIX_file_unlink(smx_process_t process, smx_file_t fd)
  {
-   smx_action_t action;
    smx_host_t host = process->smx_host;
    /* check if the host is active */
    if (surf_workstation_model->extension.
             sg_host_name(host));
    }
  
-   action = xbt_mallocator_get(simix_global->action_mallocator);
-   action->type = SIMIX_ACTION_IO;
-   action->name = NULL;
- #ifdef HAVE_TRACING
-   action->category = NULL;
- #endif
-   action->io.host = host;
-   action->io.surf_io = surf_workstation_model->extension.workstation.unlink(host, fd->surf_file);
-   surf_workstation_model->action_data_set(action->io.surf_io, action);
-   XBT_DEBUG("Create io action %p", action);
-   return action;
+   if (surf_workstation_model->extension.workstation.unlink(host, fd->surf_file)){
+     fd->surf_file = NULL;
+     return 1;
+   } else
+     return 0;
  }
  
  //SIMIX FILE LS
@@@ -264,25 -227,27 +227,27 @@@ smx_action_t SIMIX_file_ls(smx_process_
    return action;
  }
  
- static void free_file_stat(void *p)
+ size_t SIMIX_pre_file_get_size(smx_simcall_t simcall, smx_file_t fd)
  {
-   file_stat_t fs = p;
-   xbt_free(fs->date);
-   xbt_free(fs->group);
-   xbt_free(fs->time);
-   xbt_free(fs->user);
-   xbt_free(fs->user_rights);
-   xbt_free(fs);
+   return SIMIX_file_get_size(simcall->issuer, fd);
+ }
+ size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
+ {
+   smx_host_t host = process->smx_host;
+   return  surf_workstation_model->extension.workstation.get_size(host,
+       fd->surf_file);
  }
  
  void SIMIX_post_io(smx_action_t action)
  {
    xbt_fifo_item_t i;
    smx_simcall_t simcall;
-   char* key;
-   xbt_dict_cursor_t cursor = NULL;
-   s_file_stat_t *dst = NULL;
-   s_file_stat_t *src = NULL;
//  char* key;
//  xbt_dict_cursor_t cursor = NULL;
//  s_file_stat_t *dst = NULL;
//  s_file_stat_t *src = NULL;
  
    xbt_fifo_foreach(action->simcalls,i,simcall,smx_simcall_t) {
      switch (simcall->call) {
        break;
  
      case SIMCALL_FILE_CLOSE:
-       xbt_free(simcall_file_close__get__fp(simcall));
+       xbt_free(simcall_file_close__get__fd(simcall));
        simcall_file_close__set__result(simcall, 0);
        break;
  
        simcall_file_read__set__result(simcall, (action->io.surf_io)->cost);
        break;
  
-     case SIMCALL_FILE_STAT:
-       simcall_file_stat__set__result(simcall, 0);
-       dst = simcall_file_stat__get__buf(simcall);
-       src = &((action->io.surf_io)->stat);
-       file_stat_copy(src,dst);
-       break;
-     case SIMCALL_FILE_UNLINK:
-       xbt_free(simcall_file_unlink__get__fd(simcall));
-       simcall_file_unlink__set__result(simcall, 0);
-       break;
      case SIMCALL_FILE_LS:
-       xbt_dict_foreach((action->io.surf_io)->ls_dict,cursor,key, src){
-         // if there is a stat we have to duplicate it
-         if(src){
-           dst = xbt_new0(s_file_stat_t,1);
-           file_stat_copy(src, dst);
          xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,free_file_stat);
-         }
-       }
//      xbt_dict_foreach((action->io.surf_io)->ls_dict,cursor,key, src){
//        // if there is a stat we have to duplicate it
//        if(src){
//          dst = xbt_new0(s_file_stat_t,1);
//          file_stat_copy(src, dst);
//          xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,xbt_free);
//        }
//      }
        simcall_file_ls__set__result(simcall, (action->io.surf_io)->ls_dict);
        break;
      default:
        break;
      }
@@@ -356,7 -308,7 +308,7 @@@ void SIMIX_io_destroy(smx_action_t acti
  {
    XBT_DEBUG("Destroy action %p", action);
    if (action->io.surf_io)
 -    action->io.surf_io->model_type->action_unref(action->io.surf_io);
 +    action->io.surf_io->model_obj->action_unref(action->io.surf_io);
    xbt_mallocator_release(simix_global->action_mallocator, action);
  }
  
diff --combined src/simix/smx_network.c
@@@ -199,6 -199,9 +199,9 @@@ smx_action_t SIMIX_fifo_get_comm(xbt_fi
        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;
      }
@@@ -337,17 -340,17 +340,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;
    }
  }
@@@ -400,7 -403,6 +403,6 @@@ smx_action_t SIMIX_comm_isend(smx_proce
        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));
  #define SIMCALL_LIST1(ACTION, sep) \
  ACTION(SIMCALL_HOST_GET_BY_NAME, host_get_by_name, WITH_ANSWER, TSPEC(result, smx_host_t), TSTRING(name)) sep \
  ACTION(SIMCALL_HOST_GET_NAME, host_get_name, WITH_ANSWER, TSTRING(result), TSPEC(host, smx_host_t)) sep \
 +ACTION(SIMCALL_HOST_ON, host_on, WITH_ANSWER, TVOID(result), TSPEC(host, smx_host_t)) sep \
 +ACTION(SIMCALL_HOST_OFF, host_off, WITH_ANSWER, TVOID(result), TSPEC(host, smx_host_t)) sep \
  ACTION(SIMCALL_HOST_GET_PROPERTIES, host_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(host, smx_host_t)) sep \
+ ACTION(SIMCALL_HOST_GET_CORE, host_get_core, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \
  ACTION(SIMCALL_HOST_GET_SPEED, host_get_speed, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \
  ACTION(SIMCALL_HOST_GET_AVAILABLE_SPEED, host_get_available_speed, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \
  ACTION(SIMCALL_HOST_GET_STATE, host_get_state, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \
  ACTION(SIMCALL_HOST_GET_DATA, host_get_data, WITH_ANSWER, TPTR(result), TSPEC(host, smx_host_t)) sep \
  ACTION(SIMCALL_HOST_SET_DATA, host_set_data, WITH_ANSWER, TVOID(result), TSPEC(host, smx_host_t), TPTR(data)) sep \
 -ACTION(SIMCALL_HOST_EXECUTE, host_execute, WITH_ANSWER, TSPEC(result, smx_action_t), TSTRING(name), TSPEC(host, smx_host_t), TDOUBLE(computation_amount), TDOUBLE(priority)) sep \
 +ACTION(SIMCALL_HOST_EXECUTE, host_execute, WITH_ANSWER, TSPEC(result, smx_action_t), TSTRING(name), TSPEC(host, smx_host_t), TDOUBLE(computation_amount), TDOUBLE(priority), TDOUBLE(bound)) sep \
  ACTION(SIMCALL_HOST_PARALLEL_EXECUTE, host_parallel_execute, WITH_ANSWER, TSPEC(result, smx_action_t), TSTRING(name), TINT(host_nb), TSPEC(host_list, smx_host_t*), TSPEC(computation_amount, double*), TSPEC(communication_amount, double*), TDOUBLE(amount), TDOUBLE(rate)) sep \
  ACTION(SIMCALL_HOST_EXECUTION_DESTROY, host_execution_destroy, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t)) sep \
  ACTION(SIMCALL_HOST_EXECUTION_CANCEL, host_execution_cancel, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t)) sep \
  ACTION(SIMCALL_HOST_EXECUTION_GET_REMAINS, host_execution_get_remains, WITH_ANSWER, TDOUBLE(result), TSPEC(execution, smx_action_t)) sep \
  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_SET_BOUND, host_execution_set_bound, WITHOUT_ANSWER, TVOID(result), TSPEC(execution, smx_action_t), TDOUBLE(bound)) 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_SET_BOUND, vm_set_bound, WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TDOUBLE(bound)) 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 \
@@@ -357,13 -340,13 +358,13 @@@ ACTION(SIMCALL_SEM_WOULD_BLOCK, sem_wou
  ACTION(SIMCALL_SEM_ACQUIRE, sem_acquire, WITHOUT_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \
  ACTION(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem_acquire_timeout, WITHOUT_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t), TDOUBLE(timeout)) sep \
  ACTION(SIMCALL_SEM_GET_CAPACITY, sem_get_capacity, WITH_ANSWER, TINT(result), TSPEC(sem, smx_sem_t)) sep \
- ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TDOUBLE(result), TPTR(ptr), TSIZE(size), TSIZE(nmemb), TSPEC(stream, smx_file_t)) sep \
- ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TCPTR(ptr), TSIZE(size), TSIZE(nmemb), TSPEC(stream, smx_file_t)) sep \
- ACTION(SIMCALL_FILE_OPEN, file_open, WITHOUT_ANSWER, TSPEC(result, smx_file_t), TSTRING(mount), TSTRING(path), TSTRING(mode)) sep \
- ACTION(SIMCALL_FILE_CLOSE, file_close, WITHOUT_ANSWER, TINT(result), TSPEC(fp, smx_file_t)) sep \
- ACTION(SIMCALL_FILE_STAT, file_stat, WITHOUT_ANSWER, TINT(result), TSPEC(fd, smx_file_t), TSPEC(buf, s_file_stat_t*)) sep \
- ACTION(SIMCALL_FILE_UNLINK, file_unlink, WITHOUT_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \
+ ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TPTR(ptr), TSIZE(size), TSPEC(fd, smx_file_t)) sep \
+ ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TCPTR(ptr), TSIZE(size), TSPEC(fd, smx_file_t)) sep \
+ ACTION(SIMCALL_FILE_OPEN, file_open, WITHOUT_ANSWER, TSPEC(result, smx_file_t), TSTRING(mount), TSTRING(path)) sep \
+ ACTION(SIMCALL_FILE_CLOSE, file_close, WITHOUT_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \
+ ACTION(SIMCALL_FILE_UNLINK, file_unlink, WITH_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \
  ACTION(SIMCALL_FILE_LS, file_ls, WITHOUT_ANSWER, TSPEC(result, xbt_dict_t), TSTRING(mount), TSTRING(path)) sep \
+ ACTION(SIMCALL_FILE_GET_SIZE, file_get_size, WITH_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t)) sep \
  ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSTRING(name)) sep 
  
  /* SIMCALL_COMM_IS_LATENCY_BOUNDED and SIMCALL_SET_CATEGORY make things complicated
diff --combined src/simix/smx_synchro.c
@@@ -23,16 -23,14 +23,16 @@@ static void _SIMIX_sem_wait(smx_sem_t s
  static smx_action_t SIMIX_synchro_wait(smx_host_t smx_host, double timeout)
  {
    XBT_IN("(%p, %f)",smx_host,timeout);
 +  surf_model_t ws_model = surf_resource_model(smx_host, SURF_WKS_LEVEL);
 +
    smx_action_t action;
    action = xbt_mallocator_get(simix_global->action_mallocator);
    action->type = SIMIX_ACTION_SYNCHRO;
    action->name = xbt_strdup("synchro");
    action->synchro.sleep = 
 -    surf_workstation_model->extension.workstation.sleep(smx_host, timeout);
 +    ws_model->extension.workstation.sleep(smx_host, timeout);
  
 -  surf_workstation_model->action_data_set(action->synchro.sleep, action);
 +  ws_model->action_data_set(action->synchro.sleep, action);
    XBT_OUT();
    return action;
  }
@@@ -72,9 -70,7 +72,9 @@@ void SIMIX_synchro_destroy(smx_action_
  {
    XBT_IN("(%p)",action);
    XBT_DEBUG("Destroying synchro %p", action);
 -  action->synchro.sleep->model_type->action_unref(action->synchro.sleep);
 +  xbt_assert(action->type == SIMIX_ACTION_SYNCHRO);
 +
 +  action->synchro.sleep->model_obj->action_unref(action->synchro.sleep);
    xbt_free(action->name);
    xbt_mallocator_release(simix_global->action_mallocator, action);
    XBT_OUT();
  void SIMIX_post_synchro(smx_action_t action)
  {
    XBT_IN("(%p)",action);
 -  if (surf_workstation_model->action_state_get(action->synchro.sleep) == SURF_ACTION_FAILED)
 +  xbt_assert(action->type == SIMIX_ACTION_SYNCHRO);
 +  surf_model_t ws_model = action->synchro.sleep->model_obj;
 +
 +  if (ws_model->action_state_get(action->synchro.sleep) == SURF_ACTION_FAILED)
      action->state = SIMIX_FAILED;
 -  else if(surf_workstation_model->action_state_get(action->synchro.sleep) == SURF_ACTION_DONE)
 +  else if(ws_model->action_state_get(action->synchro.sleep) == SURF_ACTION_DONE)
      action->state = SIMIX_SRC_TIMEOUT;
  
    SIMIX_synchro_finish(action);  
@@@ -463,7 -456,6 +463,6 @@@ void SIMIX_sem_release(smx_sem_t sem
  
    XBT_DEBUG("Sem release semaphore %p", sem);
    if ((proc = xbt_swag_extract(sem->sleeping))) {
-     proc = xbt_swag_extract(sem->sleeping);
      SIMIX_synchro_destroy(proc->waiting_action);
      proc->waiting_action = NULL;
      SIMIX_simcall_answer(&proc->simcall);
diff --combined src/simix/smx_user.c
@@@ -44,28 -44,6 +44,28 @@@ const char* simcall_host_get_name(smx_h
    return simcall_BODY_host_get_name(host);
  }
  
 +/**
 + * \ingroup simix_host_management
 + * \brief Start the host if it is off
 + *
 + * \param host A SIMIX host
 + */
 +void simcall_host_on(smx_host_t host)
 +{
 +  simcall_BODY_host_on(host);
 +}
 +
 +/**
 + * \ingroup simix_host_management
 + * \brief Stop the host if it is on
 + *
 + * \param host A SIMIX host
 + */
 +void simcall_host_off(smx_host_t host)
 +{
 +  simcall_BODY_host_off(host);
 +}
 +
  /**
   * \ingroup simix_host_management
   * \brief Returns a dict of the properties assigned to a host.
@@@ -104,6 -82,20 +104,20 @@@ double simcall_host_get_speed(smx_host_
    return simcall_BODY_host_get_speed(host);
  }
  
+ /**
+  * \ingroup simix_host_management
+  * \brief Returns the number of core of the processor.
+  *
+  * \param host A SIMIX host
+  * \return The number of core
+  */
+ int simcall_host_get_core(smx_host_t host)
+ {
+   return simcall_BODY_host_get_core(host);
+ }
  /**
   * \ingroup simix_host_management
   * \brief Returns the available speed of the processor.
@@@ -169,13 -161,13 +183,13 @@@ void simcall_host_set_data(smx_host_t h
  
  smx_action_t simcall_host_execute(const char *name, smx_host_t host,
                                      double computation_amount,
 -                                    double priority)
 +                                    double priority, double bound)
  {
    /* checking for infinite values */
    xbt_assert(isfinite(computation_amount), "computation_amount is not finite!");
    xbt_assert(isfinite(priority), "priority is not finite!");
    
 -  return simcall_BODY_host_execute(name, host, computation_amount, priority);
 +  return simcall_BODY_host_execute(name, host, computation_amount, priority, bound);
  }
  
  /**
@@@ -285,19 -277,6 +299,19 @@@ void simcall_host_execution_set_priorit
    simcall_BODY_host_execution_set_priority(execution, priority);
  }
  
 +/**
 + * \ingroup simix_host_management
 + * \brief Changes the capping (the maximum CPU utilization) of an execution action.
 + *
 + * This functions changes the capping only. It calls a surf function.
 + * \param execution The execution action
 + * \param bound The new bound
 + */
 +void simcall_host_execution_set_bound(smx_action_t execution, double bound)
 +{
 +  simcall_BODY_host_execution_set_bound(execution, bound);
 +}
 +
  /**
   * \ingroup simix_host_management
   * \brief Waits for the completion of an execution action and destroy it.
@@@ -309,163 -288,6 +323,163 @@@ 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_vm_set_bound(smx_host_t vm, double bound)
 +{
 +  /* will jump to SIMIX_pre_vm_set_bound in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_set_bound(vm, bound);
 +}
 +
 +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.
@@@ -1283,63 -1105,62 +1297,62 @@@ int simcall_sem_get_capacity(smx_sem_t 
   * \ingroup simix_file_management
   *
   */
double simcall_file_read(void* ptr, size_t size, size_t nmemb, smx_file_t stream)
size_t simcall_file_read(void* ptr, size_t size, smx_file_t fd)
  {
-   return simcall_BODY_file_read(ptr, size, nmemb, stream);
+   return simcall_BODY_file_read(ptr, size, fd);
  }
  
  /**
   * \ingroup simix_file_management
   *
   */
- size_t simcall_file_write(const void* ptr, size_t size, size_t nmemb, smx_file_t stream)
+ size_t simcall_file_write(const void* ptr, size_t size,
+                           smx_file_t fd)
  {
-   return simcall_BODY_file_write(ptr, size, nmemb, stream);
+   return simcall_BODY_file_write(ptr, size, fd);
  }
  
  /**
   * \ingroup simix_file_management
   * \brief
   */
- smx_file_t simcall_file_open(const char* mount, const char* path, const char* mode)
+ smx_file_t simcall_file_open(const char* mount, const char* path)
  {
-   return simcall_BODY_file_open(mount, path, mode);
+   return simcall_BODY_file_open(mount, path);
  }
  
  /**
   * \ingroup simix_file_management
   *
   */
- int simcall_file_close(smx_file_t fp)
+ int simcall_file_close(smx_file_t fd)
  {
-   return simcall_BODY_file_close(fp);  
+   return simcall_BODY_file_close(fd);
  }
  
  /**
   * \ingroup simix_file_management
   *
   */
- int simcall_file_stat(smx_file_t fd, s_file_stat_t *buf)
+ int simcall_file_unlink(smx_file_t fd)
  {
-   return simcall_BODY_file_stat(fd, buf);
+   return simcall_BODY_file_unlink(fd);
  }
  
  /**
   * \ingroup simix_file_management
   *
   */
int simcall_file_unlink(smx_file_t fd)
xbt_dict_t simcall_file_ls(const char* mount, const char* path)
  {
-   return simcall_BODY_file_unlink(fd);
+   return simcall_BODY_file_ls(mount, path);
  }
  /**
   * \ingroup simix_file_management
   *
   */
- xbt_dict_t simcall_file_ls(const char* mount, const char* path)
- {
-   return simcall_BODY_file_ls(mount, path);
+ size_t simcall_file_get_size (smx_file_t fd){
+   return simcall_BODY_file_get_size(fd);
  }
  
  #ifdef HAVE_MC
diff --combined src/surf/cpu_cas01.c
@@@ -8,11 -8,8 +8,11 @@@
  #include "surf/surf_resource.h"
  #include "maxmin_private.h"
  #include "simgrid/sg_config.h"
 +#include "surf/cpu_cas01_private.h"
  
 -surf_model_t surf_cpu_model = NULL;
 +/* the model objects for physical machines and virtual machines */
 +surf_model_t surf_cpu_model_pm = NULL;
 +surf_model_t surf_cpu_model_vm = NULL;
  
  #undef GENERIC_LMM_ACTION
  #undef GENERIC_ACTION
@@@ -25,6 -22,18 +25,6 @@@ typedef struct surf_action_cpu_cas01 
    s_surf_action_lmm_t generic_lmm_action;
  } s_surf_action_cpu_Cas01_t, *surf_action_cpu_Cas01_t;
  
 -typedef struct cpu_Cas01 {
 -  s_surf_resource_t generic_resource;
 -  s_xbt_swag_hookup_t modified_cpu_hookup;
 -  double power_peak;
 -  double power_scale;
 -  tmgr_trace_event_t power_event;
 -  int core;
 -  e_surf_resource_state_t state_current;
 -  tmgr_trace_event_t state_event;
 -  lmm_constraint_t constraint;
 -} s_cpu_Cas01_t, *cpu_Cas01_t;
 -
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu, surf,
                                  "Logging specific to the SURF CPU IMPROVED module");
  
@@@ -32,14 -41,14 +32,14 @@@ static xbt_swag_
      cpu_running_action_set_that_does_not_need_being_checked = NULL;
  
  
 -/* This function is registered as a callback to sg_platf_new_host() and never called directly */
 -static void *cpu_create_resource(const char *name, double power_peak,
 +void *cpu_cas01_create_resource(const char *name, double power_peak,
                                   double power_scale,
                                   tmgr_trace_t power_trace,
                                   int core,
                                   e_surf_resource_state_t state_initial,
                                   tmgr_trace_t state_trace,
 -                                 xbt_dict_t cpu_properties)
 +                                 xbt_dict_t cpu_properties,
 +                                 surf_model_t cpu_model)
  {
    cpu_Cas01_t cpu = NULL;
  
@@@ -47,7 -56,7 +47,7 @@@
               "Host '%s' declared several times in the platform file",
               name);
    cpu = (cpu_Cas01_t) surf_resource_new(sizeof(s_cpu_Cas01_t),
 -                                        surf_cpu_model, name,
 +                                        cpu_model, name,
                                          cpu_properties);
    cpu->power_peak = power_peak;
    xbt_assert(cpu->power_peak > 0, "Power has to be >0");
@@@ -65,7 -74,7 +65,7 @@@
          tmgr_history_add_trace(history, state_trace, 0.0, 0, cpu);
  
    cpu->constraint =
 -      lmm_constraint_new(surf_cpu_model->model_private->maxmin_system, cpu,
 +      lmm_constraint_new(cpu_model->model_private->maxmin_system, cpu,
                           cpu->core * cpu->power_scale * cpu->power_peak);
  
    xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, cpu);
  
  static void parse_cpu_init(sg_platf_host_cbarg_t host)
  {
 -  cpu_create_resource(host->id,
 +  /* This function is called when a platform file is parsed. Physical machines
 +   * are defined there. Thus, we use the cpu model object for the physical
 +   * machine layer. */
 +  cpu_cas01_create_resource(host->id,
                        host->power_peak,
                        host->power_scale,
                        host->power_trace,
                        host->core_amount,
                        host->initial_state,
 -                      host->state_trace, host->properties);
 +                      host->state_trace, host->properties,
 +                      surf_cpu_model_pm);
  }
  
  static void cpu_add_traces_cpu(void)
    }
  }
  
 -static void cpu_define_callbacks()
 +static void cpu_define_callbacks_cas01()
  {
    sg_platf_host_add_cb(parse_cpu_init);
    sg_platf_postparse_add_cb(cpu_add_traces_cpu);
  
  static int cpu_resource_used(void *resource)
  {
 -  return lmm_constraint_used(surf_cpu_model->model_private->maxmin_system,
 +  surf_model_t cpu_model = ((surf_resource_t) resource)->model;
 +
 +  return lmm_constraint_used(cpu_model->model_private->maxmin_system,
                               ((cpu_Cas01_t) resource)->constraint);
  }
  
 -static double cpu_share_resources_lazy(double now)
 +static double cpu_share_resources_lazy(surf_model_t cpu_model, double now)
  {
 -  return generic_share_resources_lazy(now, surf_cpu_model);
 +  return generic_share_resources_lazy(now, cpu_model);
  }
  
 -static double cpu_share_resources_full(double now)
 +static double cpu_share_resources_full(surf_model_t cpu_model, double now)
  {
    s_surf_action_cpu_Cas01_t action;
 -  return generic_maxmin_share_resources(surf_cpu_model->states.
 +  return generic_maxmin_share_resources(cpu_model->states.
                                          running_action_set,
                                          xbt_swag_offset(action,
                                                          generic_lmm_action.
                                                          variable),
 -                                        surf_cpu_model->model_private->maxmin_system, lmm_solve);
 +                                        cpu_model->model_private->maxmin_system, lmm_solve);
  }
  
 -static void cpu_update_actions_state_lazy(double now, double delta)
 +static void cpu_update_actions_state_lazy(surf_model_t cpu_model, double now, double delta)
  {
 -  generic_update_actions_state_lazy(now, delta, surf_cpu_model);
 +  generic_update_actions_state_lazy(now, delta, cpu_model);
  }
  
 -static void cpu_update_actions_state_full(double now, double delta)
 +static void cpu_update_actions_state_full(surf_model_t cpu_model, double now, double delta)
  {
 -  generic_update_actions_state_full(now, delta, surf_cpu_model);
 +  generic_update_actions_state_full(now, delta, cpu_model);
  }
  
  static void cpu_update_resource_state(void *id,
    cpu_Cas01_t cpu = id;
    lmm_variable_t var = NULL;
    lmm_element_t elem = NULL;
 +  surf_model_t cpu_model = ((surf_resource_t) cpu)->model;
  
    surf_watched_hosts();
  
    if (event_type == cpu->power_event) {
      cpu->power_scale = value;
 -    lmm_update_constraint_bound(surf_cpu_model->model_private->maxmin_system, cpu->constraint,
 +    lmm_update_constraint_bound(cpu_model->model_private->maxmin_system, cpu->constraint,
                                  cpu->core * cpu->power_scale *
                                  cpu->power_peak);
  #ifdef HAVE_TRACING
                                cpu->power_peak);
  #endif
      while ((var = lmm_get_var_from_cnst
 -            (surf_cpu_model->model_private->maxmin_system, cpu->constraint, &elem))) {
 +            (cpu_model->model_private->maxmin_system, cpu->constraint, &elem))) {
        surf_action_cpu_Cas01_t action = lmm_variable_id(var);
 -      lmm_update_variable_bound(surf_cpu_model->model_private->maxmin_system,
 +      lmm_update_variable_bound(cpu_model->model_private->maxmin_system,
                                  GENERIC_LMM_ACTION(action).variable,
                                  cpu->power_scale * cpu->power_peak);
      }
  
        cpu->state_current = SURF_RESOURCE_OFF;
  
 -      while ((var = lmm_get_var_from_cnst(surf_cpu_model->model_private->maxmin_system, cnst, &elem))) {
 +      while ((var = lmm_get_var_from_cnst(cpu_model->model_private->maxmin_system, cnst, &elem))) {
          surf_action_t action = lmm_variable_id(var);
  
          if (surf_action_state_get(action) == SURF_ACTION_RUNNING ||
@@@ -226,27 -228,26 +226,27 @@@ static surf_action_t cpu_execute(void *
  {
    surf_action_cpu_Cas01_t action = NULL;
    cpu_Cas01_t CPU = surf_cpu_resource_priv(cpu);
 +  surf_model_t cpu_model = ((surf_resource_t) CPU)->model;
  
    XBT_IN("(%s,%g)", surf_resource_name(CPU), size);
    action =
        surf_action_new(sizeof(s_surf_action_cpu_Cas01_t), size,
 -                      surf_cpu_model,
 +                      cpu_model,
                        CPU->state_current != SURF_RESOURCE_ON);
  
    GENERIC_LMM_ACTION(action).suspended = 0;     /* Should be useless because of the
                                                     calloc but it seems to help valgrind... */
  
    GENERIC_LMM_ACTION(action).variable =
 -      lmm_variable_new(surf_cpu_model->model_private->maxmin_system, action,
 +      lmm_variable_new(cpu_model->model_private->maxmin_system, action,
                         GENERIC_ACTION(action).priority,
                         CPU->power_scale * CPU->power_peak, 1);
 -  if (surf_cpu_model->model_private->update_mechanism == UM_LAZY) {
 +  if (cpu_model->model_private->update_mechanism == UM_LAZY) {
      GENERIC_LMM_ACTION(action).index_heap = -1;
      GENERIC_LMM_ACTION(action).last_update = surf_get_clock();
      GENERIC_LMM_ACTION(action).last_value = 0.0;
    }
 -  lmm_expand(surf_cpu_model->model_private->maxmin_system, CPU->constraint,
 +  lmm_expand(cpu_model->model_private->maxmin_system, CPU->constraint,
               GENERIC_LMM_ACTION(action).variable, 1.0);
    XBT_OUT();
    return (surf_action_t) action;
  static surf_action_t cpu_action_sleep(void *cpu, double duration)
  {
    surf_action_cpu_Cas01_t action = NULL;
 +  cpu_Cas01_t CPU = surf_cpu_resource_priv(cpu);
 +  surf_model_t cpu_model = ((surf_resource_t) CPU)->model;
  
    if (duration > 0)
      duration = MAX(duration, MAXMIN_PRECISION);
      xbt_swag_insert(action, ((surf_action_t) action)->state_set);
    }
  
 -  lmm_update_variable_weight(surf_cpu_model->model_private->maxmin_system,
 +  lmm_update_variable_weight(cpu_model->model_private->maxmin_system,
                               GENERIC_LMM_ACTION(action).variable, 0.0);
 -  if (surf_cpu_model->model_private->update_mechanism == UM_LAZY) {     // remove action from the heap
 -    surf_action_lmm_heap_remove(surf_cpu_model->model_private->action_heap,(surf_action_lmm_t)action);
 +  if (cpu_model->model_private->update_mechanism == UM_LAZY) {     // remove action from the heap
 +    surf_action_lmm_heap_remove(cpu_model->model_private->action_heap,(surf_action_lmm_t)action);
      // this is necessary for a variable with weight 0 since such
      // variables are ignored in lmm and we need to set its max_duration
      // correctly at the next call to share_resources
 -    xbt_swag_insert_at_head(action,surf_cpu_model->model_private->modified_set);
 +    xbt_swag_insert_at_head(action, cpu_model->model_private->modified_set);
    }
  
    XBT_OUT();
@@@ -294,55 -293,56 +294,59 @@@ static e_surf_resource_state_t cpu_get_
    return ((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->state_current;
  }
  
 +static void cpu_set_state(void *cpu, e_surf_resource_state_t state)
 +{
 +  ((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->state_current = state;
 +}
 +
  static double cpu_get_speed(void *cpu, double load)
  {
    return load * ((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->power_peak;
  }
  
 -
 -
+ static int cpu_get_core(void *cpu)
+ {
+   return ((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->core;
+ }
  static double cpu_get_available_speed(void *cpu)
  {
    /* number between 0 and 1 */
    return ((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->power_scale;
  }
  
 -static void cpu_finalize(void)
 +static void cpu_finalize(surf_model_t cpu_model)
  {
 -  lmm_system_free(surf_cpu_model->model_private->maxmin_system);
 -  surf_cpu_model->model_private->maxmin_system = NULL;
 +  lmm_system_free(cpu_model->model_private->maxmin_system);
 +  cpu_model->model_private->maxmin_system = NULL;
  
 -  if (surf_cpu_model->model_private->action_heap)
 -    xbt_heap_free(surf_cpu_model->model_private->action_heap);
 -  xbt_swag_free(surf_cpu_model->model_private->modified_set);
 +  if (cpu_model->model_private->action_heap)
 +    xbt_heap_free(cpu_model->model_private->action_heap);
 +  xbt_swag_free(cpu_model->model_private->modified_set);
  
 -  surf_model_exit(surf_cpu_model);
 -  surf_cpu_model = NULL;
 +  surf_model_exit(cpu_model);
 +  cpu_model = NULL;
  
    xbt_swag_free(cpu_running_action_set_that_does_not_need_being_checked);
    cpu_running_action_set_that_does_not_need_being_checked = NULL;
  }
  
 -static void surf_cpu_model_init_internal()
 +static surf_model_t surf_cpu_model_init_cas01(void)
  {
    s_surf_action_t action;
    s_surf_action_cpu_Cas01_t comp;
  
    char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim");
    int select =
-       xbt_cfg_get_int(_sg_cfg_set, "cpu/maxmin_selective_update");
+       xbt_cfg_get_boolean(_sg_cfg_set, "cpu/maxmin_selective_update");
  
 -  surf_cpu_model = surf_model_init();
 +  surf_model_t cpu_model = surf_model_init();
  
    if (!strcmp(optim, "Full")) {
 -    surf_cpu_model->model_private->update_mechanism = UM_FULL;
 -    surf_cpu_model->model_private->selective_update = select;
 +    cpu_model->model_private->update_mechanism = UM_FULL;
 +    cpu_model->model_private->selective_update = select;
    } else if (!strcmp(optim, "Lazy")) {
 -    surf_cpu_model->model_private->update_mechanism = UM_LAZY;
 -    surf_cpu_model->model_private->selective_update = 1;
 +    cpu_model->model_private->update_mechanism = UM_LAZY;
 +    cpu_model->model_private->selective_update = 1;
      xbt_assert((select == 1)
                 ||
                 (xbt_cfg_is_default_value
    cpu_running_action_set_that_does_not_need_being_checked =
        xbt_swag_new(xbt_swag_offset(action, state_hookup));
  
 -  surf_cpu_model->name = "cpu";
 +  cpu_model->name = "cpu";
 +  cpu_model->type = SURF_MODEL_TYPE_CPU;
  
 -  surf_cpu_model->action_unref = surf_action_unref;
 -  surf_cpu_model->action_cancel = surf_action_cancel;
 -  surf_cpu_model->action_state_set = surf_action_state_set;
 +  cpu_model->action_unref = surf_action_unref;
 +  cpu_model->action_cancel = surf_action_cancel;
 +  cpu_model->action_state_set = surf_action_state_set;
  
 -  surf_cpu_model->model_private->resource_used = cpu_resource_used;
 +  cpu_model->model_private->resource_used = cpu_resource_used;
  
 -  if (surf_cpu_model->model_private->update_mechanism == UM_LAZY) {
 -    surf_cpu_model->model_private->share_resources =
 +  if (cpu_model->model_private->update_mechanism == UM_LAZY) {
 +    cpu_model->model_private->share_resources =
          cpu_share_resources_lazy;
 -    surf_cpu_model->model_private->update_actions_state =
 +    cpu_model->model_private->update_actions_state =
          cpu_update_actions_state_lazy;
 -  } else if (surf_cpu_model->model_private->update_mechanism == UM_FULL) {
 -    surf_cpu_model->model_private->share_resources =
 +  } else if (cpu_model->model_private->update_mechanism == UM_FULL) {
 +    cpu_model->model_private->share_resources =
          cpu_share_resources_full;
 -    surf_cpu_model->model_private->update_actions_state =
 +    cpu_model->model_private->update_actions_state =
          cpu_update_actions_state_full;
    } else
      xbt_die("Invalid cpu update mechanism!");
  
 -  surf_cpu_model->model_private->update_resource_state =
 +  cpu_model->model_private->update_resource_state =
        cpu_update_resource_state;
 -  surf_cpu_model->model_private->finalize = cpu_finalize;
 -
 -  surf_cpu_model->suspend = surf_action_suspend;
 -  surf_cpu_model->resume = surf_action_resume;
 -  surf_cpu_model->is_suspended = surf_action_is_suspended;
 -  surf_cpu_model->set_max_duration = surf_action_set_max_duration;
 -  surf_cpu_model->set_priority = surf_action_set_priority;
 +  cpu_model->model_private->finalize = cpu_finalize;
 +
 +  cpu_model->suspend = surf_action_suspend;
 +  cpu_model->resume = surf_action_resume;
 +  cpu_model->is_suspended = surf_action_is_suspended;
 +  cpu_model->set_max_duration = surf_action_set_max_duration;
 +  cpu_model->set_priority = surf_action_set_priority;
 +  cpu_model->set_bound = surf_action_set_bound;
  #ifdef HAVE_TRACING
 -  surf_cpu_model->set_category = surf_action_set_category;
 +  cpu_model->set_category = surf_action_set_category;
  #endif
 -  surf_cpu_model->get_remains = surf_action_get_remains;
 +  cpu_model->get_remains = surf_action_get_remains;
  
 -  surf_cpu_model->extension.cpu.execute = cpu_execute;
 -  surf_cpu_model->extension.cpu.sleep = cpu_action_sleep;
 +  cpu_model->extension.cpu.execute = cpu_execute;
 +  cpu_model->extension.cpu.sleep = cpu_action_sleep;
  
 -  surf_cpu_model->extension.cpu.get_state = cpu_get_state;
 -  surf_cpu_model->extension.cpu.get_core = cpu_get_core;
 -  surf_cpu_model->extension.cpu.get_speed = cpu_get_speed;
 -  surf_cpu_model->extension.cpu.get_available_speed =
 +  cpu_model->extension.cpu.get_state = cpu_get_state;
 +  cpu_model->extension.cpu.set_state = cpu_set_state;
++  cpu_model->extension.cpu.get_core = cpu_get_core;
 +  cpu_model->extension.cpu.get_speed = cpu_get_speed;
 +  cpu_model->extension.cpu.get_available_speed =
        cpu_get_available_speed;
 -  surf_cpu_model->extension.cpu.add_traces = cpu_add_traces_cpu;
 +  cpu_model->extension.cpu.add_traces = cpu_add_traces_cpu;
  
 -  if (!surf_cpu_model->model_private->maxmin_system) {
 -    surf_cpu_model->model_private->maxmin_system = lmm_system_new(surf_cpu_model->model_private->selective_update);
 +  if (!cpu_model->model_private->maxmin_system) {
 +    cpu_model->model_private->maxmin_system = lmm_system_new(cpu_model->model_private->selective_update);
    }
 -  if (surf_cpu_model->model_private->update_mechanism == UM_LAZY) {
 -    surf_cpu_model->model_private->action_heap = xbt_heap_new(8, NULL);
 -    xbt_heap_set_update_callback(surf_cpu_model->model_private->action_heap,
 +  if (cpu_model->model_private->update_mechanism == UM_LAZY) {
 +    cpu_model->model_private->action_heap = xbt_heap_new(8, NULL);
 +    xbt_heap_set_update_callback(cpu_model->model_private->action_heap,
          surf_action_lmm_update_index_heap);
 -    surf_cpu_model->model_private->modified_set =
 +    cpu_model->model_private->modified_set =
          xbt_swag_new(xbt_swag_offset(comp, generic_lmm_action.action_list_hookup));
 -    surf_cpu_model->model_private->maxmin_system->keep_track = surf_cpu_model->model_private->modified_set;
 +    cpu_model->model_private->maxmin_system->keep_track = cpu_model->model_private->modified_set;
    }
 +
 +  return cpu_model;
  }
  
  /*********************************************************************/
  /*                  \url{http://grail.sdsc.edu/papers/simgrid_ccgrid01.ps.gz}." */
  /* } */
  
 -void surf_cpu_model_init_Cas01()
 +
 +void surf_cpu_model_init_Cas01(void)
  {
    char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim");
  
 -  if (surf_cpu_model)
 -    return;
 +  xbt_assert(!surf_cpu_model_pm);
 +  xbt_assert(!surf_cpu_model_vm);
  
 -  if (!strcmp(optim, "TI")) {
 -    surf_cpu_model_init_ti();
 -    return;
 +  if (strcmp(optim, "TI") == 0) {
 +    /* FIXME: do we have to supprot TI? for VM */
 +    surf_cpu_model_pm = surf_cpu_model_init_ti();
 +    XBT_INFO("TI model is used (it will crashed since this is the hypervisor branch)");
 +  } else {
 +    surf_cpu_model_pm  = surf_cpu_model_init_cas01();
 +    surf_cpu_model_vm  = surf_cpu_model_init_cas01();
 +
 +    /* cpu_model is registered only to model_list, and not to
 +     * model_list_invoke. The shared_resource callback function will be called
 +     * from that of the workstation model. */
 +    xbt_dynar_push(model_list, &surf_cpu_model_pm);
 +    xbt_dynar_push(model_list, &surf_cpu_model_vm);
 +
 +    cpu_define_callbacks_cas01();
    }
 +}
  
 -  surf_cpu_model_init_internal();
 -  cpu_define_callbacks();
 -  xbt_dynar_push(model_list, &surf_cpu_model);
 +/* TODO: do we address nested virtualization later? */
 +#if 0
 +surf_model_t cpu_model_cas01(int level){
 +      // TODO this table should be allocated
 +      if(!surf_cpu_model[level])
 +       // allocate it
 +      return surf_cpu_model[level];
  }
 +#endif
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,18 -652,18 +652,18 @@@ 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;
  
    xbt_dict_free(&gap_lookup);
    xbt_dynar_free(&smpi_bw_factor);
@@@ -736,7 -736,7 +736,7 @@@ static void set_update_mechanism(void
  {
    char *optim = xbt_cfg_get_string(_sg_cfg_set, "network/optim");
    int select =
-       xbt_cfg_get_int(_sg_cfg_set, "network/maxmin_selective_update");
+       xbt_cfg_get_boolean(_sg_cfg_set, "network/maxmin_selective_update");
  
    if (!strcmp(optim, "Full")) {
      surf_network_model->model_private->update_mechanism = UM_FULL;
@@@ -762,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/new_model.c
@@@ -10,7 -10,6 +10,6 @@@
  
  #include "xbt/ex.h"
  #include "xbt/dict.h"
- #include "xbt/file_stat.h"
  #include "portable.h"
  #include "surf_private.h"
  #include "new_model_private.h"
@@@ -48,25 -47,25 +47,25 @@@ static void* new_model_create_resource(
    return NULL;
  }
  
 -static void new_model_finalize(void)
 +static void new_model_finalize(surf_model_t new_model)
  {
    lmm_system_free(new_model_maxmin_system);
    new_model_maxmin_system = NULL;
  
 -  surf_model_exit(surf_new_model);
 -  surf_new_model = NULL;
 +  surf_model_exit(new_model);
 +  new_model = NULL;
  
    xbt_swag_free
        (new_model_running_action_set_that_does_not_need_being_checked);
    new_model_running_action_set_that_does_not_need_being_checked = NULL;
  }
  
 -static void new_model_update_actions_state(double now, double delta)
 +static void new_model_update_actions_state(surf_model_t new_model, double now, double delta)
  {
    return;
  }
  
 -static double new_model_share_resources(double NOW)
 +static double new_model_share_resources(surf_model_t new_model, double NOW)
  {
    return -1;
  }
@@@ -148,7 -147,6 +147,7 @@@ static void surf_new_model_init_interna
        xbt_swag_new(xbt_swag_offset(action, state_hookup));
  
    surf_new_model->name = "New Model";
 +  surf_new_model->type = SURF_MODEL_TYPE_NEW_MODEL;
    surf_new_model->action_unref = new_model_action_unref;
    surf_new_model->action_cancel = new_model_action_cancel;
    surf_new_model->action_state_set = new_model_action_state_set;
diff --combined src/surf/storage.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. The SimGrid Team.
+ /* Copyright (c) 2004 - 2013. The SimGrid Team.
   * All rights reserved.                                                                 */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -6,7 -6,6 +6,6 @@@
  
  #include "xbt/ex.h"
  #include "xbt/dict.h"
- #include "xbt/file_stat.h"
  #include "portable.h"
  #include "surf_private.h"
  #include "storage_private.h"
@@@ -35,19 -34,10 +34,10 @@@ static xbt_dynar_t storage_list
  #define GENERIC_LMM_ACTION(action) action->generic_lmm_action
  #define GENERIC_ACTION(action) GENERIC_LMM_ACTION(action).generic_action
  
- static xbt_dict_t parse_storage_content(char *filename, unsigned long *used_size);
+ static xbt_dict_t parse_storage_content(char *filename, size_t *used_size);
  static int storage_action_unref(surf_action_t action);
  static void storage_action_state_set(surf_action_t action, e_surf_action_state_t state);
- static surf_action_t storage_action_execute (void *storage, double size, e_surf_action_storage_type_t type);
- static void free_storage_content(void *p);
- static surf_action_t storage_action_stat(void *storage, surf_file_t stream)
- {
-   surf_action_t action = storage_action_execute(storage,0, STAT);
-   action->file = stream;
-   action->stat = stream->content->stat;
-   return action;
- }
+ static surf_action_t storage_action_execute (void *storage, size_t size, e_surf_action_storage_type_t type);
  
  static surf_action_t storage_action_ls(void *storage, const char* path)
  {
    xbt_dict_t ls_dict = xbt_dict_new();
  
    char* key;
-   surf_stat_t data = NULL;
+   size_t size = 0;
    xbt_dict_cursor_t cursor = NULL;
  
    xbt_dynar_t dyn = NULL;
    char* file = NULL;
  
-   // foreach file int the storage
-   xbt_dict_foreach(((storage_t)storage)->content,cursor,key,data){
+   // for each file in the storage content
+   xbt_dict_foreach(((storage_t)storage)->content,cursor,key,size){
      // Search if file start with the prefix 'path'
      if(xbt_str_start_with(key,path)){
        file = &key[strlen(path)];
  
        // file
        if(xbt_dynar_length(dyn) == 1){
-         xbt_dict_set(ls_dict,file,&(data->stat),NULL);
+         xbt_dict_set(ls_dict,file,&size,NULL);
        }
        // Directory
        else
        {
-         // if directory does not exist yet in dict
+         // if directory does not exist yet in the dictionary
          if(!xbt_dict_get_or_null(ls_dict,file))
            xbt_dict_set(ls_dict,file,NULL,NULL);
        }
    return action;
  }
  
- static surf_action_t storage_action_unlink(void *storage, surf_file_t stream)
- {
-   surf_action_t action = storage_action_execute(storage,0, UNLINK);
-   // Add memory to storage
-   ((storage_t)storage)->used_size -= stream->content->stat.size;
-   // Remove the file from storage
-   xbt_dict_t content_dict = ((storage_t)storage)->content;
-   xbt_dict_remove(content_dict,stream->name);
-   free(stream->name);
-   xbt_free(stream);
-   return action;
- }
- static surf_action_t storage_action_open(void *storage, const char* mount, const char* path, const char* mode)
+ static surf_action_t storage_action_open(void *storage, const char* mount,
+                                          const char* path)
  {
    XBT_DEBUG("\tOpen file '%s'",path);
    xbt_dict_t content_dict = ((storage_t)storage)->content;
-   surf_stat_t content = xbt_dict_get_or_null(content_dict,path);
+   size_t size = (size_t) xbt_dict_get_or_null(content_dict,path);
    // if file does not exist create an empty file
-   if(!content){
-     content = xbt_new0(s_surf_stat_t,1);
-     content->stat.date = xbt_strdup("");
-     content->stat.group = xbt_strdup("");
-     content->stat.size = 0;
-     content->stat.time = xbt_strdup("");
-     content->stat.user = xbt_strdup("");
-     content->stat.user_rights = xbt_strdup("");
-     xbt_dict_set(content_dict,path,content,NULL);
+   if(!size){
+     xbt_dict_set(content_dict,path,&size,NULL);
      XBT_DEBUG("File '%s' was not found, file created.",path);
    }
    surf_file_t file = xbt_new0(s_surf_file_t,1);
    file->name = xbt_strdup(path);
-   file->content = content;
-   file->storage = mount;
+   file->size = size;
+   file->storage = xbt_strdup(mount);
  
    surf_action_t action = storage_action_execute(storage,0, OPEN);
    action->file = (void *)file;
    return action;
  }
  
- static surf_action_t storage_action_close(void *storage, surf_file_t fp)
+ static surf_action_t storage_action_close(void *storage, surf_file_t fd)
  {
-   char *filename = fp->name;
-   XBT_DEBUG("\tClose file '%s' size '%f'",filename,fp->content->stat.size);
+   char *filename = fd->name;
+   XBT_DEBUG("\tClose file '%s' size '%zu'",filename,fd->size);
    // unref write actions from storage
    surf_action_storage_t write_action;
    unsigned int i;
    xbt_dynar_foreach(((storage_t)storage)->write_actions,i,write_action) {
-     if ((write_action->generic_lmm_action.generic_action.file) == fp) {
+     if ((write_action->generic_lmm_action.generic_action.file) == fd) {
        xbt_dynar_cursor_rm(((storage_t)storage)->write_actions, &i);
        storage_action_unref((surf_action_t) write_action);
      }
    }
  
-   free(fp->name);
-   xbt_free(fp);
+   free(fd->name);
+   free(fd->storage);
+   xbt_free(fd);
    surf_action_t action = storage_action_execute(storage,0, CLOSE);
    return action;
  }
  
- static surf_action_t storage_action_read(void *storage, void* ptr, double size, size_t nmemb, surf_file_t stream)
+ static surf_action_t storage_action_read(void *storage, void* ptr, 
+                                        size_t size, surf_file_t fd)
  {
-   surf_stat_t content = stream->content;
-   if(size > content->stat.size)
-     size = content->stat.size;
+   if(size > fd->size)
+     size = fd->size;
    surf_action_t action = storage_action_execute(storage,size,READ);
    return action;
  }
  
- static surf_action_t storage_action_write(void *storage, const void* ptr, size_t size, size_t nmemb, surf_file_t stream)
+ static surf_action_t storage_action_write(void *storage, const void* ptr,
+                                           size_t size, surf_file_t fd)
  {
-   char *filename = stream->name;
-   surf_stat_t content = stream->content;
-   XBT_DEBUG("\tWrite file '%s' size '%zu/%f'",filename,size,content->stat.size);
+   char *filename = fd->name;
+   XBT_DEBUG("\tWrite file '%s' size '%zu/%zu'",filename,size,fd->size);
  
    surf_action_t action = storage_action_execute(storage,size,WRITE);
-   action->file = stream;
+   action->file = fd;
  
    // If the storage is full
    if(((storage_t)storage)->used_size==((storage_t)storage)->size) {
    return action;
  }
  
- static surf_action_t storage_action_execute (void *storage, double size, e_surf_action_storage_type_t type)
+ static surf_action_t storage_action_execute (void *storage, size_t size, e_surf_action_storage_type_t type)
  {
    surf_action_storage_t action = NULL;
    storage_t STORAGE = storage;
  
-   XBT_IN("(%s,%f)", surf_resource_name(STORAGE), size);
+   XBT_IN("(%s,%zu", surf_resource_name(STORAGE), size);
    action =
        surf_action_new(sizeof(s_surf_action_storage_t), size, surf_storage_model,
            STORAGE->state_current != SURF_RESOURCE_ON);
    case OPEN:
    case CLOSE:
    case STAT:
-   case UNLINK:
    case LS:
      break;
    case READ:
@@@ -245,7 -211,7 +211,7 @@@ static void* storage_create_resource(co
    double Bread  = atof(xbt_dict_get(storage_type->properties,"Bread"));
    double Bwrite = atof(xbt_dict_get(storage_type->properties,"Bwrite"));
    double Bconnection   = atof(xbt_dict_get(storage_type->properties,"Bconnection"));
-   XBT_DEBUG("Create resource with Bconnection '%f' Bread '%f' Bwrite '%f' and Size '%ld'",Bconnection,Bread,Bwrite,storage_type->size);
+   XBT_DEBUG("Create resource with Bconnection '%f' Bread '%f' Bwrite '%f' and Size '%lu'",Bconnection,Bread,Bwrite,(unsigned long)storage_type->size);
    storage->constraint       = lmm_constraint_new(storage_maxmin_system, storage, Bconnection);
    storage->constraint_read  = lmm_constraint_new(storage_maxmin_system, storage, Bread);
    storage->constraint_write = lmm_constraint_new(storage_maxmin_system, storage, Bwrite);
    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;
  
    xbt_dynar_free(&storage_list);
  
    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
-   // Foreach action of type write
+   // For each action of type write
    xbt_swag_foreach_safe(action, next_action, running_actions) {
      if(action->type == WRITE)
      {
        double rate = lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable);
-       ((storage_t)(action->storage))->used_size += delta * rate; // disk usage
-       ((surf_action_t)action)->file->content->stat.size += delta * rate; // file size
+       /* Hack to avoid rounding differences between x86 and x86_64
+        * (note that the next sizes are of type size_t). */
+       long incr = delta * rate + MAXMIN_PRECISION;
+       ((storage_t)(action->storage))->used_size += incr; // disk usage
+       ((surf_action_t)action)->file->size += incr; // 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);
  
@@@ -492,7 -461,6 +461,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;
    surf_storage_model->extension.storage.close = storage_action_close;
    surf_storage_model->extension.storage.read = storage_action_read;
    surf_storage_model->extension.storage.write = storage_action_write;
-   surf_storage_model->extension.storage.stat = storage_action_stat;
-   surf_storage_model->extension.storage.unlink = storage_action_unlink;
    surf_storage_model->extension.storage.ls = storage_action_ls;
  
    if (!storage_maxmin_system) {
@@@ -553,24 -519,13 +520,13 @@@ static void storage_parse_storage(sg_pl
        (void *) xbt_strdup(storage->type_id));
  }
  
- static void free_storage_content(void *p)
- {
-   surf_stat_t content = p;
-   free(content->stat.date);
-   free(content->stat.group);
-   free(content->stat.time);
-   free(content->stat.user);
-   free(content->stat.user_rights);
-   free(content);
- }
- static xbt_dict_t parse_storage_content(char *filename, unsigned long *used_size)
+ static xbt_dict_t parse_storage_content(char *filename, size_t *used_size)
  {
    *used_size = 0;
    if ((!filename) || (strcmp(filename, "") == 0))
      return NULL;
  
-   xbt_dict_t parse_content = xbt_dict_new_homogeneous(free_storage_content);
+   xbt_dict_t parse_content = xbt_dict_new_homogeneous(NULL);
    FILE *file = NULL;
  
    file = surf_fopen(filename, "r");
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
-   char user_rights[12];
-   char user[100];
-   char group[100];
-   char date[12];
-   char time[12];
    char path[1024];
-   int nb;
-   unsigned long size;
+   size_t size;
  
-   surf_stat_t content;
  
    while ((read = xbt_getline(&line, &len, file)) != -1) {
      if (read){
-     content = xbt_new0(s_surf_stat_t,1);
-     if(sscanf(line,"%s %d %s %s %ld %s %s %s",user_rights,&nb,user,group,&size,date,time,path)==8) {
-         content->stat.date = xbt_strdup(date);
-         content->stat.group = xbt_strdup(group);
-         content->stat.size = size;
-         content->stat.time = xbt_strdup(time);
-         content->stat.user = xbt_strdup(user);
-         content->stat.user_rights = xbt_strdup(user_rights);
-         *used_size += content->stat.size;
-         xbt_dict_set(parse_content,path,content,NULL);
+     if(sscanf(line,"%s %zu",path, &size)==2) {
+         *used_size += size;
+         xbt_dict_set(parse_content,path,(void*) size,NULL);
        } else {
          xbt_die("Be sure of passing a good format for content file.\n");
-         // You can generate this kind of file with command line:
-         // find /path/you/want -type f -exec ls -l {} \; 2>/dev/null > ./content.txt
        }
      }
    }
diff --combined src/surf/surf.c
@@@ -110,11 -110,7 +110,11 @@@ int __surf_is_absolute_file_path(const 
  
  double NOW = 0;
  
 -xbt_dynar_t model_list = NULL;
 +/* model_list_invoke contains only surf_workstation and surf_vm_workstation.
 + * The callback functions of cpu_model and network_model will be called from
 + * those of these workstation models. */
 +xbt_dynar_t model_list = NULL; /* for destroying all models correctly */
 +xbt_dynar_t model_list_invoke = NULL;  /* for invoking callbacks */
  tmgr_history_t history = NULL;
  lmm_system_t maxmin_system = NULL;
  xbt_dynar_t surf_path = NULL;
@@@ -208,7 -204,6 +208,6 @@@ s_surf_model_description_t surf_new_mod
  static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
  #endif
  
- static int surf_nthreads = 1;    /* number of threads of the parmap (1 means no parallelism) */
  static double *surf_mins = NULL; /* return value of share_resources for each model */
  static int surf_min_index;       /* current index in surf_mins */
  static double min;               /* duration determined by surf_solve */
@@@ -419,8 -414,6 +418,8 @@@ void surf_init(int *argc, char **argv
    xbt_init(argc, argv);
    if (!model_list)
      model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
 +  if (!model_list_invoke)
 +    model_list_invoke = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
    if (!history)
      history = tmgr_history_new();
  
@@@ -474,11 -467,8 +473,11 @@@ void surf_exit(void
    sg_config_finalize();
  
    xbt_dynar_foreach(model_list, iter, model)
 -      model->model_private->finalize();
 +      model->model_private->finalize(model);
    xbt_dynar_free(&model_list);
 +
 +  xbt_dynar_free(&model_list_invoke);
 +
    routing_exit();
  
    if (maxmin_system) {
@@@ -539,10 -529,8 +538,10 @@@ void surf_presolve(void
        }
      }
    }
 +
 +  /* FIXME: see what is check_update_action_state(). if necessary, use model_list_invoke. */
    xbt_dynar_foreach(model_list, iter, model)
 -      model->model_private->update_actions_state(NOW, 0.0);
 +      model->model_private->update_actions_state(model, NOW, 0.0);
  }
  
  double surf_solve(double max_date)
    XBT_DEBUG("Looking for next action end for all models except NS3");
  
    if (surf_mins == NULL) {
 -    surf_mins = xbt_new(double, xbt_dynar_length(model_list));
 +    surf_mins = xbt_new(double, xbt_dynar_length(model_list_invoke));
    }
    surf_min_index = 0;
  
-   if (surf_get_nthreads() > 1) {
-     /* parallel version */
- #ifdef CONTEXT_THREADS
-     xbt_parmap_apply(surf_parmap, (void_f_pvoid_t) surf_share_resources, model_list_invoke);
- #else
-     xbt_die("Asked to run in parallel, but no thread at hand...");
- #endif
-   }
-   else {
-     /* sequential version */
-     xbt_dynar_foreach(model_list_invoke, iter, model) {
-       surf_share_resources(model);
-     }
+   /* sequential version */
 -  xbt_dynar_foreach(model_list, iter, model) {
++  xbt_dynar_foreach(model_list_invoke, iter, model) {
+     surf_share_resources(model);
    }
  
    unsigned i;
 -  for (i = 0; i < xbt_dynar_length(model_list); i++) {
 +  for (i = 0; i < xbt_dynar_length(model_list_invoke); i++) {
      if ((min < 0.0 || surf_mins[i] < min)
          && surf_mins[i] >= 0.0) {
        min = surf_mins[i];
  
        XBT_DEBUG("Run for network at most %f", min);
        // run until min or next flow
 -      model_next_action_end = surf_network_model->model_private->share_resources(min);
 +      model_next_action_end = surf_network_model->model_private->share_resources(surf_network_model, min);
  
        XBT_DEBUG("Min for network : %f", model_next_action_end);
        if(model_next_action_end>=0.0)
    XBT_DEBUG("Duration set to %f", min);
  
    NOW = NOW + min;
--
-   if (surf_get_nthreads() > 1) {
-     /* parallel version */
- #ifdef CONTEXT_THREADS
-     xbt_parmap_apply(surf_parmap, (void_f_pvoid_t) surf_update_actions_state, model_list);
- #endif
-   }
-   else {
-     /* FIXME: model_list or model_list_invoke? revisit here later */
-     /* sequential version */
-     xbt_dynar_foreach(model_list, iter, model) {
-       surf_update_actions_state(model);
-     }
++  /* FIXME: model_list or model_list_invoke? revisit here later */
+   /* sequential version */
+   xbt_dynar_foreach(model_list, iter, model) {
+     surf_update_actions_state(model);
    }
  
  #ifdef HAVE_TRACING
@@@ -688,7 -656,7 +667,7 @@@ static void surf_share_resources(surf_m
    int i = __sync_fetch_and_add(&surf_min_index, 1);
    if (strcmp(model->name,"network NS3")) {
      XBT_DEBUG("Running for Resource [%s]", model->name);
 -    next_action_end = model->model_private->share_resources(NOW);
 +    next_action_end = model->model_private->share_resources(model, NOW);
      XBT_DEBUG("Resource [%s] : next action end = %f",
          model->name, next_action_end);
    }
  
  static void surf_update_actions_state(surf_model_t model)
  {
 -  model->model_private->update_actions_state(NOW, min);
 +  model->model_private->update_actions_state(model, NOW, min);
  }
  
- /**
-  * \brief Returns the number of parallel threads used to update the models.
-  * \return the number of threads (1 means no parallelism)
-  */
- int surf_get_nthreads(void) {
-   return surf_nthreads;
- }
- /**
-  * \brief Sets the number of parallel threads used to update the models.
-  *
-  * A value of 1 means no parallelism.
-  *
-  * \param nb_threads the number of threads to use
-  */
- void surf_set_nthreads(int nthreads) {
-   if (nthreads<=0) {
-      nthreads = xbt_os_get_numcores();
-      XBT_INFO("Auto-setting surf/nthreads to %d",nthreads);
-   }
- #ifdef CONTEXT_THREADS
-   xbt_parmap_destroy(surf_parmap);
-   surf_parmap = NULL;
- #endif
-   if (nthreads > 1) {
- #ifdef CONTEXT_THREADS
-     surf_parmap = xbt_parmap_new(nthreads, XBT_PARMAP_DEFAULT);
- #else
-     THROWF(arg_error, 0, "Cannot activate parallel threads in Surf: your architecture does not support threads");
- #endif
-   }
-   surf_nthreads = nthreads;
- }
--
  /* This function is a pimple that we ought to fix. But it won't be easy.
   *
   * The surf_solve() function does properly return the set of actions that changed.
diff --combined src/surf/workstation.c
  #include "storage_private.h"
  #include "surf/surf_resource.h"
  #include "simgrid/sg_config.h"
 -
 -typedef struct workstation_CLM03 {
 -  s_surf_resource_t generic_resource;   /* Must remain first to add this to a trace */
 -  void *net_elm;
 -  xbt_dynar_t storage;
 -} s_workstation_CLM03_t, *workstation_CLM03_t;
 +#include "workstation_private.h"
 +#include "vm_workstation_private.h"
 +#include "cpu_cas01_private.h"
 +#include "maxmin_private.h"
  
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf,
                                  "Logging specific to the SURF workstation module");
  
  surf_model_t surf_workstation_model = NULL;
  
 +
  static void workstation_new(sg_platf_host_cbarg_t host)
  {
 -  workstation_CLM03_t workstation = xbt_new0(s_workstation_CLM03_t, 1);
 +  const char *name = host->id;
  
 -  workstation->generic_resource.model = surf_workstation_model;
 -  workstation->generic_resource.name = xbt_strdup(host->id);
 -  workstation->storage = xbt_lib_get_or_null(storage_lib,host->id,ROUTING_STORAGE_HOST_LEVEL);
 -  workstation->net_elm = xbt_lib_get_or_null(host_lib,host->id,ROUTING_HOST_LEVEL);
 -  XBT_DEBUG("Create workstation %s with %ld mounted disks",host->id,xbt_dynar_length(workstation->storage));
 -  xbt_lib_set(host_lib, host->id, SURF_WKS_LEVEL, workstation);
 -}
 +  /* NOTE: The properties object is NULL, because the current code uses that of
 +   * that of a cpu resource. */
 +  workstation_CLM03_t ws = (workstation_CLM03_t) surf_resource_new(sizeof(s_workstation_CLM03_t), surf_workstation_model, name, NULL);
  
 -static int ws_resource_used(void *resource_id)
 -{
 -  THROW_IMPOSSIBLE;             /* This model does not implement parallel tasks */
 -  return -1;
 +  ws->storage = xbt_lib_get_or_null(storage_lib, name, ROUTING_STORAGE_HOST_LEVEL);
 +  ws->net_elm = xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
 +
 +  XBT_DEBUG("Create ws %s with %ld mounted disks", name, xbt_dynar_length(ws->storage));
 +  xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, ws);
  }
  
  static void ws_parallel_action_cancel(surf_action_t action)
  {
    THROW_UNIMPLEMENTED;          /* This model does not implement parallel tasks */
@@@ -49,28 -52,26 +48,28 @@@ static int ws_parallel_action_free(surf
    return -1;
  }
  
 -static int ws_action_unref(surf_action_t action)
 +int ws_action_unref(surf_action_t action)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      return surf_network_model->action_unref(action);
 -  else if (action->model_type == surf_cpu_model)
 -    return surf_cpu_model->action_unref(action);
 -  else if (action->model_type == surf_workstation_model)
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    return action->model_obj->action_unref(action);
 +      // previously was: Adrien/Arnaud 6 feb
 +        // surf_cpu_model->action_unref(action);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
      return ws_parallel_action_free(action);
    else
      DIE_IMPOSSIBLE;
    return 0;
  }
  
 -static void ws_action_cancel(surf_action_t action)
 +void ws_action_cancel(surf_action_t action)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      surf_network_model->action_cancel(action);
 -  else if (action->model_type == surf_cpu_model)
 -    surf_cpu_model->action_cancel(action);
 -  else if (action->model_type == surf_workstation_model)
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->action_cancel(action);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
      ws_parallel_action_cancel(action);
    else
      DIE_IMPOSSIBLE;
  static void ws_action_state_set(surf_action_t action,
                                  e_surf_action_state_t state)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      surf_network_model->action_state_set(action, state);
 -  else if (action->model_type == surf_cpu_model)
 -    surf_cpu_model->action_state_set(action, state);
 -  else if (action->model_type == surf_workstation_model)
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->action_state_set(action, state);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_WORKSTATION)
      surf_action_state_set(action, state);
    else
      DIE_IMPOSSIBLE;
    return;
  }
  
 -static double ws_share_resources(double now)
 +
 +/* -- The callback functions at model_private -- */
 +/* These callbacks are also used for the vm workstation model. */
 +int ws_resource_used(void *resource_id)
  {
 -  return -1.0;
 +  /* This model does not implement parallel tasks */
 +  THROW_IMPOSSIBLE;
 +  return -1;
 +}
 +
 +
 +/* TODO: The current code would be slow due to the iteration. Later, we can
 + * make it faster. */
 +static int constraint_is_active(cpu_Cas01_t cpu_cas01)
 +{
 +  surf_model_t cpu_model = cpu_cas01->generic_resource.model;
 +  lmm_system_t sys = cpu_model->model_private->maxmin_system;
 +  int found = 0;
 +  lmm_constraint_t cnst_tmp;
 +
 +  xbt_swag_foreach(cnst_tmp, &sys->active_constraint_set) {
 +    if (cnst_tmp == cpu_cas01->constraint) {
 +      found = 1;
 +      break;
 +    }
 +  }
 +
 +  return found;
 +}
 +
 +/* Each VM has a dummy CPU action on the PM layer. This CPU action works as the
 + * constraint (capacity) of the VM in the PM layer. If the VM does not have any
 + * active task, the dummy CPU action must be deactivated, so that the VM does
 + * not get any CPU share in the PM layer. */
 +static void adjust_weight_of_dummy_cpu_actions(void)
 +{
 +  /* iterate for all hosts including virtual machines */
 +  xbt_lib_cursor_t cursor;
 +  char *key;
 +  void **ind_host;
 +
 +  xbt_lib_foreach(host_lib, cursor, key, ind_host) {
 +    workstation_CLM03_t ws_clm03 = ind_host[SURF_WKS_LEVEL];
 +    cpu_Cas01_t cpu_cas01 = ind_host[SURF_CPU_LEVEL];
 +
 +    if (!ws_clm03)
 +      continue;
 +    /* skip if it is not a virtual machine */
 +    if (ws_clm03->generic_resource.model != surf_vm_workstation_model)
 +      continue;
 +    xbt_assert(cpu_cas01, "cpu-less workstation");
 +
 +    /* It is a virtual machine, so we can cast it to workstation_VM2013_t */
 +    workstation_VM2013_t ws_vm2013 = (workstation_VM2013_t) ws_clm03;
 +
 +    if (constraint_is_active(cpu_cas01)) {
 +      /* some tasks exist on this VM */
 +      XBT_DEBUG("set the weight of the dummy CPU action on PM to 1");
 +
 +      /* FIXME: we shoud use lmm_update_variable_weight() ? */
 +      /* FIXME: If we assgign 1.05 and 0.05, the system makes apparently wrong values. */
 +      surf_action_set_priority(ws_vm2013->cpu_action, 1);
 +
 +    } else {
 +      /* no task exits on this VM */
 +      XBT_DEBUG("set the weight of the dummy CPU action on PM to 0");
 +
 +      surf_action_set_priority(ws_vm2013->cpu_action, 0);
 +    }
 +  }
  }
  
 -static void ws_update_actions_state(double now, double delta)
 +
 +double ws_share_resources(surf_model_t workstation_model, double now)
 +{
 +  if (workstation_model->type == SURF_MODEL_TYPE_WORKSTATION)
 +    adjust_weight_of_dummy_cpu_actions();
 +
 +  /* Invoke the share_resources() callback of the physical cpu model object and
 +   * the network model objects. */
 +  surf_model_t cpu_model = workstation_model->extension.workstation.cpu_model;
 +  surf_model_t net_model = surf_network_model;
 +
 +  double min_by_cpu = cpu_model->model_private->share_resources(cpu_model, now);
 +  double min_by_net = net_model->model_private->share_resources(net_model, now);
 +
 +  XBT_DEBUG("model %p, %s min_by_cpu %f, %s min_by_net %f",
 +      workstation_model, cpu_model->name, min_by_cpu, net_model->name, min_by_net);
 +
 +  if (min_by_cpu >= 0.0 && min_by_net >= 0.0)
 +    return min(min_by_cpu, min_by_net);
 +  else if (min_by_cpu >= 0.0)
 +    return min_by_cpu;
 +  else if (min_by_net >= 0.0)
 +    return min_by_net;
 +  else
 +    return min_by_cpu;  /* probably min_by_cpu == min_by_net == -1 */
 +}
 +
 +void ws_update_actions_state(surf_model_t workstation_model, double now, double delta)
  {
    return;
  }
  
 -static void ws_update_resource_state(void *id,
 -                                     tmgr_trace_event_t event_type,
 -                                     double value, double date)
 +void ws_update_resource_state(void *id, tmgr_trace_event_t event_type, double value, double date)
  {
 -  THROW_IMPOSSIBLE;             /* This model does not implement parallel tasks */
 +  /* This model does not implement parallel tasks */
 +  THROW_IMPOSSIBLE;
  }
  
 -static surf_action_t ws_execute(void *workstation, double size)
 +void ws_finalize(surf_model_t workstation_model)
 +{
 +  surf_model_exit(workstation_model);
 +  workstation_model = NULL;
 +}
 +
 +
 +
 +surf_action_t ws_execute(void *workstation, double size)
  {
    surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
    return cpu->model->extension.cpu.execute(workstation, size);
  }
  
 -static surf_action_t ws_action_sleep(void *workstation, double duration)
 +surf_action_t ws_action_sleep(void *workstation, double duration)
  {
 -  return surf_cpu_model->extension.cpu.
 -      sleep(workstation, duration);
 +  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
 +  return cpu->model->extension.cpu.sleep(workstation, duration);
  }
  
 -static void ws_action_suspend(surf_action_t action)
 +void ws_action_suspend(surf_action_t action)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      surf_network_model->suspend(action);
 -  else if (action->model_type == surf_cpu_model)
 -    surf_cpu_model->suspend(action);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->suspend(action);
    else
      DIE_IMPOSSIBLE;
  }
  
 -static void ws_action_resume(surf_action_t action)
 +void ws_action_resume(surf_action_t action)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      surf_network_model->resume(action);
 -  else if (action->model_type == surf_cpu_model)
 -    surf_cpu_model->resume(action);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->resume(action);
    else
      DIE_IMPOSSIBLE;
  }
  
  static int ws_action_is_suspended(surf_action_t action)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      return surf_network_model->is_suspended(action);
 -  if (action->model_type == surf_cpu_model)
 -    return surf_cpu_model->is_suspended(action);
 +  if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    return action->model_obj->is_suspended(action);
    DIE_IMPOSSIBLE;
    return -1;
  }
  static void ws_action_set_max_duration(surf_action_t action,
                                         double duration)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      surf_network_model->set_max_duration(action, duration);
 -  else if (action->model_type == surf_cpu_model)
 -    surf_cpu_model->set_max_duration(action, duration);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->set_max_duration(action, duration);
    else
      DIE_IMPOSSIBLE;
  }
  
 -static void ws_action_set_priority(surf_action_t action, double priority)
 +void ws_action_set_priority(surf_action_t action, double priority)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      surf_network_model->set_priority(action, priority);
 -  else if (action->model_type == surf_cpu_model)
 -    surf_cpu_model->set_priority(action, priority);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->set_priority(action, priority);
 +  else
 +    DIE_IMPOSSIBLE;
 +}
 +
 +void ws_action_set_bound(surf_action_t action, double bound)
 +{
 +  /* FIXME: only for CPU model object? */
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
 +    surf_network_model->set_bound(action, bound);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->set_bound(action, bound);
    else
      DIE_IMPOSSIBLE;
  }
  #ifdef HAVE_TRACING
  static void ws_action_set_category(surf_action_t action, const char *category)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      surf_network_model->set_category(action, category);
 -  else if (action->model_type == surf_cpu_model)
 -    surf_cpu_model->set_category(action, category);
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->set_category(action, category);
    else
      DIE_IMPOSSIBLE;
  }
  #ifdef HAVE_LATENCY_BOUND_TRACKING
  static int ws_get_latency_limited(surf_action_t action)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      return surf_network_model->get_latency_limited(action);
    else
      return 0;
  }
  #endif
  
 -static double ws_action_get_remains(surf_action_t action)
 +double ws_action_get_remains(surf_action_t action)
  {
 -  if (action->model_type == surf_network_model)
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
      return surf_network_model->get_remains(action);
 -  if (action->model_type == surf_cpu_model)
 -    return surf_cpu_model->get_remains(action);
 +  if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    return action->model_obj->get_remains(action);
    DIE_IMPOSSIBLE;
    return -1.0;
  }
@@@ -326,28 -215,30 +325,33 @@@ static surf_action_t ws_communicate(voi
                    dst->net_elm, size, rate);
  }
  
 -static e_surf_resource_state_t ws_get_state(void *workstation)
 +e_surf_resource_state_t ws_get_state(void *workstation)
  {
 -  return surf_cpu_model->extension.cpu.
 -      get_state(workstation);
 +  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
 +  return cpu->model->extension.cpu.get_state(workstation);
  }
  
- void ws_set_state(void *workstation, e_surf_resource_state_t state)
 -static double ws_get_speed(void *workstation, double load)
++static void ws_set_state(void *workstation, e_surf_resource_state_t state)
  {
 -  return surf_cpu_model->extension.cpu.
 -      get_speed(workstation, load);
 +  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
 +  cpu->model->extension.cpu.set_state(workstation, state);
  }
  
 -static int ws_get_core(void *workstation)
 +double ws_get_speed(void *workstation, double load)
  {
 -  return surf_cpu_model->extension.cpu.
 -      get_core(workstation);
 +  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
 +  return cpu->model->extension.cpu.get_speed(workstation, load);
  }
  
 -
 -
++static int ws_get_core(void *workstation)
++{
++  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
++  return cpu->model->extension.cpu.get_core(workstation);
++}
  static double ws_get_available_speed(void *workstation)
  {
 -  return surf_cpu_model->extension.cpu.
 -      get_available_speed(workstation);
 +  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
 +  return cpu->model->extension.cpu.get_available_speed(workstation);
  }
  
  static surf_action_t ws_execute_parallel_task(int workstation_nb,
@@@ -411,6 -302,12 +415,6 @@@ static int ws_link_shared(const void *l
    return surf_network_model->extension.network.link_shared(link);
  }
  
 -static void ws_finalize(void)
 -{
 -  surf_model_exit(surf_workstation_model);
 -  surf_workstation_model = NULL;
 -}
 -
  static xbt_dict_t ws_get_properties(const void *ws)
  {
    return surf_resource_properties(surf_cpu_resource_priv(ws));
@@@ -437,55 -334,72 +441,72 @@@ static storage_t find_storage_on_mount_
    return st;
  }
  
- static surf_action_t ws_action_open(void *workstation, const char* mount, const char* path, const char* mode)
+ static surf_action_t ws_action_open(void *workstation, const char* mount,
+                                     const char* path)
  {
    storage_t st = find_storage_on_mount_list(workstation, mount);
    XBT_DEBUG("OPEN on disk '%s'",st->generic_resource.name);
    surf_model_t model = st->generic_resource.model;
-   return model->extension.storage.open(st, mount, path, mode);
+   return model->extension.storage.open(st, mount, path);
  }
  
- static surf_action_t ws_action_close(void *workstation, surf_file_t fp)
+ static surf_action_t ws_action_close(void *workstation, surf_file_t fd)
  {
-   storage_t st = find_storage_on_mount_list(workstation, fp->storage);
+   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
    XBT_DEBUG("CLOSE on disk '%s'",st->generic_resource.name);
    surf_model_t model = st->generic_resource.model;
-   return model->extension.storage.close(st, fp);
+   return model->extension.storage.close(st, fd);
  }
  
- static surf_action_t ws_action_read(void *workstation, void* ptr, size_t size, size_t nmemb, surf_file_t stream)
+ static surf_action_t ws_action_read(void *workstation, void* ptr, size_t size,
+                                     surf_file_t fd)
  {
-   storage_t st = find_storage_on_mount_list(workstation, stream->storage);
+   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
    XBT_DEBUG("READ on disk '%s'",st->generic_resource.name);
    surf_model_t model = st->generic_resource.model;
-   return model->extension.storage.read(st, ptr, (double)size, nmemb, stream);
+   return model->extension.storage.read(st, ptr, size, fd);
  }
  
- static surf_action_t ws_action_write(void *workstation, const void* ptr, size_t size, size_t nmemb, surf_file_t stream)
+ static surf_action_t ws_action_write(void *workstation, const void* ptr,
+                                      size_t size, surf_file_t fd)
  {
-   storage_t st = find_storage_on_mount_list(workstation, stream->storage);
+   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
    XBT_DEBUG("WRITE on disk '%s'",st->generic_resource.name);
    surf_model_t model = st->generic_resource.model;
-   return model->extension.storage.write(st,  ptr, size, nmemb, stream);
+   return model->extension.storage.write(st,  ptr, size, fd);
  }
  
- static surf_action_t ws_action_stat(void *workstation, surf_file_t stream)
+ static int ws_file_unlink(void *workstation, surf_file_t fd)
  {
-   storage_t st = find_storage_on_mount_list(workstation, stream->storage);
-   XBT_DEBUG("STAT on disk '%s'",st->generic_resource.name);
-   surf_model_t model = st->generic_resource.model;
-   return model->extension.storage.stat(st,  stream);
- }
+   if (!fd){
+     XBT_WARN("No such file descriptor. Impossible to unlink");
+     return 0;
+   } else {
+ //    XBT_INFO("%s %zu", fd->storage, fd->size);
+     storage_t st = find_storage_on_mount_list(workstation, fd->storage);
+     xbt_dict_t content_dict = (st)->content;
+     /* Check if the file is on this storage */
+     if (!xbt_dict_get_or_null(content_dict, fd->name)){
+       XBT_WARN("File %s is not on disk %s. Impossible to unlink", fd->name,
+           st->generic_resource.name);
+       return 0;
+     } else {
+       XBT_DEBUG("UNLINK on disk '%s'",st->generic_resource.name);
+       st->used_size -= fd->size;
  
- static surf_action_t ws_action_unlink(void *workstation, surf_file_t stream)
- {
-   storage_t st = find_storage_on_mount_list(workstation, stream->storage);
-   XBT_DEBUG("UNLINK on disk '%s'",st->generic_resource.name);
-   surf_model_t model = st->generic_resource.model;
-   return model->extension.storage.unlink(st,  stream);
+       // Remove the file from storage
+       xbt_dict_remove(content_dict,fd->name);
+       free(fd->name);
+       free(fd->storage);
+       xbt_free(fd);
+       return 1;
+     }
+   }
  }
  
- static surf_action_t ws_action_ls(void *workstation, const char* mount, const char *path)
+ static surf_action_t ws_action_ls(void *workstation, const char* mount,
+                                   const char *path)
  {
    XBT_DEBUG("LS on mount '%s' and file '%s'",mount, path);
    storage_t st = find_storage_on_mount_list(workstation, mount);
    return model->extension.storage.ls(st, path);
  }
  
 -static void surf_workstation_model_init_internal(void)
+ static size_t ws_file_get_size(void *workstation, surf_file_t fd)
+ {
+   return fd->size;
+ }
 +void ws_get_params(void *ws, ws_params_t params)
  {
 -  surf_workstation_model = surf_model_init();
 -
 -  surf_workstation_model->name = "Workstation";
 -  surf_workstation_model->action_unref = ws_action_unref;
 -  surf_workstation_model->action_cancel = ws_action_cancel;
 -  surf_workstation_model->action_state_set = ws_action_state_set;
 -
 -  surf_workstation_model->model_private->resource_used = ws_resource_used;
 -  surf_workstation_model->model_private->share_resources =
 -      ws_share_resources;
 -  surf_workstation_model->model_private->update_actions_state =
 -      ws_update_actions_state;
 -  surf_workstation_model->model_private->update_resource_state =
 -      ws_update_resource_state;
 -  surf_workstation_model->model_private->finalize = ws_finalize;
 -
 -  surf_workstation_model->suspend = ws_action_suspend;
 -  surf_workstation_model->resume = ws_action_resume;
 -  surf_workstation_model->is_suspended = ws_action_is_suspended;
 -  surf_workstation_model->set_max_duration = ws_action_set_max_duration;
 -  surf_workstation_model->set_priority = ws_action_set_priority;
 -#ifdef HAVE_TRACING
 -  surf_workstation_model->set_category = ws_action_set_category;
 -#endif
 -  surf_workstation_model->get_remains = ws_action_get_remains;
 -#ifdef HAVE_LATENCY_BOUND_TRACKING
 -  surf_workstation_model->get_latency_limited = ws_get_latency_limited;
 -#endif
 +  workstation_CLM03_t ws_clm03 = surf_workstation_resource_priv(ws);
 +  memcpy(params, &ws_clm03->params, sizeof(s_ws_params_t));
 +}
 +
 +void ws_set_params(void *ws, ws_params_t params)
 +{
 +  workstation_CLM03_t ws_clm03 = surf_workstation_resource_priv(ws);
 +  /* may check something here. */
 +  memcpy(&ws_clm03->params, params, sizeof(s_ws_params_t));
 +}
 +
 +static xbt_dynar_t ws_get_vms(void *pm)
 +{
 +  xbt_dynar_t dyn = xbt_dynar_new(sizeof(smx_host_t), NULL);
 +
 +  /* iterate for all hosts including virtual machines */
 +  xbt_lib_cursor_t cursor;
 +  char *key;
 +  void **ind_host;
 +  xbt_lib_foreach(host_lib, cursor, key, ind_host) {
 +    workstation_CLM03_t ws_clm03 = ind_host[SURF_WKS_LEVEL];
 +    if (!ws_clm03)
 +      continue;
 +    /* skip if it is not a virtual machine */
 +    if (ws_clm03->generic_resource.model != surf_vm_workstation_model)
 +      continue;
 +
 +    /* It is a virtual machine, so we can cast it to workstation_VM2013_t */
 +    workstation_VM2013_t ws_vm2013 = (workstation_VM2013_t) ws_clm03;
 +    if (pm == ws_vm2013->sub_ws)
 +      xbt_dynar_push(dyn, &ws_vm2013->sub_ws);
 +  }
 +
 +  return dyn;
 +}
  
 -  surf_workstation_model->extension.workstation.execute = ws_execute;
 -  surf_workstation_model->extension.workstation.sleep = ws_action_sleep;
 -  surf_workstation_model->extension.workstation.get_state = ws_get_state;
 -  surf_workstation_model->extension.workstation.get_core = ws_get_core;
 -  surf_workstation_model->extension.workstation.get_speed = ws_get_speed;
 -  surf_workstation_model->extension.workstation.get_available_speed =
 +
 +static void surf_workstation_model_init_internal(void)
 +{
 +  surf_model_t model = surf_model_init();
 +
 +  model->name = "Workstation";
 +  model->type = SURF_MODEL_TYPE_WORKSTATION;
 +  model->action_unref     = ws_action_unref;
 +  model->action_cancel    = ws_action_cancel;
 +  model->action_state_set = ws_action_state_set;
 +
 +  model->model_private->resource_used         = ws_resource_used;
 +  model->model_private->share_resources       = ws_share_resources;
 +  model->model_private->update_actions_state  = ws_update_actions_state;
 +  model->model_private->update_resource_state = ws_update_resource_state;
 +  model->model_private->finalize              = ws_finalize;
 +
 +  model->suspend          = ws_action_suspend;
 +  model->resume           = ws_action_resume;
 +  model->is_suspended     = ws_action_is_suspended;
 +  model->set_max_duration = ws_action_set_max_duration;
 +  model->set_priority     = ws_action_set_priority;
 +  model->set_bound        = ws_action_set_bound;
 +  #ifdef HAVE_TRACING
 +  model->set_category     = ws_action_set_category;
 +  #endif
 +  model->get_remains      = ws_action_get_remains;
 +  #ifdef HAVE_LATENCY_BOUND_TRACKING
 +  model->get_latency_limited = ws_get_latency_limited;
 +  #endif
 +
 +  /* For VM support, we have a surf cpu model object for each workstation model
 +   * object. The physical workstation model object has the cpu model object of
 +   * the physical machine layer. */
 +  xbt_assert(surf_cpu_model_pm);
 +  model->extension.workstation.cpu_model = surf_cpu_model_pm;
 +
 +  model->extension.workstation.execute   = ws_execute;
 +  model->extension.workstation.sleep     = ws_action_sleep;
 +  model->extension.workstation.get_state = ws_get_state;
 +  model->extension.workstation.set_state = ws_set_state;
++  model->extension.workstation.get_core  = ws_get_core;
 +  model->extension.workstation.get_speed = ws_get_speed;
-   model->extension.workstation.get_available_speed = ws_get_available_speed;
++  model->extension.workstation.get_available_speed =
+       ws_get_available_speed;
  
 -  surf_workstation_model->extension.workstation.communicate =
 -      ws_communicate;
 -  surf_workstation_model->extension.workstation.get_route = ws_get_route;
 -  surf_workstation_model->extension.workstation.execute_parallel_task =
 -      ws_execute_parallel_task;
 -  surf_workstation_model->extension.workstation.get_link_bandwidth =
 -      ws_get_link_bandwidth;
 -  surf_workstation_model->extension.workstation.get_link_latency =
 -      ws_get_link_latency;
 -  surf_workstation_model->extension.workstation.link_shared =
 -      ws_link_shared;
 -  surf_workstation_model->extension.workstation.get_properties =
 -      ws_get_properties;
 -
 -  surf_workstation_model->extension.workstation.open = ws_action_open;
 -  surf_workstation_model->extension.workstation.close = ws_action_close;
 -  surf_workstation_model->extension.workstation.read = ws_action_read;
 -  surf_workstation_model->extension.workstation.write = ws_action_write;
 -  surf_workstation_model->extension.workstation.unlink = ws_file_unlink;
 -  surf_workstation_model->extension.workstation.ls = ws_action_ls;
 -  surf_workstation_model->extension.workstation.get_size = ws_file_get_size;
 +  model->extension.workstation.communicate           = ws_communicate;
 +  model->extension.workstation.get_route             = ws_get_route;
 +  model->extension.workstation.execute_parallel_task = ws_execute_parallel_task;
 +  model->extension.workstation.get_link_bandwidth    = ws_get_link_bandwidth;
 +  model->extension.workstation.get_link_latency      = ws_get_link_latency;
 +  model->extension.workstation.link_shared           = ws_link_shared;
 +  model->extension.workstation.get_properties        = ws_get_properties;
 +
 +  model->extension.workstation.open   = ws_action_open;
 +  model->extension.workstation.close  = ws_action_close;
 +  model->extension.workstation.read   = ws_action_read;
 +  model->extension.workstation.write  = ws_action_write;
-   model->extension.workstation.stat   = ws_action_stat;
-   model->extension.workstation.unlink = ws_action_unlink;
++  model->extension.workstation.unlink = ws_file_unlink;
 +  model->extension.workstation.ls     = ws_action_ls;
 +
 +  model->extension.workstation.get_params = ws_get_params;
 +  model->extension.workstation.set_params = ws_set_params;
 +  model->extension.workstation.get_vms    = ws_get_vms;
 +
 +  surf_workstation_model = model;
  }
  
  void surf_workstation_model_init_current_default(void)
  {
-   xbt_cfg_setdefault_int(_sg_cfg_set, "network/crosstraffic", 1);
 -  surf_workstation_model_init_internal();
+   xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", xbt_strdup("yes"));
    surf_cpu_model_init_Cas01();
    surf_network_model_init_LegrandVelho();
  
 +  /* surf_cpu_mode_pm and surf_network_model must be initialized in advance. */
 +  xbt_assert(surf_cpu_model_pm);
 +  xbt_assert(surf_network_model);
 +  surf_workstation_model_init_internal();
 +
    xbt_dynar_push(model_list, &surf_workstation_model);
 +  xbt_dynar_push(model_list_invoke, &surf_workstation_model);
    sg_platf_host_add_cb(workstation_new);
  }
  
  void surf_workstation_model_init_compound()
  {
 -
 -  xbt_assert(surf_cpu_model, "No CPU model defined yet!");
 +  xbt_assert(surf_cpu_model_pm, "No CPU model defined yet!");
    xbt_assert(surf_network_model, "No network model defined yet!");
 +
    surf_workstation_model_init_internal();
    xbt_dynar_push(model_list, &surf_workstation_model);
 +  xbt_dynar_push(model_list_invoke, &surf_workstation_model);
    sg_platf_host_add_cb(workstation_new);
  }