Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge tag 'v3_9_90' into hypervisor
authorPaul Bédaride <paul.bedaride@gmail.com>
Fri, 8 Nov 2013 10:50:47 +0000 (11:50 +0100)
committerPaul Bédaride <paul.bedaride@gmail.com>
Fri, 8 Nov 2013 10:50:47 +0000 (11:50 +0100)
Conflicts:
include/msg/msg.h
include/simgrid/simix.h
src/include/surf/surf.h
src/msg/msg_global.c
src/msg/msg_host.c
src/msg/msg_private.h
src/msg/msg_process.c
src/simix/smx_host.c
src/simix/smx_host_private.h
src/simix/smx_smurf_private.h
src/surf/cpu_cas01.c
src/surf/cpu_cas01_private.h
src/surf/cpu_ti.c
src/surf/surf.c
src/surf/workstation.c

69 files changed:
1  2 
.cproject
.project
buildtools/Cmake/DefinePackages.cmake
doc/doxygen/platform.doc
examples/java/cloud/Cloud.java
examples/java/cloud/Master.java
examples/java/cloud/Slave.java
examples/msg/cloud/masterslave_virtual_machines.c
examples/msg/cloud/multicore.c
include/msg/datatypes.h
include/msg/msg.h
include/simgrid/platf.h
include/simgrid/simix.h
include/xbt/ex.h
include/xbt/lib.h
src/bindings/java/jmsg_host.c
src/bindings/java/jmsg_host.h
src/bindings/java/jmsg_task.c
src/bindings/java/jmsg_task.h
src/bindings/java/jmsg_vm.c
src/bindings/java/jmsg_vm.h
src/bindings/java/org/simgrid/msg/Host.java
src/bindings/java/org/simgrid/msg/Task.java
src/bindings/java/org/simgrid/msg/VM.java
src/bindings/java/smx_context_java.c
src/bindings/lua/lua_host.c
src/include/surf/maxmin.h
src/include/surf/surf.h
src/msg/instr_msg_vm.c
src/msg/msg_global.c
src/msg/msg_gos.c
src/msg/msg_host.c
src/msg/msg_private.h
src/msg/msg_process.c
src/msg/msg_task.c
src/msg/msg_vm.c
src/simdag/sd_global.c
src/simgrid/sg_config.c
src/simix/smx_deployment.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_new_api.c
src/simix/smx_process.c
src/simix/smx_smurf_private.h
src/simix/smx_synchro.c
src/simix/smx_user.c
src/smpi/smpi_bench.c
src/surf/cpu_cas01.c
src/surf/cpu_cas01_private.h
src/surf/cpu_ti.c
src/surf/maxmin.c
src/surf/network.c
src/surf/network_constant.c
src/surf/network_gtnets.c
src/surf/network_ns3.c
src/surf/new_model.c
src/surf/storage.c
src/surf/surf.c
src/surf/surf_action.c
src/surf/surf_private.h
src/surf/vm_workstation.c
src/surf/workstation.c
src/surf/workstation_ptask_L07.c
src/xbt/ex.c
src/xbt/lib.c
testsuite/surf/surf_usage.c

diff --combined .cproject
+++ b/.cproject
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
--<?fileVersion 5.0.0?>
--
--<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage2">
++<?fileVersion 5.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage2">
        <storageModule moduleId="org.eclipse.cdt.core.settings">
-               <cconfiguration id="0.1454192080">
-                       <storageModule externalCElementFile="0.1454192080_org.eclipse.cdt.core.settings" id="0.1454192080" name="Default"/>
-                       <storageModule externalCElementFile="0.1454192080_cdtBuildSystem" version="4.0.0"/>
-                       <storageModule externalCElementFile="0.1454192080_org.eclipse.cdt.core.externalSettings"/>
 -              <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1353180652">
 -                      <storageModule externalCElementFile="cdt.managedbuild.toolchain.gnu.base.1353180652_org.eclipse.cdt.core.settings" id="cdt.managedbuild.toolchain.gnu.base.1353180652" name="Default"/>
 -                      <storageModule externalCElementFile="cdt.managedbuild.toolchain.gnu.base.1353180652_cdtBuildSystem" version="4.0.0"/>
 -                      <storageModule externalCElementFile="cdt.managedbuild.toolchain.gnu.base.1353180652_org.eclipse.cdt.core.externalSettings"/>
++              <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1053321950">
++                      <storageModule externalCElementFile="cdt.managedbuild.toolchain.gnu.base.1053321950_org.eclipse.cdt.core.settings" id="cdt.managedbuild.toolchain.gnu.base.1053321950" name="Default"/>
++                      <storageModule externalCElementFile="cdt.managedbuild.toolchain.gnu.base.1053321950_cdtBuildSystem" version="4.0.0"/>
++                      <storageModule externalCElementFile="cdt.managedbuild.toolchain.gnu.base.1053321950_org.eclipse.cdt.core.externalSettings"/>
                </cconfiguration>
        </storageModule>
 -      <storageModule moduleId="org.eclipse.cdt.core.pathentry">
 -              <pathentry kind="mac" name="main" path="" value="smpi_simulated_main"/>
 -              <pathentry include="/usr/include/lua5.1" kind="inc" path="" system="true"/>
 -              <pathentry include="/usr/include" kind="inc" path="" system="true"/>
 -              <pathentry base-path="simgrid" include="include" kind="inc" path="" system="true"/>
 -              <pathentry base-path="simgrid" include="src/include" kind="inc" path="" system="true"/>
 -              <pathentry base-path="simgrid" include="src" kind="inc" path="" system="true"/>
 -              <pathentry excluding="**/CMakeFiles/" kind="out" path=""/>
 -              <pathentry kind="src" path=""/>
 -      </storageModule>
        <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-               <project id="simgrid.null.1424519849" name="simgrid"/>
 -              <project id="simgrid.null.697056024" name="simgrid"/>
++              <project id="simgrid.null.1652888656" name="simgrid"/>
 +      </storageModule>
 +      <storageModule moduleId="scannerConfiguration">
 +              <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-               <scannerConfigBuildInfo instanceId="0.1454192080">
-                       <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-               </scannerConfigBuildInfo>
+       </storageModule>
++      <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+       <storageModule moduleId="refreshScope" versionNumber="2">
+               <configuration configurationName="Default">
+                       <resource resourceType="PROJECT" workspacePath="/simgrid"/>
+               </configuration>
        </storageModule>
 -      <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
 -      <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
 -      <storageModule moduleId="scannerConfiguration">
 -              <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile"/>
 -              <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
 -                      <buildOutputProvider>
 -                              <openAction enabled="true" filePath=""/>
 -                              <parser enabled="true"/>
 -                      </buildOutputProvider>
 -                      <scannerInfoProvider id="specsFile">
 -                              <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="/usr/bin/gcc" useDefault="true"/>
 -                              <parser enabled="true"/>
 -                      </scannerInfoProvider>
 -              </profile>
 -              <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
 -                      <buildOutputProvider>
 -                              <openAction enabled="true" filePath=""/>
 -                              <parser enabled="true"/>
 -                      </buildOutputProvider>
 -                      <scannerInfoProvider id="makefileGenerator">
 -                              <runAction arguments="-f ${project_name}_scd.mk" command="/usr/bin/make" useDefault="true"/>
 -                              <parser enabled="true"/>
 -                      </scannerInfoProvider>
 -              </profile>
 -              <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1353180652;cdt.managedbuild.toolchain.gnu.base.1353180652.1797514135;cdt.managedbuild.tool.gnu.c.compiler.base.2037544368;cdt.managedbuild.tool.gnu.c.compiler.input.1851803849">
 -                      <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
 -                      <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
 -                              <buildOutputProvider>
 -                                      <openAction enabled="true" filePath=""/>
 -                                      <parser enabled="true"/>
 -                              </buildOutputProvider>
 -                              <scannerInfoProvider id="specsFile">
 -                                      <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="/usr/bin/gcc" useDefault="true"/>
 -                                      <parser enabled="true"/>
 -                              </scannerInfoProvider>
 -                      </profile>
 -                      <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
 -                              <buildOutputProvider>
 -                                      <openAction enabled="true" filePath=""/>
 -                                      <parser enabled="true"/>
 -                              </buildOutputProvider>
 -                              <scannerInfoProvider id="makefileGenerator">
 -                                      <runAction arguments="-f ${project_name}_scd.mk" command="/usr/bin/make" useDefault="true"/>
 -                                      <parser enabled="true"/>
 -                              </scannerInfoProvider>
 -                      </profile>
 -              </scannerConfigBuildInfo>
 -              <scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.1353180652;cdt.managedbuild.toolchain.gnu.base.1353180652.1797514135;cdt.managedbuild.tool.gnu.cpp.compiler.base.1129818443;cdt.managedbuild.tool.gnu.cpp.compiler.input.500761747">
 -                      <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
 -                      <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
 -                              <buildOutputProvider>
 -                                      <openAction enabled="true" filePath=""/>
 -                                      <parser enabled="true"/>
 -                              </buildOutputProvider>
 -                              <scannerInfoProvider id="specsFile">
 -                                      <runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="/usr/bin/gcc" useDefault="true"/>
 -                                      <parser enabled="true"/>
 -                              </scannerInfoProvider>
 -                      </profile>
 -                      <profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
 -                              <buildOutputProvider>
 -                                      <openAction enabled="true" filePath=""/>
 -                                      <parser enabled="true"/>
 -                              </buildOutputProvider>
 -                              <scannerInfoProvider id="makefileGenerator">
 -                                      <runAction arguments="-f ${project_name}_scd.mk" command="/usr/bin/make" useDefault="true"/>
 -                                      <parser enabled="true"/>
 -                              </scannerInfoProvider>
 -                      </profile>
 -              </scannerConfigBuildInfo>
 -      </storageModule>
  </cproject>
diff --combined .project
index 0000000,d935a7a..a3b80ff
mode 000000,100644..100644
--- /dev/null
+++ b/.project
@@@ -1,0 -1,91 +1,27 @@@
 -  <name>simgrid</name>
 -  <comment></comment>
 -  <projects>
 -  </projects>
 -  <buildSpec>
 -    <buildCommand>
 -      <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
 -      <triggers>clean,full,incremental,</triggers>
 -      <arguments>
 -        <dictionary>
 -          <key>?name?</key>
 -          <value></value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.append_environment</key>
 -          <value>true</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.autoBuildTarget</key>
 -          <value>all</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.buildArguments</key>
 -          <value></value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.buildCommand</key>
 -          <value>make</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
 -          <value>clean</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.contents</key>
 -          <value>org.eclipse.cdt.make.core.activeConfigSettings</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.enableAutoBuild</key>
 -          <value>false</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.enableCleanBuild</key>
 -          <value>true</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.enableFullBuild</key>
 -          <value>true</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.fullBuildTarget</key>
 -          <value>all</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.stopOnError</key>
 -          <value>true</value>
 -        </dictionary>
 -        <dictionary>
 -          <key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
 -          <value>true</value>
 -        </dictionary>
 -      </arguments>
 -    </buildCommand>
 -    <buildCommand>
 -      <name>org.rubypeople.rdt.core.rubybuilder</name>
 -      <arguments>
 -      </arguments>
 -    </buildCommand>
 -    <buildCommand>
 -      <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
 -      <triggers>full,incremental,</triggers>
 -      <arguments>
 -      </arguments>
 -    </buildCommand>
 -    <buildCommand>
 -      <name>org.eclipse.jdt.core.javabuilder</name>
 -      <arguments>
 -      </arguments>
 -    </buildCommand>
 -  </buildSpec>
 -  <natures>
 -    <nature>org.eclipse.cdt.core.ccnature</nature>
 -    <nature>org.eclipse.cdt.core.cnature</nature>
 -    <nature>org.rubypeople.rdt.core.rubynature</nature>
 -    <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
 -    <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
 -    <nature>org.eclipse.jdt.core.javanature</nature>
 -  </natures>
+ <?xml version="1.0" encoding="UTF-8"?>
+ <projectDescription>
++      <name>simgrid</name>
++      <comment></comment>
++      <projects>
++      </projects>
++      <buildSpec>
++              <buildCommand>
++                      <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
++                      <triggers>clean,full,incremental,</triggers>
++                      <arguments>
++                      </arguments>
++              </buildCommand>
++              <buildCommand>
++                      <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
++                      <triggers>full,incremental,</triggers>
++                      <arguments>
++                      </arguments>
++              </buildCommand>
++      </buildSpec>
++      <natures>
++              <nature>org.eclipse.cdt.core.cnature</nature>
++              <nature>org.eclipse.cdt.core.ccnature</nature>
++              <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
++              <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
++      </natures>
+ </projectDescription>
@@@ -35,12 -35,12 +35,12 @@@ set(EXTRA_DIS
    src/simix/smx_smurf_private.h
    src/simix/smx_synchro_private.h
    src/smpi/README
-   src/smpi/colls/COPYRIGHTS
    src/smpi/colls/colls.h
    src/smpi/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_cas01_private.h
    src/surf/cpu_ti_private.h
    src/surf/gtnets/gtnets_interface.h
    src/surf/gtnets/gtnets_simulator.h
@@@ -119,7 -119,6 +119,6 @@@ set(SMPI_SR
    src/smpi/colls/allgather-bruck.c
    src/smpi/colls/allgather-GB.c
    src/smpi/colls/allgather-loosely-lr.c
-   src/smpi/colls/allgather-lr.c
    src/smpi/colls/allgather-NTSLR.c
    src/smpi/colls/allgather-NTSLR-NB.c
    src/smpi/colls/allgather-pair.c
    src/smpi/colls/allgatherv-ompi-neighborexchange.c
    src/smpi/colls/allgatherv-ompi-bruck.c
    src/smpi/colls/allgatherv-mpich-rdb.c
+   src/smpi/colls/allgatherv-mpich-ring.c
    src/smpi/colls/allreduce-lr.c
-   src/smpi/colls/allreduce-NTS.c
    src/smpi/colls/allreduce-rab1.c
    src/smpi/colls/allreduce-rab2.c
    src/smpi/colls/allreduce-rab-rdb.c
-   #src/smpi/colls/allreduce-rab-reduce-scatter.c
-   src/smpi/colls/allreduce-rab-rsag.c
    src/smpi/colls/allreduce-rdb.c
    src/smpi/colls/allreduce-redbcast.c
    src/smpi/colls/allreduce-smp-binomial.c
    src/smpi/colls/allreduce-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-bruck.c
    src/smpi/colls/alltoall-pair.c
    src/smpi/colls/alltoall-pair-light-barrier.c
    src/smpi/colls/alltoall-pair-mpi-barrier.c
    src/smpi/colls/alltoall-ring-light-barrier.c
    src/smpi/colls/alltoall-ring-mpi-barrier.c
    src/smpi/colls/alltoall-ring-one-barrier.c
-   src/smpi/colls/alltoall-simple.c
    src/smpi/colls/alltoallv-pair.c   
    src/smpi/colls/alltoallv-pair-light-barrier.c
    src/smpi/colls/alltoallv-pair-mpi-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/alltoallv-ompi-basic-linear.c
    src/smpi/colls/bcast-arrival-pattern-aware.c
    src/smpi/colls/bcast-arrival-pattern-aware-wait.c
    src/smpi/colls/bcast-arrival-scatter.c
    src/smpi/colls/gather-ompi.c
    src/smpi/colls/reduce_scatter-ompi.c
    src/smpi/colls/reduce_scatter-mpich.c
+   src/smpi/colls/smpi_automatic_selector.c
    src/smpi/colls/scatter-ompi.c
    src/smpi/colls/barrier-ompi.c
    )
@@@ -311,7 -308,6 +308,7 @@@ set(SURF_SR
    src/surf/trace_mgr.c
    src/surf/workstation.c
    src/surf/workstation_ptask_L07.c
 +  src/surf/vm_workstation.c
    src/xbt/xbt_sg_stubs.c
    )
  
@@@ -329,7 -325,6 +326,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
@@@ -539,7 -534,6 +536,6 @@@ set(headers_to_instal
    include/simgrid/platf_generator.h
    include/simgrid/simix.h
    include/smpi/mpi.h
-   include/smpi/mpif.h
    include/smpi/smpi.h
    include/smpi/smpi_cocci.h
    include/smpi/smpi_main.h
    )
  set(source_of_generated_headers
    include/simgrid_config.h.in
+   include/smpi/mpif.h.in
    include/smpi/smpif.h.in
    src/context_sysv_config.h.in)
  
@@@ -709,7 -704,6 +706,6 @@@ else(
  endif()
  
  set(DOC_SOURCES
-   doc/AS_hierarchy.png
    doc/Doxyfile.in
    doc/Layout.xml
    doc/sg_thread_model.fig
    doc/msg-tuto-src/platforms/griffon.xml
    doc/msg-tuto-src/platforms/peers.xml
    doc/msg-tuto-src/platforms/platform.xml
+   
+   CITATION.bib
    )
  
  set(DOC_FIGS
@@@ -791,6 -787,7 +789,7 @@@ set(DOC_TOOL
  set(DOC_IMG
    ${CMAKE_HOME_DIRECTORY}/doc/simgrid.css
    ${CMAKE_HOME_DIRECTORY}/doc/sc3-description.png
+   ${CMAKE_HOME_DIRECTORY}/doc/webcruft/AS_hierarchy.png
    ${CMAKE_HOME_DIRECTORY}/doc/webcruft/Paje_MSG_screenshot.jpg
    ${CMAKE_HOME_DIRECTORY}/doc/webcruft/Paje_MSG_screenshot_thn.jpg
    ${CMAKE_HOME_DIRECTORY}/doc/webcruft/SGicon.gif
    ${CMAKE_HOME_DIRECTORY}/doc/webcruft/win_install_04.png
    ${CMAKE_HOME_DIRECTORY}/doc/webcruft/win_install_05.png
    ${CMAKE_HOME_DIRECTORY}/doc/webcruft/win_install_06.png
+   ${CMAKE_HOME_DIRECTORY}/doc/webcruft/smpi_simgrid_alltoall_pair_16.png
+   ${CMAKE_HOME_DIRECTORY}/doc/webcruft/smpi_simgrid_alltoall_ring_16.png
    )
  
  set(bin_files
@@@ -862,6 -861,9 +863,9 @@@ set(EXAMPLES_CMAKEFILES_TX
    examples/msg/chainsend/CMakeLists.txt
    examples/msg/chord/CMakeLists.txt
    examples/msg/cloud/CMakeLists.txt
+   examples/msg/energy/e1/CMakeLists.txt
+   examples/msg/energy/e2/CMakeLists.txt
+   examples/msg/energy/e3/CMakeLists.txt
    examples/msg/gpu/CMakeLists.txt
    examples/msg/gtnets/CMakeLists.txt
    examples/msg/icomms/CMakeLists.txt
    examples/simdag/dax/CMakeLists.txt
    examples/simdag/dot/CMakeLists.txt
    examples/simdag/goal/CMakeLists.txt
+   examples/simdag/io/CMakeLists.txt
    examples/simdag/metaxml/CMakeLists.txt
    examples/simdag/properties/CMakeLists.txt
    examples/simdag/scheduling/CMakeLists.txt
    )
  
  set(TESHSUITE_CMAKEFILES_TXT
-   teshsuite/CMakeLists.txt
    teshsuite/msg/CMakeLists.txt
+   teshsuite/msg/storage/CMakeLists.txt
    teshsuite/msg/trace/CMakeLists.txt
    teshsuite/simdag/CMakeLists.txt
    teshsuite/simdag/availability/CMakeLists.txt
    teshsuite/simdag/network/p2p/CMakeLists.txt
    teshsuite/simdag/partask/CMakeLists.txt
    teshsuite/simdag/platforms/CMakeLists.txt
+   teshsuite/simix/CMakeLists.txt
    teshsuite/smpi/CMakeLists.txt
-   teshsuite/smpi/mpich-test/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/smpi/mpich3-test/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/attr/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/comm/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/coll/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/datatype/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/group/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/init/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt
+ #  teshsuite/smpi/mpich3-test/f77/attr/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f77/coll/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f77/comm/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f77/datatype/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f77/ext/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f77/init/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f77/pt2pt/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f90/coll/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f90/datatype/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f90/init/CMakeLists.txt
+   teshsuite/smpi/mpich3-test/f90/pt2pt/CMakeLists.txt
    teshsuite/xbt/CMakeLists.txt
    )
  
@@@ -1004,6 -1021,7 +1023,7 @@@ set(PLATFORMS_EXAMPLE
    examples/platforms/conf/transform_optorsim_platform.pl
    examples/platforms/config.xml
    examples/platforms/content/storage_content.txt
+   examples/platforms/content/win_storage_content.txt
    examples/platforms/data_center.xml
    examples/platforms/g5k.xml
    examples/platforms/generation_scripts/create_hierarchical_clusters.pl
diff --combined doc/doxygen/platform.doc
@@@ -16,7 -16,7 +16,7 @@@ For the latest 2 entries, you have basi
  \li You can use two XML files: a platform description file and a
      deployment description one.
  
- For the deployment stuff, please takea look at \ref deployment
+ For the deployment stuff, please take a look at \ref deployment
  
  The platform description may be complicated. This documentation is all
  about how to write this file: what are the basic concept it relies on,
@@@ -28,10 -28,10 +28,10 @@@ write a good platform description
  We choose to use XML because of some of its possibilities: if you're
  using an accurate XML editor, or simply using any XML plug-in for
  eclipse, it will allow you to have cool stuff like auto-completion,
- validation and checking, so all syntaxic errors may be avoided this
+ validation and checking, so all syntax errors may be avoided this
  way.
  
- the XML checking is done based on the dtd which is nowaday online at
+ the XML checking is done based on the dtd which is nowadays online at
  <a href="http://simgrid.gforge.inria.fr/simgrid.dtd">http://simgrid.gforge.inria.fr/simgrid.dtd</a>
  while you might be tempted to read it, it will not help you that much.
  
@@@ -82,7 -82,7 +82,7 @@@ handles two different types of entitie
  <b>AS</b>) you will have to define routes between those elements. A
  network model have to be provided for AS, but you may/will need,
  depending of the network model, or because you want to bypass the
- default beahviour to defines routes manually. There are 3 tags to use: 
+ default behavior to defines routes manually. There are 3 tags to use: 
  \li <b>ASroute</b>: to define routes between two  <b>AS</b>
  \li <b>route</b>: to define routes between two <b>host/router</b>
  \li <b>bypassRoute</b>: to define routes between two <b>AS</b> that
@@@ -126,12 -126,12 +126,12 @@@ attributes
      That also have a big impact on how many information you'll have to
      provide to help the simulator to route between the AS elements.
      <b>routing</b> possible values are <b>Full, Floyd, Dijkstra,
-     DijkstraCache, none, RuleBased, Vivaldi, Cluster</b>. For more
+     DijkstraCache, none, Vivaldi, Cluster</b>. For more
      explanation about what to choose, take a look at the section
      devoted to it below.  
  
  Elements into an AS are basically resources (computers, network
- equipments) and some routing informations if necessary (see below for
+ equipments) and some routing information if necessary (see below for
  more explanation).
  
  <b>AS example</b>
@@@ -162,15 -162,16 +162,16 @@@ contain more than 1 core. Here are the 
      referring to it.
  \li <b>power (mandatory)</b>:the peak number FLOPS the CPU can manage.
      Expressed in flop/s.
- \li <b>core</b>: The number of core of this host. If setted, the power
-     gives the power of one core. The specified computing power will be
+ \li <b>core</b>: The number of core of this host (by default, 1). If
+     you specify the amount of cores, the 'power' parameter is the power 
+     of each core. 
+     For example, if you specify that your host has 6 cores, it will be
      available to up to 6 sequential tasks without sharing. If more
      tasks are placed on this host, the resource will be shared
-     accordingly. For example, if you schedule 12 tasks on the host,
-     each will get half of the computing power. Please note that
-     although sound, this model were never scientifically assessed.
+     accordingly. For example, if you schedule 12 tasks on that host,
+     each will get half of the specified computing power. Please note
+     that although sound, this model were never scientifically assessed.
      Please keep this fact in mind when using it.
  \li <b>availability</b>: specify if the percentage of power available.
  \li <b>availability_file</b>: Allow you to use a file as input. This
      file will contain availability traces for this computer. The
@@@ -190,7 -191,7 +191,7 @@@ between some storage resource and the <
  storage doc for more information.
  
  An host can also contain the <b>prop</b> tag. the prop tag allows you
- to define additional informations on this host following the
+ to define additional information on this host following the
  attribute/value schema. You may want to use it to give information to
  the tool you use for rendering your simulation, for example.
  
@@@ -285,7 -286,7 +286,7 @@@ A <b>cluster</b> represents a cluster. 
  when you want to have a bunch of machine defined quickly. It must be
  noted that cluster is meta-tag : <b>from the inner SimGrid point of
  view, a cluster is an AS where some optimized routing is defined</b>.
- The default inner organisation of the cluster is as follow:
+ The default inner organization of the cluster is as follow:
  
  \verbatim
                   _________
  \endverbatim
  
  You have a set of <b>host</b> defined. Each of them has a <b>link</b>
- to a central backbone (backbone is a <b>link</b> itsef, as a link can
+ to a central backbone (backbone is a <b>link</b> itself, as a link can
  be used to represent a switch, see the switch or <b>link</b> section
  below for more details about it). A <b>router</b> gives a way to the
  <b>cluster</b> to be connected to the outside world. Internally,
@@@ -323,7 -324,7 +324,7 @@@ There is an alternative organization, w
  
  The principle is the same, except we don't have the backbone. The way
  to obtain it is simple : you just have to let bb_* attributes
- unsetted.
+ unset.
  
  
  
  \li <b>sharing_policy</b>: sharing policy for the links between nodes
      and backbone (if any). See <b>link</b> section for syntax/details.     
  \li <b>bb_bw </b>: bandwidth for backbone (if any). See <b>link</b>
-     section for syntax/details. If both bb_* attributes are ommited,
+     section for syntax/details. If both bb_* attributes are omitted,
      no backbone is created (alternative cluster architecture described
      before). 
  \li <b>bb_lat </b>: latency for backbone (if any). See <b>link</b>
-     section for syntax/details. If both bb_* attributes are ommited,
+     section for syntax/details. If both bb_* attributes are omitted,
      no backbone is created (alternative cluster architecture described
      before).
  \li <b>bb_sharing_policy</b>: sharing policy for the backbone (if
@@@ -371,17 -372,14 +372,17 @@@ router_name = prefix + clusterId + rout
  
  <b>cluster example</b>
  \verbatim
 -<cluster id="my_cluster_1" prefix="" suffix=""
 -              radical="0-262144"      power="1000000000"    bw="125000000"     lat="5E-5"/>
 -<cluster id="my_cluster_1" prefix="c-" suffix=".me"
 -              radical="0-99"  power="1000000000"    bw="125000000"     lat="5E-5"
 -        bb_bw="2250000000" bb_lat="5E-4"/>
 +<cluster id="my_cluster_1" prefix="" suffix="" radical="0-262144"
 +         power="1e9" bw="125e6" lat="5E-5"/>
 +
 +<cluster id="my_cluster_1" prefix="c-" suffix=".me" radical="0-99"
 +         power="1e9" bw="125e6" lat="5E-5"
 +         bb_bw="2.25e9" bb_lat="5E-4"/>
  \endverbatim
 -The second examples creates 100 machines, which names are the following:
 +The second examples creates one router and 100 machines, which names 
 +are the following:
  \verbatim
 +c-my_cluster_1_router.me
  c-0.my_cluster_1.me
  c-1.my_cluster_1.me
  c-2.my_cluster_1.me
@@@ -394,11 -392,13 +395,13 @@@ A <b>peer</b> represents a peer, as in 
  as cluster, <b>A PEER IS INTERNALLY INTERPRETED AS AN \<AS\></b>. It's
  just a kind of shortcut that does the following :
  
+ \li It creates a tiny AS whose routing type is cluster
  \li It creates an host
  \li Two links : one for download and one for upload. This is
      convenient to use and simulate stuff under the last mile model (as
-     ADSL peers).  
- \li It creates a gateway that serve as entry point for this peer zone.
+     ADSL peers). 
+ \li It connects the two links to the host
+ \li It creates a router (a gateway) that serve as entry point for this peer zone.
      This router has coordinates.
  
  <b>peer</b> attributes :
  \li <b>state_file </b>: state file for the peer. Same as host state
      file. See <b>host</b> description for details. 
  
+ In term of XML, the <b>peer</b> construct can be explained as follows: it transforms
+ \verbatim
+   <peer id="FOO"
+       coordinates="12.8 14.4 6.4"
+       power="1.5Gf"
+       bw_in="2.25GBps"
+       bw_out="2.25GBps"
+       lat="500us" />
+ \endverbatim
+ into
+ \verbatim
+    <AS id="as_FOO" routing="Cluster">
+       <host id="peer_FOO" power="1.5Gf"/>
+       <link id="link_FOO_UP" bandwidth="2.25GBps" latency="500us"/>
+       <link id="link_FOO_DOWN" bandwidth="2.25GBps" latency="500us"/>
+       <router id="router_FOO" coordinates="25.5 9.4 1.4"/>
+       <host_link id="peer_FOO" up="link_FOO_UP" down="link_FOO_DOWN"/>
+    </AS>
+ \endverbatim
  \subsection pf_ne Network equipments: links and routers
  
  You have basically two entities available to represent network entities:
@@@ -623,12 -644,12 +647,12 @@@ resources tags. This should moved to at
  In order to run fast, it has been chosen to use static routing within
  SimGrid. By static, it means that it is calculated once (or almost),
  and will not change during execution. We chose to do that because it
- is rare to have a real deficience of a resource ; most of the time, a
+ is rare to have a real deficiency of a resource ; most of the time, a
  communication fails because the links are too overloaded, and so your
  connection stops before the time out, or because the computer at the
  other end is not answering.
  
- We also chose to use shortests paths algorithms in order to emulate
+ We also chose to use shortest paths algorithms in order to emulate
  routing. Doing so is consistent with the reality: RIP, OSPF, BGP are
  all calculating shortest paths. They have some convergence time, but
  at the end, so when the platform is stable (and this should be the
@@@ -750,12 -771,6 +774,6 @@@ DijsktraCache example 
  \subsubsection pf_rm_me Manually-entered route models
  
  \li <b>Full</b>: You have to enter all necessary routes manually
- \li <b>RuleBased</b>: Rule-Based routing data; same as Full except you
-     can use regexp to express route. As SimGrid has to evaluate the
-     regexp, it's slower than Full, but requires less memory. Regexp
-     syntax is similar as <a href="http://www.pcre.org">pcre</a> ones,
-     as this is the lib SimGrid use to do so.
  
  Full example :
  \verbatim
   </AS>
  \endverbatim
  
- RuleBased example :
- \verbatim
- <AS id="AS_orsay" routing="RuleBased" >
-                       <cluster id="AS_gdx" prefix="gdx-" suffix=".orsay.grid5000.fr"
-                               radical="1-310" power="4.7153E9" bw="1.25E8" lat="1.0E-4"
-                               bb_bw="1.25E9" bb_lat="1.0E-4"></cluster>
-                       <link   id="link_gdx" bandwidth="1.25E9" latency="1.0E-4"/>
-                       <cluster id="AS_netgdx" prefix="netgdx-" suffix=".orsay.grid5000.fr"
-                               radical="1-30" power="4.7144E9" bw="1.25E8" lat="1.0E-4"
-                               bb_bw="1.25E9" bb_lat="1.0E-4"></cluster>
-                       <link   id="link_netgdx" bandwidth="1.25E9" latency="1.0E-4"/>
-                       <AS id="gw_AS_orsay" routing="Full">
-                               <router id="gw_orsay"/>
-                       </AS>
-                       <link   id="link_gw_orsay" bandwidth="1.25E9" latency="1.0E-4"/>
-                       <ASroute src="^AS_(.*)$" dst="^AS_(.*)$"
-                               gw_src="$1src-AS_$1src_router.orsay.grid5000.fr"
-                               gw_dst="$1dst-AS_$1dst_router.orsay.grid5000.fr"
-                               symmetrical="YES">
-                                       <link_ctn id="link_$1src"/>
-                                       <link_ctn id="link_$1dst"/>
-                       </ASroute>
-                       <ASroute src="^AS_(.*)$" dst="^gw_AS_(.*)$"
-                               gw_src="$1src-AS_$1src_router.orsay.grid5000.fr"
-                               gw_dst="gw_$1dst"
-                               symmetrical="NO">
-                                       <link_ctn id="link_$1src"/>
-                       </ASroute>
-                       <ASroute src="^gw_AS_(.*)$" dst="^AS_(.*)$"
-                               gw_src="gw_$1src"
-                               gw_dst="$1dst-AS_$1dst_router.orsay.grid5000.fr"
-                               symmetrical="NO">
-                                       <link_ctn id="link_$1dst"/>
-                       </ASroute>
-               </AS>
- \endverbatim
- The example upper contains $1src and $1dst. It's simply a reference to
- string matching regexp enclosed by "()" within respectively <b>src</b>
- and <b>dst</b> attributes. If they were more than 1 "()", then you
- could referer to it as $2src, $3src and so on.
  \subsubsection pf_rm_sf Simple/fast models
  
  \li <b>none</b>: No routing (Unless you know what you are doing, avoid
@@@ -854,15 -821,15 +824,15 @@@ Consider the example below
     </route>
  \endverbatim
  
- The route here fom host Alice to Bob will be first link1, then link2,
+ The route here from host Alice to Bob will be first link1, then link2,
  and finally link3. What about the reverse route ? <b>route</b> and
  <b>ASroute</b> have an optional attribute <b>symmetrical</b>, that can
  be either YES or NO. YES means that the reverse route is the same
- route in the inverse order, and is setted to YES by default. Note that
+ route in the inverse order, and is set to YES by default. Note that
  this is not the case for bypass*Route, as it is more probable that you
  want to bypass only one default route.
  
- For an ASroute, things are just sligthly more complicated, as you have
+ For an ASroute, things are just slightly more complicated, as you have
  to give the id of the gateway which is inside the AS you're talking
  about you want to access ... So it looks like this :
  
@@@ -894,7 -861,7 +864,7 @@@ a <b>link_ctn</b> is the tag that is us
  \subsubsection pf_asro ASroute
  
  ASroute tag purpose is to let people write manually their routes
- between AS. It's usefull when you're in Full or Rule-based model.
+ between AS. It's useful when you're in Full model.
  
  <b>ASroute</b> attributes :
  \li <b>src (mandatory)</b>: the source AS id.
      will be the opposite of the one defined. Can be either YES or NO,
      default is YES.
  
- <b>Example of ASroute with RuleBased</b>
- \verbatim
- <ASroute src="^gw_AS_(.*)$" dst="^AS_(.*)$"
-                               gw_src="gw_$1src"
-                               gw_dst="$1dst-AS_$1dst_router.orsay.grid5000.fr"
-                               symmetrical="NO">
-                                       <link_ctn id="link_$1dst"/>
-                       </ASroute>
- \endverbatim
  <b>Example of ASroute with Full</b>
  \verbatim
  <AS  id="AS0"  routing="Full">
  The principle is the same as ASroute : <b>route</b> contains list of
  links that are in the path between src and dst, except that it is for
  routes between a src that can be either <b>host</b> or \b router and a
- dst that can be either <b>host</b> or \b router. Usefull for Full and
RuleBased, as well as for the shortest-paths based models, where you
- have to give topological informations.
+ dst that can be either <b>host</b> or \b router. Useful for Full 
+ as well as for the shortest-paths based models, where you
+ have to give topological information.
  
  
  <b>route</b> attributes :
@@@ -1183,7 -1141,7 +1144,7 @@@ and close tag in order to let it work
  
  \subsection pf_tra trace and trace_connect
  Both tags are an alternate way to passe availability, state, and so on
- files to entity. Instead of refering to the file directly in the host,
+ files to entity. Instead of referring to the file directly in the host,
  link, or cluster tag, you proceed by defining a trace with an id
  corresponding to a file, later an host/link/cluster, and finally using
  trace_connect you say that the file trace must be used by the entity.
@@@ -1206,7 -1164,7 +1167,7 @@@ All constraints you have is that <b>tra
      referring to it.
  \li <b>file</b>: filename of the file to include. Possible values :
      absolute or relative path, syntax similar to the one in use on
-     your system. If ommited, the system expects that you provide the
+     your system. If omitted, the system expects that you provide the
      trace values inside the trace tags (see below).
  \li <b>trace periodicity (mandatory)</b>: trace periodicity, same
      definition as in hosts (see upper for details).
@@@ -1232,8 -1190,8 +1193,8 @@@ Here is an example  of trace when no fi
  
  \section pf_hints Hints and tips, or how to write a platform efficiently
  
- Now you should know at least the syntax dans be able to create a
- platform. However, after having ourselves wrote some platforms, there
+ Now you should know at least the syntax and be able to create a
+ platform by your own. However, after having ourselves wrote some platforms, there
  are some best practices you should pay attention to in order to
  produce good platform and some choices you can make in order to have
  faster simulations. Here's some hints and tips, then.
@@@ -1248,7 -1206,7 +1209,7 @@@ only one host, then you'll also loose a
  give you. Remind you should always be "reasonable" in your platform
  definition when choosing the hierarchy. A good choice if you try to
  describe a real life platform is to follow the AS described in
- reality, since this kind og trade-off works well for real life
+ reality, since this kind of trade-off works well for real life
  platforms.
  
  \subsection pf_exit_as Exit AS: why and how
@@@ -1328,14 -1286,37 +1289,37 @@@ complicated in using it, here is an exa
  \endverbatim
  
  Coordinates are then used to calculate latency between two hosts by
- calculating the euclidian distance between the two hosts coordinates.
+ calculating the euclidean distance between the two hosts coordinates.
  The results express the latency in ms.
  
+ Note that the previous example defines a routing directly between hosts but it could be also used to define a routing between AS.
+ That is for example what is commonly done when using peers (see Section \ref pf_peer).
+ \verbatim
+ <?xml version='1.0'?>
+ <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+ <platform version="3">
+ <config id="General">
+       <prop id="network/coordinates" value="yes"></prop>
+ </config>
+  <AS  id="AS0"  routing="Vivaldi">
+    <peer id="peer-0" coordinates="173.0 96.8 0.1" power="730Mf" bw_in="13.38MBps" bw_out="1.024MBps" lat="500us"/>
+    <peer id="peer-1" coordinates="247.0 57.3 0.6" power="730Mf" bw_in="13.38MBps" bw_out="1.024MBps" lat="500us" />
+    <peer id="peer-2" coordinates="243.4 58.8 1.4" power="730Mf" bw_in="13.38MBps" bw_out="1.024MBps" lat="500us" />
+ </AS>
+ </platform>
+ \endverbatim
+ In such a case though, we connect the AS created by the <b>peer</b> tag with the Vivaldi routing mechanism. 
+ This means that to route between AS1 and AS2, it will use the coordinates of router_AS1 and router_AS2. 
+ This is currently a convention and we may offer to change this convention in the DTD later if needed.
+ You may have noted that conveniently, a peer named FOO defines an AS named FOO and a router named router_FOO, which is why it works seamlessly with the <b>peer</b> tag.
  \subsection pf_wisely Choosing wisely the routing model to use
  
  
  Choosing wisely the routing model to use can significantly fasten your
- simulation/save your time when writing the platform/save tremendeous
+ simulation/save your time when writing the platform/save tremendous
  disk space. Here is the list of available model and their
  characteristics (lookup : time to resolve a route):
  
      routes.
  \li <b>none</b>: No routing (usable with Constant network only).
      Defines that there is no routes, so if you try to determine a
-     route without constant network within this AS, SimGrid will raie
+     route without constant network within this AS, SimGrid will raise
      an exception.
- \li <b>RuleBased</b>: Rule-Based routing data (fast initialisation,
-     relatively slow lookup, moderate memory requirements, fully
-     expressive): uses regexp to define routes;
  \li <b>Vivaldi</b>: Vivaldi routing, so when you want to use coordinates
  \li <b>Cluster</b>: Cluster routing, specific to cluster tag, should
      not be used. 
  
  \subsection pf_switch Hey, I want to describe a switch but there is no switch tag !
  
- Actually we did not include swith tag, ok. But when you're trying to
+ Actually we did not include switch tag, ok. But when you're trying to
  simulate a switch, the only major impact it has when you're using
  fluid model (and SimGrid uses fluid model unless you activate GTNetS,
  ns-3, or constant network mode) is the impact of the upper limit of
@@@ -1,5 -1,6 +1,6 @@@
  /*
-  * Copyright 2012. The SimGrid Team. All rights reserved. 
+  * Copyright (c) 2012-2013. The SimGrid Team.
+  * All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. 
@@@ -16,7 -17,7 +17,7 @@@ import org.simgrid.msg.MsgException
  public class Cloud {
        public static final double task_comp_size = 10;
        public static final double task_comm_size = 10;
 -
 +      public static final int hostNB = 500 ; 
        public static void main(String[] args) throws MsgException {       
            Msg.init(args); 
            
            }
            /* Construct the platform */
                Msg.createEnvironment(args[0]);
 -                /* Retrieve the 10 first hosts of the platform file */
                Host[] hosts = Host.all();
 -              if (hosts.length < 10) {
 -                      Msg.info("I need at least 10 hosts in the platform file, but " + args[0] + " contains only " + hosts.length + " hosts");
 +              if (hosts.length < hostNB+1) {
 +                      Msg.info("I need at least "+ (hostNB+1) +"  hosts in the platform file, but " + args[0] + " contains only " + hosts.length + " hosts");
                        System.exit(42);
                }
 +              Msg.info("Start"+ hostNB +"  hosts");
                new Master(hosts[0],"Master",hosts).start();
                /* Execute the simulation */
                Msg.run();
                
      }
 -}
 +}
@@@ -1,5 -1,6 +1,6 @@@
  /*
-  * Copyright 2012. The SimGrid Team. All rights reserved. 
+  * Copyright (c) 2012-2013. The SimGrid Team.
+  * All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. 
@@@ -23,36 -24,31 +24,36 @@@ public class Master extends Process 
                this.hosts = hosts;
        }
        public void main(String[] args) throws MsgException {
 -              int slavesCount = 10;
 +              int slavesCount = Cloud.hostNB;
                
                ArrayList<VM> vms = new ArrayList<VM>();
                
 +              // Create one VM per host and bind a process inside each one. 
                for (int i = 0; i < slavesCount; i++) {
 -                      Slave slave = new Slave(hosts[i],i);
 -                      slave.start();
 -                      VM vm = new VM(hosts[i],hosts[i]+"_"+i,1);
 -                      vm.bind(slave);
 +                      Msg.info("create VM0"+i);       
 +                      VM vm = new VM(hosts[i+1],"VM0"+i);
 +                      vm.start();
                        vms.add(vm);
 +                      Slave slave = new Slave(vm,i);
 +                      Msg.info("Put Worker "+slave.msgName()+ " on "+vm.getName());
 +                      slave.start();
 +      
                }
                Msg.info("Launched " + vms.size() + " VMs");
                
                Msg.info("Send a first batch of work to everyone");
                workBatch(slavesCount);
                
 -              Msg.info("Now suspend all VMs, just for fun");
 +              Msg.info("Suspend all VMs");
                for (int i = 0; i < vms.size(); i++) {
 +                      Msg.info("Suspend "+vms.get(i).getName());
                        vms.get(i).suspend();
                }
                
                Msg.info("Wait a while");
                waitFor(2);
                
 -              Msg.info("Enough. Let's resume everybody.");
 +              Msg.info("Resume all VMs.");
                for (int i = 0; i < vms.size(); i++) {
                        vms.get(i).resume();
                }
                Msg.info("Add one more process per VM.");
                for (int i = 0; i < vms.size(); i++) {
                        VM vm = vms.get(i);
 -                      Slave slave = new Slave(hosts[i],i + vms.size());
 +                      Slave slave = new Slave(vm,i + vms.size());
                        slave.start();
 -                      vm.bind(slave);
                }
 +      
 +              workBatch(slavesCount * 2);
                
 -              Msg.info("Migrate everyone to the second host.");
 +              Msg.info("Migrate everyone to "+hosts[2].getName());
                for (int i = 0; i < vms.size(); i++) {
 -                      vms.get(i).migrate(hosts[1]);
 +                      vms.get(i).migrate(hosts[2]);
                }
                
 -              Msg.info("Suspend everyone, move them to the third host, and resume them.");
 +//            Msg.info("Suspend everyone, move them to the third host, and resume them.");
 +              Msg.info("Migrate everyone to the third host (please note that cold migration is not yet available");
 +              
 +
                for (int i = 0; i < vms.size(); i++) {
                        VM vm = vms.get(i);
 -                      vm.suspend();
 -                      vm.migrate(hosts[2]);
 -                      vm.resume();
 +      //              vm.suspend();
 +                      vm.migrate(hosts[3]);
 +              //      vm.resume();
                }
                
 -              workBatch(slavesCount * 2);
 +      
                
                Msg.info("Let's shut down the simulation and kill everyone.");
                
                for (int i = 0; i < vms.size(); i++) {
                        vms.get(i).shutdown();
 +                      vms.get(i).destroy();
                }                               
                Msg.info("Master done.");
        }
        
        public void workBatch(int slavesCount) throws MsgException {
                for (int i = 0; i < slavesCount; i++) {
 -                      Task task = new Task("Task_" + i, Cloud.task_comp_size, Cloud.task_comm_size);
 -                      Msg.info("Sending to " + i);
 -                      task.send("slave_" + i);
 +                      Task task = new Task("Task0" + i, Cloud.task_comp_size, Cloud.task_comm_size);
 +                      Msg.info("Sending to WRK0" + i);
 +                      task.send("MBOX:WRK0" + i);
                }
        }
  }
@@@ -1,5 -1,6 +1,6 @@@
  /*
-  * Copyright 2012. The SimGrid Team. All rights reserved. 
+  * Copyright (c) 2012-2013. The SimGrid Team.
+  * All rights reserved.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. 
@@@ -15,15 -16,15 +16,15 @@@ import org.simgrid.msg.Task
  public class Slave extends Process {
        private int number;
        public Slave(Host host, int number) {
 -              super(host,"Slave " + number,null);
 +              super(host,"WRK0" + number,null);
                this.number = number;
        }
        public void main(String[] args) throws MsgException {
 +              Msg.info(this.msgName() +" is listenning on MBOX:WRK0"+ number);
                while(true) {                   
 -                      Msg.info("Receiving on " + "slave_" + number);
                        Task task;
                          try {
 -                                task = Task.receive("slave_"+number);
 +                                task = Task.receive("MBOX:WRK0"+number);
                          } catch (MsgException e) {
                                  Msg.debug("Received failed. I'm done. See you!");
                                  break;
@@@ -38,9 -39,9 +39,9 @@@
                        } catch (MsgException e) {
  
                        }
 -                      Msg.info("\"" + task.getName() + "\" done ");
 +                      Msg.info(this.msgName() +" executed task (" + task.getName()+")");
                }
  
                
        }
 -}
 +}
@@@ -1,10 -1,11 +1,11 @@@
- /* Copyright (c) 2007-2012. The SimGrid Team. All rights reserved.                             */
+ /* Copyright (c) 2007-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
  
  #include <stdio.h>
 -#include "msg/msg.h"            /* Yeah! If you want to use msg, you need to include msg/msg.h */
 +#include "msg/msg.h"
  #include "xbt/sysdep.h"         /* calloc, printf */
  
  /* Create a log channel to have nice outputs. */
@@@ -15,246 -16,217 +16,246 @@@ XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test
  
  /** @addtogroup MSG_examples
   * 
 - *  - <b>cloud/masterslave_virtual_machines.c: Master/slaves
 - *    example, à la cloud</b>. The classical example revisited to demonstrate the use of virtual machines.
 + *  - <b>cloud/masterslave_virtual_machines.c: Master/workers
 + *    example on a cloud</b>. The classical example revisited to demonstrate the use of virtual machines.
   */
  
 -double task_comp_size = 10000000;
 -double task_comm_size = 10000000;
 +const double task_comp_size = 10000000;
 +const double task_comm_size = 10000000;
  
  
 -int master(int argc, char *argv[]);
 -int slave_fun(int argc, char *argv[]);
 +int master_fun(int argc, char *argv[]);
 +int worker_fun(int argc, char *argv[]);
  
 -static void work_batch(int slaves_count) {
 +
 +static void work_batch(int workers_count)
 +{
    int i;
 -  for (i = 0; i < slaves_count; i++) {
 -    char taskname_buffer[64];
 -    char mailbox_buffer[64];
 +  for (i = 0; i < workers_count; i++) {
 +    char *tname = bprintf("Task%02d", i);
 +    char *mbox =  bprintf("MBOX:WRK%02d", i);
 +
 +    msg_task_t task = MSG_task_create(tname, task_comp_size, task_comm_size, NULL);
  
 -    sprintf(taskname_buffer, "Task_%d", i);
 -    sprintf(mailbox_buffer,"Slave_%d",i);
 +    XBT_INFO("send task(%s) to mailbox(%s)", tname, mbox);
 +    MSG_task_send(task, mbox);
  
 -    XBT_INFO("Sending \"%s\" to \"%s\"",taskname_buffer,mailbox_buffer);
 -    MSG_task_send(MSG_task_create(taskname_buffer, task_comp_size, task_comm_size,NULL),
 -        mailbox_buffer);
 +    free(tname);
 +    free(mbox);
    }
  }
  
 -int master(int argc, char *argv[]) {
 -  int slaves_count = 10;
 -  msg_host_t *slaves = xbt_new(msg_host_t,10);
 -
 +int master_fun(int argc, char *argv[])
 +{
    msg_vm_t vm;
    unsigned int i;
 +  int workers_count = argc - 1;
  
 -  /* Retrive the hostnames constituting our playground today */
 -  for (i = 1; i < argc; i++) {
 -    slaves[i - 1] = MSG_get_host_by_name(argv[i]);
 -    xbt_assert(slaves[i - 1] != NULL, "Cannot use inexistent host %s", argv[i]);
 -  }
 +  msg_host_t *pms = xbt_new(msg_host_t, workers_count);
 +  xbt_dynar_t vms = xbt_dynar_new(sizeof(msg_vm_t), NULL);
  
 -  /* Launch the sub processes: one VM per host, with one process inside each */
 +  /* Retrieve the PMs that will launch worker processes. */
 +  for (i = 1; i < argc; i++)
 +    pms[i - 1] = MSG_get_host_by_name(argv[i]);
  
 -  for (i=0;i<slaves_count;i++) {
 -    char slavename[64];
 -    sprintf(slavename,"Slave %d",i);
 -    char**argv=xbt_new(char*,3);
 -    argv[0] = xbt_strdup(slavename);
 -    argv[1] = bprintf("%d",i);
 -    argv[2] = NULL;
  
 -    char vmName[64];
 -    snprintf(vmName, 64, "vm_%d", i);
 +  /* Launch VMs and worker processes. One VM per PM, and one worker process per VM. */
  
 -    msg_vm_t vm = MSG_vm_start(slaves[i],vmName,2);
 -    MSG_vm_bind(vm, MSG_process_create_with_arguments(slavename,slave_fun,NULL,slaves[i],2,argv));
 -  }
 +  XBT_INFO("Launch %d VMs", workers_count);
 +  for (i=0; i< workers_count; i++) {
 +    char *vm_name = bprintf("VM%02d", i);
 +    char *pr_name = bprintf("WRK%02d", i);
 +    char *mbox = bprintf("MBOX:WRK%02d", i);
  
 +    char **wrk_argv = xbt_new(char*, 3);
 +    wrk_argv[0] = pr_name;
 +    wrk_argv[1] = mbox;
 +    wrk_argv[2] = NULL;
  
 -  xbt_dynar_t vms = MSG_vms_as_dynar();
 -  XBT_INFO("Launched %ld VMs", xbt_dynar_length(vms));
 +    XBT_INFO("create %s", vm_name);
 +    msg_vm_t vm = MSG_vm_create_core(pms[i], vm_name);
 +
 +    s_ws_params_t params;
 +    memset(&params, 0, sizeof(params));
 +    params.ramsize = 1L * 1024 * 1024 * 1024; // 1Gbytes
 +    MSG_host_set_params(vm, &params);
 +
 +    MSG_vm_start(vm);
 +    xbt_dynar_push(vms, &vm);
 +
 +    XBT_INFO("put %s on %s", pr_name, vm_name);
 +    MSG_process_create_with_arguments(pr_name, worker_fun, NULL, vm, 2, wrk_argv);
 +  }
  
 -  /* Send a bunch of work to every one */
 -  XBT_INFO("Send a first batch of work to every one");
 -  work_batch(slaves_count);
  
 -  XBT_INFO("Now suspend all VMs, just for fun");
 +  /* Send a bunch of work to every one */
 +  XBT_INFO("Send a task to %d worker process", workers_count);
 +  work_batch(workers_count);
  
 -  xbt_dynar_foreach(vms,i,vm) {
 +  XBT_INFO("Suspend all VMs");
 +  xbt_dynar_foreach(vms, i, vm) {
 +    const char *vm_name = MSG_host_get_name(vm);
 +    XBT_INFO("suspend %s", vm_name);
      MSG_vm_suspend(vm);
    }
  
    XBT_INFO("Wait a while");
    MSG_process_sleep(2);
  
 -  XBT_INFO("Enough. Let's resume everybody.");
 -  xbt_dynar_foreach(vms,i,vm) {
 +  XBT_INFO("Resume all VMs");
 +  xbt_dynar_foreach(vms, i, vm) {
      MSG_vm_resume(vm);
    }
 +
 +
    XBT_INFO("Sleep long enough for everyone to be done with previous batch of work");
 -  MSG_process_sleep(1000-MSG_get_clock());
 +  MSG_process_sleep(1000 - MSG_get_clock());
  
    XBT_INFO("Add one more process per VM");
 -  xbt_dynar_foreach(vms,i,vm) {
 -    msg_vm_t vm = xbt_dynar_get_as(vms,i,msg_vm_t);
 -    char slavename[64];
 -    sprintf(slavename,"Slave %ld",i+xbt_dynar_length(vms));
 -    char**argv=xbt_new(char*,3);
 -    argv[0] = xbt_strdup(slavename);
 -    argv[1] = bprintf("%ld",i+xbt_dynar_length(vms));
 -    argv[2] = NULL;
 -    MSG_vm_bind(vm, MSG_process_create_with_arguments(slavename,slave_fun,NULL,slaves[i],2,argv));
 +  xbt_dynar_foreach(vms, i, vm) {
 +    unsigned int index = i + xbt_dynar_length(vms);
 +    char *vm_name = bprintf("VM%02d", i);
 +    char *pr_name = bprintf("WRK%02d", index);
 +    char *mbox = bprintf("MBOX:WRK%02d", index);
 +
 +    char **wrk_argv = xbt_new(char*, 3);
 +    wrk_argv[0] = pr_name;
 +    wrk_argv[1] = mbox;
 +    wrk_argv[2] = NULL;
 +
 +    XBT_INFO("put %s on %s", pr_name, vm_name);
 +    MSG_process_create_with_arguments(pr_name, worker_fun, NULL, vm, 2, wrk_argv);
    }
  
 -  XBT_INFO("Reboot all the VMs");
 -  xbt_dynar_foreach(vms,i,vm) {
 -    MSG_vm_reboot(vm);
 -  }
 -
 -  work_batch(slaves_count*2);
 +  XBT_INFO("Send a task to %d worker process", workers_count * 2);
 +  work_batch(workers_count * 2);
  
 -  XBT_INFO("Migrate everyone to the second host.");
 -  xbt_dynar_foreach(vms,i,vm) {
 -    MSG_vm_migrate(vm,slaves[1]);
 +  XBT_INFO("Migrate all VMs to PM(%s)", MSG_host_get_name(pms[1]));
 +  xbt_dynar_foreach(vms, i, vm) {
 +    MSG_vm_migrate(vm, pms[1]);
    }
 -  XBT_INFO("Suspend everyone, move them to the third host, and resume them.");
 -  xbt_dynar_foreach(vms,i,vm) {
 -    MSG_vm_suspend(vm);
 -    MSG_vm_migrate(vm,slaves[2]);
 -    MSG_vm_resume(vm);
 +
 +  /* Migration with default policy is called (i.e. live migration with pre-copy strategy) */
 +  /* If you want to use other policy such as post-copy or cold migration, you should add a third parameter that defines the policy */
 +  XBT_INFO("Migrate all VMs to PM(%s)", MSG_host_get_name(pms[2]));
 +  xbt_dynar_foreach(vms, i, vm) {
 +    // MSG_vm_suspend(vm);
 +    MSG_vm_migrate(vm, pms[2]);
 +    // MSG_vm_resume(vm);
    }
  
  
 -  XBT_INFO("Let's shut down the simulation. 10 first processes will be shut down cleanly while the second half will forcefully get killed");
 -  for (i = 0; i < slaves_count; i++) {
 -    char mailbox_buffer[64];
 -    sprintf(mailbox_buffer,"Slave_%d",i);
 +  XBT_INFO("Shutdown the half of worker processes gracefuly. The remaining half will be forcibly killed");
 +  for (i = 0; i < workers_count; i++) {
 +    char mbox[64];
 +    sprintf(mbox, "MBOX:WRK%02d", i);
      msg_task_t finalize = MSG_task_create("finalize", 0, 0, 0);
 -    MSG_task_send(finalize, mailbox_buffer);
 +    MSG_task_send(finalize, mbox);
    }
  
    XBT_INFO("Wait a while before effective shutdown.");
    MSG_process_sleep(2);
  
 -  xbt_dynar_foreach(vms,i,vm) {
 +
 +  XBT_INFO("Shutdown and destroy all the VMs. The remaining worker processes will be forcibly killed.");
 +  xbt_dynar_foreach(vms, i, vm) {
 +    XBT_INFO("shutdown %s", MSG_host_get_name(vm));
      MSG_vm_shutdown(vm);
 +    XBT_INFO("destroy %s", MSG_host_get_name(vm));
      MSG_vm_destroy(vm);
    }
  
    XBT_INFO("Goodbye now!");
 -  free(slaves);
 +  free(pms);
    xbt_dynar_free(&vms);
 +
    return 0;
 -}                               /* end_of_master */
 +}
  
  /** Receiver function  */
 -int slave_fun(int argc, char *argv[])
 +int worker_fun(int argc, char *argv[])
  {
 -  char mailbox_name[128];
 -  msg_task_t task = NULL;
 -  _XBT_GNUC_UNUSED int res;
 -  /* since the slaves will move around, use slave_%d as mailbox names instead of hostnames */
 -  xbt_assert(argc>=2, "slave processes need to be given their rank as parameter");
 -  sprintf(mailbox_name,"Slave_%s",argv[1]);
 -  XBT_INFO("Slave listenning on %s",argv[1]);
 -  while (1) {
 -    res = MSG_task_receive(&(task),mailbox_name);
 -    xbt_assert(res == MSG_OK, "MSG_task_get failed");
 -
 -    XBT_INFO("Received \"%s\" from mailbox %s", MSG_task_get_name(task),mailbox_name);
 +  xbt_assert(argc == 2, "need mbox in arguments");
 +
 +  char *mbox = argv[1];
 +  const char *pr_name = MSG_process_get_name(MSG_process_self());
 +  XBT_INFO("%s is listenning on mailbox(%s)", pr_name, mbox);
 +
 +  for (;;) {
 +    msg_task_t task = NULL;
 +
 +    msg_error_t res = MSG_task_receive(&task, mbox);
 +    if (res != MSG_OK) {
 +      XBT_CRITICAL("MSG_task_get failed");
 +      DIE_IMPOSSIBLE;
 +    }
 +
 +    XBT_INFO("%s received task(%s) from mailbox(%s)",
 +        pr_name, MSG_task_get_name(task), mbox);
 +
      if (!strcmp(MSG_task_get_name(task), "finalize")) {
        MSG_task_destroy(task);
        break;
      }
  
      MSG_task_execute(task);
 -    XBT_INFO("\"%s\" done", MSG_task_get_name(task));
 +    XBT_INFO("%s executed task(%s)", pr_name, MSG_task_get_name(task));
      MSG_task_destroy(task);
 -    task = NULL;
    }
  
    return 0;
 -}                               /* end_of_slave */
 +}
 +
  
  /** Main function */
  int main(int argc, char *argv[])
  {
 -  msg_error_t res = MSG_OK;
 -  xbt_dynar_t hosts_dynar;
 -  msg_host_t*hosts= xbt_new(msg_host_t,10);
 -  char**hostnames= xbt_new(char*,10);
 -  char**masterargv=xbt_new(char*,12);
 -  int i;
 +  const int nb_hosts = 3;
  
 -  /* Get the arguments */
    MSG_init(&argc, argv);
 -  if (argc < 2) {
 -    printf("Usage: %s platform_file\n", argv[0]);
 -    printf("example: %s msg_platform.xml\n", argv[0]);
 -    exit(1);
 -  } if (argc>2) {
 -    printf("Usage: %s platform_file\n", argv[0]);
 -    printf("Other parameters (such as the deployment file) are ignored.");
 +  if (argc != 2) {
 +    printf("Usage: %s example/msg/msg_platform.xml\n", argv[0]);
 +    return 1;
    }
  
 -  /* load the platform file */
 +  /* Load the platform file */
    MSG_create_environment(argv[1]);
 -  /* Retrieve the 10 first hosts of the platform file */
 -  hosts_dynar = MSG_hosts_as_dynar();
 -  xbt_assert(xbt_dynar_length(hosts_dynar)>10,
 -      "I need at least 10 hosts in the platform file, but %s contains only %ld hosts_dynar.",
 -      argv[1],xbt_dynar_length(hosts_dynar));
 -  for (i=0;i<10;i++) {
 -    hosts[i] = xbt_dynar_get_as(hosts_dynar,i,msg_host_t);
 -    hostnames[i] = xbt_strdup(MSG_host_get_name(hosts[i]));
 +
 +  /* Retrieve hosts from the platform file */
 +  xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
 +
 +  if (xbt_dynar_length(hosts_dynar) <= nb_hosts) {
 +    XBT_CRITICAL("need %d hosts", nb_hosts);
 +    return 1;
    }
 -  masterargv[0]=xbt_strdup("master");
 -  for (i=1;i<11;i++) {
 -    masterargv[i] = xbt_strdup(MSG_host_get_name(hosts[i-1]));
 +
 +  msg_host_t master_pm = NULL;
 +  char **master_argv = xbt_new(char *, 12);
 +  master_argv[0] = xbt_strdup("master");
 +  master_argv[11] = NULL;
 +
 +  unsigned int i;
 +  msg_host_t host;
 +  xbt_dynar_foreach(hosts_dynar, i, host) {
 +    if (i == 0) {
 +      master_pm = host;
 +      continue;
 +    }
 +
 +    master_argv[i] = xbt_strdup(MSG_host_get_name(host));
 +
 +    if (i == nb_hosts)
 +      break;
 +  }
 +
 +  msg_error_t res = 1;
 +  if (master_pm!=NULL){
 +    MSG_process_create_with_arguments("master", master_fun, NULL, master_pm, nb_hosts + 1, master_argv);
 +
 +    res = MSG_main();
 +    XBT_INFO("Bye (simulation time %g)", MSG_get_clock());
    }
 -  masterargv[11]=NULL;
 -  MSG_process_create_with_arguments("master",master,NULL,hosts[0],11,masterargv);
 -  res = MSG_main();
 -  XBT_INFO("Simulation time %g", MSG_get_clock());
 -
 -  free(hosts);
 -  for (i=0;i<10;i++) 
 -     free(hostnames[i]);
 -  free(hostnames);
    xbt_dynar_free(&hosts_dynar);
  
 -  if (res == MSG_OK)
 -    return 0;
 -  else
 -    return 1;
 -}                               /* end_of_main */
 +  return !(res == MSG_OK);
 +}
index 6fec15d,0000000..47adfc4
mode 100644,000000..100644
--- /dev/null
@@@ -1,433 -1,0 +1,433 @@@
-   XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm0), MSG_get_host_core(pm0), MSG_get_host_speed(pm0));
-   XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm1), MSG_get_host_core(pm1), MSG_get_host_speed(pm1));
-   XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm2), MSG_get_host_core(pm2), MSG_get_host_speed(pm2));
 +/* Copyright (c) 2007-2013. The SimGrid Team. All rights reserved. */
 +
 +/* This program is free software; you can redistribute it and/or modify it
 + * under the terms of the license (GNU LGPL) which comes with this package. */
 +
 +#include <stdio.h>
 +#include "msg/msg.h"
 +#include "xbt/sysdep.h"         /* calloc, printf */
 +
 +/* Create a log channel to have nice outputs. */
 +#include "xbt/log.h"
 +#include "xbt/asserts.h"
 +XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
 +
 +
 +struct worker_data {
 +      double computation_amount;
 +};
 +
 +
 +static int worker_main(int argc, char *argv[])
 +{
 +  struct worker_data *params = MSG_process_get_data(MSG_process_self());
 +  double computation_amount = params->computation_amount;
 +
 +  {
 +    double clock_sta = MSG_get_clock();
 +
 +    msg_task_t task = MSG_task_create("Task", computation_amount, 0, NULL);
 +    MSG_task_execute(task);
 +    MSG_task_destroy(task);
 +
 +    double clock_end = MSG_get_clock();
 +
 +    double duration = clock_end - clock_sta;
 +    double flops_per_sec = computation_amount / duration;
 +
 +    XBT_INFO("%s: amount %f duration %f (%f flops/s)",
 +                  MSG_host_get_name(MSG_host_self()), computation_amount, duration, flops_per_sec);
 +  }
 +
 +
 +
 +  xbt_free(params);
 +
 +  return 0;
 +}
 +
 +
 +
 +
 +static void test_one_task(msg_host_t hostA, double computation)
 +{
 +
 +  struct worker_data *params = xbt_new(struct worker_data, 1);
 +  params->computation_amount = computation;
 +
 +  MSG_process_create("worker", worker_main, params, hostA);
 +
 +  //xbt_free(params);
 +}
 +
 +#if 0
 +static void test_two_tasks(msg_host_t hostA, msg_host_t hostB)
 +{
 +  const double cpu_speed = MSG_get_host_speed(hostA);
 +  xbt_assert(cpu_speed == MSG_get_host_speed(hostB));
 +  const double computation_amount = cpu_speed * 10;
 +  const char *hostA_name = MSG_host_get_name(hostA);
 +  const char *hostB_name = MSG_host_get_name(hostB);
 +
 +  {
 +    XBT_INFO("### Test: no bound for Task1@%s, no bound for Task2@%s", hostA_name, hostB_name);
 +    launch_worker(hostA, "worker0", computation_amount, 0, 0);
 +    launch_worker(hostB, "worker1", computation_amount, 0, 0);
 +  }
 +
 +  MSG_process_sleep(1000);
 +
 +  {
 +    XBT_INFO("### Test: 0 for Task1@%s, 0 for Task2@%s (i.e., unlimited)", hostA_name, hostB_name);
 +    launch_worker(hostA, "worker0", computation_amount, 1, 0);
 +    launch_worker(hostB, "worker1", computation_amount, 1, 0);
 +  }
 +
 +  MSG_process_sleep(1000);
 +
 +  {
 +    XBT_INFO("### Test: 50%% for Task1@%s, 50%% for Task2@%s", hostA_name, hostB_name);
 +    launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 2);
 +    launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 2);
 +  }
 +
 +  MSG_process_sleep(1000);
 +
 +  {
 +    XBT_INFO("### Test: 25%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
 +    launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 4);
 +    launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4);
 +  }
 +
 +  MSG_process_sleep(1000);
 +
 +  {
 +    XBT_INFO("### Test: 75%% for Task1@%s, 100%% for Task2@%s", hostA_name, hostB_name);
 +    launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 0.75);
 +    launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed);
 +  }
 +
 +  MSG_process_sleep(1000);
 +
 +  {
 +    XBT_INFO("### Test: no bound for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
 +    launch_worker(hostA, "worker0", computation_amount, 0, 0);
 +    launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4);
 +  }
 +
 +  MSG_process_sleep(1000);
 +
 +  {
 +    XBT_INFO("### Test: 75%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
 +    launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 0.75);
 +    launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4);
 +  }
 +
 +  MSG_process_sleep(1000);
 +}
 +#endif
 +
 +static void test_pm(void)
 +{
 +  xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
 +  msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t);
 +  msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t);
 +  msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t);
 +
 +  const double cpu_speed = MSG_get_host_speed(pm0);
 +  const double computation_amount = cpu_speed * 10;
 +
 +  {
 +    XBT_INFO("# 1. Put a single task on each PM. ");
 +    test_one_task(pm0, computation_amount);
 +    MSG_process_sleep(100);
 +    test_one_task(pm1, computation_amount);
 +    MSG_process_sleep(100);
 +    test_one_task(pm2, computation_amount);
 +  }
 +
 +  MSG_process_sleep(100);
 +
 +  {
 +    XBT_INFO("# 2. Put 2 tasks on each PM. ");
 +    test_one_task(pm0, computation_amount);
 +    test_one_task(pm0, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(pm1, computation_amount);
 +    test_one_task(pm1, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(pm2, computation_amount);
 +    test_one_task(pm2, computation_amount);
 +  }
 +
 +  MSG_process_sleep(100);
 +
 +  {
 +    XBT_INFO("# 3. Put 4 tasks on each PM. ");
 +    test_one_task(pm0, computation_amount);
 +    test_one_task(pm0, computation_amount);
 +    test_one_task(pm0, computation_amount);
 +    test_one_task(pm0, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(pm1, computation_amount);
 +    test_one_task(pm1, computation_amount);
 +    test_one_task(pm1, computation_amount);
 +    test_one_task(pm1, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(pm2, computation_amount);
 +    test_one_task(pm2, computation_amount);
 +    test_one_task(pm2, computation_amount);
 +    test_one_task(pm2, computation_amount);
 +  }
 +
 +  MSG_process_sleep(100);
 +}
 +
 +
 +static void test_vm(void)
 +{
 +  xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
 +  msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t);
 +  msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t);
 +  msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t);
 +
 +
 +  const double cpu_speed = MSG_get_host_speed(pm0);
 +  const double computation_amount = cpu_speed * 10;
 +
 +
 +  {
 +    msg_host_t vm0 = MSG_vm_create_core(pm0, "vm0");
 +    msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
 +    msg_host_t vm2 = MSG_vm_create_core(pm2, "vm2");
 +
 +    XBT_INFO("# 1. Put a single task on each VM.");
 +    test_one_task(vm0, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(vm1, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(vm2, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    MSG_vm_destroy(vm0);
 +    MSG_vm_destroy(vm1);
 +    MSG_vm_destroy(vm2);
 +  }
 +
 +
 +  {
 +    msg_host_t vm0 = MSG_vm_create_core(pm0, "vm0");
 +    msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
 +    msg_host_t vm2 = MSG_vm_create_core(pm2, "vm2");
 +
 +    XBT_INFO("# 2. Put 2 tasks on each VM.");
 +    test_one_task(vm0, computation_amount);
 +    test_one_task(vm0, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(vm1, computation_amount);
 +    test_one_task(vm1, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(vm2, computation_amount);
 +    test_one_task(vm2, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    MSG_vm_destroy(vm0);
 +    MSG_vm_destroy(vm1);
 +    MSG_vm_destroy(vm2);
 +  }
 +
 +
 +  {
 +    msg_host_t vm0 = MSG_vm_create_core(pm0, "vm0");
 +    msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
 +    msg_host_t vm2 = MSG_vm_create_core(pm2, "vm2");
 +
 +    XBT_INFO("# 3. Put a task on each VM, and put a task on its PM.");
 +    test_one_task(vm0, computation_amount);
 +    test_one_task(pm0, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(vm1, computation_amount);
 +    test_one_task(pm1, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    test_one_task(vm2, computation_amount);
 +    test_one_task(pm2, computation_amount);
 +    MSG_process_sleep(100);
 +
 +    MSG_vm_destroy(vm0);
 +    MSG_vm_destroy(vm1);
 +    MSG_vm_destroy(vm2);
 +  }
 +
 +
 +  {
 +    {
 +       /* 1-core PM */
 +       XBT_INFO("# 4. Put 2 VMs on a 1-core PM.");
 +       msg_host_t vm0 = MSG_vm_create_core(pm0, "vm0");
 +       msg_host_t vm1 = MSG_vm_create_core(pm0, "vm1");
 +      
 +       test_one_task(vm0, computation_amount);
 +       test_one_task(vm1, computation_amount);
 +       MSG_process_sleep(100);
 +      
 +       MSG_vm_destroy(vm0);
 +       MSG_vm_destroy(vm1);
 +    }
 +
 +    {
 +       /* 2-core PM */
 +       XBT_INFO("# 5. Put 2 VMs on a 2-core PM.");
 +       msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
 +       msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
 +
 +       test_one_task(vm0, computation_amount);
 +       test_one_task(vm1, computation_amount);
 +       MSG_process_sleep(100);
 +
 +       MSG_vm_destroy(vm0);
 +       MSG_vm_destroy(vm1);
 +    }
 +
 +    {
 +       /* 2-core PM */
 +       XBT_INFO("# 6. Put 2 VMs on a 2-core PM and 1 task on the PM.");
 +       msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
 +       msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
 +
 +       test_one_task(vm0, computation_amount);
 +       test_one_task(vm1, computation_amount);
 +       test_one_task(pm1, computation_amount);
 +       MSG_process_sleep(100);
 +
 +       MSG_vm_destroy(vm0);
 +       MSG_vm_destroy(vm1);
 +    }
 +
 +    {
 +       /* 2-core PM */
 +       XBT_INFO("# 7. Put 2 VMs and 2 tasks on a 2-core PM. Put two tasks on one of the VMs.");
 +       msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
 +       msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
 +       test_one_task(pm1, computation_amount);
 +       test_one_task(pm1, computation_amount);
 +
 +       /* Reduce computation_amount to make all tasks finish at the same time. Simplify results. */
 +       test_one_task(vm0, computation_amount / 2);
 +       test_one_task(vm0, computation_amount / 2);
 +       test_one_task(vm1, computation_amount);
 +       MSG_process_sleep(100);
 +
 +       MSG_vm_destroy(vm0);
 +       MSG_vm_destroy(vm1);
 +    }
 +
 +    {
 +       /* 2-core PM */
 +       XBT_INFO("# 8. Put 2 VMs and a task on a 2-core PM. Cap the load of VM1 at 50%%.");
 +       /* This is a tricky case. The process schedular of the host OS may not work as expected. */
 +      
 +       /* VM0 gets 50%. VM1 and VM2 get 75%, respectively. */
 +       msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
 +       MSG_vm_set_bound(vm0, cpu_speed / 2);
 +       msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
 +       test_one_task(pm1, computation_amount);
 +
 +       test_one_task(vm0, computation_amount);
 +       test_one_task(vm1, computation_amount);
 +
 +       MSG_process_sleep(100);
 +
 +       MSG_vm_destroy(vm0);
 +       MSG_vm_destroy(vm1);
 +    }
 +
 +
 +    /* In all the above cases, tasks finish at the same time.
 +     * TODO: more complex cases must be done.
 +     **/
 +
 +#if 0
 +    {
 +       /* 2-core PM */
 +       XBT_INFO("# 8. Put 2 VMs and a task on a 2-core PM. Put two tasks on one of the VMs.");
 +       msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
 +       msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
 +
 +       test_one_task(vm0, computation_amount);
 +       test_one_task(vm0, computation_amount);
 +       test_one_task(vm1, computation_amount);
 +       test_one_task(pm1, computation_amount);
 +       MSG_process_sleep(100);
 +
 +       MSG_vm_destroy(vm0);
 +       MSG_vm_destroy(vm1);
 +    }
 +#endif
 +  }
 +}
 +
 +
 +
 +static int master_main(int argc, char *argv[])
 +{
 +  XBT_INFO("=== Test PM ===");
 +  test_pm();
 +
 +  XBT_INFO(" ");
 +  XBT_INFO(" ");
 +  XBT_INFO("=== Test VM ===");
 +  test_vm();
 +
 +  return 0;
 +}
 +
 +
 +
 +
 +
 +int main(int argc, char *argv[])
 +{
 +  /* Get the arguments */
 +  MSG_init(&argc, argv);
 +
 +  /* load the platform file */
 +  if (argc != 2) {
 +    printf("Usage: %s examples/msg/cloud/multicore_plat.xml\n", argv[0]);
 +    return 1;
 +  }
 +
 +  MSG_create_environment(argv[1]);
 +
 +  xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
 +  msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t);
 +  msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t);
 +  msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t);
 +
 +
++  XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm0), MSG_host_get_core_number(pm0), MSG_get_host_speed(pm0));
++  XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm1), MSG_host_get_core_number(pm1), MSG_get_host_speed(pm1));
++  XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm2), MSG_host_get_core_number(pm2), MSG_get_host_speed(pm2));
 +
 +
 +
 +  MSG_process_create("master", master_main, NULL, pm0);
 +
 +
 +
 +
 +  int res = MSG_main();
 +  XBT_INFO("Bye (simulation time %g)", MSG_get_clock());
 +
 +
 +  return !(res == MSG_OK);
 +}
diff --combined include/msg/datatypes.h
@@@ -1,4 -1,5 +1,5 @@@
- /* Copyright (c) 2004-2012. The SimGrid Team. All rights reserved.          */
+ /* Copyright (c) 2004-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
@@@ -47,12 -48,7 +48,12 @@@ 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;
 +
 +  xbt_dict_t affinity_mask_db;
 +
  #ifdef MSG_USE_DEPRECATED
    msg_mailbox_t *mailboxes;     /**< the channels  */
  #endif
@@@ -87,31 -83,66 +88,57 @@@ 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 s_msg_file_info {
+   sg_storage_size_t size;
+   char* mount_point;
+   char* storageId;
+   char* storage_type;
+   char* content_type;
+ } s_msg_file_info_t, *msg_file_info_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 */
+   char *fullname;               /**< @brief file full name (path+name)*/
+   simdata_file_t simdata;       /**< @brief simulator data  */
+   msg_file_info_t info;
  } s_msg_file_t;
  
  /** @brief File datatype.
-     @ingroup msg_file_management 
-  
-     You should consider this as an opaque object.
+  *  @ingroup msg_file_management
+  *
+  *  You should consider this as an opaque object.
   */
  typedef struct msg_file *msg_file_t;
  
+ /* ******************************** Storage ************************************ */
+ /* TODO: PV: to comment */
+ extern int MSG_STORAGE_LEVEL;
+ /** @brief Storage datatype.
+  *  @ingroup msg_storage_management
+  *
+  *  You should consider this as an opaque object.
+  */
+ typedef xbt_dictelm_t msg_storage_t;
+ typedef s_xbt_dictelm_t s_msg_storage_t;
+ typedef struct msg_storage_priv  {
+   // TODO PV: fill it (or not) !
+   void * dummy;
+ } s_msg_storage_priv_t, *msg_storage_priv_t;
  /*************** Begin GPU ***************/
  typedef struct simdata_gpu_task *simdata_gpu_task_t;
  
diff --combined include/msg/msg.h
@@@ -1,4 -1,5 +1,5 @@@
- /* Copyright (c) 2004-2012. The SimGrid Team. All rights reserved.          */
+ /* Copyright (c) 2004-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
@@@ -12,6 -13,8 +13,8 @@@
  
  #include "simgrid/simix.h"
  
+ #include "simgrid/platf.h"
  SG_BEGIN_DECL()
  
  /** @brief Return code of most MSG functions
@@@ -78,15 -81,32 +81,32 @@@ XBT_PUBLIC(const char *) MSG_environmen
  XBT_PUBLIC(xbt_dynar_t) MSG_environment_as_get_hosts(msg_as_t as);
  
  /************************** File handling ***********************************/
- 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(sg_storage_size_t) MSG_file_read(msg_file_t fd, sg_storage_size_t size);
+ XBT_PUBLIC(sg_storage_size_t) MSG_file_write(msg_file_t fd, sg_storage_size_t size);
+ XBT_PUBLIC(msg_file_t) MSG_file_open(const char* mount, const char* path,
+                                      void* data);
+ XBT_PUBLIC(void*) MSG_file_get_data(msg_file_t fd);
+ XBT_PUBLIC(msg_error_t) MSG_file_set_data(msg_file_t fd, void * data);
  XBT_PUBLIC(int) MSG_file_close(msg_file_t fd);
- XBT_PUBLIC(size_t) MSG_file_get_size(msg_file_t fd);
+ XBT_PUBLIC(sg_storage_size_t) MSG_file_get_size(msg_file_t fd);
+ XBT_PUBLIC(void) MSG_file_dump(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);
+ XBT_PUBLIC(void) __MSG_file_get_info(msg_file_t fd);
+ /************************** Storage handling ***********************************/
+ XBT_PUBLIC(msg_host_t) MSG_get_storage_by_name(const char *name);
+ XBT_PUBLIC(const char *) MSG_storage_get_name(msg_storage_t storage);
+ XBT_PUBLIC(sg_storage_size_t) MSG_storage_get_free_size(const char* name);
+ XBT_PUBLIC(sg_storage_size_t) MSG_storage_get_used_size(const char* name);
+ XBT_PUBLIC(msg_storage_t) MSG_storage_get_by_name(const char *name);
+ XBT_PUBLIC(xbt_dict_t) MSG_storage_get_properties(msg_storage_t storage);
+ XBT_PUBLIC(void) MSG_storage_set_property_value(msg_storage_t storage, const char *name, char *value,void_f_pvoid_t free_ctn);
+ XBT_PUBLIC(xbt_dynar_t) MSG_storages_as_dynar(void);
+ XBT_PUBLIC(msg_error_t) MSG_storage_set_data(msg_storage_t host, void *data);
+ XBT_PUBLIC(void *) MSG_storage_get_data(msg_storage_t storage);
+ XBT_PUBLIC(xbt_dict_t) MSG_storage_get_content(msg_storage_t storage);
+ XBT_PUBLIC(sg_storage_size_t) MSG_storage_get_size(msg_storage_t storage);
  /************************** AS Router handling ************************************/
  XBT_PUBLIC(const char *) MSG_as_router_get_property_value(const char* asr, const char *name);
  XBT_PUBLIC(xbt_dict_t) MSG_as_router_get_properties(const char* asr);
@@@ -96,17 -116,21 +116,24 @@@ 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_get_core_number(msg_host_t h);
+ XBT_PUBLIC(xbt_swag_t) MSG_host_get_process_list(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);
  
+ XBT_PUBLIC(double) MSG_get_host_power_peak_at(msg_host_t h, int pstate_index);
+ XBT_PUBLIC(double) MSG_get_host_current_power_peak(msg_host_t h);
+ XBT_PUBLIC(int) MSG_get_host_nb_pstates(msg_host_t h);
+ XBT_PUBLIC(void) MSG_set_host_power_peak_at(msg_host_t h, int pstate);
+ XBT_PUBLIC(double) MSG_get_host_consumed_energy(msg_host_t h);
  /*property handlers*/
  XBT_PUBLIC(xbt_dict_t) MSG_host_get_properties(msg_host_t host);
  XBT_PUBLIC(const char *) MSG_host_get_property_value(msg_host_t host,
@@@ -121,10 -145,8 +148,10 @@@ XBT_PUBLIC(void) MSG_create_environment
  XBT_PUBLIC(msg_host_t) MSG_get_host_by_name(const char *name);
  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);
+ XBT_PUBLIC(xbt_dict_t) MSG_host_get_storage_list(msg_host_t host);
+ XBT_PUBLIC(xbt_dict_t) MSG_host_get_storage_content(msg_host_t host);
  /************************** Process handling *********************************/
  XBT_PUBLIC(msg_process_t) MSG_process_create(const char *name,
                                             xbt_main_func_t code,
@@@ -214,8 -236,6 +241,8 @@@ 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(void) MSG_task_set_affinity(msg_task_t task, msg_host_t host, unsigned long mask);
  
  XBT_PUBLIC(msg_error_t) MSG_process_sleep(double nb_sec);
  
@@@ -389,47 -409,30 +416,47 @@@ 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, int mem_cap, int net_cap, char *disk_path, int disk_size, int mig_netspeed, int dp_intensity);
  
 -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(void) MSG_vm_set_affinity(msg_vm_t vm, msg_host_t pm, unsigned long mask);
  
 -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
@@@ -1,6 -1,7 +1,7 @@@
  /* platf.h - Public interface to the SimGrid platforms                      */
  
- /* Copyright (c) 2004-2012. The SimGrid Team. All rights reserved.          */
+ /* Copyright (c) 2004-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
@@@ -41,46 -42,6 +42,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 */
@@@ -115,6 -76,13 +116,13 @@@ static inline char* sg_host_name(sg_hos
    return host->key;
  }
  
+ typedef xbt_dictelm_t sg_storage_t;
+ static inline char* sg_storage_name(sg_storage_t storage) {
+   return storage->key;
+ }
+ /* Type for any integer storage size  */
+ typedef uint64_t sg_storage_size_t;
  
  /*
   * Platform creation functions. Instead of passing 123 arguments to the creation functions
  
  typedef struct {
    const char* id;
-   double power_peak;
+   xbt_dynar_t power_peak;
+   int pstate;
    int core_amount;
    double power_scale;
    tmgr_trace_t power_trace;
@@@ -258,6 -227,7 +267,7 @@@ typedef struct 
    const char* id;
    const char* type_id;
    const char* content;
+   const char* content_type;
    xbt_dict_t properties;
  } s_sg_platf_storage_cbarg_t, *sg_platf_storage_cbarg_t;
  
@@@ -267,8 -237,9 +277,9 @@@ typedef struct 
    const char* id;
    const char* model;
    const char* content;
+   const char* content_type;
    xbt_dict_t properties;
-   unsigned long size; /* size in Gbytes */
+   sg_storage_size_t size;
  } s_sg_platf_storage_type_cbarg_t, *sg_platf_storage_type_cbarg_t;
  
  #define SG_PLATF_STORAGE_TYPE_INITIALIZER {NULL,NULL,NULL,NULL,NULL}
@@@ -281,7 -252,7 +292,7 @@@ typedef struct 
  #define SG_PLATF_MSTORAGE_INITIALIZER {NULL,NULL}
  
  typedef struct {
-   const char* id;
+   const char* storageId;
    const char* name;
  } s_sg_platf_mount_cbarg_t, *sg_platf_mount_cbarg_t;
  
diff --combined include/simgrid/simix.h
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007-2010, 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
  #include "xbt/function_types.h"
  #include "xbt/parmap.h"
  #include "xbt/swag.h"
+ #include "simgrid/platf.h"
  
 +#include "simgrid/platf.h" // ws_params_t
 +
  SG_BEGIN_DECL()
  
  /**************************** Scalar Values **********************************/
@@@ -70,8 -69,13 +71,13 @@@ typedef struct s_smx_cond *smx_cond_t
  typedef struct s_smx_sem *smx_sem_t;
  
  /********************************** File *************************************/
  typedef struct s_smx_file *smx_file_t;
  
+ /********************************** Storage *************************************/
+ typedef xbt_dictelm_t smx_storage_t;
+ typedef struct s_smx_storage_priv *smx_storage_priv_t;
  /********************************** Action *************************************/
  typedef struct s_smx_action *smx_action_t; /* FIXME: replace by specialized action handlers */
  
@@@ -256,13 -260,11 +262,13 @@@ 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, smx_process_t issuer);
  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);
  XBT_PUBLIC(void) SIMIX_host_set_data(smx_host_t host, void *data);
+ XBT_PUBLIC(xbt_dict_t) SIMIX_host_get_storage_list(smx_host_t host);
  /********************************* Process ************************************/
  XBT_PUBLIC(int) SIMIX_process_count(void);
  XBT_PUBLIC(smx_process_t) SIMIX_process_self(void);
@@@ -285,6 -287,10 +291,10 @@@ XBT_PUBLIC(int) SIMIX_comm_has_send_mat
  XBT_PUBLIC(int) SIMIX_comm_has_recv_match(smx_rdv_t rdv, int (*match_fun)(void*, void*), void* data);
  XBT_PUBLIC(void) SIMIX_comm_finish(smx_action_t action);
  
+ /*********************************** File *************************************/
+ XBT_PUBLIC(void*) SIMIX_file_get_data(smx_file_t fd);
+ XBT_PUBLIC(void) SIMIX_file_set_data(smx_file_t fd, void *data);
  /******************************************************************************/
  /*                            SIMIX simcalls                                  */
  /******************************************************************************/
  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(xbt_swag_t) simcall_host_get_process_list(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 */
@@@ -308,9 -313,15 +319,15 @@@ XBT_PUBLIC(void *) simcall_host_get_dat
  
  XBT_PUBLIC(void) simcall_host_set_data(smx_host_t host, void *data);
  
+ XBT_PUBLIC(double) simcall_host_get_current_power_peak(smx_host_t host);
+ XBT_PUBLIC(double) simcall_host_get_power_peak_at(smx_host_t host, int pstate_index);
+ XBT_PUBLIC(int) simcall_host_get_nb_pstates(smx_host_t host);
+ XBT_PUBLIC(void) simcall_host_set_power_peak_at(smx_host_t host, int pstate_index);
+ XBT_PUBLIC(double) simcall_host_get_consumed_energy(smx_host_t host);
  XBT_PUBLIC(smx_action_t) simcall_host_execute(const char *name, smx_host_t host,
                                                  double computation_amount,
 -                                                double priority);
 +                                                double priority, double bound, unsigned long affinity_mask);
  XBT_PUBLIC(smx_action_t) simcall_host_parallel_execute(const char *name,
                                                       int host_nb,
                                                       smx_host_t *host_list,
@@@ -323,27 -334,8 +340,28 @@@ 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(void) simcall_host_execution_set_affinity(smx_action_t execution, smx_host_t host, unsigned long mask);
  XBT_PUBLIC(e_smx_state_t) simcall_host_execution_wait(smx_action_t execution);
+ XBT_PUBLIC(xbt_dict_t) simcall_host_get_storage_list(smx_host_t host);
 +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_set_affinity(smx_host_t vm, smx_host_t pm, unsigned long mask);
 +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 */
@@@ -486,15 -478,28 +504,28 @@@ XBT_PUBLIC(void) simcall_sem_acquire_ti
                                               double max_duration);
  XBT_PUBLIC(int) simcall_sem_get_capacity(smx_sem_t sem);
  
- 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);
+ /*****************************   File   **********************************/
+ XBT_PUBLIC(void *) simcall_file_get_data(smx_file_t fd);
+ XBT_PUBLIC(void) simcall_file_set_data(smx_file_t fd, void *data);
+ XBT_PUBLIC(sg_storage_size_t) simcall_file_read(smx_file_t fd, sg_storage_size_t size);
+ XBT_PUBLIC(sg_storage_size_t) simcall_file_write(smx_file_t fd, sg_storage_size_t size);
  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);
+ XBT_PUBLIC(sg_storage_size_t) simcall_file_get_size(smx_file_t fd);
+ XBT_PUBLIC(xbt_dynar_t) simcall_file_get_info(smx_file_t fd);
+ /*****************************   Storage   **********************************/
+ XBT_PUBLIC(sg_storage_size_t) simcall_storage_get_free_size (const char* name);
+ XBT_PUBLIC(sg_storage_size_t) simcall_storage_get_used_size (const char* name);
+ XBT_PUBLIC(xbt_dict_t) simcall_storage_get_properties(smx_storage_t storage);
+ XBT_PUBLIC(void*) SIMIX_storage_get_data(smx_storage_t storage);
+ XBT_PUBLIC(void) SIMIX_storage_set_data(smx_storage_t storage, void *data);
+ XBT_PUBLIC(xbt_dict_t) SIMIX_storage_get_content(smx_storage_t storage);
+ XBT_PUBLIC(xbt_dict_t) simcall_storage_get_content(smx_storage_t storage);
+ XBT_PUBLIC(const char*) SIMIX_storage_get_name(smx_host_t host);
+ XBT_PUBLIC(sg_storage_size_t) SIMIX_storage_get_size(smx_storage_t storage);
  /************************** AS router   **********************************/
  XBT_PUBLIC(xbt_dict_t) SIMIX_asr_get_properties(const char *name);
  /************************** AS router simcalls ***************************/
@@@ -503,7 -508,7 +534,7 @@@ XBT_PUBLIC(xbt_dict_t) simcall_asr_get_
  /************************** MC simcalls   **********************************/
  XBT_PUBLIC(void *) simcall_mc_snapshot(void);
  XBT_PUBLIC(int) simcall_mc_compare_snapshots(void *s1, void *s2);
- XBT_PUBLIC(int) simcall_mc_random(void);
+ XBT_PUBLIC(int) simcall_mc_random(int min, int max);
  
  /************************** New API simcalls **********************************/
  /* TUTORIAL: New API                                                          */
diff --combined include/xbt/ex.h
@@@ -1,6 -1,6 +1,6 @@@
  /* ex - Exception Handling                                                  */
  
- /*  Copyright (c) 2005-2010 The SimGrid team                                */
+ /*  Copyright (c) 2005-2013. The SimGrid Team.                              */
  /*  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>       */
  /*  Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>         */
  /*  Copyright (c) 2002-2004 Cable & Wireless <http://www.cw.com/>           */
@@@ -140,7 -140,7 +140,7 @@@ __ex_mctx_struct} __ex_mctx_t
   *
   * Any exception thrown directly from the TRIED_BLOCK block or from called
   * subroutines is caught. Cleanups which must be done after this block
-  * (whenever an exception arised or not) should be placed into the optionnal
+  * (whenever an exception arose or not) should be placed into the optionnal
   * CLEANUP_BLOCK. The code dealing with the exceptions when they arise should
   * be placed into the (mandatory) CATCH_BLOCK.
   *
@@@ -262,8 -262,7 +262,8 @@@ typedef enum 
    thread_error,                 /**< error while [un]locking */
    host_error,                   /**< host failed */
    tracing_error,                /**< error during the simulation tracing */
 -  io_error                      /**< disk or file error */
 +  io_error,                      /**< disk or file error */
 +  vm_error                      /**< vm  error */
  } xbt_errcat_t;
  
  XBT_PUBLIC(const char *) xbt_ex_catname(xbt_errcat_t cat);
diff --combined include/xbt/lib.h
@@@ -1,6 -1,6 +1,6 @@@
  /* xbt/lib.h - api to a generic library                                     */
  
- /* Copyright (c) 2011. The SimGrid Team.
+ /* Copyright (c) 2011, 2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -26,12 -26,10 +26,12 @@@ XBT_PUBLIC(void) xbt_lib_free(xbt_lib_
  XBT_PUBLIC(int) xbt_lib_add_level(xbt_lib_t lib, void_f_pvoid_t free_f);
  XBT_PUBLIC(void) xbt_lib_set(xbt_lib_t lib, const char *name, int level,
                               void *obj);
 +XBT_PUBLIC(void) xbt_lib_unset(xbt_lib_t lib, const char *key, int level, int invoke_callback);
  XBT_PUBLIC(void *) xbt_lib_get_or_null(xbt_lib_t lib, const char *name,
                                         int level);
  XBT_PUBLIC(xbt_dictelm_t) xbt_lib_get_elm_or_null(xbt_lib_t lib, const char *key);
  XBT_PUBLIC(void *) xbt_lib_get_level(xbt_dictelm_t elm, int level);
 +XBT_PUBLIC(void) xbt_lib_remove(xbt_lib_t lib, const char *key);
  
  #define xbt_lib_length(lib) xbt_dict_length((lib)->dict)
  
@@@ -1,6 -1,6 +1,6 @@@
  /* Functions related to the java host instances.                            */
  
- /* Copyright (c) 2007-2012. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -154,19 -154,6 +154,19 @@@ Java_org_simgrid_msg_Host_currentHost(J
  
    return jhost;
  }
 +
 +JNIEXPORT void JNICALL
 +Java_org_simgrid_msg_Host_on(JNIEnv *env, jobject jhost) {
 +  msg_host_t host = jhost_get_native(env, jhost);
 +  MSG_host_on(host);
 +}
 +
 +JNIEXPORT void JNICALL
 +Java_org_simgrid_msg_Host_off(JNIEnv *env, jobject jhost) {
 +  msg_host_t host = jhost_get_native(env, jhost);
 +  MSG_host_off(host);
 +}
 +
  JNIEXPORT jint JNICALL
  Java_org_simgrid_msg_Host_getCount(JNIEnv * env, jclass cls) {
    xbt_dynar_t hosts =  MSG_hosts_as_dynar();
@@@ -189,7 -176,7 +189,7 @@@ Java_org_simgrid_msg_Host_getSpeed(JNIE
  }
  
  JNIEXPORT jdouble JNICALL
- Java_org_simgrid_msg_Host_getCore(JNIEnv * env,
+ Java_org_simgrid_msg_Host_getCoreNumber(JNIEnv * env,
                                          jobject jhost) {
    msg_host_t host = jhost_get_native(env, jhost);
  
      return -1;
    }
  
-   return (jdouble) MSG_get_host_core(host);
+   return (jdouble) MSG_host_get_core_number(host);
  }
  
  JNIEXPORT jint JNICALL
@@@ -1,6 -1,6 +1,6 @@@
  /* Functions related to the java host instances.                            */
  
- /* Copyright (c) 2007-2012. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -112,24 -112,6 +112,24 @@@ Java_org_simgrid_msg_Host_nativeInit(JN
  JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Host_getByName
      (JNIEnv *, jclass, jstring);
  
 +/**
 + * This function start the host if it is off
 + *
 + * @param jhost                       The host to test the validity.
 + * @param env                 The environment of the current thread
 + *
 + */
 +JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_on(JNIEnv *env, jobject jhost);
 +
 +/**
 + * This function stop the host if it is on
 + *
 + * @param jhost                       The host to test the validity.
 + * @param env                 The environment of the current thread
 + *
 + */
 +JNIEXPORT void JNICALL Java_org_simgrid_msg_Host_off(JNIEnv *env, jobject jhost);
 +
  /*
   * Class              org_simgrid_msg_Host
   * Method             currentHost
@@@ -154,10 -136,10 +154,10 @@@ JNIEXPORT jdouble JNICALL Java_org_simg
      (JNIEnv *, jobject);
  /*
   * Class              org_simgrid_msg_Host
-  * Method             getCore
+  * Method             getCoreNumber
   * Signature  ()D
   */
- JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCore
+ JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCoreNumber
      (JNIEnv *, jobject);
  /*
   * Class              org_simgrid_msg_Host
@@@ -1,6 -1,6 +1,6 @@@
  /* Functions related to the java task instances.                            */
  
- /* Copyright (c) 2007, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007, 2009-2010, 2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -225,18 -225,6 +225,18 @@@ Java_org_simgrid_msg_Task_execute(JNIEn
    }
  }
  
 +JNIEXPORT void JNICALL
 +Java_org_simgrid_msg_Task_setBound(JNIEnv * env, jobject jtask, jdouble load)
 +{
 +  msg_task_t task = jtask_to_native_task(jtask, env);
 +
 +  if (!task) {
 +    jxbt_throw_notbound(env, "task", jtask);
 +    return;
 +  }
 +  MSG_task_set_bound(task, load);
 +}
 +
  JNIEXPORT jstring JNICALL
  Java_org_simgrid_msg_Task_getName(JNIEnv * env,
                                         jobject jtask) {
@@@ -1,6 -1,6 +1,6 @@@
  /* Functions related to the java task instances.                            */
  
- /* Copyright (c) 2007-2012. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -124,6 -124,6 +124,14 @@@ JNIEXPORT void JNICALL Java_org_simgrid
  JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_execute
      (JNIEnv *, jobject);
  
++/*
++ * Class              org_simgrid_msg_Task
++ * Method             setBound
++ * Signature  ()V
++ */
++JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setBound
++    (JNIEnv *, jobject, jdouble);
++
  /*
   * Class              org_simgrid_msg_Task
   * Method             getName
@@@ -177,7 -177,7 +185,7 @@@ JNIEXPORT void JNICALL Java_org_simgrid
      (JNIEnv *, jobject, jdouble);
  /**
   * Class              org_simgrid_msg_Task
-  * Method             setComputationAmount
+  * Method             setComputeDuration
   * Signature  (D)V
   */
  JNIEXPORT void JNICALL
@@@ -1,9 -1,10 +1,10 @@@
  /* Functions related to the MSG VM API. */
  
- /* Copyright (c) 2012. The SimGrid Team. */
+ /* Copyright (c) 2012-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
-   * under the terms of the license (GNU LGPL) which comes with this package. */
+  * under the terms of the license (GNU LGPL) which comes with this package. */
  #include "jmsg_vm.h"
  #include "jmsg_host.h"
  #include "jmsg_process.h"
@@@ -28,161 -29,100 +29,161 @@@ Java_org_simgrid_msg_VM_nativeInit(JNIE
      jxbt_throw_native(env,bprintf("Can't find some fields in Java class. You should report this bug."));
    }
  }
 +
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isCreated(JNIEnv * env, jobject jvm) {
 +  msg_vm_t vm = jvm_get_native(env,jvm);
 +  return (jint) MSG_vm_is_created(vm);
 +}
 +
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isRunning(JNIEnv * env, jobject jvm) {
 +  msg_vm_t vm = jvm_get_native(env,jvm);
 +  return (jint) MSG_vm_is_running(vm);
 +}
 +
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isMigrating(JNIEnv * env, jobject jvm) {
 +  msg_vm_t vm = jvm_get_native(env,jvm);
 +  return (jint) MSG_vm_is_migrating(vm);
 +}
 +
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isSuspended(JNIEnv * env, jobject jvm) {
 +  msg_vm_t vm = jvm_get_native(env,jvm);
 +  return (jint) MSG_vm_is_suspended(vm);
 +}
 +
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isSaving(JNIEnv * env, jobject jvm) {
 +  msg_vm_t vm = jvm_get_native(env,jvm);
 +  return (jint) MSG_vm_is_saving(vm);
 +}
 +
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isSaved(JNIEnv * env, jobject jvm) {
 +  msg_vm_t vm = jvm_get_native(env,jvm);
 +  return (jint) MSG_vm_is_saved(vm);
 +}
 +
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isRestoring(JNIEnv * env, jobject jvm) {
 +  msg_vm_t vm = jvm_get_native(env,jvm);
 +  return (jint) MSG_vm_is_restoring(vm);
 +}
 +
 +JNIEXPORT void JNICALL
 +Java_org_simgrid_msg_VM_setBound(JNIEnv *env, jobject jvm, jint load) { 
 +
 +      msg_vm_t vm = jvm_get_native(env,jvm);
 +      double bound = MSG_get_host_speed(vm) * load / 100;
 +      MSG_vm_set_bound(vm, bound); 
 +}
 +
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_start(JNIEnv *env, jobject jvm, jobject jhost, jstring jname, jint jcoreamount) {
 +Java_org_simgrid_msg_VM_create(JNIEnv *env, jobject jvm, jobject jhost, jstring jname,
 +                             jint jncore, jint jramsize, jint jnetcap, jstring jdiskpath, jint jdisksize, jint jmig_netspeed, jint jdp_intensity) {
 +
    msg_host_t host = jhost_get_native(env, jhost);
  
    const char *name;
    name = (*env)->GetStringUTFChars(env, jname, 0);
    name = xbt_strdup(name);
 -  
 -  msg_vm_t vm = MSG_vm_start(host, name, (int)jcoreamount);
 +
 +  // TODO disk concerns are not taken into account yet
 +  // const char *diskpath;
 +  // disk_path = (*env)->GetStringUTFChars(env, jdiskpath, 0);
 +  // disk_path = xbt_strdup(disk_path);
 +
 +  msg_vm_t vm = MSG_vm_create(host, name, (int) jncore, (int) jramsize,
 +                (int) jnetcap, NULL, (int) jdisksize, (int) jmig_netspeed, (int) jdp_intensity);
  
    jvm_bind(env,jvm,vm);
  }
 +
  JNIEXPORT void JNICALL
  Java_org_simgrid_msg_VM_destroy(JNIEnv *env, jobject jvm) {
    msg_vm_t vm = jvm_get_native(env,jvm);
    MSG_vm_destroy(vm);
  }
 -JNIEXPORT jboolean JNICALL
 -Java_org_simgrid_msg_VM_isSuspended(JNIEnv *env, jobject jvm) {
 -  msg_vm_t vm = jvm_get_native(env,jvm);
  
 -  return MSG_vm_is_suspended(vm) ? JNI_TRUE : JNI_FALSE;
 -}
 -JNIEXPORT jboolean JNICALL
 -Java_org_simgrid_msg_VM_isRunning(JNIEnv *env, jobject jvm) {
 -  msg_vm_t vm = jvm_get_native(env,jvm);
 -
 -  return MSG_vm_is_running(vm) ? JNI_TRUE : JNI_FALSE;
 -}
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_bind(JNIEnv *env, jobject jvm, jobject jprocess) {
 +Java_org_simgrid_msg_VM_start(JNIEnv *env, jobject jvm) {
    msg_vm_t vm = jvm_get_native(env,jvm);
 -  msg_process_t process = jprocess_to_native_process(jprocess,env);
 -
 -  xbt_assert((vm != NULL), "VM object is not bound");
 -  xbt_assert((process != NULL), "Process object is not bound.");
 -
 -  MSG_vm_bind(vm,process);
 +  MSG_vm_start(vm);
  }
 +
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_unbind(JNIEnv *env, jobject jvm, jobject jprocess) {
 +Java_org_simgrid_msg_VM_shutdown(JNIEnv *env, jobject jvm) {
    msg_vm_t vm = jvm_get_native(env,jvm);
 -  msg_process_t process = jprocess_to_native_process(jprocess,env);
 -
 -  MSG_vm_unbind(vm,process);
 +  MSG_vm_shutdown(vm);
  }
 +
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_migrate(JNIEnv *env, jobject jvm, jobject jhost) {
 +Java_org_simgrid_msg_VM_internalmig(JNIEnv *env, jobject jvm, jobject jhost) {
    msg_vm_t vm = jvm_get_native(env,jvm);
    msg_host_t host = jhost_get_native(env, jhost);
 -
    MSG_vm_migrate(vm,host);
  }
 +
  JNIEXPORT void JNICALL
  Java_org_simgrid_msg_VM_suspend(JNIEnv *env, jobject jvm) {
    msg_vm_t vm = jvm_get_native(env,jvm);
 -  xbt_ex_t e;
 -  TRY {
 -    MSG_vm_suspend(vm);
 -  }
 -  CATCH(e) {
 -    xbt_ex_free(e);
 -  }
 +  MSG_vm_suspend(vm);
  }
  JNIEXPORT void JNICALL
  Java_org_simgrid_msg_VM_resume(JNIEnv *env, jobject jvm) {
    msg_vm_t vm = jvm_get_native(env,jvm);
 -  xbt_ex_t e;
 -  TRY {
 -    MSG_vm_resume(vm);
 -  }
 -  CATCH(e) {
 -    xbt_ex_free(e);
 -  }
 +  MSG_vm_resume(vm);
  }
 +
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_shutdown(JNIEnv *env, jobject jvm) {
 +Java_org_simgrid_msg_VM_save(JNIEnv *env, jobject jvm) {
    msg_vm_t vm = jvm_get_native(env,jvm);
 -  xbt_ex_t e;
 -  TRY {
 -    MSG_vm_shutdown(vm);
 -  }
 -  CATCH(e) {
 -    xbt_ex_free(e);
 -  }
 +  MSG_vm_save(vm);
  }
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_reboot(JNIEnv *env, jobject jvm) {
 +Java_org_simgrid_msg_VM_restore(JNIEnv *env, jobject jvm) {
    msg_vm_t vm = jvm_get_native(env,jvm);
 -  xbt_ex_t e;
 -  TRY {
 -    MSG_vm_reboot(vm);
 -  }
 -  CATCH(e) {
 -    xbt_ex_free(e);
 +  MSG_vm_restore(vm);
 +}
 +
 +
 +
 +JNIEXPORT jobject JNICALL
 +Java_org_simgrid_msg_VM_get_pm(JNIEnv *env, jobject jvm) {
 +  jobject jhost;
 +  msg_vm_t vm = jvm_get_native(env,jvm);
 +  msg_host_t host = MSG_vm_get_pm(vm);
 +
 +  if (!MSG_host_get_data(host)) {
 +    /* the native host not yet associated with the java host instance */
 +
 +    /* instanciate a new java host instance */
 +    jhost = jhost_new_instance(env);
 +
 +    if (!jhost) {
 +      jxbt_throw_jni(env, "java host instantiation failed");
 +      return NULL;
 +    }
 +
 +    /* get a global reference to the newly created host */
 +    jhost = jhost_ref(env, jhost);
 +
 +    if (!jhost) {
 +      jxbt_throw_jni(env, "global ref allocation failed");
 +      return NULL;
 +    }
 +    /* Sets the host name */
 +    const char *name = MSG_host_get_name(host);
 +    jobject jname = (*env)->NewStringUTF(env,name);
 +    (*env)->SetObjectField(env, jhost, jxbt_get_jfield(env, (*env)->FindClass(env, "org/simgrid/msg/Host"), "name", "Ljava/lang/String;"), jname);
 +    /* Bind & store it */
 +    jhost_bind(jhost, host, env);
 +    MSG_host_set_data(host, (void *) jhost);
 +  } else {
 +    jhost = (jobject) MSG_host_get_data(host);
    }
 +
 +  return jhost;
  }
@@@ -1,10 -1,10 +1,10 @@@
  /* Functions related to the MSG VM API. */
  
- /* Copyright (c) 2012. The SimGrid Team. */
+ /* Copyright (c) 2012-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
-   * under the terms of the license (GNU LGPL) which comes with this package. */
+  * under the terms of the license (GNU LGPL) which comes with this package. */
  
  #ifndef MSG_VM_H
  #define MSG_VM_H
@@@ -22,101 -22,55 +22,101 @@@ msg_vm_t jvm_get_native(JNIEnv *env, jo
   */
  JNIEXPORT void JNICALL
  Java_org_simgrid_msg_VM_nativeInit(JNIEnv *env, jclass);
 +
  /**
   * Class                      org_simgrid_msg_VM
 - * Method                     start
 - * Signature  (I)V
 + * Method                     isCreated
 + * Signature  ()B
   */
 -JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_start(JNIEnv *env, jobject jvm, jobject jhost, jstring jname, jint jcoreamount);
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isCreated(JNIEnv *env, jobject jvm);
  /**
 - * Class            org_simgrid_msg_VM
 - * Method           destroy
 - * Signature    ()V
 + * Class                      org_simgrid_msg_VM
 + * Method                     isRunning
 + * Signature  ()B
   */
 -JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_destroy(JNIEnv *env, jobject jvm);
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isRunning(JNIEnv *env, jobject jvm);
 +/**
 + * Class                      org_simgrid_msg_VM
 + * Method                     isMigrating
 + * Signature  ()B
 + */
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isMigrating(JNIEnv *env, jobject jvm);
  /**
   * Class                      org_simgrid_msg_VM
   * Method                     isSuspended
   * Signature  ()B
   */
 -JNIEXPORT jboolean JNICALL
 +JNIEXPORT jint JNICALL
  Java_org_simgrid_msg_VM_isSuspended(JNIEnv *env, jobject jvm);
  /**
   * Class                      org_simgrid_msg_VM
 - * Method                     isRunning
 + * Method                     isResuming
   * Signature  ()B
   */
 -JNIEXPORT jboolean JNICALL
 -Java_org_simgrid_msg_VM_isRunning(JNIEnv *env, jobject jvm);
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isResuming(JNIEnv *env, jobject jvm);
 +/**
 + * Class                      org_simgrid_msg_VM
 + * Method                     isSuspended
 + * Signature  ()B
 + */
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isSaving(JNIEnv *env, jobject jvm);
  /**
   * Class                      org_simgrid_msg_VM
 - * Method                     bind
 - * Signature  (Lorg/simgrid/msg/Process;)V
 + * Method                     isSave
 + * Signature  ()B
 + */
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isSaved(JNIEnv *env, jobject jvm);
 +/**
 + * Class                      org_simgrid_msg_VM
 + * Method                     isResuming
 + * Signature  ()B
 + */
 +JNIEXPORT jint JNICALL
 +Java_org_simgrid_msg_VM_isRestoring(JNIEnv *env, jobject jvm);
 +/**
 + * Class                      org_simgrid_msg_VM
 + * Method                     setBound
 + * Signature  ()B
 + */
 +JNIEXPORT void JNICALL
 +Java_org_simgrid_msg_VM_setBound(JNIEnv *env, jobject jvm, jint load); 
 +
 +/**
 + * Class            org_simgrid_msg_VM
 + * Method           create
 + * Signature    ()V
   */
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_bind(JNIEnv *env, jobject jvm, jobject jprocess);
 +Java_org_simgrid_msg_VM_create(JNIEnv *env, jobject jvm, jobject jhost, jstring jname,
 +                             jint jncore, jint jramsize, jint jnetcap, jstring jdiskpath, jint jdisksize, jint dprate, jint mig_netspeed);
 +
 +/**
 + * Class            org_simgrid_msg_VM
 + * Method           destroy
 + * Signature    ()V
 + */
 +JNIEXPORT void JNICALL
 +Java_org_simgrid_msg_VM_destroy(JNIEnv *env, jobject jvm);
  /**
   * Class                      org_simgrid_msg_VM
 - * Method                     unbind
 - * Signature  (Lorg/simgrid/msg/Process;)V
 + * Method                     start
 + * Signature  (I)V
   */
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_unbind(JNIEnv *env, jobject jvm, jobject jprocess);
 +Java_org_simgrid_msg_VM_start(JNIEnv *env, jobject jvm);
  /**
   * Class                      org_simgrid_msg_VM
 - * Method                     migrate
 + * Method                     nativeMigrate
   * Signature  (Lorg/simgrid/msg/Host;)V
   */
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_migrate(JNIEnv *env, jobject jvm, jobject jhost);
 +Java_org_simgrid_msg_VM_internalmig(JNIEnv *env, jobject jvm, jobject jhost);
  /**
   * Class                      org_simgrid_msg_VM
   * Method                     suspend
@@@ -140,18 -94,11 +140,18 @@@ JNIEXPORT void JNICAL
  Java_org_simgrid_msg_VM_shutdown(JNIEnv *env, jobject jvm);
  /**
   * Class            org_simgrid_msg_VM
 - * Method           reboot
 + * Method           save
 + * Signature    ()V
 + */
 +JNIEXPORT void JNICALL
 +Java_org_simgrid_msg_VM_save(JNIEnv *env, jobject jvm);
 +/**
 + * Class            org_simgrid_msg_VM
 + * Method           save
   * Signature    ()V
   */
  JNIEXPORT void JNICALL
 -Java_org_simgrid_msg_VM_reboot(JNIEnv *env, jobject jvm);
 +Java_org_simgrid_msg_VM_restore(JNIEnv *env, jobject jvm);
  
  JNIEXPORT jobject JNICALL
  Java_org_simgrid_msg_VM_get_pm(JNIEnv *env, jobject jvm);
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * Bindings to the MSG hosts
   *
-  * Copyright 2006-2012 The SimGrid Team           
+  * Copyright (c) 2006-2013. The SimGrid Team.
   * All right reserved. 
   *
   * This program is free software; you can redistribute 
@@@ -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 String getName() {
                return name;
        }
 +
        /**
         * Sets the data of the host.
       * @param data
                return null != this.data;
        }
  
 +      /**
 +       * This method start the host if it is off
 +       */ 
 +      public native void on();
 +
 +      /**
 +       * This method stop the host if it is on
 +       */ 
 +      public native void off();
 +
 +
        /**
         * This method returns the number of tasks currently running on a host.
         * The external load is not taken in account.
         * @return                      The speed of the processor of the host in flops.
         *
         */ 
-       public native double getCore();
+       public native double getCoreNumber();
  
        /**
         * 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();
@@@ -1,5 -1,5 +1,5 @@@
  /*
-  * Copyright 2006-2012 The SimGrid Team.           
+  * Copyright (c) 2006-2013. The SimGrid Team.
   * All right reserved. 
   *
   * This program is free software; you can redistribute 
@@@ -168,11 -168,6 +168,11 @@@ public class Task 
       * @throws TaskCancelledException
       */
        public native void execute() throws HostFailureException,TaskCancelledException;
 +      /**
 +       * Bound a computation to a certain load
 +       *
 +       */
 +      public native void setBound(double load); 
        /**
         * Cancels a task.
         *
@@@ -1,7 -1,7 +1,7 @@@
  /*
 - * JNI interface to Cloud interface in Simgrid
 + * JNI interface to virtual machine in Simgrid
   * 
-  * Copyright 2006-2012 The SimGrid Team.           
+  * Copyright (c) 2006-2013. The SimGrid Team.
   * All right reserved. 
   *
   * This program is free software; you can redistribute 
@@@ -13,154 -13,61 +13,154 @@@ package org.simgrid.msg
  import org.simgrid.msg.Host;
  import org.simgrid.msg.Process;
  
 -public class VM {
 -      /**
 -       * This attribute represents a bind between a java task object and
 -       * a native task. Even if this attribute is public you must never
 -       * access to it. It is set automatically during the build of the object.
 -       */
 -      private long bind = 0;
 +public class VM extends Host{
 +      // Please note that we are not declaring a new bind variable 
 +      //(the bind variable has been inherited from the super class Host)
 +      
 +      /* Static functions */ 
 +      // GetByName is inherited from the super class Host
        
 -      private int coreAmount;
  
 -        private String name;
 +       private static VM[] vms=null;    
 +    private Host currentHost; 
 +
 +      /* Constructors / destructors */
 +    /**
 +       * Create a `basic' VM (i.e. 1 core, 1GB of RAM, other values are not taken into account).
 +       */
 +      public VM(Host host, String name) {
 +              this(host,name,1,1024, -1, null, -1,0 , 0);
 +      }
 +
        /**
 -       * Create a new empty VM.
 -       * NOTE: it is expected that in the future, the coreAmount parameter will be used
 -       * to add extra constraints on the execution, but the argument is ignored for now.
 +       * Create a  VM
 +       * @param host, Host node
 +       * @param name, name of the machine
 +       * @param nCore, number of core
 +       * @param ramSize, size of the RAM that should be allocated (in MBytes) 
 +       * @param netCap (not used for the moment)
 +       * @param diskPath (not used for the moment)
 +       * @param diskSize (not used for the moment)
 +       * @param migNetSpeed (network bandwith allocated for migrations in MB/s, if you don't know put zero ;))
 +       * @param dpIntensity (dirty page percentage according to migNetSpeed, [0-100], if you don't know put zero ;))
         */
 -      public VM(Host host, String name, int coreAmount) {
 -              this.coreAmount = coreAmount;
 -              this.name = name;
 -              start(host,name,coreAmount);
 +      
 +      public VM(Host host, String name, int nCore,  int ramSize, 
 +                      int netCap, String diskPath, int diskSize, int migNetSpeed, int dpIntensity){
 +              super();
 +              super.name = name; 
 +              this.currentHost = host; 
 +              create(host, name, nCore, ramSize, netCap, diskPath, diskSize, migNetSpeed, dpIntensity);
 +              VM.addVM(this);
 +      }
 +
 +      private static void addVM(VM vm){
 +              VM[] vmsN=null; 
 +              int i=0;
 +              if(VM.vms == null)
 +                      vmsN = new VM[1]; 
 +              else
 +                      vmsN = new VM[vms.length+1]; 
 +              
 +              for (i=0; i<vmsN.length-1 ; i ++){
 +                      vmsN[i]=vms[i]; 
 +              } 
 +              vmsN[i]=vm;
 +              vms=vmsN;
 +      }
 +   public static VM[] all(){
 +              return vms;
 +      }
 +      public static VM getVMByName(String name){
 +              for (int i=0 ; i < vms.length ; i++){
 +                        if (vms[i].getName().equals(name))
 +                                      return vms[i];          
 +              }
 +              return null; 
        }
        protected void finalize() {
                destroy();
        }
 -      /**
 -       * Destroy the VM
 -       */
 -      protected native void destroy();
 -      /**
 -       * Natively implemented method starting the VM.
 -       * @param coreAmount
 -       */
 -      private native void start(Host host, String name, int coreAmount);
 -              
 +      
 +
 +      /* JNI / Native code */
 +
 +      /* get/set property methods are inherited from the Host class. */
 +      
        /** Returns whether the given VM is currently suspended
         */     
 -      public native boolean isSuspended();
 +      public native int isCreated();
 +      
        /** Returns whether the given VM is currently running
         */
 -      public native boolean isRunning();
 -      /** Add the given process into the VM.
 -       * Afterward, when the VM is migrated or suspended or whatever, the process will have the corresponding handling, too.
 -       */     
 -      public native void bind(Process process);
 -      /** Removes the given process from the given VM, and kill it
 -       *  Will raise a ProcessNotFound exception if the process were not bound to that VM
 +      public native int isRunning();
 +
 +      /** Returns whether the given VM is currently running
 +       */
 +      public native int isMigrating();
 +      
 +      /** Returns whether the given VM is currently suspended
         */     
 -      public native void unbind(Process process);
 -      /** Immediately change the host on which all processes are running
 -       *
 -       * No migration cost occurs. If you want to simulate this too, you want to use a
 -       * Task.send() before or after, depending on whether you want to do cold or hot
 -       * migration.
 +      public native int isSuspended();
 +              
 +      /** Returns whether the given VM is currently saving
 +       */
 +      public native int isSaving();
 +      
 +      /** Returns whether the given VM is currently saved
 +       */
 +      public native int isSaved();
 +
 +      /** Returns whether the given VM is currently restoring its state
 +       */
 +      public native boolean isRestoring();
 +      
 +      /**
 +       * Natively implemented method create the VM.
 +       * @param nCore, number of core
 +       * @param ramSize, size of the RAM that should be allocated (in MB) 
 +       * @param netCap (not used for the moment)
 +       * @param diskPath (not used for the moment)
 +       * @param diskSize (not used for the moment)
 +       * @param migNetSpeed (network bandwith allocated for migrations in MB/s, if you don't know put zero ;))
 +       * @param dpIntensity (dirty page intensity, a percentage of migNetSpeed [0-100],  if you don't know put zero ;))
 +       */
 +      private native void create(Host host, String name, int nCore, int ramSize, 
 +                       int netCap, String diskPath, int diskSize, int migNetSpeed, int dpIntensity);
 +
 +
 +      /**
 +       * Bound the VM to a certain % of its vcpu capability (e.g. 75% of vm.getSpeed())
 +       * @param load, percentage (between [0,100]
 +       */
 +      public native void setBound(int load);
 +
 +      /**
 +       * start the VM
 +       */
 +      public native void start();
 +
 +      
 +      /**
 +       * Immediately kills all processes within the given VM. Any memory that they allocated will be leaked.
 +       * No extra delay occurs. If you want to simulate this too, you want to use a MSG_process_sleep() or something
 +       */
 +      public native void shutdown();
 +      
 +      /**  
 +       * Invoke native migration routine
 +      */
 +      public native void internalmig(Host destination);
 +
 +      
 +      /** Change the host on which all processes are running
 +       * (pre-copy is implemented)
         */     
 -      public native void migrate(Host destination);
 +      public void migrate(Host destination){
 +              this.internalmig(destination);
 +              this.currentHost = destination; 
 +      }
 +      
        /** Immediately suspend the execution of all processes within the given VM
         *
         * No suspension cost occurs. If you want to simulate this too, you want to
         * of VM suspend to you.
         */     
        public native void suspend();
 +      
        /** Immediately resumes the execution of all processes within the given VM
         *
         * No resume cost occurs. If you want to simulate this too, you want to
         * of VM resume to you.
         */
        public native void resume();
 -      /**
 -       * Immediately kills all processes within the given VM. Any memory that they allocated will be leaked.
 -       * No extra delay occurs. If you want to simulate this too, you want to use a MSG_process_sleep() or something
 +      
 +      /** Immediately suspend the execution of all processes within the given VM 
 +       *  and save its state on the persistent HDD
 +       *  Not yet implemented (for the moment it behaves like suspend)
 +       *  No suspension cost occurs. If you want to simulate this too, you want to
 +       *  use a \ref File.write() before or after, depending on the exact semantic
 +       *  of VM suspend to you.
 +       */     
 +      public native void save();
 +      
 +      /** Immediately resumes the execution of all processes previously saved 
 +       * within the given VM
 +       *  Not yet implemented (for the moment it behaves like resume)
 +       *
 +       * No resume cost occurs. If you want to simulate this too, you want to
 +       * use a \ref File.read() before or after, depending on the exact semantic
 +       * of VM resume to you.
         */
 -      public native void shutdown();
 +      public native void restore();
 +      
 +
        /**
 -       * Reboot the VM, restarting all the processes in it.
 +       * Destroy the VM
         */
 -      public native void reboot();
 +      public native void destroy();
  
 -      public String getName() {
 -              return name;
 -      }               
 +      
  
        /**
         * Class initializer, to initialize various JNI stuff
@@@ -1,6 -1,6 +1,6 @@@
  /* context_java - implementation of context switching for java threads */
  
- /* Copyright (c) 2009, 2010, 2012. The SimGrid Team.
+ /* Copyright (c) 2009-2010, 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -111,23 -111,18 +111,23 @@@ static void* smx_ctx_java_thread_run(vo
      (*env)->SetLongField(env, context->jprocess, jprocess_field_Process_bind,
                           (intptr_t)process);
    }
 -  xbt_assert((context->jprocess != NULL), "Process not created...");
 -  //wait for the process to be able to begin
 -  //TODO: Cache it
 +
 +  // Adrien, ugly path, just to bypass creation of context at low levels
 +  // (i.e such as for the VM migration for instance)
 +  if(context->jprocess != NULL){
 +      xbt_assert((context->jprocess != NULL), "Process not created...");
 +      //wait for the process to be able to begin
 +      //TODO: Cache it
        jfieldID jprocess_field_Process_startTime = jxbt_get_sfield(env, "org/simgrid/msg/Process", "startTime", "D");
 -  jdouble startTime =  (*env)->GetDoubleField(env, context->jprocess, jprocess_field_Process_startTime);
 -  if (startTime > MSG_get_clock()) {
 -      MSG_process_sleep(startTime - MSG_get_clock());
 +      jdouble startTime =  (*env)->GetDoubleField(env, context->jprocess, jprocess_field_Process_startTime);
 +      if (startTime > MSG_get_clock()) {
 +              MSG_process_sleep(startTime - MSG_get_clock());
 +      }
 +      //Execution of the "run" method.
 +      jmethodID id = jxbt_get_smethod(env, "org/simgrid/msg/Process", "run", "()V");
 +      xbt_assert( (id != NULL), "Method not found...");
 +      (*env)->CallVoidMethod(env, context->jprocess, id);
    }
 -  //Execution of the "run" method.
 -  jmethodID id = jxbt_get_smethod(env, "org/simgrid/msg/Process", "run", "()V");
 -  xbt_assert( (id != NULL), "Method not found...");
 -  (*env)->CallVoidMethod(env, context->jprocess, id);
    smx_ctx_java_stop((smx_context_t)context);
  
    return NULL;
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2010. The SimGrid Team.
+ /* Copyright (c) 2010, 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -184,7 -184,7 +184,7 @@@ static int l_host_sleep(lua_State *L
  static int l_host_destroy(lua_State *L)
  {
    msg_host_t ht = sglua_check_host(L, 1);
 -  __MSG_host_destroy(MSG_host_priv(ht));
 +  __MSG_host_priv_free(MSG_host_priv(ht));
    return 0;
  }
  
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. 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
@@@ -42,6 -42,8 +42,8 @@@ int lmm_constraint_is_shared(lmm_constr
  
  void lmm_constraint_free(lmm_system_t sys, lmm_constraint_t cnst);
  
+ double lmm_constraint_get_usage(lmm_constraint_t cnst);
  XBT_PUBLIC(lmm_variable_t) lmm_variable_new(lmm_system_t sys, void *id,
                                              double weight_value,
                                              double bound,
@@@ -50,8 -52,6 +52,8 @@@ XBT_PUBLIC(void) lmm_variable_free(lmm_
  XBT_PUBLIC(double) lmm_variable_getvalue(lmm_variable_t var);
  XBT_PUBLIC(double) lmm_variable_getbound(lmm_variable_t var);
  
 +XBT_PUBLIC(void) lmm_shrink(lmm_system_t sys, lmm_constraint_t cnst,
 +                            lmm_variable_t var);
  XBT_PUBLIC(void) lmm_expand(lmm_system_t sys, lmm_constraint_t cnst,
                              lmm_variable_t var, double value);
  void lmm_expand_add(lmm_system_t sys, lmm_constraint_t cnst,
diff --combined src/include/surf/surf.h
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. 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
@@@ -79,13 -79,6 +79,6 @@@ 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
   *
@@@ -99,7 -92,6 +92,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
@@@ -206,11 -193,14 +199,16 @@@ 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);
+   double (*get_current_power_peak) (void *cpu);
+   double (*get_power_peak_at) (void *cpu, int pstate_index);
+   int (*get_nb_pstates) (void *cpu);
+   void (*set_power_peak_at) (void *cpu, int pstate_index);
+   double (*get_consumed_energy) (void *cpu);
    void (*add_traces) (void);
  } s_surf_model_extension_cpu_t;
  
@@@ -243,31 -233,37 +241,40 @@@ 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);
    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(*read) (void *storage, surf_file_t fd, sg_storage_size_t size);
+   surf_action_t(*write) (void *storage, surf_file_t fd, sg_storage_size_t size);
    surf_action_t(*stat) (void *storage, surf_file_t fd);
    surf_action_t(*ls) (void *storage, const char *path);
+   xbt_dict_t(*get_properties) (const void *storage);
+   xbt_dict_t(*get_content) (void *storage);
+   sg_storage_size_t(*get_size) (void *storage);
  } 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 */
+   double (*get_current_power_peak) (void *workstation);                                         /**< Return the current CPU speed of a workstation */
+   double (*get_power_peak_at) (void *workstation, int pstate_index);                    /**< Return the speed of a workstation for a specific pstate,
+                                                                                                (where higher pstate values represent lower processor speeds) */
+   int (*get_nb_pstates) (void *workstation);                                            /**< Return the number of pstates defined for a workstation (default is 1) */
+   void (*set_power_peak_at) (void *workstation, int pstate_index);                      /**< Set the processor speed of a workstation to the speed associated with the pstate_index pstate */
+   double (*get_consumed_energy) (void *workstation);                                    /**< Return the total energy consumed by a workstation */
     surf_action_t(*communicate) (void *workstation_src,                                     /**< Execute a communication amount between two workstations */
                                  void *workstation_dst, double size,
                                  double max_rate);
    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(*read) (void *workstation, surf_file_t fd, sg_storage_size_t size);
+   surf_action_t(*write) (void *workstation, surf_file_t fd, sg_storage_size_t size);
    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);
+   sg_storage_size_t (*get_size) (void *workstation, surf_file_t fd);
+   xbt_dynar_t (*get_info) (void *workstation, surf_file_t fd);
  
    int (*link_shared) (const void *link);
-    xbt_dict_t(*get_properties) (const void *resource);
+   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);
 +
+   sg_storage_size_t (*get_free_size) (void *workstation,const char* name);
+   sg_storage_size_t (*get_used_size) (void *workstation,const char* name);
+   xbt_dict_t (*get_storage_list) (void *workstation);
  } 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()
 +  void   (*set_vm_affinity) (void *ind_vm_ws, void *ind_pm_ws, unsigned long mask); // will be vm_ws_set_vm_affinity()
 +
 +} 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
@@@ -363,9 -311,7 +372,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 */
 +
 +  /* Note (hypervisor): set_affinity() may be used only in CPU models. It might
 +   * be better to move this member to the extension field.
 +   **/
 +  void (*set_affinity) (surf_action_t action, void *workstation, unsigned long mask);     /**< Set the CPU affinity 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;
@@@ -424,8 -361,8 +433,8 @@@ static inline void *surf_cpu_resource_p
  static inline void *surf_workstation_resource_priv(const void *host){
    return xbt_lib_get_level((void *)host, SURF_WKS_LEVEL);
  }
- static inline void *surf_storage_resource_priv(const void *host){
-   return xbt_lib_get_level((void *)host, SURF_STORAGE_LEVEL);
+ static inline void *surf_storage_resource_priv(const void *storage){
+   return xbt_lib_get_level((void *)storage, SURF_STORAGE_LEVEL);
  }
  
  static inline void *surf_cpu_resource_by_name(const char *name) {
@@@ -438,15 -375,13 +447,20 @@@ 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;
+   void_f_pvoid_t free_f;
+ } 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
   */
@@@ -470,14 -405,9 +484,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;
 +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_vm;
  
  /** \ingroup SURF_models
   *  \brief Initializes the CPU model with the model Cas01
@@@ -496,7 -426,7 +510,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).
@@@ -658,6 -588,8 +672,8 @@@ XBT_PUBLIC(void) surf_storage_model_ini
   */
  XBT_PUBLIC_DATA(s_surf_model_description_t) surf_storage_model_description[];
  
+ XBT_PUBLIC_DATA(surf_model_t) surf_storage_model;
  /** \ingroup SURF_models
   *  \brief The workstation model
   *
   */
  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
   *
@@@ -726,8 -648,17 +742,18 @@@ 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;
  
+ /** \ingroup SURF_simulation
+  *  \brief List of hosts that have juste restarted and whose autorestart process should be restarted.
+  */
+ XBT_PUBLIC_DATA(xbt_dynar_t) host_that_restart;
+ /** \ingroup SURF_simulation
+  *  \brief List of hosts for which one want to be notified if they ever restart.
+  */
+ XBT_PUBLIC(xbt_dict_t) watched_hosts_lib;
  /*******************************************/
  /*** SURF Platform *************************/
  /*******************************************/
@@@ -815,8 -746,6 +841,6 @@@ XBT_PUBLIC(xbt_dict_t) get_as_router_pr
  int surf_get_nthreads(void);
  void surf_set_nthreads(int nthreads);
  
- void surf_watched_hosts(void);
  /*
   * Returns the initial path. On Windows the initial path is
   * the current directory for the current process in the other
diff --combined src/msg/instr_msg_vm.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2012. The SimGrid Team.
+ /* Copyright (c) 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -13,7 -13,7 +13,7 @@@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_
  
  char *instr_vm_id (msg_vm_t vm, char *str, int len)
  {
 -  return instr_vm_id_2 (vm->name, str, len);
 +      return instr_vm_id_2 (MSG_vm_get_name(vm), str, len);
  }
  
  char *instr_vm_id_2 (const char *vm_name, char *str, int len)
@@@ -55,7 -55,7 +55,7 @@@ void TRACE_msg_vm_change_host(msg_vm_t 
    }
  }
  
 -void TRACE_msg_vm_create (const char *vm_name, msg_host_t host)
 +void TRACE_msg_vm_create(const char *vm_name, msg_host_t host)
  {
    if (TRACE_msg_vm_is_enabled()){
      int len = INSTR_DEFAULT_STR_SIZE;
    }
  }
  
 +void TRACE_msg_vm_start(msg_vm_t vm)
 +{
 +  if (TRACE_msg_vm_is_enabled()){
 +    int len = INSTR_DEFAULT_STR_SIZE;
 +    char str[INSTR_DEFAULT_STR_SIZE];
 +
 +    container_t vm_container = PJ_container_get (instr_vm_id(vm, str, len));
 +    type_t type = PJ_type_get ("MSG_VM_STATE", vm_container->type);
 +    val_t value = PJ_value_get ("start", type);
 +    new_pajePushState (MSG_get_clock(), vm_container, type, value);
 +  }
 +
 +}
 +
  void TRACE_msg_vm_kill(msg_vm_t vm) {
    if (TRACE_msg_vm_is_enabled()) {
      int len = INSTR_DEFAULT_STR_SIZE;
@@@ -117,7 -103,7 +117,7 @@@ void TRACE_msg_vm_resume(msg_vm_t vm
    }
  }
  
 -void TRACE_msg_vm_sleep_in(msg_vm_t vm)
 +void TRACE_msg_vm_save(msg_vm_t vm)
  {
    if (TRACE_msg_vm_is_enabled()){
      int len = INSTR_DEFAULT_STR_SIZE;
  
      container_t vm_container = PJ_container_get (instr_vm_id(vm, str, len));
      type_t type = PJ_type_get ("MSG_VM_STATE", vm_container->type);
 -    val_t value = PJ_value_get ("sleep", type);
 +    val_t value = PJ_value_get ("save", type);
      new_pajePushState (MSG_get_clock(), vm_container, type, value);
    }
  }
  
 -void TRACE_msg_vm_sleep_out(msg_vm_t vm)
 +void TRACE_msg_vm_restore(msg_vm_t vm)
  {
    if (TRACE_msg_vm_is_enabled()){
      int len = INSTR_DEFAULT_STR_SIZE;
diff --combined src/msg/msg_global.c
@@@ -1,4 -1,5 +1,5 @@@
- /* Copyright (c) 2004-2012. The SimGrid Team.  All rights reserved.         */
+ /* Copyright (c) 2004-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
@@@ -37,6 -38,7 +38,6 @@@ void MSG_init_nocheck(int *argc, char *
  
    xbt_getpid = MSG_process_self_PID;
    if (!msg_global) {
 -    s_msg_vm_t vm; // to compute the offset
  
      SIMIX_global_init(argc, argv);
      
@@@ -48,6 -50,7 +49,6 @@@
      msg_global->sent_msg = 0;
      msg_global->task_copy_callback = NULL;
      msg_global->process_data_cleanup = NULL;
 -    msg_global->vms = xbt_swag_new(xbt_swag_offset(vm,all_vms_hookup));
  
      /* initialization of the action module */
      _MSG_action_init();
  #endif
  
    XBT_DEBUG("ADD MSG LEVELS");
 -  MSG_HOST_LEVEL = xbt_lib_add_level(host_lib, (void_f_pvoid_t) __MSG_host_destroy);
 +  MSG_HOST_LEVEL = xbt_lib_add_level(host_lib, (void_f_pvoid_t) __MSG_host_priv_free);
+   MSG_STORAGE_LEVEL = xbt_lib_add_level(storage_lib, (void_f_pvoid_t) __MSG_storage_destroy);
  
-   atexit(MSG_exit);
+   if(sg_cfg_get_boolean("clean_atexit")) atexit(MSG_exit);
  }
  
  #ifdef MSG_USE_DEPRECATED
@@@ -132,7 -136,7 +134,7 @@@ msg_error_t MSG_main(void
   * Do --help on any simgrid binary to see the list of currently existing configuration variables, and see Section @ref options.
   *
   * Example:
-  * MSG_config("workstation/model","KCCFLN05");
+  * MSG_config("workstation/model","ptask_L07");
   */
  void MSG_config(const char *key, const char *value){
    xbt_assert(msg_global,"ERROR: Please call MSG_init() before using MSG_config()");
@@@ -173,6 -177,7 +175,6 @@@ static void MSG_exit(void) 
    TRACE_end();
  #endif
  
 -  xbt_swag_free(msg_global->vms);
    free(msg_global);
    msg_global = NULL;
  }
diff --combined src/msg/msg_gos.c
@@@ -1,4 -1,5 +1,5 @@@
- /* Copyright (c) 2004-2012. The SimGrid Team. All rights reserved.          */
+ /* Copyright (c) 2004-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
@@@ -23,15 -24,7 +24,15 @@@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_gos
   */
  msg_error_t MSG_task_execute(msg_task_t task)
  {
 -  return MSG_parallel_task_execute(task);
 +  /* TODO: add this to other locations */
 +  msg_host_t host = MSG_process_get_host(MSG_process_self());
 +  MSG_host_add_task(host, task);
 +
 +  msg_error_t ret = MSG_parallel_task_execute(task);
 +
 +  MSG_host_del_task(host, task);
 +
 +  return ret;
  }
  
  /** \ingroup msg_task_usage
@@@ -82,16 -75,10 +83,16 @@@ msg_error_t MSG_parallel_task_execute(m
                                                         1.0, -1.0);
        XBT_DEBUG("Parallel execution action created: %p", simdata->compute);
      } else {
 +      unsigned long affinity_mask = (unsigned long) xbt_dict_get_or_null_ext(simdata->affinity_mask_db, (char *) p_simdata->m_host, sizeof(msg_host_t));
 +      XBT_INFO("execute %s@%s with affinity(0x%04lx)", MSG_task_get_name(task), MSG_host_get_name(p_simdata->m_host), affinity_mask);
 +
        simdata->compute = simcall_host_execute(task->name,
                                                p_simdata->m_host,
                                                simdata->computation_amount,
 -                                              simdata->priority);
 +                                              simdata->priority,
 +                                              simdata->bound,
 +                                              affinity_mask
 +                                              );
  
      }
  #ifdef HAVE_TRACING
      case cancel_error:
        status = MSG_TASK_CANCELED;
        break;
+     case host_error:
+       status = MSG_HOST_FAILURE;
+       break;
      default:
        RETHROW;
      }
diff --combined src/msg/msg_host.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. 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
@@@ -13,7 -13,7 +13,7 @@@
  XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(msg);
  
  /** @addtogroup m_host_management
-  *     \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Hosts" --> \endhtmlonly
+  * \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Hosts" --> \endhtmlonly
   * (#msg_host_t) and the functions for managing it.
   *  
   *  A <em>location</em> (or <em>host</em>) is any possible place where
  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;
 +
 +  priv->affinity_mask_db = xbt_dict_new_homogeneous(NULL);
 +
 +  xbt_lib_set(host_lib, name, MSG_HOST_LEVEL, priv);
    
    return xbt_lib_get_elm_or_null(host_lib, name);
  }
@@@ -118,54 -114,20 +118,54 @@@ 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_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_destroy(msg_host_priv_t host) {
 +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);
 +  xbt_dict_free(&priv->affinity_mask_db);
  
  #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
@@@ -242,15 -204,32 +242,32 @@@ double MSG_get_host_speed(msg_host_t h
  
  
  /** \ingroup m_host_management
-  * \brief Return the number of core.
+  * \brief Return the number of cores.
+  *
+  * \param host a host
+  * \return the number of cores
   */
- int MSG_get_host_core(msg_host_t h)
+ int MSG_host_get_core_number(msg_host_t host)
  {
-   xbt_assert((h != NULL), "Invalid parameters");
+   xbt_assert((host != NULL), "Invalid parameters");
+   return (simcall_host_get_core(host));
+ }
+ /** \ingroup m_host_management
+  * \brief Return the list of processes attached to an host.
+  *
+  * \param host a host
+  * \return a swag with the attached processes
+  */
+ xbt_swag_t MSG_host_get_process_list(msg_host_t host)
+ {
+   xbt_assert((host != NULL), "Invalid parameters");
  
-   return (simcall_host_get_core(h));
+   return (simcall_host_get_process_list(host));
  }
  
  /** \ingroup m_host_management
   * \brief Returns the value of a given host property
   *
@@@ -301,25 -280,95 +318,116 @@@ 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);
 +}
+ /** \ingroup m_host_management
+  * \brief Return the speed of the processor (in flop/s) at a given pstate
+  *
+  * \param  host host to test
+  * \param pstate_index pstate to test
+  * \return Returns the processor speed associated with pstate_index
+  */
+ double MSG_get_host_power_peak_at(msg_host_t host, int pstate_index) {
+         xbt_assert((host != NULL), "Invalid parameters (host is NULL)");
+         return (simcall_host_get_power_peak_at(host, pstate_index));
+ }
+ /** \ingroup m_host_management
+  * \brief Return the current speed of the processor (in flop/s)
+  *
+  * \param  host host to test
+  * \return Returns the current processor speed
+  */
+ double MSG_get_host_current_power_peak(msg_host_t host) {
+         xbt_assert((host != NULL), "Invalid parameters (host is NULL)");
+         return simcall_host_get_current_power_peak(host);
+ }
+ /** \ingroup m_host_management
+  * \brief Return the number of pstates defined for a host
+  *
+  * \param  host host to test
+  */
+ int MSG_get_host_nb_pstates(msg_host_t host) {
+         xbt_assert((host != NULL), "Invalid parameters (host is NULL)");
+         return (simcall_host_get_nb_pstates(host));
+ }
+ /** \ingroup m_host_management
+  * \brief Sets the speed of the processor (in flop/s) at a given pstate
+  *
+  * \param  host host to test
+  * \param pstate_index pstate to switch to
+  */
+ void MSG_set_host_power_peak_at(msg_host_t host, int pstate_index) {
+         xbt_assert((host != NULL), "Invalid parameters (host is NULL)");
+         simcall_host_set_power_peak_at(host, pstate_index);
+ }
+ /** \ingroup m_host_management
+  * \brief Return the total energy consumed by a host (in Joules)
+  *
+  * \param  host host to test
+  * \return Returns the consumed energy
+  */
+ double MSG_get_host_consumed_energy(msg_host_t host) {
+         xbt_assert((host != NULL), "Invalid parameters (host is NULL)");
+         return simcall_host_get_consumed_energy(host);
+ }
+ /** \ingroup m_host_management
+  * \brief Return the list of mount point names on an host.
+  * \param host a host
+  * \return a dict containing all mount point on the host (mount_name => msg_storage_t)
+  */
+ xbt_dict_t MSG_host_get_storage_list(msg_host_t host)
+ {
+   xbt_assert((host != NULL), "Invalid parameters");
+   return (simcall_host_get_storage_list(host));
+ }
+ /** \ingroup msg_host_management
+  * \brief Return the content of mounted storages on an host.
+  * \param host a host
+  * \return a dict containing content (as a dict) of all storages mounted on the host
+  */
+ xbt_dict_t MSG_host_get_storage_content(msg_host_t host)
+ {
+   xbt_assert((host != NULL), "Invalid parameters");
+   xbt_dict_t contents = xbt_dict_new_homogeneous(NULL);
+   msg_storage_t storage;
+   char* storage_name;
+   char* mount_name;
+   xbt_dict_cursor_t cursor = NULL;
+   xbt_dict_t storage_list = simcall_host_get_storage_list(host);
+   xbt_dict_foreach(storage_list,cursor,mount_name,storage_name){
+       storage = (msg_storage_t)xbt_lib_get_elm_or_null(storage_lib,storage_name);
+       xbt_dict_t content = simcall_storage_get_content(storage);
+       xbt_dict_set(contents,mount_name, content,NULL);
+   }
+   return contents;
+ }
diff --combined src/msg/msg_private.h
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. 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
@@@ -31,12 -31,7 +31,12 @@@ typedef struct simdata_task 
    msg_process_t receiver;
    msg_host_t source;
    double priority;
 -  double rate;
 +  double bound; /* Capping for CPU resource */
 +  double rate;  /* Capping for network resource */
 +
 +  /* CPU affinity database of this task */
 +  xbt_dict_t affinity_mask_db; /* smx_host_t host => unsigned long mask */
 +
    int isused;  /* Indicates whether the task is used in SIMIX currently */
    int host_nb;                  /* ==0 if sequential task; parallel task if not */
    /*******  Parallel Tasks Only !!!! *******/
@@@ -50,6 -45,11 +50,11 @@@ typedef struct simdata_file 
    smx_file_t smx_file;
  } s_simdata_file_t;
  
+ /********************************* Storage **************************************/
+ typedef struct simdata_storage {
+   smx_storage_t smx_storage;
+ } s_simdata_storage_t;
  /*************** Begin GPU ***************/
  typedef struct simdata_gpu_task {
    double computation_amount;    /* Computation size */
@@@ -73,6 -73,8 +78,6 @@@ typedef struct simdata_process 
    int argc;                     /* arguments number if any */
    msg_error_t last_errno;       /* the last value returned by a MSG_function */
  
 -  msg_vm_t vm;                 /* virtual machine the process is in */
 -
    void* data;                   /* user data */
  } s_simdata_process_t, *simdata_process_t;
  
@@@ -92,21 -94,21 +97,21 @@@ typedef struct msg_comm 
    msg_task_t *task_received;      /* where the task will be received (NULL for the sender) */
    msg_error_t status;           /* status of the communication once finished */
  } s_msg_comm_t;
 -/*
 -typedef enum {
 -  msg_vm_state_suspended, msg_vm_state_running, msg_vm_state_migrating
 -} e_msg_vm_state_t;
  
 -typedef struct msg_vm {
 -  const 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 struct dirty_page {
 +  double prev_clock;
 +  double prev_remaining;
 +  msg_task_t task;
 +} s_dirty_page, *dirty_page_t;
 +
 +XBT_PUBLIC_DATA(const char*) MSG_vm_get_property_value(msg_vm_t vm, const char *name);
 +XBT_PUBLIC_DATA(xbt_dict_t) MSG_vm_get_properties(msg_vm_t vm);
 +XBT_PUBLIC_DATA(void) MSG_vm_set_property_value(msg_vm_t vm, const char *name, void *value, void_f_pvoid_t free_ctn);
 +XBT_PUBLIC_DATA(msg_vm_t) MSG_vm_get_by_name(const char *name);
 +XBT_PUBLIC_DATA(const char*) MSG_vm_get_name(msg_vm_t vm);
 +
  /************************** Global variables ********************************/
  typedef struct MSG_Global {
    xbt_fifo_t host;
    unsigned long int sent_msg;   /* Total amount of messages sent during the simulation */
    void (*task_copy_callback) (msg_task_t task, msg_process_t src, msg_process_t dst);
    void_f_pvoid_t process_data_cleanup;
 -  xbt_swag_t vms;
  } s_MSG_Global_t, *MSG_Global_t;
  
  /*extern MSG_Global_t msg_global;*/
@@@ -138,7 -141,9 +143,9 @@@ XBT_PUBLIC_DATA(MSG_Global_t) msg_globa
  #endif
  
  msg_host_t __MSG_host_create(smx_host_t workstation);
 -void __MSG_host_destroy(msg_host_priv_t host);
+ msg_storage_t __MSG_storage_create(smx_storage_t storage);
 +void __MSG_host_destroy(msg_host_t host);
+ void __MSG_storage_destroy(msg_storage_priv_t host);
  
  void MSG_process_cleanup_from_SIMIX(smx_process_t smx_proc);
  void MSG_process_create_from_SIMIX(smx_process_t *process, const char *name,
@@@ -152,13 -157,6 +159,13 @@@ void _MSG_action_exit(void)
  
  void MSG_post_create_environment(void);
  
 +static inline void *msg_host_resource_priv(const void *host) {
 +  return xbt_lib_get_level((void *)host, MSG_HOST_LEVEL);
 +}
 +
 +void MSG_host_add_task(msg_host_t host, msg_task_t task);
 +void MSG_host_del_task(msg_host_t host, msg_task_t task);
 +
  /********** Tracing **********/
  /* declaration of instrumentation functions from msg_task_instr.c */
  void TRACE_msg_set_task_category(msg_task_t task, const char *category);
@@@ -186,17 -184,16 +193,17 @@@ void TRACE_msg_process_sleep_out(msg_pr
  void TRACE_msg_process_end(msg_process_t process);
  
  /* declaration of instrumentation functions from instr_msg_vm.c */
 -char *instr_vm_id (msg_vm_t vm, char *str, int len);
 -char *instr_vm_id_2 (const char *vm_name, char *str, int len);
 +char *instr_vm_id(msg_vm_t vm, char *str, int len);
 +char *instr_vm_id_2(const char *vm_name, char *str, int len);
  void TRACE_msg_vm_change_host(msg_vm_t vm, msg_host_t old_host,
                                     msg_host_t new_host);
 -void TRACE_msg_vm_create (const char *vm_name, msg_host_t host);
 +void TRACE_msg_vm_start(msg_vm_t vm);
 +void TRACE_msg_vm_create(const char *vm_name, msg_host_t host);
  void TRACE_msg_vm_kill(msg_vm_t process);
  void TRACE_msg_vm_suspend(msg_vm_t vm);
  void TRACE_msg_vm_resume(msg_vm_t vm);
 -void TRACE_msg_vm_sleep_in(msg_vm_t vm);
 -void TRACE_msg_vm_sleep_out(msg_vm_t vm);
 +void TRACE_msg_vm_save(msg_vm_t vm);
 +void TRACE_msg_vm_restore(msg_vm_t vm);
  void TRACE_msg_vm_end(msg_vm_t vm);
  
  SG_END_DECL()
diff --combined src/msg/msg_process.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. 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
@@@ -12,7 -12,7 +12,7 @@@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_pro
                                  "Logging specific to MSG (process)");
  
  /** @addtogroup m_process_management
-  *    \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Processes" --> \endhtmlonly
+  * \htmlonly <!-- DOXYGEN_NAVBAR_LABEL="Processes" --> \endhtmlonly
   *
   *  We need to simulate many independent scheduling decisions, so
   *  the concept of <em>process</em> is at the heart of the
@@@ -46,10 -46,16 +46,10 @@@ void MSG_process_cleanup_from_SIMIX(smx
    TRACE_msg_process_end(smx_proc);
  #endif
    // free the data if a function was provided
-   if (msg_proc->data && msg_global->process_data_cleanup) {
+   if (msg_proc && msg_proc->data && msg_global->process_data_cleanup) {
      msg_global->process_data_cleanup(msg_proc->data);
    }
  
 -  // remove the process from its virtual machine
 -  if (msg_proc && 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);
  }
diff --combined src/msg/msg_task.c
@@@ -1,11 -1,10 +1,11 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. 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
   * under the terms of the license (GNU LGPL) which comes with this package. */
  
  #include "msg_private.h"
 +#include "simix/smx_private.h"
  #include "xbt/sysdep.h"
  #include "xbt/log.h"
  
@@@ -63,8 -62,6 +63,8 @@@ msg_task_t MSG_task_create(const char *
    simdata->receiver = NULL;
    simdata->source = NULL;
    simdata->priority = 1.0;
 +  simdata->bound = 0;
 +  simdata->affinity_mask_db = xbt_dict_new_homogeneous(NULL);
    simdata->rate = -1.0;
    simdata->isused = 0;
  
@@@ -286,8 -283,6 +286,8 @@@ msg_error_t MSG_task_destroy(msg_task_
    /* parallel tasks only */
    xbt_free(task->simdata->host_list);
  
 +  xbt_dict_free(&task->simdata->affinity_mask_db);
 +
    /* free main structures */
    xbt_free(task->simdata);
    xbt_free(task);
@@@ -443,90 -438,3 +443,90 @@@ void MSG_task_set_priority(msg_task_t t
      simcall_host_execution_set_priority(task->simdata->compute,
                                        task->simdata->priority);
  }
 +
 +
 +/** \ingroup m_task_management
 + * \brief Changes the maximum CPU utilization of a computation task.
 + *        Unit is flops/s.
 + *
 + * For VMs, there is a pitfall. Please see MSG_vm_set_bound().
 + */
 +void MSG_task_set_bound(msg_task_t task, double bound)
 +{
 +  xbt_assert(task, "Invalid parameter");
 +  xbt_assert(task->simdata, "Invalid parameter");
 +
 +  if (bound == 0)
 +    XBT_INFO("bound == 0 means no capping (i.e., unlimited).");
 +
 +  task->simdata->bound = bound;
 +  if (task->simdata->compute)
 +    simcall_host_execution_set_bound(task->simdata->compute,
 +                                      task->simdata->bound);
 +}
 +
 +
 +/** \ingroup m_task_management
 + * \brief Changes the CPU affinity of a computation task.
 + *
 + * When pinning the given task to the first CPU core of the given host, use
 + * 0x01 for the mask value. Each bit of the mask value corresponds to each CPU
 + * core. See taskset(1) on Linux.
 + *
 + * \param task a target task
 + * \param host the host having a multi-core CPU
 + * \param mask the value specifying the CPU affinity setting of the task
 + *
 + *
 + * Note:
 + * 1. The current code does not allow an affinity of a task to multiple cores.
 + * The mask value 0x03 (i.e., a given task will be executed on the first core
 + * or the second core) is not allowed. The mask value 0x01 or 0x02 works. See
 + * cpu_cas01.c for details.
 + *
 + * 2. It is recommended to first compare simulation results in both the Lazy
 + * and Full calculation modes (using --cfg=cpu/optim:Full or not). Fix
 + * cpu_cas01.c if you find wrong results in the Lazy mode.
 + *
 + */
 +void MSG_task_set_affinity(msg_task_t task, msg_host_t host, unsigned long mask)
 +{
 +  xbt_assert(task, "Invalid parameter");
 +  xbt_assert(task->simdata, "Invalid parameter");
 +
 +  if (mask == 0) {
 +    /* 0 means clear */
 +    xbt_dict_remove_ext(task->simdata->affinity_mask_db, (char *) host, sizeof(host));
 +  } else
 +    xbt_dict_set_ext(task->simdata->affinity_mask_db, (char *) host, sizeof(host), (void *) mask, NULL);
 +
 +  /* We set affinity data of this task. If the task is being executed, we
 +   * actually change the affinity setting of the task. Otherwise, this change
 +   * will be applied when the task is executed. */
 +
 +  if (!task->simdata->compute) {
 +    /* task is not yet executed */
 +    XBT_INFO("set affinity(0x%04lx@%s) for %s (not active now)", mask, MSG_host_get_name(host), MSG_task_get_name(task));
 +    return;
 +  }
 +
 +  {
 +    smx_action_t compute = task->simdata->compute;
 +    msg_host_t host_now = compute->execution.host;  // simix_private.h is necessary
 +    if (host_now != host) {
 +      /* task is not yet executed on this host */
 +      XBT_INFO("set affinity(0x%04lx@%s) for %s (not active now)", mask, MSG_host_get_name(host), MSG_task_get_name(task));
 +      return;
 +    }
 +
 +    /* task is being executed on this host. so change the affinity now */
 +    {
 +      /* check it works. remove me if it works. */
 +      unsigned long affinity_mask = (unsigned long) xbt_dict_get_or_null_ext(task->simdata->affinity_mask_db, (char *) host, sizeof(msg_host_t));
 +      xbt_assert(affinity_mask == mask);
 +    }
 +
 +    XBT_INFO("set affinity(0x%04lx@%s) for %s", mask, MSG_host_get_name(host), MSG_task_get_name(task));
 +    simcall_host_execution_set_affinity(task->simdata->compute, host, mask);
 +  }
 +}
diff --combined src/msg/msg_vm.c
@@@ -1,22 -1,9 +1,23 @@@
- /* Copyright (c) 2012. The SimGrid Team. All rights reserved.               */
+ /* Copyright (c) 2012-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
  
 +// QUESTIONS:
 +// 1./ check how and where a new VM is added to the list of the hosts
 +// 2./ Diff between SIMIX_Actions and SURF_Actions
 +// => SIMIX_actions : point synchro entre processus de niveau (theoretically speaking I do not have to create such SIMIX_ACTION
 +// =>  Surf_Actions
 +
 +// TODO
 +//    MSG_TRACE can be revisited in order to use  the host
 +//    To implement a mixed model between workstation and vm_workstation,
 +//     please give a look at surf_model_private_t model_private at SURF Level and to the share resource functions
 +//     double (*share_resources) (double now);
 +//    For the action into the vm workstation model, we should be able to leverage the usual one (and if needed, look at
 +//            the workstation model.
 +
  #include "msg_private.h"
  #include "xbt/sysdep.h"
  #include "xbt/log.h"
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_vm, msg,
                                  "Cloud-oriented parts of the MSG API");
  
 -/** @brief Create a new (empty) VMs.
 - *  @ingroup msg_VMs
 +
 +/* **** ******** GENERAL ********* **** */
 +
 +/** \ingroup m_vm_management
 + * \brief Returns the value of a given vm property
   *
 - *  @bug it is expected that in the future, the coreAmount parameter will be used
 - *  to add extra constraints on the execution, but the argument is ignored for now.
 + * \param vm a vm
 + * \param name a property name
 + * \return value of a property (or NULL if property not set)
   */
  
 -msg_vm_t MSG_vm_start(msg_host_t location, const char *name, int coreAmount) {
 -  msg_vm_t res = xbt_new0(s_msg_vm_t,1);
 -  res->all_vms_hookup.prev = NULL;
 -  res->host_vms_hookup.prev = NULL;
 -  res->state = msg_vm_state_running;
 -  res->location = location;
 -  res->coreAmount = coreAmount;
 -  res->name = xbt_strdup(name);
 -  res->processes = xbt_dynar_new(sizeof(msg_process_t),NULL);
 +const char *MSG_vm_get_property_value(msg_vm_t vm, const char *name)
 +{
 +  return MSG_host_get_property_value(vm, name);
 +}
  
 -  xbt_swag_insert(res,msg_global->vms);
 -  xbt_swag_insert(res, MSG_host_priv(location)->vms);
 +/** \ingroup m_vm_management
 + * \brief Returns a xbt_dict_t consisting of the list of properties assigned to this host
 + *
 + * \param vm a vm
 + * \return a dict containing the properties
 + */
 +xbt_dict_t MSG_vm_get_properties(msg_vm_t vm)
 +{
 +  xbt_assert((vm != NULL), "Invalid parameters (vm is NULL)");
  
 -  #ifdef HAVE_TRACING
 -  TRACE_msg_vm_create(name, location);
 -  #endif
 +  return (simcall_host_get_properties(vm));
 +}
 +
 +/** \ingroup m_host_management
 + * \brief Change the value of a given host property
 + *
 + * \param host a host
 + * \param name a property name
 + * \param value what to change the property to
 + * \param free_ctn the freeing function to use to kill the value on need
 + */
 +void MSG_vm_set_property_value(msg_vm_t vm, const char *name, void *value, void_f_pvoid_t free_ctn)
 +{
 +  xbt_dict_set(MSG_host_get_properties(vm), name, value, free_ctn);
 +}
  
 +/** \ingroup msg_vm_management
 + * \brief Finds a msg_vm_t using its name.
 + *
 + * This is a name directory service
 + * \param name the name of a vm.
 + * \return the corresponding vm
 + *
 + * Please note that a VM is a specific host. Hence, you should give a different name
 + * for each VM/PM.
 + */
  
 -  return res;
 +msg_vm_t MSG_vm_get_by_name(const char *name)
 +{
 +      return MSG_get_host_by_name(name);
  }
 -/** @brief Returns a newly constructed dynar containing all existing VMs in the system.
 - *  @ingroup msg_VMs
 +
 +/** \ingroup m_vm_management
 + *
 + * \brief Return the name of the #msg_host_t.
   *
 - * Don't forget to free the dynar after use.
 + * This functions checks whether \a host is a valid pointer or not and return
 +   its name.
   */
 -xbt_dynar_t MSG_vms_as_dynar(void) {
 -  xbt_dynar_t res = xbt_dynar_new(sizeof(msg_vm_t),NULL);
 -  msg_vm_t vm;
 -  xbt_swag_foreach(vm,msg_global->vms) {
 -    xbt_dynar_push(res,&vm);
 -  }
 -  return res;
 +const char *MSG_vm_get_name(msg_vm_t vm)
 +{
 +  return MSG_host_get_name(vm);
  }
  
 -/** @brief Returns whether the given VM is currently suspended
 +
 +/* **** Check state of a VM **** */
 +static inline int __MSG_vm_is_state(msg_vm_t vm, e_surf_vm_state_t state)
 +{
 +  return simcall_vm_get_state(vm) == state;
 +}
 +
 +/** @brief Returns whether the given VM has just reated, not running.
   *  @ingroup msg_VMs
   */
 -int MSG_vm_is_suspended(msg_vm_t vm) {
 -  return vm->state == msg_vm_state_suspended;
 +int MSG_vm_is_created(msg_vm_t vm)
 +{
 +  return __MSG_vm_is_state(vm, SURF_VM_STATE_CREATED);
  }
 +
  /** @brief Returns whether the given VM is currently running
   *  @ingroup msg_VMs
   */
 -int MSG_vm_is_running(msg_vm_t vm) {
 -  return vm->state == msg_vm_state_running;
 +int MSG_vm_is_running(msg_vm_t vm)
 +{
 +  return __MSG_vm_is_state(vm, SURF_VM_STATE_RUNNING);
  }
 -/** @brief Add the given process into the VM.
 +
 +/** @brief Returns whether the given VM is currently migrating
   *  @ingroup msg_VMs
 - *
 - * Afterward, when the VM is migrated or suspended or whatever, the process will have the corresponding handling, too.
 - *
   */
 -void MSG_vm_bind(msg_vm_t vm, msg_process_t process) {
 -  /* check if the process is already in a VM */
 -  simdata_process_t simdata = simcall_process_get_data(process);
 -  if (simdata->vm) {
 -    msg_vm_t old_vm = simdata->vm;
 -    int pos = xbt_dynar_search(old_vm->processes,&process);
 -    xbt_dynar_remove_at(old_vm->processes,pos, NULL);
 -  }
 -  /* check if the host is in the right host */
 -  if (simdata->m_host != vm->location) {
 -    MSG_process_migrate(process,vm->location);
 -  }
 -  simdata->vm = vm;
 +int MSG_vm_is_migrating(msg_vm_t vm)
 +{
 +  return __MSG_vm_is_state(vm, SURF_VM_STATE_MIGRATING);
 +}
  
 -  XBT_DEBUG("binding Process %s to %p",MSG_process_get_name(process),vm);
 +/** @brief Returns whether the given VM is currently suspended, not running.
 + *  @ingroup msg_VMs
 + */
 +int MSG_vm_is_suspended(msg_vm_t vm)
 +{
 +  return __MSG_vm_is_state(vm, SURF_VM_STATE_SUSPENDED);
 +}
  
 -  xbt_dynar_push_as(vm->processes,msg_process_t,process);
 +/** @brief Returns whether the given VM is being saved (FIXME: live saving or not?).
 + *  @ingroup msg_VMs
 + */
 +int MSG_vm_is_saving(msg_vm_t vm)
 +{
 +  return __MSG_vm_is_state(vm, SURF_VM_STATE_SAVING);
  }
 -/** @brief Removes the given process from the given VM, and kill it
 +
 +/** @brief Returns whether the given VM has been saved, not running.
   *  @ingroup msg_VMs
 - *
 - *  Will raise a not_found exception if the process were not bound to that VM
   */
 -void MSG_vm_unbind(msg_vm_t vm, msg_process_t process) {
 -  int pos = xbt_dynar_search(vm->processes,process);
 -  xbt_dynar_remove_at(vm->processes,pos, NULL);
 -  MSG_process_kill(process);
 +int MSG_vm_is_saved(msg_vm_t vm)
 +{
 +  return __MSG_vm_is_state(vm, SURF_VM_STATE_SAVED);
  }
  
 -/** @brief Immediately change the host on which all processes are running.
 +/** @brief Returns whether the given VM is being restored, not running.
   *  @ingroup msg_VMs
 + */
 +int MSG_vm_is_restoring(msg_vm_t vm)
 +{
 +  return __MSG_vm_is_state(vm, SURF_VM_STATE_RESTORING);
 +}
 +
 +
 +
 +/* ------------------------------------------------------------------------- */
 +/* ------------------------------------------------------------------------- */
 +
 +/* **** ******** MSG vm actions ********* **** */
 +
 +/** @brief Create a new VM with specified parameters.
 + *  @ingroup msg_VMs*
 + *  All parameters are in MBytes
   *
 - * No migration cost occurs. If you want to simulate this too, you want to use a
 - * MSG_task_send() before or after, depending on whether you want to do cold or hot
 - * migration.
   */
 -void MSG_vm_migrate(msg_vm_t vm, msg_host_t destination) {
 -  unsigned int cpt;
 -  msg_process_t process;
 -  xbt_dynar_foreach(vm->processes,cpt,process) {
 -    MSG_process_migrate(process,destination);
 +msg_vm_t MSG_vm_create(msg_host_t ind_pm, const char *name, int ncpus, int ramsize,
 +                                           int net_cap, char *disk_path, int disksize,
 +                                               int mig_netspeed, int dp_intensity)
 +{
 +      /* For the moment, intensity_rate is the percentage against the migration bandwidth */
 +      double host_speed = MSG_get_host_speed(ind_pm);
 +      double update_speed = ((double)dp_intensity/100) * mig_netspeed;
 +      
 +      msg_vm_t vm = MSG_vm_create_core(ind_pm, name);
 +      s_ws_params_t params;
 +      memset(&params, 0, sizeof(params));
 +      params.ramsize = 1L * 1024 * 1024 * ramsize;
 +      //params.overcommit = 0;
 +      params.devsize = 0;
 +      params.skip_stage2 = 0;
 +      params.max_downtime = 0.03;
 +      params.dp_rate = (update_speed * 1L * 1024 * 1024 ) / host_speed; 
 +      params.dp_cap = params.ramsize / 0.9; // working set memory is 90%
 +      params.mig_speed = 1L * 1024 * 1024 * mig_netspeed; // mig_speed
 +
 +   //XBT_INFO("dp rate %f migspeed : %f intensity mem : %d, updatespeed %f, hostspeed %f",params.dp_rate, params.mig_speed, dp_intensity, update_speed, host_speed);
 +      simcall_host_set_params(vm, &params);
 +
 +      return vm;
 +}
 +
 +
 +/** @brief Create a new VM object. The VM is not yet started. The resource of the VM is allocated upon MSG_vm_start().
 + *  @ingroup msg_VMs*
 + *
 + * A VM is treated as a host. The name of the VM must be unique among all hosts.
 + */
 +msg_vm_t MSG_vm_create_core(msg_host_t ind_pm, const char *name)
 +{
 +  /* make sure the VM of the same name does not exit */
 +  {
 +    void *ind_host_tmp = xbt_lib_get_elm_or_null(host_lib, name);
 +    if (ind_host_tmp) {
 +      XBT_ERROR("host %s already exits", name);
 +      return NULL;
 +    }
    }
 -  xbt_swag_remove(vm, MSG_host_priv(vm->location)->vms);
 -  xbt_swag_insert_at_tail(vm, MSG_host_priv(destination)->vms);
 -  
 +
 +  /* Note: ind_vm and vm_workstation point to the same elm object. */
 +  msg_vm_t ind_vm = NULL;
 +  void *ind_vm_workstation =  NULL;
 +
 +  /* Ask the SIMIX layer to create the surf vm resource */
 +  ind_vm_workstation = simcall_vm_create(name, ind_pm);
 +  ind_vm = (msg_vm_t) __MSG_host_create(ind_vm_workstation);
 +
 +  XBT_DEBUG("A new VM (%s) has been created", name);
 +
    #ifdef HAVE_TRACING
 -  TRACE_msg_vm_change_host(vm,vm->location,destination);
 +  TRACE_msg_vm_create(name, ind_pm);
    #endif
  
 -  vm->location = destination;
 +  return ind_vm;
  }
  
 -/** @brief Immediately suspend the execution of all processes within the given VM.
 +/** @brief Destroy a VM. Destroy the VM object from the simulation.
   *  @ingroup msg_VMs
 - *
 - * No suspension cost occurs. If you want to simulate this too, you want to
 - * use a \ref MSG_file_write() before or after, depending on the exact semantic
 - * of VM suspend to you.
   */
 -void MSG_vm_suspend(msg_vm_t vm) {
 -  unsigned int cpt;
 -  msg_process_t process;
 -  xbt_dynar_foreach(vm->processes,cpt,process) {
 -    XBT_DEBUG("suspend process %s of host %s",MSG_process_get_name(process),MSG_host_get_name(MSG_process_get_host(process)));
 -    MSG_process_suspend(process);
 +void MSG_vm_destroy(msg_vm_t vm)
 +{
 +  /* First, terminate all processes on the VM if necessary */
 +  if (MSG_vm_is_running(vm))
 +      simcall_vm_shutdown(vm);
 +
 +  if (!MSG_vm_is_created(vm)) {
 +    XBT_CRITICAL("shutdown the given VM before destroying it");
 +    DIE_IMPOSSIBLE;
    }
  
 +  /* Then, destroy the VM object */
 +  simcall_vm_destroy(vm);
 +
 +  __MSG_host_destroy(vm);
 +
    #ifdef HAVE_TRACING
 -  TRACE_msg_vm_suspend(vm);
 +  TRACE_msg_vm_end(vm);
    #endif
  }
  
 -/** @brief Immediately resumes the execution of all processes within the given VM.
 +
 +/** @brief Start a vm (i.e., boot the guest operating system)
   *  @ingroup msg_VMs
   *
 - * No resume cost occurs. If you want to simulate this too, you want to
 - * use a \ref MSG_file_read() before or after, depending on the exact semantic
 - * of VM resume to you.
 + *  If the VM cannot be started, an exception is generated.
 + *
   */
 -void MSG_vm_resume(msg_vm_t vm) {
 -  unsigned int cpt;
 -  msg_process_t process;
 -  xbt_dynar_foreach(vm->processes,cpt,process) {
 -    XBT_DEBUG("resume process %s of host %s",MSG_process_get_name(process),MSG_host_get_name(MSG_process_get_host(process)));
 -    MSG_process_resume(process);
 -  }
 +void MSG_vm_start(msg_vm_t vm)
 +{
 +  simcall_vm_start(vm);
  
    #ifdef HAVE_TRACING
 -  TRACE_msg_vm_resume(vm);
 +  TRACE_msg_vm_start(vm);
    #endif
  }
  
 +
 +
  /** @brief Immediately kills all processes within the given VM. Any memory that they allocated will be leaked.
   *  @ingroup msg_VMs
   *
 - * No extra delay occurs. If you want to simulate this too, you want to
 + * FIXME: No extra delay occurs. If you want to simulate this too, you want to
   * use a #MSG_process_sleep() or something. I'm not quite sure.
   */
  void MSG_vm_shutdown(msg_vm_t vm)
  {
 -  msg_process_t process;
 -  XBT_DEBUG("%lu processes in the VM", xbt_dynar_length(vm->processes));
 -  while (!xbt_dynar_is_empty(vm->processes)) {
 -    process = xbt_dynar_get_as(vm->processes,0,msg_process_t);
 -    MSG_process_kill(process);
 +  /* msg_vm_t equals to msg_host_t */
 +  simcall_vm_shutdown(vm);
 +
 +  // #ifdef HAVE_TRACING
 +  // TRACE_msg_vm_(vm);
 +  // #endif
 +}
 +
 +
 +
 +/* We have two mailboxes. mbox is used to transfer migration data between
 + * source and destiantion PMs. mbox_ctl is used to detect the completion of a
 + * migration. The names of these mailboxes must not conflict with others. */
 +static inline char *get_mig_mbox_src_dst(const char *vm_name, const char *src_pm_name, const char *dst_pm_name)
 +{
 +  return bprintf("__mbox_mig_src_dst:%s(%s-%s)", vm_name, src_pm_name, dst_pm_name);
 +}
 +
 +static inline char *get_mig_mbox_ctl(const char *vm_name, const char *src_pm_name, const char *dst_pm_name)
 +{
 +  return bprintf("__mbox_mig_ctl:%s(%s-%s)", vm_name, src_pm_name, dst_pm_name);
 +}
 +
 +static inline char *get_mig_process_tx_name(const char *vm_name, const char *src_pm_name, const char *dst_pm_name)
 +{
 +  return bprintf("__pr_mig_tx:%s(%s-%s)", vm_name, src_pm_name, dst_pm_name);
 +}
 +
 +static inline char *get_mig_process_rx_name(const char *vm_name, const char *src_pm_name, const char *dst_pm_name)
 +{
 +  return bprintf("__pr_mig_rx:%s(%s-%s)", vm_name, src_pm_name, dst_pm_name);
 +}
 +
 +static inline char *get_mig_task_name(const char *vm_name, const char *src_pm_name, const char *dst_pm_name, int stage)
 +{
 +  return bprintf("__task_mig_stage%d:%s(%s-%s)", stage, vm_name, src_pm_name, dst_pm_name);
 +}
 +
 +static void launch_deferred_exec_process(msg_host_t host, double computation, double prio);
 +
 +static int migration_rx_fun(int argc, char *argv[])
 +{
 +  XBT_DEBUG("mig: rx_start");
 +
 +  xbt_assert(argc == 4);
 +  const char *vm_name = argv[1];
 +  const char *src_pm_name  = argv[2];
 +  const char *dst_pm_name  = argv[3];
 +  msg_vm_t vm = MSG_get_host_by_name(vm_name);
 +  msg_host_t src_pm = MSG_get_host_by_name(src_pm_name);
 +  msg_host_t dst_pm = MSG_get_host_by_name(dst_pm_name);
 +
 +
 +  s_ws_params_t params;
 +  simcall_host_get_params(vm, &params);
 +  const double xfer_cpu_overhead = params.xfer_cpu_overhead;
 +
 +
 +  int need_exit = 0;
 +
 +  char *mbox = get_mig_mbox_src_dst(vm_name, src_pm_name, dst_pm_name);
 +  char *mbox_ctl = get_mig_mbox_ctl(vm_name, src_pm_name, dst_pm_name);
 +  char *finalize_task_name = get_mig_task_name(vm_name, src_pm_name, dst_pm_name, 3);
 +
 +  for (;;) {
 +    msg_task_t task = NULL;
 +    MSG_task_recv(&task, mbox);
 +    {
 +      double received = MSG_task_get_data_size(task);
 +      /* TODO: clean up */
 +      // const double alpha = 0.22L * 1.0E8 / (80L * 1024 * 1024);
 +      launch_deferred_exec_process(vm, received * xfer_cpu_overhead, 1);
 +    }
 +
 +    if (strcmp(task->name, finalize_task_name) == 0)
 +      need_exit = 1;
 +
 +    MSG_task_destroy(task);
 +
 +    if (need_exit)
 +      break;
 +  }
 +
 +
 +  /* deinstall the current affinity setting */
 +  simcall_vm_set_affinity(vm, src_pm, 0);
 +
 +  simcall_vm_migrate(vm, dst_pm);
 +  simcall_vm_resume(vm);
 +
 +  /* install the affinity setting of the VM on the destination pm */
 +  {
 +    msg_host_priv_t priv = msg_host_resource_priv(vm);
 +
 +    unsigned long affinity_mask = (unsigned long) xbt_dict_get_or_null_ext(priv->affinity_mask_db, (char *) dst_pm, sizeof(msg_host_t));
 +    simcall_vm_set_affinity(vm, dst_pm, affinity_mask);
 +    XBT_INFO("set affinity(0x%04lx@%s) for %s", affinity_mask, MSG_host_get_name(dst_pm), MSG_host_get_name(vm));
 +  }
 +
 +  {
 +    char *task_name = get_mig_task_name(vm_name, src_pm_name, dst_pm_name, 4);
 +
 +    msg_task_t task = MSG_task_create(task_name, 0, 0, NULL);
 +    msg_error_t ret = MSG_task_send(task, mbox_ctl);
 +    xbt_assert(ret == MSG_OK);
 +
 +    xbt_free(task_name);
 +  }
 +
 +
 +  xbt_free(mbox);
 +  xbt_free(mbox_ctl);
 +  xbt_free(finalize_task_name);
 +
 +  XBT_DEBUG("mig: rx_done");
 +
 +  return 0;
 +}
 +
 +static void reset_dirty_pages(msg_vm_t vm)
 +{
 +  msg_host_priv_t priv = msg_host_resource_priv(vm);
 +
 +  char *key = NULL;
 +  xbt_dict_cursor_t cursor = NULL;
 +  dirty_page_t dp = NULL;
 +  xbt_dict_foreach(priv->dp_objs, cursor, key, dp) {
 +    double remaining = MSG_task_get_remaining_computation(dp->task);
 +    dp->prev_clock = MSG_get_clock();
 +    dp->prev_remaining = remaining;
 +
 +    // XBT_INFO("%s@%s remaining %f", key, sg_host_name(vm), remaining);
 +  }
 +}
 +
 +static void start_dirty_page_tracking(msg_vm_t vm)
 +{
 +  msg_host_priv_t priv = msg_host_resource_priv(vm);
 +  priv->dp_enabled = 1;
 +
 +  reset_dirty_pages(vm);
 +}
 +
 +static void stop_dirty_page_tracking(msg_vm_t vm)
 +{
 +  msg_host_priv_t priv = msg_host_resource_priv(vm);
 +  priv->dp_enabled = 0;
 +}
 +
 +#if 0
 +/* It might be natural that we define dp_rate for each task. But, we will also
 + * have to care about how each task behavior affects the memory update behavior
 + * at the operating system level. It may not be easy to model it with a simple algorithm. */
 +double calc_updated_pages(char *key, msg_vm_t vm, dirty_page_t dp, double remaining, double clock)
 +{
 +    double computed = dp->prev_remaining - remaining;
 +    double duration = clock - dp->prev_clock;
 +    double updated = dp->task->dp_rate * computed;
 +
 +    XBT_INFO("%s@%s: computated %f ops (remaining %f -> %f) in %f secs (%f -> %f)",
 +        key, sg_host_name(vm), computed, dp->prev_remaining, remaining, duration, dp->prev_clock, clock);
 +    XBT_INFO("%s@%s: updated %f bytes, %f Mbytes/s",
 +        key, sg_host_name(vm), updated, updated / duration / 1000 / 1000);
 +
 +    return updated;
 +}
 +#endif
 +
 +static double get_computed(char *key, msg_vm_t vm, dirty_page_t dp, double remaining, double clock)
 +{
 +  double computed = dp->prev_remaining - remaining;
 +  double duration = clock - dp->prev_clock;
 +
 +  XBT_DEBUG("%s@%s: computated %f ops (remaining %f -> %f) in %f secs (%f -> %f)",
 +      key, sg_host_name(vm), computed, dp->prev_remaining, remaining, duration, dp->prev_clock, clock);
 +
 +  return computed;
 +}
 +
 +static double lookup_computed_flop_counts(msg_vm_t vm, int stage_for_fancy_debug, int stage2_round_for_fancy_debug)
 +{
 +  msg_host_priv_t priv = msg_host_resource_priv(vm);
 +  double total = 0;
 +
 +  char *key = NULL;
 +  xbt_dict_cursor_t cursor = NULL;
 +  dirty_page_t dp = NULL;
 +  xbt_dict_foreach(priv->dp_objs, cursor, key, dp) {
 +    double remaining = MSG_task_get_remaining_computation(dp->task);
 +   
 +       double clock = MSG_get_clock();
 +
 +    // total += calc_updated_pages(key, vm, dp, remaining, clock);
 +    total += get_computed(key, vm, dp, remaining, clock);
 +
 +    dp->prev_remaining = remaining;
 +    dp->prev_clock = clock;
 +  }
 +
 +  total += priv->dp_updated_by_deleted_tasks;
 +
 +  XBT_DEBUG("mig-stage%d.%d: computed %f flop_counts (including %f by deleted tasks)",
 +      stage_for_fancy_debug,
 +      stage2_round_for_fancy_debug,
 +      total, priv->dp_updated_by_deleted_tasks);
 +
 +
 +
 +  priv->dp_updated_by_deleted_tasks = 0;
 +
 +
 +  return total;
 +}
 +
 +// TODO Is this code redundant with the information provided by
 +// msg_process_t MSG_process_create(const char *name, xbt_main_func_t code, void *data, msg_host_t host)
 +void MSG_host_add_task(msg_host_t host, msg_task_t task)
 +{
 +  msg_host_priv_t priv = msg_host_resource_priv(host);
 +  double remaining = MSG_task_get_remaining_computation(task);
 +  char *key = bprintf("%s-%lld", task->name, task->counter);
 +
 +  dirty_page_t dp = xbt_new0(s_dirty_page, 1);
 +  dp->task = task;
 +
 +  /* It should be okay that we add a task onto a migrating VM. */
 +  if (priv->dp_enabled) {
 +    dp->prev_clock = MSG_get_clock();
 +    dp->prev_remaining = remaining;
 +  }
 +
 +  xbt_assert(xbt_dict_get_or_null(priv->dp_objs, key) == NULL);
 +  xbt_dict_set(priv->dp_objs, key, dp, NULL);
 +  XBT_DEBUG("add %s on %s (remaining %f, dp_enabled %d)", key, sg_host_name(host), remaining, priv->dp_enabled);
 +
 +  xbt_free(key);
 +}
 +
 +void MSG_host_del_task(msg_host_t host, msg_task_t task)
 +{
 +  msg_host_priv_t priv = msg_host_resource_priv(host);
 +
 +  char *key = bprintf("%s-%lld", task->name, task->counter);
 +
 +  dirty_page_t dp = xbt_dict_get_or_null(priv->dp_objs, key);
 +  xbt_assert(dp->task == task);
 +
 +  /* If we are in the middle of dirty page tracking, we record how much
 +   * computaion has been done until now, and keep the information for the
 +   * lookup_() function that will called soon. */
 +  if (priv->dp_enabled) {
 +    double remaining = MSG_task_get_remaining_computation(task);
 +    double clock = MSG_get_clock();
 +    // double updated = calc_updated_pages(key, host, dp, remaining, clock);
 +    double updated = get_computed(key, host, dp, remaining, clock);
 +
 +    priv->dp_updated_by_deleted_tasks += updated;
 +  }
 +
 +  xbt_dict_remove(priv->dp_objs, key);
 +  xbt_free(dp);
 +
 +  XBT_DEBUG("del %s on %s", key, sg_host_name(host));
 +
 +  xbt_free(key);
 +}
 +
 +
 +static int deferred_exec_fun(int argc, char *argv[])
 +{
 +  xbt_assert(argc == 3);
 +  const char *comp_str = argv[1];
 +  double computaion = atof(comp_str);
 +  const char *prio_str = argv[2];
 +  double prio = atof(prio_str);
 +
 +  msg_task_t task = MSG_task_create("__task_deferred", computaion, 0, NULL);
 +  // XBT_INFO("exec deferred %f", computaion);
 +
 +  /* dpt is the results of the VM activity */
 +  MSG_task_set_priority(task, prio);
 +  MSG_task_execute(task);
 +
 +
 +
 +  MSG_task_destroy(task);
 +
 +  return 0;
 +}
 +
 +static void launch_deferred_exec_process(msg_host_t host, double computation, double prio)
 +{
 +  char *pr_name = bprintf("__pr_deferred_exec_%s", MSG_host_get_name(host));
 +
 +  int nargvs = 4;
 +  char **argv = xbt_new(char *, nargvs);
 +  argv[0] = xbt_strdup(pr_name);
 +  argv[1] = bprintf("%lf", computation);
 +  argv[2] = bprintf("%lf", prio);
 +  argv[3] = NULL;
 +
 +  MSG_process_create_with_arguments(pr_name, deferred_exec_fun, NULL, host, nargvs - 1, argv);
 +
 +  xbt_free(pr_name);
 +}
 +
 +
 +static int task_tx_overhead_fun(int argc, char *argv[])
 +{
 +  xbt_assert(argc == 2);
 +  const char *mbox = argv[1];
 +
 +  int need_exit = 0;
 +
 +  // XBT_INFO("start %s", mbox);
 +
 +  for (;;) {
 +    msg_task_t task = NULL;
 +    MSG_task_recv(&task, mbox);
 +
 +    // XBT_INFO("task->name %s", task->name);
 +
 +    if (strcmp(task->name, "finalize_making_overhead") == 0)
 +      need_exit = 1;
 +
 +    // XBT_INFO("exec");
 +    // MSG_task_set_priority(task, 1000000);
 +    MSG_task_execute(task);
 +    MSG_task_destroy(task);
 +
 +    if (need_exit)
 +      break;
 +  }
 +
 +  // XBT_INFO("bye");
 +
 +  return 0;
 +}
 +
 +static void start_overhead_process(msg_task_t comm_task)
 +{
 +  char *pr_name = bprintf("__pr_task_tx_overhead_%s", MSG_task_get_name(comm_task));
 +  char *mbox    = bprintf("__mb_task_tx_overhead_%s", MSG_task_get_name(comm_task));
 +
 +  int nargvs = 3;
 +  char **argv = xbt_new(char *, nargvs);
 +  argv[0] = xbt_strdup(pr_name);
 +  argv[1] = xbt_strdup(mbox);
 +  argv[2] = NULL;
 +
 +  // XBT_INFO("micro start: mbox %s", mbox);
 +  MSG_process_create_with_arguments(pr_name, task_tx_overhead_fun, NULL, MSG_host_self(), nargvs - 1, argv);
 +
 +  xbt_free(pr_name);
 +  xbt_free(mbox);
 +}
 +
 +static void shutdown_overhead_process(msg_task_t comm_task)
 +{
 +  char *mbox = bprintf("__mb_task_tx_overhead_%s", MSG_task_get_name(comm_task));
 +
 +  msg_task_t task = MSG_task_create("finalize_making_overhead", 0, 0, NULL);
 +
 +  // XBT_INFO("micro shutdown: mbox %s", mbox);
 +  msg_error_t ret = MSG_task_send(task, mbox);
 +  xbt_assert(ret == MSG_OK);
 +
 +  xbt_free(mbox);
 +  // XBT_INFO("shutdown done");
 +}
 +
 +static void request_overhead(msg_task_t comm_task, double computation)
 +{
 +  char *mbox = bprintf("__mb_task_tx_overhead_%s", MSG_task_get_name(comm_task));
 +
 +  msg_task_t task = MSG_task_create("micro", computation, 0, NULL);
 +
 +  // XBT_INFO("req overhead");
 +  msg_error_t ret = MSG_task_send(task, mbox);
 +  xbt_assert(ret == MSG_OK);
 +
 +  xbt_free(mbox);
 +}
 +
 +/* alpha is (floating_operations / bytes).
 + *
 + * When actual migration traffic was 32 mbytes/s, we observed the CPU
 + * utilization of the main thread of the Qemu process was 10 %. 
 + *   alpha = 0.1 * C / (32 * 1024 * 1024)
 + * where the CPU capacity of the PM is C flops/s.
 + *
 + * */
 +static void task_send_bounded_with_cpu_overhead(msg_task_t comm_task, char *mbox, double mig_speed, double alpha)
 +{
 +  const double chunk_size = 1024 * 1024 * 10;
 +  double remaining = MSG_task_get_data_size(comm_task);
 +
 +  start_overhead_process(comm_task);
 +
 +
 +  while (remaining > 0) {
 +    double data_size = chunk_size;
 +    if (remaining < chunk_size)
 +      data_size = remaining;
 +
 +    remaining -= data_size;
 +
 +    // XBT_INFO("remaining %f bytes", remaining);
 +
 +
 +    double clock_sta = MSG_get_clock();
 +
 +    /* create a micro task */
 +    {
 +      char *mtask_name = bprintf("__micro_%s", MSG_task_get_name(comm_task));
 +      msg_task_t mtask = MSG_task_create(mtask_name, 0, data_size, NULL);
 +
 +      request_overhead(comm_task, data_size * alpha);
 +
 +      msg_error_t ret = MSG_task_send(mtask, mbox);
 +      xbt_assert(ret == MSG_OK);
 +
 +      xbt_free(mtask_name);
 +    }
 +
 +#if 0
 +    {
 +      /* In the real world, sending data involves small CPU computation. */
 +      char *mtask_name = bprintf("__micro_%s", MSG_task_get_name(comm_task));
 +      msg_task_t mtask = MSG_task_create(mtask_name, data_size * alpha, data_size, NULL);
 +      MSG_task_execute(mtask);
 +      MSG_task_destroy(mtask);
 +      xbt_free(mtask_name);
 +    }
 +#endif
 +   
 +    /* TODO */
 +
 +    double clock_end = MSG_get_clock();
 +
 +
 +    if (mig_speed > 0) {
 +      /*
 +       * (max bandwidth) > data_size / ((elapsed time) + time_to_sleep)
 +       *
 +       * Thus, we get
 +       *   time_to_sleep > data_size / (max bandwidth) - (elapsed time)
 +       *
 +       * If time_to_sleep is smaller than zero, the elapsed time was too big. We
 +       * do not need a micro sleep.
 +       **/
 +      double time_to_sleep = data_size / mig_speed - (clock_end - clock_sta);
 +      if (time_to_sleep > 0)
 +        MSG_process_sleep(time_to_sleep);
 +
 +
 +      //XBT_INFO("duration %f", clock_end - clock_sta);
 +      //XBT_INFO("time_to_sleep %f", time_to_sleep);
 +    }
 +  }
 +
 +  // XBT_INFO("%s", MSG_task_get_name(comm_task));
 +  shutdown_overhead_process(comm_task);
 +
 +}
 +
 +
 +#if 0
 +static void make_cpu_overhead_of_data_transfer(msg_task_t comm_task, double init_comm_size)
 +{
 +  double prev_remaining = init_comm_size;
 +
 +  for (;;) {
 +    double remaining = MSG_task_get_remaining_communication(comm_task);
 +    if (remaining == 0)
 +      need_exit = 1;
 +
 +    double sent = prev_remaining - remaining;
 +    double comp_size = sent * overhead;
 +
 +
 +    char *comp_task_name = bprintf("__sender_overhead%s", MSG_task_get_name(comm_task));
 +    msg_task_t comp_task = MSG_task_create(comp_task_name, comp_size, 0, NULL);
 +    MSG_task_execute(comp_task);
 +    MSG_task_destroy(comp_task);
 +
 +    if (need_exit)
 +      break;
 +
 +    prev_remaining = remaining;
 +
 +  }
 +
 +  xbt_free(comp_task_name);
 +}
 +#endif
 +
 +// #define USE_MICRO_TASK 1
 +
 +#if 0
 +// const double alpha = 0.1L * 1.0E8 / (32L * 1024 * 1024);
 +// const double alpha = 0.25L * 1.0E8 / (85L * 1024 * 1024);
 +// const double alpha = 0.20L * 1.0E8 / (85L * 1024 * 1024);
 +// const double alpha = 0.25L * 1.0E8 / (85L * 1024 * 1024);
 +// const double alpha = 0.32L * 1.0E8 / (24L * 1024 * 1024);   // makes super good values for 32 mbytes/s
 +//const double alpha = 0.32L * 1.0E8 / (32L * 1024 * 1024);
 +// const double alpha = 0.56L * 1.0E8 / (80L * 1024 * 1024);
 +////const double alpha = 0.20L * 1.0E8 / (80L * 1024 * 1024);
 +// const double alpha = 0.56L * 1.0E8 / (90L * 1024 * 1024);
 +// const double alpha = 0.66L * 1.0E8 / (90L * 1024 * 1024);
 +// const double alpha = 0.20L * 1.0E8 / (80L * 1024 * 1024);
 +
 +/* CPU 22% when 80Mbyte/s */
 +const double alpha = 0.22L * 1.0E8 / (80L * 1024 * 1024);
 +#endif
 +
 +
 +static void send_migration_data(const char *vm_name, const char *src_pm_name, const char *dst_pm_name,
 +    double size, char *mbox, int stage, int stage2_round, double mig_speed, double xfer_cpu_overhead)
 +{
 +  char *task_name = get_mig_task_name(vm_name, src_pm_name, dst_pm_name, stage);
 +  msg_task_t task = MSG_task_create(task_name, 0, size, NULL);
 +
 +  /* TODO: clean up */
 +
 +  double clock_sta = MSG_get_clock();
 +
 +#ifdef USE_MICRO_TASK
 +
 +  task_send_bounded_with_cpu_overhead(task, mbox, mig_speed, xfer_cpu_overhead);
 +
 +#else
 +  msg_error_t ret;
 +  if (mig_speed > 0)
 +    ret = MSG_task_send_bounded(task, mbox, mig_speed);
 +  else
 +    ret = MSG_task_send(task, mbox);
 +  xbt_assert(ret == MSG_OK);
 +#endif
 +
 +  double clock_end = MSG_get_clock();
 +  double duration = clock_end - clock_sta;
 +  double actual_speed = size / duration;
 +#ifdef USE_MICRO_TASK
 +  double cpu_utilization = size * xfer_cpu_overhead / duration / 1.0E8;
 +#else
 +  double cpu_utilization = 0;
 +#endif
 +
 +
 +
 +
 +  if (stage == 2){
 +    XBT_DEBUG("mig-stage%d.%d: sent %f duration %f actual_speed %f (target %f) cpu %f", stage, stage2_round, size, duration, actual_speed, mig_speed, cpu_utilization);}
 +  else{
 +    XBT_DEBUG("mig-stage%d: sent %f duration %f actual_speed %f (target %f) cpu %f", stage, size, duration, actual_speed, mig_speed, cpu_utilization);
 +  }
 +
 +  xbt_free(task_name);
 +
 +
 +
 +#ifdef USE_MICRO_TASK
 +  /* The name of a micro task starts with __micro, which does not match the
 +   * special name that finalizes the receiver loop. Thus, we send the special task.
 +   **/
 +  {
 +    if (stage == 3) {
 +      char *task_name = get_mig_task_name(vm_name, src_pm_name, dst_pm_name, stage);
 +      msg_task_t task = MSG_task_create(task_name, 0, 0, NULL);
 +      msg_error_t ret = MSG_task_send(task, mbox);
 +      xbt_assert(ret == MSG_OK);
 +      xbt_free(task_name);
 +    }
 +  }
 +#endif
 +}
 +
 +static double get_updated_size(double computed, double dp_rate, double dp_cap)
 +{
 +  double updated_size = computed * dp_rate;
 +  XBT_DEBUG("updated_size %f dp_rate %f", updated_size, dp_rate);
 +  if (updated_size > dp_cap) {
 +    // XBT_INFO("mig-stage2.%d: %f bytes updated, but cap it with the working set size %f", stage2_round, updated_size, dp_cap);
 +    updated_size = dp_cap;
 +  }
 +
 +  return updated_size;
 +}
 +
 +static double send_stage1(msg_host_t vm, const char *src_pm_name, const char *dst_pm_name,
 +    long ramsize, double mig_speed, double xfer_cpu_overhead, double dp_rate, double dp_cap, double dpt_cpu_overhead)
 +{
 +  const char *vm_name = MSG_host_get_name(vm);
 +  char *mbox = get_mig_mbox_src_dst(vm_name, src_pm_name, dst_pm_name);
 +
 +  // const long chunksize = 1024 * 1024 * 100;
 +  const long chunksize = 1024L * 1024 * 100000;
 +  long remaining = ramsize;
 +  double computed_total = 0;
 +
 +  while (remaining > 0) {
 +    long datasize = chunksize;
 +    if (remaining < chunksize)
 +      datasize = remaining;
 +
 +    remaining -= datasize;
 +
 +    send_migration_data(vm_name, src_pm_name, dst_pm_name, datasize, mbox, 1, 0, mig_speed, xfer_cpu_overhead);
 +
 +    double computed = lookup_computed_flop_counts(vm, 1, 0);
 +    computed_total += computed;
 +
 +    // {
 +    //   double updated_size = get_updated_size(computed, dp_rate, dp_cap);
 +
 +    //   double overhead = dpt_cpu_overhead * updated_size;
 +    //   launch_deferred_exec_process(vm, overhead, 10000);
 +    // }
    }
  
 +  return computed_total;
 +}
 +
 +
 +
 +static double get_threshold_value(double bandwidth, double max_downtime)
 +{
 +  /* This value assumes the network link is 1Gbps. */
 +  // double threshold = max_downtime * 125 * 1024 * 1024;
 +  double threshold = max_downtime * bandwidth;
 +
 +  return threshold;
 +}
 +
 +static int migration_tx_fun(int argc, char *argv[])
 +{
 +  XBT_DEBUG("mig: tx_start");
 +
 +  xbt_assert(argc == 4);
 +  const char *vm_name = argv[1];
 +  const char *src_pm_name  = argv[2];
 +  const char *dst_pm_name  = argv[3];
 +  msg_vm_t vm = MSG_get_host_by_name(vm_name);
 +
 +
 +  s_ws_params_t params;
 +  simcall_host_get_params(vm, &params);
 +  const long ramsize        = params.ramsize;
 +  const long devsize        = params.devsize;
 +  const int skip_stage1     = params.skip_stage1;
 +  const int skip_stage2     = params.skip_stage2;
 +  const double dp_rate      = params.dp_rate;
 +  const double dp_cap       = params.dp_cap;
 +  const double mig_speed    = params.mig_speed;
 +  const double xfer_cpu_overhead = params.xfer_cpu_overhead;
 +  const double dpt_cpu_overhead = params.dpt_cpu_overhead;
 +
 +  double remaining_size = ramsize + devsize;
 +
 +  double max_downtime = params.max_downtime;
 +  if (max_downtime == 0) {
 +    XBT_WARN("use the default max_downtime value 30ms");
 +    max_downtime = 0.03;
 +  }
 +
 +  double threshold = 0.00001; /* TODO: cleanup */
 +
 +  /* setting up parameters has done */
 +
 +
 +  if (ramsize == 0)
 +    XBT_WARN("migrate a VM, but ramsize is zero");
 +
 +  char *mbox = get_mig_mbox_src_dst(vm_name, src_pm_name, dst_pm_name);
 +
 +  XBT_INFO("mig-stage1: remaining_size %f", remaining_size);
 +
 +  /* Stage1: send all memory pages to the destination. */
 +  start_dirty_page_tracking(vm);
 +
 +  double computed_during_stage1 = 0;
 +  if (!skip_stage1) {
 +    // send_migration_data(vm_name, src_pm_name, dst_pm_name, ramsize, mbox, 1, 0, mig_speed, xfer_cpu_overhead);
 +
 +    /* send ramsize, but split it */
 +    double clock_prev_send = MSG_get_clock();
 +
 +    computed_during_stage1 = send_stage1(vm, src_pm_name, dst_pm_name, ramsize, mig_speed, xfer_cpu_overhead, dp_rate, dp_cap, dpt_cpu_overhead);
 +    remaining_size -= ramsize;
 +
 +    double clock_post_send = MSG_get_clock();
 +    double bandwidth = ramsize / (clock_post_send - clock_prev_send);
 +    threshold = get_threshold_value(bandwidth, max_downtime);
 +    XBT_INFO("actual banwdidth %f, threshold %f", bandwidth / 1024 / 1024, threshold);
 +  }
 +
 +
 +  /* Stage2: send update pages iteratively until the size of remaining states
 +   * becomes smaller than the threshold value. */
 +  if (skip_stage2)
 +    goto stage3;
 +  if (max_downtime == 0) {
 +    XBT_WARN("no max_downtime parameter, skip stage2");
 +    goto stage3;
 +  }
 +
 +
 +  int stage2_round = 0;
 +  for (;;) {
 +
 +    double updated_size = 0;
 +    if (stage2_round == 0)  {
 +      /* just after stage1, nothing has been updated. But, we have to send the data updated during stage1 */
 +      updated_size = get_updated_size(computed_during_stage1, dp_rate, dp_cap);
 +    } else {
 +      double computed = lookup_computed_flop_counts(vm, 2, stage2_round);
 +      updated_size = get_updated_size(computed, dp_rate, dp_cap);
 +    }
 +
 +    XBT_INFO("mig-stage 2:%d updated_size %f computed_during_stage1 %f dp_rate %f dp_cap %f",
 +        stage2_round, updated_size, computed_during_stage1, dp_rate, dp_cap);
 +
 +
 +    // if (stage2_round != 0) {
 +    //   /* during stage1, we have already created overhead tasks */
 +    //   double overhead = dpt_cpu_overhead * updated_size;
 +    //   XBT_DEBUG("updated %f overhead %f", updated_size, overhead);
 +    //   launch_deferred_exec_process(vm, overhead, 10000);
 +    // }
 +
 +
 +    {
 +      remaining_size += updated_size;
 +
 +      XBT_INFO("mig-stage2.%d: remaining_size %f (%s threshold %f)", stage2_round,
 +          remaining_size, (remaining_size < threshold) ? "<" : ">", threshold);
 +
 +      if (remaining_size < threshold)
 +        break;
 +    }
 +
 +    double clock_prev_send = MSG_get_clock();
 +
 +    send_migration_data(vm_name, src_pm_name, dst_pm_name, updated_size, mbox, 2, stage2_round, mig_speed, xfer_cpu_overhead);
 +
 +    double clock_post_send = MSG_get_clock();
 +
 +    double bandwidth = updated_size / (clock_post_send - clock_prev_send);
 +    threshold = get_threshold_value(bandwidth, max_downtime);
 +    XBT_INFO("actual banwdidth %f, threshold %f", bandwidth / 1024 / 1024, threshold);
 +
 +
 +
 +
 +
 +
 +
 +    remaining_size -= updated_size;
 +    stage2_round += 1;
 +  }
 +
 +
 +stage3:
 +  /* Stage3: stop the VM and copy the rest of states. */
 +  XBT_INFO("mig-stage3: remaining_size %f", remaining_size);
 +  simcall_vm_suspend(vm);
 +  stop_dirty_page_tracking(vm);
 +
 +  send_migration_data(vm_name, src_pm_name, dst_pm_name, remaining_size, mbox, 3, 0, mig_speed, xfer_cpu_overhead);
 +
 +  xbt_free(mbox);
 +
 +  XBT_DEBUG("mig: tx_done");
 +
 +  return 0;
 +}
 +
 +
 +
 +static void do_migration(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm)
 +{
 +  char *mbox_ctl = get_mig_mbox_ctl(sg_host_name(vm), sg_host_name(src_pm), sg_host_name(dst_pm));
 +
 +  {
 +    char *pr_name = get_mig_process_rx_name(sg_host_name(vm), sg_host_name(src_pm), sg_host_name(dst_pm));
 +    int nargvs = 5;
 +    char **argv = xbt_new(char *, nargvs);
 +    argv[0] = xbt_strdup(pr_name);
 +    argv[1] = xbt_strdup(sg_host_name(vm));
 +    argv[2] = xbt_strdup(sg_host_name(src_pm));
 +    argv[3] = xbt_strdup(sg_host_name(dst_pm));
 +    argv[4] = NULL;
 +
 +    MSG_process_create_with_arguments(pr_name, migration_rx_fun, NULL, dst_pm, nargvs - 1, argv);
 +
 +    xbt_free(pr_name);
 +  }
 +
 +  {
 +    char *pr_name = get_mig_process_tx_name(sg_host_name(vm), sg_host_name(src_pm), sg_host_name(dst_pm));
 +    int nargvs = 5;
 +    char **argv = xbt_new(char *, nargvs);
 +    argv[0] = xbt_strdup(pr_name);
 +    argv[1] = xbt_strdup(sg_host_name(vm));
 +    argv[2] = xbt_strdup(sg_host_name(src_pm));
 +    argv[3] = xbt_strdup(sg_host_name(dst_pm));
 +    argv[4] = NULL;
 +    MSG_process_create_with_arguments(pr_name, migration_tx_fun, NULL, src_pm, nargvs - 1, argv);
 +
 +    xbt_free(pr_name);
 +  }
 +
 +  /* wait until the migration have finished */
 +  {
 +    msg_task_t task = NULL;
 +    msg_error_t ret = MSG_task_recv(&task, mbox_ctl);
 +    xbt_assert(ret == MSG_OK);
 +
 +    char *expected_task_name = get_mig_task_name(sg_host_name(vm), sg_host_name(src_pm), sg_host_name(dst_pm), 4);
 +    xbt_assert(strcmp(task->name, expected_task_name) == 0);
 +    xbt_free(expected_task_name);
 +  }
 +
 +  xbt_free(mbox_ctl);
 +}
 +
 +
 +/** @brief Migrate the VM to the given host.
 + *  @ingroup msg_VMs
 + *
 + * FIXME: No migration cost occurs. If you want to simulate this too, you want to use a
 + * MSG_task_send() before or after, depending on whether you want to do cold or hot
 + * migration.
 + */
 +void MSG_vm_migrate(msg_vm_t vm, msg_host_t new_pm)
 +{
 +  /* some thoughts:
 +   * - One approach is ...
 +   *   We first create a new VM (i.e., destination VM) on the destination
 +   *   physical host. The destination VM will receive the state of the source
 +   *   VM over network. We will finally destroy the source VM.
 +   *   - This behavior is similar to the way of migration in the real world.
 +   *     Even before a migration is completed, we will see a destination VM,
 +   *     consuming resources.
 +   *   - We have to relocate all processes. The existing process migraion code
 +   *     will work for this?
 +   *   - The name of the VM is a somewhat unique ID in the code. It is tricky
 +   *     for the destination VM?
 +   *
 +   * - Another one is ...
 +   *   We update the information of the given VM to place it to the destination
 +   *   physical host.
 +   *
 +   * The second one would be easier.
 +   *   
 +   */
 +
 +  msg_host_t old_pm = simcall_vm_get_pm(vm);
 +
 +  if (simcall_vm_get_state(vm) != SURF_VM_STATE_RUNNING)
 +    THROWF(vm_error, 0, "VM(%s) is not running", sg_host_name(vm));
 +
 +  do_migration(vm, old_pm, new_pm);
 +
 +
 +
 +  XBT_DEBUG("VM(%s) moved from PM(%s) to PM(%s)", vm->key, old_pm->key, new_pm->key);
 +
    #ifdef HAVE_TRACING
 -  TRACE_msg_vm_kill(vm);
 +  TRACE_msg_vm_change_host(vm, old_pm, new_pm);
    #endif
 +}
  
 +
 +/** @brief Immediately suspend the execution of all processes within the given VM.
 + *  @ingroup msg_VMs
 + *
 + * This function stops the exection of the VM. All the processes on this VM
 + * will pause. The state of the VM is perserved. We can later resume it again.
 + *
 + * No suspension cost occurs.
 + */
 +void MSG_vm_suspend(msg_vm_t vm)
 +{
 +  simcall_vm_suspend(vm);
 +
 +  XBT_DEBUG("vm_suspend done");
 +
 +  #ifdef HAVE_TRACING
 +  TRACE_msg_vm_suspend(vm);
 +  #endif
  }
  
 -/**
 - * \ingroup msg_VMs
 - * \brief Reboot the VM, restarting all the processes in it.
 +
 +/** @brief Resume the execution of the VM. All processes on the VM run again.
 + *  @ingroup msg_VMs
 + *
 + * No resume cost occurs.
   */
 -void MSG_vm_reboot(msg_vm_t vm)
 +void MSG_vm_resume(msg_vm_t vm)
  {
 -  xbt_dynar_t process_list = xbt_dynar_new(sizeof(msg_process_t), NULL);
 -  msg_process_t process;
 -  unsigned int cpt;
 +  simcall_vm_resume(vm);
  
 -  xbt_dynar_foreach(vm->processes, cpt, process) {
 -    xbt_dynar_push_as(process_list, msg_process_t, process);
 -  }
 +  #ifdef HAVE_TRACING
 +  TRACE_msg_vm_resume(vm);
 +  #endif
 +}
  
 -  xbt_dynar_foreach(process_list, cpt, process) {
 -    msg_process_t new_process = MSG_process_restart(process);
 -    MSG_vm_bind(vm, new_process);
 -  }
  
 -  xbt_dynar_free(&process_list);
 +/** @brief Immediately save the execution of all processes within the given VM.
 + *  @ingroup msg_VMs
 + *
 + * This function stops the exection of the VM. All the processes on this VM
 + * will pause. The state of the VM is perserved. We can later resume it again.
 + *
 + * FIXME: No suspension cost occurs. If you want to simulate this too, you want to
 + * use a \ref MSG_file_write() before or after, depending on the exact semantic
 + * of VM save to you.
 + */
 +void MSG_vm_save(msg_vm_t vm)
 +{
 +  simcall_vm_save(vm);
 +  #ifdef HAVE_TRACING
 +  TRACE_msg_vm_save(vm);
 +  #endif
  }
  
 -/** @brief Destroy a msg_vm_t.
 +/** @brief Restore the execution of the VM. All processes on the VM run again.
   *  @ingroup msg_VMs
 + *
 + * FIXME: No restore cost occurs. If you want to simulate this too, you want to
 + * use a \ref MSG_file_read() before or after, depending on the exact semantic
 + * of VM restore to you.
   */
 -void MSG_vm_destroy(msg_vm_t vm) {
 -  unsigned int cpt;
 -  msg_process_t process;
 -  xbt_dynar_foreach(vm->processes,cpt,process) {
 -    //FIXME: Slow ?
 -    simdata_process_t simdata = simcall_process_get_data(process);
 -    simdata->vm = NULL;
 -  }
 +void MSG_vm_restore(msg_vm_t vm)
 +{
 +  simcall_vm_restore(vm);
  
    #ifdef HAVE_TRACING
 -  TRACE_msg_vm_end(vm);
 +  TRACE_msg_vm_restore(vm);
    #endif
 +}
 +
 +
 +/** @brief Get the physical host of a given VM.
 + *  @ingroup msg_VMs
 + */
 +msg_host_t MSG_vm_get_pm(msg_vm_t vm)
 +{
 +  return simcall_vm_get_pm(vm);
 +}
 +
 +
 +/** @brief Set a CPU bound for a given VM.
 + *  @ingroup msg_VMs
 + *
 + * 1.
 + * Note that in some cases MSG_task_set_bound() may not intuitively work for VMs.
 + *
 + * For example,
 + *  On PM0, there are Task1 and VM0.
 + *  On VM0, there is Task2.
 + * Now we bound 75% to Task1@PM0 and bound 25% to Task2@VM0.
 + * Then, 
 + *  Task1@PM0 gets 50%.
 + *  Task2@VM0 gets 25%.
 + * This is NOT 75% for Task1@PM0 and 25% for Task2@VM0, respectively.
 + *
 + * This is because a VM has the dummy CPU action in the PM layer. Putting a
 + * task on the VM does not affect the bound of the dummy CPU action. The bound
 + * of the dummy CPU action is unlimited.
 + *
 + * There are some solutions for this problem. One option is to update the bound
 + * of the dummy CPU action automatically. It should be the sum of all tasks on
 + * the VM. But, this solution might be costy, because we have to scan all tasks
 + * on the VM in share_resource() or we have to trap both the start and end of
 + * task execution.
 + *
 + * The current solution is to use MSG_vm_set_bound(), which allows us to
 + * directly set the bound of the dummy CPU action.
 + *
 + *
 + * 2.
 + * Note that bound == 0 means no bound (i.e., unlimited). But, if a host has
 + * multiple CPU cores, the CPU share of a computation task (or a VM) never
 + * exceeds the capacity of a CPU core.
 + */
 +void MSG_vm_set_bound(msg_vm_t vm, double bound)
 +{
 +      return simcall_vm_set_bound(vm, bound);
 +}
 +
 +
 +/** @brief Set the CPU affinity of a given VM.
 + *  @ingroup msg_VMs
 + *
 + * This function changes the CPU affinity of a given VM. Usage is the same as
 + * MSG_task_set_affinity(). See the MSG_task_set_affinity() for details.
 + */
 +void MSG_vm_set_affinity(msg_vm_t vm, msg_host_t pm, unsigned long mask)
 +{
 +  msg_host_priv_t priv = msg_host_resource_priv(vm);
 +
 +  if (mask == 0)
 +    xbt_dict_remove_ext(priv->affinity_mask_db, (char *) pm, sizeof(pm));
 +  else
 +    xbt_dict_set_ext(priv->affinity_mask_db, (char *) pm, sizeof(pm), (void *) mask, NULL);
  
 -  xbt_free(vm->name);
 -  xbt_dynar_free(&vm->processes);
 -  xbt_free(vm);
 +  msg_host_t pm_now = MSG_vm_get_pm(vm);
 +  if (pm_now == pm) {
 +    XBT_INFO("set affinity(0x%04lx@%s) for %s", mask, MSG_host_get_name(pm), MSG_host_get_name(vm));
 +    simcall_vm_set_affinity(vm, pm, mask);
 +  } else
 +    XBT_INFO("set affinity(0x%04lx@%s) for %s (not active now)", mask, MSG_host_get_name(pm), MSG_host_get_name(vm));
  }
diff --combined src/simdag/sd_global.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2006-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -95,8 -95,27 +95,27 @@@ void SD_init(int *argc, char **argv
    XBT_DEBUG("ADD SD LEVELS");
    SD_HOST_LEVEL = xbt_lib_add_level(host_lib,__SD_workstation_destroy);
    SD_LINK_LEVEL = xbt_lib_add_level(link_lib,__SD_link_destroy);
+   SD_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,__SD_storage_destroy);
+   if (_sg_cfg_exit_asap) {
+     SD_exit();
+     exit(0);
+   }
  }
  
+ /** \brief set a configuration variable
+  *
+  * Do --help on any simgrid binary to see the list of currently existing configuration variables, and see Section @ref options.
+  *
+  * Example:
+  * SD_config("workstation/model","default");
+  */
+ void SD_config(const char *key, const char *value){
+   xbt_assert(sd_global,"ERROR: Please call SD_init() before using SD_config()");
+   xbt_cfg_set_as_string(_sg_cfg_set, key, value);
+ }
  /**
   * \brief Reinits the application part of the simulation (experimental feature)
   *
@@@ -191,10 -210,11 +210,11 @@@ void SD_create_environment(const char *
    char *name = NULL;
    void **surf_workstation = NULL;
    void **surf_link = NULL;
+   void **surf_storage = NULL;
  
    parse_platform_file(platform_file);
  
-   /* now let's create the SD wrappers for workstations and links */
+   /* now let's create the SD wrappers for workstations, storages and links */
    xbt_lib_foreach(host_lib, cursor, name, surf_workstation){
      if(surf_workstation[SURF_WKS_LEVEL])
        __SD_workstation_create(surf_workstation[SURF_WKS_LEVEL], NULL);
      __SD_link_create(surf_link[SURF_LINK_LEVEL], NULL);
    }
  
+   xbt_lib_foreach(storage_lib, cursor, name, surf_storage) {
+   if(surf_storage[SURF_STORAGE_LEVEL])
+     __SD_storage_create(surf_storage[SURF_STORAGE_LEVEL], NULL);
+   }
    XBT_DEBUG("Workstation number: %d, link number: %d",
           SD_workstation_get_number(), SD_link_get_number());
  #ifdef HAVE_JEDULE
@@@ -284,7 -310,6 +310,7 @@@ xbt_swag_t SD_simulate_swag(double how_
      if (elapsed_time > 0.0)
        total_time += elapsed_time;
  
 +    /* FIXME: shoud look at model_list or model_list_invoke? */
      /* let's see which tasks are done */
      xbt_dynar_foreach(model_list, iter, model) {
        while ((action = xbt_swag_extract(model->states.done_action_set))) {
diff --combined src/simgrid/sg_config.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2009-2010, 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -11,7 -11,7 +11,7 @@@
  #include "xbt/log.h"
  #include "xbt/mallocator.h"
  #include "xbt/str.h"
- #include "xbt/lib.h" 
+ #include "xbt/lib.h"
  #include "xbt/sysdep.h"
  #include "surf/surf.h"
  #include "surf/maxmin.h"
  #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");
  
  xbt_cfg_t _sg_cfg_set = NULL;
  
- int _sg_init_status = 0;      /* 0: beginning of time (config cannot be changed yet);
-                                   1: initialized: cfg_set created (config can now be changed);
-                                   2: configured: command line parsed and config part of platform file was integrated also, platform construction ongoing or done.
-                                      (Config cannot be changed anymore!) */
+ /* 0: beginning of time (config cannot be changed yet);
+  * 1: initialized: cfg_set created (config can now be changed);
+  * 2: configured: command line parsed and config part of platform file was
+  *    integrated also, platform construction ongoing or done.
+  *    (Config cannot be changed anymore!)
+  */
+ int _sg_cfg_init_status = 0;
+ /* instruct the upper layer (simix or simdag) to exit as soon as possible
+  */
+ int _sg_cfg_exit_asap = 0;
+ #define sg_cfg_exit_early() do { _sg_cfg_exit_asap = 1; return; } while (0)
  
  /* Parse the command line, looking for options */
  static void sg_config_cmd_line(int *argc, char **argv)
      argv[j] = NULL;
      *argc = j;
    }
-   if (shall_exit) {
-     _sg_init_status=1; // get everything cleanly cleaned on exit
-     exit(0);
-   }
+   if (shall_exit)
+     sg_cfg_exit_early();
  }
  
  /* callback of the workstation/model variable */
@@@ -105,14 -111,14 +112,14 @@@ static void _sg_cfg_cb__workstation_mod
  {
    char *val;
  
-   xbt_assert(_sg_init_status == 1,
+   xbt_assert(_sg_cfg_init_status < 2,
                "Cannot change the model after the initialization");
  
    val = xbt_cfg_get_string(_sg_cfg_set, name);
  
    if (!strcmp(val, "help")) {
      model_help("workstation", surf_workstation_model_description);
-     exit(0);
+     sg_cfg_exit_early();
    }
  
    /* Make sure that the model exists */
@@@ -124,14 -130,14 +131,14 @@@ static void _sg_cfg_cb__cpu_model(cons
  {
    char *val;
  
-   xbt_assert(_sg_init_status == 1,
+   xbt_assert(_sg_cfg_init_status < 2,
                "Cannot change the model after the initialization");
  
    val = xbt_cfg_get_string(_sg_cfg_set, name);
  
    if (!strcmp(val, "help")) {
      model_help("CPU", surf_cpu_model_description);
-     exit(0);
+     sg_cfg_exit_early();
    }
  
    /* New Module missing */
@@@ -143,14 -149,14 +150,14 @@@ static void _sg_cfg_cb__optimization_mo
  {
    char *val;
  
-   xbt_assert(_sg_init_status == 1,
+   xbt_assert(_sg_cfg_init_status < 2,
                "Cannot change the model after the initialization");
  
    val = xbt_cfg_get_string(_sg_cfg_set, name);
  
    if (!strcmp(val, "help")) {
      model_help("optimization", surf_optimization_mode_description);
-     exit(0);
+     sg_cfg_exit_early();
    }
  
    /* New Module missing */
@@@ -162,14 -168,14 +169,14 @@@ static void _sg_cfg_cb__storage_mode(co
  {
    char *val;
  
-   xbt_assert(_sg_init_status == 1,
+   xbt_assert(_sg_cfg_init_status < 2,
                "Cannot change the model after the initialization");
  
    val = xbt_cfg_get_string(_sg_cfg_set, name);
  
    if (!strcmp(val, "help")) {
      model_help("storage", surf_storage_model_description);
-     exit(0);
+     sg_cfg_exit_early();
    }
  
    /* New Module missing */
@@@ -181,21 -187,20 +188,20 @@@ static void _sg_cfg_cb__network_model(c
  {
    char *val;
  
-   xbt_assert(_sg_init_status == 1,
+   xbt_assert(_sg_cfg_init_status < 2,
                "Cannot change the model after the initialization");
  
    val = xbt_cfg_get_string(_sg_cfg_set, name);
  
    if (!strcmp(val, "help")) {
      model_help("network", surf_network_model_description);
-     exit(0);
+     sg_cfg_exit_early();
    }
  
    /* New Module missing */
    find_model_description(surf_network_model_description, val);
  }
  
  /* callbacks of the network models values */
  static void _sg_cfg_cb__tcp_gamma(const char *name, int pos)
  {
@@@ -230,19 -235,19 +236,19 @@@ static void _sg_cfg_cb__weight_S(const 
  #ifdef HAVE_SMPI
  /* callback of the mpi collectives */
  static void _sg_cfg_cb__coll(const char *category,
-                            s_mpi_coll_description_t * table,
-                            const char *name, int pos)
+                              s_mpi_coll_description_t * table,
+                              const char *name, int pos)
  {
    char *val;
  
-   xbt_assert(_sg_init_status == 1,
+   xbt_assert(_sg_cfg_init_status < 2,
                "Cannot change the model after the initialization");
  
    val = xbt_cfg_get_string(_sg_cfg_set, name);
  
    if (!strcmp(val, "help")) {
      coll_help(category, table);
-     exit(0);
+     sg_cfg_exit_early();
    }
  
    /* New Module missing */
@@@ -263,19 -268,19 +269,19 @@@ static void _sg_cfg_cb__coll_allreduce(
  }
  static void _sg_cfg_cb__coll_alltoall(const char *name, int pos)
  {
-   _sg_cfg_cb__coll("alltoall", mpi_coll_alltoall_description, name, 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);  
+   _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);  
+   _sg_cfg_cb__coll("bcast", mpi_coll_bcast_description, name, pos);
  }
  static void _sg_cfg_cb__coll_reduce(const char *name, int pos)
  {
-   _sg_cfg_cb__coll("reduce", mpi_coll_reduce_description, name, pos);  
+   _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);
@@@ -319,8 -324,15 +325,15 @@@ static void _sg_cfg_cb_verbose_exit(con
    _sg_do_verbose_exit = xbt_cfg_get_boolean(_sg_cfg_set, name);
  }
  
+ extern int _sg_do_clean_atexit;
  
- static void _sg_cfg_cb_context_factory(const char *name, int pos) {
+ static void _sg_cfg_cb_clean_atexit(const char *name, int pos)
+ {
+   _sg_do_clean_atexit = xbt_cfg_get_boolean(_sg_cfg_set, name);
+ }
+ static void _sg_cfg_cb_context_factory(const char *name, int pos)
+ {
    smx_context_factory_name = xbt_cfg_get_string(_sg_cfg_set, name);
  }
  
@@@ -354,12 -366,12 +367,12 @@@ static void _sg_cfg_cb_contexts_paralle
    }
    else {
      xbt_die("Command line setting of the parallel synchronization mode should "
-         "be one of \"posix\", \"futex\" or \"busy_wait\"");
+             "be one of \"posix\", \"futex\" or \"busy_wait\"");
    }
  }
  
  static void _sg_cfg_cb__surf_network_coordinates(const char *name,
-                                                    int pos)
+                                                  int pos)
  {
    int val = xbt_cfg_get_boolean(_sg_cfg_set, name);
    if (val) {
@@@ -393,14 -405,12 +406,12 @@@ static void _sg_cfg_cb__gtnets_jitter_s
  /* create the config set, register what should be and parse the command line*/
  void sg_config_init(int *argc, char **argv)
  {
-   char *description = xbt_malloc(1024), *p = description;
-   char *default_value;
-   double double_default_value;
-   int default_value_int;
+   char *description = xbt_malloc(1024);
+   char *p;
    int i;
  
    /* Create the configuration support */
-   if (_sg_init_status == 0) { /* Only create stuff if not already inited */
+   if (_sg_cfg_init_status == 0) { /* Only create stuff if not already inited */
      sprintf(description,
              "The model to use for the CPU. Possible values: ");
      p = description;
                     surf_cpu_model_description[i].name);
      sprintf(p,
              ".\n       (use 'help' as a value to see the long description of each model)");
-     default_value = xbt_strdup("Cas01");
-     xbt_cfg_register(&_sg_cfg_set, "cpu/model", description, xbt_cfgelm_string,
-                      &default_value, 1, 1, &_sg_cfg_cb__cpu_model, NULL);
+     xbt_cfg_register(&_sg_cfg_set, "cpu/model", description,
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__cpu_model, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/model", "Cas01");
  
-     sprintf(description,
-             "The optimization modes to use for the CPU. Possible values: ");
-     p = description;
      while (*(++p) != '\0');
      for (i = 0; surf_optimization_mode_description[i].name; i++)
        p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
                     surf_optimization_mode_description[i].name);
      sprintf(p,
              ".\n       (use 'help' as a value to see the long description of each optimization mode)");
-     default_value = xbt_strdup("Lazy");
-     xbt_cfg_register(&_sg_cfg_set, "cpu/optim", description, xbt_cfgelm_string,
-                      &default_value, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
+     xbt_cfg_register(&_sg_cfg_set, "cpu/optim", description,
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "cpu/optim", "Lazy");
  
      sprintf(description,
              "The model to use for the storage. Possible values: ");
                     surf_storage_model_description[i].name);
      sprintf(p,
              ".\n       (use 'help' as a value to see the long description of each model)");
-     default_value = xbt_strdup("default");
-     xbt_cfg_register(&_sg_cfg_set, "storage/model", description, xbt_cfgelm_string,
-                      &default_value, 1, 1, &_sg_cfg_cb__storage_mode,
-                      NULL);
+     xbt_cfg_register(&_sg_cfg_set, "storage/model", description,
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "storage/model", "default");
  
      /* ********************************************************************* */
      /* TUTORIAL: New model                                                   */
                     surf_new_model_description[i].name);
      sprintf(p,
              ".\n       (use 'help' as a value to see the long description of each model)");
-     default_value = xbt_strdup("default");
-     xbt_cfg_register(&_sg_cfg_set, "new_model/model", description, xbt_cfgelm_string,
-                      &default_value, 1, 1, &_sg_cfg_cb__storage_mode,
-                      NULL);
+     xbt_cfg_register(&_sg_cfg_set, "new_model/model", description,
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "new_model/model", "default");
      /* ********************************************************************* */
  
      sprintf(description,
                     surf_network_model_description[i].name);
      sprintf(p,
              ".\n       (use 'help' as a value to see the long description of each model)");
-     default_value = xbt_strdup("LV08");
-     xbt_cfg_register(&_sg_cfg_set, "network/model", description, xbt_cfgelm_string,
-                      &default_value, 1, 1, &_sg_cfg_cb__network_model,
-                      NULL);
+     xbt_cfg_register(&_sg_cfg_set, "network/model", description,
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__network_model, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "network/model", "LV08");
  
      sprintf(description,
              "The optimization modes to use for the network. Possible values: ");
                     surf_optimization_mode_description[i].name);
      sprintf(p,
              ".\n       (use 'help' as a value to see the long description of each optimization mode)");
-     default_value = xbt_strdup("Lazy");
-     xbt_cfg_register(&_sg_cfg_set, "network/optim", description, xbt_cfgelm_string,
-                      &default_value, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
+     xbt_cfg_register(&_sg_cfg_set, "network/optim", description,
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__optimization_mode, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "network/optim", "Lazy");
  
      sprintf(description,
              "The model to use for the workstation. Possible values: ");
                     surf_workstation_model_description[i].name);
      sprintf(p,
              ".\n       (use 'help' as a value to see the long description of each model)");
-     default_value = xbt_strdup("default");
-     xbt_cfg_register(&_sg_cfg_set, "workstation/model", description, xbt_cfgelm_string,
-                      &default_value, 1, 1,
-                      &_sg_cfg_cb__workstation_model, NULL);
-     xbt_free(description);
+     xbt_cfg_register(&_sg_cfg_set, "workstation/model", description,
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__workstation_model, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "workstation/model", "default");
  
      xbt_cfg_register(&_sg_cfg_set, "network/TCP_gamma",
                       "Size of the biggest TCP window (cat /proc/sys/net/ipv4/tcp_[rw]mem for recv/send window; Use the last given value, which is the max window size)",
-                      xbt_cfgelm_double, NULL, 1, 1,
-                      _sg_cfg_cb__tcp_gamma, NULL);
+                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__tcp_gamma, NULL);
      xbt_cfg_setdefault_double(_sg_cfg_set, "network/TCP_gamma", 4194304.0);
  
      xbt_cfg_register(&_sg_cfg_set, "maxmin/precision",
                       "Numerical precision used when updating simulation models (epsilon in double comparisons)",
-                      xbt_cfgelm_double, NULL, 1, 1, _sg_cfg_cb__maxmin_precision, NULL);
-     xbt_cfg_setdefault_double(_sg_cfg_set, "maxmin/precision", 0.00001); 
+                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__maxmin_precision, NULL);
+     xbt_cfg_setdefault_double(_sg_cfg_set, "maxmin/precision", 0.00001);
  
      /* The parameters of network models */
  
      xbt_cfg_register(&_sg_cfg_set, "network/sender_gap",
                       "Minimum gap between two overlapping sends",
-                      xbt_cfgelm_double, NULL, 1, 1, /* default is set in network.c */
-                      _sg_cfg_cb__sender_gap, NULL);
+                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__sender_gap, NULL);
+     /* default for "network/sender_gap" is set in network.c */
  
-     double_default_value = 1.0; // FIXME use setdefault everywhere here!
      xbt_cfg_register(&_sg_cfg_set, "network/latency_factor",
                       "Correction factor to apply to the provided latency (default value set by network model)",
-                      xbt_cfgelm_double, &double_default_value, 1, 1,
-                      _sg_cfg_cb__latency_factor, NULL);
-     double_default_value = 1.0;
+                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__latency_factor, NULL);
+     xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 1.0);
      xbt_cfg_register(&_sg_cfg_set, "network/bandwidth_factor",
                       "Correction factor to apply to the provided bandwidth (default value set by network model)",
-                      xbt_cfgelm_double, &double_default_value, 1, 1,
-                      _sg_cfg_cb__bandwidth_factor, NULL);
+                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__bandwidth_factor, NULL);
+     xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor", 1.0);
  
      xbt_cfg_register(&_sg_cfg_set, "network/weight_S",
                       "Correction factor to apply to the weight of competing streams (default value set by network model)",
-                      xbt_cfgelm_double, NULL, 1, 1, /* default is set in network.c */
-                      _sg_cfg_cb__weight_S, NULL);
+                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__weight_S, NULL);
+     /* default for "network/weight_S" is set in network.c */
  
      /* Inclusion path */
      xbt_cfg_register(&_sg_cfg_set, "path",
                       "Lookup path for inclusions in platform and deployment XML files",
-                      xbt_cfgelm_string, NULL, 0, 0,
-                      _sg_cfg_cb__surf_path, NULL);
+                      xbt_cfgelm_string, 0, 0, _sg_cfg_cb__surf_path, NULL);
  
-     default_value = xbt_strdup("off");
      xbt_cfg_register(&_sg_cfg_set, "cpu/maxmin_selective_update",
                       "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 = xbt_strdup("off");
+                      xbt_cfgelm_boolean, 0, 1, NULL, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "cpu/maxmin_selective_update", "no");
      xbt_cfg_register(&_sg_cfg_set, "network/maxmin_selective_update",
                       "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);
+                      xbt_cfgelm_boolean, 0, 1, NULL, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/maxmin_selective_update", "no");
  
  #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_boolean, NULL, 0, 1,
-                      _sg_cfg_cb_model_check, NULL);
-     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", default_value);
+                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_model_check, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check", "no");
  
      /* 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: off => stateless verification). "
+                      "Specify the amount of steps between checkpoints during stateful model-checking (default: 0 => 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_boolean(_sg_cfg_set, "model-check/checkpoint", default_value);
-     
+                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_checkpoint, NULL);
+     xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/checkpoint", 0);
      /* do liveness model-checking */
      xbt_cfg_register(&_sg_cfg_set, "model-check/property",
                       "Specify the name of the file containing the property. It must be the result of the ltl2ba program.",
-                      xbt_cfgelm_string, NULL, 0, 1,
-                      _mc_cfg_cb_property, NULL);
+                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_property, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/property", "");
  
      /* Specify the kind of model-checking reduction */
      xbt_cfg_register(&_sg_cfg_set, "model-check/reduction",
                       "Specify the kind of exploration reduction (either none or DPOR)",
-                      xbt_cfgelm_string, NULL, 0, 1,
-                      _mc_cfg_cb_reduce, NULL);
+                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_reduce, NULL);
      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_boolean, NULL, 0, 1,
-                      _mc_cfg_cb_timeout, NULL);
-     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", default_value);
+                      xbt_cfgelm_boolean, 0, 1, _mc_cfg_cb_timeout, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "model-check/timeout", "no");
  
      /* Set max depth exploration */
      xbt_cfg_register(&_sg_cfg_set, "model-check/max_depth",
                       "Specify the max depth of exploration (default : 1000)",
-                      xbt_cfgelm_int, NULL, 0, 1,
-                      _mc_cfg_cb_max_depth, NULL);
+                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_max_depth, NULL);
      xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/max_depth", 1000);
  
      /* Set number of visited state stored for state comparison reduction*/
      xbt_cfg_register(&_sg_cfg_set, "model-check/visited",
                       "Specify the number of visited state stored for state comparison reduction. If value=5, the last 5 visited states are stored",
-                      xbt_cfgelm_int, NULL, 0, 1,
-                      _mc_cfg_cb_visited, NULL);
+                      xbt_cfgelm_int, 0, 1, _mc_cfg_cb_visited, NULL);
      xbt_cfg_setdefault_int(_sg_cfg_set, "model-check/visited", 0);
  
      /* Set file name for dot output of graph state */
      xbt_cfg_register(&_sg_cfg_set, "model-check/dot_output",
                       "Specify the name of dot file corresponding to graph state",
-                      xbt_cfgelm_string, NULL, 0, 1,
-                      _mc_cfg_cb_dot_output, NULL);
+                      xbt_cfgelm_string, 0, 1, _mc_cfg_cb_dot_output, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "model-check/dot_output", "");
  #endif
  
      /* do verbose-exit */
-     default_value = xbt_strdup("on");
      xbt_cfg_register(&_sg_cfg_set, "verbose-exit",
                       "Activate the \"do nothing\" mode in Ctrl-C",
-                      xbt_cfgelm_boolean, &default_value, 0, 1,
-                      _sg_cfg_cb_verbose_exit, NULL);
-     
-     
+                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb_verbose_exit, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "verbose-exit", "yes");
      /* context factory */
-     default_value = xbt_strdup("ucontext");
-     xbt_cfg_register(&_sg_cfg_set, "contexts/factory",
-                      "Context factory to use in SIMIX (ucontext, thread or raw)",
-                      xbt_cfgelm_string, &default_value, 1, 1, _sg_cfg_cb_context_factory, NULL);
+     sprintf(description,
+             "Context factory to use in SIMIX. Possible values: thread");
+     const char *dflt_ctx_fact = "thread";
+ #ifdef CONTEXT_UCONTEXT
+     strcat(description, ", ucontext");
+     dflt_ctx_fact = "ucontext";
+ #endif
+ #ifdef HAVE_RAWCTX
+     strcat(description, ", raw");
+     dflt_ctx_fact = "raw";
+ #endif
+     strcat(description, ".");
+     xbt_cfg_register(&_sg_cfg_set, "contexts/factory", description,
+                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_context_factory, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/factory", dflt_ctx_fact);
  
      /* stack size of contexts in Ko */
-     default_value_int = 128;
      xbt_cfg_register(&_sg_cfg_set, "contexts/stack_size",
-                      "Stack size of contexts in Kib (ucontext or raw only)",
-                      xbt_cfgelm_int, &default_value_int, 1, 1,
-                      _sg_cfg_cb_context_stack_size, NULL);
+                      "Stack size of contexts in Kib",
+                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_context_stack_size, NULL);
+     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/stack_size", 128);
  
      /* number of parallel threads for user processes */
-     default_value_int = 1;
      xbt_cfg_register(&_sg_cfg_set, "contexts/nthreads",
                       "Number of parallel threads used to execute user contexts",
-                      xbt_cfgelm_int, &default_value_int, 1, 1,
-                      _sg_cfg_cb_contexts_nthreads, NULL);
+                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_nthreads, NULL);
+     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/nthreads", 1);
  
      /* minimal number of user contexts to be run in parallel */
-     default_value_int = 2;
      xbt_cfg_register(&_sg_cfg_set, "contexts/parallel_threshold",
-         "Minimal number of user contexts to be run in parallel (raw contexts only)",
-         xbt_cfgelm_int, &default_value_int, 1, 1,
-         _sg_cfg_cb_contexts_parallel_threshold, NULL);
+                      "Minimal number of user contexts to be run in parallel (raw contexts only)",
+                      xbt_cfgelm_int, 1, 1, _sg_cfg_cb_contexts_parallel_threshold, NULL);
+     xbt_cfg_setdefault_int(_sg_cfg_set, "contexts/parallel_threshold", 2);
  
      /* synchronization mode for parallel user contexts */
+     xbt_cfg_register(&_sg_cfg_set, "contexts/synchro",
+                      "Synchronization mode to use when running contexts in parallel (either futex, posix or busy_wait)",
+                      xbt_cfgelm_string, 1, 1, _sg_cfg_cb_contexts_parallel_mode, NULL);
  #ifdef HAVE_FUTEX_H
-     default_value = xbt_strdup("futex");
+     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "futex");
  #else //No futex on mac and posix is unimplememted yet
-     default_value = xbt_strdup("busy_wait");
+     xbt_cfg_setdefault_string(_sg_cfg_set, "contexts/synchro", "busy_wait");
  #endif
-     xbt_cfg_register(&_sg_cfg_set, "contexts/synchro",
-         "Synchronization mode to use when running contexts in parallel (either futex, posix or busy_wait)",
-         xbt_cfgelm_string, &default_value, 1, 1,
-         _sg_cfg_cb_contexts_parallel_mode, 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_boolean, &default_value, 1, 1,
-                      _sg_cfg_cb__surf_network_coordinates, NULL);
-     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", default_value);
+                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb__surf_network_coordinates, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/coordinates", "no");
  
-     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_boolean, &default_value, 0, 1,
-                      _sg_cfg_cb__surf_network_crosstraffic, NULL);
-     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", default_value);
+                      xbt_cfgelm_boolean, 0, 1, _sg_cfg_cb__surf_network_crosstraffic, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "no");
  
  #ifdef HAVE_GTNETS
      xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter",
                       "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)",
-                      xbt_cfgelm_double, NULL, 1, 1,
-                      _sg_cfg_cb__gtnets_jitter, NULL);
+                      xbt_cfgelm_double, 1, 1, _sg_cfg_cb__gtnets_jitter, NULL);
      xbt_cfg_setdefault_double(_sg_cfg_set, "gtnets/jitter", 0.0);
  
-     default_value_int = 10;
      xbt_cfg_register(&_sg_cfg_set, "gtnets/jitter_seed",
                       "Use a positive seed to reproduce jitted results, value must be in [1,1e8], default is 10",
-                      xbt_cfgelm_int, &default_value_int, 0, 1,
-                      _sg_cfg_cb__gtnets_jitter_seed, NULL);
+                      xbt_cfgelm_int, 0, 1, _sg_cfg_cb__gtnets_jitter_seed, NULL);
+     xbt_cfg_setdefault_int(_sg_cfg_set, "gtnets/jitter_seed", 10);
  #endif
  #ifdef HAVE_NS3
      xbt_cfg_register(&_sg_cfg_set, "ns3/TcpModel",
                       "The ns3 tcp model can be : NewReno or Reno or Tahoe",
-                      xbt_cfgelm_string, NULL, 1, 1,
-                      NULL, NULL);
+                      xbt_cfgelm_string, 1, 1, NULL, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "ns3/TcpModel", "default");
  #endif
  
  #ifdef HAVE_SMPI
-     double default_reference_speed = 20000.0;
      xbt_cfg_register(&_sg_cfg_set, "smpi/running_power",
                       "Power of the host running the simulation (in flop/s). Used to bench the operations.",
-                      xbt_cfgelm_double, &default_reference_speed, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_double, 1, 1, NULL, NULL);
+     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/running_power", 20000.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_boolean, &default_value, 1, 1, NULL,
-                      NULL);
-     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", default_value);
+                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/display_timing", "no");
+     xbt_cfg_register(&_sg_cfg_set, "smpi/use_shared_malloc",
+                      "Boolean indicating whether we should use shared memory when using SMPI_SHARED_MALLOC. Allows user to disable it for debug purposes.",
+                      xbt_cfgelm_boolean, 1, 1, NULL, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "smpi/use_shared_malloc", "yes");
  
-     double default_threshold = 1e-6;
      xbt_cfg_register(&_sg_cfg_set, "smpi/cpu_threshold",
                       "Minimal computation time (in seconds) not discarded.",
-                      xbt_cfgelm_double, &default_threshold, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_double, 1, 1, NULL, NULL);
+     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/cpu_threshold", 1e-6);
  
-     int default_small_messages_threshold = 0;
      xbt_cfg_register(&_sg_cfg_set, "smpi/async_small_thres",
                       "Maximal size of messages that are to be sent asynchronously, without waiting for the receiver",
-                      xbt_cfgelm_int, &default_small_messages_threshold, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_int, 1, 1, NULL, NULL);
+     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/async_small_thres", 0);
  
-     int default_send_is_detached_threshold = 65536;
      xbt_cfg_register(&_sg_cfg_set, "smpi/send_is_detached_thres",
                       "Threshold of message size where MPI_Send stops behaving like MPI_Isend and becomes MPI_Ssend",
-                      xbt_cfgelm_int, &default_send_is_detached_threshold, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_int, 1, 1, NULL, NULL);
+     xbt_cfg_setdefault_int(_sg_cfg_set, "smpi/send_is_detached_thres", 65536);
  
      //For smpi/bw_factor and smpi/lat_factor
      //Default value have to be "threshold0:value0;threshold1:value1;...;thresholdN:valueN"
      //  or with tag config put line <prop id="smpi/bw_factor" value="threshold0:value0;threshold1:value1;...;thresholdN:valueN"></prop>
      xbt_cfg_register(&_sg_cfg_set, "smpi/bw_factor",
                       "Bandwidth factors for smpi.",
-                      xbt_cfgelm_string, NULL, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_string, 1, 1, NULL, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/bw_factor", "65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493;1426:0.608902;732:0.341987;257:0.338112;0:0.812084");
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/lat_factor",
                       "Latency factors for smpi.",
-                      xbt_cfgelm_string, NULL, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_string, 1, 1, NULL, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/lat_factor", "65472:11.6436;15424:3.48845;9376:2.59299;5776:2.18796;3484:1.88101;1426:1.61075;732:1.9503;257:1.95341;0:2.01467");
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/os",
                       "Small messages timings (MPI_Send minimum time for small messages)",
-                      xbt_cfgelm_string, NULL, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_string, 1, 1, NULL, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/os", "1:0:0:0:0");
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/ois",
                       "Small messages timings (MPI_Isend minimum time for small messages)",
-                      xbt_cfgelm_string, NULL, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_string, 1, 1, NULL, NULL);
      xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/ois", "1:0:0:0:0");
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/or",
                       "Small messages timings (MPI_Recv minimum time for small messages)",
-                      xbt_cfgelm_string, NULL, 1, 1, NULL,
-                      NULL);
+                      xbt_cfgelm_string, 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_cfgelm_double, 1, 1, NULL, NULL);
+     xbt_cfg_setdefault_double(_sg_cfg_set, "smpi/iprobe", 1e-4);
      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);
-                    
+                      "Which collective selector to use",
+                      xbt_cfgelm_string, 1, 1, NULL, NULL);
+     xbt_cfg_setdefault_string(_sg_cfg_set, "smpi/coll_selector", "default");
+     xbt_cfg_register(&_sg_cfg_set, "smpi/gather",
+                      "Which collective to use for gather",
+                      xbt_cfgelm_string, 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, NULL, 1, 1, &_sg_cfg_cb__coll_allgather,
-                    NULL);
+                      "Which collective to use for allgather",
+                      xbt_cfgelm_string, 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);
+                      "Which collective to use for barrier",
+                      xbt_cfgelm_string, 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);
+                      "Which collective to use for reduce_scatter",
+                      xbt_cfgelm_string, 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);
+                      "Which collective to use for scatter",
+                      xbt_cfgelm_string, 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);
+                      "Which collective to use for allgatherv",
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allgatherv, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/allreduce",
-                    "Which collective to use for allreduce",
-                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_allreduce,
-                    NULL);
+                      "Which collective to use for allreduce",
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_allreduce, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/alltoall",
-                    "Which collective to use for alltoall",
-                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_alltoall,
-                    NULL);
+                      "Which collective to use for alltoall",
+                      xbt_cfgelm_string, 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);
+                      "Which collective to use for alltoallv",
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_alltoallv, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/bcast",
-                    "Which collective to use for bcast",
-                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_bcast,
-                    NULL);
+                      "Which collective to use for bcast",
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_bcast, NULL);
  
      xbt_cfg_register(&_sg_cfg_set, "smpi/reduce",
-                    "Which collective to use for reduce",
-                    xbt_cfgelm_string, NULL, 1, 1, &_sg_cfg_cb__coll_reduce,
-                    NULL);
+                      "Which collective to use for reduce",
+                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__coll_reduce, NULL);
  #endif // HAVE_SMPI
  
+     xbt_cfg_register(&_sg_cfg_set, "clean_atexit",
+                      "\"yes\" or \"no\". \"yes\" enables all the cleanups of SimGrid (XBT,SIMIX,MSG) to be registered with atexit. \"no\" may be useful if your code segfaults when calling the exit function.",
+                      xbt_cfgelm_boolean, 1, 1, _sg_cfg_cb_clean_atexit, NULL);
+     xbt_cfg_setdefault_boolean(_sg_cfg_set, "clean_atexit", "yes");
      if (!surf_path) {
-       /* retrieves the current directory of the        current process */
+       /* retrieves the current directory of the current process */
        const char *initial_path = __surf_get_initial_path();
        xbt_assert((initial_path),
                    "__surf_get_initial_path() failed! Can't resolves current Windows directory");
        xbt_cfg_setdefault_string(_sg_cfg_set, "path", initial_path);
      }
  
-     _sg_init_status = 1;
+     _sg_cfg_init_status = 1;
  
      sg_config_cmd_line(argc, argv);
  
    } else {
      XBT_WARN("Call to sg_config_init() after initialization ignored");
    }
+   xbt_free(description);
  }
  
  void sg_config_finalize(void)
  {
-   if (!_sg_init_status)
+   if (!_sg_cfg_init_status)
      return;                     /* Not initialized yet. Nothing to do */
  
    xbt_cfg_free(&_sg_cfg_set);
-   _sg_init_status = 0;
+   _sg_cfg_init_status = 0;
  }
  
  /* Pick the right models for CPU, net and workstation, and call their model_init_preparse */
  void surf_config_models_setup()
  {
-   char *workstation_model_name;
+   const char *workstation_model_name;
    int workstation_id = -1;
    char *network_model_name = NULL;
    char *cpu_model_name = NULL;
     * the right net/cpu models.
     */
  
-   if((!xbt_cfg_is_default_value(_sg_cfg_set, "network/model") ||
-     !xbt_cfg_is_default_value(_sg_cfg_set, "cpu/model")) &&
-     xbt_cfg_is_default_value(_sg_cfg_set, "workstation/model"))
-   {
-       const char *val = "compound";
-       XBT_INFO
-           ("Switching workstation model to compound since you changed the network and/or cpu model(s)");
-       xbt_cfg_set_string(_sg_cfg_set, "workstation/model", val);
-       workstation_model_name = (char *) "compound";
+   if ((!xbt_cfg_is_default_value(_sg_cfg_set, "network/model") ||
+        !xbt_cfg_is_default_value(_sg_cfg_set, "cpu/model")) &&
+       xbt_cfg_is_default_value(_sg_cfg_set, "workstation/model")) {
+     XBT_INFO("Switching workstation model to compound since you changed the network and/or cpu model(s)");
+     workstation_model_name = "compound";
+     xbt_cfg_set_string(_sg_cfg_set, "workstation/model", workstation_model_name);
    }
  
    XBT_DEBUG("Workstation model: %s", workstation_model_name);
    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();
  
  int sg_cfg_get_int(const char* name)
  {
-       return xbt_cfg_get_int(_sg_cfg_set,name);
+   return xbt_cfg_get_int(_sg_cfg_set,name);
  }
  double sg_cfg_get_double(const char* name)
  {
-       return xbt_cfg_get_double(_sg_cfg_set,name);
+   return xbt_cfg_get_double(_sg_cfg_set,name);
  }
  char* sg_cfg_get_string(const char* name)
  {
-       return xbt_cfg_get_string(_sg_cfg_set,name);
+   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);
+   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);
+   xbt_cfg_get_peer(_sg_cfg_set,name, peer, port);
  }
  xbt_dynar_t sg_cfg_get_dynar(const char* name)
  {
-       return xbt_cfg_get_dynar(_sg_cfg_set,name);
+   return xbt_cfg_get_dynar(_sg_cfg_set,name);
  }
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007, 2009-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -36,23 -36,6 +36,23 @@@ static void parse_process(sg_platf_proc
    smx_process_arg_t arg = NULL;
    smx_process_t process_created = NULL;
  
-   arg->name = (char*)(arg->argv)[0];
 +  arg = xbt_new0(s_smx_process_arg_t, 1);
 +  arg->code = parse_code;
 +  arg->data = NULL;
 +  arg->hostname = sg_host_name(host);
 +  arg->argc = process->argc;
 +  arg->argv = xbt_new(char *,process->argc);
 +  int i;
 +  for (i=0; i<process->argc; i++)
 +    arg->argv[i] = xbt_strdup(process->argv[i]);
++  arg->name = xbt_strdup(arg->argv[0]);
 +  arg->kill_time = kill_time;
 +  arg->properties = current_property_set;
 +  if (!SIMIX_host_priv(host)->boot_processes) {
 +    SIMIX_host_priv(host)->boot_processes = xbt_dynar_new(sizeof(smx_process_arg_t), _SIMIX_host_free_process_arg);
 +  }
 +  xbt_dynar_push_as(SIMIX_host_priv(host)->boot_processes,smx_process_arg_t,arg);
 +
    if (start_time > SIMIX_get_clock()) {
      arg = xbt_new0(s_smx_process_arg_t, 1);
      arg->name = (char*)(process->argv)[0];
@@@ -84,7 -67,7 +84,7 @@@
      else
        simcall_process_create(&process_created, (char*)(process->argv)[0], parse_code, NULL, sg_host_name(host), kill_time, process->argc,
            (char**)process->argv, current_property_set,auto_restart);
 -
 +    
      /* verify if process has been created (won't be the case if the host is currently dead, but that's fine) */
      if (!process_created) {
        return;
diff --combined src/simix/smx_global.c
@@@ -1,4 -1,5 +1,5 @@@
- /* Copyright (c) 2007-2012. The SimGrid Team. All rights reserved.          */
+ /* Copyright (c) 2007-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
@@@ -10,6 -11,7 +11,7 @@@
  #include "xbt/str.h"
  #include "xbt/ex.h"             /* ex_backtrace_display */
  #include "mc/mc.h"
+ #include "simgrid/sg_config.h"
  
  XBT_LOG_NEW_CATEGORY(simix, "All SIMIX categories");
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_kernel, simix,
@@@ -107,8 -109,13 +109,13 @@@ void SIMIX_global_init(int *argc, char 
    }
  
    SIMIX_HOST_LEVEL = xbt_lib_add_level(host_lib,SIMIX_host_destroy);
+   SIMIX_STORAGE_LEVEL = xbt_lib_add_level(storage_lib, SIMIX_storage_destroy);
  
-   atexit(SIMIX_clean);
+   if (sg_cfg_get_boolean("clean_atexit"))
+     atexit(SIMIX_clean);
+   if (_sg_cfg_exit_asap)
+     exit(0);
  }
  
  /**
@@@ -157,7 -164,7 +164,7 @@@ static void SIMIX_clean(void
  
  #ifdef TIME_BENCH_AMDAHL
    xbt_os_cputimer_stop(simix_global->timer_seq);
-   XBT_INFO("Amdhal timing informations. Sequential time: %lf; Parallel time: %lf",
+   XBT_INFO("Amdahl timing informations. Sequential time: %f; Parallel time: %f",
             xbt_os_timer_elapsed(simix_global->timer_seq),
             xbt_os_timer_elapsed(simix_global->timer_par));
    xbt_os_timer_free(simix_global->timer_seq);
@@@ -323,23 -330,23 +330,33 @@@ void SIMIX_run(void
        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);
 +      }
      }
  
+     /* Autorestart all process */
+     if(host_that_restart) {
+       char *hostname = NULL;
+       xbt_dynar_foreach(host_that_restart,iter,hostname) {
+         XBT_INFO("Restart processes on host: %s",hostname);
+         SIMIX_host_autorestart(SIMIX_host_get_by_name(hostname));
+       }
+       xbt_dynar_reset(host_that_restart);
+     }
      /* 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) {
      TRACE_end();
  #endif
  
-     XBT_WARN("Oops ! Deadlock or code not perfectly clean.");
+     XBT_CRITICAL("Oops ! Deadlock or code not perfectly clean.");
      SIMIX_display_process_status();
      xbt_abort();
    }
diff --combined src/simix/smx_host.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007-2012. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -34,92 -34,10 +34,92 @@@ smx_host_t SIMIX_host_create(const cha
  
    /* Update global variables */
    xbt_lib_set(host_lib,name,SIMIX_HOST_LEVEL,smx_host);
-   
-   return xbt_lib_get_elm_or_null(host_lib, name);
+   return xbt_lib_get_or_null(host_lib, name, SIMIX_HOST_LEVEL);
  }
  
 +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 = SIMIX_host_priv(h);
 +
 +  xbt_assert((host != NULL), "Invalid parameters");
 +
 +  surf_model_t ws_model = surf_resource_model(h, SURF_WKS_LEVEL);
 +  if (ws_model->extension.workstation.get_state(h)==SURF_RESOURCE_OFF) {
 +    ws_model->extension.workstation.set_state(h, SURF_RESOURCE_ON);
 +    unsigned int cpt;
 +    smx_process_arg_t arg;
 +    xbt_dynar_foreach(host->boot_processes,cpt,arg) {
 +      smx_process_t process;
 +
 +      XBT_DEBUG("Booting Process %s(%s) right now", arg->argv[0], arg->hostname);
 +      if (simix_global->create_process_function) {
 +        simix_global->create_process_function(&process,
 +                                              arg->argv[0],
 +                                              arg->code,
 +                                              NULL,
 +                                              arg->hostname,
 +                                              arg->kill_time,
 +                                              arg->argc,
 +                                              arg->argv,
 +                                              arg->properties,
 +                                              arg->auto_restart);
 +      }
 +      else {
 +        simcall_process_create(&process,
 +                                              arg->argv[0],
 +                                              arg->code,
 +                                              NULL,
 +                                              arg->hostname,
 +                                              arg->kill_time,
 +                                              arg->argc,
 +                                              arg->argv,
 +                                              arg->properties,
 +                                              arg->auto_restart);
 +      }
 +    }
 +  }
 +}
 +
 +void SIMIX_pre_host_off(smx_simcall_t simcall, smx_host_t h)
 +{
 +  SIMIX_host_off(h, simcall->issuer);
 +}
 +
 +/**
 + * \brief Stop the host if it is on
 + *
 + */
 +void SIMIX_host_off(smx_host_t h, smx_process_t issuer)
 +{
 +  smx_host_priv_t host = SIMIX_host_priv(h);
 +
 +  xbt_assert((host != NULL), "Invalid parameters");
 +  
 +  surf_model_t ws_model = surf_resource_model(h, SURF_WKS_LEVEL);
 +  if (ws_model->extension.workstation.get_state(h)==SURF_RESOURCE_ON) {
 +    ws_model->extension.workstation.set_state(h, SURF_RESOURCE_OFF);
 +
 +    /* Clean Simulator data */
 +    if (xbt_swag_size(host->process_list) != 0) {
 +      smx_process_t process = NULL;
 +      xbt_swag_foreach(process, host->process_list) {
 +        SIMIX_process_kill(process, issuer);
 +      XBT_DEBUG("Killing %s on %s by %s", process->name,  sg_host_name(process->smx_host), issuer->name);
 +      }
 +    }
 +  }
 +}
 +
  /**
   * \brief Internal function to destroy a SIMIX host.
   *
@@@ -146,7 -64,6 +146,7 @@@ void SIMIX_host_destroy(void *h
      THROWF(arg_error, 0, "%s", msg);
    }
    xbt_dynar_free(&host->auto_restart_processes);
 +  xbt_dynar_free(&host->boot_processes);
    xbt_swag_free(host->process_list);
  
    /* Clean host structure */
@@@ -218,8 -135,7 +218,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){
@@@ -242,6 -158,16 +242,16 @@@ int SIMIX_host_get_core(smx_host_t host
        get_core(host);
  }
  
+ xbt_swag_t SIMIX_pre_host_get_process_list(smx_simcall_t simcall, smx_host_t host){
+   return SIMIX_host_get_process_list(host);
+ }
+ xbt_swag_t SIMIX_host_get_process_list(smx_host_t host){
+   xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+   smx_host_priv_t host_priv = SIMIX_host_priv(host);
+   return host_priv->process_list;
+ }
  
  
  double SIMIX_pre_host_get_available_speed(smx_simcall_t simcall, smx_host_t 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);
  }
  
+ double SIMIX_pre_host_get_current_power_peak(smx_simcall_t simcall, smx_host_t host){
+   return SIMIX_host_get_current_power_peak(host);
+ }
+ double SIMIX_host_get_current_power_peak(smx_host_t host) {
+         xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+         return surf_workstation_model->extension.workstation.
+                     get_current_power_peak(host);
+ }
+ double SIMIX_pre_host_get_power_peak_at(smx_simcall_t simcall, smx_host_t host, int pstate_index){
+   return SIMIX_host_get_power_peak_at(host, pstate_index);
+ }
+ double SIMIX_host_get_power_peak_at(smx_host_t host, int pstate_index) {
+         xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+         return surf_workstation_model->extension.workstation.
+             get_power_peak_at(host, pstate_index);
+ }
+ int SIMIX_pre_host_get_nb_pstates(smx_simcall_t simcall, smx_host_t host){
+   return SIMIX_host_get_nb_pstates(host);
+ }
+ int SIMIX_host_get_nb_pstates(smx_host_t host) {
+         xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+         return surf_workstation_model->extension.workstation.
+             get_nb_pstates(host);
+ }
+ void SIMIX_pre_host_set_power_peak_at(smx_simcall_t simcall, smx_host_t host, int pstate_index){
+   SIMIX_host_set_power_peak_at(host, pstate_index);
+ }
+ void SIMIX_host_set_power_peak_at(smx_host_t host, int pstate_index) {
+         xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+         surf_workstation_model->extension.workstation.
+             set_power_peak_at(host, pstate_index);
+ }
+ double SIMIX_pre_host_get_consumed_energy(smx_simcall_t simcall, smx_host_t host){
+   return SIMIX_host_get_consumed_energy(host);
+ }
+ double SIMIX_host_get_consumed_energy(smx_host_t host) {
+         xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+         return surf_workstation_model->extension.workstation.
+                     get_consumed_energy(host);
+ }
  int SIMIX_pre_host_get_state(smx_simcall_t simcall, smx_host_t host){
    return SIMIX_host_get_state(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){
@@@ -288,9 -263,13 +347,13 @@@ void* SIMIX_host_get_data(smx_host_t ho
    return SIMIX_host_priv(host)->data;
  }
  
 -static void _SIMIX_host_free_process_arg(void *data)
 +void _SIMIX_host_free_process_arg(void *data)
  {
    smx_process_arg_t arg = *(void**)data;
+   int i;
+   for (i = 0; i < arg->argc; i++)
+     xbt_free(arg->argv[i]);
+   xbt_free(arg->argv);
    xbt_free(arg->name);
    xbt_free(arg);
  }
@@@ -336,7 -315,7 +399,7 @@@ void SIMIX_host_add_auto_restart_proces
    if( SIMIX_host_get_state(host) == SURF_RESOURCE_OFF
        && !xbt_dict_get_or_null(watched_hosts_lib,sg_host_name(host))){
      xbt_dict_set(watched_hosts_lib,sg_host_name(host),host,NULL);
-     XBT_DEBUG("Have push host %s to watched_hosts_lib because state == SURF_RESOURCE_OFF",sg_host_name(host));
+     XBT_DEBUG("Have pushed host %s to watched_hosts_lib because state == SURF_RESOURCE_OFF",sg_host_name(host));
    }
    xbt_dynar_push_as(SIMIX_host_priv(host)->auto_restart_processes,smx_process_arg_t,arg);
  }
@@@ -347,7 -326,11 +410,11 @@@ void SIMIX_host_restart_processes(smx_h
  {
    unsigned int cpt;
    smx_process_arg_t arg;
-   xbt_dynar_foreach(SIMIX_host_priv(host)->auto_restart_processes,cpt,arg) {
+   xbt_dynar_t process_list = SIMIX_host_priv(host)->auto_restart_processes;
+   if (!process_list)
+     return;
+   xbt_dynar_foreach (process_list, cpt, arg) {
  
      smx_process_t process;
  
                                              arg->argv,
                                              arg->properties,
                                              arg->auto_restart);
-     }
-     else {
+     } else {
        simcall_process_create(&process,
-                                             arg->argv[0],
-                                             arg->code,
-                                             NULL,
-                                             arg->hostname,
-                                             arg->kill_time,
-                                             arg->argc,
-                                             arg->argv,
-                                             arg->properties,
-                                             arg->auto_restart);
+                              arg->argv[0],
+                              arg->code,
+                              NULL,
+                              arg->hostname,
+                              arg->kill_time,
+                              arg->argc,
+                              arg->argv,
+                              arg->properties,
+                              arg->auto_restart);
  
      }
+     /* arg->argv is used by the process created above.  Hide it to
+      * _SIMIX_host_free_process_arg() which is called by xbt_dynar_reset()
+      * below. */
+     arg->argc = 0;
+     arg->argv = NULL;
    }
-   xbt_dynar_reset(SIMIX_host_priv(host)->auto_restart_processes);
+   xbt_dynar_reset(process_list);
  }
  
  void SIMIX_host_autorestart(smx_host_t host)
@@@ -400,11 -387,11 +471,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, unsigned long affinity_mask){
 +  return SIMIX_host_execute(name, host, computation_amount, priority, bound, affinity_mask);
  }
  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, unsigned long affinity_mask){
  
    /* 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);
 +
 +    /* Note (hypervisor): for multicore, the bound value being passed to the
 +     * surf layer should not be zero (i.e., unlimited). It should be the
 +     * capacity of a CPU core. */
 +    if (bound == 0)
 +      ws_model->set_bound(action->execution.surf_exec, SIMIX_host_get_speed(host));
 +    else
 +      ws_model->set_bound(action->execution.surf_exec, bound);
 +
 +    if (affinity_mask != 0) {
 +      /* just a double check to confirm that this host is the host where this task is running. */
 +      xbt_assert(action->execution.host == host);
 +      ws_model->set_affinity(action->execution.surf_exec, host, affinity_mask);
 +    }
    }
  
    XBT_DEBUG("Create execute action %p", action);
@@@ -475,54 -449,28 +546,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);
@@@ -535,10 -483,8 +606,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;
  }
@@@ -563,40 -508,11 +634,40 @@@ 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_set_affinity(smx_simcall_t simcall,
 +    smx_action_t action, smx_host_t host, unsigned long mask){
 +  SIMIX_host_execution_set_affinity(action, host, mask);
 +}
 +void SIMIX_host_execution_set_affinity(smx_action_t action, smx_host_t host, unsigned long mask){
 +  surf_model_t ws_model = get_ws_model_from_action(action);
 +
 +  xbt_assert(action->type == SIMIX_ACTION_EXECUTE);
 +
 +  if (action->execution.surf_exec) {
 +    /* just a double check to confirm that this host is the host where this task is running. */
 +    xbt_assert(action->execution.host == host);
 +    ws_model->set_affinity(action->execution.surf_exec, host, mask);
 +  }
  }
  
  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) {
  
        case SIMIX_FAILED:
          XBT_DEBUG("SIMIX_execution_finished: host '%s' failed", sg_host_name(simcall->issuer->smx_host));
          simcall->issuer->context->iwannadie = 1;
-         //SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
+         SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
          break;
  
        case SIMIX_CANCELED:
              (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;
    }
  
@@@ -717,42 -626,20 +788,51 @@@ 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);
 +}
 +
 +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);
 +}
++
+ xbt_dict_t SIMIX_pre_host_get_storage_list(smx_simcall_t simcall, smx_host_t host){
+   return SIMIX_host_get_storage_list(host);
+ }
++
+ xbt_dict_t SIMIX_host_get_storage_list(smx_host_t host){
+   xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
+   return surf_workstation_model->extension.workstation.get_storage_list(host);
+ }
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007-2010, 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -14,7 -14,6 +14,7 @@@
  typedef struct s_smx_host_priv {
    xbt_swag_t process_list;
    xbt_dynar_t auto_restart_processes;
 +  xbt_dynar_t boot_processes; 
    void *data;              /**< @brief user data */
  } s_smx_host_priv_t;
  
@@@ -22,7 -21,6 +22,7 @@@ static inline smx_host_priv_t SIMIX_hos
    return xbt_lib_get_level(host, SIMIX_HOST_LEVEL);
  }
  
 +void _SIMIX_host_free_process_arg(void *);
  
  smx_host_t SIMIX_host_create(const char *name, void *workstation, void *data);
  void SIMIX_host_destroy(void *host);
@@@ -41,13 -39,17 +41,19 @@@ void SIMIX_host_restart_processes(smx_h
  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);
+ xbt_swag_t SIMIX_host_get_process_list(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_process_t issuer);
+ double SIMIX_host_get_current_power_peak(smx_host_t host);
+ double SIMIX_host_get_power_peak_at(smx_host_t host, int pstate_index);
+ int SIMIX_host_get_nb_pstates(smx_host_t host);
+ double SIMIX_host_get_consumed_energy(smx_host_t host);
+ void SIMIX_host_set_power_peak_at(smx_host_t host, int pstate_index);
  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, unsigned long affinity_mask);
  smx_action_t SIMIX_host_parallel_execute(const char *name,
      int host_nb, smx_host_t *host_list,
      double *computation_amount, double *communication_amount,
@@@ -57,25 -59,28 +63,32 @@@ 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_host_execution_set_affinity(smx_action_t action, smx_host_t host, unsigned long mask);
  void SIMIX_pre_host_execution_wait(smx_simcall_t simcall, smx_action_t action);
+ xbt_dict_t SIMIX_host_get_storage_list(smx_host_t host);
  
  // 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);
+ xbt_swag_t SIMIX_pre_host_get_process_list(smx_simcall_t, smx_host_t host);
  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);
+ double SIMIX_pre_host_get_current_power_peak(smx_simcall_t, smx_host_t);
+ double SIMIX_pre_host_get_power_peak_at(smx_simcall_t, smx_host_t host, int pstate_index);
+ int SIMIX_pre_host_get_nb_pstates(smx_simcall_t, smx_host_t host);
+ void SIMIX_pre_host_set_power_peak_at(smx_simcall_t, smx_host_t host, int pstate_index);
+ double SIMIX_pre_host_get_consumed_energy(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, unsigned long);
  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);
@@@ -83,70 -88,17 +96,70 @@@ 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_pre_host_execution_set_affinity(smx_simcall_t simcall, smx_action_t action, smx_host_t host, unsigned long mask);
  
  void SIMIX_host_execution_suspend(smx_action_t action);
  void SIMIX_host_execution_resume(smx_action_t action);
  
  void SIMIX_post_host_execute(smx_action_t action);
+ xbt_dict_t SIMIX_pre_host_get_storage_list(smx_simcall_t, smx_host_t);
  #ifdef HAVE_TRACING
  void SIMIX_pre_set_category(smx_simcall_t simcall, smx_action_t action,
                            const char *category);
  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_vm_set_affinity(smx_host_t ind_vm, smx_host_t ind_pm, unsigned long mask);
 +void SIMIX_pre_vm_set_affinity(smx_simcall_t simcall, smx_host_t ind_vm, smx_host_t ind_pm, unsigned long mask);
 +
 +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
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007-2010, 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -15,17 -15,70 +15,70 @@@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_i
                                  "Logging specific to SIMIX (io)");
  
  
+ /**
+  * \brief Internal function to create a SIMIX storage.
+  * \param name name of the storage to create
+  * \param storage the SURF storage to encapsulate
+  * \param data some user data (may be NULL)
+  */
+ smx_storage_t SIMIX_storage_create(const char *name, void *storage, void *data)
+ {
+   smx_storage_priv_t smx_storage = xbt_new0(s_smx_storage_priv_t, 1);
+   smx_storage->data = data;
+   /* Update global variables */
+   xbt_lib_set(storage_lib,name,SIMIX_STORAGE_LEVEL,smx_storage);
+   return xbt_lib_get_or_null(storage_lib, name, SIMIX_STORAGE_LEVEL);
+ }
+ /**
+  * \brief Internal function to destroy a SIMIX storage.
+  *
+  * \param s the host to destroy (a smx_storage_t)
+  */
+ void SIMIX_storage_destroy(void *s)
+ {
+   smx_storage_priv_t storage = (smx_storage_priv_t) s;
+   xbt_assert((storage != NULL), "Invalid parameters");
+   if (storage->data)
+     free(storage->data);
+   /* Clean storage structure */
+   free(storage);
+ }
+ void* SIMIX_pre_file_get_data(smx_simcall_t simcall,smx_file_t fd){
+   return SIMIX_file_get_data(fd);
+ }
+ void* SIMIX_file_get_data(smx_file_t fd){
+   xbt_assert((fd != NULL), "Invalid parameters (simix file is NULL)");
+   return fd->data;
+ }
+ void SIMIX_pre_file_set_data(smx_simcall_t simcall, smx_file_t fd, void *data) {
+   SIMIX_file_set_data(fd, data);
+ }
+ void SIMIX_file_set_data(smx_file_t fd, void *data){
+   xbt_assert((fd != NULL), "Invalid parameter");
+   fd->data = data;
+ }
  //SIMIX FILE READ
- void SIMIX_pre_file_read(smx_simcall_t simcall, void *ptr, size_t size,
-                       smx_file_t fd)
+ void SIMIX_pre_file_read(smx_simcall_t simcall, smx_file_t fd, sg_storage_size_t size)
  {
-   smx_action_t action = SIMIX_file_read(simcall->issuer, ptr, size, fd);
+   smx_action_t action = SIMIX_file_read(simcall->issuer, fd, size);
    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,
-                              smx_file_t fd)
+ smx_action_t SIMIX_file_read(smx_process_t process, smx_file_t fd, sg_storage_size_t size)
  {
    smx_action_t action;
    smx_host_t host = process->smx_host;
@@@ -46,8 -99,7 +99,7 @@@
  
    action->io.host = host;
    action->io.surf_io =
-       surf_workstation_model->extension.workstation.read(host, ptr, size,
-                                                          fd->surf_file);
+       surf_workstation_model->extension.workstation.read(host, fd->surf_file, size);
  
    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,
-                         smx_file_t fd)
+ void SIMIX_pre_file_write(smx_simcall_t simcall, smx_file_t fd, sg_storage_size_t size)
  {
-   smx_action_t action = SIMIX_file_write(simcall->issuer, ptr, size, fd);
+   smx_action_t action = SIMIX_file_write(simcall->issuer, fd,  size);
    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, smx_file_t fd)
+ smx_action_t SIMIX_file_write(smx_process_t process, smx_file_t fd, sg_storage_size_t size)
  {
    smx_action_t action;
    smx_host_t host = process->smx_host;
  
    action->io.host = host;
    action->io.surf_io =
-       surf_workstation_model->extension.workstation.write(host, ptr, size,
-                                                           fd->surf_file);
+       surf_workstation_model->extension.workstation.write(host, fd->surf_file, size);
  
    surf_workstation_model->action_data_set(action->io.surf_io, action);
    XBT_DEBUG("Create io action %p", action);
@@@ -188,7 -237,7 +237,7 @@@ int SIMIX_file_unlink(smx_process_t pro
    }
  
    if (surf_workstation_model->extension.workstation.unlink(host, fd->surf_file)){
-     fd->surf_file = NULL;
+     xbt_free(fd);
      return 1;
    } else
      return 0;
@@@ -227,18 -276,102 +276,102 @@@ smx_action_t SIMIX_file_ls(smx_process_
    return action;
  }
  
- size_t SIMIX_pre_file_get_size(smx_simcall_t simcall, smx_file_t fd)
+ sg_storage_size_t SIMIX_pre_file_get_size(smx_simcall_t simcall, smx_file_t fd)
  {
    return SIMIX_file_get_size(simcall->issuer, fd);
  }
  
- size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
+ sg_storage_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);
  }
  
+ xbt_dynar_t SIMIX_pre_file_get_info(smx_simcall_t simcall, smx_file_t fd)
+ {
+   return SIMIX_file_get_info(simcall->issuer, fd);
+ }
+ xbt_dynar_t SIMIX_file_get_info(smx_process_t process, smx_file_t fd)
+ {
+   smx_host_t host = process->smx_host;
+   return  surf_workstation_model->extension.workstation.get_info(host,
+       fd->surf_file);
+ }
+ sg_storage_size_t SIMIX_pre_storage_get_free_size(smx_simcall_t simcall, const char* name)
+ {
+   return SIMIX_storage_get_free_size(simcall->issuer, name);
+ }
+ sg_storage_size_t SIMIX_storage_get_free_size(smx_process_t process, const char* name)
+ {
+   smx_host_t host = process->smx_host;
+   return  surf_workstation_model->extension.workstation.get_free_size(host,name);
+ }
+ sg_storage_size_t SIMIX_pre_storage_get_used_size(smx_simcall_t simcall, const char* name)
+ {
+   return SIMIX_storage_get_used_size(simcall->issuer, name);
+ }
+ sg_storage_size_t SIMIX_storage_get_used_size(smx_process_t process, const char* name)
+ {
+   smx_host_t host = process->smx_host;
+   return  surf_workstation_model->extension.workstation.get_used_size(host,name);
+ }
+ xbt_dict_t SIMIX_pre_storage_get_properties(smx_simcall_t simcall, smx_storage_t storage){
+   return SIMIX_storage_get_properties(storage);
+ }
+ xbt_dict_t SIMIX_storage_get_properties(smx_storage_t storage){
+   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
+   return surf_storage_model->extension.storage.get_properties(storage);
+ }
+ const char* SIMIX_pre_storage_get_name(smx_simcall_t simcall, smx_storage_t storage){
+    return SIMIX_storage_get_name(storage);
+ }
+ const char* SIMIX_storage_get_name(smx_storage_t storage){
+   xbt_assert((storage != NULL), "Invalid parameters");
+   return sg_storage_name(storage);
+ }
+ void SIMIX_pre_storage_set_data(smx_simcall_t simcall, smx_storage_t storage, void *data) {
+   SIMIX_storage_set_data(storage, data);
+ }
+ void SIMIX_storage_set_data(smx_storage_t storage, void *data){
+   xbt_assert((storage != NULL), "Invalid parameters");
+   xbt_assert((SIMIX_storage_priv(storage)->data == NULL), "Data already set");
+   SIMIX_storage_priv(storage)->data = data;
+ }
+ void* SIMIX_pre_storage_get_data(smx_simcall_t simcall,smx_storage_t storage){
+   return SIMIX_storage_get_data(storage);
+ }
+ void* SIMIX_storage_get_data(smx_storage_t storage){
+   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
+   return SIMIX_storage_priv(storage)->data;
+ }
+ xbt_dict_t SIMIX_pre_storage_get_content(smx_simcall_t simcall, smx_storage_t storage){
+   return SIMIX_storage_get_content(storage);
+ }
+ xbt_dict_t SIMIX_storage_get_content(smx_storage_t storage){
+   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
+   return surf_storage_model->extension.storage.get_content(storage);
+ }
+ sg_storage_size_t SIMIX_storage_get_size(smx_storage_t storage){
+   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
+   return surf_storage_model->extension.storage.get_size(storage);
+ }
  
  void SIMIX_post_io(smx_action_t action)
  {
@@@ -308,7 -441,7 +441,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
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2009-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -31,7 -31,7 +31,7 @@@ void SIMIX_network_init(void
  {
    rdv_points = xbt_dict_new_homogeneous(SIMIX_rdv_free);
    if(MC_is_active())
-     MC_ignore_data_bss(&smx_total_comms, sizeof(smx_total_comms));
+     MC_ignore_global_variable("smx_total_comms");
  }
  
  void SIMIX_network_exit(void)
@@@ -340,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;
    }
  }
@@@ -695,7 -695,6 +695,6 @@@ smx_action_t SIMIX_comm_iprobe(smx_proc
  
  void SIMIX_pre_comm_wait(smx_simcall_t simcall, smx_action_t action, double timeout)
  {
-   int idx = simcall->mc_value;
    /* the simcall may be a wait, a send or a recv */
    surf_action_t sleep;
  
    simcall->issuer->waiting_action = action;
  
    if (MC_is_active()) {
+     int idx = simcall->mc_value;
      if (idx == 0) {
        action->state = SIMIX_DONE;
      } else {
@@@ -764,12 -764,12 +764,12 @@@ void SIMIX_pre_comm_test(smx_simcall_t 
  
  void SIMIX_pre_comm_testany(smx_simcall_t simcall, xbt_dynar_t actions)
  {
-   int idx = simcall->mc_value;
    unsigned int cursor;
    smx_action_t action;
    simcall_comm_testany__set__result(simcall, -1);
  
    if (MC_is_active()){
+     int idx = simcall->mc_value;
      if(idx == -1){
        SIMIX_simcall_answer(simcall);
      }else{
  
  void SIMIX_pre_comm_waitany(smx_simcall_t simcall, xbt_dynar_t actions)
  {
-   int idx = simcall->mc_value;
    smx_action_t action;
    unsigned int cursor = 0;
  
    if (MC_is_active()){
+     int idx = simcall->mc_value;
      action = xbt_dynar_get_as(actions, idx, smx_action_t);
      xbt_fifo_push(action->simcalls, simcall);
      simcall_comm_waitany__set__result(simcall, idx);
diff --combined src/simix/smx_new_api.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007-2010, 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -93,7 -93,7 +93,7 @@@ void SIMIX_new_api_destroy(smx_action_
  {
    XBT_DEBUG("Destroy action %p", action);
    if (action->new_api.surf_new_api)
 -    action->new_api.surf_new_api->model_type->action_unref(action->new_api.surf_new_api);
 +    action->new_api.surf_new_api->model_obj->action_unref(action->new_api.surf_new_api);
    xbt_mallocator_release(simix_global->action_mallocator, action);
  }
  
diff --combined src/simix/smx_process.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007-2012. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -122,8 -122,8 +122,8 @@@ void SIMIX_process_empty_trash(void
  
      xbt_dynar_free(&process->on_exit);
  
-     free(process->name);
-     free(process);
+     xbt_free(process->name);
+     xbt_free(process);
    }
  }
  
@@@ -239,8 -239,12 +239,12 @@@ void SIMIX_process_create(smx_process_
    XBT_DEBUG("Start process %s on host '%s'", name, hostname);
  
    if (!SIMIX_host_get_state(host)) {
+     int i;
      XBT_WARN("Cannot launch process '%s' on failed host '%s'", name,
            hostname);
+     for (i = 0; i < argc; i++)
+       xbt_free(argv[i]);
+     xbt_free(argv);
    }
    else {
      *process = xbt_new0(s_smx_process_t, 1);
@@@ -487,8 -491,7 +491,8 @@@ smx_action_t SIMIX_process_suspend(smx_
        return NULL;
      }
    } else {
 -    return SIMIX_host_execute("suspend", process->smx_host, 0.0, 1.0);
 +    /* FIXME: computation size is zero. Is it okay that bound is zero ? */
 +    return SIMIX_host_execute("suspend", process->smx_host, 0.0, 1.0, 0.0, 0);
    }
  }
  
@@@ -690,10 -693,9 +694,10 @@@ smx_action_t SIMIX_process_sleep(smx_pr
  {
    smx_action_t action;
    smx_host_t host = process->smx_host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
  
    /* check if the host is active */
 -  if (surf_workstation_model->extension.
 +  if (ws_model->extension.
        workstation.get_state(host) != SURF_RESOURCE_ON) {
      THROWF(host_error, 0, "Host %s failed, you cannot call this function",
             sg_host_name(host));
  
    action->sleep.host = host;
    action->sleep.surf_sleep =
 -      surf_workstation_model->extension.workstation.sleep(host, duration);
 +      ws_model->extension.workstation.sleep(host, duration);
  
 -  surf_workstation_model->action_data_set(action->sleep.surf_sleep, action);
 +  ws_model->action_data_set(action->sleep.surf_sleep, action);
    XBT_DEBUG("Create sleep action %p", action);
  
    return action;
@@@ -721,13 -723,9 +725,13 @@@ void SIMIX_post_process_sleep(smx_actio
    smx_simcall_t simcall;
    e_smx_state_t state;
  
 +  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
 +  smx_host_t host = action->sleep.host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +
    while ((simcall = xbt_fifo_shift(action->simcalls))) {
  
 -    switch(surf_workstation_model->action_state_get(action->sleep.surf_sleep)){
 +    switch(ws_model->action_state_get(action->sleep.surf_sleep)){
        case SURF_ACTION_FAILED:
          simcall->issuer->context->iwannadie = 1;
          //SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
          THROW_IMPOSSIBLE;
          break;
      }
 -    if (surf_workstation_model->extension.
 +    if (ws_model->extension.
          workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
        simcall->issuer->context->iwannadie = 1;
      }
  void SIMIX_process_sleep_destroy(smx_action_t action)
  {
    XBT_DEBUG("Destroy action %p", action);
 +  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
 +
    if (action->sleep.surf_sleep)
 -    action->sleep.surf_sleep->model_type->action_unref(action->sleep.surf_sleep);
 +    action->sleep.surf_sleep->model_obj->action_unref(action->sleep.surf_sleep);
    xbt_mallocator_release(simix_global->action_mallocator, action);
  }
  
  void SIMIX_process_sleep_suspend(smx_action_t action)
  {
 -  surf_workstation_model->suspend(action->sleep.surf_sleep);
 +  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
 +  smx_host_t host = action->sleep.host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +
 +  ws_model->suspend(action->sleep.surf_sleep);
  }
  
  void SIMIX_process_sleep_resume(smx_action_t action)
  {
 -  surf_workstation_model->resume(action->sleep.surf_sleep);
 +  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
 +  smx_host_t host = action->sleep.host;
 +  surf_model_t ws_model = surf_resource_model(host, SURF_WKS_LEVEL);
 +  XBT_DEBUG("%p ws_model", ws_model);
 +
 +  ws_model->resume(action->sleep.surf_sleep);
  }
  
  /** 
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
 -/* Copyright (c) 2007-2010, 2012-2013. The SimGrid Team.
++ /* Copyright (c) 2007-2010, 2012-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
  #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_PROCESS_LIST, host_get_process_list, WITH_ANSWER, TSPEC(result, xbt_swag_t), 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), TULONG(affinity_mask)) sep \
+ ACTION(SIMCALL_HOST_GET_CURRENT_POWER_PEAK, host_get_current_power_peak, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) sep \
+ ACTION(SIMCALL_HOST_GET_POWER_PEAK_AT, host_get_power_peak_at, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t), TINT(pstate_index)) sep \
+ ACTION(SIMCALL_HOST_GET_NB_PSTATES, host_get_nb_pstates, WITH_ANSWER, TINT(result), TSPEC(host, smx_host_t)) sep \
+ ACTION(SIMCALL_HOST_SET_POWER_PEAK_AT, host_set_power_peak_at, WITH_ANSWER, TVOID(result), TSPEC(host, smx_host_t), TINT(pstate_index)) sep \
+ ACTION(SIMCALL_HOST_GET_CONSUMED_ENERGY, host_get_consumed_energy, WITH_ANSWER, TDOUBLE(result), TSPEC(host, smx_host_t)) 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, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t), TDOUBLE(bound)) sep \
 +ACTION(SIMCALL_HOST_EXECUTION_SET_AFFINITY, host_execution_set_affinity, WITH_ANSWER, TVOID(result), TSPEC(execution, smx_action_t), TSPEC(ws, smx_host_t), TULONG(mask)) 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, WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TSPEC(params, ws_params_t)) sep \
 +ACTION(SIMCALL_HOST_SET_PARAMS, host_set_params, WITH_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,     WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_SET_STATE, vm_set_state, WITH_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,   WITH_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,    WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TDOUBLE(bound)) sep \
 +ACTION(SIMCALL_VM_SET_AFFINITY, vm_set_affinity, WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TSPEC(ind_pm, smx_host_t), TULONG(mask)) sep \
 +ACTION(SIMCALL_VM_DESTROY,   vm_destroy,   WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_SUSPEND,   vm_suspend,   WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_RESUME,    vm_resume,    WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_SHUTDOWN,  vm_shutdown,  WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_SAVE,      vm_save,      WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
 +ACTION(SIMCALL_VM_RESTORE,   vm_restore,   WITH_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \
+ ACTION(SIMCALL_HOST_GET_STORAGE_LIST, host_get_storage_list, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(host, 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 \
@@@ -360,13 -347,20 +367,20 @@@ 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, 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_GET_DATA, file_get_data, WITH_ANSWER, TPTR(result), TSPEC(fd, smx_file_t)) sep \
+ ACTION(SIMCALL_FILE_SET_DATA, file_set_data, WITH_ANSWER, TVOID(result), TSPEC(fd, smx_file_t), TPTR(data)) sep \
+ ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t), TSIZE(size)) sep \
+ ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t), TSIZE(size)) 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_FILE_GET_INFO, file_get_info, WITH_ANSWER, TSPEC(result, xbt_dynar_t), TSPEC(fd, smx_file_t)) sep \
+ ACTION(SIMCALL_STORAGE_GET_FREE_SIZE, storage_get_free_size, WITH_ANSWER, TSIZE(result), TSTRING(name)) sep \
+ ACTION(SIMCALL_STORAGE_GET_USED_SIZE, storage_get_used_size, WITH_ANSWER, TSIZE(result), TSTRING(name)) sep \
+ ACTION(SIMCALL_STORAGE_GET_PROPERTIES, storage_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(storage, smx_storage_t)) sep \
+ ACTION(SIMCALL_STORAGE_GET_CONTENT, storage_get_content, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(storage, smx_storage_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
@@@ -389,7 -383,7 +403,7 @@@ ACTION(SIMCALL_SET_CATEGORY, set_catego
  #define SIMCALL_LIST4(ACTION, sep) \
  ACTION(SIMCALL_MC_SNAPSHOT, mc_snapshot, WITH_ANSWER, TPTR(result)) sep \
  ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TPTR(s1), TPTR(s2)) sep \
- ACTION(SIMCALL_MC_RANDOM, mc_random, WITH_ANSWER, TINT(result)) sep
+ ACTION(SIMCALL_MC_RANDOM, mc_random, WITH_ANSWER, TINT(result), TINT(min), TINT(max)) sep
  #else
  #define SIMCALL_LIST4(ACTION, sep)
  #endif
diff --combined src/simix/smx_synchro.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -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);  
@@@ -473,7 -466,7 +473,7 @@@ void SIMIX_sem_release(smx_sem_t sem
  }
  
  /** @brief Returns true if acquiring this semaphore would block */
XBT_INLINE int SIMIX_sem_would_block(smx_sem_t sem)
+ int SIMIX_sem_would_block(smx_sem_t sem)
  {
    XBT_IN("(%p)",sem);
    XBT_OUT();
diff --combined src/simix/smx_user.c
@@@ -1,6 -1,7 +1,7 @@@
  /* smx_user.c - public interface to simix                                   */
  
- /* Copyright (c) 2010-2012. Da SimGrid team. All rights reserved.          */
+ /* Copyright (c) 2010-2013. The SimGrid Team.
+    All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
   * under the terms of the license (GNU LGPL) which comes with this package. */
@@@ -44,28 -45,6 +45,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.
@@@ -116,6 -95,17 +117,17 @@@ int simcall_host_get_core(smx_host_t ho
    return simcall_BODY_host_get_core(host);
  }
  
+ /**
+  * \ingroup simix_host_management
+  * \brief Returns the list of processes attached to the host.
+  *
+  * \param host A SIMIX host
+  * \return the swag of attached processes
+  */
+ xbt_swag_t simcall_host_get_process_list(smx_host_t host)
+ {
+   return simcall_BODY_host_get_process_list(host);
+ }
  
  
  /**
@@@ -167,6 -157,69 +179,69 @@@ void simcall_host_set_data(smx_host_t h
    simcall_host_set_data(host, data);
  }
  
+ /**
+  * \ingroup simix_host_management
+  * \brief Returns the power peak of a host.
+  *
+  * \param host A SIMIX host
+  * \return the current power peak value (double)
+  */
+ double simcall_host_get_current_power_peak(smx_host_t host)
+ {
+   return simcall_BODY_host_get_current_power_peak(host);
+ }
+ /**
+  * \ingroup simix_host_management
+  * \brief Returns one power peak (in flops/s) of a host at a given pstate
+  *
+  * \param host A SIMIX host
+  * \param pstate_index pstate to test
+  * \return the current power peak value (double) for pstate_index
+  */
+ double simcall_host_get_power_peak_at(smx_host_t host, int pstate_index)
+ {
+   return simcall_BODY_host_get_power_peak_at(host, pstate_index);
+ }
+ /**
+  * \ingroup simix_host_management
+  * \brief Returns the number of power states for a host.
+  *
+  * \param host A SIMIX host
+  * \return the number of power states
+  */
+ int simcall_host_get_nb_pstates(smx_host_t host)
+ {
+   return simcall_BODY_host_get_nb_pstates(host);
+ }
+ /**
+  * \ingroup simix_host_management
+  * \brief Sets a new power peak for a host.
+  *
+  * \param host A SIMIX host
+  * \param pstate_index The pstate to which the CPU power will be set
+  * \return void
+  */
+ void simcall_host_set_power_peak_at(smx_host_t host, int pstate_index)
+ {
+       simcall_BODY_host_set_power_peak_at(host, pstate_index);
+ }
+ /**
+  * \ingroup simix_host_management
+  * \brief Returns the total energy consumed by the host (in Joules)
+  *
+  * \param host A SIMIX host
+  * \return the energy consumed by the host (double)
+  */
+ double simcall_host_get_consumed_energy(smx_host_t host)
+ {
+   return simcall_BODY_host_get_consumed_energy(host);
+ }
  /**
   * \ingroup simix_host_management
   * \brief Creates an action that executes some computation of an host.
   * \param priority computation priority
   * \return A new SIMIX execution action
   */
  smx_action_t simcall_host_execute(const char *name, smx_host_t host,
                                      double computation_amount,
 -                                    double priority)
 +                                    double priority, double bound, unsigned long affinity_mask)
  {
    /* 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, affinity_mask);
  }
  
  /**
@@@ -299,33 -351,6 +373,33 @@@ 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 Changes the CPU affinity of an execution action.
 + *
 + * This functions changes the CPU affinity of an execution action. See taskset(1) on Linux.
 + * \param execution The execution action
 + * \param host Host
 + * \param mask Affinity mask
 + */
 +void simcall_host_execution_set_affinity(smx_action_t execution, smx_host_t host, unsigned long mask)
 +{
 +  simcall_BODY_host_execution_set_affinity(execution, host, mask);
 +}
 +
  /**
   * \ingroup simix_host_management
   * \brief Waits for the completion of an execution action and destroy it.
@@@ -337,169 -362,6 +411,169 @@@ 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_vm_set_affinity(smx_host_t vm, smx_host_t pm, unsigned long mask)
 +{
 +  /* will jump to SIMIX_pre_vm_set_affinity in src/simix/smx_smurf_private.h */
 +  simcall_BODY_vm_set_affinity(vm, pm, mask);
 +}
 +
 +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.
@@@ -898,9 -760,11 +972,11 @@@ void simcall_comm_send(smx_rdv_t rdv, d
  
    if (MC_is_active()) {
      /* the model-checker wants two separate simcalls */
-     smx_action_t comm = simcall_comm_isend(rdv, task_size, rate,
+     smx_action_t comm = NULL; /* MC needs the comm to be set to NULL during the simcall */
+     comm = simcall_comm_isend(rdv, task_size, rate,
          src_buff, src_buff_size, match_fun, NULL, data, 0);
      simcall_comm_wait(comm, timeout);
+     comm = NULL;
    }
    else {
      simcall_BODY_comm_send(rdv, task_size, rate, src_buff, src_buff_size,
@@@ -939,9 -803,11 +1015,11 @@@ void simcall_comm_recv(smx_rdv_t rdv, v
  
    if (MC_is_active()) {
      /* the model-checker wants two separate simcalls */
-     smx_action_t comm = simcall_comm_irecv(rdv, dst_buff, dst_buff_size,
+     smx_action_t comm = NULL; /* MC needs the comm to be set to NULL during the simcall */
+     comm = simcall_comm_irecv(rdv, dst_buff, dst_buff_size,
          match_fun, data);
      simcall_comm_wait(comm, timeout);
+     comm = NULL;
    }
    else {
      simcall_BODY_comm_recv(rdv, dst_buff, dst_buff_size,
@@@ -1315,21 -1181,44 +1393,44 @@@ int simcall_sem_get_capacity(smx_sem_t 
  
  /**
   * \ingroup simix_file_management
+  * \brief Returns the user data associated to a file.
   *
+  * \param fd A simix file
+  * \return the user data of this file
   */
size_t simcall_file_read(void* ptr, size_t size, smx_file_t fd)
void* simcall_file_get_data(smx_file_t fd)
  {
-   return simcall_BODY_file_read(ptr, size, fd);
+   return simcall_BODY_file_get_data(fd);
+ }
+ /**
+  * \ingroup simix_file_management
+  * \brief Sets the user data associated to a file.
+  *
+  * \param fd A SIMIX file
+  * \param data The user data to set
+  */
+ void simcall_file_set_data(smx_file_t fd, void *data)
+ {
+   simcall_file_set_data(fd, data);
+ }
+ /**
+  * \ingroup simix_file_management
+  *
+  */
+ sg_storage_size_t simcall_file_read(smx_file_t fd, sg_storage_size_t size)
+ {
+   return simcall_BODY_file_read(fd, size);
  }
  
  /**
   * \ingroup simix_file_management
   *
   */
- size_t simcall_file_write(const void* ptr, size_t size,
-                           smx_file_t fd)
+ sg_storage_size_t simcall_file_write(smx_file_t fd, sg_storage_size_t size)
  {
-   return simcall_BODY_file_write(ptr, size, fd);
+   return simcall_BODY_file_write(fd, size);
  }
  
  /**
@@@ -1371,10 -1260,74 +1472,74 @@@ xbt_dict_t simcall_file_ls(const char* 
   * \ingroup simix_file_management
   *
   */
- size_t simcall_file_get_size (smx_file_t fd){
+ sg_storage_size_t simcall_file_get_size (smx_file_t fd){
    return simcall_BODY_file_get_size(fd);
  }
  
+ /**
+  * \ingroup simix_file_management
+  *
+  */
+ xbt_dynar_t simcall_file_get_info(smx_file_t fd)
+ {
+   return simcall_BODY_file_get_info(fd);
+ }
+ /**
+  * \ingroup simix_storage_management
+  * \brief Returns the free space size on a given storage element.
+  * \param storage name
+  * \return Return the free space size on a given storage element (as sg_storage_size_t)
+  */
+ sg_storage_size_t simcall_storage_get_free_size (const char* name){
+   return simcall_BODY_storage_get_free_size(name);
+ }
+ /**
+  * \ingroup simix_storage_management
+  * \brief Returns the used space size on a given storage element.
+  * \param storage name
+  * \return Return the used space size on a given storage element (as sg_storage_size_t)
+  */
+ sg_storage_size_t simcall_storage_get_used_size (const char* name){
+   return simcall_BODY_storage_get_used_size(name);
+ }
+ /**
+  * \ingroup simix_storage_management
+  * \brief Returns the list of storages mounted on an host.
+  * \param host A SIMIX host
+  * \return a dict containing all storages mounted on the host
+  */
+ xbt_dict_t simcall_host_get_storage_list(smx_host_t host)
+ {
+   return simcall_BODY_host_get_storage_list(host);
+ }
+ /**
+  * \ingroup simix_storage_management
+  * \brief Returns a dict of the properties assigned to a storage element.
+  *
+  * \param storage A storage element
+  * \return The properties of this storage element
+  */
+ xbt_dict_t simcall_storage_get_properties(smx_storage_t storage)
+ {
+   return simcall_BODY_storage_get_properties(storage);
+ }
+ /**
+  * \ingroup simix_storage_management
+  * \brief Returns a dict containing the content of a storage element.
+  *
+  * \param storage A storage element
+  * \return The content of this storage element as a dict (full path file => size)
+  */
+ xbt_dict_t simcall_storage_get_content(smx_storage_t storage)
+ {
+   return simcall_BODY_storage_get_content(storage);
+ }
  #ifdef HAVE_MC
  
  void *simcall_mc_snapshot(void)
@@@ -1386,9 -1339,9 +1551,9 @@@ int simcall_mc_compare_snapshots(void *
    return simcall_BODY_mc_compare_snapshots(s1, s2);
  }
  
- int simcall_mc_random(void)
+ int simcall_mc_random(int min, int max)
  {
-   return simcall_BODY_mc_random();
+   return simcall_BODY_mc_random(min, max);
  }
  
  
diff --combined src/smpi/smpi_bench.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007, 2009-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -8,6 -8,7 +8,7 @@@
  #include "xbt/dict.h"
  #include "xbt/sysdep.h"
  #include "xbt/ex.h"
+ #include "xbt/hash.h"
  #include "surf/surf.h"
  #include "simgrid/sg_config.h"
  
@@@ -102,13 -103,13 +103,13 @@@ static void* shm_map(int fd, size_t siz
      xbt_die("Could not map fd %d: %s", fd, strerror(errno));
    }
    if(!allocs_metadata) {
-     allocs_metadata = xbt_dict_new();
+     allocs_metadata = xbt_dict_new_homogeneous(xbt_free);
    }
    snprintf(loc, PTR_STRLEN, "%p", mem);
    meta = xbt_new(shared_metadata_t, 1);
    meta->size = size;
    meta->data = data;
-   xbt_dict_set(allocs_metadata, loc, meta, &free);
+   xbt_dict_set(allocs_metadata, loc, meta, NULL);
    XBT_DEBUG("MMAP %zu to %p", size, mem);
    return mem;
  }
  void smpi_bench_destroy(void)
  {
    xbt_dict_free(&allocs);
+   xbt_dict_free(&allocs_metadata);
    xbt_dict_free(&samples);
    xbt_dict_free(&calls);
  }
@@@ -127,7 -129,7 +129,7 @@@ void smpi_execute_flops(double flops) 
    host = SIMIX_host_self();
  
    XBT_DEBUG("Handle real computation time: %f flops", flops);
--  action = simcall_host_execute("computation", host, flops, 1);
++  action = simcall_host_execute("computation", host, flops, 1, 0, 0);
  #ifdef HAVE_TRACING
    simcall_set_category (action, TRACE_internal_smpi_get_category());
  #endif
@@@ -164,7 -166,7 +166,7 @@@ void smpi_bench_end(void
  unsigned int smpi_sleep(unsigned int secs)
  {
    smpi_bench_end();
-   smpi_execute((double) secs);
+   smpi_execute_flops((double) secs*simcall_host_get_speed(SIMIX_host_self()));
    smpi_bench_begin();
    return secs;
  }
@@@ -342,50 -344,83 +344,83 @@@ void smpi_sample_3(int global, const ch
  }
  
  #ifndef WIN32
void *smpi_shared_malloc(size_t size, const char *file, int line)
static void smpi_shared_alloc_free(void *p)
  {
-   char *loc = bprintf("%zu_%s_%d", (size_t)getpid(), file, line);
-   size_t len = strlen(loc);
-   size_t i;
-   int fd;
-   void* mem;
-   shared_data_t *data;
+   shared_data_t *data = p;
+   xbt_free(data->loc);
+   xbt_free(data);
+ }
  
-   for(i = 0; i < len; i++) {
-     /* Make the 'loc' ID be a flat filename */
-     if(loc[i] == '/') {
-       loc[i] = '_';
+ static char *smpi_shared_alloc_hash(char *loc)
+ {
+   char hash[42];
+   char s[7];
+   unsigned val;
+   int i, j;
+   xbt_sha(loc, hash);
+   hash[41] = '\0';
+   s[6] = '\0';
+   loc = xbt_realloc(loc, 30);
+   loc[0] = '/';
+   for (i = 0; i < 40; i += 6) { /* base64 encode */
+     memcpy(s, hash + i, 6);
+     val = strtoul(s, NULL, 16);
+     for (j = 0; j < 4; j++) {
+       unsigned char x = (val >> (18 - 3 * j)) & 0x3f;
+       loc[1 + 4 * i / 6 + j] =
+         "ABCDEFGHIJKLMNOPQRSTUVZXYZabcdefghijklmnopqrstuvzxyz0123456789-_"[x];
      }
    }
-   if (!allocs) {
-     allocs = xbt_dict_new_homogeneous(free);
-   }
-   data = xbt_dict_get_or_null(allocs, loc);
-   if(!data) {
-     fd = shm_open(loc, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-     if(fd < 0) {
-       switch(errno) {
-         case EEXIST:
-           xbt_die("Please cleanup /dev/shm/%s", loc);
-         default:
-           xbt_die("An unhandled error occured while opening %s: %s", loc, strerror(errno));
-       }
+   loc[29] = '\0';
+   return loc;
+ }
+ void *smpi_shared_malloc(size_t size, const char *file, int line)
+ {
+   void* mem;
+   if (sg_cfg_get_boolean("smpi/use_shared_malloc")){
+     char *loc = bprintf("%zu_%s_%d", (size_t)getpid(), file, line);
+     int fd;
+     shared_data_t *data;
+     loc = smpi_shared_alloc_hash(loc); /* hash loc, in order to have something
+                                         * not too long */
+     if (!allocs) {
+       allocs = xbt_dict_new_homogeneous(smpi_shared_alloc_free);
      }
-     data = xbt_new(shared_data_t, 1);
-     data->fd = fd;
-     data->count = 1;
-     data->loc = loc;
-     mem = shm_map(fd, size, data);
-     if(shm_unlink(loc) < 0) {
-       XBT_WARN("Could not early unlink %s: %s", loc, strerror(errno));
+     data = xbt_dict_get_or_null(allocs, loc);
+     if (!data) {
+       fd = shm_open(loc, O_RDWR | O_CREAT | O_EXCL,
+                     S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+       if (fd < 0) {
+         switch(errno) {
+           case EEXIST:
+             xbt_die("Please cleanup /dev/shm/%s", loc);
+           default:
+             xbt_die("An unhandled error occured while opening %s: %s", loc, strerror(errno));
+         }
+       }
+       data = xbt_new(shared_data_t, 1);
+       data->fd = fd;
+       data->count = 1;
+       data->loc = loc;
+       mem = shm_map(fd, size, data);
+       if (shm_unlink(loc) < 0) {
+         XBT_WARN("Could not early unlink %s: %s", loc, strerror(errno));
+       }
+       xbt_dict_set(allocs, loc, data, NULL);
+       XBT_DEBUG("Mapping %s at %p through %d", loc, mem, fd);
+     } else {
+       xbt_free(loc);
+       mem = shm_map(data->fd, size, data);
+       data->count++;
      }
-     xbt_dict_set(allocs, loc, data, NULL);
-     XBT_DEBUG("Mapping %s at %p through %d", loc, mem, fd);
+     XBT_DEBUG("Shared malloc %zu in %p (metadata at %p)", size, mem, data);
    } else {
-     mem = shm_map(data->fd, size, data);
-     data->count++;
+     mem = xbt_malloc(size);
+     XBT_DEBUG("Classic malloc %zu in %p", size, mem);
    }
-   XBT_DEBUG("Malloc %zu in %p (metadata at %p)", size, mem, data);
    return mem;
  }
  void smpi_shared_free(void *ptr)
    char loc[PTR_STRLEN];
    shared_metadata_t* meta;
    shared_data_t* data;
-   if (!allocs) {
-     XBT_WARN("Cannot free: nothing was allocated");
-     return;
-   }
-   if(!allocs_metadata) {
-     XBT_WARN("Cannot free: no metadata was allocated");
-   }
-   snprintf(loc, PTR_STRLEN, "%p", ptr);
-   meta = (shared_metadata_t*)xbt_dict_get_or_null(allocs_metadata, loc);
-   if (!meta) {
-     XBT_WARN("Cannot free: %p was not shared-allocated by SMPI", ptr);
-     return;
-   }
-   data = meta->data;
-   if(!data) {
-     XBT_WARN("Cannot free: something is broken in the metadata link");
-     return;
-   }
-   if(munmap(ptr, meta->size) < 0) {
-     XBT_WARN("Unmapping of fd %d failed: %s", data->fd, strerror(errno));
-   }
-   data->count--;
-   if (data->count <= 0) {
-     close(data->fd);
-     xbt_dict_remove(allocs, data->loc);
-     free(data->loc);
+   if (sg_cfg_get_boolean("smpi/use_shared_malloc")){
+   
+     if (!allocs) {
+       XBT_WARN("Cannot free: nothing was allocated");
+       return;
+     }
+     if(!allocs_metadata) {
+       XBT_WARN("Cannot free: no metadata was allocated");
+     }
+     snprintf(loc, PTR_STRLEN, "%p", ptr);
+     meta = (shared_metadata_t*)xbt_dict_get_or_null(allocs_metadata, loc);
+     if (!meta) {
+       XBT_WARN("Cannot free: %p was not shared-allocated by SMPI", ptr);
+       return;
+     }
+     data = meta->data;
+     if(!data) {
+       XBT_WARN("Cannot free: something is broken in the metadata link");
+       return;
+     }
+     if(munmap(ptr, meta->size) < 0) {
+       XBT_WARN("Unmapping of fd %d failed: %s", data->fd, strerror(errno));
+     }
+     data->count--;
+     XBT_DEBUG("Shared free - no removal - of %p, count = %d", ptr, data->count);
+     if (data->count <= 0) {
+       close(data->fd);
+       xbt_dict_remove(allocs, data->loc);
+       XBT_DEBUG("Shared free - with removal - of %p", ptr);
+     }
+   }else{
+     XBT_DEBUG("Classic free of %p", ptr);
+     xbt_free(ptr);
    }
  }
  #endif
diff --combined src/surf/cpu_cas01.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2009-2011. The SimGrid Team.
+ /* Copyright (c) 2009-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -8,38 -8,43 +8,45 @@@
  #include "surf/surf_resource.h"
  #include "maxmin_private.h"
  #include "simgrid/sg_config.h"
- #include "surf/cpu_cas01_private.h"
+ #include "cpu_cas01_private.h"
+ #include "string.h"
+ #include "stdlib.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
- #undef ACTION_GET_CPU
- #define GENERIC_LMM_ACTION(action) action->generic_lmm_action
- #define GENERIC_ACTION(action) GENERIC_LMM_ACTION(action).generic_action
- #define ACTION_GET_CPU(action) ((surf_action_cpu_Cas01_t) action)->cpu
- 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;
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu, surf,
                                  "Logging specific to the SURF CPU IMPROVED module");
  
  static xbt_swag_t
      cpu_running_action_set_that_does_not_need_being_checked = NULL;
  
+ /* Additionnal callback function to cleanup some data, called from surf_resource_free */
+ static void cpu_cas01_cleanup(void* r){
+   cpu_Cas01_t cpu = (cpu_Cas01_t)r;
+   unsigned int iter;
+   xbt_dynar_t power_tuple = NULL;
+   xbt_dynar_foreach(cpu->energy->power_range_watts_list, iter, power_tuple)
+     xbt_dynar_free(&power_tuple);
+   xbt_dynar_free(&cpu->energy->power_range_watts_list);
+   xbt_dynar_free(&cpu->power_peak_list);
+   xbt_free(cpu->energy);
+   return;
+ }
  
- void *cpu_cas01_create_resource(const char *name, double power_peak,
+ /* This function is registered as a callback to sg_platf_new_host() and never called directly */
 -static void *cpu_create_resource(const char *name, xbt_dynar_t power_peak,
++void *cpu_cas01_create_resource(const char *name, xbt_dynar_t power_peak,
+                                                                int pstate,
                                   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;
  
               "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_properties,  &cpu_cas01_cleanup);
 +                                        cpu_model, name,
-                                         cpu_properties);
-   cpu->power_peak = power_peak;
++                                        cpu_properties, &cpu_cas01_cleanup);
+   cpu->power_peak = xbt_dynar_get_as(power_peak, pstate, double);
+   cpu->power_peak_list = power_peak;
+   cpu->pstate = pstate;
+   cpu->energy = xbt_new(s_energy_cpu_cas01_t, 1);
+   cpu->energy->total_energy = 0;
+   cpu->energy->power_range_watts_list = cpu_get_watts_range_list(cpu);
+   cpu->energy->last_updated = surf_get_clock();
+   XBT_DEBUG("CPU create: peak=%f, pstate=%d",cpu->power_peak, cpu->pstate);
    xbt_assert(cpu->power_peak > 0, "Power has to be >0");
    cpu->power_scale = power_scale;
    cpu->core = core;
          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);
  
 +  /* Note (hypervisor): we create a constraint object for each CPU core, which
 +   * is used for making a contraint problem of CPU affinity.
 +   **/
 +  {
 +    /* At now, we assume that a VM does not have a multicore CPU. */
 +    if (core > 1)
 +      xbt_assert(cpu_model == surf_cpu_model_pm);
 +
 +    cpu->constraint_core = xbt_new(lmm_constraint_t, core);
 +
 +    unsigned long i;
 +    for (i = 0; i < core; i++) {
 +      /* just for a unique id, never used as a string. */
 +      void *cnst_id = bprintf("%s:%lu", name, i);
 +      cpu->constraint_core[i] =
 +        lmm_constraint_new(cpu_model->model_private->maxmin_system, cnst_id,
 +            cpu->power_scale * cpu->power_peak);
 +    }
 +  }
 +
    xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, cpu);
  
    return xbt_lib_get_elm_or_null(host_lib, name);;
  
  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->pstate,
                        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;
 +
 +  /* Note (hypervisor): we do not need to look up constraint_core[i] here. Even
 +   * when a task is pinned or not, its variable object is always linked to the
 +   * basic contraint object.
 +   **/
 +
 +  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);
  }
  
+ xbt_dynar_t cpu_get_watts_range_list(cpu_Cas01_t cpu_model)
+ {
+       xbt_dynar_t power_range_list;
+       xbt_dynar_t power_tuple;
+       int i = 0, pstate_nb=0;
+       xbt_dynar_t current_power_values;
+       double min_power, max_power;
+       xbt_dict_t props = cpu_model->generic_resource.properties;
+       if (props == NULL)
+               return NULL;
+       char* all_power_values_str = xbt_dict_get_or_null(props, "power_per_state");
+       if (all_power_values_str == NULL)
+               return NULL;
+       power_range_list = xbt_dynar_new(sizeof(xbt_dynar_t), NULL);
+       xbt_dynar_t all_power_values = xbt_str_split(all_power_values_str, ",");
+       pstate_nb = xbt_dynar_length(all_power_values);
+       for (i=0; i< pstate_nb; i++)
+       {
+               /* retrieve the power values associated with the current pstate */
+               current_power_values = xbt_str_split(xbt_dynar_get_as(all_power_values, i, char*), ":");
+               xbt_assert(xbt_dynar_length(current_power_values) > 1,
+                               "Power properties incorrectly defined - could not retrieve min and max power values for host %s",
+                               cpu_model->generic_resource.name);
+               /* min_power corresponds to the idle power (cpu load = 0) */
+               /* max_power is the power consumed at 100% cpu load       */
+               min_power = atof(xbt_dynar_get_as(current_power_values, 0, char*));
+               max_power = atof(xbt_dynar_get_as(current_power_values, 1, char*));
+               power_tuple = xbt_dynar_new(sizeof(double), NULL);
+               xbt_dynar_push_as(power_tuple, double, min_power);
+               xbt_dynar_push_as(power_tuple, double, max_power);
+               xbt_dynar_push_as(power_range_list, xbt_dynar_t, power_tuple);
+               xbt_dynar_free(&current_power_values);
+       }
+       xbt_dynar_free(&all_power_values);
+       return power_range_list;
+ }
+ /**
+  * Computes the power consumed by the host according to the current pstate and processor load
+  *
+  */
+ static double cpu_get_current_watts_value(cpu_Cas01_t cpu_model, double cpu_load)
+ {
+       xbt_dynar_t power_range_list = cpu_model->energy->power_range_watts_list;
+       if (power_range_list == NULL)
+       {
+               XBT_DEBUG("No power range properties specified for host %s", cpu_model->generic_resource.name);
+               return 0;
+       }
+       xbt_assert(xbt_dynar_length(power_range_list) == xbt_dynar_length(cpu_model->power_peak_list),
+                                               "The number of power ranges in the properties does not match the number of pstates for host %s",
+                                               cpu_model->generic_resource.name);
+     /* retrieve the power values associated with the current pstate */
+     xbt_dynar_t current_power_values = xbt_dynar_get_as(power_range_list, cpu_model->pstate, xbt_dynar_t);
+     /* min_power corresponds to the idle power (cpu load = 0) */
+     /* max_power is the power consumed at 100% cpu load       */
+     double min_power = xbt_dynar_get_as(current_power_values, 0, double);
+     double max_power = xbt_dynar_get_as(current_power_values, 1, double);
+     double power_slope = max_power - min_power;
+     double current_power = min_power + cpu_load * power_slope;
+       XBT_DEBUG("[get_current_watts] min_power=%f, max_power=%f, slope=%f", min_power, max_power, power_slope);
+     XBT_DEBUG("[get_current_watts] Current power (watts) = %f, load = %f", current_power, cpu_load);
+       return current_power;
+ }
+ /**
+  * Updates the total energy consumed as the sum of the current energy and
+  *                                             the energy consumed by the current action
+  */
+ void cpu_update_energy(cpu_Cas01_t cpu_model, double cpu_load)
+ {
+   double start_time = cpu_model->energy->last_updated;
+   double finish_time = surf_get_clock();
+   XBT_DEBUG("[cpu_update_energy] action time interval=(%f-%f), current power peak=%f, current pstate=%d",
+                 start_time, finish_time, cpu_model->power_peak, cpu_model->pstate);
+   double current_energy = cpu_model->energy->total_energy;
+   double action_energy = cpu_get_current_watts_value(cpu_model, cpu_load)*(finish_time-start_time);
+   cpu_model->energy->total_energy = current_energy + action_energy;
+   cpu_model->energy->last_updated = finish_time;
+   XBT_DEBUG("[cpu_update_energy] old_energy_value=%f, action_energy_value=%f", current_energy, action_energy);
+ }
  static void cpu_update_resource_state(void *id,
                                        tmgr_trace_event_t event_type,
                                        double value, double date)
    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) {
 +    /* TODO (Hypervisor): do the same thing for constraint_core[i] */
 +    xbt_assert(cpu->core == 1, "FIXME: add power scaling code also for constraint_core[i]");
 +
      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);
      }
      if (tmgr_trace_event_free(event_type))
        cpu->power_event = NULL;
    } else if (event_type == cpu->state_event) {
-     if (value > 0)
 +    /* TODO (Hypervisor): do the same thing for constraint_core[i] */
 +    xbt_assert(cpu->core == 1, "FIXME: add state change code also for constraint_core[i]");
 +
+     if (value > 0) {
+       if(cpu->state_current == SURF_RESOURCE_OFF)
+         xbt_dynar_push_as(host_that_restart, char*, (cpu->generic_resource.name));
        cpu->state_current = SURF_RESOURCE_ON;
-     else {
+     else {
        lmm_constraint_t cnst = cpu->constraint;
  
        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 ||
    return;
  }
  
 +
 +/*
 + *
 + * This function formulates a constraint problem that pins a given task to
 + * particular cores. Currently, it is possible to pin a task to an exactly one
 + * specific core. The system links the variable object of the task to the
 + * per-core constraint object.
 + *
 + * But, the taskset command on Linux takes a mask value specifying a CPU
 + * affinity setting of a given task. If the mask value is 0x03, the given task
 + * will be executed on the first core (CPU0) or the second core (CPU1) on the
 + * given PM. The schedular will determine appropriate placements of tasks,
 + * considering given CPU affinities and task activities.
 + *
 + * How should the system formulate constraint problems for an affinity to
 + * multiple cores?
 + *
 + * The cpu argument must be the host where the task is being executed. The
 + * action object does not have the information about the location where the
 + * action is being executed.
 + */
 +static void cpu_action_set_affinity(surf_action_t action, void *cpu, unsigned long mask)
 +{
 +  lmm_variable_t var_obj = ((surf_action_lmm_t) action)->variable;
 +
 +  surf_model_t cpu_model = action->model_obj;
 +  xbt_assert(cpu_model->type == SURF_MODEL_TYPE_CPU);
 +  cpu_Cas01_t CPU = surf_cpu_resource_priv(cpu);
 +
 +  XBT_IN("(%p,%lx)", action, mask);
 +
 +  {
 +    unsigned long nbits = 0;
 +
 +    /* FIXME: There is much faster algorithms doing this. */
 +    unsigned long i;
 +    for (i = 0; i < CPU->core; i++) {
 +      unsigned long has_affinity = (1UL << i) & mask;
 +      if (has_affinity)
 +        nbits += 1;
 +    }
 +
 +    if (nbits > 1) {
 +      XBT_CRITICAL("Do not specify multiple cores for an affinity mask.");
 +      XBT_CRITICAL("See the comment in cpu_action_set_affinity().");
 +      DIE_IMPOSSIBLE;
 +    }
 +  }
 +
 +
 +
 +  unsigned long i;
 +  for (i = 0; i < CPU->core; i++) {
 +    XBT_DEBUG("clear affinity %p to cpu-%lu@%s", action, i, CPU->generic_resource.name);
 +    lmm_shrink(cpu_model->model_private->maxmin_system, CPU->constraint_core[i], var_obj);
 +
 +    unsigned long has_affinity = (1UL << i) & mask;
 +    if (has_affinity) {
 +      /* This function only accepts an affinity setting on the host where the
 +       * task is now running. In future, a task might move to another host.
 +       * But, at this moment, this function cannot take an affinity setting on
 +       * that future host.
 +       *
 +       * It might be possible to extend the code to allow this function to
 +       * accept affinity settings on a future host. We might be able to assign
 +       * zero to elem->value to maintain such inactive affinity settings in the
 +       * system. But, this will make the system complex. */
 +      XBT_DEBUG("set affinity %p to cpu-%lu@%s", action, i, CPU->generic_resource.name);
 +      lmm_expand(cpu_model->model_private->maxmin_system, CPU->constraint_core[i], var_obj, 1.0);
 +    }
 +  }
 +
 +  if (cpu_model->model_private->update_mechanism == UM_LAZY) {
 +    /* FIXME (hypervisor): Do we need to do something for the LAZY mode? */
 +  }
 +
 +  XBT_OUT();
 +}
 +
  static surf_action_t cpu_execute(void *cpu, double size)
  {
    surf_action_cpu_Cas01_t action = NULL;
+   //xbt_dict_cursor_t cursor = NULL;
    cpu_Cas01_t CPU = surf_cpu_resource_priv(cpu);
 -  //xbt_dict_t props = CPU->generic_resource.properties;
 +  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... */
  
 +  /* Note (hypervisor): here, the bound value of the variable is set to the
 +   * capacity of a CPU core. But, after MSG_{task/vm}_set_bound() were added to
 +   * the hypervisor branch, this bound value is overwritten in
 +   * SIMIX_host_execute().
 +   * TODO: cleanup this.
 +   */
    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) {
 +                       CPU->power_scale * CPU->power_peak, 1 + CPU->core); // the basic constraint plus core-specific constraints
 +  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();
@@@ -410,11 -407,6 +533,11 @@@ 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;
@@@ -424,29 -416,65 +547,63 @@@ 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 double cpu_get_current_power_peak(void *cpu)
+ {
+   return ((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->power_peak;
+ }
+ static double cpu_get_power_peak_at(void *cpu, int pstate_index)
+ {
+   xbt_dynar_t plist = ((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->power_peak_list;
+   xbt_assert((pstate_index <= xbt_dynar_length(plist)), "Invalid parameters (pstate index out of bounds)");
+   return xbt_dynar_get_as(plist, pstate_index, double);
+ }
+ static int cpu_get_nb_pstates(void *cpu)
+ {
+   return xbt_dynar_length(((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->power_peak_list);
+ }
+ static void cpu_set_power_peak_at(void *cpu, int pstate_index)
+ {
+   cpu_Cas01_t cpu_implem = (cpu_Cas01_t)surf_cpu_resource_priv(cpu);
+   xbt_dynar_t plist = cpu_implem->power_peak_list;
+   xbt_assert((pstate_index <= xbt_dynar_length(plist)), "Invalid parameters (pstate index out of bounds)");
+   double new_power_peak = xbt_dynar_get_as(plist, pstate_index, double);
+   cpu_implem->pstate = pstate_index;
+   cpu_implem->power_peak = new_power_peak;
+ }
+ static double cpu_get_consumed_energy(void *cpu)
+ {
+   return ((cpu_Cas01_t)surf_cpu_resource_priv(cpu))->energy->total_energy;
+ }
 +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;
    int select =
        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;
 +  cpu_model->set_affinity = cpu_action_set_affinity;
  #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.get_current_power_peak = cpu_get_current_power_peak;
 -  surf_cpu_model->extension.cpu.get_power_peak_at = cpu_get_power_peak_at;
 -  surf_cpu_model->extension.cpu.get_nb_pstates = cpu_get_nb_pstates;
 -  surf_cpu_model->extension.cpu.set_power_peak_at = cpu_set_power_peak_at;
 -  surf_cpu_model->extension.cpu.get_consumed_energy = cpu_get_consumed_energy;
++  cpu_model->extension.cpu.get_current_power_peak = cpu_get_current_power_peak;
++  cpu_model->extension.cpu.get_power_peak_at = cpu_get_power_peak_at;
++  cpu_model->extension.cpu.get_nb_pstates = cpu_get_nb_pstates;
++  cpu_model->extension.cpu.set_power_peak_at = cpu_set_power_peak_at;
++  cpu_model->extension.cpu.get_consumed_energy = cpu_get_consumed_energy;
 -  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
@@@ -1,5 -1,5 +1,4 @@@
--
 -/* Copyright (c) 2009-2010, 2013. The SimGrid Team.
 +/* Copyright (c) 2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -8,6 -8,28 +7,27 @@@
  #ifndef _SURF_CPU_CAS01_PRIVATE_H
  #define _SURF_CPU_CAS01_PRIVATE_H
  
 -
+ #undef GENERIC_LMM_ACTION
+ #undef GENERIC_ACTION
+ #undef ACTION_GET_CPU
+ #define GENERIC_LMM_ACTION(action) action->generic_lmm_action
+ #define GENERIC_ACTION(action) GENERIC_LMM_ACTION(action).generic_action
+ #define ACTION_GET_CPU(action) ((surf_action_cpu_Cas01_t) action)->cpu
+ 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;
+ /*
+  * Energy-related properties for the cpu_cas01 model
+  */
+ typedef struct energy_cpu_cas01 {
+       xbt_dynar_t power_range_watts_list;             /*< List of (min_power,max_power) pairs corresponding to each cpu pstate */
+       double total_energy;                                    /*< Total energy consumed by the host */
+       double last_updated;                                    /*< Timestamp of the last energy update event*/
+ } s_energy_cpu_cas01_t, *energy_cpu_cas01_t;
  typedef struct cpu_Cas01 {
    s_surf_resource_t generic_resource;
    s_xbt_swag_hookup_t modified_cpu_hookup;
    tmgr_trace_event_t state_event;
    lmm_constraint_t constraint;
  
 -  energy_cpu_cas01_t energy;                          /*< Structure with energy-consumption data */
+   xbt_dynar_t power_peak_list;                                /*< List of supported CPU capacities */
+   int pstate;                                                         /*< Current pstate (index in the power_peak_list)*/
++  energy_cpu_cas01_t energy;  
++
 +  /* Note (hypervisor): */
 +  lmm_constraint_t *constraint_core;
  
  } s_cpu_Cas01_t, *cpu_Cas01_t;
  
-     double power_peak,
 +void *cpu_cas01_create_resource(const char *name,
++      xbt_dynar_t power_peak,
++      int pstate,
 +    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,
 +    surf_model_t cpu_model);
 +
+ xbt_dynar_t cpu_get_watts_range_list(cpu_Cas01_t cpu_model);
+ void cpu_update_energy(cpu_Cas01_t cpu_model, double cpu_load);
  #endif                          /* _SURF_CPU_CAS01_PRIVATE_H */
diff --combined src/surf/cpu_ti.c
@@@ -1,5 -1,5 +1,5 @@@
  
- /* Copyright (c) 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2009-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -111,7 -111,7 +111,7 @@@ static surf_cpu_ti_tgmr_t cpu_ti_parse_
    if (!power_trace) {
      trace->type = TRACE_FIXED;
      trace->value = value;
-     XBT_DEBUG("No availabily trace. Constant value = %lf", value);
+     XBT_DEBUG("No availability trace. Constant value = %f", value);
      return trace;
    }
  
    trace->total =
        surf_cpu_ti_integrate_trace_simple(trace->trace, 0, total_time);
  
-   XBT_DEBUG("Total integral %lf, last_time %lf ",
+   XBT_DEBUG("Total integral %f, last_time %f ",
           trace->total, trace->last_time);
  
    return trace;
  }
  
  
- static void* cpu_ti_create_resource(const char *name, double power_peak,
+ static void* cpu_ti_create_resource(const char *name, xbt_dynar_t power_peak,
+                                                  int pstate,
                             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)
  {
    tmgr_trace_t empty_trace;
    s_tmgr_event_t val;
                name);
    xbt_assert(core==1,"Multi-core not handled with this model yet");
    cpu = (cpu_ti_t) surf_resource_new(sizeof(s_cpu_ti_t),
-           cpu_model, name,cpu_properties);
 -          surf_cpu_model, name,cpu_properties, NULL);
++          cpu_model, name,cpu_properties, NULL);
    cpu->action_set =
        xbt_swag_new(xbt_swag_offset(ti_action, cpu_list_hookup));
-   cpu->power_peak = power_peak;
+   xbt_dynar_get_cpy(power_peak, 0, &cpu->power_peak);
+   xbt_dynar_free(&power_peak);  /* kill memory leak */
+   //cpu->power_peak = power_peak;
+   cpu->pstate = pstate;
+   XBT_DEBUG("CPU create: peak=%f, pstate=%d",cpu->power_peak, cpu->pstate);
    xbt_assert(cpu->power_peak > 0, "Power has to be >0");
-   XBT_DEBUG("power scale %lf", power_scale);
+   XBT_DEBUG("power scale %f", power_scale);
    cpu->power_scale = power_scale;
    cpu->avail_trace = cpu_ti_parse_trace(power_trace, power_scale);
    cpu->state_current = state_initial;
@@@ -194,13 -200,13 +201,14 @@@ static void parse_cpu_ti_init(sg_platf_
  {
    cpu_ti_create_resource(host->id,
          host->power_peak,
+         host->pstate,
          host->power_scale,
          host->power_trace,
          host->core_amount,
          host->initial_state,
          host->state_trace,
 -        host->properties);
 +        host->properties,
 +        surf_cpu_model_pm);
  
  }
  
@@@ -313,7 -319,7 +321,7 @@@ static void cpu_ti_action_state_set(sur
  * \param  cpu    Cpu on which the actions are running
  * \param  now    Current time
  */
 -static void cpu_ti_update_remaining_amount(cpu_ti_t cpu, double now)
 +static void cpu_ti_update_remaining_amount(surf_model_t cpu_model, cpu_ti_t cpu, double now)
  {
    double area_total;
    surf_action_cpu_ti_t action;
    area_total =
        surf_cpu_ti_integrate_trace(cpu->avail_trace, cpu->last_update,
                                    now) * cpu->power_peak;
-   XBT_DEBUG("Flops total: %lf, Last update %lf", area_total,
+   XBT_DEBUG("Flops total: %f, Last update %f", area_total,
           cpu->last_update);
  
    xbt_swag_foreach(action, cpu->action_set) {
      surf_action_t generic = (surf_action_t)action;
      /* action not running, skip it */
      if (generic->state_set !=
 -        surf_cpu_model->states.running_action_set)
 +        cpu_model->states.running_action_set)
        continue;
  
      /* bogus priority, skip it */
      double_update(&(generic->remains),
                    area_total / (cpu->sum_priority *
                                  generic->priority));
-     XBT_DEBUG("Update remaining action(%p) remaining %lf", action,
+     XBT_DEBUG("Update remaining action(%p) remaining %f", action,
             generic->remains);
    }
    cpu->last_update = now;
  * \param  cpu    Cpu on which the actions are running
  * \param  now    Current time
  */
 -static void cpu_ti_update_action_finish_date(cpu_ti_t cpu, double now)
 +static void cpu_ti_update_action_finish_date(surf_model_t cpu_model, cpu_ti_t cpu, double now)
  {
  #define GENERIC_ACTION(action) action->generic_action
    surf_action_cpu_ti_t action;
    double sum_priority = 0.0, total_area, min_finish = -1;
  
  /* update remaning amount of actions */
 -  cpu_ti_update_remaining_amount(cpu, now);
 +  cpu_ti_update_remaining_amount(cpu_model, cpu, now);
  
    xbt_swag_foreach(action, cpu->action_set) {
      /* action not running, skip it */
      if (GENERIC_ACTION(action).state_set !=
 -        surf_cpu_model->states.running_action_set)
 +        cpu_model->states.running_action_set)
        continue;
  
      /* bogus priority, skip it */
      min_finish = -1;
      /* action not running, skip it */
      if (GENERIC_ACTION(action).state_set !=
 -        surf_cpu_model->states.running_action_set)
 +        cpu_model->states.running_action_set)
        continue;
  
      /* verify if the action is really running on cpu */
        xbt_heap_push(cpu_ti_action_heap, action, min_finish);
  
      XBT_DEBUG
-         ("Update finish time: Cpu(%s) Action: %p, Start Time: %lf Finish Time: %lf Max duration %lf",
+         ("Update finish time: Cpu(%s) Action: %p, Start Time: %f Finish Time: %f Max duration %f",
           cpu->generic_resource.name, action, GENERIC_ACTION(action).start,
           GENERIC_ACTION(action).finish,
           GENERIC_ACTION(action).max_duration);
  #undef GENERIC_ACTION
  }
  
 -static double cpu_ti_share_resources(double now)
 +static double cpu_ti_share_resources(surf_model_t cpu_model, double now)
  {
    cpu_ti_t cpu, cpu_next;
    double min_action_duration = -1;
  
  /* iterates over modified cpus to update share resources */
    xbt_swag_foreach_safe(cpu, cpu_next, cpu_ti_modified_cpu) {
 -    cpu_ti_update_action_finish_date(cpu, now);
 +    /* FIXME: cpu_ti_modified_cpu is a global object. But, now we have multiple
 +     * cpu_model objects in the system. Do we have to create this
 +     * swag for each cpu model object?
 +     *
 +     * We should revisit here after we know what cpu_ti is.
 +     **/
 +    cpu_ti_update_action_finish_date(cpu_model, cpu, now);
    }
  /* get the min next event if heap not empty */
    if (xbt_heap_size(cpu_ti_action_heap) > 0)
      min_action_duration = xbt_heap_maxkey(cpu_ti_action_heap) - now;
  
-   XBT_DEBUG("Share resources, min next event date: %lf", min_action_duration);
+   XBT_DEBUG("Share resources, min next event date: %f", min_action_duration);
  
    return min_action_duration;
  }
  
 -static void cpu_ti_update_actions_state(double now, double delta)
 +static void cpu_ti_update_actions_state(surf_model_t cpu_model, double now, double delta)
  {
 +  /* FIXME: cpu_ti_action_heap is global. Is this okay for VM support? */
 +
  #define GENERIC_ACTION(action) action->generic_action
    surf_action_cpu_ti_t action;
    while ((xbt_heap_size(cpu_ti_action_heap) > 0)
      /* set the remains to 0 due to precision problems when updating the remaining amount */
      GENERIC_ACTION(action).remains = 0;
      cpu_ti_action_state_set((surf_action_t) action, SURF_ACTION_DONE);
 -    /* update remaining amount of all actions */
 -    cpu_ti_update_remaining_amount(surf_cpu_resource_priv(action->cpu), surf_get_clock());
 +    /* update remaining amout of all actions */
 +    cpu_ti_update_remaining_amount(cpu_model, surf_cpu_resource_priv(action->cpu), surf_get_clock());
    }
  #undef GENERIC_ACTION
  }
@@@ -502,20 -500,17 +510,18 @@@ static void cpu_ti_update_resource_stat
                                           double value, double date)
  {
    cpu_ti_t cpu = id;
 +  surf_model_t cpu_model = ((surf_resource_t) cpu)->model;
    surf_action_cpu_ti_t action;
  
-   surf_watched_hosts();
    if (event_type == cpu->power_event) {
      tmgr_trace_t power_trace;
      surf_cpu_ti_tgmr_t trace;
      s_tmgr_event_t val;
  
-     XBT_DEBUG("Finish trace date: %lf value %lf date %lf", surf_get_clock(),
+     XBT_DEBUG("Finish trace date: %f value %f date %f", surf_get_clock(),
             value, date);
      /* update remaining of actions and put in modified cpu swag */
 -    cpu_ti_update_remaining_amount(cpu, date);
 +    cpu_ti_update_remaining_amount(cpu_model, cpu, date);
      xbt_swag_insert(cpu, cpu_ti_modified_cpu);
  
      power_trace = cpu->avail_trace->power_trace;
      trace = xbt_new0(s_surf_cpu_ti_tgmr_t, 1);
      trace->type = TRACE_FIXED;
      trace->value = val.value;
-     XBT_DEBUG("value %lf", val.value);
+     XBT_DEBUG("value %f", val.value);
  
      cpu->avail_trace = trace;
  
        cpu->power_event = NULL;
  
    } else if (event_type == cpu->state_event) {
-     if (value > 0)
+     if (value > 0) {
+       if(cpu->state_current == SURF_RESOURCE_OFF)
+         xbt_dynar_push_as(host_that_restart, char*, (cpu->generic_resource.name));
        cpu->state_current = SURF_RESOURCE_ON;
-     else {
+     else {
        cpu->state_current = SURF_RESOURCE_OFF;
  
        /* put all action running on cpu to failed */
@@@ -575,11 -572,10 +583,11 @@@ static surf_action_t cpu_ti_execute(voi
  {
    surf_action_cpu_ti_t action = NULL;
    cpu_ti_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_ti_t), size, surf_cpu_model,
 +      surf_action_new(sizeof(s_surf_action_cpu_ti_t), size, cpu_model,
                        CPU->state_current != SURF_RESOURCE_ON);
    action->cpu = cpu;
    action->index_heap = -1;
@@@ -691,10 -687,9 +699,10 @@@ static void cpu_ti_action_set_priority(
  
  static double cpu_ti_action_get_remains(surf_action_t action)
  {
 +  surf_model_t cpu_model = action->model_obj;
    XBT_IN("(%p)", action);
 -  cpu_ti_update_remaining_amount((cpu_ti_t)
 -                                 ((surf_action_cpu_ti_t) action)->cpu,
 +
 +  cpu_ti_update_remaining_amount(cpu_model, (cpu_ti_t) ((surf_action_cpu_ti_t) action)->cpu,
                                   surf_get_clock());
    XBT_OUT();
    return action->remains;
@@@ -705,11 -700,6 +713,11 @@@ static e_surf_resource_state_t cpu_ti_g
    return ((cpu_ti_t)surf_cpu_resource_priv(cpu))->state_current;
  }
  
 +static void cpu_ti_set_state(void *cpu, e_surf_resource_state_t state)
 +{
 +  ((cpu_ti_t)surf_cpu_resource_priv(cpu))->state_current = state;
 +}
 +
  static double cpu_ti_get_speed(void *cpu, double load)
  {
    return load * ((cpu_ti_t)surf_cpu_resource_priv(cpu))->power_peak;
@@@ -747,15 -737,12 +755,15 @@@ static double cpu_ti_get_available_spee
    return CPU->power_scale;
  }
  
 -static void cpu_ti_finalize(void)
 +static void cpu_ti_finalize(surf_model_t cpu_model)
  {
    void **cpu;
    xbt_lib_cursor_t cursor;
    char *key;
  
 +  /* FIXME: we should update this code for VM support */
 +  xbt_abort();
 +
    xbt_lib_foreach(host_lib, cursor, key, cpu){
      if(cpu[SURF_CPU_LEVEL])
      {
      }
    }
  
 -  surf_model_exit(surf_cpu_model);
 -  surf_cpu_model = NULL;
 +  surf_model_exit(cpu_model);
 +  cpu_model = NULL;
  
    xbt_swag_free
        (cpu_ti_running_action_set_that_does_not_need_being_checked);
    xbt_heap_free(cpu_ti_action_heap);
  }
  
 -static void surf_cpu_ti_model_init_internal(void)
 +static surf_model_t surf_cpu_ti_model_init_internal(void)
  {
    s_surf_action_t action;
    s_cpu_ti_t cpu;
  
 -  surf_cpu_model = surf_model_init();
 +  surf_model_t cpu_model = surf_model_init();
  
    cpu_ti_running_action_set_that_does_not_need_being_checked =
        xbt_swag_new(xbt_swag_offset(action, state_hookup));
    cpu_ti_modified_cpu =
        xbt_swag_new(xbt_swag_offset(cpu, modified_cpu_hookup));
  
 -  surf_cpu_model->name = "cpu_ti";
 +  cpu_model->name = "cpu_ti";
 +  cpu_model->type = SURF_MODEL_TYPE_CPU;
  
 -  surf_cpu_model->action_unref = cpu_ti_action_unref;
 -  surf_cpu_model->action_cancel = cpu_ti_action_cancel;
 -  surf_cpu_model->action_state_set = cpu_ti_action_state_set;
 +  cpu_model->action_unref = cpu_ti_action_unref;
 +  cpu_model->action_cancel = cpu_ti_action_cancel;
 +  cpu_model->action_state_set = cpu_ti_action_state_set;
  
 -  surf_cpu_model->model_private->resource_used = cpu_ti_resource_used;
 -  surf_cpu_model->model_private->share_resources = cpu_ti_share_resources;
 -  surf_cpu_model->model_private->update_actions_state =
 +  cpu_model->model_private->resource_used = cpu_ti_resource_used;
 +  cpu_model->model_private->share_resources = cpu_ti_share_resources;
 +  cpu_model->model_private->update_actions_state =
        cpu_ti_update_actions_state;
 -  surf_cpu_model->model_private->update_resource_state =
 +  cpu_model->model_private->update_resource_state =
        cpu_ti_update_resource_state;
 -  surf_cpu_model->model_private->finalize = cpu_ti_finalize;
 -
 -  surf_cpu_model->suspend = cpu_ti_action_suspend;
 -  surf_cpu_model->resume = cpu_ti_action_resume;
 -  surf_cpu_model->is_suspended = cpu_ti_action_is_suspended;
 -  surf_cpu_model->set_max_duration = cpu_ti_action_set_max_duration;
 -  surf_cpu_model->set_priority = cpu_ti_action_set_priority;
 -  surf_cpu_model->get_remains = cpu_ti_action_get_remains;
 -
 -  surf_cpu_model->extension.cpu.execute = cpu_ti_execute;
 -  surf_cpu_model->extension.cpu.sleep = cpu_ti_action_sleep;
 -
 -  surf_cpu_model->extension.cpu.get_state = cpu_ti_get_state;
 -  surf_cpu_model->extension.cpu.get_speed = cpu_ti_get_speed;
 -  surf_cpu_model->extension.cpu.get_available_speed =
 +  cpu_model->model_private->finalize = cpu_ti_finalize;
 +
 +  cpu_model->suspend = cpu_ti_action_suspend;
 +  cpu_model->resume = cpu_ti_action_resume;
 +  cpu_model->is_suspended = cpu_ti_action_is_suspended;
 +  cpu_model->set_max_duration = cpu_ti_action_set_max_duration;
 +  cpu_model->set_priority = cpu_ti_action_set_priority;
 +  cpu_model->get_remains = cpu_ti_action_get_remains;
 +
 +  cpu_model->extension.cpu.execute = cpu_ti_execute;
 +  cpu_model->extension.cpu.sleep = cpu_ti_action_sleep;
 +
 +  cpu_model->extension.cpu.get_state = cpu_ti_get_state;
 +  cpu_model->extension.cpu.set_state = cpu_ti_set_state;
 +  cpu_model->extension.cpu.get_speed = cpu_ti_get_speed;
 +  cpu_model->extension.cpu.get_available_speed =
        cpu_ti_get_available_speed;
 -  surf_cpu_model->extension.cpu.add_traces = add_traces_cpu_ti;
 +  cpu_model->extension.cpu.add_traces = add_traces_cpu_ti;
  
    cpu_ti_action_heap = xbt_heap_new(8, NULL);
    xbt_heap_set_update_callback(cpu_ti_action_heap,
                                 cpu_ti_action_update_index_heap);
  
 +  return cpu_model;
  }
  
 -void surf_cpu_model_init_ti()
 +surf_model_t surf_cpu_model_init_ti(void)
  {
 -  xbt_assert(!surf_cpu_model,"CPU model already initialized. This should not happen.");
 -  surf_cpu_ti_model_init_internal();
 +  surf_model_t cpu_model = surf_cpu_ti_model_init_internal();
    cpu_ti_define_callbacks();
 -  xbt_dynar_push(model_list, &surf_cpu_model);
 +  xbt_dynar_push(model_list, &cpu_model);
 +
 +  return cpu_model;
  }
  
  
@@@ -937,7 -920,7 +945,7 @@@ static double surf_cpu_ti_integrate_tra
                                  trace->nb_points - 1);
    integral += trace->integral[ind];
    XBT_DEBUG
-       ("a %lf ind %d integral %lf ind + 1 %lf ind %lf time +1 %lf time %lf",
+       ("a %f ind %d integral %f ind + 1 %f ind %f time +1 %f time %f",
         a, ind, integral, trace->integral[ind + 1], trace->integral[ind],
         trace->time_points[ind + 1], trace->time_points[ind]);
    double_update(&a_aux, trace->time_points[ind]);
                                                                  trace->
                                                                  time_points
                                                                  [ind]);
-   XBT_DEBUG("Integral a %lf = %lf", a, integral);
+   XBT_DEBUG("Integral a %f = %f", a, integral);
  
    return integral;
  }
@@@ -999,14 -982,14 +1007,14 @@@ static double surf_cpu_ti_solve_trace(s
      return (a + (amount / trace->value));
    }
  
-   XBT_DEBUG("amount %lf total %lf", amount, trace->total);
+   XBT_DEBUG("amount %f total %f", amount, trace->total);
  /* Reduce the problem to one where amount <= trace_total */
    quotient = (int) (floor(amount / trace->total));
    reduced_amount = (trace->total) * ((amount / trace->total) -
                                       floor(amount / trace->total));
    reduced_a = a - (trace->last_time) * (int) (floor(a / trace->last_time));
  
-   XBT_DEBUG("Quotient: %d reduced_amount: %lf reduced_a: %lf", quotient,
+   XBT_DEBUG("Quotient: %d reduced_amount: %f reduced_a: %f", quotient,
           reduced_amount, reduced_a);
  
  /* Now solve for new_amount which is <= trace_total */
@@@ -1102,7 -1085,7 +1110,7 @@@ static int surf_cpu_ti_binary_search(do
    int mid;
    do {
      mid = low + (high - low) / 2;
-     XBT_DEBUG("a %lf low %d high %d mid %d value %lf", a, low, high, mid,
+     XBT_DEBUG("a %f low %d high %d mid %d value %f", a, low, high, mid,
          array[mid]);
  
      if (array[mid] > a)
diff --combined src/surf/maxmin.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004-2011. 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
@@@ -258,90 -258,6 +258,90 @@@ XBT_INLINE double lmm_variable_getbound
    return (var->bound);
  }
  
 +/* Replace the content of elem_a with elem_b. The content of elem_b is cleared. */
 +static void renew_elem_entry(lmm_element_t elem_a, lmm_element_t elem_b)
 +{
 +    elem_a->constraint = elem_b->constraint;
 +    elem_a->variable   = elem_b->variable;
 +    elem_a->value      = elem_b->value;
 +
 +    /* If elem_b is in the element_set swag, register the new element to the swag. */
 +    if (xbt_swag_remove(elem_b, &(elem_b->constraint->element_set))) {
 +      if (elem_a->variable->weight)
 +        xbt_swag_insert_at_head(elem_a, &(elem_a->constraint->element_set));
 +      else
 +        xbt_swag_insert_at_tail(elem_a, &(elem_a->constraint->element_set));
 +    }
 +
 +    if (xbt_swag_remove(elem_b, &(elem_b->constraint->active_element_set))) {
 +      if (elem_a->variable->weight)
 +        xbt_swag_insert_at_head(elem_a, &(elem_a->constraint->active_element_set));
 +      else
 +        xbt_swag_insert_at_tail(elem_a, &(elem_a->constraint->active_element_set));
 +    }
 +
 +    elem_b->constraint = NULL;
 +    elem_b->variable   = NULL;
 +    elem_b->value      = 0;
 +}
 +
 +void lmm_shrink(lmm_system_t sys, lmm_constraint_t cnst,
 +                lmm_variable_t var)
 +{
 +  lmm_element_t elem = NULL;
 +  int found = 0;
 +
 +  int i;
 +  for (i = 0; i < var->cnsts_number; i++) {
 +    elem = &(var->cnsts[i]);
 +    if (elem->constraint == cnst) {
 +      found = 1;
 +      break;
 +    }
 +  }
 +
 +  if (!found) {
 +    XBT_DEBUG("cnst %p is not found in var %p", cnst, var);
 +    return;
 +  }
 +
 +  sys->modified = 1;
 +
 +  XBT_DEBUG("remove elem(value %lf, cnst %p, var %p) in var %p",
 +      elem->value, elem->constraint, elem->variable, var);
 +
 +
 +
 +  /* We are going to change the constraint object and the variable object.
 +   * Propagate this change to other objects. Calling here (not after
 +   * modification) is correct? */
 +  lmm_update_modified_set(sys, cnst);
 +  lmm_update_modified_set(sys, var->cnsts[0].constraint); // will look up element_set of this constraint, and then each var in the element_set, and each var->cnsts[i].
 +
 +
 +
 +  /* now var->cnsts[i] is not necessary any more */
 +
 +  xbt_swag_remove(elem, &(elem->constraint->element_set));
 +  xbt_swag_remove(elem, &(elem->constraint->active_element_set));
 +  elem->constraint = NULL;
 +  elem->variable = NULL;
 +  elem->value = 0;
 +
 +
 +
 +  /* We do not want to have an empty element entry before the last entry. So,
 +   * plug up the hole with the last one. */
 +  if (i < var->cnsts_number - 1)
 +    renew_elem_entry(&var->cnsts[i], &var->cnsts[var->cnsts_number - 1]);
 +
 +  var->cnsts_number -= 1;
 +
 +
 +  if (xbt_swag_size(&(cnst->element_set)) == 0)
 +    make_constraint_inactive(sys, cnst);
 +}
 +
  void lmm_expand(lmm_system_t sys, lmm_constraint_t cnst,
                  lmm_variable_t var, double value)
  {
@@@ -973,3 -889,30 +973,30 @@@ static void lmm_remove_all_modified_set
    }
    xbt_swag_reset(&sys->modified_constraint_set);
  }
+ /**
+  *  Returns total resource load
+  *
+  *  \param cnst the lmm_constraint_t associated to the resource
+  *
+  */
+ double lmm_constraint_get_usage(lmm_constraint_t cnst) {
+    double usage = 0.0;
+    xbt_swag_t elem_list = &(cnst->element_set);
+    lmm_element_t elem = NULL;
+    xbt_swag_foreach(elem, elem_list) {
+      /* 0-weighted elements (ie, sleep actions) are at the end of the swag and we don't want to consider them */
+      if (elem->variable->weight <= 0)
+        break;
+      if ((elem->value > 0)) {
+        if (cnst->shared)
+          usage += elem->value * elem->variable->value;
+        else if (usage < elem->value * elem->variable->value)
+          usage = elem->value * elem->variable->value;
+      }
+    }
+   return usage;
+ }
diff --combined src/surf/network.c
@@@ -6,7 -6,7 +6,7 @@@
   * highly dependent on the maxmin lmm module.
   */
  
- /* Copyright (c) 2009, 2010, 2011. 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
@@@ -126,12 -126,12 +126,12 @@@ static double smpi_bandwidth_factor(dou
    double current=1.0;
    xbt_dynar_foreach(smpi_bw_factor, iter, fact) {
      if (size <= fact.factor) {
-       XBT_DEBUG("%lf <= %ld return %f", size, fact.factor, current);
+       XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current);
        return current;
      }else
        current=fact.value;
    }
-   XBT_DEBUG("%lf > %ld return %f", size, fact.factor, current);
+   XBT_DEBUG("%f > %ld return %f", size, fact.factor, current);
  
    return current;
  }
@@@ -147,12 -147,12 +147,12 @@@ static double smpi_latency_factor(doubl
    double current=1.0;
    xbt_dynar_foreach(smpi_lat_factor, iter, fact) {
      if (size <= fact.factor) {
-       XBT_DEBUG("%lf <= %ld return %f", size, fact.factor, current);
+       XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current);
        return current;
      }else
        current=fact.value;
    }
-   XBT_DEBUG("%lf > %ld return %f", size, fact.factor, current);
+   XBT_DEBUG("%f > %ld return %f", size, fact.factor, current);
  
    return current;
  }
@@@ -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,
                                        double value, double date)
  {
    link_CM02_t nw_link = id;
-   /*   printf("[" "%lg" "] Asking to update network card \"%s\" with value " */
-   /*     "%lg" " for event %p\n", surf_get_clock(), nw_link->name, */
+   /*   printf("[" "%g" "] Asking to update network card \"%s\" with value " */
+   /*     "%g" " for event %p\n", surf_get_clock(), nw_link->name, */
    /*     value, event_type); */
  
    if (event_type == nw_link->lmm_resource.power.event) {
@@@ -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);
@@@ -680,7 -680,7 +680,7 @@@ static void smpi_gap_append(double size
  
    if (sg_sender_gap > 0.0) {
      if (!gap_lookup) {
-       gap_lookup = xbt_dict_new();
+       gap_lookup = xbt_dict_new_homogeneous(NULL);
      }
      fifo = (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup, src);
      action->sender.gap = 0.0;
@@@ -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;
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2008-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -18,7 -18,6 +18,6 @@@ typedef struct surf_action_network_Cons
  } s_surf_action_network_Constant_t, *surf_action_network_Constant_t;
  
  XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
- static random_data_t random_latency = NULL;
  static int host_number_int = 0;
  
  static void netcste_count_hosts(sg_platf_host_cbarg_t h) {
@@@ -50,11 -49,11 +49,11 @@@ static void netcste_action_cancel(surf_
    return;
  }
  
 -static double netcste_share_resources(double now)
 +static double netcste_share_resources(surf_model_t network_model, double now)
  {
    surf_action_network_Constant_t action = NULL;
    xbt_swag_t running_actions =
 -      surf_network_model->states.running_action_set;
 +      network_model->states.running_action_set;
    double min = -1.0;
  
    xbt_swag_foreach(action, running_actions) {
    return min;
  }
  
 -static void netcste_update_actions_state(double now, double delta)
 +static void netcste_update_actions_state(surf_model_t network_model, double now, double delta)
  {
    surf_action_network_Constant_t action = NULL;
    surf_action_network_Constant_t next_action = NULL;
    xbt_swag_t running_actions =
 -      surf_network_model->states.running_action_set;
 +      network_model->states.running_action_set;
  
    xbt_swag_foreach_safe(action, next_action, running_actions) {
      if (action->latency > 0) {
  
      if (action->generic_action.remains <= 0) {
        action->generic_action.finish = surf_get_clock();
 -      surf_network_model->action_state_set((surf_action_t) action,
 +      network_model->action_state_set((surf_action_t) action,
                                             SURF_ACTION_DONE);
      } else if ((action->generic_action.max_duration != NO_MAX_DURATION)
                 && (action->generic_action.max_duration <= 0)) {
        action->generic_action.finish = surf_get_clock();
 -      surf_network_model->action_state_set((surf_action_t) action,
 +      network_model->action_state_set((surf_action_t) action,
                                             SURF_ACTION_DONE);
      }
    }
@@@ -126,7 -125,7 +125,7 @@@ static surf_action_t netcste_communicat
  
    action->suspended = 0;
  
-   action->latency = sg_latency_factor;          //random_generate(random_latency);
+   action->latency = sg_latency_factor;
    action->lat_init = action->latency;
  
    if (action->latency <= 0.0) {
@@@ -181,10 -180,10 +180,10 @@@ static int netcste_action_is_suspended(
    return ((surf_action_network_Constant_t) action)->suspended;
  }
  
 -static void netcste_finalize(void)
 +static void netcste_finalize(surf_model_t network_model)
  {
 -  surf_model_exit(surf_network_model);
 -  surf_network_model = NULL;
 +  surf_model_exit(network_model);
 +  network_model = NULL;
  }
  
  
@@@ -217,11 -216,7 +216,11 @@@ void surf_network_model_init_Constant(
    surf_network_model->suspend = netcste_action_suspend;
    surf_network_model->resume = netcste_action_resume;
    surf_network_model->is_suspended = netcste_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 = netcste_communicate;
    surf_network_model->extension.network.get_link_bandwidth =
    surf_network_model->set_category = netcste_action_set_category;
  #endif
  
-   if (!random_latency)
-     random_latency = random_new(RAND, 100, 0.0, 1.0, .125, .034);
    netcste_define_callbacks();
    xbt_dynar_push(model_list, &surf_network_model);
  
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -196,7 -196,7 +196,7 @@@ static void action_state_set(surf_actio
    surf_action_state_set(action, state);
  }
  
 -static double share_resources(double now)
 +static double share_resources(surf_model_t network_model, double now)
  {
    xbt_swag_t running_actions =
        surf_network_model->states.running_action_set;
  
    XBT_DEBUG("Calling gtnets_get_time_to_next_flow_completion");
    time_to_next_flow_completion = gtnets_get_time_to_next_flow_completion();
-   XBT_DEBUG("gtnets_get_time_to_next_flow_completion received %lg",
+   XBT_DEBUG("gtnets_get_time_to_next_flow_completion received %g",
           time_to_next_flow_completion);
  
    return time_to_next_flow_completion;
  }
  
 -static void update_actions_state(double now, double delta)
 +static void update_actions_state(surf_model_t network_model, double now, double delta)
  {
    surf_action_network_GTNETS_t action = NULL;
    xbt_swag_t running_actions =
 -      surf_network_model->states.running_action_set;
 +      network_model->states.running_action_set;
  
    /* If there are no running flows, just return */
    if (time_to_next_flow_completion < 0.0) {
@@@ -400,7 -400,7 +400,7 @@@ static void gtnets_action_set_category(
  }
  #endif
  
 -static void finalize(void)
 +static void finalize(surf_model_t network_model)
  {
    gtnets_finalize();
  }
@@@ -410,7 -410,6 +410,7 @@@ static void surf_network_model_init_int
    surf_network_model = surf_model_init();
  
    surf_network_model->name = "network GTNetS";
 +  surf_network_model->type = SURF_MODEL_TYPE_NETWORK;
    surf_network_model->action_unref = action_unref;
    surf_network_model->action_cancel = action_cancel;
    surf_network_model->action_recycle = action_recycle;
diff --combined src/surf/network_ns3.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010, 2011. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -23,9 -23,9 +23,9 @@@ extern xbt_dict_t dict_socket
  
  static double time_to_next_flow_completion = -1;
  
 -static double ns3_share_resources(double min);
 -static void ns3_update_actions_state(double now, double delta);
 -static void finalize(void);
 +static double ns3_share_resources(surf_model_t network_model, double min);
 +static void ns3_update_actions_state(surf_model_t network_model, double now, double delta);
 +static void finalize(surf_model_t network_model);
  static surf_action_t ns3_communicate(sg_routing_edge_t src_elm,
                                       sg_routing_edge_t dst_elm,
                                       double size, double rate);
@@@ -342,7 -342,6 +342,7 @@@ void surf_network_model_init_NS3(
  
    surf_network_model = surf_model_init();
    surf_network_model->name = "network NS3";
 +  surf_network_model->type = SURF_MODEL_TYPE_NETWORK;
    surf_network_model->extension.network.get_link_latency = ns3_get_link_latency;
    surf_network_model->extension.network.get_link_bandwidth = ns3_get_link_bandwidth;
    surf_network_model->extension.network.get_route = ns3_get_route;
  #endif
  }
  
 -static void finalize(void)
 +static void finalize(surf_model_t network_model)
  {
    ns3_finalize();
    xbt_dynar_free_container(&IPV4addr);
    xbt_dict_free(&dict_socket);
  }
  
 -static double ns3_share_resources(double min)
 +static double ns3_share_resources(surf_model_t network_model, double min)
  {
    XBT_DEBUG("ns3_share_resources");
  
    xbt_swag_t running_actions =
 -    surf_network_model->states.running_action_set;
 +    network_model->states.running_action_set;
  
    //get the first relevant value from the running_actions list
    if (!xbt_swag_size(running_actions) || min == 0.0)
    return time_to_next_flow_completion;
  }
  
 -static void ns3_update_actions_state(double now, double delta)
 +static void ns3_update_actions_state(surf_model_t network_model, double now, double delta)
  {
    xbt_dict_cursor_t cursor = NULL;
    char *key;
  
    surf_action_network_ns3_t action = NULL;
    xbt_swag_t running_actions =
 -    surf_network_model->states.running_action_set;
 +    network_model->states.running_action_set;
  
    /* If there are no running flows, just return */
    if (!xbt_swag_size(running_actions)) {
diff --combined src/surf/new_model.c
@@@ -1,8 -1,8 +1,8 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012. The SimGrid Team.
-  * All rights reserved.                                                                 */
+ /* Copyright (c) 2004-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
-  * under the terms of the license (GNU LGPL) which comes with this package.             */
+  * under the terms of the license (GNU LGPL) which comes with this package. */
  
  /* ********************************************************************* */
  /* TUTORIAL: New model                                                   */
@@@ -47,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;
  }
@@@ -147,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,8 -1,8 +1,8 @@@
- /* Copyright (c) 2004 - 2013. The SimGrid Team.
-  * All rights reserved.                                                                 */
+ /* Copyright (c) 2004-2013. The SimGrid Team.
+  * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
-  * under the terms of the license (GNU LGPL) which comes with this package.             */
+  * under the terms of the license (GNU LGPL) which comes with this package. */
  
  #include "xbt/ex.h"
  #include "xbt/dict.h"
@@@ -10,6 -10,7 +10,7 @@@
  #include "surf_private.h"
  #include "storage_private.h"
  #include "surf/surf_resource.h"
+ #include <inttypes.h>
  
  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_storage, surf,
                                  "Logging specific to the SURF storage module");
@@@ -34,19 -35,19 +35,19 @@@ 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, size_t *used_size);
+ static xbt_dict_t parse_storage_content(char *filename, sg_storage_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, size_t size, e_surf_action_storage_type_t type);
+ static surf_action_t storage_action_execute (void *storage, sg_storage_size_t size, e_surf_action_storage_type_t type);
  
  static surf_action_t storage_action_ls(void *storage, const char* path)
  {
    surf_action_t action = storage_action_execute(storage,0, LS);
    action->ls_dict = NULL;
-   xbt_dict_t ls_dict = xbt_dict_new();
+   xbt_dict_t ls_dict = xbt_dict_new_homogeneous(xbt_free);
  
    char* key;
-   size_t size = 0;
+   sg_storage_size_t size = 0;
    xbt_dict_cursor_t cursor = NULL;
  
    xbt_dynar_t dyn = NULL;
@@@ -64,7 -65,9 +65,9 @@@
  
        // file
        if(xbt_dynar_length(dyn) == 1){
-         xbt_dict_set(ls_dict,file,&size,NULL);
+         sg_storage_size_t *psize = xbt_new(sg_storage_size_t,1);
+         *psize=size;
+         xbt_dict_set(ls_dict,file,psize,NULL);
        }
        // Directory
        else
@@@ -86,16 -89,22 +89,22 @@@ static surf_action_t storage_action_ope
  {
    XBT_DEBUG("\tOpen file '%s'",path);
    xbt_dict_t content_dict = ((storage_t)storage)->content;
-   size_t size = (size_t) xbt_dict_get_or_null(content_dict,path);
+   sg_storage_size_t size, *psize;
+   psize = (sg_storage_size_t*) xbt_dict_get_or_null(content_dict, path);
+   if (psize)
+     size = *psize;
+   else {
    // if file does not exist create an empty file
-   if(!size){
-     xbt_dict_set(content_dict,path,&size,NULL);
+     psize = xbt_new(sg_storage_size_t,1);
+     size = 0;
+     *psize = size;
+     xbt_dict_set(content_dict,path,psize,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->size = size;
-   file->storage = xbt_strdup(mount);
+   file->mount = xbt_strdup(mount);
  
    surf_action_t action = storage_action_execute(storage,0, OPEN);
    action->file = (void *)file;
  static surf_action_t storage_action_close(void *storage, surf_file_t fd)
  {
    char *filename = fd->name;
-   XBT_DEBUG("\tClose file '%s' size '%zu'",filename,fd->size);
+   XBT_DEBUG("\tClose file '%s' size '%" PRIu64 "'", filename, fd->size);
    // unref write actions from storage
    surf_action_storage_t write_action;
    unsigned int i;
        storage_action_unref((surf_action_t) write_action);
      }
    }
    free(fd->name);
-   free(fd->storage);
+   free(fd->mount);
    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, 
-                                        size_t size, surf_file_t fd)
+ static surf_action_t storage_action_read(void *storage, surf_file_t fd, sg_storage_size_t size)
  {
    if(size > fd->size)
      size = fd->size;
    return action;
  }
  
- static surf_action_t storage_action_write(void *storage, const void* ptr,
-                                           size_t size, surf_file_t fd)
+ static surf_action_t storage_action_write(void *storage, surf_file_t fd, sg_storage_size_t size)
  {
    char *filename = fd->name;
-   XBT_DEBUG("\tWrite file '%s' size '%zu/%zu'",filename,size,fd->size);
+   XBT_DEBUG("\tWrite file '%s' size '%" PRIu64 "/%" PRIu64 "'",
+             filename, size, fd->size);
  
    surf_action_t action = storage_action_execute(storage,size,WRITE);
    action->file = fd;
    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_execute (void *storage, sg_storage_size_t size, e_surf_action_storage_type_t type)
  {
    surf_action_storage_t action = NULL;
    storage_t STORAGE = storage;
  
-   XBT_IN("(%s,%zu", surf_resource_name(STORAGE), size);
+   XBT_IN("(%s,%" PRIu64, 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);
    return (surf_action_t) action;
  }
  
- static void* storage_create_resource(const char* id, const char* model,const char* type_id,const char* content_name)
+ static xbt_dict_t storage_get_properties(const void *storage)
+ {
+   return surf_resource_properties(surf_storage_resource_priv(storage));
+ }
+ static xbt_dict_t storage_get_content(void *storage)
  {
+   /* For the moment this action has no cost, but in the future we could take in account access latency of the disk */
+   /*surf_action_t action = storage_action_execute(storage,0, LS);*/
+   void *storage_resource = surf_storage_resource_priv(storage);
+   xbt_dict_t content_dict = xbt_dict_new_homogeneous(NULL);
+   xbt_dict_cursor_t cursor = NULL;
+   char *file;
+   sg_storage_size_t *psize;
+   xbt_dict_foreach(((storage_t)storage_resource)->content, cursor, file, psize){
+     xbt_dict_set(content_dict,file,psize,NULL);
+   }
+   return content_dict;
+ }
+ static sg_storage_size_t storage_get_size(void *storage){
+   void *storage_resource = surf_storage_resource_priv(storage);
+   return ((storage_t)storage_resource)->size;
+ }
+ static void* storage_create_resource(const char* id, const char* model,
+     const char* type_id, const char* content_name, const char* content_type, xbt_dict_t properties){
    storage_t storage = NULL;
  
    xbt_assert(!surf_storage_resource_priv(surf_storage_resource_by_name(id)),
                "Storage '%s' declared several times in the platform file",
                id);
    storage = (storage_t) surf_resource_new(sizeof(s_storage_t),
-           surf_storage_model, id,NULL);
+           surf_storage_model, id, properties, NULL);
  
    storage->state_current = SURF_RESOURCE_ON;
    storage->used_size = 0;
    storage->write_actions = xbt_dynar_new(sizeof(char *),NULL);
  
    storage_type_t storage_type = xbt_lib_get_or_null(storage_type_lib, type_id,ROUTING_STORAGE_TYPE_LEVEL);
-   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"));
+   double Bread =
+       surf_parse_get_bandwidth(xbt_dict_get(storage_type->properties,"Bread"));
+   double Bwrite =
+       surf_parse_get_bandwidth(xbt_dict_get(storage_type->properties,"Bwrite"));
+   double Bconnection =
+       surf_parse_get_bandwidth(xbt_dict_get(storage_type->properties,
+                                             "Bconnection"));
    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);
    storage->content = parse_storage_content((char*)content_name,&(storage->used_size));
+   storage->content_type = xbt_strdup(content_type);
    storage->size = storage_type->size;
+   storage->type_id = xbt_strdup(type_id);
  
    xbt_lib_set(storage_lib, id, SURF_STORAGE_LEVEL, storage);
  
        storage_type->properties,
        Bread);
  
-   if(!storage_list) storage_list=xbt_dynar_new(sizeof(char *),NULL);
+   if (!storage_list)
+     storage_list = xbt_dynar_new(sizeof(char *),NULL);
    xbt_dynar_push(storage_list,&storage);
  
    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
-   // For each action of type write
    xbt_swag_foreach_safe(action, next_action, running_actions) {
      if(action->type == WRITE)
      {
+       // Update the disk usage
+       // Update the file size
+       // Update the storage content (with file size)
        double rate = lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable);
        /* Hack to avoid rounding differences between x86 and x86_64
-        * (note that the next sizes are of type size_t). */
+        * (note that the next sizes are of type sg_storage_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
-     }
-   }
  
-   xbt_swag_foreach_safe(action, next_action, running_actions) {
+       sg_storage_size_t *psize = xbt_new(sg_storage_size_t,1);
+       *psize = ((surf_action_t)action)->file->size;
+       xbt_dict_t content_dict = ((storage_t)(action->storage))->content;
+       xbt_dict_set(content_dict,((surf_action_t)action)->file->name,psize,NULL);
+     }
  
      double_update(&(GENERIC_ACTION(action).remains),
                    lmm_variable_getvalue(GENERIC_LMM_ACTION(action).variable) * delta);
    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);
  
@@@ -411,20 -456,28 +456,28 @@@ static void parse_storage_init(sg_platf
    // if storage content is not specified use the content of storage_type if exist
    if(!strcmp(storage->content,"") && strcmp(((storage_type_t) stype)->content,"")){
      storage->content = ((storage_type_t) stype)->content;
-     XBT_DEBUG("For disk '%s' content is empty, use the content of storage type '%s'",storage->id,((storage_type_t) stype)->type_id);
+     storage->content_type = ((storage_type_t) stype)->content_type;
+     XBT_DEBUG("For disk '%s' content is empty, inherit the content (of type %s) from storage type '%s' ",
+         storage->id,((storage_type_t) stype)->content_type,
+         ((storage_type_t) stype)->type_id);
    }
  
-   XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' \n\t\tmodel '%s' \n\t\tcontent '%s'\n\t\tproperties '%p'\n",
+   XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' "
+       "\n\t\tmodel '%s' \n\t\tcontent '%s'\n\t\tcontent_type '%s' "
+       "\n\t\tproperties '%p'\n",
        storage->id,
        ((storage_type_t) stype)->model,
        ((storage_type_t) stype)->type_id,
        storage->content,
+       storage->content_type,
        ((storage_type_t) stype)->properties);
  
    storage_create_resource(storage->id,
       ((storage_type_t) stype)->model,
       ((storage_type_t) stype)->type_id,
-      storage->content);
+      storage->content,
+      storage->content_type,
+      storage->properties);
  }
  
  static void parse_mstorage_init(sg_platf_mstorage_cbarg_t mstorage)
@@@ -461,7 -514,6 +514,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.read = storage_action_read;
    surf_storage_model->extension.storage.write = storage_action_write;
    surf_storage_model->extension.storage.ls = storage_action_ls;
+   surf_storage_model->extension.storage.get_properties = storage_get_properties;
+   surf_storage_model->extension.storage.get_content = storage_get_content;
+   surf_storage_model->extension.storage.get_size = storage_get_size;
    if (!storage_maxmin_system) {
      storage_maxmin_system = lmm_system_new(storage_selective_update);
    }
  }
  
  void surf_storage_model_init_default(void)
@@@ -520,13 -573,13 +574,13 @@@ static void storage_parse_storage(sg_pl
        (void *) xbt_strdup(storage->type_id));
  }
  
- static xbt_dict_t parse_storage_content(char *filename, size_t *used_size)
+ static xbt_dict_t parse_storage_content(char *filename, sg_storage_size_t *used_size)
  {
    *used_size = 0;
    if ((!filename) || (strcmp(filename, "") == 0))
      return NULL;
  
-   xbt_dict_t parse_content = xbt_dict_new_homogeneous(NULL);
+   xbt_dict_t parse_content = xbt_dict_new_homogeneous(xbt_free);
    FILE *file = NULL;
  
    file = surf_fopen(filename, "r");
    size_t len = 0;
    ssize_t read;
    char path[1024];
-   size_t size;
+   sg_storage_size_t size;
  
    while ((read = xbt_getline(&line, &len, file)) != -1) {
      if (read){
-     if(sscanf(line,"%s %zu",path, &size)==2) {
+     if (sscanf(line,"%s %" SCNu64, path, &size) == 2) {
          *used_size += size;
-         xbt_dict_set(parse_content,path,(void*) size,NULL);
+         sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
+         *psize = size;
+         xbt_dict_set(parse_content,path,psize,NULL);
        } else {
          xbt_die("Be sure of passing a good format for content file.\n");
        }
@@@ -564,13 -618,16 +619,16 @@@ static void storage_parse_storage_type(
    stype->model = xbt_strdup(storage_type->model);
    stype->properties = storage_type->properties;
    stype->content = xbt_strdup(storage_type->content);
+   stype->content_type = xbt_strdup(storage_type->content_type);
    stype->type_id = xbt_strdup(storage_type->id);
-   stype->size = storage_type->size * 1000000000; /* storage_type->size is in Gbytes and stype->sizeis in bytes */
+   stype->size = storage_type->size;
  
-   XBT_DEBUG("ROUTING Create a storage type id '%s' with model '%s' content '%s'",
+   XBT_DEBUG("ROUTING Create a storage type id '%s' with model '%s', "
+       "content '%s', and content_type '%s'",
        stype->type_id,
        stype->model,
-       storage_type->content);
+       storage_type->content,
+       storage_type->content_type);
  
    xbt_lib_set(storage_type_lib,
        stype->type_id,
@@@ -605,14 -662,15 +663,15 @@@ static void storage_parse_mount(sg_plat
  {
    // Verification of an existing storage
  #ifndef NDEBUG
-   void* storage = xbt_lib_get_or_null(storage_lib, mount->id,ROUTING_STORAGE_LEVEL);
+   void* storage = xbt_lib_get_or_null(storage_lib, mount->storageId,ROUTING_STORAGE_LEVEL);
  #endif
-   xbt_assert(storage,"Disk id \"%s\" does not exists", mount->id);
+   xbt_assert(storage,"Disk id \"%s\" does not exists", mount->storageId);
  
-   XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->id, mount->name);
+   XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->storageId, mount->name);
  
    s_mount_t mnt;
-   mnt.id = surf_storage_resource_priv(surf_storage_resource_by_name(mount->id));
+   mnt.storage =
+     surf_storage_resource_priv(surf_storage_resource_by_name(mount->storageId));
    mnt.name = xbt_strdup(mount->name);
  
    if(!mount_list){
@@@ -628,6 -686,7 +687,7 @@@ static XBT_INLINE void routing_storage_
    free(stype->model);
    free(stype->type_id);
    free(stype->content);
+   free(stype->content_type);
    xbt_dict_free(&(stype->properties));
    free(stype);
  }
@@@ -638,6 -697,8 +698,8 @@@ static XBT_INLINE void surf_storage_res
    storage_t storage = r;
    xbt_dict_free(&storage->content);
    xbt_dynar_free(&storage->write_actions);
+   free(storage->type_id);
+   free(storage->content_type);
    // generic resource
    surf_resource_free(r);
  }
@@@ -660,3 -721,4 +722,4 @@@ void storage_register_callbacks() 
    sg_platf_storage_type_add_cb(storage_parse_storage_type);
    sg_platf_mount_add_cb(storage_parse_mount);
  }
diff --combined src/surf/surf.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011. 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
@@@ -110,14 -110,12 +110,16 @@@ 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;
+ xbt_dynar_t host_that_restart = NULL;
+ xbt_dict_t watched_hosts_lib;
  
  /* Don't forget to update the option description in smx_config when you change this */
  s_surf_model_description_t surf_network_model_description[] = {
@@@ -354,14 -352,14 +356,14 @@@ double generic_share_resources_lazy(dou
        max_dur_flag = 1;
      }
  
-     XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
+     XBT_DEBUG("Action(%p) Start %f Finish %f Max_duration %f", action,
          action->generic_action.start, now + value,
          action->generic_action.max_duration);
  
      if (min != -1) {
        surf_action_lmm_heap_remove(model->model_private->action_heap,action);
        surf_action_lmm_heap_insert(model->model_private->action_heap,action, min, max_dur_flag ? MAX_DURATION : NORMAL);
-       XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
+       XBT_DEBUG("Insert at heap action(%p) min %f now %f", action, min,
                  now);
      } else DIE_IMPOSSIBLE;
    }
    else
      min = -1;
  
-   XBT_DEBUG("The minimum with the HEAP %lf", min);
+   XBT_DEBUG("The minimum with the HEAP %f", min);
  
    return min;
  }
@@@ -403,7 -401,7 +405,7 @@@ void surf_init(int *argc, char **argv
    as_router_lib = xbt_lib_new();
    storage_lib = xbt_lib_new();
    storage_type_lib = xbt_lib_new();
-   watched_hosts_lib = xbt_dict_new();
+   watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
  
    XBT_DEBUG("Add routing levels");
    ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
    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();
  
@@@ -470,14 -466,16 +472,19 @@@ void surf_exit(void
    unsigned int iter;
    surf_model_t model = NULL;
  
+ #ifdef HAVE_TRACING
+   TRACE_end();                  /* Just in case it was not called by the upper
+                                  * layer (or there is no upper layer) */
+ #endif
    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) {
    xbt_free(surf_mins);
    surf_mins = NULL;
  #endif
+   xbt_dynar_free(&host_that_restart);
    xbt_dynar_free(&surf_path);
  
    xbt_lib_free(&host_lib);
@@@ -538,15 -536,12 +545,15 @@@ 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)
  {
 +                
    min = -1.0; /* duration */
    double next_event_date = -1.0;
    double model_next_action_end = -1.0;
    tmgr_trace_event_t event = NULL;
    unsigned int iter;
  
+   if(!host_that_restart)
+     host_that_restart = xbt_dynar_new(sizeof(char*), NULL);
    if (max_date != -1.0 && max_date != NOW) {
      min = max_date - NOW;
    }
    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;
  
    /* 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)
              tmgr_history_get_next_event_leq(history, next_event_date,
                                              &value,
                                              (void **) &resource))) {
-       if (resource->model->model_private->resource_used(resource)) {
+       if (resource->model->model_private->resource_used(resource) ||
+           xbt_dict_get_or_null(watched_hosts_lib,resource->name)
+           ) {
          min = next_event_date - NOW;
          XBT_DEBUG
              ("This event will modify model state. Next event set to %f",
        }
        /* update state of model_obj according to new value. Does not touch lmm.
           It will be modified if needed when updating actions */
-       XBT_DEBUG("Calling update_resource_state for resource %s with min %lf",
-              resource->model->name, min);
+       XBT_DEBUG("Calling update_resource_state for resource %s with min %f",
+              resource->name, min);
        resource->model->model_private->update_resource_state(resource,
                                                              event, value,
                                                              next_event_date);
    XBT_DEBUG("Duration set to %f", min);
  
    NOW = NOW + min;
 -
 +  /* FIXME: model_list or model_list_invoke? revisit here later */
    /* sequential version */
    xbt_dynar_foreach(model_list, iter, model) {
      surf_update_actions_state(model);
@@@ -667,7 -669,7 +680,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);
  }
  
- /* 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.
-  * Instead, each model change a global data, and then the caller of surf_solve must
-  * pick into these sets of action_failed and action_done.
-  *
-  * This was not clean but ok as long as we didn't had to restart the processes when the resource comes back up.
-  * We worked by putting sentinel actions on every resources we are interested in,
-  * so that surf informs us if/when the corresponding resource fails.
-  *
-  * But this does not work to get Simix informed of when a resource comes back up, and this is where this pimple comes.
-  * We have a set of resources that are currently down and for which simix needs to know when it comes back up.
-  * And the current function is called *at every simulation step* to sweep over that set, searching for a resource
-  * that was turned back up in the meanwhile. This is UGLY and slow.
-  *
-  * The proper solution would be to not rely on globals for the action_failed and action_done swags.
-  * They must be passed as parameter by the caller (the handling of these actions in simix may let you
-  * think that these two sets can be merged, but their handling in SimDag induce the contrary unless this
-  * simdag code can check by itself whether the action is done of failed -- seems very doable, but yet more
-  * cleanup to do).
-  *
-  * Once surf_solve() is passed the set of actions that changed, you want to add a new set of resources back up
-  * as parameter to this function. You also want to add a boolean field "restart_watched" to each resource, and
-  * make sure that whenever a resource with this field enabled comes back up, it's added to that set so that Simix
-  * sees it and react accordingly. This would kill that need for surf to call simix.
-  *
-  */
- static void remove_watched_host(void *key)
- {
-   xbt_dict_remove(watched_hosts_lib, *(char**)key);
- }
- void surf_watched_hosts(void)
- {
-   char *key;
-   void *host;
-   xbt_dict_cursor_t cursor;
-   xbt_dynar_t hosts = xbt_dynar_new(sizeof(char*), NULL);
-   XBT_DEBUG("Check for host SURF_RESOURCE_ON on watched_hosts_lib");
-   xbt_dict_foreach(watched_hosts_lib,cursor,key,host)
-   {
-     if(SIMIX_host_get_state(host) == SURF_RESOURCE_ON){
-       XBT_INFO("Restart processes on host: %s",SIMIX_host_get_name(host));
-       SIMIX_host_autorestart(host);
-       xbt_dynar_push_as(hosts, char*, key);
-     }
-     else
-       XBT_DEBUG("See SURF_RESOURCE_OFF on host: %s",key);
-   }
-   xbt_dynar_map(hosts, remove_watched_host);
-   xbt_dynar_free(&hosts);
- }
diff --combined src/surf/surf_action.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2009-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -6,6 -6,9 +6,9 @@@
  
  #include "surf_private.h"
  #include "network_private.h"
+ #include "maxmin_private.h"
+ #include "surf/datatypes.h"
+ #include "cpu_cas01_private.h"
  #include "xbt/mallocator.h"
  
  XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_kernel);
@@@ -74,7 -77,7 +77,7 @@@ void *surf_action_new(size_t size, doub
    action->max_duration = NO_MAX_DURATION;
    action->start = surf_get_clock();
    action->finish = -1.0;
 -  action->model_type = model;
 +  action->model_obj = model;
  #ifdef HAVE_TRACING
    action->category = NULL;
  #endif
@@@ -91,7 -94,7 +94,7 @@@
  
  e_surf_action_state_t surf_action_state_get(surf_action_t action)
  {
 -  surf_action_state_t action_state = &(action->model_type->states);
 +  surf_action_state_t action_state = &(action->model_obj->states);
  
    if (action->state_set == action_state->ready_action_set)
      return SURF_ACTION_READY;
@@@ -124,7 -127,7 +127,7 @@@ XBT_INLINE void surf_action_free(surf_a
  void surf_action_state_set(surf_action_t action,
                             e_surf_action_state_t state)
  {
 -  surf_action_state_t action_state = &(action->model_type->states);
 +  surf_action_state_t action_state = &(action->model_obj->states);
    XBT_IN("(%p,%s)", action, surf_action_state_names[state]);
    xbt_swag_remove(action, action->state_set);
  
@@@ -187,7 -190,7 +190,7 @@@ void surf_action_lmm_heap_remove(xbt_he
  
  void surf_action_cancel(surf_action_t action)
  {
 -  surf_model_t model = action->model_type;
 +  surf_model_t model = action->model_obj;
    surf_action_state_set(action, SURF_ACTION_FAILED);
    if (model->model_private->update_mechanism == UM_LAZY) {
      xbt_swag_remove(action, model->model_private->modified_set);
  
  int surf_action_unref(surf_action_t action)
  {
 -  surf_model_t model = action->model_type;
 +  surf_model_t model = action->model_obj;
    action->refcount--;
    if (!action->refcount) {
      xbt_swag_remove(action, action->state_set);
  
  void surf_action_suspend(surf_action_t action)
  {
 -  surf_model_t model = action->model_type;
 +  surf_model_t model = action->model_obj;
    XBT_IN("(%p)", action);
    if (((surf_action_lmm_t) action)->suspended != 2) {
      lmm_update_variable_weight(model->model_private->maxmin_system,
  
  void surf_action_resume(surf_action_t action)
  {
 -  surf_model_t model = action->model_type;
 +  surf_model_t model = action->model_obj;
    XBT_IN("(%p)", action);
    if (((surf_action_lmm_t) action)->suspended != 2) {
      lmm_update_variable_weight(model->model_private->maxmin_system,
@@@ -256,7 -259,7 +259,7 @@@ int surf_action_is_suspended(surf_actio
  
  void surf_action_set_max_duration(surf_action_t action, double duration)
  {
 -  surf_model_t model = action->model_type;
 +  surf_model_t model = action->model_obj;
    XBT_IN("(%p,%g)", action, duration);
    action->max_duration = duration;
    if (model->model_private->update_mechanism == UM_LAZY)      // remove action from the heap
  
  void surf_action_set_priority(surf_action_t action, double priority)
  {
 -  surf_model_t model = action->model_type;
 +  surf_model_t model = action->model_obj;
    XBT_IN("(%p,%g)", action, priority);
    action->priority = priority;
    lmm_update_variable_weight(model->model_private->maxmin_system,
    XBT_OUT();
  }
  
 +void surf_action_set_bound(surf_action_t action, double bound)
 +{
 +  surf_model_t model = action->model_obj;
 +  XBT_IN("(%p,%g)", action, bound);
 +  action->bound = bound;
 +  lmm_update_variable_bound(model->model_private->maxmin_system, ((surf_action_lmm_t) action)->variable, bound);
 +
 +  if (model->model_private->update_mechanism == UM_LAZY)
 +    surf_action_lmm_heap_remove(model->model_private->action_heap, (surf_action_lmm_t) action);
 +  XBT_OUT();
 +}
 +
  #ifdef HAVE_TRACING
  void surf_action_set_category(surf_action_t action,
                                      const char *category)
  void generic_update_action_remaining_lazy( surf_action_lmm_t action, double now)
  {
    double delta = 0.0;
 -  surf_model_t model = action->generic_action.model_type;
 +  surf_model_t model = action->generic_action.model_obj;
  
    if(model == surf_network_model)
    {
    delta = now - action->last_update;
  
    if (action->generic_action.remains > 0) {
-     XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", action, action->generic_action.remains, action->last_update);
+     XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", action, action->generic_action.remains, action->last_update);
      double_update(&(action->generic_action.remains),
          action->last_value * delta);
  
  #ifdef HAVE_TRACING
 -    if (model == surf_cpu_model && TRACE_is_enabled()) {
 +    if (model->type == SURF_MODEL_TYPE_CPU && TRACE_is_enabled()) {
        surf_resource_t cpu =
            lmm_constraint_id(lmm_get_cnst_from_var
                (model->model_private->maxmin_system,
            now - action->last_update);
      }
  #endif
-     XBT_DEBUG("Updating action(%p): remains is now %lf", action,
+     XBT_DEBUG("Updating action(%p): remains is now %f", action,
          action->generic_action.remains);
    }
  
  double surf_action_get_remains(surf_action_t action)
  {
    XBT_IN("(%p)", action);
 -  surf_model_t model = action->model_type;
 +  surf_model_t model = action->model_obj;
    /* update remains before return it */
    if (model->model_private->update_mechanism == UM_LAZY)      /* update remains before return it */
      generic_update_action_remaining_lazy((surf_action_lmm_t)action, surf_get_clock());
    return action->remains;
  }
  
 -    if(model == surf_cpu_model){
+ /**
+  * Update the CPU total energy for a finished action
+  *
+  */
+ void update_resource_energy(surf_model_t model, surf_action_lmm_t action)
+ {
++    if(model->type == SURF_MODEL_TYPE_CPU){
+         cpu_Cas01_t cpu_model = (cpu_Cas01_t)lmm_constraint_id(lmm_get_cnst_from_var
+                                                                                 (model->model_private->maxmin_system,
+                                                                                                 action->variable, 0));
+         if( cpu_model->energy->last_updated < surf_get_clock()) {
+               double load = lmm_constraint_get_usage(cpu_model->constraint) / cpu_model->power_peak;
+               cpu_update_energy(cpu_model, load);
+         }
+     }
+ }
  void generic_update_actions_state_lazy(double now, double delta, surf_model_t model)
  {
    surf_action_lmm_t action;
      XBT_DEBUG("Something happened to action %p", action);
  #ifdef HAVE_TRACING
      if (TRACE_is_enabled()) {
 -      if(model == surf_cpu_model){
 +      if(model->type == SURF_MODEL_TYPE_CPU){
        surf_resource_t cpu =
            lmm_constraint_id(lmm_get_cnst_from_var
                              (model->model_private->maxmin_system,
      }
  #endif
  
 -    if(model == surf_cpu_model){
 +    if(model->type == SURF_MODEL_TYPE_CPU){
        action->generic_action.finish = surf_get_clock();
-       XBT_DEBUG("Action %p finished", action);
+       update_resource_energy(model, action);
  
        /* set the remains to 0 due to precision problems when updating the remaining amount */
        action->generic_action.remains = 0;
      }
    }
  #ifdef HAVE_TRACING
 -  if (TRACE_is_enabled() && model == surf_cpu_model) {
 +  if (TRACE_is_enabled() && model->type == SURF_MODEL_TYPE_CPU) {
      //defining the last timestamp that we can safely dump to trace file
      //without losing the event ascending order (considering all CPU's)
      double smaller = -1;
@@@ -576,6 -589,8 +601,8 @@@ void generic_update_actions_state_full(
        if (model->gap_remove && model == surf_network_model)
          model->gap_remove(action);
      }
+     update_resource_energy(model, action);
    }
  
    return;
diff --combined src/surf/surf_private.h
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. 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
@@@ -31,12 -31,12 +31,12 @@@ typedef struct surf_model_private 
    int (*resource_used) (void *resource_id);
    /* Share the resources to the actions and return in how much time
       the next action may terminate */
 -  double (*share_resources) (double now);
 +  double (*share_resources) (surf_model_t model, double now);
    /* Update the actions' state */
 -  void (*update_actions_state) (double now, double delta);
 -  void (*update_resource_state) (void *id, tmgr_trace_event_t event_type,
 +  void (*update_actions_state) (surf_model_t model, double now, double delta);
 +  void (*update_resource_state) (void *resource, tmgr_trace_event_t event_type,
                                   double value, double time);
 -  void (*finalize) (void);
 +  void (*finalize) (surf_model_t model);
  
    lmm_system_t maxmin_system;
    e_UM_t update_mechanism;
@@@ -75,12 -75,12 +75,13 @@@ void surf_action_resume(surf_action_t a
  int surf_action_is_suspended(surf_action_t action);
  void surf_action_set_max_duration(surf_action_t action, double duration);
  void surf_action_set_priority(surf_action_t action, double priority);
 +void surf_action_set_bound(surf_action_t action, double bound);
  #ifdef HAVE_TRACING
  void surf_action_set_category(surf_action_t action,
                                      const char *category);
  #endif
  double surf_action_get_remains(surf_action_t action);
+ void update_resource_energy(surf_model_t model, surf_action_lmm_t action);
  void generic_update_action_remaining_lazy( surf_action_lmm_t action, double now);
  void generic_update_actions_state_lazy(double now, double delta, surf_model_t model);
  void generic_update_actions_state_full(double now, double delta, surf_model_t model);
index 1d0a398,0000000..145d1c8
mode 100644,000000..100644
--- /dev/null
@@@ -1,558 -1,0 +1,559 @@@
-       surf_vm_workstation_model, name, NULL);
 +/* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
 + * All rights reserved.                                                     */
 +
 +/* This program is free software; you can redistribute it and/or modify it
 + * under the terms of the license (GNU LGPL) which comes with this package. */
 +
 +#include "xbt/ex.h"
 +#include "xbt/dict.h"
 +#include "portable.h"
 +#include "surf_private.h"
 +#include "surf/surf_resource.h"
 +#include "simgrid/sg_config.h"
 +#include "vm_workstation_private.h"
 +#include "cpu_cas01_private.h"
 +#include "maxmin_private.h"
 +
 +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_vm_workstation, surf,
 +                                "Logging specific to the SURF VM workstation module");
 +
 +
 +surf_model_t surf_vm_workstation_model = NULL;
 +
 +/* ind means ''indirect'' that this is a reference on the whole dict_elm
 + * structure (i.e not on the surf_resource_private infos) */
 +
 +static void vm_ws_create(const char *name, void *ind_phys_workstation)
 +{
 +  workstation_CLM03_t sub_ws = surf_workstation_resource_priv(ind_phys_workstation);
 +  const char *sub_ws_name = sub_ws->generic_resource.name;
 +
 +  /* The workstation_VM2013 struct inherits the workstation_CLM03 struct. We
 +   * create a physical workstation resource, but specifying the size of
 +   * s_workstation_VM2013_t and the vm workstation model object. */
 +  workstation_CLM03_t ws = (workstation_CLM03_t) surf_resource_new(sizeof(s_workstation_VM2013_t),
-       sub_cpu->power_peak,        // host->power_peak,
++      surf_vm_workstation_model, name, NULL, NULL);
 +
 +  /* Currently, we assume a VM has no storage. */
 +  ws->storage = NULL;
 +
 +  /* Currently, a VM uses the network resource of its physical host. In
 +   * host_lib, this network resource object is refered from two different keys.
 +   * When deregistering the reference that points the network resource object
 +   * from the VM name, we have to make sure that the system does not call the
 +   * free callback for the network resource object. The network resource object
 +   * is still used by the physical machine. */
 +  ws->net_elm = xbt_lib_get_or_null(host_lib, sub_ws_name, ROUTING_HOST_LEVEL);
 +  xbt_lib_set(host_lib, name, ROUTING_HOST_LEVEL, ws->net_elm);
 +
 +  /* The SURF_WKS_LEVEL at host_lib saves workstation_CLM03 objects. Please
 +   * note workstation_VM2013 objects, inheriting the workstation_CLM03
 +   * structure, are also saved there. 
 +   *
 +   * If you want to get a workstation_VM2013 object from host_lib, see
 +   * ws->generic_resouce.model->type first. If it is
 +   * SURF_MODEL_TYPE_VM_WORKSTATION, you can cast ws to vm_ws. */
 +  XBT_INFO("Create VM(%s)@PM(%s) with %ld mounted disks", name, sub_ws_name, xbt_dynar_length(ws->storage));
 +  xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, ws);
 +
 +
 +  /* We initialize the VM-specific members. */
 +  workstation_VM2013_t vm_ws = (workstation_VM2013_t) ws;
 +  vm_ws->sub_ws = sub_ws;
 +  vm_ws->current_state = SURF_VM_STATE_CREATED;
 +
 +
 +
 +  // //// CPU  RELATED STUFF ////
 +  // Roughly, create a vcpu resource by using the values of the sub_cpu one.
 +  cpu_Cas01_t sub_cpu = surf_cpu_resource_priv(ind_phys_workstation);
 +
 +  /* We can assume one core and cas01 cpu for the first step.
 +   * Do xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, cpu) if you get the resource. */
 +  cpu_cas01_create_resource(name, // name
++      sub_cpu->power_peak_list,        // host->power_peak,
++      sub_cpu->pstate,
 +      1,                          // host->power_scale,
 +      NULL,                       // host->power_trace,
 +      1,                          // host->core_amount,
 +      SURF_RESOURCE_ON,           // host->initial_state,
 +      NULL,                       // host->state_trace,
 +      NULL,                       // host->properties,
 +      surf_cpu_model_vm);
 +
 +
 +
 +  /* We create cpu_action corresponding to a VM process on the host operating system. */
 +  /* FIXME: TODO: we have to peridocally input GUESTOS_NOISE to the system? how ? */
 +  // vm_ws->cpu_action = surf_cpu_model_pm->extension.cpu.execute(ind_phys_workstation, GUESTOS_NOISE);
 +  vm_ws->cpu_action = surf_cpu_model_pm->extension.cpu.execute(ind_phys_workstation, 0);
 +
 +
 +  /* TODO:
 +   * - check how network requests are scheduled between distinct processes competing for the same card.
 +   */
 +}
 +
 +/*
 + * Update the physical host of the given VM
 + */
 +static void vm_ws_migrate(void *ind_vm, void *ind_dst_pm)
 +{ 
 +   /* ind_phys_workstation equals to smx_host_t */
 +   workstation_VM2013_t ws_vm2013 = surf_workstation_resource_priv(ind_vm);
 +   workstation_CLM03_t ws_clm03_dst = surf_workstation_resource_priv(ind_dst_pm);
 +   const char *vm_name = ws_vm2013->ws.generic_resource.name;
 +   const char *pm_name_src = ws_vm2013->sub_ws->generic_resource.name;
 +   const char *pm_name_dst = ws_clm03_dst->generic_resource.name;
 +
 +   xbt_assert(ws_vm2013);
 +   xbt_assert(ws_clm03_dst);
 +
 +   /* do something */
 +
 +   /* update net_elm with that of the destination physical host */
 +   void *old_net_elm = ws_vm2013->ws.net_elm;
 +   void *new_net_elm = xbt_lib_get_or_null(host_lib, pm_name_dst, ROUTING_HOST_LEVEL);
 +   xbt_assert(new_net_elm);
 +
 +   /* Unregister the current net_elm from host_lib. Do not call the free callback. */
 +   xbt_lib_unset(host_lib, vm_name, ROUTING_HOST_LEVEL, 0);
 +
 +   /* Then, resister the new one. */
 +   ws_vm2013->ws.net_elm = new_net_elm;
 +   xbt_lib_set(host_lib, vm_name, ROUTING_HOST_LEVEL, ws_vm2013->ws.net_elm);
 +
 +   ws_vm2013->sub_ws = ws_clm03_dst;
 +
 +   /* Update vcpu's action for the new pm */
 +   {
 +#if 0
 +     XBT_INFO("cpu_action->remains %g", ws_vm2013->cpu_action->remains);
 +     XBT_INFO("cost %f remains %f start %f finish %f", ws_vm2013->cpu_action->cost,
 +         ws_vm2013->cpu_action->remains,
 +         ws_vm2013->cpu_action->start,
 +         ws_vm2013->cpu_action->finish
 +         );
 +     XBT_INFO("cpu_action state %d", surf_action_state_get(ws_vm2013->cpu_action));
 +#endif
 +
 +     /* create a cpu action bound to the pm model at the destination. */
 +     surf_action_t new_cpu_action = surf_cpu_model_pm->extension.cpu.execute(ind_dst_pm, 0);
 +
 +     e_surf_action_state_t state = surf_action_state_get(ws_vm2013->cpu_action);
 +     if (state != SURF_ACTION_DONE)
 +       XBT_CRITICAL("FIXME: may need a proper handling, %d", state);
 +     if (ws_vm2013->cpu_action->remains > 0)
 +       XBT_CRITICAL("FIXME: need copy the state(?), %f", ws_vm2013->cpu_action->remains);
 +
 +     int ret = surf_cpu_model_pm->action_unref(ws_vm2013->cpu_action);
 +     xbt_assert(ret == 1, "Bug: some resource still remains");
 +
 +     ws_vm2013->cpu_action = new_cpu_action;
 +   }
 +
 +   XBT_DEBUG("migrate VM(%s): change net_elm (%p to %p)", vm_name, old_net_elm, new_net_elm);
 +   XBT_DEBUG("migrate VM(%s): change PM (%s to %s)", vm_name, pm_name_src, pm_name_dst);
 +}
 +
 +/*
 + * A physical host does not disapper in the current SimGrid code, but a VM may
 + * disapper during a simulation.
 + */
 +static void vm_ws_destroy(void *ind_vm_workstation)
 +{ 
 +      /* ind_phys_workstation equals to smx_host_t */
 +
 +  /* Before clearing the entries in host_lib, we have to pick up resources. */
 +      workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_vm_workstation);
 +  cpu_Cas01_t cpu = surf_cpu_resource_priv(ind_vm_workstation);
 +      const char *name = vm_ws->ws.generic_resource.name;
 +
 +      xbt_assert(vm_ws);
 +      xbt_assert(vm_ws->ws.generic_resource.model == surf_vm_workstation_model);
 +
 +
 +  /* We deregister objects from host_lib, without invoking the freeing callback
 +   * of each level.
 +   *
 +   * Do not call xbt_lib_remove() here. It deletes all levels of the key,
 +   * including MSG_HOST_LEVEL and others. We should unregister only what we know.
 +   */
 +  xbt_lib_unset(host_lib, name, SURF_CPU_LEVEL, 0);
 +  xbt_lib_unset(host_lib, name, ROUTING_HOST_LEVEL, 0);
 +  xbt_lib_unset(host_lib, name, SURF_WKS_LEVEL, 0);
 +
 +  /* TODO: comment out when VM stroage is implemented. */
 +  // xbt_lib_unset(host_lib, name, SURF_STORAGE_LEVEL, 0);
 +
 +
 +  /* Free the cpu_action of the VM. */
 +  int ret = surf_cpu_model_pm->action_unref(vm_ws->cpu_action);
 +  xbt_assert(ret == 1, "Bug: some resource still remains");
 +
 +  /* Free the cpu resource of the VM. If using power_trace, we will have to
 +   * free other objects than lmm_constraint. */
 +  surf_model_t cpu_model = cpu->generic_resource.model;
 +  lmm_constraint_free(cpu_model->model_private->maxmin_system, cpu->constraint);
 +  {
 +    unsigned long i;
 +    for (i = 0; i < cpu->core; i++) {
 +      void *cnst_id = cpu->constraint_core[i]->id;
 +      lmm_constraint_free(cpu_model->model_private->maxmin_system, cpu->constraint_core[i]);
 +      xbt_free(cnst_id);
 +    }
 +
 +    xbt_free(cpu->constraint_core);
 +  }
 +
 +  surf_resource_free(cpu);
 +
 +  /* Free the network resource of the VM. */
 +      // Nothing has to be done, because net_elmts is just a pointer on the physical one
 +
 +  /* Free the storage resource of the VM. */
 +  // Not relevant yet
 +
 +      /* Free the workstation resource of the VM. */
 +  surf_resource_free(vm_ws);
 +}
 +
 +static int vm_ws_get_state(void *ind_vm_ws)
 +{
 +      return ((workstation_VM2013_t) surf_workstation_resource_priv(ind_vm_ws))->current_state;
 +}
 +
 +static void vm_ws_set_state(void *ind_vm_ws, int state)
 +{
 +       ((workstation_VM2013_t) surf_workstation_resource_priv(ind_vm_ws))->current_state = state;
 +}
 +
 +static void vm_ws_suspend(void *ind_vm_ws)
 +{
 +  workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_vm_ws);
 +
 +  surf_action_suspend(vm_ws->cpu_action);
 +
 +  vm_ws->current_state = SURF_VM_STATE_SUSPENDED;
 +}
 +
 +static void vm_ws_resume(void *ind_vm_ws)
 +{
 +  workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_vm_ws);
 +
 +  surf_action_resume(vm_ws->cpu_action);
 +
 +  vm_ws->current_state = SURF_VM_STATE_RUNNING;
 +}
 +
 +static void vm_ws_save(void *ind_vm_ws)
 +{
 +  workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_vm_ws);
 +
 +  vm_ws->current_state = SURF_VM_STATE_SAVING;
 +
 +  /* FIXME: do something here */
 +  surf_action_suspend(vm_ws->cpu_action);
 +
 +  vm_ws->current_state = SURF_VM_STATE_SAVED;
 +}
 +
 +static void vm_ws_restore(void *ind_vm_ws)
 +{
 +  workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_vm_ws);
 +
 +  vm_ws->current_state = SURF_VM_STATE_RESTORING;
 +
 +  /* FIXME: do something here */
 +  surf_action_resume(vm_ws->cpu_action);
 +
 +  vm_ws->current_state = SURF_VM_STATE_RUNNING;
 +}
 +
 +static double get_solved_value(surf_action_t cpu_action)
 +{
 +  lmm_variable_t var = ((surf_action_lmm_t) cpu_action)->variable;
 +
 +  return var->value;
 +}
 +
 +/* In the real world, processes on the guest operating system will be somewhat
 + * degraded due to virtualization overhead. The total CPU share that these
 + * processes get is smaller than that of the VM process gets on a host
 + * operating system. */
 +// const double virt_overhead = 0.95;
 +const double virt_overhead = 1;
 +
 +static double vm_ws_share_resources(surf_model_t workstation_model, double now)
 +{
 +  /* TODO: udpate action's cost with the total cost of processes on the VM. */
 +
 +
 +  /* 0. Make sure that we already calculated the resource share at the physical
 +   * machine layer. */
 +  {
 +    unsigned int index_of_pm_ws_model = xbt_dynar_search(model_list_invoke, &surf_workstation_model);
 +    unsigned int index_of_vm_ws_model = xbt_dynar_search(model_list_invoke, &surf_vm_workstation_model);
 +    xbt_assert((index_of_pm_ws_model < index_of_vm_ws_model), "Cannot assume surf_workstation_model comes before");
 + 
 +    /* Another option is that we call sub_ws->share_resource() here. The
 +     * share_resource() function has no side-effect. We can call it here to
 +     * ensure that. */
 +  }
 +
 +
 +  /* 1. Now we know how many resource should be assigned to each virtual
 +   * machine. We update constraints of the virtual machine layer.
 +   *
 +   *
 +   * If we have two virtual machine (VM1 and VM2) on a physical machine (PM1).
 +   *     X1 + X2 = C       (Equation 1)
 +   * where
 +   *    the resource share of VM1: X1
 +   *    the resource share of VM2: X2
 +   *    the capacity of PM1: C
 +   *
 +   * Then, if we have two process (P1 and P2) on VM1.
 +   *     X1_1 + X1_2 = X1  (Equation 2)
 +   * where
 +   *    the resource share of P1: X1_1
 +   *    the resource share of P2: X1_2
 +   *    the capacity of VM1: X1
 +   *
 +   * Equation 1 was solved in the physical machine layer.
 +   * Equation 2 is solved in the virtual machine layer (here).
 +   * X1 must be passed to the virtual machine laye as a constraint value.
 +   *
 +   **/
 +
 +  /* 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;
 +
 +    double solved_value = get_solved_value(ws_vm2013->cpu_action);
 +    XBT_DEBUG("assign %f to vm %s @ pm %s", solved_value,
 +        ws_clm03->generic_resource.name, ws_vm2013->sub_ws->generic_resource.name);
 +
 +    // TODO: check lmm_update_constraint_bound() works fine instead of the below manual substitution.
 +    // cpu_cas01->constraint->bound = solved_value;
 +    surf_model_t cpu_model = cpu_cas01->generic_resource.model;
 +    xbt_assert(cpu_model == surf_cpu_model_vm);
 +    lmm_system_t vcpu_system = cpu_model->model_private->maxmin_system;
 +    lmm_update_constraint_bound(vcpu_system, cpu_cas01->constraint, virt_overhead * solved_value);
 +  }
 +
 +
 +  /* 2. Calculate resource share at the virtual machine layer. */
 +  double ret = ws_share_resources(workstation_model, now);
 +
 +
 +  /* FIXME: 3. do we have to re-initialize our cpu_action object? */
 +#if 0
 +  /* iterate for all hosts including virtual machines */
 +  xbt_lib_foreach(host_lib, cursor, key, ind_host) {
 +    workstation_CLM03_t ws_clm03 = ind_host[SURF_WKS_LEVEL];
 +
 +    /* skip if it is not a virtual machine */
 +    if (!ws_clm03)
 +      continue;
 +    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 */
 +    {
 +#if 0
 +      workstation_VM2013_t ws_vm2013 = (workstation_VM2013_t) ws_clm03;           
 +      XBT_INFO("cost %f remains %f start %f finish %f", ws_vm2013->cpu_action->cost,
 +          ws_vm2013->cpu_action->remains,
 +          ws_vm2013->cpu_action->start,
 +          ws_vm2013->cpu_action->finish
 +          );
 +#endif
 +#if 0
 +      void *ind_sub_host = xbt_lib_get_elm_or_null(host_lib, ws_vm2013->sub_ws->generic_resource.name);      
 +      surf_cpu_model_pm->action_unref(ws_vm2013->cpu_action);
 +      /* FIXME: this means busy loop? */
 +      // ws_vm2013->cpu_action = surf_cpu_model_pm->extension.cpu.execute(ind_sub_host, GUESTOS_NOISE);
 +      ws_vm2013->cpu_action = surf_cpu_model_pm->extension.cpu.execute(ind_sub_host, 0);
 +#endif
 +
 +    }
 +  }
 +#endif
 +
 +
 +  return ret;
 +}
 +
 +
 +/*
 + * A surf level object will be useless in the upper layer. Returing the
 + * dict_elm of the host.
 + **/
 +static void *vm_ws_get_pm(void *ind_vm_ws)
 +{
 +      workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_vm_ws);
 +  const char *sub_ws_name = vm_ws->sub_ws->generic_resource.name;
 +
 +  return xbt_lib_get_elm_or_null(host_lib, sub_ws_name);
 +}
 +
 +
 +/* Adding a task to a VM updates the VCPU task on its physical machine. */
 +static surf_action_t vm_ws_execute(void *workstation, double size)
 +{
 +  surf_resource_t ws = ((surf_resource_t) surf_workstation_resource_priv(workstation));
 +
 +  xbt_assert(ws->model->type == SURF_MODEL_TYPE_VM_WORKSTATION);
 +  workstation_VM2013_t vm_ws = (workstation_VM2013_t) ws;
 +
 +  double old_cost = vm_ws->cpu_action->cost;
 +  double new_cost = old_cost + size;
 +
 +  XBT_DEBUG("VM(%s)@PM(%s): update dummy action's cost (%f -> %f)",
 +      ws->name, vm_ws->sub_ws->generic_resource.name,
 +      old_cost, new_cost);
 +
 +  vm_ws->cpu_action->cost = new_cost;
 +
 +  return ws_execute(workstation, size);
 +}
 +
 +static void vm_ws_action_cancel(surf_action_t action)
 +{
 +  XBT_CRITICAL("FIXME: Not yet implemented. Reduce dummy action's cost by %f", action->cost);
 +
 +  ws_action_cancel(action);
 +}
 +
 +
 +/* Now we can set bound for each task by using MSG_task_set_bound. But, it does
 + * not work for the dummy CPU action of a VM. Here, we add the set_bound
 + * function for the dummy CPU action. */
 +static void vm_ws_set_vm_bound(void *vm, double bound)
 +{
 +  surf_resource_t ws = ((surf_resource_t) surf_workstation_resource_priv(vm));
 +  xbt_assert(ws->model->type == SURF_MODEL_TYPE_VM_WORKSTATION);
 +  workstation_VM2013_t vm_ws = (workstation_VM2013_t) ws;
 +
 +  surf_action_set_bound(vm_ws->cpu_action, bound);
 +}
 +
 +
 +/* set the affinity of a VM to the CPU cores of a PM */
 +static void vm_ws_set_vm_affinity(void *vm, void *pm, unsigned long mask)
 +{
 +  surf_resource_t ws = ((surf_resource_t) surf_workstation_resource_priv(vm));
 +  xbt_assert(ws->model->type == SURF_MODEL_TYPE_VM_WORKSTATION);
 +  workstation_VM2013_t vm_ws = (workstation_VM2013_t) ws;
 +
 +  surf_cpu_model_pm->set_affinity(vm_ws->cpu_action, pm, mask);
 +}
 +
 +
 +static void surf_vm_workstation_model_init_internal(void)
 +{
 +  surf_model_t model = surf_model_init();
 +
 +  model->name = "Virtual Workstation";
 +  model->type = SURF_MODEL_TYPE_VM_WORKSTATION;
 +
 +  model->action_unref     = ws_action_unref;
 +  model->action_cancel    = vm_ws_action_cancel;
 +  // model->action_state_set = ws_action_state_set;
 +
 +
 +  model->model_private->share_resources       = vm_ws_share_resources;
 +  model->model_private->resource_used         = ws_resource_used;
 +  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;
 +
 +
 +  /* operation for an action, not for VM it self */
 +  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;
 +  model->set_affinity     = ws_action_set_affinity;
 +// #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
 +
 +
 +
 +
 +
 +
 +
 +  xbt_assert(surf_cpu_model_vm);
 +  model->extension.workstation.cpu_model = surf_cpu_model_vm;
 +
 +  model->extension.workstation.execute   = vm_ws_execute;
 +  model->extension.workstation.sleep     = ws_action_sleep;
 +  model->extension.workstation.get_state = ws_get_state;
 +  model->extension.workstation.get_speed = ws_get_speed;
 +  // model->extension.workstation.get_available_speed = ws_get_available_speed;
 +
 +  // 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.ls     = ws_action_ls;
 +
 +
 +  model->extension.vm_workstation.create        = vm_ws_create;
 +  model->extension.vm_workstation.set_state     = vm_ws_set_state;
 +  model->extension.vm_workstation.get_state     = vm_ws_get_state;
 +  model->extension.vm_workstation.migrate       = vm_ws_migrate;
 +  model->extension.vm_workstation.destroy       = vm_ws_destroy;
 +  model->extension.vm_workstation.suspend       = vm_ws_suspend;
 +  model->extension.vm_workstation.resume        = vm_ws_resume;
 +  model->extension.vm_workstation.save          = vm_ws_save;
 +  model->extension.vm_workstation.restore       = vm_ws_restore;
 +  model->extension.vm_workstation.get_pm        = vm_ws_get_pm;
 +  model->extension.vm_workstation.set_vm_bound  = vm_ws_set_vm_bound;
 +  model->extension.vm_workstation.set_vm_affinity  = vm_ws_set_vm_affinity;
 +
 +  model->extension.workstation.set_params    = ws_set_params;
 +  model->extension.workstation.get_params    = ws_get_params;
 +
 +  surf_vm_workstation_model = model;
 +}
 +
 +void surf_vm_workstation_model_init(void)
 +{
 +  surf_vm_workstation_model_init_internal();
 +  xbt_dynar_push(model_list, &surf_vm_workstation_model);
 +  xbt_dynar_push(model_list_invoke, &surf_vm_workstation_model);
 +}
diff --combined src/surf/workstation.c
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. 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
  #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);
++  workstation_CLM03_t ws = (workstation_CLM03_t) surf_resource_new(sizeof(s_workstation_CLM03_t), surf_workstation_model, name, NULL, 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)
@@@ -48,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;
  }
  
 -static void ws_update_actions_state(double now, double delta)
 +
 +/* TODO: iterating active constraint_set may be faster? */
 +#if 0
 +static void deactivate_dummy_cpu_action(void)
 +{
 +  lmm_system_t sys = surf_cpu_model_vm->model_private->maxmin_system;
 +
 +  lmm_constraint_t cnst;
 +  xbt_swag_foreach(cnst, &sys->active_constraint_set) {
 +    /* get vcpu resource */
 +    surf_resource_t cpu = lmm_constraint_id(cnst);
 +    xbt_assert(cpu->model == surf_cpu_model_vm);
 +
 +    /* get vm_ws resource */
 +    workstation_CLM03_t ws = xbt_lib_get_or_null(host_lib, cpu->name, SURF_WKS_LEVEL);
 +
 +    /* make sure we can cast */
 +    xbt_assert(ws->generic_resouce.model == surf_vm_workstation_model);
 +    workstation_VM2013_t vm_ws = (workstation_VM2013_t) ws;
 +
 +    /* make it active in the PM layer */
 +    surf_action_set_priority(vm_ws->cpu_action, 1);
 +  }
 +}
 +#endif
 +
 +
 +/* TODO: Delete this unused code if everything looks good. */
 +#if 0
 +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;
 +}
 +#endif
 +
 +
 +/* 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;
 +
 +    lmm_system_t sys = surf_cpu_model_vm->model_private->maxmin_system;
 +    int is_active = lmm_constraint_used(sys, cpu_cas01->constraint);
 +    // int is_active_old = constraint_is_active(cpu_cas01);
 +
 +    // {
 +    //   xbt_assert(is_active == is_active_old, "%d %d", is_active, is_active_old);
 +    // }
 +
 +    if (is_active) {
 +      /* 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);
 +    }
 +  }
 +}
 +
 +
 +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)
 +{
 +  /* This model does not implement parallel tasks */
 +  THROW_IMPOSSIBLE;
 +}
 +
 +void ws_finalize(surf_model_t workstation_model)
  {
 -  THROW_IMPOSSIBLE;             /* This model does not implement parallel tasks */
 +  surf_model_exit(workstation_model);
 +  workstation_model = NULL;
  }
  
 -static surf_action_t ws_execute(void *workstation, double size)
 +
 +
 +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;
 +}
 +
 +void ws_action_set_affinity(surf_action_t action, void *workstation, unsigned long mask)
 +{
 +  if (action->model_obj->type == SURF_MODEL_TYPE_NETWORK)
 +    DIE_IMPOSSIBLE;
 +  else if (action->model_obj->type == SURF_MODEL_TYPE_CPU)
 +    action->model_obj->set_affinity(action, workstation, mask);
    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;
  }
@@@ -371,35 -215,63 +371,71 @@@ 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);
  }
  
 -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);
  }
  
 -  return surf_cpu_model->extension.cpu.
+ static double ws_get_current_power_peak(void *workstation)
+ {
 -  return surf_cpu_model->extension.cpu.
++  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
++  return cpu->model->extension.cpu.
+       get_current_power_peak(workstation);
+ }
+ static double ws_get_power_peak_at(void *workstation, int pstate_index)
+ {
 -  return surf_cpu_model->extension.cpu.
++  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
++  return cpu->model->extension.cpu.
+       get_power_peak_at(workstation, pstate_index);
+ }
+ static int ws_get_nb_pstates(void *workstation)
+ {
 -  surf_cpu_model->extension.cpu.
++  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
++  return cpu->model->extension.cpu.
+       get_nb_pstates(workstation);
+ }
+ static void ws_set_power_peak_at(void *workstation, int pstate_index)
+ {
 -  return surf_cpu_model->extension.cpu.
++  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
++  cpu->model->extension.cpu.
+       set_power_peak_at(workstation, pstate_index);
+ }
+ static double ws_get_consumed_energy(void *workstation)
+ {
++  surf_resource_t cpu = ((surf_resource_t) surf_cpu_resource_priv(workstation));
++  return cpu->model->extension.cpu.
+       get_consumed_energy(workstation);
+ }
  static surf_action_t ws_execute_parallel_task(int workstation_nb,
                                                void **workstation_list,
                                                double *computation_amount,
@@@ -461,12 -333,18 +497,12 @@@ 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));
  }
  
- static storage_t find_storage_on_mount_list(void *workstation,const char* storage)
+ static storage_t find_storage_on_mount_list(void *workstation,const char* mount)
  {
    storage_t st = NULL;
    s_mount_t mnt;
    workstation_CLM03_t ws = (workstation_CLM03_t) surf_workstation_resource_priv(workstation);
    xbt_dynar_t storage_list = ws->storage;
  
-   XBT_DEBUG("Search for storage name '%s' on '%s'",storage,ws->generic_resource.name);
+   XBT_DEBUG("Search for storage name '%s' on '%s'",mount,ws->generic_resource.name);
    xbt_dynar_foreach(storage_list,cursor,mnt)
    {
      XBT_DEBUG("See '%s'",mnt.name);
-     if(!strcmp(storage,mnt.name)){
-       st = mnt.id;
+     if(!strcmp(mount,mnt.name)){
+       st = mnt.storage;
        break;
      }
    }
-   if(!st) xbt_die("Can't find mount '%s' for '%s'",storage,ws->generic_resource.name);
+   if(!st) xbt_die("Can't find mount '%s' for '%s'",mount,ws->generic_resource.name);
    return st;
  }
  
+ static xbt_dict_t ws_get_storage_list(void *workstation)
+ {
+   s_mount_t mnt;
+   unsigned int i;
+   xbt_dict_t storage_list = xbt_dict_new_homogeneous(NULL);
+   char *storage_name = NULL;
+   workstation_CLM03_t ws = (workstation_CLM03_t) surf_workstation_resource_priv(workstation);
+   xbt_dynar_t storages = ws->storage;
+   xbt_dynar_foreach(storages,i,mnt){
+     storage_name = ((storage_t)mnt.storage)->generic_resource.name;
+     xbt_dict_set(storage_list,mnt.name,storage_name,NULL);
+   }
+   return storage_list;
+ }
  static surf_action_t ws_action_open(void *workstation, const char* mount,
                                      const char* path)
  {
  
  static surf_action_t ws_action_close(void *workstation, surf_file_t fd)
  {
-   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
+   storage_t st = find_storage_on_mount_list(workstation, fd->mount);
    XBT_DEBUG("CLOSE on disk '%s'",st->generic_resource.name);
    surf_model_t model = st->generic_resource.model;
    return model->extension.storage.close(st, fd);
  }
  
- static surf_action_t ws_action_read(void *workstation, void* ptr, size_t size,
-                                     surf_file_t fd)
+ static surf_action_t ws_action_read(void *workstation, surf_file_t fd, sg_storage_size_t size)
  {
-   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
+   storage_t st = find_storage_on_mount_list(workstation, fd->mount);
    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, size, fd);
+   return model->extension.storage.read(st, fd, size);
  }
  
- static surf_action_t ws_action_write(void *workstation, const void* ptr,
-                                      size_t size, surf_file_t fd)
+ static surf_action_t ws_action_write(void *workstation, surf_file_t fd, sg_storage_size_t size)
  {
-   storage_t st = find_storage_on_mount_list(workstation, fd->storage);
+   storage_t st = find_storage_on_mount_list(workstation, fd->mount);
    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, fd);
+   return model->extension.storage.write(st, fd, size);
  }
  
  static int ws_file_unlink(void *workstation, surf_file_t fd)
      return 0;
    } else {
  //    XBT_INFO("%s %zu", fd->storage, fd->size);
-     storage_t st = find_storage_on_mount_list(workstation, fd->storage);
+     storage_t st = find_storage_on_mount_list(workstation, fd->mount);
      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_dict_remove(content_dict,fd->name);
  
        free(fd->name);
-       free(fd->storage);
+       free(fd->mount);
        xbt_free(fd);
        return 1;
      }
@@@ -560,141 -453,126 +611,178 @@@ static surf_action_t ws_action_ls(void 
    return model->extension.storage.ls(st, path);
  }
  
- static size_t ws_file_get_size(void *workstation, surf_file_t fd)
+ static sg_storage_size_t ws_file_get_size(void *workstation, surf_file_t fd)
  {
    return fd->size;
  }
  
 -static void surf_workstation_model_init_internal(void)
+ static xbt_dynar_t ws_file_get_info(void *workstation, surf_file_t fd)
+ {
+   storage_t st = find_storage_on_mount_list(workstation, fd->mount);
+   sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
+   *psize = fd->size;
+   xbt_dynar_t info = xbt_dynar_new(sizeof(void*), NULL);
+   xbt_dynar_push_as(info, sg_storage_size_t *, psize);
+   xbt_dynar_push_as(info, void *, fd->mount);
+   xbt_dynar_push_as(info, void *, st->generic_resource.name);
+   xbt_dynar_push_as(info, void *, st->type_id);
+   xbt_dynar_push_as(info, void *, st->content_type);
+   return info;
+ }
+ static sg_storage_size_t ws_storage_get_free_size(void *workstation,const char* name)
+ {
+   storage_t st = find_storage_on_mount_list(workstation, name);
+   return st->size - st->used_size;
+ }
+ static sg_storage_size_t ws_storage_get_used_size(void *workstation,const char* name)
+ {
+   storage_t st = find_storage_on_mount_list(workstation, name);
+   return st->used_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;
 +  model->set_affinity     = ws_action_set_affinity;
 +  #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;
 -  surf_workstation_model->extension.workstation.get_current_power_peak = ws_get_current_power_peak;
 -  surf_workstation_model->extension.workstation.get_power_peak_at = ws_get_power_peak_at;
 -  surf_workstation_model->extension.workstation.get_nb_pstates = ws_get_nb_pstates;
 -  surf_workstation_model->extension.workstation.set_power_peak_at = ws_set_power_peak_at;
 -  surf_workstation_model->extension.workstation.get_consumed_energy = ws_get_consumed_energy;
--
-   model->extension.workstation.communicate           = ws_communicate;
-   model->extension.workstation.get_route             = ws_get_route;
 -  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;
 -  surf_workstation_model->extension.workstation.get_info = ws_file_get_info;
 -  surf_workstation_model->extension.workstation.get_free_size = ws_storage_get_free_size;
 -  surf_workstation_model->extension.workstation.get_used_size = ws_storage_get_used_size;
 -  surf_workstation_model->extension.workstation.get_storage_list = ws_get_storage_list;
++  model->extension.workstation.get_current_power_peak = ws_get_current_power_peak;
++  model->extension.workstation.get_power_peak_at = ws_get_power_peak_at;
++  model->extension.workstation.get_nb_pstates = ws_get_nb_pstates;
++  model->extension.workstation.set_power_peak_at = ws_set_power_peak_at;
++  model->extension.workstation.get_consumed_energy = ws_get_consumed_energy;
++
++  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.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.unlink = ws_file_unlink;
-   model->extension.workstation.ls     = ws_action_ls;
++  model->extension.workstation.ls = ws_action_ls;
++  model->extension.workstation.get_size = ws_file_get_size;
++  model->extension.workstation.get_info = ws_file_get_info;
++  model->extension.workstation.get_free_size = ws_storage_get_free_size;
++  model->extension.workstation.get_used_size = ws_storage_get_used_size;
++  model->extension.workstation.get_storage_list = ws_get_storage_list;
 +
 +  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_boolean(_sg_cfg_set, "network/crosstraffic", xbt_strdup("yes"));
 -  surf_workstation_model_init_internal();
+   xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "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);
  }
@@@ -1,4 -1,4 +1,4 @@@
- /* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2007-2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -219,13 -219,13 +219,13 @@@ static int ptask_resource_used(void *re
  
  }
  
 -static double ptask_share_resources(double now)
 +static double ptask_share_resources(surf_model_t workstation_model, double now)
  {
    s_surf_action_workstation_L07_t s_action;
    surf_action_workstation_L07_t action = NULL;
  
    xbt_swag_t running_actions =
 -      surf_workstation_model->states.running_action_set;
 +      workstation_model->states.running_action_set;
    double min = generic_maxmin_share_resources(running_actions,
                                                xbt_swag_offset(s_action,
                                                                variable),
    return min;
  }
  
 -static void ptask_update_actions_state(double now, double delta)
 +static void ptask_update_actions_state(surf_model_t workstation_model, double now, double delta)
  {
    double deltap = 0.0;
    surf_action_workstation_L07_t action = NULL;
    surf_action_workstation_L07_t next_action = NULL;
    xbt_swag_t running_actions =
 -      surf_workstation_model->states.running_action_set;
 +      workstation_model->states.running_action_set;
  
    xbt_swag_foreach_safe(action, next_action, running_actions) {
      deltap = delta;
@@@ -410,12 -410,12 +410,12 @@@ static void ptask_update_resource_state
    return;
  }
  
 -static void ptask_finalize(void)
 +static void ptask_finalize(surf_model_t workstation_model)
  {
    xbt_dict_free(&ptask_parallel_task_link_set);
  
 -  surf_model_exit(surf_workstation_model);
 -  surf_workstation_model = NULL;
 +  surf_model_exit(workstation_model);
 +  workstation_model = NULL;
    surf_model_exit(surf_network_model);
    surf_network_model = NULL;
  
@@@ -446,6 -446,34 +446,34 @@@ static double ptask_get_available_speed
    return ((cpu_L07_t)surf_workstation_resource_priv(cpu))->power_current;
  }
  
+ static double ws_get_current_power_peak(void *cpu)
+ {
+   return ((cpu_L07_t)surf_workstation_resource_priv(cpu))->power_current;
+ }
+ static double ws_get_power_peak_at(void *cpu, int pstate_index)
+ {
+       XBT_DEBUG("[ws_get_power_peak_at] Not implemented for workstation_ptask_L07");
+       return 0.0;
+ }
+ static int ws_get_nb_pstates(void *workstation)
+ {
+       XBT_DEBUG("[ws_get_nb_pstates] Not implemented for workstation_ptask_L07");
+       return 0.0;
+ }
+ static void ws_set_power_peak_at(void *cpu, int pstate_index)
+ {
+       XBT_DEBUG("[ws_set_power_peak_at] Not implemented for workstation_ptask_L07");
+ }
+ static double ws_get_consumed_energy(void *cpu)
+ {
+       XBT_DEBUG("[ws_get_consumed_energy] Not implemented for workstation_ptask_L07");
+       return 0.0;
+ }
  static surf_action_t ptask_execute_parallel_task(int workstation_nb,
                                                   void **workstation_list,
                                                   double
@@@ -640,7 -668,7 +668,7 @@@ static void* ptask_cpu_create_resource(
                name);
  
    cpu = (cpu_L07_t) surf_resource_new(sizeof(s_cpu_L07_t),
-           surf_workstation_model, name,cpu_properties);
+           surf_workstation_model, name,cpu_properties, NULL);
  
    cpu->type = SURF_WORKSTATION_RESOURCE_CPU;
    cpu->info = xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
  
  static void ptask_parse_cpu_init(sg_platf_host_cbarg_t host)
  {
+   double power_peak = xbt_dynar_get_as(host->power_peak, host->pstate, double);
+  //cpu->power_peak = power_peak;
+   xbt_dynar_free(&(host->power_peak));  /* kill memory leak */
    ptask_cpu_create_resource(
        host->id,
-       host->power_peak,
+       power_peak,
        host->power_scale,
        host->power_trace,
        host->initial_state,
@@@ -859,7 -890,6 +890,7 @@@ static void ptask_model_init_internal(v
    surf_workstation_model->set_priority = ptask_action_set_priority;
    surf_workstation_model->get_remains = ptask_action_get_remains;
    surf_workstation_model->name = "Workstation ptask_L07";
 +  surf_workstation_model->type = SURF_MODEL_TYPE_WORKSTATION;
  
    surf_workstation_model->model_private->resource_used =
        ptask_resource_used;
        ptask_get_speed;
    surf_workstation_model->extension.workstation.get_available_speed =
        ptask_get_available_speed;
+   surf_workstation_model->extension.workstation.get_current_power_peak = ws_get_current_power_peak;
+   surf_workstation_model->extension.workstation.get_power_peak_at = ws_get_power_peak_at;
+   surf_workstation_model->extension.workstation.get_nb_pstates = ws_get_nb_pstates;
+   surf_workstation_model->extension.workstation.set_power_peak_at = ws_set_power_peak_at;
+   surf_workstation_model->extension.workstation.get_consumed_energy = ws_get_consumed_energy;
    surf_workstation_model->extension.workstation.communicate =
        ptask_communicate;
    surf_workstation_model->extension.workstation.get_route =
  void surf_workstation_model_init_ptask_L07(void)
  {
    XBT_INFO("surf_workstation_model_init_ptask_L07");
 -  xbt_assert(!surf_cpu_model, "CPU model type already defined");
 +  xbt_assert(!surf_cpu_model_pm, "CPU model type already defined");
    xbt_assert(!surf_network_model, "network model type already defined");
    ptask_define_callbacks();
    ptask_model_init_internal();
diff --combined src/xbt/ex.c
@@@ -1,6 -1,6 +1,6 @@@
  /* ex - Exception Handling                                                  */
  
- /*  Copyright (c) 2005-2010 The SimGrid team                                */
+ /*  Copyright (c) 2005-2013. The SimGrid Team.                              */
  /*  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>       */
  /*  Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>         */
  /*  Copyright (c) 2002-2004 Cable & Wireless <http://www.cw.com/>           */
@@@ -75,7 -75,7 +75,7 @@@ xbt_running_ctx_t *__xbt_ex_ctx_default
       real life and in simulation when using threads to implement the simulation
       processes (ie, with pthreads and on windows).
  
-      It also gets overriden in xbt/context.c when using ucontextes (as well as
+      It also gets overriden in xbt/context.c when using ucontexts (as well as
       in Java for now, but after the java overhaul, it will get cleaned out)
     */
    static xbt_running_ctx_t ctx = XBT_RUNNING_CTX_INITIALIZER;
@@@ -223,9 -223,6 +223,9 @@@ const char *xbt_ex_catname(xbt_errcat_
      return "tracing error";
    case io_error:
      return "io error";
 +  case vm_error:
 +    return "vm error";
 +
    }
    return "INVALID ERROR";
  }
diff --combined src/xbt/lib.c
@@@ -1,6 -1,6 +1,6 @@@
  /* lib - a generic library, variation over dictionary                    */
  
- /* Copyright (c) 2011. The SimGrid Team.
+ /* Copyright (c) 2011, 2013. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -70,37 -70,6 +70,37 @@@ void xbt_lib_set(xbt_lib_t lib, const c
    elts[level] = obj;
  }
  
 +/* for vm */
 +void xbt_lib_unset(xbt_lib_t lib, const char *key, int level, int invoke_callback)
 +{
 +  void **elts = xbt_dict_get_or_null(lib->dict, key);
 +  if (!elts) {
 +     XBT_WARN("no key %s", key);
 +     return;
 +  }
 +
 +  void *obj = elts[level];
 +
 +  if (!obj) {
 +     XBT_WARN("no key %s at level %d", key, level);
 +  } else {
 +     XBT_DEBUG("Remove %p of key %s at level %d", obj, key, level);
 +     if (invoke_callback)
 +       lib->free_f[level](obj);
 +     elts[level] = NULL;
 +  }
 +
 +  /* check if there still remains any elements of this key */
 +  int i;
 +  for (i = 0; i < lib->levels; i++) {
 +     if (elts[i] != NULL)
 +       return;
 +  }
 +
 +  /* there is no element at any level, so delete the key */
 +  xbt_dict_remove(lib->dict, key);
 +}
 +
  void *xbt_lib_get_or_null(xbt_lib_t lib, const char *key, int level)
  {
    void **elts = xbt_dict_get_or_null(lib->dict, key);
@@@ -116,7 -85,3 +116,7 @@@ void *xbt_lib_get_level(xbt_dictelm_t e
    void **elts = elm->content;
    return elts ? elts[level] : NULL;
  }
 +
 +void xbt_lib_remove(xbt_lib_t lib, const char *key){
 +  xbt_dict_remove(lib->dict, key);
 +}
@@@ -1,6 -1,6 +1,6 @@@
  /* A few basic tests for the surf library                                   */
  
- /* Copyright (c) 2004, 2005, 2006, 2007, 2008, 2009, 2010. The SimGrid Team.
+ /* Copyright (c) 2004-2012. The SimGrid Team.
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
@@@ -58,7 -58,7 +58,7 @@@ void test(char *platform
    parse_platform_file(platform);
  
    /*********************** CPU ***********************************/
 -  XBT_DEBUG("%p", surf_cpu_model);
 +  XBT_DEBUG("%p", surf_cpu_model_pm);
    cpuA = surf_cpu_resource_by_name("Cpu A");
    cpuB = surf_cpu_resource_by_name("Cpu B");
  
    XBT_DEBUG("%s : %p", surf_resource_name(cpuB), cpuB);
  
    /* Let's do something on it */
 -  actionA = surf_cpu_model->extension.cpu.execute(cpuA, 1000.0);
 -  actionB = surf_cpu_model->extension.cpu.execute(cpuB, 1000.0);
 -  actionC = surf_cpu_model->extension.cpu.sleep(cpuB, 7.32);
 +  actionA = surf_cpu_model_pm->extension.cpu.execute(cpuA, 1000.0);
 +  actionB = surf_cpu_model_pm->extension.cpu.execute(cpuB, 1000.0);
 +  actionC = surf_cpu_model_pm->extension.cpu.sleep(cpuB, 7.32);
  
    /* Use whatever calling style you want... */
 -  stateActionA = surf_cpu_model->action_state_get(actionA);     /* When you know actionA model type */
 -  stateActionB = actionB->model_type->action_state_get(actionB);        /* If you're unsure about it's model type */
 -  stateActionC = surf_cpu_model->action_state_get(actionC);     /* When you know actionA model type */
 +  stateActionA = surf_cpu_model_pm->action_state_get(actionA);     /* When you know actionA model type */
 +  stateActionB = actionB->model_obj->action_state_get(actionB);        /* If you're unsure about it's model type */
 +  stateActionC = surf_cpu_model_pm->action_state_get(actionC);     /* When you know actionA model type */
  
    /* And just look at the state of these tasks */
    XBT_DEBUG("actionA : %p (%s)", actionA, string_action(stateActionA));
      XBT_DEBUG("Next Event : %g", now);
      XBT_DEBUG("\t CPU actions");
      while ((action =
 -            xbt_swag_extract(surf_cpu_model->states.failed_action_set))) {
 +            xbt_swag_extract(surf_cpu_model_pm->states.failed_action_set))) {
        XBT_DEBUG("\t * Failed : %p", action);
 -      action->model_type->action_unref(action);
 +      action->model_obj->action_unref(action);
      }
      while ((action =
 -            xbt_swag_extract(surf_cpu_model->states.done_action_set))) {
 +            xbt_swag_extract(surf_cpu_model_pm->states.done_action_set))) {
        XBT_DEBUG("\t * Done : %p", action);
 -      action->model_type->action_unref(action);
 +      action->model_obj->action_unref(action);
      }
      XBT_DEBUG("\t Network actions");
      while ((action =
              xbt_swag_extract(surf_network_model->states.
                               failed_action_set))) {
        XBT_DEBUG("\t * Failed : %p", action);
 -      action->model_type->action_unref(action);
 +      action->model_obj->action_unref(action);
      }
      while ((action =
              xbt_swag_extract(surf_network_model->states.
                               done_action_set))) {
        XBT_DEBUG("\t * Done : %p", action);
 -      action->model_type->action_unref(action);
 +      action->model_obj->action_unref(action);
      }
  
    } while ((xbt_swag_size(surf_network_model->states.running_action_set) ||
 -            xbt_swag_size(surf_cpu_model->states.running_action_set)) &&
 +            xbt_swag_size(surf_cpu_model_pm->states.running_action_set)) &&
             surf_solve(-1.0) >= 0.0);
  
    XBT_DEBUG("Simulation Terminated");