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 --cc .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 --cc .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>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
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);
 +}
Simple merge
@@@ -102,11 -120,17 +122,18 @@@ XBT_PUBLIC(msg_host_t) MSG_host_self(vo
  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,
Simple merge
  #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 **********************************/
@@@ -297,9 -303,8 +307,10 @@@ XBT_PUBLIC(void) SIMIX_file_set_data(sm
  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 */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -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
Simple merge
Simple merge
@@@ -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 
Simple merge
Simple merge
Simple merge
@@@ -243,23 -233,21 +241,24 @@@ 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 */
    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
@@@ -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
   */
@@@ -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 *************************/
  /*******************************************/
Simple merge
@@@ -68,9 -71,10 +69,10 @@@ void MSG_init_nocheck(int *argc, char *
  #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
Simple merge
@@@ -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;
+ }
@@@ -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,
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -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];
@@@ -323,15 -330,20 +330,25 @@@ 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();
  
@@@ -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.
   *
@@@ -250,10 -176,59 +260,59 @@@ double SIMIX_pre_host_get_available_spe
  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);
  }
@@@ -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);
  }
@@@ -728,31 -635,11 +799,40 @@@ void SIMIX_set_category(smx_action_t ac
  }
  #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);
+ }
@@@ -44,10 -43,13 +45,15 @@@ xbt_swag_t SIMIX_host_get_process_list(
  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,18 -59,16 +63,20 @@@ 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);
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -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 \
Simple merge
@@@ -180,10 -233,9 +255,9 @@@ double simcall_host_get_consumed_energy
   * \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!");
@@@ -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
@@@ -8,31 -8,37 +8,38 @@@
  #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,
               "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;
  
  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,
@@@ -174,19 -159,123 +192,123 @@@ static double cpu_share_resources_full(
                                          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
      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;
@@@ -335,8 -338,9 +457,9 @@@ static void cpu_action_set_affinity(sur
  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 =
@@@ -430,17 -424,51 +553,51 @@@ static double cpu_get_available_speed(v
    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;
@@@ -497,46 -524,47 +654,52 @@@ static surf_model_t surf_cpu_model_init
    } 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;
  }
  
  /*********************************************************************/
@@@ -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 */
@@@ -161,12 -161,18 +162,18 @@@ static void* cpu_ti_create_resource(con
                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;
@@@ -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;
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -252,11 -293,9 +293,9 @@@ static void storage_update_actions_stat
  {
    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)
      {
diff --cc src/surf/surf.c
@@@ -676,60 -678,6 +689,6 @@@ static void surf_share_resources(surf_m
  
  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);
- }
@@@ -380,6 -371,27 +383,27 @@@ double surf_action_get_remains(surf_act
    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;
      }
  #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;
Simple merge
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);
 +}
@@@ -21,20 -23,22 +21,20 @@@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_wo
  
  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)
@@@ -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,
@@@ -565,116 -458,108 +616,153 @@@ static sg_storage_size_t ws_file_get_si
    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();
  
Simple merge
diff --cc src/xbt/ex.c
Simple merge
diff --cc src/xbt/lib.c
Simple merge
Simple merge