Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge commit '045db1657e870c721be490b411868f4181a12ced' into surf++
authorPaul Bédaride <paul.bedaride@gmail.com>
Wed, 30 Oct 2013 14:26:47 +0000 (15:26 +0100)
committerPaul Bédaride <paul.bedaride@gmail.com>
Wed, 30 Oct 2013 14:26:47 +0000 (15:26 +0100)
Conflicts:
buildtools/Cmake/DefinePackages.cmake
src/include/surf/datatypes.h
src/include/surf/surf.h
src/simgrid/sg_config.c
src/simix/smx_io.c
src/simix/smx_smurf_private.h
src/surf/cpu_cas01.c
src/surf/cpu_ti.c
src/surf/network.c
src/surf/network_constant.c
src/surf/network_gtnets.c
src/surf/new_model.c
src/surf/storage.c
src/surf/storage_private.h
src/surf/surf.c
src/surf/surf_action.c
src/surf/surf_model.c
src/surf/surf_routing.cpp
src/surf/surf_routing_cluster.c
src/surf/surf_routing_floyd.cpp
src/surf/surf_routing_full.cpp
src/surf/surf_routing_none.c
src/surf/surf_routing_vivaldi.c
src/surf/workstation.c
src/surf/workstation_ptask_L07.c

95 files changed:
.cproject
CMakeLists.txt
buildtools/Cmake/DefinePackages.cmake
include/msg/datatypes.h
include/simgrid/platf.h
include/surf/surf_routing.h
include/xbt/automaton.h
include/xbt/heap.h
include/xbt/module.h
src/include/instr/instr_interface.h
src/include/simgrid/platf_interface.h
src/include/simgrid/sg_config.h
src/include/surf/datatypes.h
src/include/surf/maxmin.h
src/include/surf/surf.h
src/include/surf/surf_resource.h
src/include/surf/surf_resource_lmm.h
src/include/surf/trace_mgr.h
src/instr/instr_interface.c
src/instr/instr_private.h
src/simdag/sd_global.c
src/simdag/sd_link.c
src/simdag/sd_task.c
src/simdag/sd_workstation.c
src/simgrid/sg_config.c
src/simix/smx_global.c
src/simix/smx_host.c
src/simix/smx_host_private.h
src/simix/smx_io.c
src/simix/smx_network.c
src/simix/smx_new_api.c
src/simix/smx_process.c
src/simix/smx_smurf_private.h
src/simix/smx_synchro.c
src/surf/cpu.cpp [new file with mode: 0644]
src/surf/cpu.hpp [new file with mode: 0644]
src/surf/cpu_cas01.cpp [new file with mode: 0644]
src/surf/cpu_cas01.hpp [new file with mode: 0644]
src/surf/cpu_ti.cpp [new file with mode: 0644]
src/surf/cpu_ti.hpp [new file with mode: 0644]
src/surf/fair_bottleneck.cpp [new file with mode: 0644]
src/surf/instr_routing.c
src/surf/instr_surf.c
src/surf/lagrange.cpp [new file with mode: 0644]
src/surf/maxmin_private_.h [new file with mode: 0644]
src/surf/network.cpp [new file with mode: 0644]
src/surf/network.hpp [new file with mode: 0644]
src/surf/network_constant.cpp [new file with mode: 0644]
src/surf/network_constant.hpp [new file with mode: 0644]
src/surf/network_gtnets.cpp [new file with mode: 0644]
src/surf/network_gtnets.hpp [new file with mode: 0644]
src/surf/network_smpi.cpp [new file with mode: 0644]
src/surf/network_smpi.hpp [new file with mode: 0644]
src/surf/new_model_private.h [deleted file]
src/surf/solver.cpp [new file with mode: 0644]
src/surf/solver.h [new file with mode: 0644]
src/surf/solver.hpp [new file with mode: 0644]
src/surf/solver_c.cpp [new file with mode: 0644]
src/surf/storage.cpp [new file with mode: 0644]
src/surf/storage.hpp [new file with mode: 0644]
src/surf/storage_private.h
src/surf/surf.cpp [new file with mode: 0644]
src/surf/surf.hpp [new file with mode: 0644]
src/surf/surf_c.h [new file with mode: 0644]
src/surf/surf_interface.cpp [new file with mode: 0644]
src/surf/surf_private.h
src/surf/surf_private.hpp [new file with mode: 0644]
src/surf/surf_routing.cpp [moved from src/surf/surf_routing.c with 82% similarity]
src/surf/surf_routing.hpp [new file with mode: 0644]
src/surf/surf_routing_cluster.cpp [new file with mode: 0644]
src/surf/surf_routing_cluster.hpp [new file with mode: 0644]
src/surf/surf_routing_dijkstra.cpp [moved from src/surf/surf_routing_dijkstra.c with 57% similarity]
src/surf/surf_routing_dijkstra.hpp [new file with mode: 0644]
src/surf/surf_routing_floyd.cpp [moved from src/surf/surf_routing_floyd.c with 56% similarity]
src/surf/surf_routing_floyd.hpp [new file with mode: 0644]
src/surf/surf_routing_full.cpp [moved from src/surf/surf_routing_full.c with 59% similarity]
src/surf/surf_routing_full.hpp [new file with mode: 0644]
src/surf/surf_routing_generic.cpp [moved from src/surf/surf_routing_generic.c with 57% similarity]
src/surf/surf_routing_generic.hpp [new file with mode: 0644]
src/surf/surf_routing_none.cpp [new file with mode: 0644]
src/surf/surf_routing_none.hpp [new file with mode: 0644]
src/surf/surf_routing_private.h
src/surf/surf_routing_private.hpp [new file with mode: 0644]
src/surf/surf_routing_vivaldi.cpp [new file with mode: 0644]
src/surf/surf_routing_vivaldi.hpp [new file with mode: 0644]
src/surf/surfxml_parse.c
src/surf/workstation.cpp [new file with mode: 0644]
src/surf/workstation.hpp [new file with mode: 0644]
src/surf/workstation_ptask_L07.cpp [new file with mode: 0644]
src/surf/workstation_ptask_L07.hpp [new file with mode: 0644]
src/xbt/log.c
src/xbt/swag.c
teshsuite/simdag/platforms/flatifier.c
testsuite/surf/surf_usage.c
testsuite/surf/surf_usage2.c

index 2d167a8..49ed4f4 100644 (file)
--- a/.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 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
        <storageModule moduleId="org.eclipse.cdt.core.settings">
-               <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="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1628373792">
+                       <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1628373792" moduleId="org.eclipse.cdt.core.settings" name="Build (GNU)">
+                               <externalSettings/>
+                               <extensions>
+                                       <extension id="org.eclipse.cdt.core.MachO64" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.PE" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.Cygwin_PE" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
+                                       <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+                               </extensions>
+                       </storageModule>
+                       <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+                               <configuration buildProperties="" description="" id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1628373792" name="Build (GNU)" parent="org.eclipse.cdt.build.core.emptycfg">
+                                       <folderInfo id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1628373792.978950279" name="/" resourcePath="">
+                                               <toolChain id="org.eclipse.linuxtools.cdt.autotools.core.toolChain.451718623" name="org.eclipse.linuxtools.cdt.autotools.core.toolChain" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolChain">
+                                                       <targetPlatform id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform.2070619552" isAbstract="false" name="GNU Autotools Target Platform" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.targetPlatform"/>
+                                                       <builder buildPath="${workspace_loc:/simgrid}/build" command="make" id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder.1564602718" keepEnvironmentInBuildfile="false" managedBuildOn="false" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.builder"/>
+                                                       <tool id="org.eclipse.linuxtools.cdt.autotools.core.gnu.toolchain.tool.configure.2013870946" name="configure" superClass="org.eclipse.linuxtools.cdt.autotools.core.gnu.toolchain.tool.configure">
+                                                               <option id="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name.1303771952" name="Name" superClass="org.eclipse.linuxtools.cdt.autotools.core.option.configure.name" value="org.eclipse.linuxtools.cdt.autotools.core.toolChain.1628373792" valueType="string"/>
+                                                       </tool>
+                                                       <tool id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.autogen.1873998201" name="autogen.sh" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.autogen"/>
+                                                       <tool id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.gcc.1609982557" name="GCC C Compiler" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.gcc">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.673666909" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
+                                                       </tool>
+                                                       <tool id="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.gpp.129357715" name="GCC C++ Compiler" superClass="org.eclipse.linuxtools.cdt.autotools.core.toolchain.tool.gpp">
+                                                               <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1566467247" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
+                                                       </tool>
+                                               </toolChain>
+                                       </folderInfo>
+                               </configuration>
+                       </storageModule>
+                       <storageModule moduleId="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.697056024" name="simgrid"/>
+               <project id="simgrid.null.1460982030" name="simgrid"/>
+       </storageModule>
+       <storageModule moduleId="scannerConfiguration">
+               <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
        </storageModule>
+       <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
        <storageModule moduleId="refreshScope" versionNumber="2">
-               <configuration configurationName="Default">
+               <configuration configurationName="Build (GNU)">
                        <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>
index d4d633c..0a44682 100644 (file)
@@ -7,6 +7,9 @@ project(SimGrid C)
 if (enable_gtnets OR enable_ns3)
   enable_language(CXX)
 endif()
+
+enable_language(CXX)
+
 if (NOT DEFINED enable_smpi OR enable_smpi) # smpi is enabled by default
   # Call enable_language(Fortran) in order to load the build rules for
   # this language, needed by teshsuite/smpi/mpich-test/.  Use
@@ -32,7 +35,7 @@ if (NOT DEFINED enable_smpi OR enable_smpi) # smpi is enabled by default
 endif()
 
 set(CMAKE_C_FLAGS "" CACHE TYPE INTERNAL FORCE)
-set(CMAKE_CXX_FLAGS "" CACHE TYPE INTERNAL FORCE)
+set(CMAKE_CXX_FLAGS " -std=c++11 " CACHE TYPE INTERNAL FORCE)
 set(CMAKE_EXE_LINKER_FLAGS "" CACHE TYPE INTERNAL FORCE)
 set(CMAKE_C_LINK_FLAGS "" CACHE TYPE INTERNAL FORCE)
 set(CMAKE_Fortran_FLAGS "" CACHE TYPE INTERNAL FORCE)
index 8629c55..cdef08e 100644 (file)
@@ -35,20 +35,26 @@ set(EXTRA_DIST
   src/simix/smx_smurf_private.h
   src/simix/smx_synchro_private.h
   src/smpi/README
+  src/smpi/colls/COPYRIGHTS
   src/smpi/colls/colls.h
   src/smpi/colls/colls_private.h
   src/smpi/colls/coll_tuned_topo.h
   src/smpi/private.h
   src/smpi/smpi_mpi_dt_private.h
-  src/surf/cpu_cas01_private.h
+  src/surf/cpu.hpp
+  src/surf/cpu_ti.hpp
+  src/surf/cpu_cas01.hpp
   src/surf/cpu_ti_private.h
   src/surf/gtnets/gtnets_interface.h
   src/surf/gtnets/gtnets_simulator.h
   src/surf/gtnets/gtnets_topology.h
   src/surf/maxmin_private.h
-  src/surf/network_gtnets_private.h
+  src/surf/network_gtnets.hpp
   src/surf/network_ns3_private.h
   src/surf/network_private.h
+  src/surf/network.hpp
+  src/surf/network_smpi.hpp
+  src/surf/network_constant.hpp
   src/surf/ns3/my-point-to-point-helper.h
   src/surf/ns3/ns3_interface.h
   src/surf/ns3/ns3_simulator.h
@@ -56,11 +62,24 @@ set(EXTRA_DIST
   src/surf/platf_generator_private.h
   src/surf/simgrid.dtd
   src/surf/simgrid_dtd.c
+  src/surf/storage.hpp
   src/surf/storage_private.h
+  src/surf/surf.hpp
   src/surf/surf_private.h
   src/surf/surf_routing_private.h
+  src/surf/surf_routing_private.hpp
+  src/surf/surf_routing.hpp
+  src/surf/surf_routing_cluster.hpp
+  src/surf/surf_routing_dijkstra.hpp
+  src/surf/surf_routing_floyd.hpp
+  src/surf/surf_routing_full.hpp
+  src/surf/surf_routing_generic.hpp
+  src/surf/surf_routing_none.hpp
+  src/surf/surf_routing_vivaldi.hpp
   src/surf/surfxml_parse.c
   src/surf/trace_mgr_private.h
+  src/surf/workstation.hpp
+  src/surf/workstation_ptask_L07.hpp
   src/win32/config.h
   src/xbt/automaton/automaton_lexer.yy.c
   src/xbt/automaton/parserPromela.lex
@@ -267,7 +286,7 @@ set(GTNETS_SRC
   src/surf/gtnets/gtnets_interface.cc
   src/surf/gtnets/gtnets_simulator.cc
   src/surf/gtnets/gtnets_topology.cc
-  src/surf/network_gtnets.c
+  src/surf/network_gtnets.cpp
   )
 
 set(NS3_SRC
@@ -279,35 +298,36 @@ set(NS3_SRC
   )
 
 set(SURF_SRC
-  src/surf/cpu_cas01.c
-  src/surf/cpu_ti.c
+  src/surf/cpu.cpp
+  src/surf/cpu_ti.cpp
+  src/surf/cpu_cas01.cpp
   src/surf/fair_bottleneck.c
   src/surf/instr_routing.c
   src/surf/instr_surf.c
   src/surf/lagrange.c
   src/surf/maxmin.c
-  src/surf/network.c
-  src/surf/network_constant.c
+  src/surf/network.cpp
+  src/surf/network_smpi.cpp  
+  src/surf/network_constant.cpp
   src/surf/platf_generator.c
   src/surf/random_mgr.c
   src/surf/sg_platf.c
-  src/surf/storage.c
-  src/surf/surf.c
-  src/surf/surf_action.c
-  src/surf/surf_model.c
-  src/surf/surf_routing.c
-  src/surf/surf_routing_cluster.c
-  src/surf/surf_routing_dijkstra.c
-  src/surf/surf_routing_floyd.c
-  src/surf/surf_routing_full.c
-  src/surf/surf_routing_generic.c
-  src/surf/surf_routing_none.c
-  src/surf/surf_routing_vivaldi.c
+  src/surf/storage.cpp
+  src/surf/surf.cpp
+  src/surf/surf_interface.cpp
+  src/surf/surf_routing.cpp  
+  src/surf/surf_routing_cluster.cpp
+  src/surf/surf_routing_dijkstra.cpp
+  src/surf/surf_routing_floyd.cpp
+  src/surf/surf_routing_full.cpp
+  src/surf/surf_routing_generic.cpp
+  src/surf/surf_routing_none.cpp
+  src/surf/surf_routing_vivaldi.cpp
   src/surf/surfxml_parse.c
   src/surf/surfxml_parseplatf.c
   src/surf/trace_mgr.c
-  src/surf/workstation.c
-  src/surf/workstation_ptask_L07.c
+  src/surf/workstation.cpp
+  src/surf/workstation_ptask_L07.cpp
   src/xbt/xbt_sg_stubs.c
   )
 
@@ -371,11 +391,9 @@ set(SIMIX_SRC
 
 set(SURF_SRC
   ${SURF_SRC}
-  src/surf/new_model.c
   )
 set(EXTRA_DIST
   ${EXTRA_DIST}
-  src/surf/new_model_private.h
   )
 #* ****************************************************************************************** *#
 
index efee4e6..f0b1573 100644 (file)
@@ -28,7 +28,7 @@ SG_BEGIN_DECL()
 typedef struct s_smx_rvpoint *msg_mailbox_t;
 
 /* ******************************** Environment ************************************ */
-typedef struct s_as *msg_as_t;
+typedef struct As *msg_as_t;
 
 /* ******************************** Host ************************************ */
 
index ff9095d..b888225 100644 (file)
 
 #include <xbt.h>
 
-typedef void *sg_routing_link_t; /* The actual type is model-dependent so use void* instead*/
-typedef struct s_routing_edge *sg_routing_edge_t;
+typedef void *sg_routing_link_t; /* FIXME:The actual type is model-dependent so use void* instead*/
+typedef struct RoutingEdge *sg_routing_edge_t;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 XBT_PUBLIC(sg_routing_edge_t) sg_routing_edge_by_name_or_null(const char *name);
+#ifdef __cplusplus
+}
+#endif
 
 /** Defines whether a given resource is working or not */
 typedef enum {
@@ -47,6 +53,9 @@ typedef struct tmgr_trace *tmgr_trace_t; /**< Opaque structure defining an avail
 /** opaque structure defining a event generator for availability based on a probability distribution */
 typedef struct probabilist_event_generator *probabilist_event_generator_t;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 XBT_PUBLIC(tmgr_trace_t) tmgr_trace_new_from_file(const char *filename);
 XBT_PUBLIC(tmgr_trace_t) tmgr_trace_new_from_string(const char *id,
                                                     const char *input,
@@ -71,6 +80,10 @@ XBT_PUBLIC(probabilist_event_generator_t) tmgr_event_generator_new_exponential(c
 XBT_PUBLIC(probabilist_event_generator_t) tmgr_event_generator_new_weibull(const char* id,
                                                                            double scale,
                                                                            double shape);
+#ifdef __cplusplus
+}
+#endif
+
 typedef xbt_dictelm_t sg_host_t;
 static inline char* sg_host_name(sg_host_t host) {
   return host->key;
@@ -319,6 +332,10 @@ typedef struct s_sg_platf_gpu_cbarg {
 
 /* ***************************************** */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 XBT_PUBLIC(void) sg_platf_begin(void);  // Start a new platform
 XBT_PUBLIC(void) sg_platf_end(void); // Finish the creation of the platform
 
@@ -368,5 +385,8 @@ XBT_PUBLIC(void) sg_platf_ASroute_add_link (const char* link_id, sg_platf_route_
 typedef void (*sg_platf_process_cb_t)(sg_platf_process_cbarg_t);
 XBT_PUBLIC(void) sg_platf_process_add_cb(sg_platf_process_cb_t fct);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif                          /* SG_PLATF_H */
index d9e91ef..3c2e36a 100644 (file)
 #include "xbt/lib.h"
 #include "simgrid/platf_interface.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 XBT_PUBLIC(xbt_lib_t) host_lib;
 XBT_PUBLIC(int) ROUTING_HOST_LEVEL; //Routing level
 XBT_PUBLIC(int)  SURF_CPU_LEVEL;    //Surf cpu level
@@ -47,4 +51,8 @@ void routing_AS_end(sg_platf_AS_cbarg_t AS);
 
 void routing_cluster_add_backbone(void* bb);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif                          /* _SURF_SURF_H */
index 0cdf31f..0994be3 100644 (file)
@@ -28,7 +28,7 @@ typedef struct xbt_automaton {
 typedef struct xbt_automaton* xbt_automaton_t;
 
 typedef struct xbt_automaton_exp_label{
-  enum{or=0, and=1, not=2, predicat=3, one=4} type;
+  enum{AUT_OR=0, AUT_AND=1, AUT_NOT=2, AUT_PREDICAT=3, AUT_ONE=4} type;
   union{
     struct{
       struct xbt_automaton_exp_label* left_exp;
index 29a9149..cc50c02 100644 (file)
@@ -16,6 +16,9 @@
  *  @{
  */
 /* @brief heap datatype */
+#ifdef __cplusplus
+extern "C" {
+#endif
 typedef struct xbt_heap *xbt_heap_t;
 
 XBT_PUBLIC(xbt_heap_t) xbt_heap_new(int init_size,
@@ -33,6 +36,8 @@ XBT_PUBLIC(void) xbt_heap_set_update_callback(xbt_heap_t H,
                                                                        *,
                                                                        int));
 XBT_PUBLIC(void *) xbt_heap_remove(xbt_heap_t H, int i);
-
+#ifdef __cplusplus
+}
+#endif
 /* @} */
 #endif                          /* _XBT_HEAP_H */
index b5b9a82..29cad1b 100644 (file)
 
 #include <xbt/misc.h>           /* XBT_PUBLIC */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 XBT_PUBLIC(void) xbt_init(int *argc, char **argv);
 XBT_PUBLIC(void) xbt_exit(void);
+#ifdef __cplusplus
+}
+#endif
+
 #endif                          /* _XBT_MODULE_H */
index 52664c7..0f5c429 100644 (file)
@@ -1,5 +1,9 @@
 #include "xbt.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 XBT_PUBLIC(int) TRACE_start (void);
 XBT_PUBLIC(int) TRACE_end (void);
 XBT_PUBLIC(void) TRACE_global_init(int *argc, char **argv);
@@ -8,3 +12,7 @@ XBT_PUBLIC(void) TRACE_surf_resource_utilization_alloc(void);
 XBT_PUBLIC(void) TRACE_surf_resource_utilization_release(void);
 XBT_PUBLIC(void) TRACE_add_start_function(void (*func)(void));
 XBT_PUBLIC(void) TRACE_add_end_function(void (*func)(void));
+
+#ifdef __cplusplus
+}
+#endif
index 2ecc52a..7091f04 100644 (file)
@@ -41,6 +41,10 @@ typedef void (*sg_platf_mstorage_cb_t)(sg_platf_mstorage_cbarg_t);
 /* ***************************************** */
 /* TUTORIAL: New TAG                         */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef void (*sg_platf_gpu_cb_t)(sg_platf_gpu_cbarg_t);
 XBT_PUBLIC(void) sg_platf_gpu_add_cb(sg_platf_gpu_cb_t);
 /* ***************************************** */
@@ -70,6 +74,9 @@ XBT_PUBLIC(void) sg_platf_mstorage_add_cb(sg_platf_mstorage_cb_t fct);
 XBT_PUBLIC(void) sg_platf_storage_type_add_cb(sg_platf_storage_type_cb_t fct);
 XBT_PUBLIC(void) sg_platf_mount_add_cb(sg_platf_mount_cb_t fct);
 
+#ifdef __cplusplus
+}
+#endif
 /** \brief Pick the right models for CPU, net and workstation, and call their model_init_preparse
  *
  * Must be called within parsing/creating the environment (after the <config>s, if any, and before <AS> or friends such as <cluster>)
index e4142a9..3d01e63 100644 (file)
@@ -9,6 +9,11 @@
 /*******************************************/
 /*** Config Globals **************************/
 /*******************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 XBT_PUBLIC_DATA(xbt_cfg_t) _sg_cfg_set;
 XBT_PUBLIC_DATA(int) _sg_cfg_init_status;
 XBT_PUBLIC_DATA(int) _sg_cfg_exit_asap;
@@ -21,3 +26,7 @@ XBT_PUBLIC(xbt_dynar_t) sg_cfg_get_dynar(const char* name);
 
 void sg_config_init(int *argc, char **argv);
 void sg_config_finalize(void);
+
+#ifdef __cplusplus
+}
+#endif
index 31375cd..3dd00e0 100644 (file)
@@ -13,7 +13,7 @@
  *  Generic data structure for a model. The workstations,
  *  the CPUs and the network links are examples of models.
  */
-typedef struct surf_model *surf_model_t;
+//FIXME: typedef struct surf_model *surf_model_t;
 
 /** \ingroup SURF_actions
  *  \brief Action datatype
@@ -21,8 +21,8 @@ typedef struct surf_model *surf_model_t;
  * An action is some working amount on a model.
  * It is represented as a cost, a priority, a duration and a state.
  */
-typedef struct surf_action *surf_action_t;
-typedef struct surf_file *surf_file_t;
+//FIXME:typedef struct surf_action *surf_action_t;
+//FIXME:typedef struct surf_file *surf_file_t;
 typedef struct surf_storage *surf_storage_t;
 typedef struct surf_stat *surf_stat_t;
 
index 0db88a3..257cc47 100644 (file)
@@ -31,6 +31,10 @@ static XBT_INLINE int double_equals(double value1, double value2)
   return (fabs(value1 - value2) < MAXMIN_PRECISION);
 }
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 XBT_PUBLIC(lmm_system_t) lmm_system_new(int selective_update);
 XBT_PUBLIC(void) lmm_system_free(lmm_system_t sys);
 void lmm_variable_disable(lmm_system_t sys, lmm_variable_t var);
@@ -128,5 +132,8 @@ XBT_PUBLIC(double func_vegas_f) (lmm_variable_t var, double x);
 XBT_PUBLIC(double func_vegas_fp) (lmm_variable_t var, double x);
 XBT_PUBLIC(double func_vegas_fpi) (lmm_variable_t var, double x);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif                          /* _SURF_MAXMIN_H */
index 0f0694a..be43397 100644 (file)
@@ -35,7 +35,6 @@ extern int sg_gtnets_jitter_seed;
 #endif
 extern xbt_dynar_t surf_path;
 
-
 typedef enum {
   SURF_NETWORK_ELEMENT_NULL = 0,        /* NULL */
   SURF_NETWORK_ELEMENT_HOST,    /* host type */
@@ -43,6 +42,78 @@ typedef enum {
   SURF_NETWORK_ELEMENT_AS       /* AS type */
 } e_surf_network_element_type_t;
 
+#ifdef __cplusplus
+class Model;
+class CpuModel;
+class WorkstationModel;
+class NetworkCm02Model;
+class StorageModel;
+class Resource;
+class ResourceLmm;
+class WorkstationCLM03;
+class NetworkCm02Link;
+class Cpu;
+class Action;
+class ActionLmm;
+class StorageActionLmm;
+class As;
+class RoutingEdge;
+class RoutingPlatf;
+#else
+typedef struct Model Model;
+typedef struct CpuModel CpuModel;
+typedef struct WorkstationModel WorkstationModel;
+typedef struct NetworkCm02Model NetworkCm02Model;
+typedef struct StorageModel StorageModel;
+typedef struct Resource Resource;
+typedef struct ResourceLmm ResourceLmm;
+typedef struct WorkstationCLM03 WorkstationCLM03;
+typedef struct NetworkCm02Link NetworkCm02Link;
+typedef struct Cpu Cpu;
+typedef struct Action Action;
+typedef struct ActionLmm ActionLmm;
+typedef struct StorageActionLmm StorageActionLmm;
+typedef struct As As;
+typedef struct RoutingEdge RoutingEdge;
+typedef struct RoutingPlatf RoutingPlatf;
+#endif
+
+/** \ingroup SURF_models
+ *  \brief Model datatype
+ *
+ *  Generic data structure for a model. The workstations,
+ *  the CPUs and the network links are examples of models.
+ */
+typedef Model *surf_model_t;
+typedef CpuModel *surf_cpu_model_t;
+typedef WorkstationModel *surf_workstation_model_t;
+typedef NetworkCm02Model *surf_network_model_t;
+typedef StorageModel *surf_storage_model_t;
+
+typedef xbt_dictelm_t surf_resource_t;
+typedef Resource *surf_cpp_resource_t;
+typedef WorkstationCLM03 *surf_workstation_CLM03_t;
+typedef NetworkCm02Link *surf_network_link_t;
+typedef Cpu *surf_cpu_t;
+
+/** \ingroup SURF_actions
+ *  \brief Action structure
+ *
+ *  Never create s_surf_action_t by yourself ! The actions are created
+ *  on the fly when you call execute or communicate on a model.
+ *
+ *  \see e_surf_action_state_t
+ */
+typedef Action *surf_action_t;
+typedef ActionLmm *surf_action_lmm_t;
+typedef StorageActionLmm *surf_storage_action_lmm_t;
+
+typedef As *AS_t;
+typedef RoutingEdge *routing_edge_t;
+typedef RoutingPlatf *routing_platf_t;
+
+typedef struct surf_file *surf_file_t;
+
 XBT_PUBLIC(e_surf_network_element_type_t)
   routing_get_network_element_type(const char* name);
 
@@ -72,57 +143,7 @@ XBT_PUBLIC(int) find_model_description(s_surf_model_description_t * table,
 XBT_PUBLIC(void) model_help(const char *category,
                             s_surf_model_description_t * table);
 
-enum heap_action_type{
-  LATENCY = 100,
-  MAX_DURATION,
-  NORMAL,
-  NOTSET
-};
-
-/** \ingroup SURF_actions
- *  \brief Action structure
- *
- *  Never create s_surf_action_t by yourself ! The actions are created
- *  on the fly when you call execute or communicate on a model.
- *
- *  \see e_surf_action_state_t
- */
-typedef struct surf_action {
-  s_xbt_swag_hookup_t state_hookup;
-  xbt_swag_t state_set;
-  double cost;                  /**< cost        */
-  double priority;              /**< priority (1.0 by default) */
-  double max_duration;          /**< max_duration (may fluctuate until
-           the task is completed) */
-  double remains;               /**< How much of that cost remains to
-         * be done in the currently running task */
-#ifdef HAVE_LATENCY_BOUND_TRACKING
-  int latency_limited;               /**< Set to 1 if is limited by latency, 0 otherwise */
-#endif
 
-  double start;                 /**< start time  */
-  double finish;                /**< finish time : this is modified during the run
-         * and fluctuates until the task is completed */
-  void *data;                   /**< for your convenience */
-  int refcount;
-  surf_model_t model_type;
-#ifdef HAVE_TRACING
-  char *category;               /**< tracing category for categorized resource utilization monitoring */
-#endif
-  surf_file_t file;        /**< surf_file_t for storage model */
-  xbt_dict_t ls_dict;
-} s_surf_action_t;
-
-typedef struct surf_action_lmm {
-  s_surf_action_t generic_action;
-  lmm_variable_t variable;
-  int suspended;
-  s_xbt_swag_hookup_t action_list_hookup;
-  int index_heap;
-  double last_update;
-  double last_value;
-  enum heap_action_type hat;
-} s_surf_action_lmm_t, *surf_action_lmm_t;
 
 /** \ingroup SURF_actions
  *  \brief Action states
@@ -131,6 +152,7 @@ typedef struct surf_action_lmm {
  *
  *  \see surf_action_t, surf_action_state_t
  */
+
 typedef enum {
   SURF_ACTION_READY = 0,        /**< Ready        */
   SURF_ACTION_RUNNING,          /**< Running      */
@@ -141,29 +163,10 @@ typedef enum {
                                 /**< Not in the system anymore. Why did you ask ? */
 } e_surf_action_state_t;
 
-/** \ingroup SURF_actions
- *  \brief Action state sets
- *
- *  This structure contains some sets of actions.
- *  It provides a fast access to the actions in each state.
- *
- *  \see surf_action_t, e_surf_action_state_t
- */
-typedef struct surf_action_state {
-  xbt_swag_t ready_action_set;
-                                 /**< Actions in state SURF_ACTION_READY */
-  xbt_swag_t running_action_set;
-                                 /**< Actions in state SURF_ACTION_RUNNING */
-  xbt_swag_t failed_action_set;
-                                 /**< Actions in state SURF_ACTION_FAILED */
-  xbt_swag_t done_action_set;
-                                 /**< Actions in state SURF_ACTION_DONE */
-} s_surf_action_state_t, *surf_action_state_t;
-
 /***************************/
 /* Generic model object */
 /***************************/
-typedef struct s_routing_platf s_routing_platf_t, *routing_platf_t;
+//FIXME:REMOVE typedef struct s_routing_platf s_routing_platf_t, *routing_platf_t;
 XBT_PUBLIC_DATA(routing_platf_t) routing_platf;
 
 /*******************************************
@@ -299,70 +302,14 @@ typedef struct surf_workstation_model_extension_public {
 } s_surf_model_extension_workstation_t;
 
 
-
-
-/** \ingroup SURF_models
- *  \brief Model datatype
- *
- *  Generic data structure for a model. The workstations,
- *  the CPUs and the network links are examples of models.
- */
-typedef struct surf_model {
-  const char *name;     /**< Name of this model */
-  s_surf_action_state_t states;      /**< Any living action on this model */
-
-   e_surf_action_state_t(*action_state_get) (surf_action_t action);
-                                                                       /**< Return the state of an action */
-  void (*action_state_set) (surf_action_t action,
-                            e_surf_action_state_t state);
-                                                                  /**< Change an action state*/
-
-  double (*action_get_start_time) (surf_action_t action);     /**< Return the start time of an action */
-  double (*action_get_finish_time) (surf_action_t action);     /**< Return the finish time of an action */
-  int (*action_unref) (surf_action_t action);     /**< Specify that we don't use that action anymore. Returns true if the action was destroyed and false if someone still has references on it. */
-  void (*action_cancel) (surf_action_t action);     /**< Cancel a running action */
-  void (*action_recycle) (surf_action_t action);     /**< Recycle an action */
-  void (*action_data_set) (surf_action_t action, void *data);     /**< Set the user data of an action */
-  void (*suspend) (surf_action_t action);     /**< Suspend an action */
-  void (*resume) (surf_action_t action);     /**< Resume a suspended action */
-  int (*is_suspended) (surf_action_t action);     /**< Return whether an action is suspended */
-  void (*set_max_duration) (surf_action_t action, double duration);     /**< Set the max duration of an action*/
-  void (*set_priority) (surf_action_t action, double priority);     /**< Set the priority of an action */
-#ifdef HAVE_TRACING
-  void (*set_category) (surf_action_t action, const char *category); /**< Set the category of an action */
-#endif
-  double (*get_remains) (surf_action_t action);     /**< Get the remains of an action */
-#ifdef HAVE_LATENCY_BOUND_TRACKING
-  int (*get_latency_limited) (surf_action_t action);     /**< Return 1 if action is limited by latency, 0 otherwise */
-#endif
-
-  void (*gap_remove) (surf_action_lmm_t action);
-
-  surf_model_private_t model_private;
-
-  union extension {
-    s_surf_model_extension_cpu_t cpu;
-    s_surf_model_extension_network_t network;
-    s_surf_model_extension_storage_t storage;
-    s_surf_model_extension_workstation_t workstation;
-    /*******************************************/
-    /* TUTORIAL: New model                     */
-    s_surf_model_extension_new_model_t new_model;
-    /*******************************************/
-  } extension;
-} s_surf_model_t;
-
-surf_model_t surf_model_init(void);
-void surf_model_exit(surf_model_t model);
-
 static inline void *surf_cpu_resource_priv(const void *host) {
-  return xbt_lib_get_level((void *)host, SURF_CPU_LEVEL);
+  return xbt_lib_get_level((xbt_dictelm_t)host, SURF_CPU_LEVEL);
 }
 static inline void *surf_workstation_resource_priv(const void *host){
-  return xbt_lib_get_level((void *)host, SURF_WKS_LEVEL);
+  return (void*)xbt_lib_get_level((xbt_dictelm_t)host, SURF_WKS_LEVEL);
 }
 static inline void *surf_storage_resource_priv(const void *storage){
-  return xbt_lib_get_level((void *)storage, SURF_STORAGE_LEVEL);
+  return (void*)xbt_lib_get_level((xbt_dictelm_t)storage, SURF_STORAGE_LEVEL);
 }
 
 static inline void *surf_cpu_resource_by_name(const char *name) {
@@ -375,29 +322,76 @@ static inline void *surf_storage_resource_by_name(const char *name){
   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;
-
-/**
- * Resource which have a metric handled by a maxmin system
- */
-typedef struct {
-  double scale;
-  double peak;
-  tmgr_trace_event_t event;
-} s_surf_metric_t;
-
-typedef struct surf_resource_lmm {
-  s_surf_resource_t generic_resource;
-  lmm_constraint_t constraint;
-  e_surf_resource_state_t state_current;
-  tmgr_trace_event_t state_event;
-  s_surf_metric_t power;
-} s_surf_resource_lmm_t, *surf_resource_lmm_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
+char *surf_routing_edge_name(sg_routing_edge_t edge);
+void *surf_as_cluster_get_backbone(AS_t as);
+void surf_as_cluster_set_backbone(AS_t as, void* backbone);
+const char *surf_model_name(surf_model_t model);
+xbt_swag_t surf_model_done_action_set(surf_model_t model);
+xbt_swag_t surf_model_failed_action_set(surf_model_t model);
+xbt_swag_t surf_model_ready_action_set(surf_model_t model);
+xbt_swag_t surf_model_running_action_set(surf_model_t model);
+surf_action_t surf_workstation_model_execute_parallel_task(surf_workstation_model_t model,
+                                                   int workstation_nb,
+                                            void **workstation_list,
+                                            double *computation_amount,
+                                            double *communication_amount,
+                                            double rate);
+surf_action_t surf_workstation_model_communicate(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst, double size, double rate);
+xbt_dynar_t surf_workstation_model_get_route(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst);
+surf_action_t surf_network_model_communicate(surf_network_model_t model, sg_routing_edge_t src, sg_routing_edge_t dst, double size, double rate);
+const char *surf_resource_name(surf_cpp_resource_t resource);
+xbt_dict_t surf_resource_get_properties(surf_cpp_resource_t resource);
+e_surf_resource_state_t surf_resource_get_state(surf_cpp_resource_t resource);
+double surf_workstation_get_speed(surf_resource_t resource, double load);
+double surf_workstation_get_available_speed(surf_resource_t resource);
+int surf_workstation_get_core(surf_resource_t resource);
+surf_action_t surf_workstation_execute(surf_resource_t resource, double size);
+surf_action_t surf_workstation_sleep(surf_resource_t resource, double duration);
+surf_action_t surf_workstation_open(surf_resource_t workstation, const char* mount, const char* path);
+surf_action_t surf_workstation_close(surf_resource_t workstation, surf_file_t fd);
+surf_action_t surf_workstation_read(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size);
+surf_action_t surf_workstation_write(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size);
+xbt_dynar_t surf_workstation_get_info(surf_resource_t resource, surf_file_t fd);
+sg_storage_size_t surf_workstation_get_free_size(surf_resource_t resource, const char* name);
+sg_storage_size_t surf_workstation_get_used_size(surf_resource_t resource, const char* name);
+surf_action_t surf_cpu_execute(surf_resource_t cpu, double size);
+surf_action_t surf_cpu_sleep(surf_resource_t cpu, double duration);
+double surf_workstation_get_current_power_peak(surf_resource_t host);
+double surf_workstation_get_power_peak_at(surf_resource_t host, int pstate_index);
+int surf_workstation_get_nb_pstates(surf_resource_t host);
+void surf_workstation_set_power_peak_at(surf_resource_t host, int pstate_index);
+double surf_workstation_get_consumed_energy(surf_resource_t host);
+xbt_dict_t surf_workstation_get_storage_list(surf_resource_t workstation);
+int surf_workstation_unlink(surf_resource_t workstation, surf_file_t fd);
+surf_action_t surf_workstation_ls(surf_resource_t workstation, const char* mount, const char *path);
+size_t surf_workstation_get_size(surf_resource_t workstation, surf_file_t fd);
+int surf_network_link_is_shared(surf_cpp_resource_t link);
+double surf_network_link_get_bandwidth(surf_cpp_resource_t link);
+double surf_network_link_get_latency(surf_cpp_resource_t link);
+xbt_dict_t surf_storage_get_content(surf_resource_t resource);
+sg_storage_size_t surf_storage_get_size(surf_resource_t resource);
+void *surf_action_get_data(surf_action_t action);
+void surf_action_set_data(surf_action_t action, void *data);
+void surf_action_unref(surf_action_t action);
+double surf_action_get_start_time(surf_action_t action);
+double surf_action_get_finish_time(surf_action_t action);
+double surf_action_get_remains(surf_action_t action);
+void surf_action_suspend(surf_action_t action);
+void surf_action_resume(surf_action_t action);
+void surf_action_cancel(surf_action_t action);
+void surf_action_set_priority(surf_action_t action, double priority);
+void surf_action_set_category(surf_action_t action, const char *category);
+e_surf_action_state_t surf_action_get_state(surf_action_t action);
+int surf_action_get_cost(surf_action_t action);
+surf_file_t surf_storage_action_get_file(surf_action_t action);
+xbt_dict_t surf_storage_action_get_ls_dict(surf_action_t action);
+
+#ifdef __cplusplus
+}
+#endif
 
 /**************************************/
 /* Implementations of model object */
@@ -407,7 +401,7 @@ typedef struct surf_resource_lmm {
 /** \ingroup SURF_models
  *  \brief The CPU model
  */
-XBT_PUBLIC_DATA(surf_model_t) surf_cpu_model;
+XBT_PUBLIC_DATA(surf_cpu_model_t) surf_cpu_model;
 
 /** \ingroup SURF_models
  *  \brief Initializes the CPU model with the model Cas01
@@ -452,7 +446,7 @@ XBT_PUBLIC_DATA(s_surf_model_description_t) surf_cpu_model_description[];
  *  model should be accessed because depending on the platform model,
  *  the network model can be NULL.
  */
-XBT_PUBLIC_DATA(surf_model_t) surf_network_model;
+XBT_PUBLIC_DATA(surf_network_model_t) surf_network_model;
 
 /** \ingroup SURF_models
  *  \brief Same as network model 'LagrangeVelho', only with different correction factors.
@@ -588,7 +582,7 @@ XBT_PUBLIC(void) surf_storage_model_init_default(void);
  */
 XBT_PUBLIC_DATA(s_surf_model_description_t) surf_storage_model_description[];
 
-XBT_PUBLIC_DATA(surf_model_t) surf_storage_model;
+XBT_PUBLIC_DATA(surf_storage_model_t) surf_storage_model;
 
 /** \ingroup SURF_models
  *  \brief The workstation model
@@ -598,7 +592,7 @@ XBT_PUBLIC_DATA(surf_model_t) surf_storage_model;
  *  because depending on the platform model, the network model and the CPU model
  *  may not exist.
  */
-XBT_PUBLIC_DATA(surf_model_t) surf_workstation_model;
+XBT_PUBLIC_DATA(surf_workstation_model_t) surf_workstation_model;
 
 /** \ingroup SURF_models
  *  \brief Initializes the platform with a compound workstation model
@@ -637,11 +631,6 @@ XBT_PUBLIC(void) surf_workstation_model_init_ptask_L07(void);
 XBT_PUBLIC_DATA(s_surf_model_description_t)
     surf_workstation_model_description[];
 
-/*******************************************
- *  TUTORIAL: New model
- */
-XBT_PUBLIC(void) surf_new_model_init_default(void);
-XBT_PUBLIC_DATA(s_surf_model_description_t) surf_new_model_description[];
 /*******************************************/
 
 /** \ingroup SURF_models
@@ -662,13 +651,20 @@ XBT_PUBLIC(xbt_dict_t) watched_hosts_lib;
 /*******************************************/
 /*** SURF Platform *************************/
 /*******************************************/
-typedef struct s_as *AS_t;
-
+#ifdef __cplusplus
+extern "C" {
+#endif
 XBT_PUBLIC_DATA(AS_t) surf_AS_get_routing_root(void); 
 XBT_PUBLIC_DATA(const char *) surf_AS_get_name(AS_t as);
 XBT_PUBLIC_DATA(xbt_dict_t) surf_AS_get_routing_sons(AS_t as);
 XBT_PUBLIC_DATA(const char *) surf_AS_get_model(AS_t as);
 XBT_PUBLIC_DATA(xbt_dynar_t) surf_AS_get_hosts(AS_t as);
+XBT_PUBLIC_DATA(void) surf_AS_get_graph(AS_t as, xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+XBT_PUBLIC_DATA(AS_t) surf_platf_get_root(routing_platf_t platf);
+XBT_PUBLIC_DATA(e_surf_network_element_type_t) surf_routing_edge_get_rc_type(sg_routing_edge_t edge);
+#ifdef __cplusplus
+}
+#endif
 
 /*******************************************/
 /*** SURF Globals **************************/
@@ -765,7 +761,7 @@ void instr_routing_define_callbacks (void);
 void instr_new_variable_type (const char *new_typename, const char *color);
 void instr_new_user_variable_type  (const char *father_type, const char *new_typename, const char *color);
 void instr_new_user_state_type (const char *father_type, const char *new_typename);
-void instr_new_value_for_user_state_type (const char *typename, const char *value, const char *color);
+void instr_new_value_for_user_state_type (const char *_typename, const char *value, const char *color);
 int instr_platform_traced (void);
 xbt_graph_t instr_routing_platform_graph (void);
 void instr_routing_platform_graph_export_graphviz (xbt_graph_t g, const char *filename);
index 963fdff..fdc1eb6 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef SURF_RESOURCE_H
 #define SURF_RESOURCE_H
 
-static XBT_INLINE
+/*FIXME:DELETEstatic XBT_INLINE
     surf_resource_t surf_resource_new(size_t childsize,
                                       surf_model_t model, const char *name,
                                       xbt_dict_t props, void_f_pvoid_t free_f)
@@ -40,6 +40,6 @@ static XBT_INLINE const char *surf_resource_name(const void *resource)
 static XBT_INLINE xbt_dict_t surf_resource_properties(const void *resource)
 {
   return ((surf_resource_t) resource)->properties;
-}
+}*/
 
 #endif                          /* SURF_RESOURCE_H */
index 44bfeaf..4be9408 100644 (file)
@@ -11,7 +11,7 @@
 #include "surf/trace_mgr.h"
 #include "surf/surf_resource.h"
 
-
+#ifdef TOMATO
 static XBT_INLINE
     surf_resource_lmm_t surf_resource_lmm_new(size_t childsize,
                                               /* for superclass */
@@ -43,7 +43,7 @@ static XBT_INLINE
         tmgr_history_add_trace(history, metric_trace, 0.0, 0, res);
   return res;
 }
-
+#endif
 
 static XBT_INLINE e_surf_resource_state_t surf_resource_lmm_get_state(void
                                                                       *r)
index 85c80a6..3343492 100644 (file)
 #include "surf/datatypes.h"
 #include "simgrid/platf_interface.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* Creation functions */
 XBT_PUBLIC(tmgr_history_t) tmgr_history_new(void);
 XBT_PUBLIC(void) tmgr_history_free(tmgr_history_t history);
@@ -43,4 +47,8 @@ XBT_PUBLIC(tmgr_trace_event_t)
 
 XBT_PUBLIC(void) tmgr_finalize(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif                          /* _SURF_TMGR_H */
index 052144c..170ebb1 100644 (file)
@@ -8,7 +8,10 @@
 
 #ifdef HAVE_TRACING
 #include "instr/instr_private.h"
-#include "surf/network_private.h"
+#include "surf/surf.h"
+#include "surf/surf_private.h"
+
+//FIXME:#include "surf/network_private.h"
 
 typedef enum {
   INSTR_US_DECLARE,
@@ -374,7 +377,7 @@ static void instr_user_srcdst_variable(double time,
   unsigned int i;
   void *link;
   xbt_dynar_foreach (route, i, link) {
-    char *link_name = ((link_CM02_t)link)->lmm_resource.generic_resource.name;
+    char *link_name = (char*)surf_resource_name(link);
     instr_user_variable (time, link_name, variable, father_type, value, what, NULL, user_link_variables);
   }
 }
index 21baa8f..d758703 100644 (file)
@@ -102,6 +102,10 @@ extern xbt_dict_t user_vm_variables;
 extern xbt_dict_t user_link_variables;
 extern double TRACE_last_timestamp_to_dump;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* instr_paje_header.c */
 void TRACE_header(int basic, int size);
 
@@ -214,6 +218,10 @@ XBT_PUBLIC(val_t)  PJ_value_get_or_new (const char *name, const char *color, typ
 XBT_PUBLIC(val_t)  PJ_value_get (const char *name, const type_t father);
 void PJ_value_free (val_t value);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* HAVE_TRACING */
 
 #ifdef HAVE_JEDULE
index 54feb2d..5927386 100644 (file)
@@ -312,11 +312,10 @@ xbt_swag_t SD_simulate_swag(double how_long) {
 
     /* let's see which tasks are done */
     xbt_dynar_foreach(model_list, iter, model) {
-      while ((action = xbt_swag_extract(model->states.done_action_set))) {
-        task = action->data;
-        task->start_time =
-            surf_workstation_model->
-            action_get_start_time(task->surf_action);
+      while ((action = xbt_swag_extract(surf_model_done_action_set(model)))) {
+        task = surf_action_get_data(action);
+        task->start_time = surf_action_get_start_time(task->surf_action);
+
         task->finish_time = surf_get_clock();
         XBT_VERB("Task '%s' done", SD_task_get_name(task));
         XBT_DEBUG("Calling __SD_task_just_done");
@@ -380,15 +379,13 @@ xbt_swag_t SD_simulate_swag(double how_long) {
       }
 
       /* let's see which tasks have just failed */
-      while ((action = xbt_swag_extract(model->states.failed_action_set))) {
-        task = action->data;
-        task->start_time =
-            surf_workstation_model->
-            action_get_start_time(task->surf_action);
+      while ((action = xbt_swag_extract(surf_model_failed_action_set(model)))) {
+        task = surf_action_get_data(action);
+        task->start_time = surf_action_get_start_time(task->surf_action);
         task->finish_time = surf_get_clock();
         XBT_VERB("Task '%s' failed", SD_task_get_name(task));
         __SD_task_set_state(task, SD_FAILED);
-        surf_workstation_model->action_unref(action);
+        surf_action_unref(action);
         task->surf_action = NULL;
 
         xbt_swag_insert(task,sd_global->return_set);
index e147c42..f5e993d 100644 (file)
@@ -23,7 +23,7 @@ SD_link_t __SD_link_create(void *surf_link, void *data)
   link = xbt_new(s_SD_link_t, 1);
   link->surf_link = surf_link;
   link->data = data;            /* user data */
-  if (surf_workstation_model->extension.workstation.link_shared(surf_link))
+  if (surf_network_link_is_shared(surf_link))
     link->sharing_policy = SD_LINK_SHARED;
   else
     link->sharing_policy = SD_LINK_FATPIPE;
@@ -118,8 +118,7 @@ const char *SD_link_get_name(SD_link_t link)
  */
 double SD_link_get_current_bandwidth(SD_link_t link)
 {
-  return surf_workstation_model->extension.workstation.
-      get_link_bandwidth(link->surf_link);
+  return surf_network_link_get_bandwidth(link->surf_link);
 }
 
 /**
@@ -130,8 +129,7 @@ double SD_link_get_current_bandwidth(SD_link_t link)
  */
 double SD_link_get_current_latency(SD_link_t link)
 {
-  return surf_workstation_model->extension.workstation.
-      get_link_latency(link->surf_link);
+  return surf_network_link_get_latency(link->surf_link);
 }
 
 /**
index c098fd1..ea42489 100644 (file)
@@ -257,7 +257,7 @@ void SD_task_destroy(SD_task_t task)
   xbt_free(task->name);
 
   if (task->surf_action != NULL)
-    surf_workstation_model->action_unref(task->surf_action);
+       surf_action_unref(task->surf_action);
 
   xbt_free(task->workstation_list);
   xbt_free(task->communication_amount);
@@ -358,13 +358,11 @@ void __SD_task_set_state(SD_task_t task, e_SD_task_state_t new_state)
     break;
   case SD_RUNNING:
     task->state_set = sd_global->running_task_set;
-    task->start_time =
-        surf_workstation_model->action_get_start_time(task->surf_action);
+    task->start_time = surf_action_get_start_time(task->surf_action);
     break;
   case SD_DONE:
     task->state_set = sd_global->done_task_set;
-    task->finish_time =
-        surf_workstation_model->action_get_finish_time(task->surf_action);
+    task->finish_time = surf_action_get_finish_time(task->surf_action);
     task->remains = 0;
 #ifdef HAVE_JEDULE
     jedule_log_sd_event(task);
@@ -519,7 +517,7 @@ double SD_task_get_alpha(SD_task_t task)
 double SD_task_get_remaining_amount(SD_task_t task)
 {
   if (task->surf_action)
-    return surf_workstation_model->get_remains(task->surf_action);
+       return surf_action_get_remains(task->surf_action);
   else
     return task->remains;
 }
@@ -1067,7 +1065,7 @@ void SD_task_unschedule(SD_task_t task)
   }
 
   if (__SD_task_is_running(task))       /* the task should become SD_FAILED */
-    surf_workstation_model->action_cancel(task->surf_action);
+       surf_action_cancel(task->surf_action);
   else {
     if (task->unsatisfied_dependencies == 0)
       __SD_task_set_state(task, SD_SCHEDULABLE);
@@ -1134,7 +1132,7 @@ void __SD_task_really_run(SD_task_t task)
   surf_workstations = xbt_new(void *, workstation_nb);
 
   for (i = 0; i < workstation_nb; i++)
-    surf_workstations[i] = task->workstation_list[i];
+    surf_workstations[i] =  surf_workstation_resource_priv(task->workstation_list[i]);
 
   double *computation_amount = xbt_new0(double, workstation_nb);
   double *communication_amount = xbt_new0(double, workstation_nb * workstation_nb);
@@ -1147,15 +1145,14 @@ void __SD_task_really_run(SD_task_t task)
     memcpy(communication_amount, task->communication_amount,
            sizeof(double) * workstation_nb * workstation_nb);
 
-  task->surf_action =
-        surf_workstation_model->extension.
-        workstation.execute_parallel_task(workstation_nb,
-                                          surf_workstations,
-                                          computation_amount,
-                                          communication_amount,
-                                          task->rate);
+  task->surf_action = surf_workstation_model_execute_parallel_task((surf_workstation_model_t)surf_workstation_model,
+                                                                    workstation_nb,
+                                                                    surf_workstations,
+                                                                    computation_amount,
+                                                                    communication_amount,
+                                                                    task->rate);
 
-  surf_workstation_model->action_data_set(task->surf_action, task);
+  surf_action_set_data(task->surf_action, task);
 
   XBT_DEBUG("surf_action = %p", task->surf_action);
 
@@ -1244,7 +1241,7 @@ void __SD_task_just_done(SD_task_t task)
   candidates = xbt_new(SD_task_t, 8);
 
   __SD_task_set_state(task, SD_DONE);
-  surf_workstation_model->action_unref(task->surf_action);
+  surf_action_unref(task->surf_action);
   task->surf_action = NULL;
 
   XBT_DEBUG("Looking for candidates");
@@ -1402,8 +1399,7 @@ static void __SD_task_remove_dependencies(SD_task_t task)
 double SD_task_get_start_time(SD_task_t task)
 {
   if (task->surf_action)
-    return surf_workstation_model->
-        action_get_start_time(task->surf_action);
+    return surf_action_get_start_time(task->surf_action);
   else
     return task->start_time;
 }
@@ -1422,8 +1418,7 @@ double SD_task_get_start_time(SD_task_t task)
 double SD_task_get_finish_time(SD_task_t task)
 {
   if (task->surf_action)        /* should never happen as actions are destroyed right after their completion */
-    return surf_workstation_model->
-        action_get_finish_time(task->surf_action);
+    return surf_action_get_finish_time(task->surf_action);
   else
     return task->finish_time;
 }
index 14a0c70..f868b59 100644 (file)
@@ -12,8 +12,6 @@
 #include "surf/surf.h"
 #include "surf/surf_resource.h"
 
-
-
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sd_workstation, sd,
                                 "Logging specific to SimDag (workstation)");
 
@@ -178,8 +176,7 @@ const char *SD_workstation_get_property_value(SD_workstation_t ws,
  */
 xbt_dict_t SD_workstation_get_properties(SD_workstation_t workstation)
 {
-  return surf_workstation_model->extension.
-      workstation.get_properties(surf_workstation_resource_priv(workstation));
+  return surf_resource_get_properties(surf_workstation_resource_priv(workstation));
 }
 
 
@@ -247,9 +244,9 @@ const SD_link_t *SD_route_get_list(SD_workstation_t src,
 
   surf_src = src;
   surf_dst = dst;
-  surf_route =
-      surf_workstation_model->extension.workstation.get_route(surf_src,
-                                                              surf_dst);
+
+  surf_route = surf_workstation_model_get_route((surf_workstation_model_t)surf_workstation_model,
+                                                       surf_src, surf_dst);
 
   xbt_dynar_foreach(surf_route, cpt, surf_link) {
     link_name = surf_resource_name(surf_link);
@@ -269,8 +266,8 @@ const SD_link_t *SD_route_get_list(SD_workstation_t src,
  */
 int SD_route_get_size(SD_workstation_t src, SD_workstation_t dst)
 {
-  return xbt_dynar_length(surf_workstation_model->extension.
-                          workstation.get_route(src, dst));
+  return xbt_dynar_length(surf_workstation_model_get_route(
+                   (surf_workstation_model_t)surf_workstation_model, src, dst));
 }
 
 /**
@@ -282,8 +279,7 @@ int SD_route_get_size(SD_workstation_t src, SD_workstation_t dst)
  */
 double SD_workstation_get_power(SD_workstation_t workstation)
 {
-  return surf_workstation_model->extension.workstation.
-      get_speed(workstation, 1.0);
+  return surf_workstation_get_speed(workstation, 1.0);
 }
 
 /**
@@ -295,8 +291,7 @@ double SD_workstation_get_power(SD_workstation_t workstation)
  */
 double SD_workstation_get_available_power(SD_workstation_t workstation)
 {
-  return surf_workstation_model->extension.
-      workstation.get_available_speed(workstation);
+  return surf_workstation_get_available_speed(workstation);
 }
 
 /**
@@ -482,7 +477,7 @@ void SD_workstation_set_access_mode(SD_workstation_t workstation,
  * \return a dynar containing all mounted storages on the workstation
  */
 xbt_dict_t SD_workstation_get_storage_list(SD_workstation_t workstation){
-  return surf_workstation_model->extension.workstation.get_storage_list(workstation);
+  return surf_workstation_get_storage_list(workstation);
 }
 
 /* Returns whether a task can start now on a workstation*/
index 5b8a406..e2a11b9 100644 (file)
@@ -447,22 +447,6 @@ void sg_config_init(int *argc, char **argv)
                      xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
     xbt_cfg_setdefault_string(_sg_cfg_set, "storage/model", "default");
 
-    /* ********************************************************************* */
-    /* TUTORIAL: New model                                                   */
-    sprintf(description,
-            "The model to use for the New model. Possible values: ");
-    p = description;
-    while (*(++p) != '\0');
-    for (i = 0; surf_new_model_description[i].name; i++)
-      p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
-                   surf_new_model_description[i].name);
-    sprintf(p,
-            ".\n       (use 'help' as a value to see the long description of each model)");
-    xbt_cfg_register(&_sg_cfg_set, "new_model/model", description,
-                     xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__storage_mode, NULL);
-    xbt_cfg_setdefault_string(_sg_cfg_set, "new_model/model", "default");
-    /* ********************************************************************* */
-
     sprintf(description,
             "The model to use for the network. Possible values: ");
     p = description;
@@ -890,15 +874,6 @@ void surf_config_models_setup()
   storage_id = find_model_description(surf_storage_model_description, storage_model_name);
   surf_storage_model_description[storage_id].model_init_preparse();
 
-  /* ********************************************************************* */
-  /* TUTORIAL: New model                                                   */
-  int new_model_id = -1;
-  char *new_model_name = NULL;
-  new_model_name = xbt_cfg_get_string(_sg_cfg_set, "new_model/model");
-  XBT_DEBUG("Call new model_init");
-  new_model_id = find_model_description(surf_new_model_description, new_model_name);
-  surf_new_model_description[new_model_id].model_init_preparse();
-  /* ********************************************************************* */
 }
 
 int sg_cfg_get_int(const char* name)
index 48127cb..4a6c7ac 100644 (file)
@@ -324,14 +324,15 @@ void SIMIX_run(void)
          ((void (*)(void*))timer->func)(timer->args);
        xbt_free(timer);
     }
+
     /* Wake up all processes waiting for a Surf action to finish */
     xbt_dynar_foreach(model_list, iter, model) {
-      set = model->states.failed_action_set;
+      set = surf_model_failed_action_set(model);
       while ((action = xbt_swag_extract(set)))
-        SIMIX_simcall_post((smx_action_t) action->data);
-      set = model->states.done_action_set;
+        SIMIX_simcall_post((smx_action_t) surf_action_get_data(action));
+      set = surf_model_done_action_set(model);
       while ((action = xbt_swag_extract(set)))
-        SIMIX_simcall_post((smx_action_t) action->data);
+        SIMIX_simcall_post((smx_action_t) surf_action_get_data(action));
     }
 
     /* Autorestart all process */
index 2480bbd..df02f0f 100644 (file)
@@ -135,7 +135,7 @@ xbt_dict_t SIMIX_pre_host_get_properties(smx_simcall_t simcall, smx_host_t host)
 xbt_dict_t SIMIX_host_get_properties(smx_host_t host){
   xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
 
-  return surf_workstation_model->extension.workstation.get_properties(host);
+  return surf_resource_get_properties(surf_workstation_resource_priv(host));
 }
 
 double SIMIX_pre_host_get_speed(smx_simcall_t simcall, smx_host_t host){
@@ -143,9 +143,7 @@ double SIMIX_pre_host_get_speed(smx_simcall_t simcall, smx_host_t host){
 }
 double SIMIX_host_get_speed(smx_host_t host){
   xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
-
-  return surf_workstation_model->extension.workstation.
-      get_speed(host, 1.0);
+  return surf_workstation_get_speed(host, 1.0);
 }
 
 int SIMIX_pre_host_get_core(smx_simcall_t simcall, smx_host_t host){
@@ -154,8 +152,7 @@ int SIMIX_pre_host_get_core(smx_simcall_t simcall, smx_host_t host){
 int SIMIX_host_get_core(smx_host_t host){
   xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
 
-  return surf_workstation_model->extension.workstation.
-      get_core(host);
+  return surf_workstation_get_core(host);
 }
 
 xbt_swag_t SIMIX_pre_host_get_process_list(smx_simcall_t simcall, smx_host_t host){
@@ -176,8 +173,7 @@ double SIMIX_pre_host_get_available_speed(smx_simcall_t simcall, smx_host_t host
 double SIMIX_host_get_available_speed(smx_host_t host){
   xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
 
-  return surf_workstation_model->extension.workstation.
-      get_available_speed(host);
+  return surf_workstation_get_available_speed(host);
 }
 
 double SIMIX_pre_host_get_current_power_peak(smx_simcall_t simcall, smx_host_t host){
@@ -185,8 +181,7 @@ double SIMIX_pre_host_get_current_power_peak(smx_simcall_t simcall, smx_host_t h
 }
 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);
+         return surf_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){
@@ -195,8 +190,7 @@ double SIMIX_pre_host_get_power_peak_at(smx_simcall_t simcall, smx_host_t host,
 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);
+         return surf_workstation_get_power_peak_at(host, pstate_index);
 }
 
 int SIMIX_pre_host_get_nb_pstates(smx_simcall_t simcall, smx_host_t host){
@@ -205,8 +199,7 @@ int SIMIX_pre_host_get_nb_pstates(smx_simcall_t simcall, smx_host_t 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);
+         return surf_workstation_get_nb_pstates(host);
 }
 
 
@@ -216,8 +209,7 @@ void SIMIX_pre_host_set_power_peak_at(smx_simcall_t simcall, smx_host_t host, in
 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);
+         surf_workstation_set_power_peak_at(host, pstate_index);
 }
 
 double SIMIX_pre_host_get_consumed_energy(smx_simcall_t simcall, smx_host_t host){
@@ -225,8 +217,7 @@ double SIMIX_pre_host_get_consumed_energy(smx_simcall_t simcall, smx_host_t 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);
+         return surf_workstation_get_consumed_energy(host);
 }
 
 int SIMIX_pre_host_get_state(smx_simcall_t simcall, smx_host_t host){
@@ -235,8 +226,7 @@ int SIMIX_pre_host_get_state(smx_simcall_t simcall, smx_host_t host){
 int SIMIX_host_get_state(smx_host_t host){
   xbt_assert((host != NULL), "Invalid parameters (simix host is NULL)");
 
-  return surf_workstation_model->extension.workstation.
-      get_state(host);
+  return surf_resource_get_state(surf_workstation_resource_priv(host));
 }
 
 void* SIMIX_pre_host_self_get_data(smx_simcall_t simcall){
@@ -407,10 +397,9 @@ smx_action_t SIMIX_host_execute(const char *name,
   /* set surf's action */
   if (!MC_is_active()) {
     action->execution.surf_exec =
-      surf_workstation_model->extension.workstation.execute(host,
-    computation_amount);
-    surf_workstation_model->action_data_set(action->execution.surf_exec, action);
-    surf_workstation_model->set_priority(action->execution.surf_exec, priority);
+      surf_workstation_execute(host, computation_amount);
+    surf_action_set_data(action->execution.surf_exec, action);
+    surf_action_set_priority(action->execution.surf_exec, priority);
   }
 
   XBT_DEBUG("Create execute action %p", action);
@@ -447,16 +436,15 @@ smx_action_t SIMIX_host_parallel_execute(const char *name,
   /* set surf's action */
   workstation_list = xbt_new0(void *, host_nb);
   for (i = 0; i < host_nb; i++)
-    workstation_list[i] = host_list[i];
+    workstation_list[i] = surf_workstation_resource_priv(host_list[i]);
 
   /* set surf's action */
   if (!MC_is_active()) {
     action->execution.surf_exec =
-      surf_workstation_model->extension.workstation.
-      execute_parallel_task(host_nb, workstation_list, computation_amount,
-                      communication_amount, rate);
+      surf_workstation_model_execute_parallel_task((surf_workstation_model_t)surf_workstation_model,
+                 host_nb, workstation_list, computation_amount, communication_amount, rate);
 
-    surf_workstation_model->action_data_set(action->execution.surf_exec, action);
+    surf_action_set_data(action->execution.surf_exec, action);
   }
   XBT_DEBUG("Create parallel execute action %p", action);
 
@@ -470,7 +458,7 @@ void SIMIX_host_execution_destroy(smx_action_t action){
   XBT_DEBUG("Destroy action %p", action);
 
   if (action->execution.surf_exec) {
-    surf_workstation_model->action_unref(action->execution.surf_exec);
+    surf_action_unref(action->execution.surf_exec);
     action->execution.surf_exec = NULL;
   }
   xbt_free(action->name);
@@ -484,7 +472,7 @@ void SIMIX_host_execution_cancel(smx_action_t action){
   XBT_DEBUG("Cancel action %p", action);
 
   if (action->execution.surf_exec)
-    surf_workstation_model->action_cancel(action->execution.surf_exec);
+    surf_action_cancel(action->execution.surf_exec);
 }
 
 double SIMIX_pre_host_execution_get_remains(smx_simcall_t simcall, smx_action_t action){
@@ -494,7 +482,7 @@ double SIMIX_host_execution_get_remains(smx_action_t action){
   double result = 0.0;
 
   if (action->state == SIMIX_RUNNING)
-    result = surf_workstation_model->get_remains(action->execution.surf_exec);
+    result = surf_action_get_remains(action->execution.surf_exec);
 
   return result;
 }
@@ -512,7 +500,7 @@ void SIMIX_pre_host_execution_set_priority(smx_simcall_t simcall, smx_action_t a
 }
 void SIMIX_host_execution_set_priority(smx_action_t action, double priority){
   if(action->execution.surf_exec)
-    surf_workstation_model->set_priority(action->execution.surf_exec, priority);
+       surf_action_set_priority(action->execution.surf_exec, priority);
 }
 
 void SIMIX_pre_host_execution_wait(smx_simcall_t simcall, smx_action_t action){
@@ -538,13 +526,13 @@ void SIMIX_pre_host_execution_wait(smx_simcall_t simcall, smx_action_t action){
 void SIMIX_host_execution_suspend(smx_action_t action)
 {
   if(action->execution.surf_exec)
-    surf_workstation_model->suspend(action->execution.surf_exec);
+    surf_action_suspend(action->execution.surf_exec);
 }
 
 void SIMIX_host_execution_resume(smx_action_t action)
 {
   if(action->execution.surf_exec)
-    surf_workstation_model->resume(action->execution.surf_exec);
+    surf_action_resume(action->execution.surf_exec);
 }
 
 void SIMIX_execution_finish(smx_action_t action)
@@ -577,8 +565,8 @@ void SIMIX_execution_finish(smx_action_t action)
             (int)action->state);
     }
     /* check if the host is down */
-    if (surf_workstation_model->extension.
-        workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+
+    if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
       simcall->issuer->context->iwannadie = 1;
     }
 
@@ -595,11 +583,11 @@ void SIMIX_post_host_execute(smx_action_t action)
 {
   if (action->type == SIMIX_ACTION_EXECUTE && /* FIMXE: handle resource failure
                                                * for parallel tasks too */
-      surf_workstation_model->extension.workstation.get_state(action->execution.host) == SURF_RESOURCE_OFF) {
+      surf_resource_get_state(surf_workstation_resource_priv(action->execution.host)) == SURF_RESOURCE_OFF) {
     /* If the host running the action failed, notice it so that the asking
      * process can be killed if it runs on that host itself */
     action->state = SIMIX_FAILED;
-  } else if (surf_workstation_model->action_state_get(action->execution.surf_exec) == SURF_ACTION_FAILED) {
+  } else if (surf_action_get_state(action->execution.surf_exec) == SURF_ACTION_FAILED) {
     /* If the host running the action didn't fail, then the action was
      * canceled */
     action->state = SIMIX_CANCELED;
@@ -608,7 +596,7 @@ void SIMIX_post_host_execute(smx_action_t action)
   }
 
   if (action->execution.surf_exec) {
-    surf_workstation_model->action_unref(action->execution.surf_exec);
+    surf_action_unref(action->execution.surf_exec);
     action->execution.surf_exec = NULL;
   }
 
@@ -628,9 +616,9 @@ void SIMIX_set_category(smx_action_t action, const char *category)
 {
   if (action->state != SIMIX_RUNNING) return;
   if (action->type == SIMIX_ACTION_EXECUTE){
-    surf_workstation_model->set_category(action->execution.surf_exec, category);
+    surf_action_set_category(action->execution.surf_exec, category);
   }else if (action->type == SIMIX_ACTION_COMMUNICATE){
-    surf_workstation_model->set_category(action->comm.surf_comm, category);
+    surf_action_set_category(action->comm.surf_comm, category);
   }
 }
 #endif
@@ -641,5 +629,5 @@ xbt_dict_t SIMIX_pre_host_get_storage_list(smx_simcall_t simcall, smx_host_t hos
 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);
+  return surf_workstation_get_storage_list(host);
 }
index f91d19d..d89e927 100644 (file)
@@ -18,10 +18,12 @@ typedef struct s_smx_host_priv {
 } s_smx_host_priv_t;
 
 static inline smx_host_priv_t SIMIX_host_priv(smx_host_t host){
-  return xbt_lib_get_level(host, SIMIX_HOST_LEVEL);
+  return (smx_host_priv_t) xbt_lib_get_level(host, SIMIX_HOST_LEVEL);
 }
 
-
+#ifdef __cplusplus
+extern "C" {
+#endif
 smx_host_t SIMIX_host_create(const char *name, void *workstation, void *data);
 void SIMIX_host_destroy(void *host);
 
@@ -100,5 +102,9 @@ void SIMIX_pre_set_category(smx_simcall_t simcall, smx_action_t action,
 void SIMIX_set_category(smx_action_t action, const char *category);
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
 
index 07a354c..f177592 100644 (file)
@@ -5,7 +5,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "smx_private.h"
-#include "surf/storage_private.h"
+//#include "surf/storage_private.h"
 #include "xbt/sysdep.h"
 #include "xbt/log.h"
 #include "xbt/dict.h"
@@ -84,8 +84,7 @@ smx_action_t SIMIX_file_read(smx_process_t process, smx_file_t fd, sg_storage_si
   smx_host_t host = process->smx_host;
 
   /* check if the host is active */
-  if (surf_workstation_model->extension.
-      workstation.get_state(host) != SURF_RESOURCE_ON) {
+  if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
            sg_host_name(host));
   }
@@ -98,10 +97,9 @@ smx_action_t SIMIX_file_read(smx_process_t process, smx_file_t fd, sg_storage_si
 #endif
 
   action->io.host = host;
-  action->io.surf_io =
-      surf_workstation_model->extension.workstation.read(host, fd->surf_file, size);
+  action->io.surf_io = surf_workstation_read(host, fd->surf_file, size);
 
-  surf_workstation_model->action_data_set(action->io.surf_io, action);
+  surf_action_set_data(action->io.surf_io, action);
   XBT_DEBUG("Create io action %p", action);
 
   return action;
@@ -121,8 +119,7 @@ smx_action_t SIMIX_file_write(smx_process_t process, smx_file_t fd, sg_storage_s
   smx_host_t host = process->smx_host;
 
   /* check if the host is active */
-  if (surf_workstation_model->extension.
-      workstation.get_state(host) != SURF_RESOURCE_ON) {
+  if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
            sg_host_name(host));
   }
@@ -135,10 +132,9 @@ smx_action_t SIMIX_file_write(smx_process_t process, smx_file_t fd, sg_storage_s
 #endif
 
   action->io.host = host;
-  action->io.surf_io =
-      surf_workstation_model->extension.workstation.write(host, fd->surf_file, size);
+  action->io.surf_io = surf_workstation_write(host, fd->surf_file, size);
 
-  surf_workstation_model->action_data_set(action->io.surf_io, action);
+  surf_action_set_data(action->io.surf_io, action);
   XBT_DEBUG("Create io action %p", action);
 
   return action;
@@ -160,8 +156,7 @@ smx_action_t SIMIX_file_open(smx_process_t process ,const char* mount,
   smx_host_t host = process->smx_host;
 
   /* check if the host is active */
-  if (surf_workstation_model->extension.
-      workstation.get_state(host) != SURF_RESOURCE_ON) {
+  if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
            sg_host_name(host));
   }
@@ -174,10 +169,9 @@ smx_action_t SIMIX_file_open(smx_process_t process ,const char* mount,
 #endif
 
   action->io.host = host;
-  action->io.surf_io =
-      surf_workstation_model->extension.workstation.open(host, mount, path);
+  action->io.surf_io = surf_workstation_open(host, mount, path);
 
-  surf_workstation_model->action_data_set(action->io.surf_io, action);
+  surf_action_set_data(action->io.surf_io, action);
   XBT_DEBUG("Create io action %p", action);
 
   return action;
@@ -197,8 +191,7 @@ smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fd)
   smx_host_t host = process->smx_host;
 
   /* check if the host is active */
-  if (surf_workstation_model->extension.
-      workstation.get_state(host) != SURF_RESOURCE_ON) {
+  if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
            sg_host_name(host));
   }
@@ -211,9 +204,9 @@ smx_action_t SIMIX_file_close(smx_process_t process, smx_file_t fd)
 #endif
 
   action->io.host = host;
-  action->io.surf_io = surf_workstation_model->extension.workstation.close(host, fd->surf_file);
+  action->io.surf_io = surf_workstation_close(host, fd->surf_file);
 
-  surf_workstation_model->action_data_set(action->io.surf_io, action);
+  surf_action_set_data(action->io.surf_io, action);
   XBT_DEBUG("Create io action %p", action);
 
   return action;
@@ -230,13 +223,12 @@ int SIMIX_file_unlink(smx_process_t process, smx_file_t fd)
 {
   smx_host_t host = process->smx_host;
   /* check if the host is active */
-  if (surf_workstation_model->extension.
-      workstation.get_state(host) != SURF_RESOURCE_ON) {
+  if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
            sg_host_name(host));
   }
 
-  if (surf_workstation_model->extension.workstation.unlink(host, fd->surf_file)){
+  if (surf_workstation_unlink(host, fd->surf_file)){
     xbt_free(fd);
     return 1;
   } else
@@ -256,7 +248,7 @@ smx_action_t SIMIX_file_ls(smx_process_t process, const char* mount, const char
   smx_action_t action;
   smx_host_t host = process->smx_host;
   /* check if the host is active */
-  if (surf_workstation_model->extension.workstation.get_state(host) != SURF_RESOURCE_ON) {
+  if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
            sg_host_name(host));
   }
@@ -269,9 +261,9 @@ smx_action_t SIMIX_file_ls(smx_process_t process, const char* mount, const char
 #endif
 
   action->io.host = host;
-  action->io.surf_io = surf_workstation_model->extension.workstation.ls(host,mount,path);
+  action->io.surf_io = surf_workstation_ls(host,mount,path);
 
-  surf_workstation_model->action_data_set(action->io.surf_io, action);
+  surf_action_set_data(action->io.surf_io, action);
   XBT_DEBUG("Create io action %p", action);
   return action;
 }
@@ -284,8 +276,7 @@ sg_storage_size_t SIMIX_pre_file_get_size(smx_simcall_t simcall, smx_file_t fd)
 sg_storage_size_t SIMIX_file_get_size(smx_process_t process, smx_file_t fd)
 {
   smx_host_t host = process->smx_host;
-  return  surf_workstation_model->extension.workstation.get_size(host,
-      fd->surf_file);
+  return  surf_workstation_get_size(host, fd->surf_file);
 }
 
 xbt_dynar_t SIMIX_pre_file_get_info(smx_simcall_t simcall, smx_file_t fd)
@@ -296,8 +287,7 @@ xbt_dynar_t SIMIX_pre_file_get_info(smx_simcall_t simcall, smx_file_t fd)
 xbt_dynar_t SIMIX_file_get_info(smx_process_t process, smx_file_t fd)
 {
   smx_host_t host = process->smx_host;
-  return  surf_workstation_model->extension.workstation.get_info(host,
-      fd->surf_file);
+  return  surf_workstation_get_info(host, fd->surf_file);
 }
 
 sg_storage_size_t SIMIX_pre_storage_get_free_size(smx_simcall_t simcall, const char* name)
@@ -308,7 +298,7 @@ sg_storage_size_t SIMIX_pre_storage_get_free_size(smx_simcall_t simcall, const c
 sg_storage_size_t SIMIX_storage_get_free_size(smx_process_t process, const char* name)
 {
   smx_host_t host = process->smx_host;
-  return  surf_workstation_model->extension.workstation.get_free_size(host,name);
+  return  surf_workstation_get_free_size(host, name);
 }
 
 sg_storage_size_t SIMIX_pre_storage_get_used_size(smx_simcall_t simcall, const char* name)
@@ -319,7 +309,7 @@ sg_storage_size_t SIMIX_pre_storage_get_used_size(smx_simcall_t simcall, const c
 sg_storage_size_t SIMIX_storage_get_used_size(smx_process_t process, const char* name)
 {
   smx_host_t host = process->smx_host;
-  return  surf_workstation_model->extension.workstation.get_used_size(host,name);
+  return  surf_workstation_get_used_size(host, name);
 }
 
 xbt_dict_t SIMIX_pre_storage_get_properties(smx_simcall_t simcall, smx_storage_t storage){
@@ -327,7 +317,7 @@ xbt_dict_t SIMIX_pre_storage_get_properties(smx_simcall_t simcall, smx_storage_t
 }
 xbt_dict_t SIMIX_storage_get_properties(smx_storage_t storage){
   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
-  return surf_storage_model->extension.storage.get_properties(storage);
+  return surf_resource_get_properties(surf_workstation_resource_priv(storage));
 }
 
 const char* SIMIX_pre_storage_get_name(smx_simcall_t simcall, smx_storage_t storage){
@@ -365,12 +355,12 @@ xbt_dict_t SIMIX_pre_storage_get_content(smx_simcall_t simcall, smx_storage_t st
 
 xbt_dict_t SIMIX_storage_get_content(smx_storage_t storage){
   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
-  return surf_storage_model->extension.storage.get_content(storage);
+  return surf_storage_get_content(storage);
 }
 
 sg_storage_size_t SIMIX_storage_get_size(smx_storage_t storage){
   xbt_assert((storage != NULL), "Invalid parameters (simix storage is NULL)");
-  return surf_storage_model->extension.storage.get_size(storage);
+  return surf_storage_get_size(storage);
 }
 
 void SIMIX_post_io(smx_action_t action)
@@ -386,7 +376,7 @@ void SIMIX_post_io(smx_action_t action)
     switch (simcall->call) {
     case SIMCALL_FILE_OPEN:;
       smx_file_t tmp = xbt_new(s_smx_file_t,1);
-      tmp->surf_file = (action->io.surf_io)->file;
+      tmp->surf_file = surf_storage_action_get_file(action->io.surf_io);
       simcall_file_open__set__result(simcall, tmp);
       break;
 
@@ -394,13 +384,12 @@ void SIMIX_post_io(smx_action_t action)
       xbt_free(simcall_file_close__get__fd(simcall));
       simcall_file_close__set__result(simcall, 0);
       break;
-
     case SIMCALL_FILE_WRITE:
-      simcall_file_write__set__result(simcall, (action->io.surf_io)->cost);
+      simcall_file_write__set__result(simcall, surf_action_get_cost(action->io.surf_io));
       break;
 
     case SIMCALL_FILE_READ:
-      simcall_file_read__set__result(simcall, (action->io.surf_io)->cost);
+      simcall_file_read__set__result(simcall, surf_action_get_cost(action->io.surf_io));
       break;
 
     case SIMCALL_FILE_LS:
@@ -412,14 +401,14 @@ void SIMIX_post_io(smx_action_t action)
 //          xbt_dict_set((action->io.surf_io)->ls_dict,key,dst,xbt_free);
 //        }
 //      }
-      simcall_file_ls__set__result(simcall, (action->io.surf_io)->ls_dict);
+      simcall_file_ls__set__result(simcall, surf_storage_action_get_ls_dict(action->io.surf_io));
       break;
     default:
       break;
     }
   }
 
-  switch (surf_workstation_model->action_state_get(action->io.surf_io)) {
+  switch (surf_action_get_state(action->io.surf_io)) {
 
     case SURF_ACTION_FAILED:
       action->state = SIMIX_FAILED;
@@ -441,7 +430,7 @@ void SIMIX_io_destroy(smx_action_t action)
 {
   XBT_DEBUG("Destroy action %p", action);
   if (action->io.surf_io)
-    action->io.surf_io->model_type->action_unref(action->io.surf_io);
+    surf_action_unref(action->io.surf_io);
   xbt_mallocator_release(simix_global->action_mallocator, action);
 }
 
@@ -471,8 +460,7 @@ void SIMIX_io_finish(smx_action_t action)
             (int)action->state);
     }
 
-    if (surf_workstation_model->extension.
-        workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+    if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
       simcall->issuer->context->iwannadie = 1;
     }
 
index 0cb33eb..5e849a6 100644 (file)
@@ -340,17 +340,17 @@ void SIMIX_comm_destroy_internal_actions(smx_action_t action)
 #ifdef HAVE_LATENCY_BOUND_TRACKING
     action->latency_limited = SIMIX_comm_is_latency_bounded(action);
 #endif
-    action->comm.surf_comm->model_type->action_unref(action->comm.surf_comm);
+    surf_action_unref(action->comm.surf_comm);
     action->comm.surf_comm = NULL;
   }
 
   if (action->comm.src_timeout){
-    action->comm.src_timeout->model_type->action_unref(action->comm.src_timeout);
+    surf_action_unref(action->comm.src_timeout);
     action->comm.src_timeout = NULL;
   }
 
   if (action->comm.dst_timeout){
-    action->comm.dst_timeout->model_type->action_unref(action->comm.dst_timeout);
+    surf_action_unref(action->comm.dst_timeout);
     action->comm.dst_timeout = NULL;
   }
 }
@@ -729,8 +729,8 @@ void SIMIX_pre_comm_wait(smx_simcall_t simcall, smx_action_t action, double time
   if (action->state != SIMIX_WAITING && action->state != SIMIX_RUNNING) {
     SIMIX_comm_finish(action);
   } else { /* if (timeout >= 0) { we need a surf sleep action even when there is no timeout, otherwise surf won't tell us when the host fails */
-    sleep = surf_workstation_model->extension.workstation.sleep(simcall->issuer->smx_host, timeout);
-    surf_workstation_model->action_data_set(sleep, action);
+    sleep = surf_workstation_sleep(simcall->issuer->smx_host, timeout);
+    surf_action_set_data(sleep, action);
 
     if (simcall->issuer == action->comm.src_proc)
       action->comm.src_timeout = sleep;
@@ -846,15 +846,16 @@ XBT_INLINE void SIMIX_comm_start(smx_action_t action)
     XBT_DEBUG("Starting communication %p from '%s' to '%s'", action,
               SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
 
-    action->comm.surf_comm = surf_workstation_model->extension.workstation.
-      communicate(sender, receiver, action->comm.task_size, action->comm.rate);
+    action->comm.surf_comm = surf_workstation_model_communicate(surf_workstation_model,
+                                                                   sender, receiver,
+                                                                   action->comm.task_size, action->comm.rate);
 
-    surf_workstation_model->action_data_set(action->comm.surf_comm, action);
+    surf_action_set_data(action->comm.surf_comm, action);
 
     action->state = SIMIX_RUNNING;
 
     /* If a link is failed, detect it immediately */
-    if (surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+    if (surf_action_get_state(action->comm.surf_comm) == SURF_ACTION_FAILED) {
       XBT_DEBUG("Communication from '%s' to '%s' failed to start because of a link failure",
                 SIMIX_host_get_name(sender), SIMIX_host_get_name(receiver));
       action->state = SIMIX_LINK_FAILURE;
@@ -874,7 +875,7 @@ XBT_INLINE void SIMIX_comm_start(smx_action_t action)
         XBT_DEBUG("The communication is suspended on startup because dst (%s:%s) were suspended since it initiated the communication",
                   SIMIX_host_get_name(action->comm.dst_proc->smx_host), action->comm.dst_proc->name);
 
-      surf_workstation_model->suspend(action->comm.surf_comm);
+      surf_action_suspend(action->comm.surf_comm);
 
     }
   }
@@ -980,8 +981,7 @@ void SIMIX_comm_finish(smx_action_t action)
       }
     }
 
-    if (surf_workstation_model->extension.
-        workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+    if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
       simcall->issuer->context->iwannadie = 1;
     }
 
@@ -1013,19 +1013,19 @@ void SIMIX_post_comm(smx_action_t action)
 {
   /* Update action state */
   if (action->comm.src_timeout &&
-      surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_DONE)
+      surf_action_get_state(action->comm.src_timeout) == SURF_ACTION_DONE)
     action->state = SIMIX_SRC_TIMEOUT;
   else if (action->comm.dst_timeout &&
-           surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_DONE)
+         surf_action_get_state(action->comm.dst_timeout) == SURF_ACTION_DONE)
     action->state = SIMIX_DST_TIMEOUT;
   else if (action->comm.src_timeout &&
-           surf_workstation_model->action_state_get(action->comm.src_timeout) == SURF_ACTION_FAILED)
+         surf_action_get_state(action->comm.src_timeout) == SURF_ACTION_FAILED)
     action->state = SIMIX_SRC_HOST_FAILURE;
   else if (action->comm.dst_timeout &&
-           surf_workstation_model->action_state_get(action->comm.dst_timeout) == SURF_ACTION_FAILED)
+      surf_action_get_state(action->comm.dst_timeout) == SURF_ACTION_FAILED)
     action->state = SIMIX_DST_HOST_FAILURE;
   else if (action->comm.surf_comm &&
-           surf_workstation_model->action_state_get(action->comm.surf_comm) == SURF_ACTION_FAILED) {
+         surf_action_get_state(action->comm.surf_comm) == SURF_ACTION_FAILED) {
     XBT_DEBUG("Puta madre. Surf says that the link broke");
     action->state = SIMIX_LINK_FAILURE;
   } else
@@ -1066,7 +1066,7 @@ void SIMIX_comm_cancel(smx_action_t action)
   else if (!MC_is_active() /* when running the MC there are no surf actions */
            && (action->state == SIMIX_READY || action->state == SIMIX_RUNNING)) {
 
-    surf_workstation_model->action_cancel(action->comm.surf_comm);
+    surf_action_cancel(action->comm.surf_comm);
   }
 }
 
@@ -1074,7 +1074,7 @@ void SIMIX_comm_suspend(smx_action_t action)
 {
   /*FIXME: shall we suspend also the timeout actions? */
   if (action->comm.surf_comm)
-    surf_workstation_model->suspend(action->comm.surf_comm);
+    surf_action_suspend(action->comm.surf_comm);
   /* in the other case, the action will be suspended on creation, in SIMIX_comm_start() */
 }
 
@@ -1082,7 +1082,7 @@ void SIMIX_comm_resume(smx_action_t action)
 {
   /*FIXME: check what happen with the timeouts */
   if (action->comm.surf_comm)
-    surf_workstation_model->resume(action->comm.surf_comm);
+    surf_action_resume(action->comm.surf_comm);
   /* in the other case, the action were not really suspended yet, see SIMIX_comm_suspend() and SIMIX_comm_start() */
 }
 
@@ -1107,7 +1107,7 @@ double SIMIX_comm_get_remains(smx_action_t action)
   switch (action->state) {
 
   case SIMIX_RUNNING:
-    remains = surf_workstation_model->get_remains(action->comm.surf_comm);
+    remains = surf_action_get_remains(action->comm.surf_comm);
     break;
 
   case SIMIX_WAITING:
index eb0a9f1..01c3b5a 100644 (file)
@@ -43,7 +43,7 @@ void SIMIX_post_new_api(smx_action_t action)
     }
   }
 
-  switch (surf_workstation_model->action_state_get(action->new_api.surf_new_api)) {
+  switch (surf_action_get_state(action->new_api.surf_new_api)) {
 
     case SURF_ACTION_FAILED:
       action->state = SIMIX_FAILED;
@@ -67,8 +67,7 @@ smx_action_t SIMIX_new_api_fct(smx_process_t process, const char* param1, double
   smx_host_t host = process->smx_host;
 
   /* check if the host is active */
-  if (surf_workstation_model->extension.
-      workstation.get_state(host) != SURF_RESOURCE_ON) {
+  if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
            sg_host_name(host));
   }
@@ -81,9 +80,9 @@ smx_action_t SIMIX_new_api_fct(smx_process_t process, const char* param1, double
 #endif
 
   // Called the function from the new model
-  action->new_api.surf_new_api = surf_workstation_model->extension.new_model.fct();
+  //FIXME:CHECK WHAT TO DO action->new_api.surf_new_api = surf_workstation_model->extension.new_model.fct();
 
-  surf_workstation_model->action_data_set(action->new_api.surf_new_api, action);
+  surf_action_set_data(action->new_api.surf_new_api, action);
   XBT_DEBUG("Create NEW MODEL action %p", action);
 
   return action;
@@ -93,7 +92,7 @@ void SIMIX_new_api_destroy(smx_action_t action)
 {
   XBT_DEBUG("Destroy action %p", action);
   if (action->new_api.surf_new_api)
-    action->new_api.surf_new_api->model_type->action_unref(action->new_api.surf_new_api);
+    surf_action_unref(action->new_api.surf_new_api);
   xbt_mallocator_release(simix_global->action_mallocator, action);
 }
 
@@ -123,8 +122,7 @@ void SIMIX_new_api_finish(smx_action_t action)
             (int)action->state);
     }
 
-    if (surf_workstation_model->extension.
-        workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+    if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
       simcall->issuer->context->iwannadie = 1;
     }
 
index bc5c087..29e3217 100644 (file)
@@ -695,8 +695,7 @@ smx_action_t SIMIX_process_sleep(smx_process_t process, double duration)
   smx_host_t host = process->smx_host;
 
   /* check if the host is active */
-  if (surf_workstation_model->extension.
-      workstation.get_state(host) != SURF_RESOURCE_ON) {
+  if (surf_resource_get_state(surf_workstation_resource_priv(host)) != SURF_RESOURCE_ON) {
     THROWF(host_error, 0, "Host %s failed, you cannot call this function",
            sg_host_name(host));
   }
@@ -710,9 +709,9 @@ smx_action_t SIMIX_process_sleep(smx_process_t process, double duration)
 
   action->sleep.host = host;
   action->sleep.surf_sleep =
-      surf_workstation_model->extension.workstation.sleep(host, duration);
+      surf_workstation_sleep(host, duration);
 
-  surf_workstation_model->action_data_set(action->sleep.surf_sleep, action);
+  surf_action_set_data(action->sleep.surf_sleep, action);
   XBT_DEBUG("Create sleep action %p", action);
 
   return action;
@@ -725,7 +724,7 @@ void SIMIX_post_process_sleep(smx_action_t action)
 
   while ((simcall = xbt_fifo_shift(action->simcalls))) {
 
-    switch(surf_workstation_model->action_state_get(action->sleep.surf_sleep)){
+    switch(surf_action_get_state(action->sleep.surf_sleep)){
       case SURF_ACTION_FAILED:
         simcall->issuer->context->iwannadie = 1;
         //SMX_EXCEPTION(simcall->issuer, host_error, 0, "Host failed");
@@ -740,8 +739,7 @@ void SIMIX_post_process_sleep(smx_action_t action)
         THROW_IMPOSSIBLE;
         break;
     }
-    if (surf_workstation_model->extension.
-        workstation.get_state(simcall->issuer->smx_host) != SURF_RESOURCE_ON) {
+    if (surf_resource_get_state(surf_workstation_resource_priv(simcall->issuer->smx_host)) != SURF_RESOURCE_ON) {
       simcall->issuer->context->iwannadie = 1;
     }
     simcall_process_sleep__set__result(simcall, state);
@@ -756,18 +754,18 @@ void SIMIX_process_sleep_destroy(smx_action_t action)
 {
   XBT_DEBUG("Destroy action %p", action);
   if (action->sleep.surf_sleep)
-    action->sleep.surf_sleep->model_type->action_unref(action->sleep.surf_sleep);
+    surf_action_unref(action->sleep.surf_sleep);
   xbt_mallocator_release(simix_global->action_mallocator, action);
 }
 
 void SIMIX_process_sleep_suspend(smx_action_t action)
 {
-  surf_workstation_model->suspend(action->sleep.surf_sleep);
+  surf_action_suspend(action->sleep.surf_sleep);
 }
 
 void SIMIX_process_sleep_resume(smx_action_t action)
 {
-  surf_workstation_model->resume(action->sleep.surf_sleep);
+  surf_action_resume(action->sleep.surf_sleep);
 }
 
 /** 
index 1e191f7..bb33f4d 100644 (file)
 #define TULONG(n) (n, unsigned long, ul)
 #define TFLOAT(n) (n, float, f)
 #define TDOUBLE(n) (n, double, d)
-#define TPTR(n) (n, void*, p)
+#define TDPTR(n) (n, void*, dp, void*)
+#define TFPTR(n) (n, FPtr, fp, FPtr)
 #define TCPTR(n) (n, const void*, cp)
 #define TSIZE(n) (n, size_t, si)
 #define TVOID(n) (n, void)
-#define TSPEC(n,t) (n, t, p)
+#define TDSPEC(n,t) (n, t, dp, void*)
+#define TFSPEC(n,t) (n, t, fp, FPtr)
 
 /* use comma or nothing to separate elements*/
 #define SIMCALL_SEP_COMMA ,
 #define SIMCALL_SEP_NOTHING
 
 /* get the name of the parameter */
-#define SIMCALL_NAME_(name, type, field) name
+#define SIMCALL_NAME_(name, type, field, ...) name
 #define SIMCALL_NAME(i, v) SIMCALL_NAME_ v
 
+/* get the cast of the parameter */
+#define SIMCALL_CASTTYPE_(name, type, field, cast) (cast)
+#define SIMCALL_NOCASTTYPE_(name, type, field) 
+#define SIMCALL_CASTTYPE(...) MAYBE5(,##__VA_ARGS__, SIMCALL_CASTTYPE_, SIMCALL_NOCASTTYPE_) (__VA_ARGS__)
+
+/* get the uncast of the parameter */
+#define SIMCALL_UNCASTTYPE_(name, type, field, cast) (type)
+#define SIMCALL_NOUNCASTTYPE_(name, type, field) 
+#define SIMCALL_UNCASTTYPE(...) MAYBE5(,##__VA_ARGS__, SIMCALL_UNCASTTYPE_, SIMCALL_NOUNCASTTYPE_) (__VA_ARGS__)
+
 /* get the %s format code of the parameter */
-#define SIMCALL_FORMAT_(name, type, field) %field
+#define SIMCALL_FORMAT_(name, type, field, ...) %field
 #define SIMCALL_FORMAT(i, v) SIMCALL_FORMAT_ v
 
 /* get the field of the parameter */
-#define SIMCALL_FIELD_(name, type, field) field
+#define SIMCALL_FIELD_(name, type, field, ...) field
 #define SIMCALL_FIELD(i, v) SIMCALL_FIELD_ v
 
 /* get the parameter declaration */
-#define SIMCALL_ARG_(name, type, field) type name
+#define SIMCALL_ARG_(name, type, field, ...) type name
 #define SIMCALL_ARG(i, v) SIMCALL_ARG_ v
 
 /* get the parameter initialisation field */
-#define SIMCALL_INIT_FIELD_(name, type, field) .field = name
+#define SIMCALL_INIT_FIELD_(name, type, field, ...) .field = SIMCALL_CASTTYPE(name, type, field,##__VA_ARGS__) name
 #define SIMCALL_INIT_FIELD(i, d, v) self->simcall.args[i]SIMCALL_INIT_FIELD_ v;
 
 /* get the case of the parameter */
-#define SIMCALL_CASE_PARAM_(name, type, field) field
-#define SIMCALL_CASE_PARAM(i, v) simcall->args[i].SIMCALL_CASE_PARAM_ v
+#define SIMCALL_CASE_PARAM_(name, type, field, ...) field
+#define SIMCALL_CASE_PARAM(i, v) SIMCALL_UNCASTTYPE v simcall->args[i].SIMCALL_CASE_PARAM_ v
 
 /* generate some code for SIMCALL_CASE if the simcall has an answer */
+#define MAYBE5(_0, _1, _2, _3, _4, func, ...) func
+#define MAYBE3(_0, _1, _2, func, ...) func
 #define MAYBE2(_0, _1, func, ...) func
 
-#define SIMCALL_WITH_RESULT_BEGIN(name, type, field) simcall->result.field =
+#define SIMCALL_WITH_RESULT_BEGIN(name, type, field, ...) simcall->result.field =
 #define SIMCALL_WITHOUT_RESULT_BEGIN(name, type, field)
 #define SIMCALL_RESULT_BEGIN_(name, type, ...)\
-        MAYBE2(,##__VA_ARGS__, SIMCALL_WITH_RESULT_BEGIN, SIMCALL_WITHOUT_RESULT_BEGIN)\
+        MAYBE3(,##__VA_ARGS__, SIMCALL_WITH_RESULT_BEGIN, SIMCALL_WITH_RESULT_BEGIN, SIMCALL_WITHOUT_RESULT_BEGIN)\
        (name, type, __VA_ARGS__)
 #define SIMCALL_RESULT_BEGIN(answer, res) answer(SIMCALL_RESULT_BEGIN_ res)
 
 #define SIMCALL_WITH_FUNC_SIMCALL(name, type, field) smx_simcall_t simcall = 
 #define SIMCALL_WITHOUT_FUNC_SIMCALL(name, type, field)
 #define SIMCALL_FUNC_SIMCALL_(name, type, ...)\
-        MAYBE2(,##__VA_ARGS__, SIMCALL_WITH_FUNC_SIMCALL, SIMCALL_WITHOUT_FUNC_SIMCALL)\
+        MAYBE3(,##__VA_ARGS__, SIMCALL_WITH_FUNC_SIMCALL, SIMCALL_WITH_FUNC_SIMCALL, SIMCALL_WITHOUT_FUNC_SIMCALL)\
        (name, type, __VA_ARGS__)
 #define SIMCALL_FUNC_SIMCALL(res) SIMCALL_FUNC_SIMCALL_ res
 
-#define SIMCALL_WITH_FUNC_RETURN(name, type, field) return self->simcall.result.field;
+#define SIMCALL_WITH_FUNC_RETURN(name, type, field, ...) return self->simcall.result.field;
 #define SIMCALL_WITHOUT_FUNC_RETURN(name, type, field)
 #define SIMCALL_FUNC_RETURN_(name, type, ...)\
-        MAYBE2(,##__VA_ARGS__, SIMCALL_WITH_FUNC_RETURN, SIMCALL_WITHOUT_FUNC_RETURN)\
+        MAYBE3(,##__VA_ARGS__, SIMCALL_WITH_FUNC_RETURN, SIMCALL_WITH_FUNC_RETURN, SIMCALL_WITHOUT_FUNC_RETURN)\
        (name, type, __VA_ARGS__)
 #define SIMCALL_FUNC_RETURN(res) SIMCALL_FUNC_RETURN_ res
 
 /* generate the simcalls args getter/setter */
 #define SIMCALL_ARG_GETSET_(i, name, v) \
   static inline SIMCALL_FUNC_RETURN_TYPE(v) SIMCALL_GS_FUNC(SIMCALL_GS_SC_NAME(name), get, SIMCALL_GS_ARG_NAME(v))(smx_simcall_t simcall){\
-    return simcall->args[i].SIMCALL_FIELD_ v ;\
+    return (SIMCALL_FUNC_RETURN_TYPE(v)) simcall->args[i].SIMCALL_FIELD_ v ;\
   }\
   static inline void SIMCALL_GS_FUNC(SIMCALL_GS_SC_NAME(name), set, SIMCALL_GS_ARG_NAME(v))(smx_simcall_t simcall, SIMCALL_ARG_ v){\
-    simcall->args[i].SIMCALL_FIELD_ v = SIMCALL_NAME_ v ;\
+    simcall->args[i].SIMCALL_FIELD_ v = SIMCALL_CASTTYPE v SIMCALL_NAME_ v ;\
   }
 
 #define SIMCALL_ARG_GETSET(type, name, answer, res, ...)\
 /* generate the simcalls result getter/setter */
 #define SIMCALL_WITH_RES_GETSET(name, v) \
   static inline SIMCALL_FUNC_RETURN_TYPE(v) SIMCALL_GS_FUNC(SIMCALL_GS_SC_NAME((name)), get, SIMCALL_GS_ARG_NAME(v))(smx_simcall_t simcall){\
-    return simcall->result.SIMCALL_FIELD_ v ;\
+    return (SIMCALL_FUNC_RETURN_TYPE(v)) simcall->result.SIMCALL_FIELD_ v ;\
   }\
   static inline void SIMCALL_GS_FUNC(SIMCALL_GS_SC_NAME((name)), set, SIMCALL_GS_ARG_NAME(v))(smx_simcall_t simcall, SIMCALL_ARG_ v){\
     simcall->result.SIMCALL_FIELD_ v = SIMCALL_NAME_ v ;\
   }
 #define SIMCALL_WITHOUT_RES_GETSET(name, v)
 #define SIMCALL_RES_GETSET__(name, type, ...)\
-        MAYBE2(,##__VA_ARGS__, SIMCALL_WITH_RES_GETSET, SIMCALL_WITHOUT_RES_GETSET)
+        MAYBE3(,##__VA_ARGS__, SIMCALL_WITH_RES_GETSET, SIMCALL_WITH_RES_GETSET, SIMCALL_WITHOUT_RES_GETSET)
 #define SIMCALL_RES_GETSET_(scname, v)\
         SIMCALL_RES_GETSET__ v (scname, v)
 #define SIMCALL_RES_GETSET(type, name, answer, res, ...)\
   inline void SIMCALL_GS_FUNC(SIMCALL_GS_SC_NAME((name)), set, SIMCALL_GS_ARG_NAME(v))(smx_simcall_t simcall, SIMCALL_ARG_ v);
 #define SIMCALL_WITHOUT_RES_GETSET_PROTO(name, v)
 #define SIMCALL_RES_GETSET_PROTO__(name, type, ...)\
-        MAYBE2(,##__VA_ARGS__, SIMCALL_WITH_RES_GETSET_PROTO, SIMCALL_WITHOUT_RES_GETSET_PROTO)
+        MAYBE3(,##__VA_ARGS__, SIMCALL_WITH_RES_GETSET_PROTO, SIMCALL_WITHOUT_RES_GETSET_PROTO, SIMCALL_WITHOUT_RES_GETSET_PROTO)
 #define SIMCALL_RES_GETSET_PROTO_(scname, v)\
         SIMCALL_RES_GETSET_PROTO__ v (scname, v)
 #define SIMCALL_RES_GETSET_PROTO(type, name, answer, res, ...)\
 
 /* the list of simcalls definitions */
 #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_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_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_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_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_WAIT, host_execution_wait, WITHOUT_ANSWER, TINT(result), TSPEC(execution, smx_action_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_HOST_GET_BY_NAME, host_get_by_name, WITH_ANSWER, TDSPEC(result, smx_host_t), TSTRING(name)) sep \
+ACTION(SIMCALL_HOST_GET_NAME, host_get_name, WITH_ANSWER, TSTRING(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_PROPERTIES, host_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_CORE, host_get_core, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_PROCESS_LIST, host_get_process_list, WITH_ANSWER, TDSPEC(result, xbt_swag_t), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_SPEED, host_get_speed, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_AVAILABLE_SPEED, host_get_available_speed, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_STATE, host_get_state, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_DATA, host_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_SET_DATA, host_set_data, WITH_ANSWER, TVOID(result), TDSPEC(host, smx_host_t), TDPTR(data)) sep \
+ACTION(SIMCALL_HOST_GET_CURRENT_POWER_PEAK, host_get_current_power_peak, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_GET_POWER_PEAK_AT, host_get_power_peak_at, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t), TINT(pstate_index)) sep \
+ACTION(SIMCALL_HOST_GET_NB_PSTATES, host_get_nb_pstates, WITH_ANSWER, TINT(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_SET_POWER_PEAK_AT, host_set_power_peak_at, WITH_ANSWER, TVOID(result), TDSPEC(host, smx_host_t), TINT(pstate_index)) sep \
+ACTION(SIMCALL_HOST_GET_CONSUMED_ENERGY, host_get_consumed_energy, WITH_ANSWER, TDOUBLE(result), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTE, host_execute, WITH_ANSWER, TDSPEC(result, smx_action_t), TSTRING(name), TDSPEC(host, smx_host_t), TDOUBLE(computation_amount), TDOUBLE(priority)) sep \
+ACTION(SIMCALL_HOST_PARALLEL_EXECUTE, host_parallel_execute, WITH_ANSWER, TDSPEC(result, smx_action_t), TSTRING(name), TINT(host_nb), TDSPEC(host_list, smx_host_t*), TDSPEC(computation_amount, double*), TDSPEC(communication_amount, double*), TDOUBLE(amount), TDOUBLE(rate)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_DESTROY, host_execution_destroy, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_CANCEL, host_execution_cancel, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_GET_REMAINS, host_execution_get_remains, WITH_ANSWER, TDOUBLE(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_GET_STATE, host_execution_get_state, WITH_ANSWER, TINT(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_SET_PRIORITY, host_execution_set_priority, WITH_ANSWER, TVOID(result), TDSPEC(execution, smx_action_t), TDOUBLE(priority)) sep \
+ACTION(SIMCALL_HOST_EXECUTION_WAIT, host_execution_wait, WITHOUT_ANSWER, TINT(result), TDSPEC(execution, smx_action_t)) sep \
+ACTION(SIMCALL_HOST_GET_STORAGE_LIST, host_get_storage_list, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_PROCESS_CREATE, process_create, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t*), TSTRING(name), TFSPEC(code, xbt_main_func_t), TDPTR(data), TSTRING(hostname), TDOUBLE(kill_time), TINT(argc), TDSPEC(argv, char**), TDSPEC(properties, xbt_dict_t), TINT(auto_restart)) sep \
+ACTION(SIMCALL_PROCESS_KILL, process_kill, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \
 ACTION(SIMCALL_PROCESS_KILLALL, process_killall, WITH_ANSWER, TVOID(result), TINT(reset_pid)) sep \
-ACTION(SIMCALL_PROCESS_CLEANUP, process_cleanup, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_CHANGE_HOST, process_change_host, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TSPEC(dest, smx_host_t)) sep \
-ACTION(SIMCALL_PROCESS_SUSPEND, process_suspend, WITHOUT_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_RESUME, process_resume, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_CLEANUP, process_cleanup, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_CHANGE_HOST, process_change_host, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TDSPEC(dest, smx_host_t)) sep \
+ACTION(SIMCALL_PROCESS_SUSPEND, process_suspend, WITHOUT_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_RESUME, process_resume, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t)) sep \
 ACTION(SIMCALL_PROCESS_COUNT, process_count, WITH_ANSWER, TINT(result)) sep \
-ACTION(SIMCALL_PROCESS_GET_PID, process_get_PID, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep  \
-ACTION(SIMCALL_PROCESS_GET_PPID, process_get_PPID, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep  \
-ACTION(SIMCALL_PROCESS_GET_DATA, process_get_data, WITH_ANSWER, TPTR(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_SET_DATA, process_set_data, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TPTR(data)) sep \
-ACTION(SIMCALL_PROCESS_GET_HOST, process_get_host, WITH_ANSWER, TSPEC(result, smx_host_t), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_GET_NAME, process_get_name, WITH_ANSWER, TSTRING(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_IS_SUSPENDED, process_is_suspended, WITH_ANSWER, TINT(result), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_PROCESS_GET_PROPERTIES, process_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_GET_PID, process_get_PID, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep  \
+ACTION(SIMCALL_PROCESS_GET_PPID, process_get_PPID, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep  \
+ACTION(SIMCALL_PROCESS_GET_DATA, process_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_SET_DATA, process_set_data, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TDPTR(data)) sep \
+ACTION(SIMCALL_PROCESS_GET_HOST, process_get_host, WITH_ANSWER, TDSPEC(result, smx_host_t), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_GET_NAME, process_get_name, WITH_ANSWER, TSTRING(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_IS_SUSPENDED, process_is_suspended, WITH_ANSWER, TINT(result), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_PROCESS_GET_PROPERTIES, process_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(process, smx_process_t)) sep \
 ACTION(SIMCALL_PROCESS_SLEEP, process_sleep, WITHOUT_ANSWER, TINT(result), TDOUBLE(duration)) sep \
-ACTION(SIMCALL_PROCESS_ON_EXIT, process_on_exit, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TSPEC(fun, int_f_pvoid_t), TPTR(data)) sep \
-ACTION(SIMCALL_PROCESS_AUTO_RESTART_SET, process_auto_restart_set, WITH_ANSWER, TVOID(result), TSPEC(process, smx_process_t), TINT(auto_restart)) sep \
-ACTION(SIMCALL_PROCESS_RESTART, process_restart, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(process, smx_process_t)) sep \
-ACTION(SIMCALL_RDV_CREATE, rdv_create, WITH_ANSWER, TSPEC(result, smx_rdv_t), TSTRING(name)) sep \
-ACTION(SIMCALL_RDV_DESTROY, rdv_destroy, WITH_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t)) sep \
-ACTION(SIMCALL_RDV_GET_BY_NAME, rdv_get_by_name, WITH_ANSWER, TSPEC(result, smx_host_t), TSTRING(name)) sep \
-ACTION(SIMCALL_RDV_COMM_COUNT_BY_HOST, rdv_comm_count_by_host, WITH_ANSWER, TUINT(result), TSPEC(rdv, smx_rdv_t), TSPEC(host, smx_host_t)) sep \
-ACTION(SIMCALL_RDV_GET_HEAD, rdv_get_head, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t)) sep \
-ACTION(SIMCALL_RDV_SET_RECV, rdv_set_receiver, WITH_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TSPEC(receiver, smx_process_t)) sep \
-ACTION(SIMCALL_RDV_GET_RECV, rdv_get_receiver, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(rdv, smx_rdv_t)) sep \
-ACTION(SIMCALL_COMM_IPROBE, comm_iprobe, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TINT(src), TINT(tag), TSPEC(match_fun, simix_match_func_t), TPTR(data)) sep \
-ACTION(SIMCALL_COMM_SEND, comm_send, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TPTR(src_buff), TSIZE(src_buff_size), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_COMM_ISEND, comm_isend, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TPTR(src_buff), TSIZE(src_buff_size), TSPEC(match_fun, simix_match_func_t), TSPEC(clean_fun, simix_clean_func_t), TPTR(data), TINT(detached)) sep \
-ACTION(SIMCALL_COMM_RECV, comm_recv, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_COMM_IRECV, comm_irecv, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data)) sep \
-ACTION(SIMCALL_COMM_RECV_BOUNDED, comm_recv_bounded, WITHOUT_ANSWER, TVOID(result), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(timeout), TDOUBLE(rate)) sep \
-ACTION(SIMCALL_COMM_IRECV_BOUNDED, comm_irecv_bounded, WITH_ANSWER, TSPEC(result, smx_action_t), TSPEC(rdv, smx_rdv_t), TPTR(dst_buff), TSPEC(dst_buff_size, size_t*), TSPEC(match_fun, simix_match_func_t), TPTR(data), TDOUBLE(rate)) sep \
-ACTION(SIMCALL_COMM_DESTROY, comm_destroy, WITH_ANSWER, TVOID(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_CANCEL, comm_cancel, WITH_ANSWER, TVOID(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_WAITANY, comm_waitany, WITHOUT_ANSWER, TINT(result), TSPEC(comms, xbt_dynar_t)) sep \
-ACTION(SIMCALL_COMM_WAIT, comm_wait, WITHOUT_ANSWER, TVOID(result), TSPEC(comm, smx_action_t), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_COMM_TEST, comm_test, WITHOUT_ANSWER, TINT(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_TESTANY, comm_testany, WITHOUT_ANSWER, TINT(result), TSPEC(comms, xbt_dynar_t)) sep \
-ACTION(SIMCALL_COMM_GET_REMAINS, comm_get_remains, WITH_ANSWER, TDOUBLE(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_STATE, comm_get_state, WITH_ANSWER, TINT(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_SRC_DATA, comm_get_src_data, WITH_ANSWER, TPTR(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_DST_DATA, comm_get_dst_data, WITH_ANSWER, TPTR(result), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_SRC_PROC, comm_get_src_proc, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_COMM_GET_DST_PROC, comm_get_dst_proc, WITH_ANSWER, TSPEC(result, smx_process_t), TSPEC(comm, smx_action_t)) sep \
-ACTION(SIMCALL_MUTEX_INIT, mutex_init, WITH_ANSWER, TSPEC(result, smx_mutex_t)) sep \
-ACTION(SIMCALL_MUTEX_DESTROY, mutex_destroy, WITH_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_MUTEX_LOCK, mutex_lock, WITHOUT_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_MUTEX_TRYLOCK, mutex_trylock, WITH_ANSWER, TINT(result), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_MUTEX_UNLOCK, mutex_unlock, WITH_ANSWER, TVOID(result), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_COND_INIT, cond_init, WITH_ANSWER, TSPEC(result, smx_cond_t)) sep \
-ACTION(SIMCALL_COND_DESTROY, cond_destroy, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \
-ACTION(SIMCALL_COND_SIGNAL, cond_signal, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \
-ACTION(SIMCALL_COND_WAIT, cond_wait, WITHOUT_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t), TSPEC(mutex, smx_mutex_t)) sep \
-ACTION(SIMCALL_COND_WAIT_TIMEOUT, cond_wait_timeout, WITHOUT_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t), TSPEC(mutex, smx_mutex_t), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_COND_BROADCAST, cond_broadcast, WITH_ANSWER, TVOID(result), TSPEC(cond, smx_cond_t)) sep \
-ACTION(SIMCALL_SEM_INIT, sem_init, WITH_ANSWER, TSPEC(result, smx_sem_t), TINT(capacity)) sep \
-ACTION(SIMCALL_SEM_DESTROY, sem_destroy, WITH_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_SEM_RELEASE, sem_release, WITH_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_SEM_WOULD_BLOCK, sem_would_block, WITH_ANSWER, TINT(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_SEM_ACQUIRE, sem_acquire, WITHOUT_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem_acquire_timeout, WITHOUT_ANSWER, TVOID(result), TSPEC(sem, smx_sem_t), TDOUBLE(timeout)) sep \
-ACTION(SIMCALL_SEM_GET_CAPACITY, sem_get_capacity, WITH_ANSWER, TINT(result), TSPEC(sem, smx_sem_t)) sep \
-ACTION(SIMCALL_FILE_GET_DATA, file_get_data, WITH_ANSWER, TPTR(result), TSPEC(fd, smx_file_t)) sep \
-ACTION(SIMCALL_FILE_SET_DATA, file_set_data, WITH_ANSWER, TVOID(result), TSPEC(fd, smx_file_t), TPTR(data)) sep \
-ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t), TSIZE(size)) sep \
-ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t), TSIZE(size)) sep \
-ACTION(SIMCALL_FILE_OPEN, file_open, WITHOUT_ANSWER, TSPEC(result, smx_file_t), TSTRING(mount), TSTRING(path)) sep \
-ACTION(SIMCALL_FILE_CLOSE, file_close, WITHOUT_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \
-ACTION(SIMCALL_FILE_UNLINK, file_unlink, WITH_ANSWER, TINT(result), TSPEC(fd, smx_file_t)) sep \
-ACTION(SIMCALL_FILE_LS, file_ls, WITHOUT_ANSWER, TSPEC(result, xbt_dict_t), TSTRING(mount), TSTRING(path)) sep \
-ACTION(SIMCALL_FILE_GET_SIZE, file_get_size, WITH_ANSWER, TSIZE(result), TSPEC(fd, smx_file_t)) sep \
-ACTION(SIMCALL_FILE_GET_INFO, file_get_info, WITH_ANSWER, TSPEC(result, xbt_dynar_t), TSPEC(fd, smx_file_t)) sep \
+ACTION(SIMCALL_PROCESS_ON_EXIT, process_on_exit, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TFSPEC(fun, int_f_pvoid_t), TDPTR(data)) sep \
+ACTION(SIMCALL_PROCESS_AUTO_RESTART_SET, process_auto_restart_set, WITH_ANSWER, TVOID(result), TDSPEC(process, smx_process_t), TINT(auto_restart)) sep \
+ACTION(SIMCALL_PROCESS_RESTART, process_restart, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(process, smx_process_t)) sep \
+ACTION(SIMCALL_RDV_CREATE, rdv_create, WITH_ANSWER, TDSPEC(result, smx_rdv_t), TSTRING(name)) sep \
+ACTION(SIMCALL_RDV_DESTROY, rdv_destroy, WITH_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t)) sep \
+ACTION(SIMCALL_RDV_GET_BY_NAME, rdv_get_by_name, WITH_ANSWER, TDSPEC(result, smx_host_t), TSTRING(name)) sep \
+ACTION(SIMCALL_RDV_COMM_COUNT_BY_HOST, rdv_comm_count_by_host, WITH_ANSWER, TUINT(result), TDSPEC(rdv, smx_rdv_t), TDSPEC(host, smx_host_t)) sep \
+ACTION(SIMCALL_RDV_GET_HEAD, rdv_get_head, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t)) sep \
+ACTION(SIMCALL_RDV_SET_RECV, rdv_set_receiver, WITH_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDSPEC(receiver, smx_process_t)) sep \
+ACTION(SIMCALL_RDV_GET_RECV, rdv_get_receiver, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(rdv, smx_rdv_t)) sep \
+ACTION(SIMCALL_COMM_IPROBE, comm_iprobe, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TINT(src), TINT(tag), TFSPEC(match_fun, simix_match_func_t), TDPTR(data)) sep \
+ACTION(SIMCALL_COMM_SEND, comm_send, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TDPTR(src_buff), TSIZE(src_buff_size), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_COMM_ISEND, comm_isend, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDOUBLE(task_size), TDOUBLE(rate), TDPTR(src_buff), TSIZE(src_buff_size), TFSPEC(match_fun, simix_match_func_t), TFSPEC(clean_fun, simix_clean_func_t), TDPTR(data), TINT(detached)) sep \
+ACTION(SIMCALL_COMM_RECV, comm_recv, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_COMM_IRECV, comm_irecv, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data)) sep \
+ACTION(SIMCALL_COMM_RECV_BOUNDED, comm_recv_bounded, WITHOUT_ANSWER, TVOID(result), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(timeout), TDOUBLE(rate)) sep \
+ACTION(SIMCALL_COMM_IRECV_BOUNDED, comm_irecv_bounded, WITH_ANSWER, TDSPEC(result, smx_action_t), TDSPEC(rdv, smx_rdv_t), TDPTR(dst_buff), TDSPEC(dst_buff_size, size_t*), TFSPEC(match_fun, simix_match_func_t), TDPTR(data), TDOUBLE(rate)) sep \
+ACTION(SIMCALL_COMM_DESTROY, comm_destroy, WITH_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_CANCEL, comm_cancel, WITH_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_WAITANY, comm_waitany, WITHOUT_ANSWER, TINT(result), TDSPEC(comms, xbt_dynar_t)) sep \
+ACTION(SIMCALL_COMM_WAIT, comm_wait, WITHOUT_ANSWER, TVOID(result), TDSPEC(comm, smx_action_t), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_COMM_TEST, comm_test, WITHOUT_ANSWER, TINT(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_TESTANY, comm_testany, WITHOUT_ANSWER, TINT(result), TDSPEC(comms, xbt_dynar_t)) sep \
+ACTION(SIMCALL_COMM_GET_REMAINS, comm_get_remains, WITH_ANSWER, TDOUBLE(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_STATE, comm_get_state, WITH_ANSWER, TINT(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_SRC_DATA, comm_get_src_data, WITH_ANSWER, TDPTR(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_DST_DATA, comm_get_dst_data, WITH_ANSWER, TDPTR(result), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_SRC_PROC, comm_get_src_proc, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_COMM_GET_DST_PROC, comm_get_dst_proc, WITH_ANSWER, TDSPEC(result, smx_process_t), TDSPEC(comm, smx_action_t)) sep \
+ACTION(SIMCALL_MUTEX_INIT, mutex_init, WITH_ANSWER, TDSPEC(result, smx_mutex_t)) sep \
+ACTION(SIMCALL_MUTEX_DESTROY, mutex_destroy, WITH_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_MUTEX_LOCK, mutex_lock, WITHOUT_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_MUTEX_TRYLOCK, mutex_trylock, WITH_ANSWER, TINT(result), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_MUTEX_UNLOCK, mutex_unlock, WITH_ANSWER, TVOID(result), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_COND_INIT, cond_init, WITH_ANSWER, TDSPEC(result, smx_cond_t)) sep \
+ACTION(SIMCALL_COND_DESTROY, cond_destroy, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \
+ACTION(SIMCALL_COND_SIGNAL, cond_signal, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \
+ACTION(SIMCALL_COND_WAIT, cond_wait, WITHOUT_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t), TDSPEC(mutex, smx_mutex_t)) sep \
+ACTION(SIMCALL_COND_WAIT_TIMEOUT, cond_wait_timeout, WITHOUT_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t), TDSPEC(mutex, smx_mutex_t), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_COND_BROADCAST, cond_broadcast, WITH_ANSWER, TVOID(result), TDSPEC(cond, smx_cond_t)) sep \
+ACTION(SIMCALL_SEM_INIT, sem_init, WITH_ANSWER, TDSPEC(result, smx_sem_t), TINT(capacity)) sep \
+ACTION(SIMCALL_SEM_DESTROY, sem_destroy, WITH_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_SEM_RELEASE, sem_release, WITH_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_SEM_WOULD_BLOCK, sem_would_block, WITH_ANSWER, TINT(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_SEM_ACQUIRE, sem_acquire, WITHOUT_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem_acquire_timeout, WITHOUT_ANSWER, TVOID(result), TDSPEC(sem, smx_sem_t), TDOUBLE(timeout)) sep \
+ACTION(SIMCALL_SEM_GET_CAPACITY, sem_get_capacity, WITH_ANSWER, TINT(result), TDSPEC(sem, smx_sem_t)) sep \
+ACTION(SIMCALL_FILE_GET_DATA, file_get_data, WITH_ANSWER, TDPTR(result), TDSPEC(fd, smx_file_t)) sep \
+ACTION(SIMCALL_FILE_SET_DATA, file_set_data, WITH_ANSWER, TVOID(result), TDSPEC(fd, smx_file_t), TDPTR(data)) sep \
+ACTION(SIMCALL_FILE_READ, file_read, WITHOUT_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t),  TSIZE(size)) sep \
+ACTION(SIMCALL_FILE_WRITE, file_write, WITHOUT_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t), TSIZE(size)) sep \
+ACTION(SIMCALL_FILE_OPEN, file_open, WITHOUT_ANSWER, TDSPEC(result, smx_file_t), TSTRING(mount), TSTRING(path)) sep \
+ACTION(SIMCALL_FILE_CLOSE, file_close, WITHOUT_ANSWER, TINT(result), TDSPEC(fd, smx_file_t)) sep \
+ACTION(SIMCALL_FILE_UNLINK, file_unlink, WITH_ANSWER, TINT(result), TDSPEC(fd, smx_file_t)) sep \
+ACTION(SIMCALL_FILE_LS, file_ls, WITHOUT_ANSWER, TDSPEC(result, xbt_dict_t), TSTRING(mount), TSTRING(path)) sep \
+ACTION(SIMCALL_FILE_GET_SIZE, file_get_size, WITH_ANSWER, TSIZE(result), TDSPEC(fd, smx_file_t)) sep \
+ACTION(SIMCALL_FILE_GET_INFO, file_get_info, WITH_ANSWER, TDSPEC(result, xbt_dynar_t), TDSPEC(fd, smx_file_t)) sep \
 ACTION(SIMCALL_STORAGE_GET_FREE_SIZE, storage_get_free_size, WITH_ANSWER, TSIZE(result), TSTRING(name)) sep \
 ACTION(SIMCALL_STORAGE_GET_USED_SIZE, storage_get_used_size, WITH_ANSWER, TSIZE(result), TSTRING(name)) sep \
-ACTION(SIMCALL_STORAGE_GET_PROPERTIES, storage_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(storage, smx_storage_t)) sep \
-ACTION(SIMCALL_STORAGE_GET_CONTENT, storage_get_content, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSPEC(storage, smx_storage_t)) sep \
-ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TSPEC(result, xbt_dict_t), TSTRING(name)) sep 
+ACTION(SIMCALL_STORAGE_GET_PROPERTIES, storage_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(storage, smx_storage_t)) sep \
+ACTION(SIMCALL_STORAGE_GET_CONTENT, storage_get_content, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TDSPEC(storage, smx_storage_t)) sep \
+ACTION(SIMCALL_ASR_GET_PROPERTIES, asr_get_properties, WITH_ANSWER, TDSPEC(result, xbt_dict_t), TSTRING(name)) sep
 
 /* SIMCALL_COMM_IS_LATENCY_BOUNDED and SIMCALL_SET_CATEGORY make things complicated
  * because they are not always present */
 #ifdef HAVE_LATENCY_BOUND_TRACKING
 #define SIMCALL_LIST2(ACTION, sep) \
-ACTION(SIMCALL_COMM_IS_LATENCY_BOUNDED, comm_is_latency_bounded, WITH_ANSWER, TINT(result), TSPEC(comm, smx_action_t)) sep
+ACTION(SIMCALL_COMM_IS_LATENCY_BOUNDED, comm_is_latency_bounded, WITH_ANSWER, TINT(result), TDSPEC(comm, smx_action_t)) sep
 #else
 #define SIMCALL_LIST2(ACTION, sep)
 #endif
 
 #ifdef HAVE_TRACING
 #define SIMCALL_LIST3(ACTION, sep) \
-ACTION(SIMCALL_SET_CATEGORY, set_category, WITH_ANSWER, TVOID(result), TSPEC(action, smx_action_t), TSTRING(category)) sep
+ACTION(SIMCALL_SET_CATEGORY, set_category, WITH_ANSWER, TVOID(result), TDSPEC(action, smx_action_t), TSTRING(category)) sep
 #else
 #define SIMCALL_LIST3(ACTION, sep)
 #endif
 
 #ifdef HAVE_MC
 #define SIMCALL_LIST4(ACTION, sep) \
-ACTION(SIMCALL_MC_SNAPSHOT, mc_snapshot, WITH_ANSWER, TPTR(result)) sep \
-ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TPTR(s1), TPTR(s2)) sep \
+ACTION(SIMCALL_MC_SNAPSHOT, mc_snapshot, WITH_ANSWER, TDPTR(result)) sep \
+ACTION(SIMCALL_MC_COMPARE_SNAPSHOTS, mc_compare_snapshots, WITH_ANSWER, TINT(result), TDPTR(s1), TDPTR(s2)) sep \
 ACTION(SIMCALL_MC_RANDOM, mc_random, WITH_ANSWER, TINT(result), TINT(min), TINT(max)) sep
 #else
 #define SIMCALL_LIST4(ACTION, sep)
@@ -412,6 +426,7 @@ NUM_SIMCALLS
 
 typedef int (*simix_match_func_t)(void *, void *, smx_action_t);
 typedef void (*simix_clean_func_t)(void *);
+typedef void (*FPtr)(void); // Hide the ugliness
 
 /* Pack all possible scalar types in an union */
 union u_smx_scalar {
@@ -427,7 +442,8 @@ union u_smx_scalar {
   float           f;
   double          d;
   size_t          si;
-  void*           p;
+  void*           dp;
+  FPtr            fp;
   const void*     cp;
 };
 
@@ -451,8 +467,14 @@ typedef struct s_smx_simcall {
   };
 } s_smx_simcall_t, *smx_simcall_t;
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 SIMCALL_LIST(SIMCALL_RES_GETSET, SIMCALL_SEP_NOTHING)
 SIMCALL_LIST(SIMCALL_ARG_GETSET, SIMCALL_SEP_NOTHING)
+#ifdef __cplusplus
+}
+#endif
 
 /******************************** General *************************************/
 
index c9d14d0..90e0da2 100644 (file)
@@ -28,9 +28,9 @@ static smx_action_t SIMIX_synchro_wait(smx_host_t smx_host, double timeout)
   action->type = SIMIX_ACTION_SYNCHRO;
   action->name = xbt_strdup("synchro");
   action->synchro.sleep = 
-    surf_workstation_model->extension.workstation.sleep(smx_host, timeout);
+    surf_workstation_sleep(smx_host, timeout);
 
-  surf_workstation_model->action_data_set(action->synchro.sleep, action);
+  surf_action_set_data(action->synchro.sleep, action);
   XBT_OUT();
   return action;
 }
@@ -70,7 +70,7 @@ void SIMIX_synchro_destroy(smx_action_t action)
 {
   XBT_IN("(%p)",action);
   XBT_DEBUG("Destroying synchro %p", action);
-  action->synchro.sleep->model_type->action_unref(action->synchro.sleep);
+  surf_action_unref(action->synchro.sleep);
   xbt_free(action->name);
   xbt_mallocator_release(simix_global->action_mallocator, action);
   XBT_OUT();
@@ -79,9 +79,9 @@ void SIMIX_synchro_destroy(smx_action_t action)
 void SIMIX_post_synchro(smx_action_t action)
 {
   XBT_IN("(%p)",action);
-  if (surf_workstation_model->action_state_get(action->synchro.sleep) == SURF_ACTION_FAILED)
+  if (surf_action_get_state(action->synchro.sleep) == SURF_ACTION_FAILED)
     action->state = SIMIX_FAILED;
-  else if(surf_workstation_model->action_state_get(action->synchro.sleep) == SURF_ACTION_DONE)
+  else if(surf_action_get_state(action->synchro.sleep) == SURF_ACTION_DONE)
     action->state = SIMIX_SRC_TIMEOUT;
 
   SIMIX_synchro_finish(action);  
diff --git a/src/surf/cpu.cpp b/src/surf/cpu.cpp
new file mode 100644 (file)
index 0000000..d550b0a
--- /dev/null
@@ -0,0 +1,164 @@
+#include "cpu.hpp"
+
+extern "C" {
+XBT_LOG_EXTERNAL_CATEGORY(surf_kernel);
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu, surf,
+                                "Logging specific to the SURF cpu module");
+}
+
+CpuModelPtr surf_cpu_model;
+
+/*********
+ * Model *
+ *********/
+
+void CpuModel::updateActionsStateLazy(double now, double delta)
+{
+  void *_action;
+  CpuActionLmmPtr action;
+  while ((xbt_heap_size(p_actionHeap) > 0)
+         && (double_equals(xbt_heap_maxkey(p_actionHeap), now))) {
+    action = dynamic_cast<CpuActionLmmPtr>(static_cast<ActionLmmPtr>(xbt_heap_pop(p_actionHeap)));
+    XBT_CDEBUG(surf_kernel, "Something happened to action %p", action);
+#ifdef HAVE_TRACING
+    if (TRACE_is_enabled()) {
+      CpuPtr cpu = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var(p_maxminSystem, action->p_variable, 0));
+      TRACE_surf_host_set_utilization(cpu->m_name, action->p_category,
+                                      lmm_variable_getvalue(action->p_variable),
+                                      action->m_lastUpdate,
+                                      now - action->m_lastUpdate);
+    }
+#endif
+
+    action->m_finish = surf_get_clock();
+    XBT_CDEBUG(surf_kernel, "Action %p finished", action);
+
+    action->updateEnergy();
+
+    /* set the remains to 0 due to precision problems when updating the remaining amount */
+    action->m_remains = 0;
+    action->setState(SURF_ACTION_DONE);
+    action->heapRemove(p_actionHeap); //FIXME: strange call since action was already popped
+  }
+#ifdef HAVE_TRACING
+  if (TRACE_is_enabled()) {
+    //defining the last timestamp that we can safely dump to trace file
+    //without losing the event ascending order (considering all CPU's)
+    double smaller = -1;
+    xbt_swag_foreach(_action, p_runningActionSet) {
+      action = dynamic_cast<CpuActionLmmPtr>(static_cast<ActionPtr>(_action));
+        if (smaller < 0) {
+          smaller = action->m_lastUpdate;
+          continue;
+        }
+        if (action->m_lastUpdate < smaller) {
+          smaller = action->m_lastUpdate;
+        }
+    }
+    if (smaller > 0) {
+      TRACE_last_timestamp_to_dump = smaller;
+    }
+  }
+#endif
+  return;
+}
+
+void CpuModel::updateActionsStateFull(double now, double delta)
+{
+  void *_action, *_next_action;
+  CpuActionLmmPtr action = NULL;
+  xbt_swag_t running_actions = p_runningActionSet;
+
+  xbt_swag_foreach_safe(_action, _next_action, running_actions) {
+    action = dynamic_cast<CpuActionLmmPtr>(static_cast<ActionPtr>(_action));
+#ifdef HAVE_TRACING
+    if (TRACE_is_enabled()) {
+      CpuPtr x = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var
+                              (p_maxminSystem, action->p_variable, 0));
+
+      TRACE_surf_host_set_utilization(x->m_name,
+                                      action->p_category,
+                                      lmm_variable_getvalue(action->p_variable),
+                                      now - delta,
+                                      delta);
+      TRACE_last_timestamp_to_dump = now - delta;
+    }
+#endif
+
+    double_update(&(action->m_remains),
+                  lmm_variable_getvalue(action->p_variable) * delta);
+
+
+    if (action->m_maxDuration != NO_MAX_DURATION)
+      double_update(&(action->m_maxDuration), delta);
+
+
+    if ((action->m_remains <= 0) &&
+        (lmm_get_variable_weight(action->p_variable) > 0)) {
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_DONE);
+
+    } else if ((action->m_maxDuration != NO_MAX_DURATION) &&
+               (action->m_maxDuration <= 0)) {
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_DONE);
+    }
+    action->updateEnergy();
+  }
+
+  return;
+}
+
+/************
+ * Resource *
+ ************/
+
+double Cpu::getSpeed(double load)
+{
+  return load * m_powerPeak;
+}
+
+double Cpu::getAvailableSpeed()
+{
+/* number between 0 and 1 */
+  return m_powerScale;
+}
+
+int Cpu::getCore()
+{
+  return m_core;
+}
+
+/**********
+ * Action *
+ **********/
+
+void CpuActionLmm::updateRemainingLazy(double now)
+{
+  double delta = 0.0;
+
+  xbt_assert(p_stateSet == p_model->p_runningActionSet,
+      "You're updating an action that is not running.");
+
+  /* bogus priority, skip it */
+  xbt_assert(m_priority > 0,
+      "You're updating an action that seems suspended.");
+
+  delta = now - m_lastUpdate;
+
+  if (m_remains > 0) {
+    XBT_CDEBUG(surf_kernel, "Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate);
+    double_update(&(m_remains), m_lastValue * delta);
+
+#ifdef HAVE_TRACING
+    if (TRACE_is_enabled()) {
+      CpuPtr cpu = (CpuPtr) lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0));
+      TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
+    }
+#endif
+    XBT_CDEBUG(surf_kernel, "Updating action(%p): remains is now %lf", this, m_remains);
+  }
+
+  m_lastUpdate = now;
+  m_lastValue = lmm_variable_getvalue(p_variable);
+}
diff --git a/src/surf/cpu.hpp b/src/surf/cpu.hpp
new file mode 100644 (file)
index 0000000..b7c5e78
--- /dev/null
@@ -0,0 +1,93 @@
+#include "surf.hpp"
+
+#ifndef SURF_MODEL_CPU_H_
+#define SURF_MODEL_CPU_H_
+
+/***********
+ * Classes *
+ ***********/
+class CpuModel;
+typedef CpuModel *CpuModelPtr;
+
+class Cpu;
+typedef Cpu *CpuPtr;
+
+class CpuLmm;
+typedef CpuLmm *CpuLmmPtr;
+
+class CpuAction;
+typedef CpuAction *CpuActionPtr;
+
+class CpuActionLmm;
+typedef CpuActionLmm *CpuActionLmmPtr;
+
+/*********
+ * Model *
+ *********/
+class CpuModel : public Model {
+public:
+  CpuModel(string name) : Model(name) {};
+  CpuPtr createResource(string name);
+  void updateActionsStateLazy(double now, double delta);
+  void updateActionsStateFull(double now, double delta);
+
+  virtual void addTraces() =0;
+};
+
+/************
+ * Resource *
+ ************/
+class Cpu : virtual public Resource {
+public:
+  Cpu(){};
+  Cpu(CpuModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {};
+  virtual ActionPtr execute(double size)=0;
+  virtual ActionPtr sleep(double duration)=0;
+  virtual int getCore();
+  virtual double getSpeed(double load);
+  virtual double getAvailableSpeed();
+
+  virtual double getCurrentPowerPeak()=0;
+  virtual double getPowerPeakAt(int pstate_index)=0;
+  virtual int getNbPstates()=0;
+  virtual void setPowerPeakAt(int pstate_index)=0;
+  virtual double getConsumedEnergy()=0;
+
+  void addTraces(void);
+  double m_powerPeak;            /*< CPU power peak */
+  double m_powerScale;           /*< Percentage of CPU disponible */
+protected:
+  int m_core;
+
+  //virtual boost::shared_ptr<Action> execute(double size) = 0;
+  //virtual boost::shared_ptr<Action> sleep(double duration) = 0;
+};
+
+class CpuLmm : public ResourceLmm, public Cpu {
+public:
+  CpuLmm(){};
+  CpuLmm(CpuModelPtr model, const char* name, xbt_dict_t properties) : ResourceLmm(), Cpu(model, name, properties) {};
+
+};
+
+/**********
+ * Action *
+ **********/
+class CpuAction : virtual public Action {
+public:
+  CpuAction(){};
+  CpuAction(ModelPtr model, double cost, bool failed)
+  : Action(model, cost, failed) {};
+};
+
+class CpuActionLmm : public ActionLmm, public CpuAction {
+public:
+  CpuActionLmm(){};
+  CpuActionLmm(ModelPtr model, double cost, bool failed)
+  : Action(model, cost, failed), ActionLmm(model, cost, failed), CpuAction(model, cost, failed) {};
+  void updateRemainingLazy(double now);
+  virtual void updateEnergy()=0;
+};
+
+
+#endif /* SURF_MODEL_CPU_H_ */
diff --git a/src/surf/cpu_cas01.cpp b/src/surf/cpu_cas01.cpp
new file mode 100644 (file)
index 0000000..61e1e9e
--- /dev/null
@@ -0,0 +1,505 @@
+/* Copyright (c) 2009-2011. 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 "cpu_cas01.hpp"
+#include "cpu_ti.hpp"
+#include "surf.hpp"
+#include "maxmin_private.h"
+#include "simgrid/sg_config.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_cas, surf_cpu,
+                                "Logging specific to the SURF CPU IMPROVED module");
+}
+
+static xbt_swag_t
+    cpu_running_action_set_that_does_not_need_being_checked = NULL;
+
+/*************
+ * CallBacks *
+ *************/
+
+static void parse_cpu_init(sg_platf_host_cbarg_t host){
+  ((CpuCas01ModelPtr)surf_cpu_model)->parseInit(host);
+}
+
+static void cpu_add_traces_cpu(){
+  surf_cpu_model->addTraces();
+}
+
+static void cpu_define_callbacks()
+{
+  sg_platf_host_add_cb(parse_cpu_init);
+  sg_platf_postparse_add_cb(cpu_add_traces_cpu);
+}
+
+/*********
+ * Model *
+ *********/
+void surf_cpu_model_init_Cas01()
+{
+  char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim");
+
+  if (surf_cpu_model)
+    return;
+
+  if (!strcmp(optim, "TI")) {
+    surf_cpu_model_init_ti();
+    return;
+  }
+
+  surf_cpu_model = new CpuCas01Model();
+  cpu_define_callbacks();
+  ModelPtr model = static_cast<ModelPtr>(surf_cpu_model);
+  xbt_dynar_push(model_list, &model);
+}
+
+CpuCas01Model::CpuCas01Model() : CpuModel("cpu")
+{
+  ActionPtr action;
+  ActionLmmPtr actionlmm;
+
+  char *optim = xbt_cfg_get_string(_sg_cfg_set, "cpu/optim");
+  int select = xbt_cfg_get_boolean(_sg_cfg_set, "cpu/maxmin_selective_update");
+
+  if (!strcmp(optim, "Full")) {
+    p_updateMechanism = UM_FULL;
+    m_selectiveUpdate = select;
+  } else if (!strcmp(optim, "Lazy")) {
+    p_updateMechanism = UM_LAZY;
+    m_selectiveUpdate = 1;
+    xbt_assert((select == 1)
+               ||
+               (xbt_cfg_is_default_value
+                (_sg_cfg_set, "cpu/maxmin_selective_update")),
+               "Disabling selective update while using the lazy update mechanism is dumb!");
+  } else {
+    xbt_die("Unsupported optimization (%s) for this model", optim);
+  }
+
+  cpu_running_action_set_that_does_not_need_being_checked =
+      xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+
+  if (p_updateMechanism == UM_LAZY) {
+       shareResources = &CpuCas01Model::shareResourcesLazy;
+       updateActionsState = &CpuCas01Model::updateActionsStateLazy;
+
+  } else if (p_updateMechanism == UM_FULL) {
+       shareResources = &CpuCas01Model::shareResourcesFull;
+       updateActionsState = &CpuCas01Model::updateActionsStateFull;
+  } else
+    xbt_die("Invalid cpu update mechanism!");
+
+  if (!p_maxminSystem) {
+    p_maxminSystem = lmm_system_new(m_selectiveUpdate);
+  }
+
+  if (p_updateMechanism == UM_LAZY) {
+    p_actionHeap = xbt_heap_new(8, NULL);
+    xbt_heap_set_update_callback(p_actionHeap,  surf_action_lmm_update_index_heap);
+    p_modifiedSet = xbt_swag_new(xbt_swag_offset(*actionlmm, p_actionListHookup));
+    p_maxminSystem->keep_track = p_modifiedSet;
+  }
+}
+
+CpuCas01Model::~CpuCas01Model()
+{
+  lmm_system_free(p_maxminSystem);
+  p_maxminSystem = NULL;
+
+  if (p_actionHeap)
+    xbt_heap_free(p_actionHeap);
+  xbt_swag_free(p_modifiedSet);
+
+  surf_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;
+}
+
+void CpuCas01Model::parseInit(sg_platf_host_cbarg_t host)
+{
+  createResource(host->id,
+        host->power_peak,
+        host->pstate,
+        host->power_scale,
+        host->power_trace,
+        host->core_amount,
+        host->initial_state,
+        host->state_trace,
+        host->properties);
+}
+
+CpuCas01LmmPtr CpuCas01Model::createResource(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)
+{
+  CpuPtr cpu = NULL;
+  xbt_assert(!surf_cpu_resource_priv(surf_cpu_resource_by_name(name)),
+             "Host '%s' declared several times in the platform file",
+             name);
+  xbt_assert(power_peak > 0, "Power has to be >0");
+  xbt_assert(core > 0, "Invalid number of cores %d", core);
+
+  cpu = new CpuCas01Lmm(this, name, power_peak, pstate, power_scale, power_trace, core, state_initial, state_trace, cpu_properties);
+  xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast<ResourcePtr>(cpu));
+
+  return (CpuCas01LmmPtr) xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+double CpuCas01Model::shareResourcesFull(double now)
+{
+  return Model::shareResourcesMaxMin(p_runningActionSet,
+                             p_maxminSystem, lmm_solve);
+}
+
+void CpuCas01Model::addTraces()
+{
+  xbt_dict_cursor_t cursor = NULL;
+  char *trace_name, *elm;
+  static int called = 0;
+  if (called)
+    return;
+  called = 1;
+
+  /* connect all traces relative to hosts */
+  xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    CpuCas01LmmPtr host = static_cast<CpuCas01LmmPtr>(surf_cpu_resource_priv(surf_cpu_resource_by_name(elm)));
+
+    xbt_assert(host, "Host %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    host->p_stateEvent =
+        tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(host));
+  }
+
+  xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    CpuCas01LmmPtr host = dynamic_cast<CpuCas01LmmPtr>(static_cast<ResourcePtr>(surf_cpu_resource_priv(surf_cpu_resource_by_name(elm))));
+
+    xbt_assert(host, "Host %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    host->p_powerEvent =
+        tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(host));
+  }
+}
+
+/************
+ * Resource *
+ ************/
+CpuCas01Lmm::CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, xbt_dynar_t powerPeak,
+               int pstate, double powerScale, tmgr_trace_t powerTrace, int core,
+        e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace,
+       xbt_dict_t properties) :
+       CpuLmm(model, name, properties), Resource(model, name, properties) {
+  m_powerPeak = xbt_dynar_get_as(powerPeak, pstate, double);
+  p_powerPeakList = powerPeak;
+  m_pstate = pstate;
+
+  p_energy = xbt_new(s_energy_cpu_cas01_t, 1);
+  p_energy->total_energy = 0;
+  p_energy->power_range_watts_list = getWattsRangeList();
+  p_energy->last_updated = surf_get_clock();
+
+  XBT_DEBUG("CPU create: peak=%f, pstate=%d", m_powerPeak, m_pstate);
+
+  m_powerScale = powerScale;
+  m_core = core;
+  p_stateCurrent = stateInitial;
+  if (powerTrace)
+    p_powerEvent = tmgr_history_add_trace(history, powerTrace, 0.0, 0, static_cast<ResourcePtr>(this));
+
+  if (stateTrace)
+    p_stateEvent = tmgr_history_add_trace(history, stateTrace, 0.0, 0, static_cast<ResourcePtr>(this));
+
+  p_constraint = lmm_constraint_new(p_model->p_maxminSystem, this, m_core * m_powerScale * m_powerPeak);
+}
+
+CpuCas01Lmm::~CpuCas01Lmm(){
+  unsigned int iter;
+  xbt_dynar_t power_tuple = NULL;
+  xbt_dynar_foreach(p_energy->power_range_watts_list, iter, power_tuple)
+    xbt_dynar_free(&power_tuple);
+  xbt_dynar_free(&p_energy->power_range_watts_list);
+  xbt_dynar_free(&p_powerPeakList);
+  xbt_free(p_energy);
+  return;
+}
+
+bool CpuCas01Lmm::isUsed()
+{
+  return lmm_constraint_used(p_model->p_maxminSystem, p_constraint);
+}
+
+void CpuCas01Lmm::updateState(tmgr_trace_event_t event_type, double value, double date)
+{
+  lmm_variable_t var = NULL;
+  lmm_element_t elem = NULL;
+
+  if (event_type == p_powerEvent) {
+    m_powerScale = value;
+    lmm_update_constraint_bound(surf_cpu_model->p_maxminSystem, p_constraint,
+                                m_core * m_powerScale *
+                                m_powerPeak);
+#ifdef HAVE_TRACING
+    TRACE_surf_host_set_power(date, m_name,
+                              m_core * m_powerScale *
+                              m_powerPeak);
+#endif
+    while ((var = lmm_get_var_from_cnst
+            (surf_cpu_model->p_maxminSystem, p_constraint, &elem))) {
+      CpuCas01ActionLmmPtr action = static_cast<CpuCas01ActionLmmPtr>(static_cast<ActionLmmPtr>(lmm_variable_id(var)));
+
+      lmm_update_variable_bound(surf_cpu_model->p_maxminSystem,
+                                action->p_variable,
+                                m_powerScale * m_powerPeak);
+    }
+    if (tmgr_trace_event_free(event_type))
+      p_powerEvent = NULL;
+  } else if (event_type == p_stateEvent) {
+    if (value > 0) {
+      if(p_stateCurrent == SURF_RESOURCE_OFF)
+        xbt_dynar_push_as(host_that_restart, char*, (char *)m_name);
+      p_stateCurrent = SURF_RESOURCE_ON;
+    } else {
+      lmm_constraint_t cnst = p_constraint;
+
+      p_stateCurrent = SURF_RESOURCE_OFF;
+
+      while ((var = lmm_get_var_from_cnst(surf_cpu_model->p_maxminSystem, cnst, &elem))) {
+        ActionLmmPtr action = static_cast<ActionLmmPtr>(lmm_variable_id(var));
+
+        if (action->getState() == SURF_ACTION_RUNNING ||
+            action->getState() == SURF_ACTION_READY ||
+            action->getState() == SURF_ACTION_NOT_IN_THE_SYSTEM) {
+          action->m_finish = date;
+          action->setState(SURF_ACTION_FAILED);
+        }
+      }
+    }
+    if (tmgr_trace_event_free(event_type))
+      p_stateEvent = NULL;
+  } else {
+    XBT_CRITICAL("Unknown event ! \n");
+    xbt_abort();
+  }
+
+  return;
+}
+
+ActionPtr CpuCas01Lmm::execute(double size)
+{
+
+  XBT_IN("(%s,%g)", m_name, size);
+  CpuCas01ActionLmmPtr action = new CpuCas01ActionLmm(surf_cpu_model, size, p_stateCurrent != SURF_RESOURCE_ON);
+
+  action->m_suspended = 0;     /* Should be useless because of the
+                                                   calloc but it seems to help valgrind... */
+
+  action->p_variable =
+      lmm_variable_new(surf_cpu_model->p_maxminSystem, static_cast<ActionLmmPtr>(action),
+                       action->m_priority,
+                       m_powerScale * m_powerPeak, 1);
+  if (surf_cpu_model->p_updateMechanism == UM_LAZY) {
+    action->m_indexHeap = -1;
+    action->m_lastUpdate = surf_get_clock();
+    action->m_lastValue = 0.0;
+  }
+  lmm_expand(surf_cpu_model->p_maxminSystem, p_constraint,
+             action->p_variable, 1.0);
+  XBT_OUT();
+  return action;
+}
+
+ActionPtr CpuCas01Lmm::sleep(double duration)
+{
+  if (duration > 0)
+    duration = MAX(duration, MAXMIN_PRECISION);
+
+  XBT_IN("(%s,%g)", m_name, duration);
+  CpuCas01ActionLmmPtr action = dynamic_cast<CpuCas01ActionLmmPtr>(execute(1.0));
+
+  // FIXME: sleep variables should not consume 1.0 in lmm_expand
+  action->m_maxDuration = duration;
+  action->m_suspended = 2;
+  if (duration == NO_MAX_DURATION) {
+    /* Move to the *end* of the corresponding action set. This convention
+       is used to speed up update_resource_state  */
+    xbt_swag_remove(static_cast<ActionPtr>(action), action->p_stateSet);
+    action->p_stateSet = cpu_running_action_set_that_does_not_need_being_checked;
+    xbt_swag_insert(static_cast<ActionPtr>(action), action->p_stateSet);
+  }
+
+  lmm_update_variable_weight(surf_cpu_model->p_maxminSystem,
+                             action->p_variable, 0.0);
+  if (surf_cpu_model->p_updateMechanism == UM_LAZY) {     // remove action from the heap
+    action->heapRemove(surf_cpu_model->p_actionHeap);
+    // this is necessary for a variable with weight 0 since such
+    // variables are ignored in lmm and we need to set its max_duration
+    // correctly at the next call to share_resources
+    xbt_swag_insert_at_head(static_cast<ActionLmmPtr>(action), surf_cpu_model->p_modifiedSet);
+  }
+
+  XBT_OUT();
+  return action;
+}
+
+xbt_dynar_t CpuCas01Lmm::getWattsRangeList()
+{
+       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;
+
+       if (m_properties == NULL)
+               return NULL;
+
+       char* all_power_values_str = (char*)xbt_dict_get_or_null(m_properties, "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",
+                               m_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
+ *
+ */
+double CpuCas01Lmm::getCurrentWattsValue(double cpu_load)
+{
+       xbt_dynar_t power_range_list = p_energy->power_range_watts_list;
+
+       if (power_range_list == NULL)
+       {
+               XBT_DEBUG("No power range properties specified for host %s", m_name);
+               return 0;
+       }
+       xbt_assert(xbt_dynar_length(power_range_list) == xbt_dynar_length(p_powerPeakList),
+                                               "The number of power ranges in the properties does not match the number of pstates for host %s",
+                                               m_name);
+
+    /* retrieve the power values associated with the current pstate */
+    xbt_dynar_t current_power_values = xbt_dynar_get_as(power_range_list, m_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 CpuCas01Lmm::updateEnergy(double cpu_load)
+{
+  double start_time = p_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, m_powerPeak, m_pstate);
+  double current_energy = p_energy->total_energy;
+  double action_energy = getCurrentWattsValue(cpu_load)*(finish_time-start_time);
+
+  p_energy->total_energy = current_energy + action_energy;
+  p_energy->last_updated = finish_time;
+
+  XBT_DEBUG("[cpu_update_energy] old_energy_value=%f, action_energy_value=%f", current_energy, action_energy);
+}
+
+double CpuCas01Lmm::getCurrentPowerPeak()
+{
+  return m_powerPeak;
+}
+
+double CpuCas01Lmm::getPowerPeakAt(int pstate_index)
+{
+  xbt_dynar_t plist = p_powerPeakList;
+  xbt_assert((pstate_index <= xbt_dynar_length(plist)), "Invalid parameters (pstate index out of bounds)");
+
+  return xbt_dynar_get_as(plist, pstate_index, double);
+}
+
+int CpuCas01Lmm::getNbPstates()
+{
+  return xbt_dynar_length(p_powerPeakList);
+}
+
+void CpuCas01Lmm::setPowerPeakAt(int pstate_index)
+{
+  xbt_dynar_t plist = p_powerPeakList;
+  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);
+  m_pstate = pstate_index;
+  m_powerPeak = new_power_peak;
+}
+
+double CpuCas01Lmm::getConsumedEnergy()
+{
+  return p_energy->total_energy;
+}
+
+/**********
+ * Action *
+ **********/
+
+/**
+ * Update the CPU total energy for a finished action
+ *
+ */
+void CpuCas01ActionLmm::updateEnergy()
+{
+  CpuCas01LmmPtr cpu  = static_cast<CpuCas01LmmPtr>(lmm_constraint_id(lmm_get_cnst_from_var
+                                                                                 (p_model->p_maxminSystem,
+                                                                                                 p_variable, 0)));
+
+  if(cpu->p_energy->last_updated < surf_get_clock()) {
+       double load = lmm_constraint_get_usage(cpu->p_constraint) / cpu->m_powerPeak;
+    cpu->updateEnergy(load);
+  }
+}
diff --git a/src/surf/cpu_cas01.hpp b/src/surf/cpu_cas01.hpp
new file mode 100644 (file)
index 0000000..5e12cc2
--- /dev/null
@@ -0,0 +1,88 @@
+#include "cpu.hpp"
+
+/***********
+ * Classes *
+ ***********/
+class CpuCas01Model;
+typedef CpuCas01Model *CpuCas01ModelPtr;
+
+class CpuCas01Lmm;
+typedef CpuCas01Lmm *CpuCas01LmmPtr;
+
+class CpuCas01ActionLmm;
+typedef CpuCas01ActionLmm *CpuCas01ActionLmmPtr;
+
+/*********
+ * Model *
+ *********/
+class CpuCas01Model : public CpuModel {
+public:
+  CpuCas01Model();
+  ~CpuCas01Model();
+
+  double (CpuCas01Model::*shareResources)(double now);
+  void (CpuCas01Model::*updateActionsState)(double now, double delta);
+
+  void parseInit(sg_platf_host_cbarg_t host);  
+  CpuCas01LmmPtr createResource(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);
+  double shareResourcesFull(double now);  
+  void addTraces();
+};
+
+/************
+ * Resource *
+ ************/
+/*
+ * 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;
+
+class CpuCas01Lmm : public CpuLmm {
+public:
+  CpuCas01Lmm(CpuCas01ModelPtr model, const char *name, xbt_dynar_t power_peak,
+        int pstate, double powerScale, tmgr_trace_t powerTrace, int core,
+        e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace,
+       xbt_dict_t properties) ;
+  ~CpuCas01Lmm();
+  void updateState(tmgr_trace_event_t event_type, double value, double date);
+  ActionPtr execute(double size);
+  ActionPtr sleep(double duration);
+
+  xbt_dynar_t getWattsRangeList();
+  double getCurrentWattsValue(double cpu_load);
+  void updateEnergy(double cpu_load);
+
+  double getCurrentPowerPeak();
+  double getPowerPeakAt(int pstate_index);
+  int getNbPstates();
+  void setPowerPeakAt(int pstate_index);
+  double getConsumedEnergy();
+
+  bool isUsed();
+
+  tmgr_trace_event_t p_powerEvent;
+
+  xbt_dynar_t p_powerPeakList;                         /*< List of supported CPU capacities */
+  int m_pstate;                                                                /*< Current pstate (index in the power_peak_list)*/
+  energy_cpu_cas01_t p_energy;                         /*< Structure with energy-consumption data */
+};
+
+/**********
+ * Action *
+ **********/
+class CpuCas01ActionLmm: public CpuActionLmm {
+public:
+  CpuCas01ActionLmm() {};
+  CpuCas01ActionLmm(ModelPtr model, double cost, bool failed): Action(model, cost, failed), CpuActionLmm(model, cost, failed) {};
+  void updateEnergy();
+
+};
diff --git a/src/surf/cpu_ti.cpp b/src/surf/cpu_ti.cpp
new file mode 100644 (file)
index 0000000..545f2ba
--- /dev/null
@@ -0,0 +1,1006 @@
+#include "cpu_ti.hpp"
+#include "trace_mgr_private.h"
+#include "xbt/heap.h"
+
+#ifndef SURF_MODEL_CPUTI_H_
+#define SURF_MODEL_CPUTI_H_
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_ti, surf_cpu,
+                                "Logging specific to the SURF CPU TRACE INTEGRATION module");
+}
+
+static xbt_swag_t cpu_ti_running_action_set_that_does_not_need_being_checked;
+static xbt_swag_t cpu_ti_modified_cpu;
+static xbt_heap_t cpu_ti_action_heap;
+
+static void cpu_ti_action_update_index_heap(void *action, int i);
+
+/*********
+ * Trace *
+ *********/
+
+CpuTiTrace::CpuTiTrace(tmgr_trace_t power_trace)
+{
+  s_tmgr_event_t val;
+  unsigned int cpt;
+  double integral = 0;
+  double time = 0;
+  int i = 0;
+  p_timePoints = (double*) xbt_malloc0(sizeof(double) *
+                  (xbt_dynar_length(power_trace->s_list.event_list) + 1));
+  p_integral = (double*) xbt_malloc0(sizeof(double) *
+                  (xbt_dynar_length(power_trace->s_list.event_list) + 1));
+  m_nbPoints = xbt_dynar_length(power_trace->s_list.event_list);
+  xbt_dynar_foreach(power_trace->s_list.event_list, cpt, val) {
+    p_timePoints[i] = time;
+    p_integral[i] = integral;
+    integral += val.delta * val.value;
+    time += val.delta;
+    i++;
+  }
+  p_timePoints[i] = time;
+  p_integral[i] = integral;
+}
+
+CpuTiTrace::~CpuTiTrace()
+{
+  xbt_free(p_timePoints);
+  xbt_free(p_integral);
+}
+
+CpuTiTgmr::~CpuTiTgmr()
+{
+  if (p_trace)
+    delete p_trace;
+}
+
+/**
+* \brief Integrate trace
+*
+* Wrapper around surf_cpu_integrate_trace_simple() to get
+* the cyclic effect.
+*
+* \param trace Trace structure.
+* \param a      Begin of interval
+* \param b      End of interval
+* \return the integrate value. -1 if an error occurs.
+*/
+double CpuTiTgmr::integrate(double a, double b)
+{
+  double first_chunk;
+  double middle_chunk;
+  double last_chunk;
+  int a_index, b_index;
+
+  if ((a < 0.0) || (a > b)) {
+    XBT_CRITICAL
+        ("Error, invalid integration interval [%.2f,%.2f]. You probably have a task executing with negative computation amount. Check your code.",
+         a, b);
+    xbt_abort();
+  }
+  if (a == b)
+    return 0.0;
+
+  if (m_type == TRACE_FIXED) {
+    return ((b - a) * m_value);
+  }
+
+  if (ceil(a / m_lastTime) == a / m_lastTime)
+    a_index = 1 + (int) (ceil(a / m_lastTime));
+  else
+    a_index = (int) (ceil(a / m_lastTime));
+
+  b_index = (int) (floor(b / m_lastTime));
+
+  if (a_index > b_index) {      /* Same chunk */
+    return p_trace->integrateSimple(a - (a_index -
+                                              1) * m_lastTime,
+                                         b -
+                                         (b_index) *
+                                         m_lastTime);
+  }
+
+  first_chunk = p_trace->integrateSimple(a - (a_index -
+                                                   1) *
+                                              m_lastTime,
+                                              m_lastTime);
+  middle_chunk = (b_index - a_index) * m_total;
+  last_chunk = p_trace->integrateSimple(0.0,
+                                             b -
+                                             (b_index) *
+                                             m_lastTime);
+
+  XBT_DEBUG("first_chunk=%.2f  middle_chunk=%.2f  last_chunk=%.2f\n",
+         first_chunk, middle_chunk, last_chunk);
+
+  return (first_chunk + middle_chunk + last_chunk);
+}
+
+/**
+ * \brief Auxiliary function to calculate the integral between a and b.
+ *     It simply calculates the integral at point a and b and returns the difference 
+ *   between them.
+ * \param trace    Trace structure
+ * \param a        Initial point
+ * \param b  Final point
+ * \return  Integral
+*/
+double CpuTiTrace::integrateSimple(double a, double b)
+{
+  return integrateSimplePoint(b) - integrateSimplePoint(a);
+}
+
+/**
+ * \brief Auxiliary function to calculate the integral at point a.
+ * \param trace    Trace structure
+ * \param a        point
+ * \return  Integral
+*/
+double CpuTiTrace::integrateSimplePoint(double a)
+{
+  double integral = 0;
+  int ind;
+  double a_aux = a;
+  ind = binarySearch(p_timePoints, a, 0, m_nbPoints - 1);
+  integral += p_integral[ind];
+  XBT_DEBUG
+      ("a %f ind %d integral %f ind + 1 %f ind %f time +1 %f time %f",
+       a, ind, integral, p_integral[ind + 1], p_integral[ind],
+       p_timePoints[ind + 1], p_timePoints[ind]);
+  double_update(&a_aux, p_timePoints[ind]);
+  if (a_aux > 0)
+    integral +=
+        ((p_integral[ind + 1] -
+          p_integral[ind]) / (p_timePoints[ind + 1] -
+                              p_timePoints[ind])) * (a - p_timePoints[ind]);
+  XBT_DEBUG("Integral a %f = %f", a, integral);
+
+  return integral;
+}
+
+/**
+* \brief Calculate the time needed to execute "amount" on cpu.
+*
+* Here, amount can span multiple trace periods
+*
+* \param trace   CPU trace structure
+* \param a        Initial time
+* \param amount  Amount to be executed
+* \return  End time
+*/
+double CpuTiTgmr::solve(double a, double amount)
+{
+  int quotient;
+  double reduced_b;
+  double reduced_amount;
+  double reduced_a;
+  double b;
+
+/* Fix very small negative numbers */
+  if ((a < 0.0) && (a > -EPSILON)) {
+    a = 0.0;
+  }
+  if ((amount < 0.0) && (amount > -EPSILON)) {
+    amount = 0.0;
+  }
+
+/* Sanity checks */
+  if ((a < 0.0) || (amount < 0.0)) {
+    XBT_CRITICAL
+        ("Error, invalid parameters [a = %.2f, amount = %.2f]. You probably have a task executing with negative computation amount. Check your code.",
+         a, amount);
+    xbt_abort();
+  }
+
+/* At this point, a and amount are positive */
+
+  if (amount < EPSILON)
+    return a;
+
+/* Is the trace fixed ? */
+  if (m_type == TRACE_FIXED) {
+    return (a + (amount / m_value));
+  }
+
+  XBT_DEBUG("amount %f total %f", amount, m_total);
+/* Reduce the problem to one where amount <= trace_total */
+  quotient = (int) (floor(amount / m_total));
+  reduced_amount = (m_total) * ((amount / m_total) -
+                                     floor(amount / m_total));
+  reduced_a = a - (m_lastTime) * (int) (floor(a / m_lastTime));
+
+  XBT_DEBUG("Quotient: %d reduced_amount: %f reduced_a: %f", quotient,
+         reduced_amount, reduced_a);
+
+/* Now solve for new_amount which is <= trace_total */
+/*
+   fprintf(stderr,"reduced_a = %.2f\n",reduced_a);
+   fprintf(stderr,"reduced_amount = %.2f\n",reduced_amount);
+ */
+  reduced_b = solveSomewhatSimple(reduced_a, reduced_amount);
+
+/* Re-map to the original b and amount */
+  b = (m_lastTime) * (int) (floor(a / m_lastTime)) +
+      (quotient * m_lastTime) + reduced_b;
+  return b;
+}
+
+/**
+* \brief Auxiliary function to solve integral
+*
+* Here, amount is <= trace->total
+* and a <=trace->last_time
+*
+*/
+double CpuTiTgmr::solveSomewhatSimple(double a, double amount)
+{
+  double amount_till_end;
+  double b;
+
+  XBT_DEBUG("Solve integral: [%.2f, amount=%.2f]", a, amount);
+  amount_till_end = integrate(a, m_lastTime);
+/*
+   fprintf(stderr,"amount_till_end=%.2f\n",amount_till_end);
+ */
+
+  if (amount_till_end > amount) {
+    b = p_trace->solveSimple(a, amount);
+  } else {
+    b = m_lastTime + p_trace->solveSimple(0.0, amount - amount_till_end);
+  }
+  return b;
+}
+
+/**
+ * \brief Auxiliary function to solve integral.
+ *  It returns the date when the requested amount of flops is available
+ * \param trace    Trace structure
+ * \param a        Initial point
+ * \param amount  Amount of flops 
+ * \return The date when amount is available.
+*/
+double CpuTiTrace::solveSimple(double a, double amount)
+{
+  double integral_a;
+  int ind;
+  double time;
+  integral_a = integrateSimplePoint(a);
+  ind = binarySearch(p_integral, integral_a + amount, 0, m_nbPoints - 1);
+  time = p_timePoints[ind];
+  time +=
+      (integral_a + amount -
+       p_integral[ind]) / ((p_integral[ind + 1] -
+                                 p_integral[ind]) /
+                                (p_timePoints[ind + 1] -
+                                 p_timePoints[ind]));
+
+  return time;
+}
+
+/**
+* \brief Auxiliary function to update the CPU power scale.
+*
+*  This function uses the trace structure to return the power scale at the determined time a.
+* \param trace    Trace structure to search the updated power scale
+* \param a        Time
+* \return CPU power scale
+*/
+double CpuTiTgmr::getPowerScale(double a)
+{
+  double reduced_a;
+  int point;
+  s_tmgr_event_t val;
+
+  reduced_a = a - floor(a / m_lastTime) * m_lastTime;
+  point = p_trace->binarySearch(p_trace->p_timePoints, reduced_a, 0,
+                                p_trace->m_nbPoints - 1);
+  xbt_dynar_get_cpy(p_powerTrace->s_list.event_list, point, &val);
+  return val.value;
+}
+
+/**
+* \brief Creates a new integration trace from a tmgr_trace_t
+*
+* \param  power_trace    CPU availability trace
+* \param  value          Percentage of CPU power available (useful to fixed tracing)
+* \param  spacing        Initial spacing
+* \return  Integration trace structure
+*/
+CpuTiTgmr::CpuTiTgmr(tmgr_trace_t power_trace, double value)
+{
+  double total_time = 0.0;
+  s_tmgr_event_t val;
+  unsigned int cpt;
+  p_trace = 0;
+
+/* no availability file, fixed trace */
+  if (!power_trace) {
+    m_type = TRACE_FIXED;
+    m_value = value;
+    XBT_DEBUG("No availability trace. Constant value = %lf", value);
+    return;
+  }
+
+  /* only one point available, fixed trace */
+  if (xbt_dynar_length(power_trace->s_list.event_list) == 1) {
+    xbt_dynar_get_cpy(power_trace->s_list.event_list, 0, &val);
+    m_type = TRACE_FIXED;
+    m_value = val.value;
+    return;
+  }
+
+  m_type = TRACE_DYNAMIC;
+  p_powerTrace = power_trace;
+
+  /* count the total time of trace file */
+  xbt_dynar_foreach(power_trace->s_list.event_list, cpt, val) {
+    total_time += val.delta;
+  }
+  p_trace = new CpuTiTrace(power_trace);
+  m_lastTime = total_time;
+  m_total = p_trace->integrateSimple(0, total_time);
+
+  XBT_DEBUG("Total integral %lf, last_time %lf ",
+            m_total, m_lastTime);
+}
+
+/**
+ * \brief Binary search in array.
+ *  It returns the first point of the interval in which "a" is. 
+ * \param array    Array
+ * \param a        Value to search
+ * \param low     Low bound to search in array
+ * \param high    Upper bound to search in array
+ * \return Index of point
+*/
+int CpuTiTrace::binarySearch(double *array, double a, int low, int high)
+{
+  xbt_assert(low < high, "Wrong parameters: low (%d) should be smaller than"
+      " high (%d)", low, high);
+
+  int mid;
+  do {
+    mid = low + (high - low) / 2;
+    XBT_DEBUG("a %f low %d high %d mid %d value %f", a, low, high, mid,
+        array[mid]);
+
+    if (array[mid] > a)
+      high = mid;
+    else
+      low = mid;
+  }
+  while (low < high - 1);
+
+  return low;
+}
+
+/*************
+ * CallBacks *
+ *************/
+
+static void parse_cpu_ti_init(sg_platf_host_cbarg_t host){
+  ((CpuTiModelPtr)surf_cpu_model)->parseInit(host);
+}
+
+static void add_traces_cpu_ti(){
+  surf_cpu_model->addTraces();
+}
+
+static void cpu_ti_define_callbacks()
+{
+  sg_platf_host_add_cb(parse_cpu_ti_init);
+  sg_platf_postparse_add_cb(add_traces_cpu_ti);
+}
+
+/*********
+ * Model *
+ *********/
+
+void surf_cpu_model_init_ti()
+{
+  xbt_assert(!surf_cpu_model,"CPU model already initialized. This should not happen.");
+  surf_cpu_model = new CpuTiModel();
+  cpu_ti_define_callbacks();
+  ModelPtr model = static_cast<ModelPtr>(surf_cpu_model);
+  xbt_dynar_push(model_list, &model);
+}
+
+CpuTiModel::CpuTiModel() : CpuModel("cpu_ti")
+{
+  xbt_assert(!surf_cpu_model,"CPU model already initialized. This should not happen.");
+  ActionPtr action;
+  CpuTi cpu;
+
+  cpu_ti_running_action_set_that_does_not_need_being_checked =
+      xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+
+  cpu_ti_modified_cpu =
+      xbt_swag_new(xbt_swag_offset(cpu, p_modifiedCpuHookup));
+
+  cpu_ti_action_heap = xbt_heap_new(8, NULL);
+  xbt_heap_set_update_callback(cpu_ti_action_heap,
+                               cpu_ti_action_update_index_heap);
+}
+
+CpuTiModel::~CpuTiModel()
+{
+  void **cpu;
+  xbt_lib_cursor_t cursor;
+  char *key;
+
+  xbt_lib_foreach(host_lib, cursor, key, cpu){
+    if(cpu[SURF_CPU_LEVEL])
+    {
+        CpuTiPtr CPU = dynamic_cast<CpuTiPtr>(static_cast<ResourcePtr>(cpu[SURF_CPU_LEVEL]));
+        xbt_swag_free(CPU->p_actionSet);
+        delete CPU->p_availTrace;
+    }
+  }
+
+  surf_cpu_model = NULL;
+
+  xbt_swag_free
+      (cpu_ti_running_action_set_that_does_not_need_being_checked);
+  xbt_swag_free(cpu_ti_modified_cpu);
+  cpu_ti_running_action_set_that_does_not_need_being_checked = NULL;
+  xbt_heap_free(cpu_ti_action_heap);
+}
+
+void CpuTiModel::parseInit(sg_platf_host_cbarg_t host)
+{
+  createResource(host->id,
+        host->power_peak,
+        host->pstate,
+        host->power_scale,
+        host->power_trace,
+        host->core_amount,
+        host->initial_state,
+        host->state_trace,
+        host->properties);
+}
+
+CpuTiPtr CpuTiModel::createResource(const char *name,
+                              xbt_dynar_t powerPeak,
+                              int pstate,
+                           double powerScale,
+                           tmgr_trace_t powerTrace,
+                           int core,
+                           e_surf_resource_state_t stateInitial,
+                           tmgr_trace_t stateTrace,
+                           xbt_dict_t cpuProperties)
+{
+  tmgr_trace_t empty_trace;
+  s_tmgr_event_t val;
+  CpuTiActionPtr cpuAction;
+  xbt_assert(core==1,"Multi-core not handled with this model yet");
+  xbt_assert(!surf_cpu_resource_priv(surf_cpu_resource_by_name(name)),
+              "Host '%s' declared several times in the platform file",
+              name);
+  CpuTiPtr cpu = new CpuTi(this, name, powerPeak, pstate, powerScale, powerTrace,
+                          core, stateInitial, stateTrace, cpuProperties);
+  xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast<ResourcePtr>(cpu));
+  return (CpuTiPtr) xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+CpuTiActionPtr CpuTiModel::createAction(double cost, bool failed)
+{
+  return NULL;//new CpuTiAction(this, cost, failed);
+}
+
+double CpuTiModel::shareResources(double now)
+{
+  void *_cpu, *_cpu_next;
+  double min_action_duration = -1;
+
+/* iterates over modified cpus to update share resources */
+  xbt_swag_foreach_safe(_cpu, _cpu_next, cpu_ti_modified_cpu) {
+    static_cast<CpuTiPtr>(_cpu)->updateActionFinishDate(now);
+  }
+/* get the min next event if heap not empty */
+  if (xbt_heap_size(cpu_ti_action_heap) > 0)
+    min_action_duration = xbt_heap_maxkey(cpu_ti_action_heap) - now;
+
+  XBT_DEBUG("Share resources, min next event date: %f", min_action_duration);
+
+  return min_action_duration;
+}
+
+void CpuTiModel::updateActionsState(double now, double delta)
+{
+  while ((xbt_heap_size(cpu_ti_action_heap) > 0)
+         && (xbt_heap_maxkey(cpu_ti_action_heap) <= now)) {
+    CpuTiActionPtr action = (CpuTiActionPtr) xbt_heap_pop(cpu_ti_action_heap);
+    XBT_DEBUG("Action %p: finish", action);
+    action->m_finish = surf_get_clock();
+    /* set the remains to 0 due to precision problems when updating the remaining amount */
+    action->m_remains = 0;
+    action->setState(SURF_ACTION_DONE);
+    /* update remaining amount of all actions */
+    action->p_cpu->updateRemainingAmount(surf_get_clock());
+  }
+}
+
+void CpuTiModel::addTraces()
+{
+  xbt_dict_cursor_t cursor = NULL;
+  char *trace_name, *elm;
+
+  static int called = 0;
+
+  if (called)
+    return;
+  called = 1;
+
+/* connect all traces relative to hosts */
+  xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    CpuTiPtr cpu = static_cast<CpuTiPtr>(surf_cpu_resource_priv(surf_cpu_resource_by_name(elm)));
+
+    xbt_assert(cpu, "Host %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    if (cpu->p_stateEvent) {
+      XBT_DEBUG("Trace already configured for this CPU(%s), ignoring it",
+             elm);
+      continue;
+    }
+    XBT_DEBUG("Add state trace: %s to CPU(%s)", trace_name, elm);
+    cpu->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(cpu));
+  }
+
+  xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    CpuTiPtr cpu = dynamic_cast<CpuTiPtr>(static_cast<ResourcePtr>(surf_cpu_resource_priv(surf_cpu_resource_by_name(elm))));
+
+    xbt_assert(cpu, "Host %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    XBT_DEBUG("Add power trace: %s to CPU(%s)", trace_name, elm);
+    if (cpu->p_availTrace)
+      delete cpu->p_availTrace;
+
+    cpu->p_availTrace = new CpuTiTgmr(trace, cpu->m_powerScale);
+
+    /* add a fake trace event if periodicity == 0 */
+    if (trace && xbt_dynar_length(trace->s_list.event_list) > 1) {
+      s_tmgr_event_t val;
+      xbt_dynar_get_cpy(trace->s_list.event_list,
+                        xbt_dynar_length(trace->s_list.event_list) - 1, &val);
+      if (val.delta == 0) {
+        tmgr_trace_t empty_trace;
+        empty_trace = tmgr_empty_trace_new();
+        cpu->p_powerEvent =
+            tmgr_history_add_trace(history, empty_trace,
+                                   cpu->p_availTrace->m_lastTime, 0, static_cast<ResourcePtr>(cpu));
+      }
+    }
+  }
+}
+
+/************
+ * Resource *
+ ************/
+CpuTi::CpuTi(CpuTiModelPtr model, const char *name, xbt_dynar_t powerPeak,
+        int pstate, double powerScale, tmgr_trace_t powerTrace, int core,
+        e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace,
+       xbt_dict_t properties) :
+       Resource(model, name, properties), Cpu(model, name, properties) {
+  p_stateCurrent = stateInitial;
+  m_powerScale = powerScale;
+  m_core = core;
+  tmgr_trace_t empty_trace;            
+  s_tmgr_event_t val;          
+  xbt_assert(core==1,"Multi-core not handled with this model yet");
+  XBT_DEBUG("power scale %lf", powerScale);
+  p_availTrace = new CpuTiTgmr(powerTrace, powerScale);
+
+  CpuTiActionPtr action;
+  p_actionSet = xbt_swag_new(xbt_swag_offset(*action, p_cpuListHookup));
+
+  xbt_dynar_get_cpy(powerPeak, 0, &m_powerPeak);
+  xbt_dynar_free(&powerPeak);  /* kill memory leak */
+  m_pstate = pstate;
+  XBT_DEBUG("CPU create: peak=%f, pstate=%d", m_powerPeak, m_pstate);
+
+  p_modifiedCpuHookup.prev = 0;
+  p_modifiedCpuHookup.next = 0;
+
+  if (stateTrace)
+    p_stateEvent = tmgr_history_add_trace(history, stateTrace, 0.0, 0, static_cast<ResourcePtr>(this));
+  if (powerTrace && xbt_dynar_length(powerTrace->s_list.event_list) > 1) {
+    // add a fake trace event if periodicity == 0 
+    xbt_dynar_get_cpy(powerTrace->s_list.event_list,
+                      xbt_dynar_length(powerTrace->s_list.event_list) - 1, &val);
+    if (val.delta == 0) {
+      empty_trace = tmgr_empty_trace_new();
+      p_powerEvent =
+        tmgr_history_add_trace(history, empty_trace,
+                               p_availTrace->m_lastTime, 0, static_cast<ResourcePtr>(this));
+    }
+  }
+};
+
+void CpuTi::updateState(tmgr_trace_event_t event_type,
+                        double value, double date)
+{
+  void *_action;
+  CpuTiActionPtr action;
+
+  if (event_type == p_powerEvent) {
+    tmgr_trace_t power_trace;
+    CpuTiTgmrPtr trace;
+    s_tmgr_event_t val;
+
+    XBT_DEBUG("Finish trace date: %f value %lf date %f", surf_get_clock(),
+           value, date);
+    /* update remaining of actions and put in modified cpu swag */
+    updateRemainingAmount(date);
+    xbt_swag_insert(this, cpu_ti_modified_cpu);
+
+    power_trace = p_availTrace->p_powerTrace;
+    xbt_dynar_get_cpy(power_trace->s_list.event_list,
+                      xbt_dynar_length(power_trace->s_list.event_list) - 1, &val);
+    /* free old trace */
+    delete p_availTrace;
+    m_powerScale = val.value;
+
+    trace = new CpuTiTgmr(TRACE_FIXED, val.value);
+    XBT_DEBUG("value %f", val.value);
+
+    p_availTrace = trace;
+
+    if (tmgr_trace_event_free(event_type))
+      p_powerEvent = NULL;
+
+  } else if (event_type == p_stateEvent) {
+    if (value > 0) {
+      if(p_stateCurrent == SURF_RESOURCE_OFF)
+        xbt_dynar_push_as(host_that_restart, char*, (char *)m_name);
+      p_stateCurrent = SURF_RESOURCE_ON;
+    } else {
+      p_stateCurrent = SURF_RESOURCE_OFF;
+
+      /* put all action running on cpu to failed */
+      xbt_swag_foreach(_action, p_actionSet) {
+       action = static_cast<CpuTiActionPtr>(_action);
+        if (action->getState() == SURF_ACTION_RUNNING
+         || action->getState() == SURF_ACTION_READY
+         || action->getState() == SURF_ACTION_NOT_IN_THE_SYSTEM) {
+          action->m_finish = date;
+          action->setState(SURF_ACTION_FAILED);
+          if (action->m_indexHeap >= 0) {
+            CpuTiActionPtr heap_act = (CpuTiActionPtr)
+                xbt_heap_remove(cpu_ti_action_heap, action->m_indexHeap);
+            if (heap_act != action)
+              DIE_IMPOSSIBLE;
+          }
+        }
+      }
+    }
+    if (tmgr_trace_event_free(event_type))
+      p_stateEvent = NULL;
+  } else {
+    XBT_CRITICAL("Unknown event ! \n");
+    xbt_abort();
+  }
+
+  return;
+}
+
+void CpuTi::updateActionFinishDate(double now)
+{
+  void *_action;
+  CpuTiActionPtr action;
+  double sum_priority = 0.0, total_area, min_finish = -1;
+
+/* update remaning amount of actions */
+updateRemainingAmount(now);
+
+  xbt_swag_foreach(_action, p_actionSet) {
+    action = static_cast<CpuTiActionPtr>(_action);
+    /* action not running, skip it */
+    if (action->p_stateSet !=
+        surf_cpu_model->p_runningActionSet)
+      continue;
+
+    /* bogus priority, skip it */
+    if (action->m_priority <= 0)
+      continue;
+
+    /* action suspended, skip it */
+    if (action->m_suspended != 0)
+      continue;
+
+    sum_priority += 1.0 / action->m_priority;
+  }
+  m_sumPriority = sum_priority;
+
+  xbt_swag_foreach(_action, p_actionSet) {
+    action = static_cast<CpuTiActionPtr>(_action);
+    min_finish = -1;
+    /* action not running, skip it */
+    if (action->p_stateSet !=
+        surf_cpu_model->p_runningActionSet)
+      continue;
+
+    /* verify if the action is really running on cpu */
+    if (action->m_suspended == 0 && action->m_priority > 0) {
+      /* total area needed to finish the action. Used in trace integration */
+      total_area =
+          (action->m_remains) * sum_priority *
+           action->m_priority;
+
+      total_area /= m_powerPeak;
+
+      action->m_finish = p_availTrace->solve(now, total_area);
+      /* verify which event will happen before (max_duration or finish time) */
+      if (action->m_maxDuration != NO_MAX_DURATION &&
+          action->m_start + action->m_maxDuration < action->m_finish)
+        min_finish = action->m_start + action->m_maxDuration;
+      else
+        min_finish = action->m_finish;
+    } else {
+      /* put the max duration time on heap */
+      if (action->m_maxDuration != NO_MAX_DURATION)
+        min_finish = action->m_start + action->m_maxDuration;
+    }
+    /* add in action heap */
+    XBT_DEBUG("action(%p) index %d", action, action->m_indexHeap);
+    if (action->m_indexHeap >= 0) {
+      CpuTiActionPtr heap_act = (CpuTiActionPtr)
+          xbt_heap_remove(cpu_ti_action_heap, action->m_indexHeap);
+      if (heap_act != action)
+        DIE_IMPOSSIBLE;
+    }
+    if (min_finish != NO_MAX_DURATION)
+      xbt_heap_push(cpu_ti_action_heap, action, min_finish);
+
+    XBT_DEBUG
+        ("Update finish time: Cpu(%s) Action: %p, Start Time: %f Finish Time: %f Max duration %f",
+         m_name, action, action->m_start,
+         action->m_finish,
+         action->m_maxDuration);
+  }
+/* remove from modified cpu */
+  xbt_swag_remove(this, cpu_ti_modified_cpu);
+}
+
+bool CpuTi::isUsed()
+{
+  return xbt_swag_size(p_actionSet);
+}
+
+
+
+double CpuTi::getAvailableSpeed()
+{
+  m_powerScale = p_availTrace->getPowerScale(surf_get_clock());
+  return Cpu::getAvailableSpeed();
+}
+
+/**
+* \brief Update the remaining amount of actions
+*
+* \param  now    Current time
+*/
+void CpuTi::updateRemainingAmount(double now)
+{
+  double area_total;
+  void* _action;
+  CpuTiActionPtr action;
+
+  /* already updated */
+  if (m_lastUpdate >= now)
+    return;
+
+/* calcule the surface */
+  area_total = p_availTrace->integrate(m_lastUpdate, now) * m_powerPeak;
+  XBT_DEBUG("Flops total: %f, Last update %f", area_total,
+         m_lastUpdate);
+
+  xbt_swag_foreach(_action, p_actionSet) {
+    action = static_cast<CpuTiActionPtr>(_action);
+    /* action not running, skip it */
+    if (action->p_stateSet !=
+        getModel()->p_runningActionSet)
+      continue;
+
+    /* bogus priority, skip it */
+    if (action->m_priority <= 0)
+      continue;
+
+    /* action suspended, skip it */
+    if (action->m_suspended != 0)
+      continue;
+
+    /* action don't need update */
+    if (action->m_start >= now)
+      continue;
+
+    /* skip action that are finishing now */
+    if (action->m_finish >= 0
+        && action->m_finish <= now)
+      continue;
+
+    /* update remaining */
+    double_update(&(action->m_remains),
+                  area_total / (m_sumPriority *
+                                action->m_priority));
+    XBT_DEBUG("Update remaining action(%p) remaining %f", action,
+           action->m_remains);
+  }
+  m_lastUpdate = now;
+}
+
+CpuActionPtr CpuTi::execute(double size)
+{
+  return _execute(size);
+}
+
+CpuTiActionPtr CpuTi::_execute(double size)
+{
+  XBT_IN("(%s,%g)", m_name, size);
+  CpuTiActionPtr action = new CpuTiAction(static_cast<CpuTiModelPtr>(p_model), size, p_stateCurrent != SURF_RESOURCE_ON);
+
+  action->p_cpu = this;
+  action->m_indexHeap = -1;
+
+  xbt_swag_insert(this, cpu_ti_modified_cpu);
+
+  xbt_swag_insert(action, p_actionSet);
+
+  action->m_suspended = 0;        /* Should be useless because of the
+              »                     calloc but it seems to help valgrind... */
+
+  XBT_OUT();
+  return action;
+}
+
+
+CpuActionPtr CpuTi::sleep(double duration)
+{
+  if (duration > 0)
+    duration = MAX(duration, MAXMIN_PRECISION);
+
+  XBT_IN("(%s,%g)", m_name, duration);
+  CpuTiActionPtr action = _execute(1.0);
+  action->m_maxDuration = duration;
+  action->m_suspended = 2;
+  if (duration == NO_MAX_DURATION) {
+    /* Move to the *end* of the corresponding action set. This convention
+       is used to speed up update_resource_state  */
+    xbt_swag_remove(static_cast<ActionPtr>(action), action->p_stateSet);
+    action->p_stateSet = cpu_ti_running_action_set_that_does_not_need_being_checked;
+    xbt_swag_insert(static_cast<ActionPtr>(action), action->p_stateSet);
+  }
+  XBT_OUT();
+  return action;
+}
+
+void CpuTi::printCpuTiModel()
+{
+  std::cout << getModel()->getName() << "<<plop"<< std::endl;
+};
+
+/**********
+ * Action *
+ **********/
+static void cpu_ti_action_update_index_heap(void *action, int i)
+{
+  ((CpuTiActionPtr)action)->updateIndexHeap(i); 
+}
+void CpuTiAction::updateIndexHeap(int i)
+{
+  m_indexHeap = i;
+}
+
+void CpuTiAction::setState(e_surf_action_state_t state)
+{
+  Action::setState(state);
+  xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+}
+
+int CpuTiAction::unref()
+{
+  m_refcount--;
+  if (!m_refcount) {
+    xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+    /* remove from action_set */
+    xbt_swag_remove(this, p_cpu->p_actionSet);
+    /* remove from heap */
+    xbt_heap_remove(cpu_ti_action_heap, this->m_indexHeap);
+    xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+    delete this;
+    return 1;
+  }
+  return 0;
+}
+
+void CpuTiAction::cancel()
+{
+  this->setState(SURF_ACTION_FAILED);
+  xbt_heap_remove(cpu_ti_action_heap, this->m_indexHeap);
+  xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+  return;
+}
+
+void CpuTiAction::recycle()
+{
+  DIE_IMPOSSIBLE;
+}
+
+void CpuTiAction::suspend()
+{
+  XBT_IN("(%p)", this);
+  if (m_suspended != 2) {
+    m_suspended = 1;
+    xbt_heap_remove(cpu_ti_action_heap, m_indexHeap);
+    xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+  }
+  XBT_OUT();
+}
+
+void CpuTiAction::resume()
+{
+  XBT_IN("(%p)", this);
+  if (m_suspended != 2) {
+    m_suspended = 0;
+    xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+  }
+  XBT_OUT();
+}
+
+bool CpuTiAction::isSuspended()
+{
+  return m_suspended == 1;
+}
+
+void CpuTiAction::setMaxDuration(double duration)
+{
+  double min_finish;
+
+  XBT_IN("(%p,%g)", this, duration);
+
+  m_maxDuration = duration;
+
+  if (duration >= 0)
+    min_finish = (m_start + m_maxDuration) < m_finish ?
+                 (m_start + m_maxDuration) : m_finish;
+  else
+    min_finish = m_finish;
+
+/* add in action heap */
+  if (m_indexHeap >= 0) {
+    CpuTiActionPtr heap_act = (CpuTiActionPtr)
+        xbt_heap_remove(cpu_ti_action_heap, m_indexHeap);
+    if (heap_act != this)
+      DIE_IMPOSSIBLE;
+  }
+  xbt_heap_push(cpu_ti_action_heap, this, min_finish);
+
+  XBT_OUT();
+}
+
+void CpuTiAction::setPriority(double priority)
+{
+  XBT_IN("(%p,%g)", this, priority);
+  m_priority = priority;
+  xbt_swag_insert(p_cpu, cpu_ti_modified_cpu);
+  XBT_OUT();
+}
+
+double CpuTiAction::getRemains()
+{
+  XBT_IN("(%p)", this);
+  p_cpu->updateRemainingAmount(surf_get_clock());
+  XBT_OUT();
+  return m_remains;
+}
+
+static void check() {
+  CpuTiActionPtr cupAction = new CpuTiAction(NULL, 0, true);
+}
+
+#endif /* SURF_MODEL_CPUTI_H_ */
+
diff --git a/src/surf/cpu_ti.hpp b/src/surf/cpu_ti.hpp
new file mode 100644 (file)
index 0000000..cccac33
--- /dev/null
@@ -0,0 +1,178 @@
+#include "cpu.hpp"
+#include "trace_mgr_private.h"
+#include "surf/surf_routing.h"
+
+/* Epsilon */
+#define EPSILON 0.000000001
+
+/***********
+ * Classes *
+ ***********/
+class CpuTiTrace;
+typedef CpuTiTrace *CpuTiTracePtr;
+
+class CpuTiTgmr;
+typedef CpuTiTgmr *CpuTiTgmrPtr;
+
+class CpuTiModel;
+typedef CpuTiModel *CpuTiModelPtr;
+
+class CpuTi;
+typedef CpuTi *CpuTiPtr;
+
+class CpuTiAction;
+typedef CpuTiAction *CpuTiActionPtr;
+
+/*********
+ * Trace *
+ *********/
+class CpuTiTrace {
+public:
+  CpuTiTrace(tmgr_trace_t powerTrace);
+  ~CpuTiTrace();
+
+  double integrateSimple(double a, double b);
+  double integrateSimplePoint(double a);
+  double solveSimple(double a, double amount);
+
+  double *p_timePoints;
+  double *p_integral;
+  int m_nbPoints;
+  int binarySearch(double *array, double a, int low, int high);
+
+private:
+};
+
+enum trace_type {
+  
+  TRACE_FIXED,                /*< Trace fixed, no availability file */
+  TRACE_DYNAMIC               /*< Dynamic, availability file disponible */
+};
+
+class CpuTiTgmr {
+public:
+  CpuTiTgmr(trace_type type, double value): m_type(type), m_value(value){};
+  CpuTiTgmr(tmgr_trace_t power_trace, double value);
+  ~CpuTiTgmr();
+
+  double integrate(double a, double b);
+  double solve(double a, double amount);
+  double solveSomewhatSimple(double a, double amount);
+  double getPowerScale(double a);
+
+  trace_type m_type;
+  double m_value;                 /*< Percentage of cpu power disponible. Value fixed between 0 and 1 */
+
+  /* Dynamic */
+  double m_lastTime;             /*< Integral interval last point (discret time) */
+  double m_total;                 /*< Integral total between 0 and last_pointn */
+
+  CpuTiTracePtr p_trace;
+  tmgr_trace_t p_powerTrace;
+};
+
+
+/*********
+ * Model *
+ *********/
+class CpuTiModel : public CpuModel {
+public:
+  CpuTiModel();
+  ~CpuTiModel();
+
+  void parseInit(sg_platf_host_cbarg_t host);
+  CpuTiPtr createResource(const char *name,  xbt_dynar_t powerPeak,
+                          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);
+  CpuTiActionPtr createAction(double cost, bool failed);
+  double shareResources(double now);
+  void updateActionsState(double now, double delta);
+  void addTraces();
+
+protected:
+  void NotifyResourceTurnedOn(ResourcePtr r){};
+  void NotifyResourceTurnedOff(ResourcePtr r){};
+
+  void NotifyActionCancel(ActionPtr a){};
+  void NotifyActionResume(ActionPtr a){};
+  void NotifyActionSuspend(ActionPtr a){};
+};
+
+/************
+ * Resource *
+ ************/
+class CpuTi : public Cpu {
+public:
+  CpuTi() {};
+  CpuTi(CpuTiModelPtr model, const char *name, xbt_dynar_t powerPeak,
+        int pstate, double powerScale, tmgr_trace_t powerTrace, int core,
+        e_surf_resource_state_t stateInitial, tmgr_trace_t stateTrace,
+       xbt_dict_t properties) ;
+  ~CpuTi() {};
+
+  void updateState(tmgr_trace_event_t event_type, double value, double date);  
+  void updateActionFinishDate(double now);
+  bool isUsed();
+  void printCpuTiModel();
+  CpuActionPtr execute(double size);
+  CpuTiActionPtr _execute(double size);
+  CpuActionPtr sleep(double duration);
+  double getAvailableSpeed();
+
+  xbt_dynar_t getWattsRangeList() {};
+  double getCurrentWattsValue(double cpu_load) {};
+  void updateEnergy(double cpu_load) {};
+
+  double getCurrentPowerPeak() {};
+  double getPowerPeakAt(int pstate_index) {};
+  int getNbPstates() {};
+  void setPowerPeakAt(int pstate_index) {};
+  double getConsumedEnergy() {};
+
+  CpuTiTgmrPtr p_availTrace;       /*< Structure with data needed to integrate trace file */
+  tmgr_trace_event_t p_stateEvent;       /*< trace file with states events (ON or OFF) */
+  tmgr_trace_event_t p_powerEvent;       /*< trace file with availability events */
+  xbt_swag_t p_actionSet;        /*< set with all actions running on cpu */
+  s_xbt_swag_hookup_t p_modifiedCpuHookup;      /*< hookup to swag that indicates whether share resources must be recalculated or not */
+  double m_sumPriority;          /*< the sum of actions' priority that are running on cpu */
+  double m_lastUpdate;           /*< last update of actions' remaining amount done */
+
+  int m_pstate;                                                                /*< Current pstate (index in the power_peak_list)*/
+  double current_frequency;
+
+  void updateRemainingAmount(double now);
+};
+
+/**********
+ * Action *
+ **********/
+
+class CpuTiAction: public CpuAction {
+public:
+  CpuTiAction() {};
+  CpuTiAction(CpuTiModelPtr model, double cost, bool failed)
+  : Action(model, cost, failed), CpuAction(model, cost, failed) {
+       p_cpuListHookup.next = 0;
+       p_cpuListHookup.prev = 0;
+  };
+
+  void setState(e_surf_action_state_t state);
+  int unref();
+  void cancel();
+  void recycle();
+  void updateIndexHeap(int i);
+  void suspend();
+  void resume();
+  bool isSuspended();
+  void setMaxDuration(double duration);
+  void setPriority(double priority);
+  double getRemains();
+  CpuTiPtr p_cpu;
+  int m_indexHeap;
+  s_xbt_swag_hookup_t p_cpuListHookup;
+  int m_suspended;
+private:
+};
diff --git a/src/surf/fair_bottleneck.cpp b/src/surf/fair_bottleneck.cpp
new file mode 100644 (file)
index 0000000..b4a0994
--- /dev/null
@@ -0,0 +1,192 @@
+/* Copyright (c) 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/sysdep.h"
+#include "xbt/log.h"
+#include "solver.hpp"
+#include <stdlib.h>
+#include <math.h>
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_maxmin);
+#define SHOW_EXPR_G(expr) XBT_DEBUG(#expr " = %g",expr);
+#define SHOW_EXPR_D(expr) XBT_DEBUG(#expr " = %d",expr);
+#define SHOW_EXPR_P(expr) XBT_DEBUG(#expr " = %p",expr);
+
+void bottleneck_solve(lmm_system_t sys)
+{
+  lmm_variable_t var_next = NULL;
+  lmm_constraint_t cnst = NULL;
+  //s_lmm_constraint_t s_cnst;
+  lmm_constraint_t cnst_next = NULL;
+  xbt_swag_t cnst_list = NULL;
+  
+  xbt_swag_t elem_list = NULL;
+  int i;
+
+  static s_xbt_swag_t cnst_to_update;
+  vector<ConstraintPtr> cnstToUpdate;
+
+  if (!(lmm_system_modified(sys)))
+    return;
+
+  /* Init */
+
+  lmm_variable_t var = NULL;
+  lmm_element_t elem = NULL;  
+  std::vector<VariablePtr> *varList; 
+  std::vector<VariablePtr>::iterator varIt;
+  std::vector<ElementPtr> *elemList;  
+  std::vector<ElementPtr>::iterator elemIt;
+  std::vector<ConstraintPtr> *cnstList;
+  std::vector<ConstraintPtr>::iterator cnstIt;
+
+  varList = &(sys->m_variableSet);  
+  XBT_DEBUG("Variable set : %d", varList->size());
+  for (varIt=varList->begin(); varIt!=varList->end(); ++varIt) {
+    int nb = 0;
+    var = *varIt;
+    var->m_value = 0.0;
+    XBT_DEBUG("Handling variable %p", var);
+    sys->m_saturatedVariableSet.push_back(var);
+    for (elemIt=var->m_cnsts.begin(); elemIt!=var->m_cnsts.end(); ++elemIt) 
+      if ((*elemIt)->m_value == 0.0)
+       nb++; 
+    if ((nb == var->getNumberOfCnst()) && (var->m_weight > 0.0)) {
+      XBT_DEBUG("Err, finally, there is no need to take care of variable %p",
+               var);
+      sys->m_saturatedVariableSet.erase(std::find(sys->m_saturatedVariableSet.begin(), sys->m_saturatedVariableSet.end(), var));
+      var->m_value = 1.0;
+    }
+    if (var->m_weight <= 0.0) {
+      XBT_DEBUG("Err, finally, there is no need to take care of variable %p",
+             var);
+      sys->m_saturatedVariableSet.erase(std::find(sys->m_saturatedVariableSet.begin(), sys->m_saturatedVariableSet.end(), var));      
+    }
+  }
+  varList = &(sys->m_saturatedVariableSet);
+  cnstList = &(sys->m_activeConstraintSet);
+  XBT_DEBUG("Active constraints : %d", cnstList->size());
+  sys->m_saturatedConstraintSet.insert(sys->m_saturatedConstraintSet.end(), cnstList->begin(), cnstList->end());
+  cnstList = &(sys->m_saturatedConstraintSet);
+  for(cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt) {
+    (*cnstIt)->m_remaining = (*cnstIt)->m_bound;
+    (*cnstIt)->m_usage = 0.0;
+  }
+  XBT_DEBUG("Fair bottleneck Initialized");
+
+  /* 
+   * Compute Usage and store the variables that reach the maximum.
+   */
+
+  do {
+    if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
+      XBT_DEBUG("Fair bottleneck done");
+      lmm_print(sys);
+    }
+    XBT_DEBUG("******* Constraints to process: %d *******",
+           cnstList->size());
+    for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end();){
+      cnst = *cnstIt;
+      int nb = 0;
+      XBT_DEBUG("Processing cnst %p ", cnst);
+      elemList = &(cnst->m_elementSet);
+      cnst->m_usage = 0.0;
+      for(elemIt=elemList->begin(); elemIt!=elemList->end(); elemIt++) {
+        if (elem->p_variable->m_weight <= 0)
+          break;
+        if ((elem->m_value > 0)
+            && std::find(varList->begin(), varList->end(), elem->p_variable)!=varList->end());
+          nb++;
+      }
+      XBT_DEBUG("\tThere are %d variables", nb);
+      if (nb > 0 && !cnst->m_shared)
+        nb = 1;
+      if (!nb) {
+        cnst->m_remaining = 0.0;
+        cnst->m_usage = cnst->m_remaining;
+        cnstList->erase(std::find(cnstList->begin(), cnstList->end(), *cnstIt));       
+        continue;
+      }
+      cnst->m_usage = cnst->m_remaining / nb;
+      XBT_DEBUG("\tConstraint Usage %p : %f with %d variables", cnst,
+             cnst->m_usage, nb);
+      ++cnstIt;      
+    }
+
+    for (varIt=varList->begin(); varIt!=varList->end();){
+      var = *varIt;
+      double minInc =
+          var->m_cnsts.front()->p_constraint->m_usage / var->m_cnsts.front()->m_value;
+      for (elemIt=++var->m_cnsts.begin(); elemIt!=var->m_cnsts.end(); ++elemIt) {
+       elem = (*elemIt);
+        minInc = MIN(minInc, elem->p_constraint->m_usage / elem->m_value);
+      }
+      if (var->m_bound > 0)
+        minInc = MIN(minInc, var->m_bound - var->m_value);
+      var->m_mu = minInc;
+      XBT_DEBUG("Updating variable %p maximum increment: %g", var, var->m_mu);
+      var->m_value += var->m_mu;
+      if (var->m_value == var->m_bound) {
+        varList->erase(std::find(varList->begin(), varList->end(), var));      
+      } else 
+       ++varIt;
+    }
+
+    for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end();) {
+      cnst = *cnstIt;
+      XBT_DEBUG("Updating cnst %p ", cnst);
+      elemList = &(cnst->m_elementSet);
+      for (elemIt=elemList->begin(); elemIt!=elemList->end();++elemIt) {
+       elem = *elemIt;
+        if (elem->p_variable->m_weight <= 0)
+          break;
+        if (cnst->m_shared) {
+          XBT_DEBUG("\tUpdate constraint %p (%g) with variable %p by %g",
+                 cnst, cnst->m_remaining, elem->p_variable,
+                 elem->p_variable->m_mu);
+          double_update(&(cnst->m_remaining),
+                        elem->m_value * elem->p_variable->m_mu);
+        } else {
+          XBT_DEBUG
+              ("\tNon-Shared variable. Update constraint usage of %p (%g) with variable %p by %g",
+               cnst, cnst->m_usage, elem->p_variable, elem->p_variable->m_mu);
+          cnst->m_usage = MIN(cnst->m_usage, elem->m_value * elem->p_variable->m_mu);
+        }
+      }
+
+      if (!cnst->m_shared) {
+        XBT_DEBUG("\tUpdate constraint %p (%g) by %g",
+               cnst, cnst->m_remaining, cnst->m_usage);
+
+        double_update(&(cnst->m_remaining), cnst->m_usage);
+      }
+
+      XBT_DEBUG("\tRemaining for %p : %g", cnst, cnst->m_remaining);
+      if (cnst->m_remaining == 0.0) {
+        XBT_DEBUG("\tGet rid of constraint %p", cnst);
+
+        cnstList->erase(std::find(cnstList->begin(), cnstList->end(), cnst));
+
+        for (elemIt=elemList->begin(); elemIt!=elemList->end();++elemIt) {
+          if (elem->p_variable->m_weight <= 0)
+            break;
+          if (elem->m_value > 0) {
+            XBT_DEBUG("\t\tGet rid of variable %p", elem->p_variable);
+            varList->erase(std::find(varList->begin(), varList->end(), elem->p_variable));     
+          }
+        }
+      } else
+       ++cnstIt;
+    }
+  } while (!varList->empty());
+  
+  cnstList->clear();
+  sys->m_modified = 0;
+  if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
+    XBT_DEBUG("Fair bottleneck done");
+    sys->print();
+  }
+}
index e3e652f..35a0118 100644 (file)
@@ -8,7 +8,7 @@
 
 #ifdef HAVE_TRACING
 #include "surf/surf_private.h"
-#include "surf/network_private.h"
+//FIXME:#include "surf/network_private.h"
 #include "xbt/graph.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY (instr_routing, instr, "Tracing platform hierarchy");
@@ -130,14 +130,14 @@ static void recursiveGraphExtraction (AS_t rc, container_t container, xbt_dict_t
     XBT_DEBUG("Graph extraction disabled by user.");
     return;
   }
-  XBT_DEBUG ("Graph extraction for routing_component = %s", rc->name);
-  if (!xbt_dict_is_empty(rc->routing_sons)){
+  XBT_DEBUG ("Graph extraction for routing_component = %s", surf_AS_get_name(rc));
+  if (!xbt_dict_is_empty(surf_AS_get_routing_sons(rc))){
     xbt_dict_cursor_t cursor = NULL;
     AS_t rc_son;
     char *child_name;
     //bottom-up recursion
-    xbt_dict_foreach(rc->routing_sons, cursor, child_name, rc_son) {
-      container_t child_container = xbt_dict_get (container->children, rc_son->name);
+    xbt_dict_foreach(surf_AS_get_routing_sons(rc), cursor, child_name, rc_son) {
+      container_t child_container = xbt_dict_get (container->children, surf_AS_get_name(rc_son));
       recursiveGraphExtraction (rc_son, child_container, filter);
     }
   }
@@ -151,7 +151,7 @@ static void recursiveGraphExtraction (AS_t rc, container_t container, xbt_dict_t
     xbt_dict_cursor_t cursor = NULL;
     char *edge_name;
 
-    rc->get_graph(graph,nodes,edges,rc);
+    surf_AS_get_graph(rc, graph, nodes, edges);
     xbt_dict_foreach(edges,cursor,edge_name,edge) {
         linkContainers(PJ_container_get(edge->src->data), PJ_container_get(edge->dst->data), filter);
     }
@@ -329,7 +329,7 @@ static void instr_routing_parse_end_platform ()
   currentContainer = NULL;
   xbt_dict_t filter = xbt_dict_new_homogeneous(xbt_free);
   XBT_DEBUG ("Starting graph extraction.");
-  recursiveGraphExtraction (routing_platf->root, PJ_container_get_root(), filter);
+  recursiveGraphExtraction (surf_platf_get_root(routing_platf), PJ_container_get_root(), filter);
   XBT_DEBUG ("Graph extraction finished.");
   xbt_dict_free(&filter);
   platform_created = 1;
@@ -449,18 +449,18 @@ int instr_platform_traced ()
 static void recursiveXBTGraphExtraction (xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges,
     AS_t rc, container_t container)
 {
-  if (!xbt_dict_is_empty(rc->routing_sons)){
+  if (!xbt_dict_is_empty(surf_AS_get_routing_sons(rc))){
     xbt_dict_cursor_t cursor = NULL;
     AS_t rc_son;
     char *child_name;
     //bottom-up recursion
-    xbt_dict_foreach(rc->routing_sons, cursor, child_name, rc_son) {
-      container_t child_container = xbt_dict_get (container->children, rc_son->name);
+    xbt_dict_foreach(surf_AS_get_routing_sons(rc), cursor, child_name, rc_son) {
+      container_t child_container = xbt_dict_get (container->children, surf_AS_get_name(rc_son));
       recursiveXBTGraphExtraction (graph, nodes, edges, rc_son, child_container);
     }
   }
 
-  rc->get_graph(graph,nodes,edges,rc);
+  surf_AS_get_graph(rc, graph, nodes, edges);
 }
 
 xbt_graph_t instr_routing_platform_graph (void)
@@ -468,7 +468,7 @@ xbt_graph_t instr_routing_platform_graph (void)
   xbt_graph_t ret = xbt_graph_new_graph (0, NULL);
   xbt_dict_t nodes = xbt_dict_new_homogeneous(NULL);
   xbt_dict_t edges = xbt_dict_new_homogeneous(NULL);
-  recursiveXBTGraphExtraction (ret, nodes, edges, routing_platf->root, PJ_container_get_root());
+  recursiveXBTGraphExtraction (ret, nodes, edges, surf_platf_get_root(routing_platf), PJ_container_get_root());
   xbt_dict_free (&nodes);
   xbt_dict_free (&edges);
   return ret;
index e9570dd..71e63b4 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "instr/instr_private.h"
 #include "surf/surf_private.h"
-#include "surf/network_gtnets_private.h"
+//FIXME:#include "surf/network_gtnets_private.h"
 
 #ifdef HAVE_TRACING
 
@@ -43,9 +43,9 @@ void TRACE_surf_link_set_bandwidth(double date, const char *resource, double ban
 /* to trace gtnets */
 void TRACE_surf_gtnets_communicate(void *action, void *src, void *dst)
 {
-  surf_action_network_GTNETS_t gtnets_action = (surf_action_network_GTNETS_t)action;
+  /*FIXME:surf_action_network_GTNETS_t gtnets_action = (surf_action_network_GTNETS_t)action;
   gtnets_action->src = src;
-  gtnets_action->dst = dst;
+  gtnets_action->dst = dst;*/
 }
 
 void TRACE_surf_action(surf_action_t surf_action, const char *category)
@@ -57,6 +57,6 @@ void TRACE_surf_action(surf_action_t surf_action, const char *category)
   if (!category)
     return;
 
-  surf_action->category = xbt_strdup(category);
+  surf_action_set_category(surf_action, xbt_strdup(category));
 }
 #endif /* HAVE_TRACING */
diff --git a/src/surf/lagrange.cpp b/src/surf/lagrange.cpp
new file mode 100644 (file)
index 0000000..1b4cc95
--- /dev/null
@@ -0,0 +1,674 @@
+/* Copyright (c) 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. */
+
+/*
+ * Modelling the proportional fairness using the Lagrange Optimization 
+ * Approach. For a detailed description see:
+ * "ssh://username@scm.gforge.inria.fr/svn/memo/people/pvelho/lagrange/ppf.ps".
+ */
+#include "xbt/log.h"
+#include "xbt/sysdep.h"
+//#include "maxmin_private.h"
+#include "solver.h"
+#include "solver.hpp"
+#include <stdlib.h>
+#ifndef MATH
+#include <math.h>
+#endif
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_lagrange, surf,
+                                "Logging specific to SURF (lagrange)");
+XBT_LOG_NEW_SUBCATEGORY(surf_lagrange_dichotomy, surf_lagrange,
+                        "Logging specific to SURF (lagrange dichotomy)");
+
+#define SHOW_EXPR(expr) XBT_CDEBUG(surf_lagrange,#expr " = %g",expr);
+
+double (*func_f_def) (lmm_variable_t, double);
+double (*func_fp_def) (lmm_variable_t, double);
+double (*func_fpi_def) (lmm_variable_t, double);
+
+/*
+ * Local prototypes to implement the lagrangian optimization with optimal step, also called dichotomy.
+ */
+//solves the proportional fairness using a lagrange optimizition with dichotomy step
+void lagrange_solve(lmm_system_t sys);
+//computes the value of the dichotomy using a initial values, init, with a specific variable or constraint
+static double dichotomy(double init, double diff(double, void *),
+                        void *var_cnst, double min_error);
+//computes the value of the differential of constraint param_cnst applied to lambda  
+static double partial_diff_lambda(double lambda, void *param_cnst);
+
+static int __check_feasible(std::vector<ConstraintPtr> *cnstList, std::vector<VariablePtr> *varList,
+                            int warn)
+{
+  std::vector<ElementPtr> *elemList = NULL;
+  lmm_element_t elem = NULL;
+  lmm_constraint_t cnst = NULL;
+  lmm_variable_t var = NULL;
+  std::vector<VariablePtr>::iterator varIt;
+  std::vector<ElementPtr>::iterator elemIt;
+  std::vector<ConstraintPtr>::iterator cnstIt;
+
+  double tmp;
+
+  for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt) {
+    cnst = (*cnstIt);
+    tmp = 0;
+    elemList = &(cnst->m_elementSet);
+    for (elemIt=elemList->begin(); elemIt!=elemList->end(); ++elemIt) {
+      var = (*elemIt)->p_variable;
+      if (var->m_weight <= 0)
+        continue;
+      tmp += var->m_value;
+    }
+
+    if (double_positive(tmp - cnst->m_bound)) {
+      if (warn)
+        XBT_WARN
+            ("The link (%p) is over-used. Expected less than %f and got %f",
+             cnst, cnst->m_bound, tmp);
+      return 0;
+    }
+    XBT_DEBUG
+        ("Checking feasability for constraint (%p): sat = %f, lambda = %f ",
+         cnst, tmp - cnst->m_bound, cnst->m_lambda);
+  }
+
+  for (varIt=varList->begin(); varIt!=varList->end(); ++varIt) {
+    if (!var->m_weight)
+      break;
+    if (var->m_bound < 0)
+      continue;
+    XBT_DEBUG("Checking feasability for variable (%p): sat = %f mu = %f", var,
+           var->m_value - var->m_bound, var->m_mu);
+
+    if (double_positive(var->m_value - var->m_bound)) {
+      if (warn)
+        XBT_WARN
+            ("The variable (%p) is too large. Expected less than %f and got %f",
+             var, var->m_bound, var->m_value);
+      return 0;
+    }
+  }  
+  return 1;
+}
+
+static double new_value(lmm_variable_t var)
+{
+  double tmp = 0;
+  int i;
+  std::vector<ElementPtr>::iterator elemIt;
+
+  for (elemIt=var->m_cnsts.begin(); elemIt!=var->m_cnsts.end(); ++elemIt) {
+    tmp += ((*elemIt)->p_constraint)->m_lambda;
+  }
+  if (var->m_bound > 0)
+    tmp += var->m_mu;
+  XBT_DEBUG("\t Working on var (%p). cost = %e; Weight = %e", var, tmp,
+         var->m_weight);
+  //uses the partial differential inverse function
+  return var->p_funcFPI(var, tmp);
+}
+
+static double new_mu(lmm_variable_t var)
+{
+  double mu_i = 0.0;
+  double sigma_i = 0.0;
+  int j;
+  std::vector<ElementPtr>::iterator elemIt;
+
+  for (elemIt=var->m_cnsts.begin(); elemIt!=var->m_cnsts.end(); ++elemIt) {
+    sigma_i += ((*elemIt)->p_constraint)->m_lambda;
+  }
+  mu_i = var->p_funcFP(var, var->m_bound) - sigma_i;
+  if (mu_i < 0.0)
+    return 0.0;
+  return mu_i;
+}
+
+static double dual_objective(std::vector<VariablePtr> *varList, std::vector<ConstraintPtr> *cnstList)
+{
+  lmm_constraint_t cnst = NULL;
+  lmm_variable_t var = NULL;
+
+  double obj = 0.0;
+  std::vector<VariablePtr>::iterator varIt;
+  std::vector<ElementPtr>::iterator elemIt;
+  std::vector<ConstraintPtr>::iterator cnstIt;
+
+  for (varIt=varList->begin(); varIt!=varList->end(); ++varIt) {
+    var = (*varIt);
+    double sigma_i = 0.0;
+    int j;
+
+    if (!var->m_weight)
+      break;
+
+    for (elemIt=var->m_cnsts.begin(); elemIt!=var->m_cnsts.end(); ++elemIt)
+      sigma_i += ((*elemIt)->p_constraint)->m_lambda;
+       
+    if (var->m_bound > 0)
+      sigma_i += var->m_mu;
+
+    XBT_DEBUG("var %p : sigma_i = %1.20f", var, sigma_i);
+
+    obj += var->p_funcF(var, var->p_funcFPI(var, sigma_i)) -
+        sigma_i * var->p_funcFPI(var, sigma_i);
+
+    if (var->m_bound > 0)
+      obj += var->m_mu * var->m_bound;
+  }
+
+  for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt)
+    obj += (*cnstIt)->m_lambda * (*cnstIt)->m_bound;
+  
+  return obj;
+}
+
+void lagrange_solve(lmm_system_t sys)
+{
+  /*
+   * Lagrange Variables.
+   */
+  int max_iterations = 100;
+  double epsilon_min_error = MAXMIN_PRECISION;
+  double dichotomy_min_error = 1e-14;
+  double overall_modification = 1;
+
+  /*
+   * Variables to manipulate the data structure proposed to model the maxmin
+   * fairness. See docummentation for more details.
+   */
+  std::vector<ConstraintPtr> *cnstList = NULL;
+  std::vector<ConstraintPtr>::iterator cnstIt;  
+  lmm_constraint_t cnst = NULL;
+
+  std::vector<VariablePtr> *varList = NULL;
+  std::vector<VariablePtr>::iterator varIt;  
+  lmm_variable_t var = NULL;
+
+  std::vector<ElementPtr>::iterator elemIt;  
+
+  /*
+   * Auxiliar variables.
+   */
+  int iteration = 0;
+  double tmp = 0;
+  int i;
+  double obj, new_obj;
+
+  XBT_DEBUG("Iterative method configuration snapshot =====>");
+  XBT_DEBUG("#### Maximum number of iterations       : %d", max_iterations);
+  XBT_DEBUG("#### Minimum error tolerated            : %e",
+         epsilon_min_error);
+  XBT_DEBUG("#### Minimum error tolerated (dichotomy) : %e",
+         dichotomy_min_error);
+
+  if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) {
+    lmm_print(sys);
+  }
+
+  if (!(sys->m_modified))
+    return;
+
+  /* 
+   * Initialize lambda.
+   */
+  cnstList = &(sys->m_activeConstraintSet);
+  for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt) {
+    cnst = *cnstIt;
+    cnst->m_lambda = 1.0;
+    cnst->m_newLambda = 2.0;
+    XBT_DEBUG("#### cnst(%p)->lambda :  %e", cnst, cnst->m_lambda);
+  }
+
+  /* 
+   * Initialize the var list variable with only the active variables. 
+   * Associate an index in the swag variables. Initialize mu.
+   */
+  varList = &(sys->m_variableSet);
+  i = 0;
+  for (varIt=varList->begin(); varIt!=varList->end(); ++varIt) {
+    var = *varIt;
+    if (!var->m_weight)
+      var->m_value = 0.0;
+    else {
+      int nb = 0;
+      if (var->m_bound < 0.0) {
+        XBT_DEBUG("#### NOTE var(%d) is a boundless variable", i);
+        var->m_mu = -1.0;
+        var->m_value = new_value(var);
+      } else {
+        var->m_mu = 1.0;
+        var->m_newMu = 2.0;
+        var->m_value = new_value(var);
+      }
+      XBT_DEBUG("#### var(%p) ->weight :  %e", var, var->m_weight);
+      XBT_DEBUG("#### var(%p) ->mu :  %e", var, var->m_mu);
+      XBT_DEBUG("#### var(%p) ->weight: %e", var, var->m_weight);
+      XBT_DEBUG("#### var(%p) ->bound: %e", var, var->m_bound);
+      for (elemIt=var->m_cnsts.begin(); elemIt!=var->m_cnsts.end(); ++elemIt) {
+        if ((*elemIt)->m_value == 0.0)
+          nb++;
+      }
+      if (nb == var->m_cnsts.size())
+        var->m_value = 1.0;
+    }
+  }
+
+  /* 
+   * Compute dual objective.
+   */
+  obj = dual_objective(varList, cnstList);
+
+  /*
+   * While doesn't reach a minimun error or a number maximum of iterations.
+   */
+  while (overall_modification > epsilon_min_error
+         && iteration < max_iterations) {
+/*     int dual_updated=0; */
+
+    iteration++;
+    XBT_DEBUG("************** ITERATION %d **************", iteration);
+    XBT_DEBUG("-------------- Gradient Descent ----------");
+
+    /*                       
+     * Improve the value of mu_i
+     */
+    for (varIt=varList->begin(); varIt!=varList->end(); ++varIt) {
+      var = *varIt;    
+      if (!var->m_weight)
+        break;
+      if (var->m_bound >= 0) {
+        XBT_DEBUG("Working on var (%p)", var);
+        var->m_newMu = new_mu(var);
+/*   dual_updated += (fabs(var->new_mu-var->mu)>dichotomy_min_error); */
+/*   XBT_DEBUG("dual_updated (%d) : %1.20f",dual_updated,fabs(var->new_mu-var->mu)); */
+        XBT_DEBUG("Updating mu : var->mu (%p) : %1.20f -> %1.20f", var,
+               var->m_mu, var->m_newMu);
+        var->m_mu = var->m_newMu;
+
+        new_obj = dual_objective(varList, cnstList);
+        XBT_DEBUG("Improvement for Objective (%g -> %g) : %g", obj, new_obj,
+               obj - new_obj);
+        xbt_assert(obj - new_obj >= -epsilon_min_error,
+                    "Our gradient sucks! (%1.20f)", obj - new_obj);
+        obj = new_obj;
+      }
+    }
+
+    /*
+     * Improve the value of lambda_i
+     */
+    for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt) {
+      cnst = *cnstIt;
+      XBT_DEBUG("Working on cnst (%p)", cnst);
+      cnst->m_newLambda =
+          dichotomy(cnst->m_lambda, partial_diff_lambda, cnst,
+                    dichotomy_min_error);
+/*       dual_updated += (fabs(cnst->new_lambda-cnst->lambda)>dichotomy_min_error); */
+/*       XBT_DEBUG("dual_updated (%d) : %1.20f",dual_updated,fabs(cnst->new_lambda-cnst->lambda)); */
+      XBT_DEBUG("Updating lambda : cnst->lambda (%p) : %1.20f -> %1.20f",
+             cnst, cnst->m_lambda, cnst->m_newLambda);
+      cnst->m_lambda = cnst->m_newLambda;
+
+      new_obj = dual_objective(varList, cnstList);
+      XBT_DEBUG("Improvement for Objective (%g -> %g) : %g", obj, new_obj,
+             obj - new_obj);
+      xbt_assert(obj - new_obj >= -epsilon_min_error,
+                  "Our gradient sucks! (%1.20f)", obj - new_obj);
+      obj = new_obj;
+    }
+
+    /*
+     * Now computes the values of each variable (\rho) based on
+     * the values of \lambda and \mu.
+     */
+    XBT_DEBUG("-------------- Check convergence ----------");
+    overall_modification = 0;
+    for (varIt=varList->begin(); varIt!=varList->end(); ++varIt) {
+      var = *varIt;
+      if (var->m_weight <= 0)
+        var->m_value = 0.0;
+      else {
+        tmp = new_value(var);
+
+        overall_modification =
+            MAX(overall_modification, fabs(var->m_value - tmp));
+
+        var->m_value = tmp;
+        XBT_DEBUG("New value of var (%p)  = %e, overall_modification = %e",
+               var, var->m_value, overall_modification);
+      }
+    }
+
+    XBT_DEBUG("-------------- Check feasability ----------");
+    if (!__check_feasible(cnstList, varList, 0))
+      overall_modification = 1.0;
+    XBT_DEBUG("Iteration %d: overall_modification : %f", iteration,
+           overall_modification);
+/*     if(!dual_updated) { */
+/*       XBT_WARN("Could not improve the convergence at iteration %d. Drop it!",iteration); */
+/*       break; */
+/*     } */
+  }
+  __check_feasible(cnstList, varList, 1);
+
+  if (overall_modification <= epsilon_min_error) {
+    XBT_DEBUG("The method converges in %d iterations.", iteration);
+  }
+  if (iteration >= max_iterations) {
+    XBT_DEBUG
+        ("Method reach %d iterations, which is the maximum number of iterations allowed.",
+         iteration);
+  }
+/*   XBT_INFO("Method converged after %d iterations", iteration); */
+
+  if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) {
+    lmm_print(sys);
+  }
+}
+
+/*
+ * Returns a double value corresponding to the result of a dichotomy proccess with
+ * respect to a given variable/constraint (\mu in the case of a variable or \lambda in
+ * case of a constraint) and a initial value init. 
+ *
+ * @param init initial value for \mu or \lambda
+ * @param diff a function that computes the differential of with respect a \mu or \lambda
+ * @param var_cnst a pointer to a variable or constraint 
+ * @param min_erro a minimun error tolerated
+ *
+ * @return a double correponding to the result of the dichotomyal process
+ */
+static double dichotomy(double init, double diff(double, void *),
+                        void *var_cnst, double min_error)
+{
+  #ifdef TOREPAIR
+  double min, max;
+  double overall_error;
+  double middle;
+  double min_diff, max_diff, middle_diff;
+  double diff_0 = 0.0;
+  min = max = init;
+
+  XBT_IN();
+
+  if (init == 0.0) {
+    min = max = 0.5;
+  }
+
+  min_diff = max_diff = middle_diff = 0.0;
+  overall_error = 1;
+
+  if ((diff_0 = diff(1e-16, var_cnst)) >= 0) {
+    XBT_CDEBUG(surf_lagrange_dichotomy, "returning 0.0 (diff = %e)", diff_0);
+    XBT_OUT();
+    return 0.0;
+  }
+
+  min_diff = diff(min, var_cnst);
+  max_diff = diff(max, var_cnst);
+
+  while (overall_error > min_error) {
+    XBT_CDEBUG(surf_lagrange_dichotomy,
+            "[min, max] = [%1.20f, %1.20f] || diffmin, diffmax = %1.20f, %1.20f",
+            min, max, min_diff, max_diff);
+
+    if (min_diff > 0 && max_diff > 0) {
+      if (min == max) {
+        XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing min");
+        min = min / 2.0;
+        min_diff = diff(min, var_cnst);
+      } else {
+        XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing max");
+        max = min;
+        max_diff = min_diff;
+      }
+    } else if (min_diff < 0 && max_diff < 0) {
+      if (min == max) {
+        XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing max");
+        max = max * 2.0;
+        max_diff = diff(max, var_cnst);
+      } else {
+        XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing min");
+        min = max;
+        min_diff = max_diff;
+      }
+    } else if (min_diff < 0 && max_diff > 0) {
+      middle = (max + min) / 2.0;
+      XBT_CDEBUG(surf_lagrange_dichotomy, "Trying (max+min)/2 : %1.20f",
+              middle);
+
+      if ((min == middle) || (max == middle)) {
+        XBT_CWARN(surf_lagrange_dichotomy,
+               "Cannot improve the convergence! min=max=middle=%1.20f, diff = %1.20f."
+               " Reaching the 'double' limits. Maybe scaling your function would help ([%1.20f,%1.20f]).",
+               min, max - min, min_diff, max_diff);
+        break;
+      }
+      middle_diff = diff(middle, var_cnst);
+
+      if (middle_diff < 0) {
+        XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing min");
+        min = middle;
+        overall_error = max_diff - middle_diff;
+        min_diff = middle_diff;
+/*   SHOW_EXPR(overall_error); */
+      } else if (middle_diff > 0) {
+        XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing max");
+        max = middle;
+        overall_error = max_diff - middle_diff;
+        max_diff = middle_diff;
+/*   SHOW_EXPR(overall_error); */
+      } else {
+        overall_error = 0;
+/*   SHOW_EXPR(overall_error); */
+      }
+    } else if (min_diff == 0) {
+      max = min;
+      overall_error = 0;
+/*       SHOW_EXPR(overall_error); */
+    } else if (max_diff == 0) {
+      min = max;
+      overall_error = 0;
+/*       SHOW_EXPR(overall_error); */
+    } else if (min_diff > 0 && max_diff < 0) {
+      XBT_CWARN(surf_lagrange_dichotomy,
+             "The impossible happened, partial_diff(min) > 0 && partial_diff(max) < 0");
+      xbt_abort();
+    } else {
+      XBT_CWARN(surf_lagrange_dichotomy,
+             "diffmin (%1.20f) or diffmax (%1.20f) are something I don't know, taking no action.",
+             min_diff, max_diff);
+      xbt_abort();
+    }
+  }
+
+  XBT_CDEBUG(surf_lagrange_dichotomy, "returning %e", (min + max) / 2.0);
+  XBT_OUT();
+  return ((min + max) / 2.0);
+  #endif
+}
+
+static double partial_diff_lambda(double lambda, void *param_cnst)
+{
+  #ifdef TOREPAIR
+  int j;
+  xbt_swag_t elem_list = NULL;
+  lmm_element_t elem = NULL;
+  lmm_variable_t var = NULL;
+  lmm_constraint_t cnst = (lmm_constraint_t) param_cnst;
+  double diff = 0.0;
+  double sigma_i = 0.0;
+
+  XBT_IN();
+  elem_list = &(cnst->element_set);
+
+  XBT_CDEBUG(surf_lagrange_dichotomy, "Computing diff of cnst (%p)", cnst);
+
+  xbt_swag_foreach(elem, elem_list) {
+    var = elem->variable;
+    if (var->weight <= 0)
+      continue;
+
+    XBT_CDEBUG(surf_lagrange_dichotomy, "Computing sigma_i for var (%p)",
+            var);
+    // Initialize the summation variable
+    sigma_i = 0.0;
+
+    // Compute sigma_i 
+    for (j = 0; j < var->cnsts_number; j++) {
+      sigma_i += (var->cnsts[j].constraint)->lambda;
+    }
+
+    //add mu_i if this flow has a RTT constraint associated
+    if (var->bound > 0)
+      sigma_i += var->mu;
+
+    //replace value of cnst->lambda by the value of parameter lambda
+    sigma_i = (sigma_i - cnst->lambda) + lambda;
+
+    diff += -var->func_fpi(var, sigma_i);
+  }
+
+
+  diff += cnst->bound;
+
+  XBT_CDEBUG(surf_lagrange_dichotomy,
+          "d D/d lambda for cnst (%p) at %1.20f = %1.20f", cnst, lambda,
+          diff);
+  XBT_OUT();
+  return diff;
+  #endif
+}
+
+/** \brief Attribute the value bound to var->bound.
+ * 
+ *  \param func_fpi  inverse of the partial differential of f (f prime inverse, (f')^{-1})
+ * 
+ *  Set default functions to the ones passed as parameters. This is a polimorfism in C pure, enjoy the roots of programming.
+ *
+ */
+void lmm_set_default_protocol_function(double (*func_f) (lmm_variable_t var, double x),
+                                       double (*func_fp) (lmm_variable_t var, double x),
+                                       double (*func_fpi) (lmm_variable_t var, double x))
+{
+  func_f_def = func_f;
+  func_fp_def = func_fp;
+  func_fpi_def = func_fpi;
+}
+
+
+/**************** Vegas and Reno functions *************************/
+/*
+ * NOTE for Reno: all functions consider the network
+ * coeficient (alpha) equal to 1.
+ */
+
+/*
+ * For Vegas: $f(x) = \alpha D_f\ln(x)$
+ * Therefore: $fp(x) = \frac{\alpha D_f}{x}$
+ * Therefore: $fpi(x) = \frac{\alpha D_f}{x}$
+ */
+#define VEGAS_SCALING 1000.0
+
+double func_vegas_f(lmm_variable_t var, double x)
+{
+  #ifdef TOREPAIR  
+  xbt_assert(x > 0.0, "Don't call me with stupid values! (%1.20f)", x);
+  return VEGAS_SCALING * var->weight * log(x);
+  #endif
+}
+
+double func_vegas_fp(lmm_variable_t var, double x)
+{
+  #ifdef TOREPAIR  
+  xbt_assert(x > 0.0, "Don't call me with stupid values! (%1.20f)", x);
+  return VEGAS_SCALING * var->weight / x;
+  #endif
+}
+
+double func_vegas_fpi(lmm_variable_t var, double x)
+{
+  #ifdef TOREPAIR  
+  xbt_assert(x > 0.0, "Don't call me with stupid values! (%1.20f)", x);
+  return var->weight / (x / VEGAS_SCALING);
+  #endif
+}
+
+/*
+ * For Reno:  $f(x) = \frac{\sqrt{3/2}}{D_f} atan(\sqrt{3/2}D_f x)$
+ * Therefore: $fp(x)  = \frac{3}{3 D_f^2 x^2+2}$
+ * Therefore: $fpi(x)  = \sqrt{\frac{1}{{D_f}^2 x} - \frac{2}{3{D_f}^2}}$
+ */
+#define RENO_SCALING 1.0
+double func_reno_f(lmm_variable_t var, double x)
+{
+  xbt_assert(var->m_weight > 0.0, "Don't call me with stupid values!");
+
+  return RENO_SCALING * sqrt(3.0 / 2.0) / var->m_weight *
+      atan(sqrt(3.0 / 2.0) * var->m_weight * x);
+}
+
+double func_reno_fp(lmm_variable_t var, double x)
+{
+  return RENO_SCALING * 3.0 / (3.0 * var->m_weight * var->m_weight * x * x +
+                               2.0);
+}
+
+double func_reno_fpi(lmm_variable_t var, double x)
+{
+  double res_fpi;
+
+  xbt_assert(var->m_weight > 0.0, "Don't call me with stupid values!");
+  xbt_assert(x > 0.0, "Don't call me with stupid values!");
+
+  res_fpi =
+      1.0 / (var->m_weight * var->m_weight * (x / RENO_SCALING)) -
+      2.0 / (3.0 * var->m_weight * var->m_weight);
+  if (res_fpi <= 0.0)
+    return 0.0;
+//   xbt_assert(res_fpi>0.0,"Don't call me with stupid values!"); 
+  return sqrt(res_fpi);
+}
+
+
+/* Implementing new Reno-2
+ * For Reno-2:  $f(x)   = U_f(x_f) = \frac{{2}{D_f}}*ln(2+x*D_f)$
+ * Therefore:   $fp(x)  = 2/(Weight*x + 2)
+ * Therefore:   $fpi(x) = (2*Weight)/x - 4
+ */
+#define RENO2_SCALING 1.0
+double func_reno2_f(lmm_variable_t var, double x)
+{
+  xbt_assert(var->m_weight > 0.0, "Don't call me with stupid values!");
+  return RENO2_SCALING * (1.0 / var->m_weight) * log((x * var->m_weight) /
+                                                   (2.0 * x * var->m_weight +
+                                                    3.0));
+}
+
+double func_reno2_fp(lmm_variable_t var, double x)
+{
+  return RENO2_SCALING * 3.0 / (var->m_weight * x *
+                                (2.0 * var->m_weight * x + 3.0));
+}
+
+double func_reno2_fpi(lmm_variable_t var, double x)
+{
+  double res_fpi;
+  double tmp;
+
+  xbt_assert(x > 0.0, "Don't call me with stupid values!");
+  tmp = x * var->m_weight * var->m_weight;
+  res_fpi = tmp * (9.0 * x + 24.0);
+
+  if (res_fpi <= 0.0)
+    return 0.0;
+
+  res_fpi = RENO2_SCALING * (-3.0 * tmp + sqrt(res_fpi)) / (4.0 * tmp);
+  return res_fpi;
+}
diff --git a/src/surf/maxmin_private_.h b/src/surf/maxmin_private_.h
new file mode 100644 (file)
index 0000000..bdf6fc4
--- /dev/null
@@ -0,0 +1,112 @@
+/* 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. */
+
+#ifndef _SURF_MAXMIN_PRIVATE_H
+#define _SURF_MAXMIN_PRIVATE_H
+
+#include "surf/maxmin_.h"
+#include "xbt/swag.h"
+#include "xbt/mallocator.h"
+
+
+
+typedef struct lmm_element {
+  /* hookup to constraint */
+  s_xbt_swag_hookup_t element_set_hookup;
+  s_xbt_swag_hookup_t active_element_set_hookup;
+
+  lmm_constraint_t constraint;
+  lmm_variable_t variable;
+  double value;
+} s_lmm_element_t;
+#define make_elem_active(elem) xbt_swag_insert_at_head(elem,&(elem->constraint->active_element_set))
+#define make_elem_inactive(elem) xbt_swag_remove(elem,&(elem->constraint->active_element_set))
+
+typedef struct lmm_constraint_light {
+  double remaining_over_usage;
+  lmm_constraint_t cnst;
+} s_lmm_constraint_light_t;
+
+typedef struct lmm_constraint {
+  /* hookup to system */
+  s_xbt_swag_hookup_t constraint_set_hookup;
+  s_xbt_swag_hookup_t active_constraint_set_hookup;
+  s_xbt_swag_hookup_t modified_constraint_set_hookup;
+  s_xbt_swag_hookup_t saturated_constraint_set_hookup;
+
+  s_xbt_swag_t element_set;     /* a list of lmm_element_t */
+  s_xbt_swag_t active_element_set;      /* a list of lmm_element_t */
+  double remaining;
+  double usage;
+  double bound;
+  int shared;
+  void *id;
+  int id_int;
+  double lambda;
+  double new_lambda;
+  lmm_constraint_light_t cnst_light;
+} s_lmm_constraint_t;
+
+typedef struct lmm_variable {
+  /* hookup to system */
+  s_xbt_swag_hookup_t variable_set_hookup;
+  s_xbt_swag_hookup_t saturated_variable_set_hookup;
+
+  s_lmm_element_t *cnsts;
+  int cnsts_size;
+  int cnsts_number;
+  double weight;
+  double bound;
+  double value;
+  void *id;
+  int id_int;
+  unsigned visited;             /* used by lmm_update_modified_set */
+  /* \begin{For Lagrange only} */
+  double mu;
+  double new_mu;
+  double (*func_f) (struct lmm_variable * var, double x);       /* (f)    */
+  double (*func_fp) (struct lmm_variable * var, double x);      /* (f')    */
+  double (*func_fpi) (struct lmm_variable * var, double x);     /* (f')^{-1}    */
+  /* \end{For Lagrange only} */
+} s_lmm_variable_t;
+
+typedef struct lmm_system {
+  int modified;
+  int selective_update_active;  /* flag to update partially the system only selecting changed portions */
+  unsigned visited_counter;     /* used by lmm_update_modified_set */
+  s_xbt_swag_t variable_set;    /* a list of lmm_variable_t */
+  s_xbt_swag_t constraint_set;  /* a list of lmm_constraint_t */
+
+  s_xbt_swag_t active_constraint_set;   /* a list of lmm_constraint_t */
+  s_xbt_swag_t modified_constraint_set; /* a list of modified lmm_constraint_t */
+
+  s_xbt_swag_t saturated_variable_set;  /* a list of lmm_variable_t */
+  s_xbt_swag_t saturated_constraint_set;        /* a list of lmm_constraint_t_t */
+
+  xbt_swag_t keep_track;
+
+  xbt_mallocator_t variable_mallocator;
+} s_lmm_system_t;
+
+#define extract_variable(sys) xbt_swag_extract(&(sys->variable_set))
+#define extract_constraint(sys) xbt_swag_extract(&(sys->constraint_set))
+#define insert_constraint(sys,cnst) xbt_swag_insert(cnst,&(sys->constraint_set))
+#define remove_variable(sys,var) do {xbt_swag_remove(var,&(sys->variable_set));\
+                                 xbt_swag_remove(var,&(sys->saturated_variable_set));} while(0)
+#define remove_constraint(sys,cnst) do {xbt_swag_remove(cnst,&(sys->constraint_set));\
+                                        xbt_swag_remove(cnst,&(sys->saturated_constraint_set));} while(0)
+#define make_constraint_active(sys,cnst) xbt_swag_insert(cnst,&(sys->active_constraint_set))
+#define make_constraint_inactive(sys,cnst) \
+  do { xbt_swag_remove(cnst, &sys->active_constraint_set);              \
+    xbt_swag_remove(cnst, &sys->modified_constraint_set); } while (0)
+
+void lmm_print(lmm_system_t sys);
+
+extern double (*func_f_def) (lmm_variable_t, double);
+extern double (*func_fp_def) (lmm_variable_t, double);
+extern double (*func_fpi_def) (lmm_variable_t, double);
+
+#endif                          /* _SURF_MAXMIN_PRIVATE_H */
diff --git a/src/surf/network.cpp b/src/surf/network.cpp
new file mode 100644 (file)
index 0000000..e8e886e
--- /dev/null
@@ -0,0 +1,698 @@
+#include "network.hpp"
+#include "maxmin_private.h"
+#include "simgrid/sg_config.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf,
+                                "Logging specific to the SURF network module");
+}
+
+NetworkCm02ModelPtr surf_network_model = NULL;
+
+double sg_sender_gap = 0.0;
+double sg_latency_factor = 1.0; /* default value; can be set by model or from command line */
+double sg_bandwidth_factor = 1.0;       /* default value; can be set by model or from command line */
+double sg_weight_S_parameter = 0.0;     /* default value; can be set by model or from command line */
+
+double sg_tcp_gamma = 0.0;
+int sg_network_crosstraffic = 0;
+
+/*************
+ * CallBacks *
+ *************/
+
+static void net_parse_link_init(sg_platf_link_cbarg_t link){
+  if (link->policy == SURF_LINK_FULLDUPLEX) {
+    char *link_id;
+    link_id = bprintf("%s_UP", link->id);
+    surf_network_model->createResource(link_id,
+                      link->bandwidth,
+                      link->bandwidth_trace,
+                      link->latency,
+                      link->latency_trace,
+                      link->state,
+                      link->state_trace, link->policy, link->properties);
+    xbt_free(link_id);
+    link_id = bprintf("%s_DOWN", link->id);
+    surf_network_model->createResource(link_id,
+                      link->bandwidth,
+                      link->bandwidth_trace,
+                      link->latency,
+                      link->latency_trace,
+                      link->state,
+                      link->state_trace, link->policy, link->properties);
+    xbt_free(link_id);
+  } else {
+       surf_network_model->createResource(link->id,
+                      link->bandwidth,
+                      link->bandwidth_trace,
+                      link->latency,
+                      link->latency_trace,
+                      link->state,
+                      link->state_trace, link->policy, link->properties);
+  }
+}
+
+static void net_add_traces(void){
+  xbt_dict_cursor_t cursor = NULL;
+  char *trace_name, *elm;
+
+  static int called = 0;
+  if (called)
+    return;
+  called = 1;
+
+  /* connect all traces relative to network */
+  xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    NetworkCm02LinkLmmPtr link = dynamic_cast<NetworkCm02LinkLmmPtr>(
+                                    static_cast<ResourcePtr>(
+                                                 xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+    xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
+               trace_name, elm);
+    xbt_assert(trace,
+               "Cannot connect trace %s to link %s: trace undefined",
+               trace_name, elm);
+
+    link->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+  }
+
+  xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    NetworkCm02LinkLmmPtr link = dynamic_cast<NetworkCm02LinkLmmPtr>(
+                                 static_cast<ResourcePtr>(
+                                             xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+    xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
+               trace_name, elm);
+    xbt_assert(trace,
+               "Cannot connect trace %s to link %s: trace undefined",
+               trace_name, elm);
+
+    link->p_power.event = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+  }
+
+  xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    NetworkCm02LinkLmmPtr link = dynamic_cast<NetworkCm02LinkLmmPtr>(
+                                 static_cast<ResourcePtr>(
+                                             xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+    xbt_assert(link, "Cannot connect trace %s to link %s: link undefined",
+               trace_name, elm);
+    xbt_assert(trace,
+               "Cannot connect trace %s to link %s: trace undefined",
+               trace_name, elm);
+
+    link->p_latEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+  }
+}
+
+void net_define_callbacks(void)
+{
+  /* Figuring out the network links */
+  sg_platf_link_add_cb(net_parse_link_init);
+  sg_platf_postparse_add_cb(net_add_traces);
+}
+
+/*********
+ * Model *
+ *********/
+
+/************************************************************************/
+/* New model based on optimizations discussed during Pedro Velho's thesis*/
+/************************************************************************/
+/* @techreport{VELHO:2011:HAL-00646896:1, */
+/*      url = {http://hal.inria.fr/hal-00646896/en/}, */
+/*      title = {{Flow-level network models: have we reached the limits?}}, */
+/*      author = {Velho, Pedro and Schnorr, Lucas and Casanova, Henri and Legrand, Arnaud}, */
+/*      type = {Rapport de recherche}, */
+/*      institution = {INRIA}, */
+/*      number = {RR-7821}, */
+/*      year = {2011}, */
+/*      month = Nov, */
+/*      pdf = {http://hal.inria.fr/hal-00646896/PDF/rr-validity.pdf}, */
+/*  } */
+void surf_network_model_init_LegrandVelho(void)
+{
+  if (surf_network_model)
+    return;
+
+  surf_network_model = new NetworkCm02Model();
+  net_define_callbacks();
+  ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+  xbt_dynar_push(model_list, &model);
+
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor",
+                            13.01);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+                            0.97);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 20537);
+}
+
+/***************************************************************************/
+/* The nice TCP sharing model designed by Loris Marchal and Henri Casanova */
+/***************************************************************************/
+/* @TechReport{      rr-lip2002-40, */
+/*   author        = {Henri Casanova and Loris Marchal}, */
+/*   institution   = {LIP}, */
+/*   title         = {A Network Model for Simulation of Grid Application}, */
+/*   number        = {2002-40}, */
+/*   month         = {oct}, */
+/*   year          = {2002} */
+/* } */
+void surf_network_model_init_CM02(void)
+{
+
+  if (surf_network_model)
+    return;
+
+  surf_network_model = new NetworkCm02Model();
+  net_define_callbacks();
+  ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+  xbt_dynar_push(model_list, &model);
+
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 1.0);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+                            1.0);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 0.0);
+}
+
+/***************************************************************************/
+/* The models from Steven H. Low                                           */
+/***************************************************************************/
+/* @article{Low03,                                                         */
+/*   author={Steven H. Low},                                               */
+/*   title={A Duality Model of {TCP} and Queue Management Algorithms},     */
+/*   year={2003},                                                          */
+/*   journal={{IEEE/ACM} Transactions on Networking},                      */
+/*    volume={11}, number={4},                                             */
+/*  }                                                                      */
+void surf_network_model_init_Reno(void)
+{
+  if (surf_network_model)
+    return;
+
+  surf_network_model = new NetworkCm02Model();
+  net_define_callbacks();
+  ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+  xbt_dynar_push(model_list, &model);
+  lmm_set_default_protocol_function(func_reno_f, func_reno_fp,
+                                    func_reno_fpi);
+  surf_network_model->f_networkSolve = lagrange_solve;
+
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+                            0.92);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775);
+}
+
+
+void surf_network_model_init_Reno2(void)
+{
+  if (surf_network_model)
+    return;
+
+  surf_network_model = new NetworkCm02Model();
+  net_define_callbacks();
+  ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+  xbt_dynar_push(model_list, &model);
+  lmm_set_default_protocol_function(func_reno2_f, func_reno2_fp,
+                                    func_reno2_fpi);
+  surf_network_model->f_networkSolve = lagrange_solve;
+
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+                            0.92);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S_parameter",
+                            8775);
+}
+
+void surf_network_model_init_Vegas(void)
+{
+  if (surf_network_model)
+    return;
+
+  surf_network_model = new NetworkCm02Model();
+  net_define_callbacks();
+  ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+  xbt_dynar_push(model_list, &model);
+  lmm_set_default_protocol_function(func_vegas_f, func_vegas_fp,
+                                    func_vegas_fpi);
+  surf_network_model->f_networkSolve = lagrange_solve;
+
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/latency_factor", 10.4);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/bandwidth_factor",
+                            0.92);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775);
+}
+
+NetworkCm02Model::NetworkCm02Model() : NetworkCm02Model("network"){
+}
+
+NetworkCm02Model::NetworkCm02Model(string name) : Model(name){
+  ActionLmmPtr comm;
+
+  char *optim = xbt_cfg_get_string(_sg_cfg_set, "network/optim");
+  int select =
+      xbt_cfg_get_boolean(_sg_cfg_set, "network/maxmin_selective_update");
+
+  if (!strcmp(optim, "Full")) {
+    p_updateMechanism = UM_FULL;
+    m_selectiveUpdate = select;
+  } else if (!strcmp(optim, "Lazy")) {
+    p_updateMechanism = UM_LAZY;
+    m_selectiveUpdate = 1;
+    xbt_assert((select == 1)
+               ||
+               (xbt_cfg_is_default_value
+                (_sg_cfg_set, "network/maxmin_selective_update")),
+               "Disabling selective update while using the lazy update mechanism is dumb!");
+  } else {
+    xbt_die("Unsupported optimization (%s) for this model", optim);
+  }
+
+  if (!p_maxminSystem)
+       p_maxminSystem = lmm_system_new(m_selectiveUpdate);
+
+  routing_model_create(static_cast<ResourcePtr>(createResource("__loopback__",
+                                                  498000000, NULL, 0.000015, NULL,
+                                                  SURF_RESOURCE_ON, NULL,
+                                                  SURF_LINK_FATPIPE, NULL)));
+
+  if (p_updateMechanism == UM_LAZY) {
+       p_actionHeap = xbt_heap_new(8, NULL);
+       xbt_heap_set_update_callback(p_actionHeap, surf_action_lmm_update_index_heap);
+       p_modifiedSet = xbt_swag_new(xbt_swag_offset(*comm, p_actionListHookup));
+       p_maxminSystem->keep_track = p_modifiedSet;
+  }
+}
+
+NetworkCm02LinkLmmPtr NetworkCm02Model::createResource(const char *name,
+                                 double bw_initial,
+                                 tmgr_trace_t bw_trace,
+                                 double lat_initial,
+                                 tmgr_trace_t lat_trace,
+                                 e_surf_resource_state_t state_initial,
+                                 tmgr_trace_t state_trace,
+                                 e_surf_link_sharing_policy_t policy,
+                                 xbt_dict_t properties)
+{
+  xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL),
+             "Link '%s' declared several times in the platform file.",
+             name);
+
+  NetworkCm02LinkLmmPtr nw_link =
+                 new NetworkCm02LinkLmm(this, name, properties, p_maxminSystem, sg_bandwidth_factor * bw_initial, history,
+                                                state_initial, state_trace, bw_initial, bw_trace, lat_initial, lat_trace, policy);
+
+
+  xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, static_cast<ResourcePtr>(nw_link));
+  XBT_DEBUG("Create link '%s'",name);
+
+  return nw_link;
+}
+
+void NetworkCm02Model::updateActionsStateLazy(double now, double delta)
+{
+  NetworkCm02ActionLmmPtr action;
+  while ((xbt_heap_size(p_actionHeap) > 0)
+         && (double_equals(xbt_heap_maxkey(p_actionHeap), now))) {
+    action = (NetworkCm02ActionLmmPtr) xbt_heap_pop(p_actionHeap);
+    XBT_DEBUG("Something happened to action %p", action);
+#ifdef HAVE_TRACING
+    if (TRACE_is_enabled()) {
+      int n = lmm_get_number_of_cnst_from_var(p_maxminSystem, action->p_variable);
+      unsigned int i;
+      for (i = 0; i < n; i++){
+        lmm_constraint_t constraint = lmm_get_cnst_from_var(p_maxminSystem,
+                                                            action->p_variable,
+                                                            i);
+        NetworkCm02LinkPtr link = static_cast<NetworkCm02LinkPtr>(lmm_constraint_id(constraint));
+        TRACE_surf_link_set_utilization(link->m_name,
+                                        action->p_category,
+                                        (lmm_variable_getvalue(action->p_variable)*
+                                            lmm_get_cnst_weight_from_var(p_maxminSystem,
+                                                action->p_variable,
+                                                i)),
+                                        action->m_lastUpdate,
+                                        now - action->m_lastUpdate);
+      }
+    }
+#endif
+
+    // if I am wearing a latency hat
+    if (action->m_hat == LATENCY) {
+      XBT_DEBUG("Latency paid for action %p. Activating", action);
+      lmm_update_variable_weight(p_maxminSystem, action->p_variable, action->m_weight);
+      action->heapRemove(p_actionHeap);
+      action->m_lastUpdate = surf_get_clock();
+
+        // if I am wearing a max_duration or normal hat
+    } else if (action->m_hat == MAX_DURATION ||
+        action->m_hat == NORMAL) {
+        // no need to communicate anymore
+        // assume that flows that reached max_duration have remaining of 0
+      action->m_finish = surf_get_clock();
+      XBT_DEBUG("Action %p finished", action);
+      action->m_remains = 0;
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_DONE);
+      action->heapRemove(p_actionHeap);
+
+      action->gapRemove();
+    }
+  }
+  return;
+}
+
+xbt_dynar_t NetworkCm02Model::getRoute(RoutingEdgePtr src, RoutingEdgePtr dst)
+{
+  xbt_dynar_t route = NULL;
+  routing_platf->getRouteAndLatency(src, dst, &route, NULL);
+  return route;
+}
+
+ActionPtr NetworkCm02Model::communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+                                                double size, double rate)
+{
+  unsigned int i;
+  void *_link;
+  NetworkCm02LinkLmmPtr link;
+  int failed = 0;
+  NetworkCm02ActionLmmPtr action = NULL;
+  double bandwidth_bound;
+  double latency = 0.0;
+  xbt_dynar_t back_route = NULL;
+  int constraints_per_variable = 0;
+
+  xbt_dynar_t route = xbt_dynar_new(sizeof(RoutingEdgePtr), NULL);
+
+  XBT_IN("(%s,%s,%g,%g)", src->p_name, dst->p_name, size, rate);
+
+  routing_platf->getRouteAndLatency(src, dst, &route, &latency);
+  xbt_assert(!xbt_dynar_is_empty(route) || latency,
+             "You're trying to send data from %s to %s but there is no connection at all between these two hosts.",
+             src->p_name, dst->p_name);
+
+  xbt_dynar_foreach(route, i, _link) {
+       link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+    if (link->p_stateCurrent == SURF_RESOURCE_OFF) {
+      failed = 1;
+      break;
+    }
+  }
+  if (sg_network_crosstraffic == 1) {
+         routing_platf->getRouteAndLatency(dst, src, &back_route, NULL);
+    xbt_dynar_foreach(back_route, i, _link) {
+      link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+      if (link->p_stateCurrent == SURF_RESOURCE_OFF) {
+        failed = 1;
+        break;
+      }
+    }
+  }
+
+  action = new NetworkCm02ActionLmm(this, size, failed);
+
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+  action->m_latencyLimited = 0;
+#endif
+  action->m_weight = action->m_latency = latency;
+
+  //FIXME:REMOVxbt_swag_insert(action, action->p_stateSet);
+  action->m_rate = rate;
+  if (p_updateMechanism == UM_LAZY) {
+    action->m_indexHeap = -1;
+    action->m_lastUpdate = surf_get_clock();
+  }
+
+  bandwidth_bound = -1.0;
+  if (sg_weight_S_parameter > 0) {
+    xbt_dynar_foreach(route, i, _link) {
+      link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+      action->m_weight +=
+         sg_weight_S_parameter /
+         (link->p_power.peak * link->p_power.scale);
+    }
+  }
+  xbt_dynar_foreach(route, i, _link) {
+       link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+    double bb = bandwidthFactor(size) * (link->p_power.peak * link->p_power.scale);
+    bandwidth_bound =
+        (bandwidth_bound < 0.0) ? bb : min(bandwidth_bound, bb);
+  }
+
+  action->m_latCurrent = action->m_latency;
+  action->m_latency *= latencyFactor(size);
+  action->m_rate = bandwidthConstraint(action->m_rate, bandwidth_bound, size);
+  if (m_haveGap) {
+    xbt_assert(!xbt_dynar_is_empty(route),
+               "Using a model with a gap (e.g., SMPI) with a platform without links (e.g. vivaldi)!!!");
+
+    //link = *(NetworkCm02LinkLmmPtr *) xbt_dynar_get_ptr(route, 0);
+    link = dynamic_cast<NetworkCm02LinkLmmPtr>(*static_cast<ResourcePtr *>(xbt_dynar_get_ptr(route, 0)));
+    gapAppend(size, link, action);
+    XBT_DEBUG("Comm %p: %s -> %s gap=%f (lat=%f)",
+              action, src->p_name, dst->p_name, action->m_senderGap,
+              action->m_latency);
+  }
+
+  constraints_per_variable = xbt_dynar_length(route);
+  if (back_route != NULL)
+    constraints_per_variable += xbt_dynar_length(back_route);
+
+  if (action->m_latency > 0) {
+    action->p_variable = lmm_variable_new(p_maxminSystem, action, 0.0, -1.0,
+                         constraints_per_variable);
+    if (p_updateMechanism == UM_LAZY) {
+      // add to the heap the event when the latency is payed
+      XBT_DEBUG("Added action (%p) one latency event at date %f", action,
+                action->m_latency + action->m_lastUpdate);
+      action->heapInsert(p_actionHeap, action->m_latency + action->m_lastUpdate, xbt_dynar_is_empty(route) ? NORMAL : LATENCY);
+    }
+  } else
+    action->p_variable = lmm_variable_new(p_maxminSystem, action, 1.0, -1.0, constraints_per_variable);
+
+  if (action->m_rate < 0) {
+    lmm_update_variable_bound(p_maxminSystem, action->p_variable, (action->m_latCurrent > 0) ? sg_tcp_gamma / (2.0 * action->m_latCurrent) : -1.0);
+  } else {
+    lmm_update_variable_bound(p_maxminSystem, action->p_variable, (action->m_latCurrent > 0) ? min(action->m_rate, sg_tcp_gamma / (2.0 * action->m_latCurrent)) : action->m_rate);
+  }
+
+  xbt_dynar_foreach(route, i, _link) {
+       link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+    lmm_expand(p_maxminSystem, link->p_constraint, action->p_variable, 1.0);
+  }
+
+  if (sg_network_crosstraffic == 1) {
+    XBT_DEBUG("Fullduplex active adding backward flow using 5%%");
+    xbt_dynar_foreach(back_route, i, _link) {
+      link = dynamic_cast<NetworkCm02LinkLmmPtr>(static_cast<ResourcePtr>(_link));
+      lmm_expand(p_maxminSystem, link->p_constraint, action->p_variable, .05);
+    }
+  }
+
+  xbt_dynar_free(&route);
+  XBT_OUT();
+
+  return action;
+}
+
+double NetworkCm02Model::latencyFactor(double size) {
+  return sg_latency_factor;
+}
+
+double NetworkCm02Model::bandwidthFactor(double size) {
+  return sg_bandwidth_factor;
+}
+
+double NetworkCm02Model::bandwidthConstraint(double rate, double bound, double size) {
+  return rate;
+}
+
+/************
+ * Resource *
+ ************/
+NetworkCm02LinkLmm::NetworkCm02LinkLmm(NetworkCm02ModelPtr model, const char *name, xbt_dict_t props,
+                                  lmm_system_t system,
+                                  double constraint_value,
+                                  tmgr_history_t history,
+                                  e_surf_resource_state_t state_init,
+                                  tmgr_trace_t state_trace,
+                                  double metric_peak,
+                                  tmgr_trace_t metric_trace,
+                                  double lat_initial,
+                                  tmgr_trace_t lat_trace,
+                                  e_surf_link_sharing_policy_t policy)
+: Resource(model, name, props),
+  ResourceLmm(model, name, props, system, constraint_value, history, state_init, state_trace, metric_peak, metric_trace),
+  NetworkCm02Link(model, name, props)
+{
+  m_latCurrent = lat_initial;
+  if (lat_trace)
+       p_latEvent = tmgr_history_add_trace(history, lat_trace, 0.0, 0, static_cast<ResourcePtr>(this));
+
+  if (policy == SURF_LINK_FATPIPE)
+       lmm_constraint_shared(p_constraint);
+}
+
+bool NetworkCm02LinkLmm::isUsed()
+{
+  return lmm_constraint_used(p_model->p_maxminSystem, p_constraint);
+}
+
+double NetworkCm02Link::getLatency()
+{
+  return m_latCurrent;
+}
+
+double NetworkCm02LinkLmm::getBandwidth()
+{
+  return p_power.peak * p_power.scale;
+}
+
+bool NetworkCm02LinkLmm::isShared()
+{
+  return lmm_constraint_is_shared(p_constraint);
+}
+
+void NetworkCm02LinkLmm::updateState(tmgr_trace_event_t event_type,
+                                      double value, double date)
+{
+  /*   printf("[" "%g" "] Asking to update network card \"%s\" with value " */
+  /*     "%g" " for event %p\n", surf_get_clock(), nw_link->name, */
+  /*     value, event_type); */
+
+  if (event_type == p_power.event) {
+    double delta =
+        sg_weight_S_parameter / value - sg_weight_S_parameter /
+        (p_power.peak * p_power.scale);
+    lmm_variable_t var = NULL;
+    lmm_element_t elem = NULL;
+    NetworkCm02ActionLmmPtr action = NULL;
+
+    p_power.peak = value;
+    lmm_update_constraint_bound(p_model->p_maxminSystem,
+                                p_constraint,
+                                sg_bandwidth_factor *
+                                (p_power.peak * p_power.scale));
+#ifdef HAVE_TRACING
+    TRACE_surf_link_set_bandwidth(date, m_name, sg_bandwidth_factor * p_power.peak * p_power.scale);
+#endif
+    if (sg_weight_S_parameter > 0) {
+      while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, p_constraint, &elem))) {
+        action = (NetworkCm02ActionLmmPtr) lmm_variable_id(var);
+        action->m_weight += delta;
+        if (!action->m_suspended)
+          lmm_update_variable_weight(p_model->p_maxminSystem, action->p_variable, action->m_weight);
+      }
+    }
+    if (tmgr_trace_event_free(event_type))
+      p_power.event = NULL;
+  } else if (event_type == p_latEvent) {
+    double delta = value - m_latCurrent;
+    lmm_variable_t var = NULL;
+    lmm_element_t elem = NULL;
+    NetworkCm02ActionLmmPtr action = NULL;
+
+    m_latCurrent = value;
+    while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, p_constraint, &elem))) {
+      action = (NetworkCm02ActionLmmPtr) lmm_variable_id(var);
+      action->m_latCurrent += delta;
+      action->m_weight += delta;
+      if (action->m_rate < 0)
+        lmm_update_variable_bound(p_model->p_maxminSystem, action->p_variable, sg_tcp_gamma / (2.0 * action->m_latCurrent));
+      else {
+        lmm_update_variable_bound(p_model->p_maxminSystem, action->p_variable,
+                                  min(action->m_rate, sg_tcp_gamma / (2.0 * action->m_latCurrent)));
+
+        if (action->m_rate < sg_tcp_gamma / (2.0 * action->m_latCurrent)) {
+          XBT_INFO("Flow is limited BYBANDWIDTH");
+        } else {
+          XBT_INFO("Flow is limited BYLATENCY, latency of flow is %f",
+                   action->m_latCurrent);
+        }
+      }
+      if (!action->m_suspended)
+        lmm_update_variable_weight(p_model->p_maxminSystem, action->p_variable, action->m_weight);
+
+    }
+    if (tmgr_trace_event_free(event_type))
+      p_latEvent = NULL;
+  } else if (event_type == p_stateEvent) {
+    if (value > 0)
+      p_stateCurrent = SURF_RESOURCE_ON;
+    else {
+      lmm_constraint_t cnst = p_constraint;
+      lmm_variable_t var = NULL;
+      lmm_element_t elem = NULL;
+
+      p_stateCurrent = SURF_RESOURCE_OFF;
+      while ((var = lmm_get_var_from_cnst(p_model->p_maxminSystem, cnst, &elem))) {
+        ActionPtr action = (ActionPtr) lmm_variable_id(var);
+
+        if (action->getState() == SURF_ACTION_RUNNING ||
+            action->getState() == SURF_ACTION_READY) {
+          action->m_finish = date;
+          action->setState(SURF_ACTION_FAILED);
+        }
+      }
+    }
+    if (tmgr_trace_event_free(event_type))
+      p_stateEvent = NULL;
+  } else {
+    XBT_CRITICAL("Unknown event ! \n");
+    xbt_abort();
+  }
+
+  XBT_DEBUG
+      ("There were a resource state event, need to update actions related to the constraint (%p)",
+       p_constraint);
+  return;
+}
+
+/**********
+ * Action *
+ **********/
+void NetworkCm02ActionLmm::updateRemainingLazy(double now)
+{
+  double delta = 0.0;
+
+  if (m_suspended != 0)
+    return;
+
+  delta = now - m_lastUpdate;
+
+  if (m_remains > 0) {
+    XBT_DEBUG("Updating action(%p): remains was %lf, last_update was: %lf", this, m_remains, m_lastUpdate);
+    double_update(&(m_remains), m_lastValue * delta);
+
+    XBT_DEBUG("Updating action(%p): remains is now %lf", this, m_remains);
+  }
+
+  if (m_maxDuration != NO_MAX_DURATION)
+    double_update(&m_maxDuration, delta);
+
+  if (m_remains <= 0 &&
+      (lmm_get_variable_weight(p_variable) > 0)) {
+    m_finish = surf_get_clock();
+    setState(SURF_ACTION_DONE);
+
+    heapRemove(p_model->p_actionHeap);
+  } else if (((m_maxDuration != NO_MAX_DURATION)
+      && (m_maxDuration <= 0))) {
+    m_finish = surf_get_clock();
+    setState(SURF_ACTION_DONE);
+    heapRemove(p_model->p_actionHeap);
+  }
+
+  m_lastUpdate = now;
+  m_lastValue = lmm_variable_getvalue(p_variable);
+}
+void NetworkCm02ActionLmm::recycle()
+{
+  return;
+}
+
diff --git a/src/surf/network.hpp b/src/surf/network.hpp
new file mode 100644 (file)
index 0000000..f51a46e
--- /dev/null
@@ -0,0 +1,135 @@
+#include "surf.hpp"
+#include "xbt/fifo.h"
+#include "xbt/graph.h"
+#include "surf_routing.hpp"
+
+#ifndef SURF_MODEL_NETWORK_H_
+#define SURF_MODEL_NETWORK_H_
+
+/***********
+ * Classes *
+ ***********/
+class NetworkCm02Model;
+typedef NetworkCm02Model *NetworkCm02ModelPtr;
+
+class NetworkCm02Link;
+typedef NetworkCm02Link *NetworkCm02LinkPtr;
+
+class NetworkCm02LinkLmm;
+typedef NetworkCm02LinkLmm *NetworkCm02LinkLmmPtr;
+
+class NetworkCm02Action;
+typedef NetworkCm02Action *NetworkCm02ActionPtr;
+
+class NetworkCm02ActionLmm;
+typedef NetworkCm02ActionLmm *NetworkCm02ActionLmmPtr;
+
+/*********
+ * Tools *
+ *********/
+extern NetworkCm02ModelPtr surf_network_model;
+
+void net_define_callbacks(void);
+
+/*********
+ * Model *
+ *********/
+class NetworkCm02Model : public Model {
+public:
+  NetworkCm02Model(int i) : Model("network") {};//FIXME: add network clean interface
+  NetworkCm02Model(string name);
+  NetworkCm02Model();
+  //FIXME:NetworkCm02LinkPtr createResource(string name);
+  NetworkCm02LinkLmmPtr createResource(const char *name,
+                                   double bw_initial,
+                                   tmgr_trace_t bw_trace,
+                                   double lat_initial,
+                                   tmgr_trace_t lat_trace,
+                                   e_surf_resource_state_t state_initial,
+                                   tmgr_trace_t state_trace,
+                                   e_surf_link_sharing_policy_t policy,
+                                   xbt_dict_t properties);
+  void updateActionsStateLazy(double now, double delta);
+  virtual void gapAppend(double size, const NetworkCm02LinkLmmPtr link, NetworkCm02ActionLmmPtr action) {};
+  virtual ActionPtr communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+                                          double size, double rate);
+  xbt_dynar_t getRoute(RoutingEdgePtr src, RoutingEdgePtr dst); //FIXME: kill field? That is done by the routing nowadays
+  //FIXME: virtual void addTraces() =0;
+  void (*f_networkSolve)(lmm_system_t) = lmm_solve;
+  virtual double latencyFactor(double size);
+  virtual double bandwidthFactor(double size);
+  virtual double bandwidthConstraint(double rate, double bound, double size);
+  bool m_haveGap = false;
+};
+
+/************
+ * Resource *
+ ************/
+
+class NetworkCm02Link : virtual public Resource {
+public:
+  NetworkCm02Link(){};
+  NetworkCm02Link(NetworkCm02ModelPtr model, const char* name, xbt_dict_t properties) : Resource(model, name, properties) {};
+  virtual double getBandwidth()=0;
+  virtual double getLatency();
+  virtual bool isShared()=0;
+  /* Using this object with the public part of
+    model does not make sense */
+  double m_latCurrent;
+  tmgr_trace_event_t p_latEvent;
+};
+
+class NetworkCm02LinkLmm : public ResourceLmm, public NetworkCm02Link {
+public:
+  NetworkCm02LinkLmm(NetworkCm02ModelPtr model, const char* name, xbt_dict_t properties)
+   : ResourceLmm(), NetworkCm02Link(model, name, properties) {};
+  NetworkCm02LinkLmm(NetworkCm02ModelPtr model, const char *name, xbt_dict_t props,
+                                  lmm_system_t system,
+                                  double constraint_value,
+                                  tmgr_history_t history,
+                                  e_surf_resource_state_t state_init,
+                                  tmgr_trace_t state_trace,
+                                  double metric_peak,
+                                  tmgr_trace_t metric_trace,
+                                  double lat_initial,
+                                  tmgr_trace_t lat_trace,
+                               e_surf_link_sharing_policy_t policy);
+  bool isShared();
+  bool isUsed();
+  double getBandwidth();
+  void updateState(tmgr_trace_event_t event_type, double value, double date);
+};
+
+
+/**********
+ * Action *
+ **********/
+class NetworkCm02Action : virtual public Action {
+public:
+  NetworkCm02Action(ModelPtr model, double cost, bool failed)
+ : Action(model, cost, failed) {};
+  double m_latency;
+  double m_latCurrent;
+  double m_weight;
+  double m_rate;
+  const char* p_senderLinkName;
+  double m_senderGap;
+  double m_senderSize;
+  xbt_fifo_item_t p_senderFifoItem;
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+  int m_latencyLimited;
+#endif
+
+};
+
+class NetworkCm02ActionLmm : public ActionLmm, public NetworkCm02Action {
+public:
+  NetworkCm02ActionLmm(ModelPtr model, double cost, bool failed)
+ : Action(model, cost, failed),
+   ActionLmm(model, cost, failed),
+   NetworkCm02Action(model, cost, failed) {};
+  void updateRemainingLazy(double now);
+  void recycle();
+};
+
+#endif /* SURF_MODEL_NETWORK_H_ */
diff --git a/src/surf/network_constant.cpp b/src/surf/network_constant.cpp
new file mode 100644 (file)
index 0000000..13fff27
--- /dev/null
@@ -0,0 +1,168 @@
+#include "network_constant.hpp"
+#include "surf/random_mgr.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
+static int host_number_int = 0;
+
+static void netcste_count_hosts(sg_platf_host_cbarg_t h) {
+  host_number_int++;
+}
+
+/*********
+ * Model *
+ *********/
+void surf_network_model_init_Constant()
+{
+  xbt_assert(surf_network_model == NULL);
+  surf_network_model = new NetworkConstantModel();
+
+  sg_platf_host_add_cb(netcste_count_hosts);
+
+  ModelPtr model = static_cast<ModelPtr>(surf_network_model);
+  xbt_dynar_push(model_list, &model);
+
+  routing_model_create(NULL);
+}
+
+double NetworkConstantModel::shareResources(double now)
+{
+  void *_action = NULL;
+  NetworkConstantActionLmmPtr action = NULL;
+  double min = -1.0;
+
+  xbt_swag_foreach(_action, p_runningActionSet) {
+       action = dynamic_cast<NetworkConstantActionLmmPtr>(static_cast<ActionPtr>(_action));
+    if (action->m_latency > 0) {
+      if (min < 0)
+        min = action->m_latency;
+      else if (action->m_latency < min)
+        min = action->m_latency;
+    }
+  }
+
+  return min;
+}
+
+void NetworkConstantModel::updateActionsState(double now, double delta)
+{
+  void *_action, *_next_action;
+  NetworkConstantActionLmmPtr action = NULL;
+
+  xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
+       action = dynamic_cast<NetworkConstantActionLmmPtr>(static_cast<ActionPtr>(_action));
+    if (action->m_latency > 0) {
+      if (action->m_latency > delta) {
+        double_update(&(action->m_latency), delta);
+      } else {
+        action->m_latency = 0.0;
+      }
+    }
+    double_update(&(action->m_remains),
+                  action->m_cost * delta / action->m_latInit);
+    if (action->m_maxDuration != NO_MAX_DURATION)
+      double_update(&(action->m_maxDuration), delta);
+
+    if (action->m_remains <= 0) {
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_DONE);
+    } else if ((action->m_maxDuration != NO_MAX_DURATION)
+               && (action->m_maxDuration <= 0)) {
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_DONE);
+    }
+  }
+}
+
+ActionPtr NetworkConstantModel::communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+                                        double size, double rate)
+{
+  char *src_name = src->p_name;
+  char *dst_name = dst->p_name;
+
+  XBT_IN("(%s,%s,%g,%g)", src_name, dst_name, size, rate);
+  NetworkConstantActionLmmPtr action = new NetworkConstantActionLmm(this, sg_latency_factor);
+  XBT_OUT();
+
+  return action;
+}
+
+/************
+ * Resource *
+ ************/
+bool NetworkConstantLinkLmm::isUsed()
+{
+  return 0;
+}
+
+void NetworkConstantLinkLmm::updateState(tmgr_trace_event_t event_type,
+                                      double value, double time)
+{
+  DIE_IMPOSSIBLE;
+}
+
+double NetworkConstantLinkLmm::getBandwidth()
+{
+  DIE_IMPOSSIBLE;
+  return -1.0; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */
+}
+
+double NetworkConstantLinkLmm::getLatency()
+{
+  DIE_IMPOSSIBLE;
+  return -1.0; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */
+}
+
+bool NetworkConstantLinkLmm::isShared()
+{
+  DIE_IMPOSSIBLE;
+  return -1; /* useless since DIE actually abort(), but eclipse prefer to have a useless and harmless return */
+}
+
+/**********
+ * Action *
+ **********/
+
+int NetworkConstantActionLmm::unref()
+{
+  m_refcount--;
+  if (!m_refcount) {
+    xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+    delete this;
+  return 1;
+  }
+  return 0;
+}
+
+void NetworkConstantActionLmm::cancel()
+{
+  return;
+}
+
+#ifdef HAVE_TRACING
+void NetworkConstantActionLmm::setCategory(const char *category)
+{
+  //ignore completely the categories in constant model, they are not traced
+}
+#endif
+
+void NetworkConstantActionLmm::suspend()
+{
+  m_suspended = true;
+}
+
+void NetworkConstantActionLmm::resume()
+{
+  if (m_suspended)
+       m_suspended = false;
+}
+
+void NetworkConstantActionLmm::recycle()
+{
+  return;
+}
+
+bool NetworkConstantActionLmm::isSuspended()
+{
+  return m_suspended;
+}
+
diff --git a/src/surf/network_constant.hpp b/src/surf/network_constant.hpp
new file mode 100644 (file)
index 0000000..c9c140d
--- /dev/null
@@ -0,0 +1,70 @@
+#include "network.hpp"
+
+#ifndef NETWORK_CONSTANT_HPP_
+#define NETWORK_CONSTANT_HPP_
+
+/***********
+ * Classes *
+ ***********/
+class NetworkConstantModel;
+typedef NetworkConstantModel *NetworkConstantModelPtr;
+
+class NetworkConstantLinkLmm;
+typedef NetworkConstantLinkLmm *NetworkConstantLinkLmmPtr;
+
+class NetworkConstantActionLmm;
+typedef NetworkConstantActionLmm *NetworkConstantActionLmmPtr;
+
+/*********
+ * Model *
+ *********/
+class NetworkConstantModel : public NetworkCm02Model {
+public:
+  NetworkConstantModel() : NetworkCm02Model("constant time network") {};
+  NetworkCm02LinkLmmPtr createResource(string name);
+  double shareResources(double now);
+  void updateActionsState(double now, double delta);
+  ActionPtr communicate(RoutingEdgePtr src, RoutingEdgePtr dst,
+                                          double size, double rate);
+  void gapRemove(ActionLmmPtr action);
+  //FIXME:virtual void addTraces() =0;
+};
+
+/************
+ * Resource *
+ ************/
+class NetworkConstantLinkLmm : public NetworkCm02LinkLmm {
+public:
+  NetworkConstantLinkLmm(NetworkCm02ModelPtr model, const char* name, xbt_dict_t properties);
+  bool isUsed();
+  void updateState(tmgr_trace_event_t event_type, double value, double date);
+  double getBandwidth();
+  double getLatency();
+  bool isShared();
+};
+
+/**********
+ * Action *
+ **********/
+class NetworkConstantActionLmm : public NetworkCm02ActionLmm {
+public:
+  NetworkConstantActionLmm(NetworkConstantModelPtr model, double latency):
+         Action(model, 0, false), NetworkCm02ActionLmm(model, 0, false), m_latInit(latency) {
+       m_latency = latency;
+       if (m_latency <= 0.0) {
+         p_stateSet = p_model->p_doneActionSet;
+         xbt_swag_insert(static_cast<ActionPtr>(this), p_stateSet);
+       }
+  };
+  int unref();
+  void recycle();
+  void cancel();
+  void setCategory(const char *category);
+  void suspend();
+  void resume();
+  bool isSuspended();
+  double m_latInit;
+  int m_suspended;
+};
+
+#endif /* NETWORK_CONSTANT_HPP_ */
diff --git a/src/surf/network_gtnets.cpp b/src/surf/network_gtnets.cpp
new file mode 100644 (file)
index 0000000..5570c20
--- /dev/null
@@ -0,0 +1,108 @@
+#include "network_gtnets.hpp"
+
+static double time_to_next_flow_completion = -1;
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets, surf,
+                                "Logging specific to the SURF network GTNetS module");
+
+extern routing_platf_t routing_platf;
+
+double sg_gtnets_jitter = 0.0;
+int sg_gtnets_jitter_seed = 10;
+
+/*********
+ * Model *
+ *********/
+
+void newRoute(int src_id, int dst_id,
+                     xbt_dynar_t links, int nb_link)
+{
+  void *_link;
+  NetworkGTNetsLinkPtr link;
+  unsigned int cursor;
+  int i = 0;
+  int *gtnets_links;
+
+  XBT_IN("(src_id=%d, dst_id=%d, links=%p, nb_link=%d)",
+          src_id, dst_id, links, nb_link);
+
+  /* Build the list of gtnets link IDs */
+  gtnets_links = xbt_new0(int, nb_link);
+  i = 0;
+  xbt_dynar_foreach(links, cursor, _link) {
+       link = (NetworkGTNetsLinkPtr) _link;
+    gtnets_links[i++] = link->m_id;
+  }
+
+  if (gtnets_add_route(src_id, dst_id, gtnets_links, nb_link)) {
+    xbt_die("Cannot create GTNetS route");
+  }
+  XBT_OUT();
+}
+
+void newRouteOnehop(int src_id, int dst_id,
+                    NetworkGTNetsLinkPtr link)
+{
+  if (gtnets_add_onehop_route(src_id, dst_id, link->m_id)) {
+    xbt_die("Cannot create GTNetS route");
+  }
+}
+
+int NetworkGTNetsModel::addLink(ind id, double bandwidth, double latency)
+{
+  double bw = bandwidth * 8; //Bandwidth in bits (used in GTNETS).
+
+  map<int,GTNETS_Link*>::iterator iter = p_links.find(id);
+  xbt_assert((iter == p_links.end()), "Link %d already exists", id);
+
+  if(iter == p_links.end()) {
+    GTNETS_Link* link= new GTNETS_Link(id);
+    p_links[id] = link;
+  }
+
+  XBT_DEBUG("Creating a new P2P, linkid %d, bandwidth %gl, latency %gl", id, bandwidth, latency);
+  p_gtnetsLinks_[id] = new Linkp2p(bw, latency);
+         if(jitter_ > 0){
+               XBT_DEBUG("Using jitter %f, and seed %u", jitter_, jitter_seed_);
+               double min = -1*jitter_*latency;
+               double max = jitter_*latency;
+               uniform_jitter_generator_[id] = new Uniform(min,max);
+               gtnets_links_[id]->Jitter((const Random &) *(uniform_jitter_generator_[id]));
+         }
+
+         return 0;
+}
+
+/************
+ * Resource *
+ ************/
+NetworkGTNetsLink::NetworkGTNetsLink(NetworkGTNetsModelPtr model, const char* name, double bw, double lat, xbt_dict_t properties)
+  :NetworkCm02Link(model, name, properties), m_bwCurrent(bw), m_latCurrent(lat)
+{
+
+  static int link_count = -1;
+
+  if (xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL)) {
+    return;
+  }
+
+  XBT_DEBUG("Scanning link name %s", name);
+
+  link_count++;
+
+  XBT_DEBUG("Adding new link, linkid %d, name %s, latency %g, bandwidth %g",
+           link_count, name, lat, bw);
+
+
+
+  if (gtnets_add_link(link_count, bw, lat)) {
+    xbt_die("Cannot create GTNetS link");
+  }
+  m_id = link_count;
+
+  xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, this);
+}
+
+/**********
+ * Action *
+ **********/
diff --git a/src/surf/network_gtnets.hpp b/src/surf/network_gtnets.hpp
new file mode 100644 (file)
index 0000000..a2af26d
--- /dev/null
@@ -0,0 +1,124 @@
+#include "network.hpp"
+
+#ifndef NETWORK_GTNETS_HPP_
+#define NETWORK_GTNETS_HPP_
+
+#include "simulator.h"          // Definitions for the Simulator Object
+#include "node.h"               // Definitions for the Node Object
+#include "linkp2p.h"            // Definitions for point-to-point link objects
+#include "ratetimeparse.h"      // Definitions for Rate and Time objects
+#include "application-tcpserver.h"      // Definitions for TCPServer application
+#include "application-tcpsend.h"        // Definitions for TCP Sending application
+#include "tcp-tahoe.h"          // Definitions for TCP Tahoe
+#include "tcp-reno.h"
+#include "tcp-newreno.h"
+#include "event.h"
+#include "routing-manual.h"
+#include "red.h"
+
+xbt_dict_t network_card_ids;
+
+/***********
+ * Classes *
+ ***********/
+class NetworkGTNetsModel;
+typedef NetworkGTNetsModel *NetworkGTNetsModelPtr;
+
+class NetworkGTNetsLink;
+typedef NetworkGTNetsLink *NetworkGTNetsLinkPtr;
+
+class NetworkGTNetsAction;
+typedef NetworkGTNetsAction *NetworkGTNetsActionPtr;
+
+class NetworkGTNetsActionLmm;
+typedef NetworkGTNetsActionLmm *NetworkGTNetsActionLmmPtr;
+
+/*********
+ * Model *
+ *********/
+class NetworkGTNetsModel : public NetworkCm02Model {
+public:
+  NetworkGTNetsModel() : NetworkCm02Model("constant time network") {};
+  int addLink(int id, double bandwidth, double latency);
+  int addOnehop_route(int src, int dst, int link);
+  int addRoute(int src, int dst, int *links, int nlink);
+  int addRouter(int id);
+  int createFlow(int src, int dst, long datasize, void *metadata);
+  double getTimeToNextFlowCompletion();
+  int runUntilNextFlowCompletion(void ***metadata,
+                                     int *number_of_flows);
+  int run(double deltat);
+  // returns the total received by the TCPServer peer of the given action
+  double gtNetsGetFlowRx(void *metadata);
+  void createGTNetsTopology();
+  void printTopology();
+  void setJitter(double);
+  void setJitterSeed(int);
+private:
+  void addNodes();
+  void nodeConnect();
+
+  bool nodeInclude(int);
+  bool linkInclude(int);
+  Simulator *p_sim;
+  GTNETS_Topology *p_topo;
+  RoutingManual *p_rm;
+  REDQueue *p_redQueue;
+  int m_nnode;
+  int m_isTopology;
+  int m_nflow;
+  double m_jitter;
+  int m_jitterSeed;
+   map<int, Uniform*> p_uniformJitterGenerator;
+
+   map<int, TCPServer*> p_gtnetsServers;
+   map<int, TCPSend*> p_gtnetsClients;
+   map<int, Linkp2p*> p_gtnetsLinks_;
+   map<int, Node*> p_gtnetsNodes;
+   map<void*, int> p_gtnetsActionToFlow;
+
+   map <int, void*> p_gtnetsMetadata;
+
+   // From Topology
+   int m_nodeID;
+   map<int, GTNETS_Link*> p_links;
+   vector<GTNETS_Node*> p_nodes;
+   map<int, int> p_hosts;      //hostid->nodeid
+   set<int > p_routers;
+};
+
+/************
+ * Resource *
+ ************/
+class NetworkGTNetsLink : public NetworkCm02Link {
+public:
+  NetworkGTNetsLink(NetworkGTNetsModelPtr model, const char* name, double bw, double lat, xbt_dict_t properties);
+  /* Using this object with the public part of
+  model does not make sense */
+  double m_bwCurrent;
+  double m_latCurrent;
+  int m_id;
+};
+
+/**********
+ * Action *
+ **********/
+class NetworkGTNetsAction : public NetworkCm02Action {
+public:
+  NetworkGTNetsAction(NetworkGTNetsModelPtr model, double latency){};
+
+  double m_latency;
+  double m_latCurrent;
+#ifdef HAVE_TRACING
+  int m_lastRemains;
+#endif
+  lmm_variable_t p_variable;
+  double m_rate;
+  int m_suspended;
+#ifdef HAVE_TRACING
+  RoutingEdgePtr src;
+  RoutingEdgePtr dst;
+#endif //HAVE_TRACING
+};
+
+#endif /* NETWORK_GTNETS_HPP_ */
diff --git a/src/surf/network_smpi.cpp b/src/surf/network_smpi.cpp
new file mode 100644 (file)
index 0000000..ee6e415
--- /dev/null
@@ -0,0 +1,197 @@
+#include "network_smpi.hpp"
+#include "simgrid/sg_config.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
+
+xbt_dynar_t smpi_bw_factor = NULL;
+xbt_dynar_t smpi_lat_factor = NULL;
+
+typedef struct s_smpi_factor *smpi_factor_t;
+typedef struct s_smpi_factor {
+  long factor;
+  double value;
+} s_smpi_factor_t;
+
+xbt_dict_t gap_lookup = NULL;
+
+static int factor_cmp(const void *pa, const void *pb)
+{
+  return (((s_smpi_factor_t*)pa)->factor > ((s_smpi_factor_t*)pb)->factor);
+}
+
+
+static xbt_dynar_t parse_factor(const char *smpi_coef_string)
+{
+  char *value = NULL;
+  unsigned int iter = 0;
+  s_smpi_factor_t fact;
+  xbt_dynar_t smpi_factor, radical_elements, radical_elements2 = NULL;
+
+  smpi_factor = xbt_dynar_new(sizeof(s_smpi_factor_t), NULL);
+  radical_elements = xbt_str_split(smpi_coef_string, ";");
+  xbt_dynar_foreach(radical_elements, iter, value) {
+
+    radical_elements2 = xbt_str_split(value, ":");
+    if (xbt_dynar_length(radical_elements2) != 2)
+      xbt_die("Malformed radical for smpi factor!");
+    fact.factor = atol(xbt_dynar_get_as(radical_elements2, 0, char *));
+    fact.value = atof(xbt_dynar_get_as(radical_elements2, 1, char *));
+    xbt_dynar_push_as(smpi_factor, s_smpi_factor_t, fact);
+    XBT_DEBUG("smpi_factor:\t%ld : %f", fact.factor, fact.value);
+    xbt_dynar_free(&radical_elements2);
+  }
+  xbt_dynar_free(&radical_elements);
+  iter=0;
+  xbt_dynar_sort(smpi_factor, &factor_cmp);
+  xbt_dynar_foreach(smpi_factor, iter, fact) {
+    XBT_DEBUG("ordered smpi_factor:\t%ld : %f", fact.factor, fact.value);
+
+  }
+  return smpi_factor;
+}
+
+/*********
+ * Model *
+ *********/
+
+/************************************************************************/
+/* New model based on LV08 and experimental results of MPI ping-pongs   */
+/************************************************************************/
+/* @Inproceedings{smpi_ipdps, */
+/*  author={Pierre-Nicolas Clauss and Mark Stillwell and Stéphane Genaud and Frédéric Suter and Henri Casanova and Martin Quinson}, */
+/*  title={Single Node On-Line Simulation of {MPI} Applications with SMPI}, */
+/*  booktitle={25th IEEE International Parallel and Distributed Processing Symposium (IPDPS'11)}, */
+/*  address={Anchorage (Alaska) USA}, */
+/*  month=may, */
+/*  year={2011} */
+/*  } */
+void surf_network_model_init_SMPI(void)
+{
+
+  if (surf_network_model)
+    return;
+  surf_network_model = new NetworkSmpiModel();
+  net_define_callbacks();
+  xbt_dynar_push(model_list, &surf_network_model);
+  //network_solve = lmm_solve;
+
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/sender_gap", 10e-6);
+  xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775);
+}
+
+void NetworkSmpiModel::gapAppend(double size, const NetworkCm02LinkLmmPtr link, NetworkCm02ActionLmmPtr action)
+{
+  const char *src = link->m_name;
+  xbt_fifo_t fifo;
+  //surf_action_network_CM02_t last_action;
+  //double bw;
+
+  if (sg_sender_gap > 0.0) {
+    if (!gap_lookup) {
+      gap_lookup = xbt_dict_new_homogeneous(NULL);
+    }
+    fifo = (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup, src);
+    action->m_senderGap = 0.0;
+    if (fifo && xbt_fifo_size(fifo) > 0) {
+      /* Compute gap from last send */
+      /*last_action =
+          (surf_action_network_CM02_t)
+          xbt_fifo_get_item_content(xbt_fifo_get_last_item(fifo));*/
+     // bw = net_get_link_bandwidth(link);
+      action->m_senderGap = sg_sender_gap;
+        /*  max(sg_sender_gap,last_action->sender.size / bw);*/
+      action->m_latency += action->m_senderGap;
+    }
+    /* Append action as last send */
+    /*action->sender.link_name = link->lmm_resource.generic_resource.name;
+    fifo =
+        (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup,
+                                          action->sender.link_name);
+    if (!fifo) {
+      fifo = xbt_fifo_new();
+      xbt_dict_set(gap_lookup, action->sender.link_name, fifo, NULL);
+    }
+    action->sender.fifo_item = xbt_fifo_push(fifo, action);*/
+    action->m_senderSize = size;
+  }
+}
+
+void NetworkSmpiModel::gapRemove(ActionLmmPtr lmm_action)
+{
+  xbt_fifo_t fifo;
+  size_t size;
+  NetworkCm02ActionLmmPtr action = (NetworkCm02ActionLmmPtr)(lmm_action);
+
+  if (sg_sender_gap > 0.0 && action->p_senderLinkName
+      && action->p_senderFifoItem) {
+    fifo =
+        (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup,
+                                          action->p_senderLinkName);
+    xbt_fifo_remove_item(fifo, action->p_senderFifoItem);
+    size = xbt_fifo_size(fifo);
+    if (size == 0) {
+      xbt_fifo_free(fifo);
+      xbt_dict_remove(gap_lookup, action->p_senderLinkName);
+      size = xbt_dict_length(gap_lookup);
+      if (size == 0) {
+        xbt_dict_free(&gap_lookup);
+      }
+    }
+  }
+}
+
+double NetworkSmpiModel::bandwidthFactor(double size)
+{
+  if (!smpi_bw_factor)
+    smpi_bw_factor =
+        parse_factor(sg_cfg_get_string("smpi/bw_factor"));
+
+  unsigned int iter = 0;
+  s_smpi_factor_t fact;
+  double current=1.0;
+  xbt_dynar_foreach(smpi_bw_factor, iter, fact) {
+    if (size <= fact.factor) {
+      XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current);
+      return current;
+    }else
+      current=fact.value;
+  }
+  XBT_DEBUG("%f > %ld return %f", size, fact.factor, current);
+
+  return current;
+}
+double NetworkSmpiModel::latencyFactor(double size)
+{
+  if (!smpi_lat_factor)
+    smpi_lat_factor =
+        parse_factor(sg_cfg_get_string("smpi/lat_factor"));
+
+  unsigned int iter = 0;
+  s_smpi_factor_t fact;
+  double current=1.0;
+  xbt_dynar_foreach(smpi_lat_factor, iter, fact) {
+    if (size <= fact.factor) {
+      XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current);
+      return current;
+    }else
+      current=fact.value;
+  }
+  XBT_DEBUG("%f > %ld return %f", size, fact.factor, current);
+
+  return current;
+}
+
+double NetworkSmpiModel::bandwidthConstraint(double rate, double bound, double size)
+{
+  return rate < 0 ? bound : min(bound, rate * bandwidthFactor(size));
+}
+
+/************
+ * Resource *
+ ************/
+
+
+
+/**********
+ * Action *
+ **********/
diff --git a/src/surf/network_smpi.hpp b/src/surf/network_smpi.hpp
new file mode 100644 (file)
index 0000000..f5d38fa
--- /dev/null
@@ -0,0 +1,40 @@
+#include "network.hpp"
+
+/***********
+ * Classes *
+ ***********/
+
+class NetworkSmpiModel;
+typedef NetworkSmpiModel *NetworkSmpiModelPtr;
+
+/*********
+ * Tools *
+ *********/
+
+/*********
+ * Model *
+ *********/
+
+class NetworkSmpiModel : public NetworkCm02Model {
+public:
+  NetworkSmpiModel() : NetworkCm02Model() {m_haveGap=true;};
+  void gapAppend(double size, const NetworkCm02LinkLmmPtr link, NetworkCm02ActionLmmPtr action);
+  void gapRemove(ActionLmmPtr action);
+  double latencyFactor(double size);
+  double bandwidthFactor(double size);
+  double bandwidthConstraint(double rate, double bound, double size);
+  void communicateCallBack() {};
+};
+
+
+/************
+ * Resource *
+ ************/
+
+
+/**********
+ * Action *
+ **********/
+
+
+
diff --git a/src/surf/new_model_private.h b/src/surf/new_model_private.h
deleted file mode 100644 (file)
index 3cdbeeb..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * TUTORIAL: New model
- * new_model_private.h
- *
- *  Created on: 12 October 2012
- *      Author: navarro
- */
-
-#ifndef NEW_MODEL_PRIVATE_H_
-#define NEW_MODEL_PRIVATE_H_
-
-
-
-#endif /* NEW_MODEL_PRIVATE_H_ */
diff --git a/src/surf/solver.cpp b/src/surf/solver.cpp
new file mode 100644 (file)
index 0000000..74abd69
--- /dev/null
@@ -0,0 +1,735 @@
+#include "solver.hpp"
+
+#include "xbt/log.h"
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_maxmin, surf,
+                                "Logging specific to SURF (maxmin)");
+
+static int Global_debug_id = 1;
+static int Global_const_debug_id = 1;
+
+Solver::Solver(int selectiveUpdate)
+{
+  VariablePtr var;
+  ConstraintPtr cnst;
+
+  m_modified = 0;
+  m_selectiveUpdateActive = selectiveUpdate;
+  m_visitedCounter = 1;
+
+  XBT_DEBUG("Setting selective_update_active flag to %d\n",
+         this->m_selectiveUpdateActive);
+
+  /*xbt_swag_init(&(l->variable_set),
+                xbt_swag_offset(var, variable_set_hookup));
+  xbt_swag_init(&(l->constraint_set),
+                xbt_swag_offset(cnst, constraint_set_hookup));
+
+  xbt_swag_init(&(l->active_constraint_set),
+                xbt_swag_offset(cnst, active_constraint_set_hookup));
+
+  xbt_swag_init(&(l->modified_constraint_set),
+                xbt_swag_offset(cnst, modified_constraint_set_hookup));
+  xbt_swag_init(&(l->saturated_variable_set),
+                xbt_swag_offset(var, saturated_variable_set_hookup));
+  xbt_swag_init(&(l->saturated_constraint_set),
+                xbt_swag_offset(cnst, saturated_constraint_set_hookup));
+
+  l->variable_mallocator = xbt_mallocator_new(65536,
+                                              lmm_variable_mallocator_new_f,
+                                              lmm_variable_mallocator_free_f,
+                                              lmm_variable_mallocator_reset_f);*/
+}
+
+ConstraintPtr Solver::createConstraint(void *id, double bound)
+{
+  ConstraintPtr cnst = m_constraintAllocator.construct(id, bound);
+  m_constraintSet.push_back(cnst);
+  return cnst;
+}
+
+void Solver::destroyConstraint(Constraint* cnst)
+{
+  m_constraintAllocator.destroy(cnst);
+}
+
+
+VariablePtr Solver::createVariable(void *id, double weight, double bound)
+{
+  void *mem = m_variableAllocator.malloc();
+  VariablePtr var = new (mem) Variable(id, weight, bound, m_visitedCounter - 1);
+  var->m_visited = m_visitedCounter - 1;
+  if (weight)
+    m_variableSet.insert(m_variableSet.begin(), var);
+  else
+    m_variableSet.push_back(var);
+  return var;
+}
+
+void Solver::destroyVariable(Variable* var)
+{
+  m_variableAllocator.destroy(var);
+}
+
+void Solver::destroyElement(Element* elem)
+{
+  m_elementAllocator.destroy(elem);
+}
+
+void Solver::expand(ConstraintPtr cnst, VariablePtr var,  double value)
+{
+  m_modified = 1;
+  
+  ElementPtr elem = m_elementAllocator.construct(cnst, var, value);
+  var->m_cnsts.push_back(elem);
+
+  if (var->m_weight)
+    cnst->m_elementSet.insert(cnst->m_elementSet.begin(), elem);
+  else
+    cnst->m_elementSet.push_back(elem);
+  if(!m_selectiveUpdateActive) {
+    activateConstraint(cnst);
+  } else if(value>0 || var->m_weight >0) {
+    activateConstraint(cnst);
+    updateModifiedSet(cnst);
+    if (var->m_cnsts.size() > 1)
+      updateModifiedSet(var->m_cnsts.front()->p_constraint);
+  }
+}
+
+void Solver::expandAdd(ConstraintPtr cnst, VariablePtr var,  double value)
+{
+  m_modified = 1;
+
+  std::vector<ElementPtr>::iterator it;
+  for (it=var->m_cnsts.begin(); it!=var->m_cnsts.end(); ++it )
+    if ((*it)->p_constraint == cnst)
+      break;
+  
+  if (it != var->m_cnsts.end()) {
+    if (cnst->isShared())
+      (*it)->m_value += value;
+    else 
+      (*it)->m_value = MAX((*it)->m_value, value);
+    updateModifiedSet(cnst);
+  } else
+    expand(cnst, var, value);
+}
+
+void Solver::elementSetValue(ConstraintPtr cnst, VariablePtr var, double value)
+{
+  std::vector<ElementPtr>::iterator it;
+  for (it=var->m_cnsts.begin(); it!=var->m_cnsts.end(); ++it ) {
+    ElementPtr elem = (*it);
+    if (elem->p_constraint == cnst) {
+      elem->m_value = value;
+      m_modified = 1;
+      updateModifiedSet(cnst);
+    }
+  }
+  if (it==var->m_cnsts.end()) {
+    DIE_IMPOSSIBLE;
+  }
+}
+
+//XBT_INLINE 
+ConstraintPtr Variable::getCnst(int num)
+{
+  if (num < m_cnsts.size())
+    return m_cnsts.at(num)->p_constraint;
+  else {
+    ConstraintPtr res;
+    return res;
+  }
+}
+
+//XBT_INLINE
+double Variable::getCnstWeight(int num)
+{
+  if (num < m_cnsts.size())
+    return (m_cnsts.at(num)->m_value);
+  else
+    return 0.0;
+}
+
+//XBT_INLINE 
+int Variable::getNumberOfCnst()
+{
+  return m_cnsts.size();
+}
+
+VariablePtr Constraint::getVar(ElementPtr elem)
+{
+  vector<ElementPtr>::iterator it;
+  if (!elem)
+    elem = m_elementSet.front();
+  else
+    elem = *(++find(m_elementSet.begin(), m_elementSet.end(), elem));
+  if (elem)
+    return elem->p_variable;
+  else {
+    VariablePtr res;
+    return res;
+  }
+}
+
+//XBT_INLINE
+void* Constraint::id()
+{
+  return p_id;
+}
+
+//XBT_INLINE
+void* Variable::id()
+{
+  return p_id;
+}
+
+//static XBT_INLINE
+void Solver::saturatedConstraintSetUpdate(double usage,
+                                  ConstraintLightPtr cnstLight,
+                                  vector<ConstraintLightPtr> saturatedConstraintSet,
+                                  double *minUsage)
+{
+  xbt_assert(usage > 0,"Impossible");
+  
+  if (*minUsage < 0 || *minUsage > usage) {
+    *minUsage = usage;
+    saturatedConstraintSet.clear();
+    saturatedConstraintSet.push_back(cnstLight);
+    XBT_HERE(" min_usage=%f (cnst->remaining / cnst->usage =%f)", *minUsage, usage);
+  } else if (*minUsage == usage) {
+    saturatedConstraintSet.push_back(cnstLight);
+  }
+}
+
+//static XBT_INLINE
+void Solver::saturatedVariableSetUpdate(vector<ConstraintLightPtr> cnstLightList,
+                                        vector<ConstraintLightPtr> saturatedCnstSet)
+{
+  ConstraintLight* cnst = NULL;
+  Element* elem = NULL;
+  vector<ElementPtr>* elem_list;
+  std::vector<ConstraintLightPtr>::iterator it;
+  std::vector<ElementPtr>::iterator elemIt;
+  for (it=saturatedCnstSet.begin(); it!=saturatedCnstSet.end(); ++it) {
+    cnst = (*it);
+    elem_list = &(cnst->p_cnst->m_activeElementSet);
+    for (elemIt=elem_list->begin(); elemIt!=elem_list->end(); ++elemIt) {
+      elem = (*elemIt);
+      if (elem->p_variable->m_weight <= 0)
+       break;
+      if (elem->m_value >0)
+       m_saturatedVariableSet.push_back(elem->p_variable);
+    }
+  }
+}
+
+void Element::activate()
+{
+  p_constraint->m_activeElementSet.push_back(this);
+}
+
+void Element::inactivate()
+{
+  std::vector<ElementPtr>::iterator it;
+  vector<ElementPtr> elemSet = p_constraint->m_activeElementSet;  
+  it = find(elemSet.begin(), elemSet.end(), this);
+  if (it != elemSet.end())
+    elemSet.erase(it);
+}
+
+void Solver::activateConstraint(ConstraintPtr cnst)
+{
+  m_activeConstraintSet.push_back(cnst);
+}
+
+void Solver::inactivateConstraint(ConstraintPtr cnst)
+{
+  std::vector<ConstraintPtr>::iterator it;
+  it = find(m_activeConstraintSet.begin(), m_activeConstraintSet.end(), cnst);
+  if (it != m_activeConstraintSet.end())
+    m_activeConstraintSet.erase(it);
+  m_modifiedConstraintSet.erase(std::find(m_modifiedConstraintSet.begin(), m_modifiedConstraintSet.end(), cnst));
+}
+
+template <class T>
+void vector_remove_first(vector<T> vec, T obj) {
+  typename vector<T>::iterator it;
+  for (it=vec.begin(); it != vec.end(); ++it) {
+    if ((*it) == (obj)) {
+      vec.erase(it);
+      break;
+    }
+  }
+}
+
+void Solver::print()
+{
+  //TODO
+}
+
+void Solver::solve()
+{
+  Variable* var = NULL;
+  Constraint* cnst = NULL;
+  Element* elem = NULL;
+  vector<ConstraintPtr>* cnstList = NULL;
+  std::vector<ConstraintPtr>::iterator cnstIt;
+  vector<VariablePtr>* varList = NULL;
+  std::vector<VariablePtr>::iterator varIt;    
+  vector<ElementPtr>* elemList = NULL;
+  std::vector<ElementPtr>::iterator elemIt;
+  vector<ElementPtr>* elemListB = NULL;
+  std::vector<ElementPtr>::iterator elemItB;
+  double minUsage = -1;
+  double minBound = -1;
+
+  if (!m_modified)
+    return;
+
+  XBT_IN("(sys=%p)", this);
+
+  /*
+   * Compute Usage and store the variables that reach the maximum.
+   */
+  cnstList = m_selectiveUpdateActive ? &m_modifiedConstraintSet :
+                                       &m_activeConstraintSet;
+
+  XBT_DEBUG("Active constraintsSolver : %d", cnstList->size());
+  /* Init: Only modified code portions */
+  
+  for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt) {
+    elemList = &((*cnstIt)->m_elementSet);
+    for (elemIt=elemList->begin(); elemIt!=elemList->end(); ++elemIt) {
+      var = ((*elemIt)->p_variable);
+      if (var->m_weight <= 0.0)
+       break;
+      var->m_value = 0.0;
+    }
+  }
+
+  vector<ConstraintLightPtr> cnstLightList;
+  std::vector<ConstraintLightPtr>::iterator cnstLightIt;
+
+  vector<ConstraintLightPtr> saturatedConstraintSet;
+  saturatedConstraintSet.reserve(5);
+  
+  for (cnstIt=cnstList->begin(); cnstIt!=cnstList->end(); ++cnstIt) {
+    /* INIT */
+    cnst = (*cnstIt);
+    if (cnst->m_remaining == 0)
+      continue;
+    cnst->m_usage = 0;
+    elemList = &(cnst->m_elementSet);
+    for (elemIt=elemList->begin(); elemIt!=elemList->end(); ++elemIt) {
+      /* 0-weighted elements (ie, sleep actions) are at the end of the swag and we don't want to consider them */
+      elem = (*elemIt);
+      if (elem->p_variable->m_weight <= 0)
+        break;
+      if ((elem->m_value > 0)) {
+        if (cnst->m_shared)
+          cnst->m_usage += elem->m_value / elem->p_variable->m_weight;
+        else if (cnst->m_usage < elem->m_value / elem->p_variable->m_weight)
+          cnst->m_usage = elem->m_value / elem->p_variable->m_weight;
+
+        elem->activate();
+        if (m_keepTrack.size()) //TODO: check good semantic
+         m_keepTrack.push_back(elem->p_variable->p_id);
+      }
+    }
+    XBT_DEBUG("Constraint Usage '%d' : %f", cnst->m_idInt, cnst->m_usage);
+    /* Saturated constraints update */
+    if(cnst->m_usage > 0) {
+      ConstraintLightPtr cnstLight (new ConstraintLight((*cnstIt), cnst->m_remaining / cnst->m_usage));
+      cnst->p_cnstLight = cnstLight;
+      saturatedConstraintSetUpdate(cnstLight->m_remainingOverUsage, cnstLight, saturatedConstraintSet, &minUsage);
+      cnstLightList.push_back(cnstLight);      
+    }
+  }
+
+  saturatedVariableSetUpdate(cnstLightList, saturatedConstraintSet);
+
+  /* Saturated variables update */
+  do {
+    /* Fix the variables that have to be */
+    varList = &m_saturatedVariableSet;
+
+    for (varIt=varList->begin(); varIt!=varList->end(); ++varIt) {
+      var = (*varIt);
+      if (var->m_weight <= 0.0) {
+        DIE_IMPOSSIBLE;
+      }
+      /* First check if some of these variables have reach their upper
+         bound and update min_usage accordingly. */
+      XBT_DEBUG
+          ("var=%d, var->bound=%f, var->weight=%f, min_usage=%f, var->bound*var->weight=%f",
+           var->m_idInt, var->m_bound, var->m_weight, minUsage,
+           var->m_bound * var->m_weight);
+
+      if ((var->m_bound > 0) && (var->m_bound * var->m_weight < minUsage)) {
+        if (minBound < 0)
+          minBound = var->m_bound;
+        else
+          minBound = MIN(minBound, var->m_bound);
+        XBT_DEBUG("Updated min_bound=%f", minBound);
+      }
+    }
+
+    while (varList->size()>0) {
+      var = varList->front();
+      int i;
+
+      if (minBound < 0) {
+        var->m_value = minUsage / var->m_weight;
+      } else {
+        if (minBound == var->m_bound)
+          var->m_value = var->m_bound;
+        else {
+          vector_remove_first(*varList, varList->front());
+          continue;
+        }
+      }
+      XBT_DEBUG("Min usage: %f, Var(%d)->weight: %f, Var(%d)->value: %f ",
+             minUsage, var->m_idInt, var->m_weight, var->m_idInt, var->m_value);
+
+      /* Update usage */
+
+      for (elemIt=var->m_cnsts.begin(); elemIt!=var->m_cnsts.end(); ++elemIt) {
+        elem = (*elemIt);
+        cnst = elem->p_constraint;
+        if (cnst->m_shared) {
+          double_update(&(cnst->m_remaining), elem->m_value * var->m_value);
+          double_update(&(cnst->m_usage), elem->m_value / var->m_weight);
+          if(cnst->m_usage<=0 || cnst->m_remaining<=0) {
+            if (cnst->p_cnstLight) {
+             // TODO: reformat message
+              XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p \t cnst_light_tab: %p ",
+                  elemIt - var->m_cnsts.begin(), var->m_cnsts.size(), cnst, cnst->p_cnstLight, &cnstLightList);
+             vector_remove_first(cnstLightList, cnst->p_cnstLight);
+              cnst->p_cnstLight = ConstraintLightPtr();
+            }
+          } else {
+            cnst->p_cnstLight->m_remainingOverUsage = cnst->m_remaining / cnst->m_usage;
+          }
+          elem->inactivate();
+        } else {
+          cnst->m_usage = 0.0;
+          elem->inactivate();
+          elemListB = &(cnst->m_elementSet);
+          for (elemItB=elemListB->begin(); elemItB!=elemListB->end(); ++elemItB) {
+            elem = (*elemItB);
+            if (elem->p_variable->m_weight <= 0 || elem->p_variable->m_value > 0)
+              break;
+            if (elem->m_value > 0)
+              cnst->m_usage = MAX(cnst->m_usage, elem->m_value / elem->p_variable->m_weight);
+          }
+          if (cnst->m_usage<=0 || cnst->m_remaining<=0) {
+            if(cnst->p_cnstLight) {
+             vector_remove_first(cnstLightList, cnst->p_cnstLight);
+             // TODO: reformat message       
+              XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p \t cnst_light_tab: %p ",
+                  elemIt - var->m_cnsts.begin(),  var->m_cnsts.size(), cnst, cnst->p_cnstLight, &cnstLightList);
+              cnst->p_cnstLight = ConstraintLightPtr();
+            }
+          } else {
+            cnst->p_cnstLight->m_remainingOverUsage = cnst->m_remaining / cnst->m_usage;
+          }
+        }
+      }
+      vector_remove_first(*varList, varList->front());
+    }
+
+    /* Find out which variables reach the maximum */
+    minUsage = -1;
+    minBound = -1;
+    m_saturatedConstraintSet.clear();
+
+    for (cnstLightIt=cnstLightList.begin(); cnstLightIt!=cnstLightList.end(); ++cnstLightIt)
+      saturatedConstraintSetUpdate((*cnstLightIt)->m_remainingOverUsage, 
+                                  (*cnstLightIt),
+                                   saturatedConstraintSet,
+                                   &minUsage);
+    saturatedVariableSetUpdate(cnstLightList, saturatedConstraintSet);
+
+  } while (cnstLightList.size() > 0);
+
+  m_modified = 0;
+
+  if (m_selectiveUpdateActive)
+    removeAllModifiedSet();
+  
+
+  if (m_selectiveUpdateActive)
+    removeAllModifiedSet();
+
+  if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
+    print();
+  }
+
+  /*TODO: xbt_free(saturated_constraint_set->data);
+  xbt_free(saturated_constraint_set);
+  xbt_free(cnst_light_tab);*/
+  XBT_OUT();
+}
+
+/* Not a O(1) function */
+
+void Solver::update(ConstraintPtr cnst, VariablePtr var, double value)
+{
+  std::vector<ElementPtr>::iterator it;
+  for (it=var->m_cnsts.begin(); it!=var->m_cnsts.end(); ++it )
+    if ((*it)->p_constraint == cnst) {
+      (*it)->m_value = value;
+      m_modified = true;
+      updateModifiedSet(cnst);
+      return;
+    }
+}
+
+/** \brief Attribute the value bound to var->bound.
+ * 
+ *  \param sys the lmm_system_t
+ *  \param var the lmm_variable_t
+ *  \param bound the new bound to associate with var
+ * 
+ *  Makes var->bound equal to bound. Whenever this function is called 
+ *  a change is  signed in the system. To
+ *  avoid false system changing detection it is a good idea to test 
+ *  (bound != 0) before calling it.
+ *
+ */
+void Solver::updateVariableBound(VariablePtr var, double bound)
+{
+  m_modified = 1;
+  var->m_bound = bound;
+
+  if (var->m_cnsts.size() > 0)
+    updateModifiedSet(var->m_cnsts.front()->p_constraint);
+}
+
+void Solver::updateVariableWeight(VariablePtr var, double weight)
+{
+  int i;
+
+  if (weight == var->m_weight)
+    return;
+  XBT_IN("(sys=%p, var=%p, weight=%f)", this, var, weight);
+  m_modified = 1;
+  var->m_weight = weight;
+  vector_remove_first(m_variableSet, var);
+  if (weight) // TODO: use swap instead
+    m_variableSet.insert(m_variableSet.begin(), var);
+  else
+    m_variableSet.push_back(var);
+
+  vector<ElementPtr> elemList;
+  vector<ElementPtr>::iterator it;
+  for (it=var->m_cnsts.begin(); it!=var->m_cnsts.end(); ++it ) {
+    elemList = (*it)->p_constraint->m_elementSet;
+    vector_remove_first(elemList, (*it));
+    if (weight)
+      elemList.insert(elemList.begin(), *it);
+    else
+      elemList.push_back(*it);
+    if (it == var->m_cnsts.begin())
+      updateModifiedSet((*it)->p_constraint);
+  }
+  if (!weight)
+    var->m_value = 0.0;
+
+  XBT_OUT();
+}
+
+double Variable::getWeight()
+{ return m_weight; }
+
+//XBT_INLINE
+void Solver::updateConstraintBound(ConstraintPtr cnst, double bound)
+{
+  m_modified = 1;
+  updateModifiedSet(cnst);
+  cnst->m_bound = bound;
+}
+
+//XBT_INLINE
+bool Solver::constraintUsed(ConstraintPtr cnst)
+{
+  return std::find(m_activeConstraintSet.begin(),
+                   m_activeConstraintSet.end(), cnst)!=m_activeConstraintSet.end();
+}
+
+//XBT_INLINE
+ConstraintPtr Solver::getFirstActiveConstraint()
+{
+  return m_activeConstraintSet.front();
+}
+
+//XBT_INLINE 
+ConstraintPtr Solver::getNextActiveConstraint(ConstraintPtr cnst)
+{
+  return *(++std::find(m_activeConstraintSet.begin(), m_activeConstraintSet.end(), cnst));
+}
+
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+//XBT_INLINE 
+bool Variable::isLimitedByLatency()
+{
+  return (double_equals(m_bound, m_value));
+}
+#endif
+
+/** \brief Update the constraint set propagating recursively to
+ *  other constraints so the system should not be entirely computed.
+ *
+ *  \param sys the lmm_system_t
+ *  \param cnst the lmm_constraint_t affected by the change
+ *
+ *  A recursive algorithm to optimize the system recalculation selecting only
+ *  constraints that have changed. Each constraint change is propagated
+ *  to the list of constraints for each variable.
+ */
+//static 
+void Solver::updateModifiedSetRec(ConstraintPtr cnst)
+{
+  std::vector<ElementPtr>::iterator elemIt;
+  for (elemIt=cnst->m_elementSet.begin(); elemIt!=cnst->m_elementSet.end(); ++elemIt) {
+    VariablePtr var = (*elemIt)->p_variable;
+    vector<ElementPtr> cnsts = var->m_cnsts;
+    std::vector<ElementPtr>::iterator cnstIt;
+    for (cnstIt=cnsts.begin(); var->m_visited != m_visitedCounter 
+        && cnstIt!=cnsts.end(); ++cnstIt){
+      if ((*cnstIt)->p_constraint != cnst
+         && std::find(m_modifiedConstraintSet.begin(),
+                   m_modifiedConstraintSet.end(), (*cnstIt)->p_constraint)
+            == m_modifiedConstraintSet.end()) {
+       m_modifiedConstraintSet.push_back((*cnstIt)->p_constraint);
+        updateModifiedSetRec((*cnstIt)->p_constraint);
+      }
+    }
+    var->m_visited = m_visitedCounter;
+  }
+}
+
+//static
+void Solver::updateModifiedSet(ConstraintPtr cnst)
+{
+  /* nothing to do if selective update isn't active */
+  if (m_selectiveUpdateActive
+      && std::find(m_modifiedConstraintSet.begin(),
+                   m_modifiedConstraintSet.end(), cnst)
+        == m_modifiedConstraintSet.end()) {
+    m_modifiedConstraintSet.push_back(cnst);
+    updateModifiedSetRec(cnst);
+  }
+}
+
+/** \brief Remove all constraints of the modified_constraint_set.
+ *
+ *  \param sys the lmm_system_t
+ */
+//static 
+void Solver::removeAllModifiedSet()
+{
+  if (++m_visitedCounter == 1) {
+    /* the counter wrapped around, reset each variable->visited */
+    std::vector<VariablePtr>::iterator it;
+    for (it=m_variableSet.begin(); it!=m_variableSet.end(); ++it)
+      (*it)->m_visited = 0;
+  }
+  m_modifiedConstraintSet.clear();
+}
+
+inline void Solver::disableVariable(VariablePtr var)
+{
+  int i;
+  bool m = false;
+
+  ElementPtr elem;
+
+  XBT_IN("(sys=%p, var=%p)", this, var);
+  m_modified = 1;
+  
+  std::vector<ElementPtr>::iterator varIt, elemIt;
+  for (varIt=var->m_cnsts.begin(); varIt!=var->m_cnsts.end();  ) {
+    vector<ElementPtr> elemSet = (*varIt)->p_constraint->m_elementSet;
+    elemSet.erase(std::find(elemSet.begin(), elemSet.end(), *varIt));
+    vector<ElementPtr> activeElemSet = (*varIt)->p_constraint->m_activeElementSet;
+    activeElemSet.erase(std::find(activeElemSet.begin(), activeElemSet.end(), *varIt));
+    if (elemSet.empty()) {
+      inactivateConstraint((*varIt)->p_constraint);
+      var->m_cnsts.erase(varIt);
+    } else {
+      ++varIt;
+      m = true;
+    }
+  }
+  if (m)
+    updateModifiedSet(var->m_cnsts.front()->p_constraint);
+  var->m_cnsts.clear();
+
+  XBT_OUT();
+}
+
+Constraint::Constraint(void *id, double bound): 
+  p_id(id), m_idInt(1), m_bound(bound), m_usage(0), m_shared(1),
+  m_elementsZeroWeight(0)
+{
+  m_idInt = Global_const_debug_id++;
+}
+
+void Constraint::addElement(ElementPtr elem)
+{
+  m_elementSet.push_back(elem);
+  if (elem->p_variable->m_weight<0)
+    std::swap(m_elementSet[m_elementSet.size()-1], m_elementSet[m_elementsZeroWeight++]);
+}
+
+void Constraint::shared() {
+  m_shared = 0;
+}
+
+bool Constraint::isShared() {
+  return m_shared;
+}
+
+Variable::Variable(void *id, double weight, double bound, int visited)
+{
+  int i;
+
+  // TODO: reformat
+  XBT_IN("(sys=%p, id=%p, weight=%f, bound=%f, num_cons =%d)",
+           0, id, weight, bound, 0);
+
+  p_id = id;
+  m_idInt = Global_debug_id++;
+  
+  // TODO: optimize cache 
+
+  m_weight = weight;
+  m_bound = bound;
+  m_value = 0.0;
+  m_visited = visited;//sys->visited_counter - 1;
+  m_mu = 0.0;
+  m_newMu = 0.0;
+  //m_func_f = func_f_def;
+  //m_func_fp = func_fp_def;
+  //m_func_fpi = func_fpi_def;
+
+
+  XBT_OUT(" returns %p", this);
+}
+
+double Variable::value()
+{
+  return m_value;
+}
+
+double Variable::bound()
+{
+  return m_bound;
+}
+
+Element::Element(ConstraintPtr cnst, VariablePtr var, double value):
+  p_constraint(cnst), p_variable(var), m_value(value)
+{}
+
diff --git a/src/surf/solver.h b/src/surf/solver.h
new file mode 100644 (file)
index 0000000..e594831
--- /dev/null
@@ -0,0 +1,153 @@
+#include <xbt.h>
+#include <math.h>
+
+#ifndef SURF_SOLVER_H_
+#define SURF_SOLVER_H_
+
+static double MAXMIN_PRECISION = 0.001;
+extern double sg_maxmin_precision;
+
+static XBT_INLINE int double_equals(double value1, double value2)
+{
+  return (fabs(value1 - value2) < MAXMIN_PRECISION);
+}
+
+static XBT_INLINE void double_update(double *variable, double value)
+{
+  *variable -= value;
+  if (*variable < MAXMIN_PRECISION)
+    *variable = 0.0;
+}
+
+#ifdef __cplusplus
+#include <vector>
+#include <boost/smart_ptr.hpp>
+#include <boost/pool/object_pool.hpp>
+#include <boost/bind.hpp>
+
+using namespace std;
+
+static XBT_INLINE int double_positive(double value)
+{
+  return (value > MAXMIN_PRECISION);
+}
+
+class Solver;
+class Element;
+class Constraint;
+class ConstraintLight;
+class Variable;
+
+/*struct ElementPtrOps
+{
+  bool operator()( const ElementPtr & a, const ElementPtr & b )
+    { return true; } //a > b; }
+};*/
+
+#else
+  typedef struct Solver Solver;
+  typedef struct Element Element;
+  typedef struct Constraint Constraint;
+  typedef struct ConstraintLight ConstraintLight;
+  typedef struct Variable Variable;
+
+#endif
+typedef Element *ElementPtr;
+typedef Variable *VariablePtr;
+typedef Constraint *ConstraintPtr;
+typedef ConstraintLight *ConstraintLightPtr;
+typedef Solver *SolverPtr;
+
+typedef ElementPtr lmm_element_t;
+typedef VariablePtr lmm_variable_t;
+typedef ConstraintPtr lmm_constraint_t;
+typedef ConstraintLightPtr lmm_constraint_light_t;
+typedef SolverPtr lmm_system_t;
+
+extern double (*func_f_def) (lmm_variable_t, double);
+extern double (*func_fp_def) (lmm_variable_t, double);
+extern double (*func_fpi_def) (lmm_variable_t, double);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  extern void _simgrid_log_category__surf_lagrange__constructor__(void);
+  extern void _simgrid_log_category__surf_maxmin__constructor__(void);
+  extern void _simgrid_log_category__surf_lagrange_dichotomy__constructor__(void);
+
+  extern void lmm_set_default_protocol_function(double (*func_f)(lmm_variable_t var, double x),
+                                               double (*func_fp) (lmm_variable_t var, double x),
+                                               double (*func_fpi) (lmm_variable_t var, double x));
+  extern double func_reno_f(lmm_variable_t var, double x);
+  extern double func_reno_fp(lmm_variable_t var, double x);
+  extern double func_reno_fpi(lmm_variable_t var, double x);
+  extern double func_reno2_f(lmm_variable_t var, double x);
+  extern double func_reno2_fp(lmm_variable_t var, double x);
+  extern double func_reno2_fpi(lmm_variable_t var, double x);
+  extern double func_vegas_f(lmm_variable_t var, double x);
+  extern double func_vegas_fp(lmm_variable_t var, double x);
+  extern double func_vegas_fpi(lmm_variable_t var, double x);
+
+
+  //extern int double_equals(double value1, double value2);
+  //extern void double_update(double *variable, double value);
+
+  extern lmm_variable_t lmm_get_var_from_cnst(lmm_system_t sys, lmm_constraint_t cnst, lmm_element_t * elem);
+  extern lmm_constraint_t lmm_get_cnst_from_var(lmm_system_t sys, lmm_variable_t var, int num);
+  extern double lmm_get_cnst_weight_from_var(lmm_system_t sys, lmm_variable_t var, int num);
+  extern int lmm_get_number_of_cnst_from_var(lmm_system_t sys, lmm_variable_t var);
+
+  extern lmm_variable_t lmm_variable_new(lmm_system_t sys, void *id,
+                                            double weight_value,
+                                            double bound,
+                                            int number_of_constraints); 
+  extern void *lmm_variable_id(lmm_variable_t var);      
+  extern double lmm_variable_getvalue(lmm_variable_t var);
+  extern double lmm_get_variable_weight(lmm_variable_t var);
+  extern void lmm_variable_free(lmm_system_t sys, lmm_variable_t var);
+  
+  extern lmm_constraint_t lmm_constraint_new(lmm_system_t sys, void *id,
+                                    double bound_value);         
+  extern void *lmm_constraint_id(lmm_constraint_t cnst);
+  extern void lmm_constraint_shared(lmm_constraint_t cnst);
+  extern int lmm_constraint_is_shared(lmm_constraint_t cnst);
+  extern int lmm_constraint_used(lmm_system_t sys, lmm_constraint_t cnst);
+  extern void lmm_constraint_free(lmm_system_t sys, lmm_constraint_t cnst);
+
+  extern lmm_system_t lmm_system_new(int selective_update);      
+  extern int lmm_system_modified(lmm_system_t solver);   
+  extern void lmm_expand(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var, double value);
+  extern void lmm_expand_add(lmm_system_t sys, lmm_constraint_t cnst,
+                    lmm_variable_t var, double value);
+  extern void lmm_update_variable_bound(lmm_system_t sys, lmm_variable_t var,
+                               double bound);
+  extern void lmm_update_variable_weight(lmm_system_t sys,
+                                            lmm_variable_t var,
+                                            double weight);      
+  extern void lmm_update_constraint_bound(lmm_system_t sys,
+                                             lmm_constraint_t cnst,
+                                             double bound);
+  extern void lmm_solve(lmm_system_t solver);
+  extern void lagrange_solve(lmm_system_t solver);
+  extern void bottleneck_solve(lmm_system_t solver);
+  extern void lmm_system_free(lmm_system_t solver);
+
+  extern void c_function(lmm_system_t);   /* ANSI C prototypes */
+  extern lmm_system_t cplusplus_callback_function(lmm_system_t);
+  extern void lmm_print(lmm_system_t sys);
+  
+  /*********
+   * FIXES *
+   *********/
+  extern int fix_constraint_is_active(lmm_system_t sys, lmm_constraint_t cnst);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#endif /* SURF_SOLVER_H_ */
diff --git a/src/surf/solver.hpp b/src/surf/solver.hpp
new file mode 100644 (file)
index 0000000..76d3275
--- /dev/null
@@ -0,0 +1,174 @@
+#include <xbt.h>
+#include <vector>
+#include "solver.h"
+#include <boost/pool/object_pool.hpp>
+#include <boost/bind.hpp>
+
+#ifndef SURF_SOLVER_HPP_
+#define SURF_SOLVER_HPP_
+using namespace std;
+
+/*static void double_update(double *variable, double value)
+{
+  *variable -= value;
+  if (*variable < MAXMIN_PRECISION)
+    *variable = 0.0;
+}*/
+
+class Solver;
+class Element;
+class Constraint;
+class ConstraintLight;
+class Variable;
+
+struct ElementOps
+{
+  bool operator()( const Element & a, const Element & b )
+    { return true; } //a > b; }
+};
+
+class Element {
+public:
+  Element(ConstraintPtr cnst, VariablePtr var, double value);
+  ConstraintPtr p_constraint;
+  VariablePtr p_variable;
+  double m_value;
+
+  void activate();
+  void inactivate();
+};
+
+class ConstraintLight {
+public:
+  ConstraintLight(ConstraintPtr cnst, double remainingOverUsage):
+    m_remainingOverUsage(remainingOverUsage), p_cnst(cnst) {};
+  double m_remainingOverUsage;
+  ConstraintPtr p_cnst;
+};
+
+class Constraint {
+public:
+  Constraint(void *id, double bound);
+  ~Constraint() {
+  std::cout << "Del Const:" << m_bound << std::endl;    
+  };
+  
+  void shared();
+  bool isShared();
+  void* id();
+  VariablePtr getVar(ElementPtr elem);
+  void addElement(ElementPtr elem);
+
+  vector<ElementPtr> m_elementSet;     /* a list of lmm_element_t */
+  int m_elementsZeroWeight;
+  vector<ElementPtr> m_activeElementSet;      /* a list of lmm_element_t */
+  double m_remaining;
+  double m_usage;
+  double m_bound;
+  int m_shared;
+  void *p_id;
+  int m_idInt;
+  double m_lambda;
+  double m_newLambda;
+  ConstraintLightPtr p_cnstLight;
+};
+
+class Variable {
+public:
+  Variable(void *id, double weight, double bound, int visited);
+  ~Variable() {
+  std::cout << "Del Variable" << std::endl;
+  };
+
+  double value();
+  double bound();
+  void* id();
+  double getWeight();
+  int getNumberOfCnst();
+  ConstraintPtr getCnst(int num);
+  double getCnstWeight(int num);
+  double isLimitedByLatency();
+
+  /* \begin{For Lagrange only} */
+  double (*p_funcF) (VariablePtr var, double x);       /* (f)    */
+  double (*p_funcFP) (VariablePtr var, double x);      /* (f')    */
+  double (*p_funcFPI) (VariablePtr var, double x);     /* (f')^{-1}    */
+  /* \end{For Lagrange only} */
+  vector<ElementPtr> m_cnsts;
+
+  unsigned m_visited;             /* used by lmm_update_modified_set */
+  double m_weight;
+  double m_bound;
+  double m_value;
+  void *p_id;
+  int m_idInt;
+  double m_mu;
+  double m_newMu;
+
+protected:
+  /* \begin{For Lagrange only} */
+  /* \end{For Lagrange only} */
+};
+
+class Solver {
+public:
+  Solver(int selective_update);
+  ~Solver() {
+  std::cout << "Del Solver" << std::endl;    
+  }      
+
+  inline void disableVariable(VariablePtr var);
+  ConstraintPtr createConstraint(void *id, double bound_value);
+  VariablePtr createVariable(void *id, double weight, double bound);
+  void expand(ConstraintPtr cnst, VariablePtr var,  double value);
+  void expandAdd(ConstraintPtr cnst, VariablePtr var,  double value);
+  void elementSetValue(ConstraintPtr cnst, VariablePtr var, double value);
+  void saturatedConstraintSetUpdate(double usage, ConstraintLightPtr cnstLight,
+                                  vector<ConstraintLightPtr> saturatedConstraintSet,
+                                  double *minUsage);
+  void saturatedVariableSetUpdate(vector<ConstraintLightPtr> cnstLightList,
+    vector<ConstraintLightPtr> saturatedConstraintSet);
+  void solve();
+  void update(ConstraintPtr cnst, VariablePtr var, double value);
+  void updateVariableBound(VariablePtr var, double bound);
+  void updateVariableWeight(VariablePtr var, double weight);
+  void updateConstraintBound(ConstraintPtr cnst, double bound);
+  bool constraintUsed(ConstraintPtr cnst);
+  ConstraintPtr getFirstActiveConstraint();
+  ConstraintPtr getNextActiveConstraint(ConstraintPtr cnst);
+  void updateModifiedSetRec(ConstraintPtr cnst);
+  void updateModifiedSet(ConstraintPtr cnst);
+  void removeAllModifiedSet();
+  void activateConstraint(ConstraintPtr cnst);
+  void inactivateConstraint(ConstraintPtr cnst);
+  void print();
+
+  vector<VariablePtr>   m_variableSet;    /* a list of lmm_variable_t */
+  vector<VariablePtr> m_saturatedVariableSet;  /* a list of lmm_variable_t */
+  vector<ConstraintPtr> m_activeConstraintSet;   /* a list of lmm_constraint_t */
+  vector<ConstraintPtr> m_constraintSet;  /* a list of lmm_constraint_t */
+  vector<ConstraintPtr> m_modifiedConstraintSet; /* a list of modified lmm_constraint_t */
+  vector<ConstraintPtr> m_saturatedConstraintSet;        /* a list of lmm_constraint_t_t */
+
+  bool m_modified;
+private:
+
+
+protected:
+  bool m_selectiveUpdateActive;  /* flag to update partially the system only selecting changed portions */
+  unsigned m_visitedCounter;     /* used by lmm_update_modified_set */
+  
+
+  boost::object_pool<Constraint> m_constraintAllocator;
+  boost::object_pool<Variable> m_variableAllocator;
+  boost::object_pool<Element> m_elementAllocator;  
+  void destroyConstraint(Constraint* cnst);
+  void destroyVariable(Variable* var);
+  void destroyElement(Element* elem);
+
+  vector<void*> m_keepTrack;
+
+  //xbt_mallocator_t variable_mallocator;
+};
+
+#endif /* SURF_SOLVER_H_ */
diff --git a/src/surf/solver_c.cpp b/src/surf/solver_c.cpp
new file mode 100644 (file)
index 0000000..5774f86
--- /dev/null
@@ -0,0 +1,159 @@
+#include "solver.hpp"
+#include <boost/smart_ptr.hpp>
+#include <boost/pool/object_pool.hpp>
+#include <boost/bind.hpp>
+
+double sg_maxmin_precision = 0.00001;
+#define RENO_SCALING 1.0
+
+void lmm_solve(lmm_system_t solver)
+{
+  solver->solve();     
+}
+
+void lmm_print(lmm_system_t solver)
+{
+  solver->print();
+}
+
+lmm_variable_t lmm_get_var_from_cnst(lmm_system_t sys, lmm_constraint_t cnst, lmm_element_t * elem)
+{
+  cnst->getVar(*elem);
+}
+
+lmm_constraint_t lmm_get_cnst_from_var(lmm_system_t sys, lmm_variable_t var, int num)
+{
+  var->getCnst(num);
+}
+
+double lmm_get_cnst_weight_from_var(lmm_system_t sys, lmm_variable_t var, int num)
+{
+  var->getCnstWeight(num);
+}
+
+int lmm_get_number_of_cnst_from_var(lmm_system_t sys, lmm_variable_t var)
+{
+  var->getNumberOfCnst();
+}
+
+lmm_variable_t lmm_variable_new(lmm_system_t sys, void *id,
+                                            double weight_value,
+                                            double bound,
+                                            int number_of_constraints)
+{
+  return sys->createVariable(id, weight_value, bound);
+}
+
+void *lmm_variable_id(lmm_variable_t var)
+{
+  return var->id();
+}
+
+double lmm_variable_getvalue(lmm_variable_t var)
+{
+  return var->m_value;
+}
+
+double lmm_get_variable_weight(lmm_variable_t var)
+{
+  return var->m_weight;
+}
+
+void lmm_variable_free(lmm_system_t sys, lmm_variable_t var)
+{
+  //TOREPAIR free
+}
+
+lmm_constraint_t lmm_constraint_new(lmm_system_t sys, void *id,
+                                    double bound_value)          
+{
+  return sys->createConstraint(id, bound_value);
+}
+
+void *lmm_constraint_id(lmm_constraint_t cnst)
+{
+  return cnst->id();
+}
+
+void lmm_constraint_shared(lmm_constraint_t cnst)
+{
+  cnst->shared();
+}
+
+int lmm_constraint_is_shared(lmm_constraint_t cnst)
+{
+  return cnst->isShared();
+}
+
+int lmm_constraint_used(lmm_system_t sys, lmm_constraint_t cnst)
+{
+  return (int) sys->constraintUsed(cnst);
+}
+
+void lmm_constraint_free(lmm_system_t sys, lmm_constraint_t cnst)
+{
+  //TOREPAIR free
+}
+
+lmm_system_t lmm_system_new(int selective_update) {
+  return new Solver(selective_update);
+}
+
+void lmm_system_free(lmm_system_t sys) {
+  //TOREPAIR free
+}
+
+int lmm_system_modified(lmm_system_t solver)
+{
+  solver->m_modified;
+}
+void lmm_expand(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var, double value)
+{
+  sys->expand(cnst, var, value);
+}
+
+void lmm_expand_add(lmm_system_t sys, lmm_constraint_t cnst,
+                    lmm_variable_t var, double value)
+{
+  sys->expandAdd(cnst, var, value);
+}
+
+void lmm_update_variable_bound(lmm_system_t sys, lmm_variable_t var,
+                               double bound)
+{
+  sys->updateVariableBound(var, bound);
+}
+
+void lmm_update_variable_weight(lmm_system_t sys,
+                                            lmm_variable_t var,
+                                            double weight)
+{
+  sys->updateVariableWeight(var, weight);
+}
+
+void lmm_update_constraint_bound(lmm_system_t sys,
+                                             lmm_constraint_t cnst,
+                                             double bound)
+{
+  sys->updateConstraintBound(cnst, bound);
+}
+
+
+/*********
+ * FIXES *
+ *********/
+int fix_constraint_is_active(lmm_system_t sys, lmm_constraint_t cnst)
+{
+  int found = 0;
+  std::vector<ConstraintPtr>::iterator cnstIt;
+  lmm_constraint_t cnst_tmp;  
+  for (cnstIt=sys->m_activeConstraintSet.begin(); cnstIt!=sys->m_activeConstraintSet.end(); ++cnstIt) {
+    cnst_tmp = *cnstIt;
+    if (cnst_tmp == cnst) {
+      found = 1;
+      break;
+    }
+  }
+  return found;
+}
+
diff --git a/src/surf/storage.cpp b/src/surf/storage.cpp
new file mode 100644 (file)
index 0000000..1244418
--- /dev/null
@@ -0,0 +1,702 @@
+#include "storage.hpp"
+#include "surf_private.h"
+
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_storage, surf,
+                                "Logging specific to the SURF storage module");
+}
+
+xbt_lib_t storage_lib;
+int ROUTING_STORAGE_LEVEL;      //Routing for storagelevel
+int ROUTING_STORAGE_HOST_LEVEL;
+int SURF_STORAGE_LEVEL;
+xbt_lib_t storage_type_lib;
+int ROUTING_STORAGE_TYPE_LEVEL; //Routing for storage_type level
+
+static xbt_dynar_t storage_list;
+
+xbt_dynar_t mount_list = NULL;  /* temporary store of current mount storage */
+StorageModelPtr surf_storage_model = NULL;
+
+static int storage_selective_update = 0;
+static xbt_swag_t storage_running_action_set_that_does_not_need_being_checked = NULL;
+
+/*************
+ * CallBacks *
+ *************/
+
+static XBT_INLINE void routing_storage_type_free(void *r)
+{
+  storage_type_t stype = (storage_type_t) r;
+  free(stype->model);
+  free(stype->type_id);
+  free(stype->content);
+  xbt_dict_free(&(stype->properties));
+  xbt_dict_free(&(stype->properties));
+  free(stype);
+}
+
+static XBT_INLINE void surf_storage_resource_free(void *r)
+{
+  // specific to storage
+  StoragePtr storage = dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(r));
+  xbt_dict_free(&storage->p_content);
+  xbt_dynar_free(&storage->p_writeActions);
+  free(storage->p_typeId);
+  free(storage->p_contentType);
+  // generic resource
+  delete storage;
+}
+
+static XBT_INLINE void routing_storage_host_free(void *r)
+{
+  xbt_dynar_t dyn = (xbt_dynar_t) r;
+  xbt_dynar_free(&dyn);
+}
+
+static void parse_storage_init(sg_platf_storage_cbarg_t storage)
+{
+  void* stype = xbt_lib_get_or_null(storage_type_lib,
+                                    storage->type_id,
+                                    ROUTING_STORAGE_TYPE_LEVEL);
+  if(!stype) xbt_die("No storage type '%s'",storage->type_id);
+
+  // if storage content is not specified use the content of storage_type if exist
+  if(!strcmp(storage->content,"") && strcmp(((storage_type_t) stype)->content,"")){
+    storage->content = ((storage_type_t) stype)->content;
+    storage->content_type = ((storage_type_t) stype)->content_type;
+    XBT_DEBUG("For disk '%s' content is empty, inherit the content (of type %s) from storage type '%s' ",
+        storage->id,((storage_type_t) stype)->content_type,
+        ((storage_type_t) stype)->type_id);
+  }
+
+  XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' "
+      "\n\t\tmodel '%s' \n\t\tcontent '%s'\n\t\tcontent_type '%s' "
+      "\n\t\tproperties '%p'\n",
+      storage->id,
+      ((storage_type_t) stype)->model,
+      ((storage_type_t) stype)->type_id,
+      storage->content,
+      storage->content_type,
+      ((storage_type_t) stype)->properties);
+
+  surf_storage_model->createResource(storage->id, ((storage_type_t) stype)->model,
+                                     ((storage_type_t) stype)->type_id,
+                                     storage->content,
+                                     storage->content_type,
+                                     storage->properties);
+}
+
+static void parse_mstorage_init(sg_platf_mstorage_cbarg_t mstorage)
+{
+  XBT_DEBUG("parse_mstorage_init");
+}
+
+static void parse_storage_type_init(sg_platf_storage_type_cbarg_t storagetype_)
+{
+  XBT_DEBUG("parse_storage_type_init");
+}
+
+static void parse_mount_init(sg_platf_mount_cbarg_t mount)
+{
+  XBT_DEBUG("parse_mount_init");
+}
+
+static void storage_parse_storage(sg_platf_storage_cbarg_t storage)
+{
+  xbt_assert(!xbt_lib_get_or_null(storage_lib, storage->id,ROUTING_STORAGE_LEVEL),
+               "Reading a storage, processing unit \"%s\" already exists", storage->id);
+
+  // Verification of an existing type_id
+#ifndef NDEBUG
+  void* storage_type = xbt_lib_get_or_null(storage_type_lib, storage->type_id,ROUTING_STORAGE_TYPE_LEVEL);
+#endif
+  xbt_assert(storage_type,"Reading a storage, type id \"%s\" does not exists", storage->type_id);
+
+  XBT_DEBUG("ROUTING Create a storage name '%s' with type_id '%s' and content '%s'",
+      storage->id,
+      storage->type_id,
+      storage->content);
+
+  xbt_lib_set(storage_lib,
+      storage->id,
+      ROUTING_STORAGE_LEVEL,
+      (void *) xbt_strdup(storage->type_id));
+}
+
+static xbt_dict_t parse_storage_content(char *filename, sg_storage_size_t *used_size)
+{
+  *used_size = 0;
+  if ((!filename) || (strcmp(filename, "") == 0))
+    return NULL;
+
+  xbt_dict_t parse_content = xbt_dict_new_homogeneous(xbt_free);
+  FILE *file = NULL;
+
+  file = surf_fopen(filename, "r");
+  xbt_assert(file != NULL, "Cannot open file '%s' (path=%s)", filename,
+              xbt_str_join(surf_path, ":"));
+
+  char *line = NULL;
+  size_t len = 0;
+  ssize_t read;
+  char path[1024];
+  sg_storage_size_t size;
+
+
+  while ((read = xbt_getline(&line, &len, file)) != -1) {
+    if (read){
+    if(sscanf(line,"%s %" SCNu64, path, &size) == 2) {
+        *used_size += size;
+        sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
+        *psize = size;
+        xbt_dict_set(parse_content,path,psize,NULL);
+      } else {
+        xbt_die("Be sure of passing a good format for content file.\n");
+      }
+    }
+  }
+  free(line);
+  fclose(file);
+  return parse_content;
+}
+
+static void storage_parse_storage_type(sg_platf_storage_type_cbarg_t storage_type)
+{
+  xbt_assert(!xbt_lib_get_or_null(storage_type_lib, storage_type->id,ROUTING_STORAGE_TYPE_LEVEL),
+               "Reading a storage type, processing unit \"%s\" already exists", storage_type->id);
+
+  storage_type_t stype = xbt_new0(s_storage_type_t, 1);
+  stype->model = xbt_strdup(storage_type->model);
+  stype->properties = storage_type->properties;
+  stype->content = xbt_strdup(storage_type->content);
+  stype->content_type = xbt_strdup(storage_type->content_type);
+  stype->type_id = xbt_strdup(storage_type->id);
+  stype->size = storage_type->size;
+
+  XBT_DEBUG("ROUTING Create a storage type id '%s' with model '%s', "
+      "content '%s', and content_type '%s'",
+      stype->type_id,
+      stype->model,
+      storage_type->content,
+      storage_type->content_type);
+
+  xbt_lib_set(storage_type_lib,
+      stype->type_id,
+      ROUTING_STORAGE_TYPE_LEVEL,
+      (void *) stype);
+}
+static void storage_parse_mstorage(sg_platf_mstorage_cbarg_t mstorage)
+{
+  THROW_UNIMPLEMENTED;
+//  mount_t mnt = xbt_new0(s_mount_t, 1);
+//  mnt->id = xbt_strdup(mstorage->type_id);
+//  mnt->name = xbt_strdup(mstorage->name);
+//
+//  if(!mount_list){
+//    XBT_DEBUG("Creata a Mount list for %s",A_surfxml_host_id);
+//    mount_list = xbt_dynar_new(sizeof(char *), NULL);
+//  }
+//  xbt_dynar_push(mount_list,(void *) mnt);
+//  free(mnt->id);
+//  free(mnt->name);
+//  xbt_free(mnt);
+//  XBT_DEBUG("ROUTING Mount a storage name '%s' with type_id '%s'",mstorage->name, mstorage->id);
+}
+
+static void mount_free(void *p)
+{
+  mount_t mnt = (mount_t) p;
+  xbt_free(mnt->name);
+}
+
+static void storage_parse_mount(sg_platf_mount_cbarg_t mount)
+{
+  // Verification of an existing storage
+#ifndef NDEBUG
+  void* storage = xbt_lib_get_or_null(storage_lib, mount->storageId, ROUTING_STORAGE_LEVEL);
+#endif
+  xbt_assert(storage,"Disk id \"%s\" does not exists", mount->storageId);
+
+  XBT_DEBUG("ROUTING Mount '%s' on '%s'",mount->storageId, mount->name);
+
+  s_mount_t mnt;
+  mnt.storage = surf_storage_resource_priv(surf_storage_resource_by_name(mount->storageId));
+  mnt.name = xbt_strdup(mount->name);
+
+  if(!mount_list){
+    //FIXME:XBT_DEBUG("Create a Mount list for %s",A_surfxml_host_id);
+    mount_list = xbt_dynar_new(sizeof(s_mount_t), mount_free);
+  }
+  xbt_dynar_push(mount_list,&mnt);
+}
+
+static void storage_define_callbacks()
+{
+  sg_platf_storage_add_cb(parse_storage_init);
+  sg_platf_storage_type_add_cb(parse_storage_type_init);
+  sg_platf_mstorage_add_cb(parse_mstorage_init);
+  sg_platf_mount_add_cb(parse_mount_init);
+}
+
+void storage_register_callbacks() {
+
+  ROUTING_STORAGE_LEVEL = xbt_lib_add_level(storage_lib,xbt_free);
+  ROUTING_STORAGE_HOST_LEVEL = xbt_lib_add_level(storage_lib, routing_storage_host_free);
+  ROUTING_STORAGE_TYPE_LEVEL = xbt_lib_add_level(storage_type_lib, routing_storage_type_free);
+  SURF_STORAGE_LEVEL = xbt_lib_add_level(storage_lib, surf_storage_resource_free);
+
+  sg_platf_storage_add_cb(storage_parse_storage);
+  sg_platf_mstorage_add_cb(storage_parse_mstorage);
+  sg_platf_storage_type_add_cb(storage_parse_storage_type);
+  sg_platf_mount_add_cb(storage_parse_mount);
+}
+
+/*********
+ * Model *
+ *********/
+
+void surf_storage_model_init_default(void)
+{
+  surf_storage_model = new StorageModel();
+  storage_define_callbacks();
+  xbt_dynar_push(model_list, &surf_storage_model);
+}
+
+StorageModel::StorageModel() : Model("Storage") {
+  StorageActionLmm action;
+
+  XBT_DEBUG("surf_storage_model_init_internal");
+
+  storage_running_action_set_that_does_not_need_being_checked =
+      xbt_swag_new(xbt_swag_offset(action, p_stateHookup));
+
+  if (!p_maxminSystem) {
+    p_maxminSystem = lmm_system_new(storage_selective_update);
+  }
+}
+
+
+StorageModel::~StorageModel(){
+  lmm_system_free(p_maxminSystem);
+
+  surf_storage_model = NULL;
+
+  xbt_dynar_free(&storage_list);
+
+  xbt_swag_free(storage_running_action_set_that_does_not_need_being_checked);
+  storage_running_action_set_that_does_not_need_being_checked = NULL;
+}
+
+StoragePtr StorageModel::createResource(const char* id, const char* model, const char* type_id,
+               const char* content_name, const char* content_type, xbt_dict_t properties)
+{
+
+  xbt_assert(!surf_storage_resource_priv(surf_storage_resource_by_name(id)),
+              "Storage '%s' declared several times in the platform file",
+              id);
+
+  storage_type_t storage_type = (storage_type_t) xbt_lib_get_or_null(storage_type_lib, type_id,ROUTING_STORAGE_TYPE_LEVEL);
+
+  double Bread  = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bread"));
+  double Bwrite = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bwrite"));
+  double Bconnection   = surf_parse_get_bandwidth((char*)xbt_dict_get(storage_type->properties, "Bconnection"));
+
+  StoragePtr storage = new StorageLmm(this, id, properties, p_maxminSystem,
+                 Bread, Bwrite, Bconnection,
+                 type_id, (char *)content_name, xbt_strdup(content_type), storage_type->size);
+
+  xbt_lib_set(storage_lib, id, SURF_STORAGE_LEVEL, static_cast<ResourcePtr>(storage));
+
+  XBT_DEBUG("SURF storage create resource\n\t\tid '%s'\n\t\ttype '%s' \n\t\tmodel '%s' \n\t\tproperties '%p'\n\t\tBread '%f'\n",
+      id,
+      model,
+      type_id,
+      storage_type->properties,
+      Bread);
+
+  if(!storage_list)
+       storage_list = xbt_dynar_new(sizeof(char *),NULL);
+  xbt_dynar_push(storage_list, &storage);
+
+  return storage;
+}
+
+double StorageModel::shareResources(double now)
+{
+  XBT_DEBUG("storage_share_resources %f", now);
+  unsigned int i, j;
+  StoragePtr storage;
+  StorageActionLmmPtr write_action;
+
+  double min_completion = shareResourcesMaxMin(p_runningActionSet,
+      p_maxminSystem, lmm_solve);
+
+  double rate;
+  // Foreach disk
+  xbt_dynar_foreach(storage_list,i,storage)
+  {
+    rate = 0;
+    // Foreach write action on disk
+    xbt_dynar_foreach(storage->p_writeActions, j, write_action)
+    {
+      rate += lmm_variable_getvalue(write_action->p_variable);
+    }
+    if(rate > 0)
+      min_completion = MIN(min_completion, (storage->m_size-storage->m_usedSize)/rate);
+  }
+
+  return min_completion;
+}
+
+void StorageModel::updateActionsState(double now, double delta)
+{
+  void *_action, *_next_action;
+  StorageActionLmmPtr action = NULL;
+
+  xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
+       action = dynamic_cast<StorageActionLmmPtr>(static_cast<ActionPtr>(_action));
+    if(action->m_type == WRITE)
+    {
+      // Update the disk usage
+     // Update the file size
+     // For each action of type write
+      double rate = lmm_variable_getvalue(action->p_variable);
+      /* Hack to avoid rounding differences between x86 and x86_64
+       * (note that the next sizes are of type sg_storage_size_t). */
+      long incr = delta * rate + MAXMIN_PRECISION;
+      action->p_storage->m_usedSize += incr; // disk usage
+      action->p_file->size += incr; // file size
+
+      sg_storage_size_t *psize = xbt_new(sg_storage_size_t,1);
+      *psize = action->p_file->size;
+
+      xbt_dict_t content_dict = action->p_storage->p_content;
+      xbt_dict_set(content_dict, action->p_file->name, psize, NULL);
+    }
+
+    double_update(&action->m_remains,
+                  lmm_variable_getvalue(action->p_variable) * delta);
+
+    if (action->m_maxDuration != NO_MAX_DURATION)
+      double_update(&action->m_maxDuration, delta);
+
+    if(action->m_remains > 0 &&
+        lmm_get_variable_weight(action->p_variable) > 0 &&
+        action->p_storage->m_usedSize == action->p_storage->m_size)
+    {
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_FAILED);
+    } else if ((action->m_remains <= 0) &&
+        (lmm_get_variable_weight(action->p_variable) > 0))
+    {
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_DONE);
+    } else if ((action->m_maxDuration != NO_MAX_DURATION) &&
+               (action->m_maxDuration <= 0))
+    {
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_DONE);
+    }
+  }
+
+  return;
+}
+
+xbt_dict_t Storage::parseContent(char *filename)
+{
+  m_usedSize = 0;
+  if ((!filename) || (strcmp(filename, "") == 0))
+    return NULL;
+
+  xbt_dict_t parse_content = xbt_dict_new_homogeneous(xbt_free);
+  FILE *file = NULL;
+
+  file = surf_fopen(filename, "r");
+  xbt_assert(file != NULL, "Cannot open file '%s' (path=%s)", filename,
+              xbt_str_join(surf_path, ":"));
+
+  char *line = NULL;
+  size_t len = 0;
+  ssize_t read;
+  char path[1024];
+  sg_storage_size_t size;
+
+
+  while ((read = xbt_getline(&line, &len, file)) != -1) {
+    if (read){
+    if(sscanf(line,"%s %" SCNu64, path, &size) == 2) {
+        m_usedSize += size;
+        sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
+        *psize = size;
+        xbt_dict_set(parse_content,path,psize,NULL);
+      } else {
+        xbt_die("Be sure of passing a good format for content file.\n");
+      }
+    }
+  }
+  free(line);
+  fclose(file);
+  return parse_content;
+}
+
+/************
+ * Resource *
+ ************/
+
+Storage::Storage(StorageModelPtr model, const char* name, xbt_dict_t properties)
+:  Resource(model, name, properties)
+{
+  p_writeActions = xbt_dynar_new(sizeof(char *),NULL);
+}
+
+StorageLmm::StorageLmm(StorageModelPtr model, const char* name, xbt_dict_t properties,
+            lmm_system_t maxminSystem, double bread, double bwrite, double bconnection,
+            const char* type_id, char *content_name, char *content_type, size_t size)
+ :  Resource(model, name, properties), ResourceLmm(), Storage(model, name, properties) {
+  XBT_DEBUG("Create resource with Bconnection '%f' Bread '%f' Bwrite '%f' and Size '%lu'", bconnection, bread, bwrite, ((unsigned long)size));
+
+  p_stateCurrent = SURF_RESOURCE_ON;
+  m_usedSize = 0;
+  m_size = 0;
+
+  p_content = parseContent(content_name);
+  p_contentType = content_type;
+  p_constraint = lmm_constraint_new(maxminSystem, this, bconnection);
+  p_constraintRead  = lmm_constraint_new(maxminSystem, this, bread);
+  p_constraintWrite = lmm_constraint_new(maxminSystem, this, bwrite);
+  m_size = size;
+  p_typeId = xbt_strdup(type_id);
+}
+
+bool Storage::isUsed()
+{
+  THROW_UNIMPLEMENTED;
+  return false;
+}
+
+void Storage::updateState(tmgr_trace_event_t event_type, double value, double date)
+{
+  THROW_UNIMPLEMENTED;
+}
+
+StorageActionPtr StorageLmm::ls(const char* path)
+{
+  StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, LS);
+
+  action->p_lsDict = NULL;
+  xbt_dict_t ls_dict = xbt_dict_new_homogeneous(xbt_free);
+
+  char* key;
+  sg_storage_size_t size = 0;
+  xbt_dict_cursor_t cursor = NULL;
+
+  xbt_dynar_t dyn = NULL;
+  char* file = NULL;
+
+  // for each file in the storage content
+  xbt_dict_foreach(p_content,cursor,key,size){
+    // Search if file start with the prefix 'path'
+    if(xbt_str_start_with(key,path)){
+      file = &key[strlen(path)];
+
+      // Split file with '/'
+      dyn = xbt_str_split(file,"/");
+      file = xbt_dynar_get_as(dyn,0,char*);
+
+      // file
+      if(xbt_dynar_length(dyn) == 1){
+        sg_storage_size_t *psize = xbt_new(sg_storage_size_t, 1);
+        *psize=size;
+        xbt_dict_set(ls_dict, file, psize, NULL);
+      }
+      // Directory
+      else
+      {
+        // if directory does not exist yet in the dictionary
+        if(!xbt_dict_get_or_null(ls_dict,file))
+          xbt_dict_set(ls_dict,file,NULL,NULL);
+      }
+      xbt_dynar_free(&dyn);
+    }
+  }
+
+  action->p_lsDict = ls_dict;
+  return action;
+}
+
+StorageActionPtr StorageLmm::open(const char* mount, const char* path)
+{
+  XBT_DEBUG("\tOpen file '%s'",path);
+  sg_storage_size_t size, *psize;
+  psize = (sg_storage_size_t*) xbt_dict_get_or_null(p_content, path);
+  // if file does not exist create an empty file
+  if(psize)
+    size = *psize;
+  else {
+       psize = xbt_new(sg_storage_size_t,1);
+    size = 0;
+    *psize = size;
+    xbt_dict_set(p_content, path, psize, NULL);
+    XBT_DEBUG("File '%s' was not found, file created.",path);
+  }
+  surf_file_t file = xbt_new0(s_surf_file_t,1);
+  file->name = xbt_strdup(path);
+  file->size = size;
+  file->mount = xbt_strdup(mount);
+
+  StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, OPEN);
+  action->p_file = file;
+  return action;
+}
+
+StorageActionPtr StorageLmm::close(surf_file_t fd)
+{
+  char *filename = fd->name;
+  XBT_DEBUG("\tClose file '%s' size '%" PRIu64 "'", filename, fd->size);
+  // unref write actions from storage
+  StorageActionLmmPtr write_action;
+  unsigned int i;
+  xbt_dynar_foreach(p_writeActions, i, write_action) {
+    if ((write_action->p_file) == fd) {
+      xbt_dynar_cursor_rm(p_writeActions, &i);
+      write_action->unref();
+    }
+  }
+  free(fd->name);
+  free(fd->mount);
+  xbt_free(fd);
+  StorageActionLmmPtr action = new StorageActionLmm(p_model, 0, p_stateCurrent != SURF_RESOURCE_ON, this, CLOSE);
+  return action;
+}
+
+StorageActionPtr StorageLmm::read(surf_file_t fd, sg_storage_size_t size)
+{
+  if(size > fd->size)
+    size = fd->size;
+  StorageActionLmmPtr action = new StorageActionLmm(p_model, size, p_stateCurrent != SURF_RESOURCE_ON, this, READ);
+  return action;
+}
+
+StorageActionPtr StorageLmm::write(surf_file_t fd, sg_storage_size_t size)
+{
+  char *filename = fd->name;
+  XBT_DEBUG("\tWrite file '%s' size '%" PRIu64 "/%" PRIu64 "'",filename,size,fd->size);
+
+  StorageActionLmmPtr action = new StorageActionLmm(p_model, size, p_stateCurrent != SURF_RESOURCE_ON, this, WRITE);
+  action->p_file = fd;
+
+  // If the storage is full
+  if(m_usedSize==m_size) {
+    action->setState(SURF_ACTION_FAILED);
+  }
+  return action;
+}
+
+xbt_dict_t StorageLmm::getContent()
+{
+  /* For the moment this action has no cost, but in the future we could take in account access latency of the disk */
+  /*surf_action_t action = storage_action_execute(storage,0, LS);*/
+
+  xbt_dict_t content_dict = xbt_dict_new_homogeneous(NULL);
+  xbt_dict_cursor_t cursor = NULL;
+  char *file;
+  sg_storage_size_t *psize;
+
+  xbt_dict_foreach(p_content, cursor, file, psize){
+    xbt_dict_set(content_dict,file,psize,NULL);
+  }
+  return content_dict;
+}
+
+sg_storage_size_t StorageLmm::getSize(){
+  return m_size;
+}
+
+/**********
+ * Action *
+ **********/
+
+StorageActionLmm::StorageActionLmm(ModelPtr model, double cost, bool failed, StorageLmmPtr storage, e_surf_action_storage_type_t type)
+  : Action(model, cost, failed), ActionLmm(model, cost, failed), StorageAction(model, cost, failed, storage, type) {
+  XBT_IN("(%s,%" PRIu64, storage->m_name, cost);
+  p_variable = lmm_variable_new(p_model->p_maxminSystem, this, 1.0, -1.0 , 3);
+
+  // Must be less than the max bandwidth for all actions
+  lmm_expand(p_model->p_maxminSystem, storage->p_constraint, p_variable, 1.0);
+  switch(type) {
+  case OPEN:
+  case CLOSE:
+  case STAT:
+  case LS:
+    break;
+  case READ:
+    lmm_expand(p_model->p_maxminSystem, storage->p_constraintRead,
+               p_variable, 1.0);
+    break;
+  case WRITE:
+    lmm_expand(p_model->p_maxminSystem, storage->p_constraintWrite,
+               p_variable, 1.0);
+    xbt_dynar_push(storage->p_writeActions, static_cast<ActionPtr>(this));
+    break;
+  }
+  XBT_OUT();
+}
+
+int StorageActionLmm::unref()
+{
+  m_refcount--;
+  if (!m_refcount) {
+    xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+    if (p_variable)
+      lmm_variable_free(p_model->p_maxminSystem, p_variable);
+#ifdef HAVE_TRACING
+    xbt_free(p_category);
+#endif
+    delete this;
+    return 1;
+  }
+  return 0;
+}
+
+void StorageActionLmm::cancel()
+{
+  setState(SURF_ACTION_FAILED);
+  return;
+}
+
+void StorageActionLmm::suspend()
+{
+  XBT_IN("(%p)", this);
+  if (m_suspended != 2) {
+    lmm_update_variable_weight(p_model->p_maxminSystem,
+                               p_variable,
+                               0.0);
+    m_suspended = 1;
+  }
+  XBT_OUT();
+}
+
+void StorageActionLmm::resume()
+{
+  THROW_UNIMPLEMENTED;
+}
+
+bool StorageActionLmm::isSuspended()
+{
+  return m_suspended == 1;
+}
+
+void StorageActionLmm::setMaxDuration(double duration)
+{
+  THROW_UNIMPLEMENTED;
+}
+
+void StorageActionLmm::setPriority(double priority)
+{
+  THROW_UNIMPLEMENTED;
+}
+
diff --git a/src/surf/storage.hpp b/src/surf/storage.hpp
new file mode 100644 (file)
index 0000000..cceebf5
--- /dev/null
@@ -0,0 +1,150 @@
+#include "surf.hpp"
+
+#ifndef STORAGE_HPP_
+#define STORAGE_HPP_
+
+/***********
+ * Classes *
+ ***********/
+
+class StorageModel;
+typedef StorageModel *StorageModelPtr;
+
+class Storage;
+typedef Storage *StoragePtr;
+
+class StorageLmm;
+typedef StorageLmm *StorageLmmPtr;
+
+class StorageAction;
+typedef StorageAction *StorageActionPtr;
+
+class StorageActionLmm;
+typedef StorageActionLmm *StorageActionLmmPtr;
+
+
+/*********
+ * Model *
+ *********/
+class StorageModel : public Model {
+public:
+  StorageModel();
+  ~StorageModel();
+  StoragePtr createResource(const char* id, const char* model, const char* type_id,
+                  const char* content_name, const char* content_type, xbt_dict_t properties);
+  double shareResources(double now);
+  void updateActionsState(double now, double delta);
+
+};
+
+/************
+ * Resource *
+ ************/
+
+class Storage : virtual public Resource {
+public:
+  Storage(StorageModelPtr model, const char* name, xbt_dict_t properties);
+
+  bool isUsed();
+  void updateState(tmgr_trace_event_t event_type, double value, double date);
+
+  xbt_dict_t p_content;
+  char* p_contentType;
+  sg_storage_size_t m_size;
+  sg_storage_size_t m_usedSize;
+  char * p_typeId;
+
+  virtual StorageActionPtr open(const char* mount, const char* path)=0;
+  virtual StorageActionPtr close(surf_file_t fd)=0;
+  //virtual StorageActionPtr unlink(surf_file_t fd)=0;
+  virtual StorageActionPtr ls(const char *path)=0;
+  virtual StorageActionPtr read(surf_file_t fd, sg_storage_size_t size)=0;
+  virtual StorageActionPtr write(surf_file_t fd, sg_storage_size_t size)=0;
+  virtual xbt_dict_t getContent()=0;
+  virtual sg_storage_size_t getSize()=0;
+
+  xbt_dict_t parseContent(char *filename);
+
+  xbt_dynar_t p_writeActions;
+};
+
+class StorageLmm : public ResourceLmm, public Storage {
+public:
+  StorageLmm(StorageModelPtr model, const char* name, xbt_dict_t properties,
+                    lmm_system_t maxminSystem, double bread, double bwrite, double bconnection,
+                    const char* type_id, char *content_name, char *content_type, size_t size);
+
+  StorageActionPtr open(const char* mount, const char* path);
+  StorageActionPtr close(surf_file_t fd);
+  //StorageActionPtr unlink(surf_file_t fd);
+  StorageActionPtr ls(const char *path);
+  xbt_dict_t getContent();
+  sg_storage_size_t getSize();
+  StorageActionPtr read(surf_file_t fd, sg_storage_size_t size);//FIXME:why we have a useless param ptr ??
+  StorageActionPtr write(surf_file_t fd, sg_storage_size_t size);//FIXME:why we have a useless param ptr ??
+
+  lmm_constraint_t p_constraintWrite;    /* Constraint for maximum write bandwidth*/
+  lmm_constraint_t p_constraintRead;     /* Constraint for maximum write bandwidth*/
+};
+
+/**********
+ * Action *
+ **********/
+
+typedef enum {
+  READ=0, WRITE, STAT, OPEN, CLOSE, LS
+} e_surf_action_storage_type_t;
+
+
+class StorageAction : virtual public Action {
+public:
+  StorageAction(){};
+  StorageAction(ModelPtr model, double cost, bool failed, StoragePtr storage, e_surf_action_storage_type_t type)
+   : p_storage(storage), m_type(type) {};
+
+
+
+  e_surf_action_storage_type_t m_type;
+  StoragePtr p_storage;
+  surf_file_t p_file;
+  xbt_dict_t p_lsDict;
+};
+
+class StorageActionLmm : public ActionLmm, public StorageAction {
+public:
+  StorageActionLmm(){};
+  StorageActionLmm(ModelPtr model, double cost, bool failed, StorageLmmPtr storage, e_surf_action_storage_type_t type);
+  void suspend();
+  int unref();
+  void cancel();
+  //FIXME:??void recycle();
+  void resume();
+  bool isSuspended();
+  void setMaxDuration(double duration);
+  void setPriority(double priority);
+
+};
+
+
+typedef struct s_storage_type {
+  char *model;
+  char *content;
+  char *content_type;
+  char *type_id;
+  xbt_dict_t properties;
+  sg_storage_size_t size;
+} s_storage_type_t, *storage_type_t;
+
+typedef struct s_mount {
+  void *storage;
+  char *name;
+} s_mount_t, *mount_t;
+
+typedef struct surf_file {
+  char *name;
+  char *mount;
+  sg_storage_size_t size;
+} s_surf_file_t;
+
+
+#endif /* STORAGE_HPP_ */
index ee023b4..13b67f7 100644 (file)
@@ -27,8 +27,16 @@ typedef struct surf_file {
   sg_storage_size_t size;
 } s_surf_file_t;
 
+<<<<<<< HEAD
+typedef struct storage {
+  //FIXME:s_surf_resource_t generic_resource;   /*< Structure with generic data. Needed at begin to interact with SURF */
+||||||| merged common ancestors
+typedef struct storage {
+  s_surf_resource_t generic_resource;   /*< Structure with generic data. Needed at begin to interact with SURF */
+=======
 typedef struct surf_storage {
   s_surf_resource_t generic_resource;   /*< Structure with generic data. Needed at begin to interact with SURF */
+>>>>>>> 045db1657e870c721be490b411868f4181a12ced
   e_surf_resource_state_t state_current;        /*< STORAGE current state (ON or OFF) */
   lmm_constraint_t constraint;          /* Constraint for maximum bandwidth from connection */
   lmm_constraint_t constraint_write;    /* Constraint for maximum write bandwidth*/
@@ -47,7 +55,7 @@ typedef enum {
 } e_surf_action_storage_type_t;
 
 typedef struct surf_action_storage {
-  s_surf_action_lmm_t generic_lmm_action;
+  //FIXME:s_surf_action_lmm_t generic_lmm_action;
   e_surf_action_storage_type_t type;
   void *storage;
 } s_surf_action_storage_t, *surf_action_storage_t;
diff --git a/src/surf/surf.cpp b/src/surf/surf.cpp
new file mode 100644 (file)
index 0000000..010de57
--- /dev/null
@@ -0,0 +1,1053 @@
+#include "surf_private.h"
+#include "surf.hpp"
+#include "network.hpp"
+#include "cpu.hpp"
+#include "workstation.hpp"
+#include "simix/smx_host_private.h"
+#include "surf_routing.hpp"
+#include "simgrid/sg_config.h"
+#include "mc/mc.h"
+
+extern "C" {
+XBT_LOG_NEW_CATEGORY(surf, "All SURF categories");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_kernel, surf,
+                                "Logging specific to SURF (kernel)");
+}
+
+/*********
+ * Utils *
+ *********/
+
+/* 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((smx_host_t)host) == SURF_RESOURCE_ON){
+      XBT_INFO("Restart processes on host: %s", SIMIX_host_get_name((smx_host_t)host));
+      SIMIX_host_autorestart((smx_host_t)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);
+}*/
+
+
+xbt_dynar_t model_list = NULL;
+tmgr_history_t history = NULL;
+lmm_system_t maxmin_system = NULL;
+xbt_dynar_t surf_path = NULL;
+xbt_dynar_t host_that_restart = NULL;
+xbt_dict_t watched_hosts_lib;
+
+/* Don't forget to update the option description in smx_config when you change this */
+s_surf_model_description_t surf_network_model_description[] = {
+  {"LV08",
+   "Realistic network analytic model (slow-start modeled by multiplying latency by 10.4, bandwidth by .92; bottleneck sharing uses a payload of S=8775 for evaluating RTT). ",
+   surf_network_model_init_LegrandVelho},
+  {"Constant",
+   "Simplistic network model where all communication take a constant time (one second). This model provides the lowest realism, but is (marginally) faster.",
+   surf_network_model_init_Constant},
+  {"SMPI",
+   "Realistic network model specifically tailored for HPC settings (accurate modeling of slow start with correction factors on three intervals: < 1KiB, < 64 KiB, >= 64 KiB)",
+   surf_network_model_init_SMPI},
+  {"CM02",
+   "Legacy network analytic model (Very similar to LV08, but without corrective factors. The timings of small messages are thus poorly modeled).",
+   surf_network_model_init_CM02},
+#ifdef HAVE_GTNETS
+  {"GTNets",
+   "Network pseudo-model using the GTNets simulator instead of an analytic model",
+   surf_network_model_init_GTNETS},
+#endif
+#ifdef HAVE_NS3
+  {"NS3",
+   "Network pseudo-model using the NS3 tcp model instead of an analytic model",
+  surf_network_model_init_NS3},
+#endif
+  {"Reno",
+   "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
+   surf_network_model_init_Reno},
+  {"Reno2",
+   "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
+   surf_network_model_init_Reno2},
+  {"Vegas",
+   "Model from Steven H. Low using lagrange_solve instead of lmm_solve (experts only; check the code for more info).",
+   surf_network_model_init_Vegas},
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
+
+s_surf_model_description_t surf_cpu_model_description[] = {
+  {"Cas01",
+   "Simplistic CPU model (time=size/power).",
+   surf_cpu_model_init_Cas01},
+  {NULL, NULL,  NULL}      /* this array must be NULL terminated */
+};
+
+s_surf_model_description_t surf_workstation_model_description[] = {
+  {"default",
+   "Default workstation model. Currently, CPU:Cas01 and network:LV08 (with cross traffic enabled)",
+   surf_workstation_model_init_current_default},
+  {"compound",
+   "Workstation model that is automatically chosen if you change the network and CPU models",
+   surf_workstation_model_init_compound},
+  {"ptask_L07", "Workstation model somehow similar to Cas01+CM02 but allowing parallel tasks",
+   surf_workstation_model_init_ptask_L07},
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
+
+s_surf_model_description_t surf_optimization_mode_description[] = {
+  {"Lazy",
+   "Lazy action management (partial invalidation in lmm + heap in action remaining).",
+   NULL},
+  {"TI",
+   "Trace integration. Highly optimized mode when using availability traces (only available for the Cas01 CPU model for now).",
+    NULL},
+  {"Full",
+   "Full update of remaining and variables. Slow but may be useful when debugging.",
+   NULL},
+  {NULL, NULL, NULL}      /* this array must be NULL terminated */
+};
+
+s_surf_model_description_t surf_storage_model_description[] = {
+  {"default",
+   "Simplistic storage model.",
+   surf_storage_model_init_default},
+  {NULL, NULL,  NULL}      /* this array must be NULL terminated */
+};
+
+#ifdef CONTEXT_THREADS
+static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
+#endif
+
+static double *surf_mins = NULL; /* return value of share_resources for each model */
+static int surf_min_index;       /* current index in surf_mins */
+static double min;               /* duration determined by surf_solve */
+
+double NOW = 0;
+
+double surf_get_clock(void)
+{
+  return NOW;
+}
+
+#ifdef _XBT_WIN32
+# define FILE_DELIM "\\"
+#else
+# define FILE_DELIM "/"         /* FIXME: move to better location */
+#endif
+
+FILE *surf_fopen(const char *name, const char *mode)
+{
+  unsigned int cpt;
+  char *path_elm = NULL;
+  char *buff;
+  FILE *file = NULL;
+
+  xbt_assert(name);
+
+  if (__surf_is_absolute_file_path(name))       /* don't mess with absolute file names */
+    return fopen(name, mode);
+
+  /* search relative files in the path */
+  xbt_dynar_foreach(surf_path, cpt, path_elm) {
+    buff = bprintf("%s" FILE_DELIM "%s", path_elm, name);
+    file = fopen(buff, mode);
+    free(buff);
+
+    if (file)
+      return file;
+  }
+  return NULL;
+}
+
+/*
+ * Returns the initial path. On Windows the initial path is
+ * the current directory for the current process in the other
+ * case the function returns "./" that represents the current
+ * directory on Unix/Linux platforms.
+ */
+
+const char *__surf_get_initial_path(void)
+{
+
+#ifdef _XBT_WIN32
+  unsigned i;
+  char current_directory[MAX_PATH + 1] = { 0 };
+  unsigned int len = GetCurrentDirectory(MAX_PATH + 1, current_directory);
+  char root[4] = { 0 };
+
+  if (!len)
+    return NULL;
+
+  strncpy(root, current_directory, 3);
+
+  for (i = 0; i < MAX_DRIVE; i++) {
+    if (toupper(root[0]) == disk_drives_letter_table[i][0])
+      return disk_drives_letter_table[i];
+  }
+
+  return NULL;
+#else
+  return "./";
+#endif
+}
+
+/* The __surf_is_absolute_file_path() returns 1 if
+ * file_path is a absolute file path, in the other
+ * case the function returns 0.
+ */
+int __surf_is_absolute_file_path(const char *file_path)
+{
+#ifdef _XBT_WIN32
+  WIN32_FIND_DATA wfd = { 0 };
+  HANDLE hFile = FindFirstFile(file_path, &wfd);
+
+  if (INVALID_HANDLE_VALUE == hFile)
+    return 0;
+
+  FindClose(hFile);
+  return 1;
+#else
+  return (file_path[0] == '/');
+#endif
+}
+
+/** Displays the long description of all registered models, and quit */
+void model_help(const char *category, s_surf_model_description_t * table)
+{
+  int i;
+  printf("Long description of the %s models accepted by this simulator:\n",
+         category);
+  for (i = 0; table[i].name; i++)
+    printf("  %s: %s\n", table[i].name, table[i].description);
+}
+
+int find_model_description(s_surf_model_description_t * table,
+                           const char *name)
+{
+  int i;
+  char *name_list = NULL;
+
+  for (i = 0; table[i].name; i++)
+    if (!strcmp(name, table[i].name)) {
+      return i;
+    }
+  name_list = strdup(table[0].name);
+  for (i = 1; table[i].name; i++) {
+    name_list = (char *) xbt_realloc(name_list, strlen(name_list) + strlen(table[i].name) + 3);
+    strcat(name_list, ", ");
+    strcat(name_list, table[i].name);
+  }
+  xbt_die("Model '%s' is invalid! Valid models are: %s.", name, name_list);
+  return -1;
+}
+
+static XBT_INLINE void routing_asr_host_free(void *p)
+{
+  delete ((RoutingEdgePtr) p);
+}
+
+static XBT_INLINE void routing_asr_prop_free(void *p)
+{
+  xbt_dict_t elm = (xbt_dict_t) p;
+  xbt_dict_free(&elm);
+}
+
+static XBT_INLINE void surf_cpu_free(void *r)
+{
+  delete dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(r));
+}
+
+static XBT_INLINE void surf_link_free(void *r)
+{
+  delete dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(r));
+}
+
+static XBT_INLINE void surf_workstation_free(void *r)
+{
+  delete dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(r));
+}
+
+
+void sg_version(int *ver_major,int *ver_minor,int *ver_patch) {
+  *ver_major = SIMGRID_VERSION_MAJOR;
+  *ver_minor = SIMGRID_VERSION_MINOR;
+  *ver_patch = SIMGRID_VERSION_PATCH;
+}
+
+void surf_init(int *argc, char **argv)
+{
+  XBT_DEBUG("Create all Libs");
+  host_lib = xbt_lib_new();
+  link_lib = xbt_lib_new();
+  as_router_lib = xbt_lib_new();
+  storage_lib = xbt_lib_new();
+  storage_type_lib = xbt_lib_new();
+  watched_hosts_lib = xbt_dict_new_homogeneous(NULL);
+
+  XBT_DEBUG("Add routing levels");
+  ROUTING_HOST_LEVEL = xbt_lib_add_level(host_lib,routing_asr_host_free);
+  ROUTING_ASR_LEVEL  = xbt_lib_add_level(as_router_lib,routing_asr_host_free);
+  ROUTING_PROP_ASR_LEVEL = xbt_lib_add_level(as_router_lib,routing_asr_prop_free);
+
+  XBT_DEBUG("Add SURF levels");
+  SURF_CPU_LEVEL = xbt_lib_add_level(host_lib,surf_cpu_free);
+  SURF_WKS_LEVEL = xbt_lib_add_level(host_lib,surf_workstation_free);
+  SURF_LINK_LEVEL = xbt_lib_add_level(link_lib,surf_link_free);
+
+  xbt_init(argc, argv);
+  if (!model_list)
+    model_list = xbt_dynar_new(sizeof(surf_model_private_t), NULL);
+  if (!history)
+    history = tmgr_history_new();
+
+#ifdef HAVE_TRACING
+  TRACE_add_start_function(TRACE_surf_alloc);
+  TRACE_add_end_function(TRACE_surf_release);
+#endif
+
+  sg_config_init(argc, argv);
+
+  surf_action_init();
+  if (MC_is_active())
+    MC_memory_init();
+}
+
+void surf_exit(void)
+{
+  unsigned int iter;
+  ModelPtr model = NULL;
+
+#ifdef HAVE_TRACING
+  TRACE_end();                  /* Just in case it was not called by the upper
+                                 * layer (or there is no upper layer) */
+#endif
+
+  sg_config_finalize();
+
+  xbt_dynar_foreach(model_list, iter, model)
+    delete model;
+  xbt_dynar_free(&model_list);
+  routing_exit();
+
+  if (maxmin_system) {
+    lmm_system_free(maxmin_system);
+    maxmin_system = NULL;
+  }
+  if (history) {
+    tmgr_history_free(history);
+    history = NULL;
+  }
+  surf_action_exit();
+
+#ifdef CONTEXT_THREADS
+  xbt_parmap_destroy(surf_parmap);
+  xbt_free(surf_mins);
+  surf_mins = NULL;
+#endif
+  xbt_dynar_free(&host_that_restart);
+  xbt_dynar_free(&surf_path);
+
+  xbt_lib_free(&host_lib);
+  xbt_lib_free(&link_lib);
+  xbt_lib_free(&as_router_lib);
+  xbt_lib_free(&storage_lib);
+  xbt_lib_free(&storage_type_lib);
+
+  xbt_dict_free(&watched_hosts_lib);
+
+  tmgr_finalize();
+  surf_parse_lex_destroy();
+  surf_parse_free_callbacks();
+
+  NOW = 0;                      /* Just in case the user plans to restart the simulation afterward */
+}
+/*********
+ * Model *
+ *********/
+
+Model::Model(string name)
+ : m_name(name), m_resOnCB(0), m_resOffCB(0),
+   m_actSuspendCB(0), m_actCancelCB(0), m_actResumeCB(0),
+   p_maxminSystem(0)
+{
+  ActionPtr action;
+  p_readyActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+  p_runningActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+  p_failedActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+  p_doneActionSet = xbt_swag_new(xbt_swag_offset(*action, p_stateHookup));
+
+  p_modifiedSet = NULL;
+  p_actionHeap = NULL;
+  p_updateMechanism = UM_UNDEFINED;
+  m_selectiveUpdate = 0;
+}
+
+Model::~Model(){
+xbt_swag_free(p_readyActionSet);
+xbt_swag_free(p_runningActionSet);
+xbt_swag_free(p_failedActionSet);
+xbt_swag_free(p_doneActionSet);
+}
+
+double Model::shareResources(double now)
+{
+  //FIXME: set the good function once and for all
+  if (p_updateMechanism == UM_LAZY)
+       return shareResourcesLazy(now);
+  else if (p_updateMechanism == UM_FULL)
+       return shareResourcesFull(now);
+  else
+       xbt_die("Invalid cpu update mechanism!");
+}
+
+double Model::shareResourcesLazy(double now)
+{
+  ActionLmmPtr action = NULL;
+  double min = -1;
+  double value;
+
+  XBT_DEBUG
+      ("Before share resources, the size of modified actions set is %d",
+       xbt_swag_size(p_modifiedSet));
+
+  lmm_solve(p_maxminSystem);
+
+  XBT_DEBUG
+      ("After share resources, The size of modified actions set is %d",
+       xbt_swag_size(p_modifiedSet));
+
+  while((action = static_cast<ActionLmmPtr>(xbt_swag_extract(p_modifiedSet)))) {
+    int max_dur_flag = 0;
+
+    if (action->p_stateSet != p_runningActionSet)
+      continue;
+
+    /* bogus priority, skip it */
+    if (action->m_priority <= 0)
+      continue;
+
+    action->updateRemainingLazy(now);
+
+    min = -1;
+    value = lmm_variable_getvalue(action->p_variable);
+    if (value > 0) {
+      if (action->m_remains > 0) {
+        value = action->m_remains / value;
+        min = now + value;
+      } else {
+        value = 0.0;
+        min = now;
+      }
+    }
+
+    if ((action->m_maxDuration != NO_MAX_DURATION)
+        && (min == -1
+            || action->m_start +
+            action->m_maxDuration < min)) {
+      min = action->m_start +
+          action->m_maxDuration;
+      max_dur_flag = 1;
+    }
+
+    XBT_DEBUG("Action(%p) Start %lf Finish %lf Max_duration %lf", action,
+        action->m_start, now + value,
+        action->m_maxDuration);
+
+    if (min != -1) {
+      action->heapRemove(p_actionHeap);
+      action->heapInsert(p_actionHeap, min, max_dur_flag ? MAX_DURATION : NORMAL);
+      XBT_DEBUG("Insert at heap action(%p) min %lf now %lf", action, min,
+                now);
+    } else DIE_IMPOSSIBLE;
+  }
+
+  //hereafter must have already the min value for this resource model
+  if (xbt_heap_size(p_actionHeap) > 0)
+    min = xbt_heap_maxkey(p_actionHeap) - now;
+  else
+    min = -1;
+
+  XBT_DEBUG("The minimum with the HEAP %lf", min);
+
+  return min;
+}
+
+double Model::shareResourcesFull(double now) {
+  THROW_UNIMPLEMENTED;
+}
+
+
+double Model::shareResourcesMaxMin(xbt_swag_t running_actions,
+                          lmm_system_t sys,
+                          void (*solve) (lmm_system_t))
+{
+  void *_action = NULL;
+  ActionLmmPtr action = NULL;
+  double min = -1;
+  double value = -1;
+
+  solve(sys);
+
+  xbt_swag_foreach(_action, running_actions) {
+    action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
+    value = lmm_variable_getvalue(action->p_variable);
+    if ((value > 0) || (action->m_maxDuration >= 0))
+      break;
+  }
+
+  if (!_action)
+    return -1.0;
+
+  if (value > 0) {
+    if (action->m_remains > 0)
+      min = action->m_remains / value;
+    else
+      min = 0.0;
+    if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min))
+      min = action->m_maxDuration;
+  } else
+    min = action->m_maxDuration;
+
+
+  for (_action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset);
+       _action;
+       _action = xbt_swag_getNext(static_cast<ActionPtr>(action), running_actions->offset)) {
+       action = dynamic_cast<ActionLmmPtr>(static_cast<ActionPtr>(_action));
+    value = lmm_variable_getvalue(action->p_variable);
+    if (value > 0) {
+      if (action->m_remains > 0)
+        value = action->m_remains / value;
+      else
+        value = 0.0;
+      if (value < min) {
+        min = value;
+        XBT_DEBUG("Updating min (value) with %p: %f", action, min);
+      }
+    }
+    if ((action->m_maxDuration >= 0) && (action->m_maxDuration < min)) {
+      min = action->m_maxDuration;
+      XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
+    }
+  }
+  XBT_DEBUG("min value : %f", min);
+
+  return min;
+}
+
+void Model::updateActionsState(double now, double delta)
+{
+  if (p_updateMechanism == UM_FULL)
+       updateActionsStateFull(now, delta);
+  else if (p_updateMechanism == UM_LAZY)
+       updateActionsStateLazy(now, delta);
+  else
+       xbt_die("Invalid cpu update mechanism!");
+}
+
+void Model::updateActionsStateLazy(double now, double delta)
+{
+
+}
+
+void Model::updateActionsStateFull(double now, double delta)
+{
+
+}
+
+
+void Model::addTurnedOnCallback(ResourceCallback rc)
+{
+  m_resOnCB = rc;
+}
+
+void Model::notifyResourceTurnedOn(ResourcePtr r)
+{
+  m_resOnCB(r);
+}
+
+void Model::addTurnedOffCallback(ResourceCallback rc)
+{
+  m_resOffCB = rc;
+}
+
+void Model::notifyResourceTurnedOff(ResourcePtr r)
+{
+  m_resOffCB(r);
+}
+
+void Model::addActionCancelCallback(ActionCallback ac)
+{
+  m_actCancelCB = ac;
+}
+
+void Model::notifyActionCancel(ActionPtr a)
+{
+  m_actCancelCB(a);
+}
+
+void Model::addActionResumeCallback(ActionCallback ac)
+{
+  m_actResumeCB = ac;
+}
+
+void Model::notifyActionResume(ActionPtr a)
+{
+  m_actResumeCB(a);
+}
+
+void Model::addActionSuspendCallback(ActionCallback ac)
+{
+  m_actSuspendCB = ac;
+}
+
+void Model::notifyActionSuspend(ActionPtr a)
+{
+  m_actSuspendCB(a);
+}
+
+
+/************
+ * Resource *
+ ************/
+
+Resource::Resource(surf_model_t model, const char *name, xbt_dict_t props)
+  : m_name(xbt_strdup(name)), m_running(true), p_model(model), m_properties(props)
+{}
+
+Resource::Resource(){
+  //FIXME:free(m_name);
+  //FIXME:xbt_dict_free(&m_properties);
+}
+
+const char *Resource::getName()
+{
+  return m_name;
+}
+
+xbt_dict_t Resource::getProperties()
+{
+  return m_properties;
+}
+
+e_surf_resource_state_t Resource::getState()
+{
+  return p_stateCurrent;
+}
+
+bool Resource::isOn()
+{
+  return m_running;
+}
+
+void Resource::turnOn()
+{
+  if (!m_running) {
+    m_running = true;
+    p_model->notifyResourceTurnedOn(this);
+  }
+}
+
+void Resource::turnOff()
+{
+  if (m_running) {
+    m_running = false;
+    p_model->notifyResourceTurnedOff(this);
+  }
+}
+
+ResourceLmm::ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
+                         lmm_system_t system,
+                         double constraint_value,
+                         tmgr_history_t history,
+                         e_surf_resource_state_t state_init,
+                         tmgr_trace_t state_trace,
+                         double metric_peak,
+                         tmgr_trace_t metric_trace)
+  : Resource(model, name, props)
+{
+  p_constraint = lmm_constraint_new(system, this, constraint_value);
+  p_stateCurrent = state_init;
+  if (state_trace)
+    p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(this));
+  p_power.scale = 1.0;
+  p_power.peak = metric_peak;
+  if (metric_trace)
+    p_power.event = tmgr_history_add_trace(history, metric_trace, 0.0, 0, static_cast<ResourcePtr>(this));
+}
+
+/**********
+ * Action *
+ **********/
+
+const char *surf_action_state_names[6] = {
+  "SURF_ACTION_READY",
+  "SURF_ACTION_RUNNING",
+  "SURF_ACTION_FAILED",
+  "SURF_ACTION_DONE",
+  "SURF_ACTION_TO_FREE",
+  "SURF_ACTION_NOT_IN_THE_SYSTEM"
+};
+
+/**
+ * \brief Initializes the action module of Surf.
+ */
+void surf_action_init(void) {
+
+  /* the action mallocator will always provide actions of the following size,
+   * so this size should be set to the maximum size of the surf action structures
+   */
+  /*FIXME:action_mallocator_allocated_size = sizeof(s_surf_action_network_CM02_t);
+  action_mallocator = xbt_mallocator_new(65536, surf_action_mallocator_new_f,
+      surf_action_mallocator_free_f, surf_action_mallocator_reset_f);*/
+}
+
+/**
+ * \brief Uninitializes the action module of Surf.
+ */
+void surf_action_exit(void) {
+  //FIXME:xbt_mallocator_free(action_mallocator);
+}
+
+Action::Action(){}
+
+Action::Action(ModelPtr model, double cost, bool failed):
+        m_cost(cost), p_model(model), m_failed(failed), m_remains(cost),
+        m_refcount(1), m_priority(1.0), m_maxDuration(NO_MAX_DURATION),
+        m_start(surf_get_clock()), m_finish(-1.0)
+{
+  #ifdef HAVE_TRACING
+    p_category = NULL;
+  #endif
+  p_stateHookup.prev = 0;
+  p_stateHookup.next = 0;
+  if (failed)
+    p_stateSet = p_model->p_failedActionSet;
+  else
+    p_stateSet = p_model->p_runningActionSet;
+
+  xbt_swag_insert(this, p_stateSet);
+}
+
+Action::~Action() {}
+
+int Action::unref(){
+  DIE_IMPOSSIBLE;
+}
+
+void Action::cancel(){
+  DIE_IMPOSSIBLE;
+}
+
+void Action::recycle(){
+  DIE_IMPOSSIBLE;
+}
+
+e_surf_action_state_t Action::getState()
+{
+  if (p_stateSet ==  p_model->p_readyActionSet)
+    return SURF_ACTION_READY;
+  if (p_stateSet ==  p_model->p_runningActionSet)
+    return SURF_ACTION_RUNNING;
+  if (p_stateSet ==  p_model->p_failedActionSet)
+    return SURF_ACTION_FAILED;
+  if (p_stateSet ==  p_model->p_doneActionSet)
+    return SURF_ACTION_DONE;
+  return SURF_ACTION_NOT_IN_THE_SYSTEM;
+}
+
+void Action::setState(e_surf_action_state_t state)
+{
+  //surf_action_state_t action_state = &(action->model_type->states);
+  XBT_IN("(%p,%s)", this, surf_action_state_names[state]);
+  xbt_swag_remove(this, p_stateSet);
+
+  if (state == SURF_ACTION_READY)
+    p_stateSet = p_model->p_readyActionSet;
+  else if (state == SURF_ACTION_RUNNING)
+    p_stateSet = p_model->p_runningActionSet;
+  else if (state == SURF_ACTION_FAILED)
+    p_stateSet = p_model->p_failedActionSet;
+  else if (state == SURF_ACTION_DONE)
+    p_stateSet = p_model->p_doneActionSet;
+  else
+    p_stateSet = NULL;
+
+  if (p_stateSet)
+    xbt_swag_insert(this, p_stateSet);
+  XBT_OUT();
+}
+
+double Action::getStartTime()
+{
+  return m_start;
+}
+
+double Action::getFinishTime()
+{
+  /* keep the function behavior, some models (cpu_ti) change the finish time before the action end */
+  return m_remains == 0 ? m_finish : -1;
+}
+
+double Action::getRemains()
+{
+  XBT_IN("(%p)", this);
+  XBT_OUT();
+  return m_remains;
+}
+
+void Action::setData(void* data)
+{
+  p_data = data;
+}
+
+#ifdef HAVE_TRACING
+void Action::setCategory(const char *category)
+{
+  XBT_IN("(%p,%s)", this, category);
+  p_category = xbt_strdup(category);
+  XBT_OUT();
+}
+#endif
+
+void Action::ref(){
+  m_refcount++;
+}
+
+void ActionLmm::setMaxDuration(double duration)
+{
+  XBT_IN("(%p,%g)", this, duration);
+  m_maxDuration = duration;
+  if (p_model->p_updateMechanism == UM_LAZY)      // remove action from the heap
+    heapRemove(p_model->p_actionHeap);
+  XBT_OUT();
+}
+
+void ActionLmm::gapRemove() {}
+
+void ActionLmm::setPriority(double priority)
+{
+  XBT_IN("(%p,%g)", this, priority);
+  m_priority = priority;
+  lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, priority);
+
+  if (p_model->p_updateMechanism == UM_LAZY)
+       heapRemove(p_model->p_actionHeap);
+  XBT_OUT();
+}
+
+void ActionLmm::cancel(){
+  setState(SURF_ACTION_FAILED);
+  if (p_model->p_updateMechanism == UM_LAZY) {
+    xbt_swag_remove(this, p_model->p_modifiedSet);
+    heapRemove(p_model->p_actionHeap);
+  }
+}
+
+int ActionLmm::unref(){
+  m_refcount--;
+  if (!m_refcount) {
+       xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+       if (p_variable)
+         lmm_variable_free(p_model->p_maxminSystem, p_variable);
+       if (p_model->p_updateMechanism == UM_LAZY) {
+         /* remove from heap */
+         heapRemove(p_model->p_actionHeap);
+         xbt_swag_remove(this, p_model->p_modifiedSet);
+    }
+#ifdef HAVE_TRACING
+    xbt_free(p_category);
+#endif
+       delete this;
+       return 1;
+  }
+  return 0;
+}
+
+void ActionLmm::suspend()
+{
+  XBT_IN("(%p)", this);
+  if (m_suspended != 2) {
+    lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, 0.0);
+    m_suspended = 1;
+    if (p_model->p_updateMechanism == UM_LAZY)
+      heapRemove(p_model->p_actionHeap);
+  }
+  XBT_OUT();
+}
+
+void ActionLmm::resume()
+{
+  XBT_IN("(%p)", this);
+  if (m_suspended != 2) {
+    lmm_update_variable_weight(p_model->p_maxminSystem, p_variable, m_priority);
+    m_suspended = 0;
+    if (p_model->p_updateMechanism == UM_LAZY)
+      heapRemove(p_model->p_actionHeap);
+  }
+  XBT_OUT();
+}
+
+bool ActionLmm::isSuspended()
+{
+  return m_suspended == 1;
+}
+/* insert action on heap using a given key and a hat (heap_action_type)
+ * a hat can be of three types for communications:
+ *
+ * NORMAL = this is a normal heap entry stating the date to finish transmitting
+ * LATENCY = this is a heap entry to warn us when the latency is payed
+ * MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
+ */
+void ActionLmm::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
+{
+  m_hat = hat;
+  xbt_heap_push(heap, this, key);
+}
+
+void ActionLmm::heapRemove(xbt_heap_t heap)
+{
+  m_hat = NOTSET;
+  if (m_indexHeap >= 0) {
+    xbt_heap_remove(heap, m_indexHeap);
+  }
+}
+
+/* added to manage the communication action's heap */
+void surf_action_lmm_update_index_heap(void *action, int i) {
+  ((ActionLmmPtr)action)->updateIndexHeap(i);
+}
+
+void ActionLmm::updateIndexHeap(int i) {
+  m_indexHeap = i;
+}
+
+double ActionLmm::getRemains()
+{
+  XBT_IN("(%p)", this);
+  /* update remains before return it */
+  if (p_model->p_updateMechanism == UM_LAZY)      /* update remains before return it */
+    updateRemainingLazy(surf_get_clock());
+  XBT_OUT();
+  return m_remains;
+}
+
+//FIXME split code in the right places
+void ActionLmm::updateRemainingLazy(double now)
+{
+  double delta = 0.0;
+
+  if(p_model == static_cast<ModelPtr>(surf_network_model))
+  {
+    if (m_suspended != 0)
+      return;
+  }
+  else
+  {
+    xbt_assert(p_stateSet == p_model->p_runningActionSet,
+        "You're updating an action that is not running.");
+
+      /* bogus priority, skip it */
+    xbt_assert(m_priority > 0,
+        "You're updating an action that seems suspended.");
+  }
+
+  delta = now - m_lastUpdate;
+
+  if (m_remains > 0) {
+    XBT_DEBUG("Updating action(%p): remains was %f, last_update was: %f", this, m_remains, m_lastUpdate);
+    double_update(&m_remains, m_lastValue * delta);
+
+#ifdef HAVE_TRACING
+    if (p_model == static_cast<ModelPtr>(surf_cpu_model) && TRACE_is_enabled()) {
+      ResourcePtr cpu = static_cast<ResourcePtr>(lmm_constraint_id(lmm_get_cnst_from_var(p_model->p_maxminSystem, p_variable, 0)));
+      TRACE_surf_host_set_utilization(cpu->m_name, p_category, m_lastValue, m_lastUpdate, now - m_lastUpdate);
+    }
+#endif
+    XBT_DEBUG("Updating action(%p): remains is now %f", this, m_remains);
+  }
+
+  if(p_model == static_cast<ModelPtr>(surf_network_model))
+  {
+    if (m_maxDuration != NO_MAX_DURATION)
+      double_update(&m_maxDuration, delta);
+
+    //FIXME: duplicated code
+    if ((m_remains <= 0) &&
+        (lmm_get_variable_weight(p_variable) > 0)) {
+      m_finish = surf_get_clock();
+      setState(SURF_ACTION_DONE);
+      heapRemove(p_model->p_actionHeap);
+    } else if (((m_maxDuration != NO_MAX_DURATION)
+        && (m_maxDuration <= 0))) {
+      m_finish = surf_get_clock();
+      setState(SURF_ACTION_DONE);
+      heapRemove(p_model->p_actionHeap);
+    }
+  }
+
+  m_lastUpdate = now;
+  m_lastValue = lmm_variable_getvalue(p_variable);
+}
+
+/*void Action::cancel()
+{
+  p_model->notifyActionCancel(this);
+}
+
+void Action::suspend()
+{
+  p_model->notifyActionSuspend(this);
+}
+
+void Action::resume()
+{
+  p_model->notifyActionResume(this);
+}
+
+bool Action::isSuspended()
+{
+  return false;
+}*/
+
diff --git a/src/surf/surf.hpp b/src/surf/surf.hpp
new file mode 100644 (file)
index 0000000..874acdd
--- /dev/null
@@ -0,0 +1,330 @@
+//using namespace generic;
+
+#ifndef SURF_MODEL_H_
+#define SURF_MODEL_H_
+
+#include <xbt.h>
+#include <string>
+#include <vector>
+#include <memory>
+#include <boost/smart_ptr.hpp>
+#include <boost/function.hpp>
+#include <boost/functional/factory.hpp>
+#include <boost/bind.hpp>
+#include "surf/trace_mgr.h"
+#include "xbt/lib.h"
+#include "surf/surf_routing.h"
+#include "simgrid/platf_interface.h"
+#include "surf/surf.h"
+#include "surf/surf_private.h"
+
+extern tmgr_history_t history;
+#define NO_MAX_DURATION -1.0
+
+using namespace std;
+
+/** \ingroup SURF_simulation
+ *  \brief Return the current time
+ *
+ *  Return the current time in millisecond.
+ */
+
+/*********
+ * Utils *
+ *********/
+
+/* user-visible parameters */
+extern double sg_tcp_gamma;
+extern double sg_sender_gap;
+extern double sg_latency_factor;
+extern double sg_bandwidth_factor;
+extern double sg_weight_S_parameter;
+extern int sg_network_crosstraffic;
+#ifdef HAVE_GTNETS
+extern double sg_gtnets_jitter;
+extern int sg_gtnets_jitter_seed;
+#endif
+extern xbt_dynar_t surf_path;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+XBT_PUBLIC(double) surf_get_clock(void);
+#ifdef __cplusplus
+}
+#endif
+
+extern double sg_sender_gap;
+XBT_PUBLIC(int)  SURF_CPU_LEVEL;    //Surf cpu level
+
+int __surf_is_absolute_file_path(const char *file_path);
+
+/***********
+ * Classes *
+ ***********/
+//class Model;
+typedef Model* ModelPtr;
+
+//class Resource;
+typedef Resource* ResourcePtr;
+typedef boost::function<void (ResourcePtr r)> ResourceCallback;
+                       
+//class Action;
+typedef Action* ActionPtr;
+typedef boost::function<void (ActionPtr a)> ActionCallback;
+
+//class ActionLmm;
+typedef ActionLmm* ActionLmmPtr;
+
+enum heap_action_type{
+  LATENCY = 100,
+  MAX_DURATION,
+  NORMAL,
+  NOTSET
+};
+
+/*********
+ * Trace *
+ *********/
+/* For the trace and trace:connect tag (store their content till the end of the parsing) */
+XBT_PUBLIC_DATA(xbt_dict_t) traces_set_list;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_host_avail;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_power;
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_link_avail; 
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_bandwidth; 
+XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_latency;
+
+
+/*********
+ * Model *
+ *********/
+XBT_PUBLIC_DATA(xbt_dynar_t) model_list;
+
+class Model {
+public:
+  Model(string name);
+  virtual ~Model();
+
+  ResourcePtr createResource(string name);
+  ActionPtr createAction(double _cost, bool _failed);
+  virtual double shareResources(double now);
+  virtual double shareResourcesLazy(double now);
+  virtual double shareResourcesFull(double now);
+  double shareResourcesMaxMin(xbt_swag_t running_actions,
+                                      lmm_system_t sys,
+                                      void (*solve) (lmm_system_t));
+  virtual void updateActionsState(double now, double delta);
+  virtual void updateActionsStateLazy(double now, double delta);
+  virtual void updateActionsStateFull(double now, double delta);
+
+  string getName() {return m_name;};
+
+  void addTurnedOnCallback(ResourceCallback rc);
+  void notifyResourceTurnedOn(ResourcePtr r);
+
+  void addTurnedOffCallback(ResourceCallback rc);  
+  void notifyResourceTurnedOff(ResourcePtr r);
+
+  void addActionCancelCallback(ActionCallback ac);
+  void notifyActionCancel(ActionPtr a);
+  void addActionResumeCallback(ActionCallback ac);
+  void notifyActionResume(ActionPtr a);
+  void addActionSuspendCallback(ActionCallback ac);  
+  void notifyActionSuspend(ActionPtr a);
+
+  lmm_system_t p_maxminSystem;
+  e_UM_t p_updateMechanism;
+  xbt_swag_t p_modifiedSet;
+  xbt_heap_t p_actionHeap;
+  int m_selectiveUpdate;
+
+  xbt_swag_t p_readyActionSet; /**< Actions in state SURF_ACTION_READY */
+  xbt_swag_t p_runningActionSet; /**< Actions in state SURF_ACTION_RUNNING */
+  xbt_swag_t p_failedActionSet; /**< Actions in state SURF_ACTION_FAILED */
+  xbt_swag_t p_doneActionSet; /**< Actions in state SURF_ACTION_DONE */
+  string m_name;
+
+protected:
+  std::vector<ActionPtr> m_failedActions, m_runningActions;
+
+private:
+  ResourceCallback m_resOnCB, m_resOffCB;
+  ActionCallback m_actCancelCB, m_actSuspendCB, m_actResumeCB;
+};
+
+/************
+ * Resource *
+ ************/
+
+/**
+ * Resource which have a metric handled by a maxmin system
+ */
+typedef struct {
+  double scale;
+  double peak;
+  tmgr_trace_event_t event;
+} s_surf_metric_t;
+
+class Resource {
+public:
+  Resource();
+  Resource(ModelPtr model, const char *name, xbt_dict_t properties);
+  virtual ~Resource() {};
+
+  virtual void updateState(tmgr_trace_event_t event_type, double value, double date)=0;
+
+  //private
+  virtual bool isUsed()=0;
+  //FIXME:updateActionState();
+  //FIXME:updateResourceState();
+  //FIXME:finilize();
+
+  bool isOn();
+  void turnOn();
+  void turnOff();
+  void setName(string name);
+  const char *getName();
+  virtual xbt_dict_t getProperties();
+
+  ModelPtr getModel() {return p_model;};
+  virtual e_surf_resource_state_t getState();
+  void printModel() { std::cout << p_model->getName() << "<<plop"<<std::endl;};
+  void *p_resource;
+  const char *m_name;
+  xbt_dict_t m_properties;
+  ModelPtr p_model;
+  e_surf_resource_state_t p_stateCurrent;
+
+protected:
+
+private:
+  bool m_running;  
+};
+
+class ResourceLmm: virtual public Resource {
+public:
+  ResourceLmm() {};
+  ResourceLmm(surf_model_t model, const char *name, xbt_dict_t props,
+                           lmm_system_t system,
+                           double constraint_value,
+                           tmgr_history_t history,
+                           e_surf_resource_state_t state_init,
+                           tmgr_trace_t state_trace,
+                           double metric_peak,
+                           tmgr_trace_t metric_trace);
+  lmm_constraint_t p_constraint;
+  tmgr_trace_event_t p_stateEvent;
+  s_surf_metric_t p_power;
+};
+
+/**********
+ * Action *
+ **********/
+
+class Action {
+public:
+  Action();
+  Action(ModelPtr model, double cost, bool failed);
+  virtual ~Action();
+  
+  s_xbt_swag_hookup_t p_stateHookup;
+
+  e_surf_action_state_t getState(); /**< get the state*/
+  virtual void setState(e_surf_action_state_t state); /**< Change state*/
+  double getStartTime(); /**< Return the start time of an action */
+  double getFinishTime(); /**< Return the finish time of an action */
+  void setData(void* data);
+
+  void ref();
+  virtual int unref();     /**< Specify that we don't use that action anymore. Returns true if the action was destroyed and false if someone still has references on it. */
+  virtual void cancel();     /**< Cancel a running action */
+  virtual void recycle();     /**< Recycle an action */
+  
+  virtual void suspend()=0;     /**< Suspend an action */
+  virtual void resume()=0;     /**< Resume a suspended action */
+  virtual bool isSuspended()=0;     /**< Return whether an action is suspended */
+  virtual void setMaxDuration(double duration)=0;     /**< Set the max duration of an action*/
+  virtual void setPriority(double priority)=0;     /**< Set the priority of an action */
+#ifdef HAVE_TRACING
+  void setCategory(const char *category); /**< Set the category of an action */
+#endif
+  virtual double getRemains();     /**< Get the remains of an action */
+#ifdef HAVE_LATENCY_BOUND_TRACKING
+  int getLatencyLimited();     /**< Return 1 if action is limited by latency, 0 otherwise */
+#endif
+
+  xbt_swag_t p_stateSet;
+
+  double m_priority; /**< priority (1.0 by default) */
+  bool m_failed;
+  double m_start; /**< start time  */
+  double m_finish; /**< finish time : this is modified during the run and fluctuates until the task is completed */
+  double m_remains; /**< How much of that cost remains to be done in the currently running task */
+  #ifdef HAVE_LATENCY_BOUND_TRACKING
+  int m_latencyLimited;               /**< Set to 1 if is limited by latency, 0 otherwise */
+  #endif
+  double m_maxDuration; /*< max_duration (may fluctuate until the task is completed) */  
+  char *p_category;               /**< tracing category for categorized resource utilization monitoring */  
+  int    m_cost;
+  void *p_data; /**< for your convenience */
+protected:
+  ModelPtr p_model;  
+  int    m_refcount;
+#ifdef HAVE_TRACING
+#endif
+  e_UM_t p_updateMechanism;
+
+private:
+  int resourceUsed(void *resource_id);
+  /* Share the resources to the actions and return in how much time
+     the next action may terminate */
+  double shareResources(double now);
+  /* Update the actions' state */
+  void updateActionsState(double now, double delta);
+  void updateResourceState(void *id, tmgr_trace_event_t event_type,
+                                 double value, double time);
+
+  xbt_swag_t p_modifiedSet;
+  xbt_heap_t p_actionHeap;
+  int m_selectiveUpdate;
+};
+
+//FIXME:REMOVE
+void surf_action_lmm_update_index_heap(void *action, int i);
+
+class ActionLmm: virtual public Action {
+public:
+  ActionLmm() : m_suspended(false) {
+       p_actionListHookup.prev = 0;
+       p_actionListHookup.next = 0;
+  };
+  ActionLmm(ModelPtr model, double cost, bool failed) : m_suspended(false) {
+       p_actionListHookup.prev = 0;
+       p_actionListHookup.next = 0;
+  };
+
+  virtual void updateRemainingLazy(double now);
+  void heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat);
+  void heapRemove(xbt_heap_t heap);
+  double getRemains();     /**< Get the remains of an action */
+  void updateIndexHeap(int i);
+
+  virtual int unref();
+  void cancel();
+  void suspend();
+  void resume();
+  bool isSuspended();
+  void setMaxDuration(double duration);
+  void setPriority(double priority);
+  void gapRemove();
+
+  lmm_variable_t p_variable;
+  s_xbt_swag_hookup_t p_actionListHookup;
+  int m_indexHeap;
+  double m_lastUpdate;
+  double m_lastValue;
+  enum heap_action_type m_hat;
+  int m_suspended;
+};
+
+#endif /* SURF_MODEL_H_ */
diff --git a/src/surf/surf_c.h b/src/surf/surf_c.h
new file mode 100644 (file)
index 0000000..6731d82
--- /dev/null
@@ -0,0 +1,85 @@
+#include <xbt.h>
+
+#ifndef SURF_SOLVER_H_
+#define SURF_SOLVER_H_
+
+static double MAXMIN_PRECISION = 0.001;
+
+
+#ifdef __cplusplus
+#include <vector>
+#include <boost/smart_ptr.hpp>
+#include <boost/pool/object_pool.hpp>
+#include <boost/bind.hpp>
+
+static void double_update(double *variable, double value)
+{
+  *variable -= value;
+  if (*variable < MAXMIN_PRECISION)
+    *variable = 0.0;
+}
+
+using namespace std;
+
+class Solver;
+typedef boost::shared_ptr<Solver> SolverPtr;
+
+class Element;
+typedef boost::shared_ptr<Element> ElementPtr;
+
+class Constraint;
+typedef boost::shared_ptr<Constraint> ConstraintPtr;
+
+class ConstraintLight;
+typedef boost::shared_ptr<ConstraintLight> ConstraintLightPtr;
+
+class Variable;
+typedef boost::shared_ptr<Variable> VariablePtr;
+
+struct ElementPtrOps
+{
+  bool operator()( const ElementPtr & a, const ElementPtr & b )
+    { return true; } //a > b; }
+};
+
+#else
+  typedef struct Solver Solver;
+  typedef struct Element Element;
+  typedef struct Constraint Constraint;
+  typedef struct ConstraintLight ConstraintLight;
+  typedef struct Variable Variable;
+
+#endif
+
+typedef Element *lmm_element_t;
+typedef Variable *lmm_variable_t;
+typedef Constraint *lmm_constraint_t;
+typedef ConstraintLight *lmm_constraint_light_t;
+typedef Solver *lmm_system_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__STDC__) || defined(__cplusplus)
+  extern lmm_system_t lmm_system_new(int selective_update);
+
+  extern void c_function(Solver*);   /* ANSI C prototypes */
+  extern Solver* cplusplus_callback_function(Solver*);
+
+#else
+  extern lmm_system_t lmm_system_new(int selective_update);
+
+  extern void c_function();        /* K&R style */
+  extern Solver* cplusplus_callback_function();
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+#endif /* SURF_SOLVER_H_ */
diff --git a/src/surf/surf_interface.cpp b/src/surf/surf_interface.cpp
new file mode 100644 (file)
index 0000000..8718872
--- /dev/null
@@ -0,0 +1,436 @@
+#include "surf.hpp"
+#include "workstation.hpp"
+#include "network.hpp"
+#include "surf_routing_cluster.hpp"
+#include "instr/instr_private.h"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_kernel);
+
+/*********
+ * TOOLS *
+ *********/
+extern double NOW;
+
+static CpuPtr get_casted_cpu(surf_resource_t resource){
+  return dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(surf_cpu_resource_priv(resource)));
+}
+
+static WorkstationCLM03Ptr get_casted_workstation(surf_resource_t resource){
+  return dynamic_cast<WorkstationCLM03Ptr>(static_cast<ResourcePtr>(surf_workstation_resource_priv(resource)));
+}
+
+char *surf_routing_edge_name(sg_routing_edge_t edge){
+  return edge->p_name;
+}
+
+#ifdef CONTEXT_THREADS
+static xbt_parmap_t surf_parmap = NULL; /* parallel map on models */
+#endif
+
+static double *surf_mins = NULL; /* return value of share_resources for each model */
+static int surf_min_index;       /* current index in surf_mins */
+static double surf_min;               /* duration determined by surf_solve */
+
+void surf_presolve(void)
+{
+  double next_event_date = -1.0;
+  tmgr_trace_event_t event = NULL;
+  double value = -1.0;
+  ResourcePtr resource = NULL;
+  ModelPtr model = NULL;
+  unsigned int iter;
+
+  XBT_DEBUG
+      ("First Run! Let's \"purge\" events and put models in the right state");
+  while ((next_event_date = tmgr_history_next_date(history)) != -1.0) {
+    if (next_event_date > NOW)
+      break;
+    while ((event =
+            tmgr_history_get_next_event_leq(history, next_event_date,
+                                            &value,
+                                            (void **) &resource))) {
+      if (value >= 0){
+        resource->updateState(event, value, NOW);
+      }
+    }
+  }
+  xbt_dynar_foreach(model_list, iter, model)
+      model->updateActionsState(NOW, 0.0);
+}
+
+static void surf_share_resources(surf_model_t model)
+{
+  double next_action_end = -1.0;
+  int i = __sync_fetch_and_add(&surf_min_index, 1);
+  if (strcmp(model->m_name.c_str(), "network NS3")) {
+    XBT_DEBUG("Running for Resource [%s]", model->m_name.c_str());
+    next_action_end = model->shareResources(NOW);
+    XBT_DEBUG("Resource [%s] : next action end = %f",
+        model->m_name.c_str(), next_action_end);
+  }
+  surf_mins[i] = next_action_end;
+}
+
+static void surf_update_actions_state(surf_model_t model)
+{
+  model->updateActionsState(NOW, surf_min);
+}
+
+double surf_solve(double max_date)
+{
+  surf_min = -1.0; /* duration */
+  double next_event_date = -1.0;
+  double model_next_action_end = -1.0;
+  double value = -1.0;
+  ResourcePtr resource = NULL;
+  ModelPtr model = NULL;
+  tmgr_trace_event_t event = NULL;
+  unsigned int iter;
+
+  if(!host_that_restart)
+    host_that_restart = xbt_dynar_new(sizeof(char*), NULL);
+
+  if (max_date != -1.0 && max_date != NOW) {
+    surf_min = max_date - NOW;
+  }
+
+  XBT_DEBUG("Looking for next action end for all models except NS3");
+
+  if (surf_mins == NULL) {
+    surf_mins = xbt_new(double, xbt_dynar_length(model_list));
+  }
+  surf_min_index = 0;
+
+  /* sequential version */
+  xbt_dynar_foreach(model_list, iter, model) {
+    surf_share_resources(static_cast<ModelPtr>(model));
+  }
+
+  unsigned i;
+  for (i = 0; i < xbt_dynar_length(model_list); i++) {
+    if ((surf_min < 0.0 || surf_mins[i] < surf_min)
+        && surf_mins[i] >= 0.0) {
+      surf_min = surf_mins[i];
+    }
+  }
+
+  XBT_DEBUG("Min for resources (remember that NS3 don't update that value) : %f", surf_min);
+
+  XBT_DEBUG("Looking for next trace event");
+
+  do {
+    XBT_DEBUG("Next TRACE event : %f", next_event_date);
+
+    next_event_date = tmgr_history_next_date(history);
+
+    if(!strcmp(surf_network_model->m_name.c_str(), "network NS3")){//FIXME: add surf_network_model->m_name &&
+      if(next_event_date!=-1.0 && surf_min!=-1.0) {
+        surf_min = MIN(next_event_date - NOW, surf_min);
+      } else{
+        surf_min = MAX(next_event_date - NOW, surf_min);
+      }
+
+      XBT_DEBUG("Run for network at most %f", surf_min);
+      // run until min or next flow
+      model_next_action_end = surf_network_model->shareResources(surf_min);
+
+      XBT_DEBUG("Min for network : %f", model_next_action_end);
+      if(model_next_action_end>=0.0)
+        surf_min = model_next_action_end;
+    }
+
+    if (next_event_date < 0.0) {
+      XBT_DEBUG("no next TRACE event. Stop searching for it");
+      break;
+    }
+
+    if ((surf_min == -1.0) || (next_event_date > NOW + surf_min)) break;
+
+    XBT_DEBUG("Updating models (min = %g, NOW = %g, next_event_date = %g)", surf_min, NOW, next_event_date);
+    while ((event =
+            tmgr_history_get_next_event_leq(history, next_event_date,
+                                            &value,
+                                            (void **) &resource))) {
+      if (resource->isUsed() || xbt_dict_get_or_null(watched_hosts_lib, resource->m_name)) {
+        surf_min = next_event_date - NOW;
+        XBT_DEBUG
+            ("This event will modify model state. Next event set to %f",
+             surf_min);
+      }
+      /* update state of model_obj according to new value. Does not touch lmm.
+         It will be modified if needed when updating actions */
+      XBT_DEBUG("Calling update_resource_state for resource %s with min %lf",
+             resource->m_name, surf_min);
+      resource->updateState(event, value, next_event_date);
+    }
+  } while (1);
+
+  /* FIXME: Moved this test to here to avoid stopping simulation if there are actions running on cpus and all cpus are with availability = 0.
+   * This may cause an infinite loop if one cpu has a trace with periodicity = 0 and the other a trace with periodicity > 0.
+   * The options are: all traces with same periodicity(0 or >0) or we need to change the way how the events are managed */
+  if (surf_min == -1.0) {
+  XBT_DEBUG("No next event at all. Bail out now.");
+    return -1.0;
+  }
+
+  XBT_DEBUG("Duration set to %f", surf_min);
+
+  NOW = NOW + surf_min;
+
+  /* sequential version */
+  xbt_dynar_foreach(model_list, iter, model) {
+    surf_update_actions_state(model);
+  }
+
+#ifdef HAVE_TRACING
+  TRACE_paje_dump_buffer (0);
+#endif
+
+  return surf_min;
+}
+
+XBT_INLINE double surf_get_clock(void)
+{
+  return NOW;
+}
+
+void routing_get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
+                              xbt_dynar_t * route, double *latency){
+  routing_platf->getRouteAndLatency(src, dst, route, latency);
+}
+
+/*********
+ * MODEL *
+ *********/
+
+void *surf_as_cluster_get_backbone(AS_t as){
+  return static_cast<AsClusterPtr>(as)->p_backbone;
+}
+
+void surf_as_cluster_set_backbone(AS_t as, void* backbone){
+  static_cast<AsClusterPtr>(as)->p_backbone = dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(backbone));
+}
+
+const char *surf_model_name(surf_model_t model){
+  return model->m_name.c_str();
+}
+
+xbt_swag_t surf_model_done_action_set(surf_model_t model){
+  return model->p_doneActionSet;
+}
+
+xbt_swag_t surf_model_failed_action_set(surf_model_t model){
+  return model->p_failedActionSet;
+}
+
+xbt_swag_t surf_model_ready_action_set(surf_model_t model){
+  return model->p_readyActionSet;
+}
+
+xbt_swag_t surf_model_running_action_set(surf_model_t model){
+  return model->p_runningActionSet;
+}
+
+surf_action_t surf_workstation_model_execute_parallel_task(surf_workstation_model_t model,
+                                                   int workstation_nb,
+                                            void **workstation_list,
+                                            double *computation_amount,
+                                            double *communication_amount,
+                                            double rate){
+  return static_cast<ActionPtr>(model->executeParallelTask(workstation_nb, workstation_list, computation_amount, communication_amount, rate));
+}
+
+surf_action_t surf_workstation_model_communicate(surf_workstation_model_t model, surf_resource_t src, surf_resource_t dst, double size, double rate){
+  return model->communicate(get_casted_workstation(src), get_casted_workstation(dst), size, rate);
+}
+
+xbt_dynar_t surf_workstation_model_get_route(surf_workstation_model_t model,
+                                                    surf_resource_t src, surf_resource_t dst){
+  return model->getRoute(get_casted_workstation(src), get_casted_workstation(dst));
+}
+
+surf_action_t surf_network_model_communicate(surf_network_model_t model, sg_routing_edge_t src, sg_routing_edge_t dst, double size, double rate){
+  return model->communicate(src, dst, size, rate);
+}
+
+const char *surf_resource_name(surf_cpp_resource_t resource){
+  return resource->m_name;
+}
+
+xbt_dict_t surf_resource_get_properties(surf_cpp_resource_t resource){
+  return resource->getProperties();
+}
+
+e_surf_resource_state_t surf_resource_get_state(surf_cpp_resource_t resource){
+  return resource->getState();
+}
+
+surf_action_t surf_workstation_sleep(surf_resource_t resource, double duration){
+  return get_casted_workstation(resource)->sleep(duration);
+}
+
+double surf_workstation_get_speed(surf_resource_t resource, double load){
+  return get_casted_workstation(resource)->getSpeed(load);
+}
+
+double surf_workstation_get_available_speed(surf_resource_t resource){
+  return get_casted_workstation(resource)->getAvailableSpeed();
+}
+
+int surf_workstation_get_core(surf_resource_t resource){
+  return get_casted_workstation(resource)->getCore();
+}
+
+surf_action_t surf_workstation_execute(surf_resource_t resource, double size){
+  return get_casted_workstation(resource)->execute(size);
+}
+
+double surf_workstation_get_current_power_peak(surf_resource_t resource){
+  return get_casted_workstation(resource)->getCurrentPowerPeak();
+}
+
+double surf_workstation_get_power_peak_at(surf_resource_t resource, int pstate_index){
+  return get_casted_workstation(resource)->getPowerPeakAt(pstate_index);
+}
+
+int surf_workstation_get_nb_pstates(surf_resource_t resource){
+  return get_casted_workstation(resource)->getNbPstates();
+}
+
+void surf_workstation_set_power_peak_at(surf_resource_t resource, int pstate_index){
+  return get_casted_workstation(resource)->setPowerPeakAt(pstate_index);
+}
+
+double surf_workstation_get_consumed_energy(surf_resource_t resource){
+  return get_casted_workstation(resource)->getConsumedEnergy();
+}
+
+xbt_dict_t surf_workstation_get_storage_list(surf_resource_t workstation){
+  return get_casted_workstation(workstation)->getStorageList();
+}
+surf_action_t surf_workstation_open(surf_resource_t workstation, const char* mount, const char* path){
+  return get_casted_workstation(workstation)->open(mount, path);
+}
+
+surf_action_t surf_workstation_close(surf_resource_t workstation, surf_file_t fd){
+  return get_casted_workstation(workstation)->close(fd);
+}
+
+int surf_workstation_unlink(surf_resource_t workstation, surf_file_t fd){
+  return get_casted_workstation(workstation)->unlink(fd);
+}
+
+surf_action_t surf_workstation_ls(surf_resource_t workstation, const char* mount, const char *path){
+  return get_casted_workstation(workstation)->ls(mount, path);
+}
+
+size_t surf_workstation_get_size(surf_resource_t workstation, surf_file_t fd){
+  return get_casted_workstation(workstation)->getSize(fd);
+}
+
+surf_action_t surf_workstation_read(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size){
+  return get_casted_workstation(resource)->read(fd, size);
+}
+
+surf_action_t surf_workstation_write(surf_resource_t resource, surf_file_t fd, sg_storage_size_t size){
+  return get_casted_workstation(resource)->write(fd, size);
+}
+
+xbt_dynar_t surf_workstation_get_info(surf_resource_t resource, surf_file_t fd){
+  return get_casted_workstation(resource)->getInfo(fd);
+}
+
+sg_storage_size_t surf_workstation_get_free_size(surf_resource_t resource, const char* name){
+  return get_casted_workstation(resource)->getFreeSize(name);
+}
+sg_storage_size_t surf_workstation_get_used_size(surf_resource_t resource, const char* name){
+  return get_casted_workstation(resource)->getUsedSize(name);
+}
+
+int surf_network_link_is_shared(surf_cpp_resource_t link){
+  return dynamic_cast<NetworkCm02LinkPtr>(link)->isShared();
+}
+
+double surf_network_link_get_bandwidth(surf_cpp_resource_t link){
+  return dynamic_cast<NetworkCm02LinkPtr>(link)->getBandwidth();
+}
+
+double surf_network_link_get_latency(surf_cpp_resource_t link){
+  return dynamic_cast<NetworkCm02LinkPtr>(link)->getLatency();
+}
+
+xbt_dict_t surf_storage_get_content(surf_resource_t resource){
+  return dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(surf_storage_resource_priv(resource)))->getContent();
+}
+
+sg_storage_size_t surf_storage_get_size(surf_resource_t resource){
+  return dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(surf_storage_resource_priv(resource)))->getSize();
+}
+
+surf_action_t surf_cpu_execute(surf_resource_t cpu, double size){
+  return get_casted_cpu(cpu)->execute(size);
+}
+
+surf_action_t surf_cpu_sleep(surf_resource_t cpu, double duration){
+  return get_casted_cpu(cpu)->sleep(duration);
+}
+
+double surf_action_get_start_time(surf_action_t action){
+  return action->m_start;
+}
+
+double surf_action_get_finish_time(surf_action_t action){
+  return action->m_finish;
+}
+
+double surf_action_get_remains(surf_action_t action){
+  return action->getRemains();
+}
+
+void surf_action_unref(surf_action_t action){
+  action->unref();
+}
+
+void surf_action_suspend(surf_action_t action){
+  action->suspend();
+}
+
+void surf_action_resume(surf_action_t action){
+  action->resume();
+}
+
+void surf_action_cancel(surf_action_t action){
+  action->cancel();
+}
+
+void surf_action_set_priority(surf_action_t action, double priority){
+  action->setPriority(priority);
+}
+
+void surf_action_set_category(surf_action_t action, const char *category){
+  action->setCategory(category);
+}
+
+void *surf_action_get_data(surf_action_t action){
+  return action->p_data;
+}
+
+void surf_action_set_data(surf_action_t action, void *data){
+  action->p_data = data;
+}
+
+e_surf_action_state_t surf_action_get_state(surf_action_t action){
+  return action->getState();
+}
+
+int surf_action_get_cost(surf_action_t action){
+  return action->m_cost;
+}
+
+surf_file_t surf_storage_action_get_file(surf_action_t action){
+  return dynamic_cast<StorageActionPtr>(action)->p_file;
+}
+
+xbt_dict_t surf_storage_action_get_ls_dict(surf_action_t action){
+  return dynamic_cast<StorageActionPtr>(action)->p_lsDict;
+}
index 10066b0..9f60ac9 100644 (file)
 
 #define NO_MAX_DURATION -1.0
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 extern xbt_dict_t watched_hosts_lib;
 
 extern const char *surf_action_state_names[6];
@@ -46,30 +50,30 @@ typedef struct surf_model_private {
 
 } s_surf_model_private_t;
 
-double generic_maxmin_share_resources(xbt_swag_t running_actions,
+/*FIXME:REMOVEdouble generic_maxmin_share_resources(xbt_swag_t running_actions,
                                       size_t offset,
                                       lmm_system_t sys,
-                                      void (*solve) (lmm_system_t));
+                                      void (*solve) (lmm_system_t));*/
 double generic_share_resources_lazy(double now, surf_model_t model);
 
 /* Generic functions common to all models */
 void surf_action_init(void);
 void surf_action_exit(void);
 e_surf_action_state_t surf_action_state_get(surf_action_t action);      /* cannot declare inline since we use a pointer to it */
-double surf_action_get_start_time(surf_action_t action);        /* cannot declare inline since we use a pointer to it */
+//FIXME:DELETEdouble surf_action_get_start_time(surf_action_t action);        /* cannot declare inline since we use a pointer to it */
 double surf_action_get_finish_time(surf_action_t action);       /* cannot declare inline since we use a pointer to it */
 void surf_action_free(surf_action_t * action);
-void surf_action_state_set(surf_action_t action,
-                           e_surf_action_state_t state);
-void surf_action_data_set(surf_action_t action, void *data);    /* cannot declare inline since we use a pointer to it */
+/*FIXME:void surf_action_state_set(surf_action_t action,
+                           e_surf_action_state_t state);*/
+//FIXME:void surf_action_data_set(surf_action_t action, void *data);    /* cannot declare inline since we use a pointer to it */
 
 void surf_action_lmm_update_index_heap(void *action, int i); /* callback for heap management shared by cpu and net models */
-void surf_action_lmm_heap_insert(xbt_heap_t heap, surf_action_lmm_t action,
-    double key, enum heap_action_type hat);
+/*FIXME:void surf_action_lmm_heap_insert(xbt_heap_t heap, surf_action_lmm_t action,
+    double key, enum heap_action_type hat);*/
 void surf_action_lmm_heap_remove(xbt_heap_t heap,surf_action_lmm_t action);
 
 void surf_action_cancel(surf_action_t action);
-int surf_action_unref(surf_action_t action);
+//FIXME:removeint surf_action_unref(surf_action_t action);
 void surf_action_suspend(surf_action_t action);
 void surf_action_resume(surf_action_t action);
 int surf_action_is_suspended(surf_action_t action);
@@ -196,8 +200,8 @@ XBT_PUBLIC(void) generic_get_graph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict
 /**
  * Resource protected methods
  */
-XBT_PUBLIC(void) surfxml_bufferstack_push(int new);
-XBT_PUBLIC(void) surfxml_bufferstack_pop(int new);
+XBT_PUBLIC(void) surfxml_bufferstack_push(int _new);
+XBT_PUBLIC(void) surfxml_bufferstack_pop(int _new);
 
 XBT_PUBLIC_DATA(int) surfxml_bufferstack_size;
 
@@ -206,5 +210,8 @@ XBT_PUBLIC_DATA(int) surfxml_bufferstack_size;
 void TRACE_surf_host_set_power(double date, const char *resource, double power);
 void TRACE_surf_link_set_bandwidth(double date, const char *resource, double bandwidth);
 
+#ifdef __cplusplus
+}
+#endif
 
 #endif                          /* _SURF_SURF_PRIVATE_H */
diff --git a/src/surf/surf_private.hpp b/src/surf/surf_private.hpp
new file mode 100644 (file)
index 0000000..1b540c6
--- /dev/null
@@ -0,0 +1,14 @@
+
+#ifndef SURF_PRIVATE_HPP_
+#define SURF_PRIVATE_HPP_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+FILE *surf_fopen(const char *name, const char *mode);
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* SURF_PRIVATE_HPP_ */
similarity index 82%
rename from src/surf/surf_routing.c
rename to src/surf/surf_routing.cpp
index ec7334f..d667710 100644 (file)
@@ -1,14 +1,15 @@
-/* Copyright (c) 2009-2013. The SimGrid Team.
+/* Copyright (c) 2009, 2010, 2011. 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 "surf_routing.hpp"
+#include "surf_routing_private.hpp"
+
 #include "simgrid/platf_interface.h"    // platform creation API internal interface
 #include "simgrid/sg_config.h"
 
-#include "surf_routing_private.h"
-#include "surf/surf_routing.h"
 #include "surf/surfxml_parse_values.h"
 
 /**
@@ -46,24 +47,28 @@ int ROUTING_PROP_ASR_LEVEL;     //Where the properties are stored
 
 static xbt_dict_t random_value = NULL;
 
+
 /** @brief Retrieve a routing edge from its name
  *
  * Routing edges are either CPU/workstation and routers, whatever
  */
-sg_routing_edge_t sg_routing_edge_by_name_or_null(const char *name) {
-    sg_routing_edge_t net_elm = xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
-    if(!net_elm) net_elm = xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL);
+RoutingEdgePtr sg_routing_edge_by_name_or_null(const char *name) {
+  RoutingEdgePtr net_elm = (RoutingEdgePtr) xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL);
+  if (!net_elm)
+       net_elm = (RoutingEdgePtr) xbt_lib_get_or_null(as_router_lib, name, ROUTING_ASR_LEVEL);
   return net_elm;
 }
 
 /* Global vars */
-routing_platf_t routing_platf = NULL;
-AS_t current_routing = NULL;
+RoutingPlatfPtr routing_platf = NULL;
+AsPtr current_routing = NULL;
 
 /* global parse functions */
 extern xbt_dynar_t mount_list;
 
+extern "C" {
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route, surf, "Routing part of surf");
+}
 
 static void routing_parse_peer(sg_platf_peer_cbarg_t peer);     /* peer bypass */
 static void routing_parse_Srandom(void);        /* random bypass */
@@ -108,11 +113,10 @@ struct s_model_type routing_models[] = {
  */
 static void parse_S_host_link(sg_platf_host_link_cbarg_t host)
 {
-  sg_routing_edge_t info = NULL;
-  info = xbt_lib_get_or_null(host_lib, host->id, ROUTING_HOST_LEVEL);
-  xbt_assert(info, "Host '%s' not found!",host->id);
-  xbt_assert(current_routing->model_desc == &routing_models[SURF_MODEL_CLUSTER] ||
-      current_routing->model_desc == &routing_models[SURF_MODEL_VIVALDI],
+  RoutingEdgePtr info = static_cast<RoutingEdgePtr>(xbt_lib_get_or_null(host_lib, host->id, ROUTING_HOST_LEVEL));
+  xbt_assert(info, "Host '%s' not found!", host->id);
+  xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER] ||
+      current_routing->p_modelDesc == &routing_models[SURF_MODEL_VIVALDI],
       "You have to be in model Cluster to use tag host_link!");
 
   s_surf_parsing_link_up_down_t link_up_down;
@@ -124,16 +128,16 @@ static void parse_S_host_link(sg_platf_host_link_cbarg_t host)
   xbt_assert(link_up_down.link_up, "Link '%s' not found!",host->link_up);
   xbt_assert(link_up_down.link_down, "Link '%s' not found!",host->link_down);
 
-  if(!current_routing->link_up_down_list)
-    current_routing->link_up_down_list = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
+  if(!current_routing->p_linkUpDownList)
+    current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
 
   // If dynar is is greater than edge id and if the host_link is already defined
-  if(xbt_dynar_length(current_routing->link_up_down_list) > info->id &&
-      xbt_dynar_get_as(current_routing->link_up_down_list,info->id,void*))
+  if(xbt_dynar_length(current_routing->p_linkUpDownList) > info->m_id &&
+      xbt_dynar_get_as(current_routing->p_linkUpDownList, info->m_id, void*))
     xbt_die("Host_link for '%s' is already defined!",host->id);
 
-  XBT_DEBUG("Push Host_link for host '%s' to position %d",info->name,info->id);
-  xbt_dynar_set_as(current_routing->link_up_down_list,info->id,s_surf_parsing_link_up_down_t,link_up_down);
+  XBT_DEBUG("Push Host_link for host '%s' to position %d", info->p_name, info->m_id);
+  xbt_dynar_set_as(current_routing->p_linkUpDownList, info->m_id, s_surf_parsing_link_up_down_t, link_up_down);
 }
 
 /**
@@ -141,19 +145,18 @@ static void parse_S_host_link(sg_platf_host_link_cbarg_t host)
  */
 static void parse_S_host(sg_platf_host_cbarg_t host)
 {
-  sg_routing_edge_t info = NULL;
-  if (current_routing->hierarchy == SURF_ROUTING_NULL)
-    current_routing->hierarchy = SURF_ROUTING_BASE;
+  if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
+    current_routing->p_hierarchy = SURF_ROUTING_BASE;
   xbt_assert(!xbt_lib_get_or_null(host_lib, host->id, ROUTING_HOST_LEVEL),
              "Reading a host, processing unit \"%s\" already exists", host->id);
 
-  info = xbt_new0(s_routing_edge_t, 1);
-  info->rc_component = current_routing;
-  info->rc_type = SURF_NETWORK_ELEMENT_HOST;
-  info->name = xbt_strdup(host->id);
-  info->id = current_routing->parse_PU(current_routing, (void *) info);
+  RoutingEdgePtr info = new RoutingEdge();
+  info->p_rcComponent = current_routing;
+  info->p_rcType = SURF_NETWORK_ELEMENT_HOST;
+  info->p_name = xbt_strdup(host->id);
+  info->m_id = current_routing->parsePU(info);
   xbt_lib_set(host_lib, host->id, ROUTING_HOST_LEVEL, (void *) info);
-  XBT_DEBUG("Having set name '%s' id '%d'",host->id,info->id);
+  XBT_DEBUG("Having set name '%s' id '%d'", host->id, info->m_id);
 
   if(mount_list){
     xbt_lib_set(storage_lib, host->id, ROUTING_STORAGE_HOST_LEVEL, (void *) mount_list);
@@ -185,20 +188,19 @@ static void parse_S_host(sg_platf_host_cbarg_t host)
  */
 static void parse_S_router(sg_platf_router_cbarg_t router)
 {
-  sg_routing_edge_t info = NULL;
-  if (current_routing->hierarchy == SURF_ROUTING_NULL)
-    current_routing->hierarchy = SURF_ROUTING_BASE;
+  if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
+    current_routing->p_hierarchy = SURF_ROUTING_BASE;
   xbt_assert(!xbt_lib_get_or_null(as_router_lib, router->id, ROUTING_ASR_LEVEL),
              "Reading a router, processing unit \"%s\" already exists",
              router->id);
 
-  info = xbt_new0(s_routing_edge_t, 1);
-  info->rc_component = current_routing;
-  info->rc_type = SURF_NETWORK_ELEMENT_ROUTER;
-  info->name = xbt_strdup(router->id);
-  info->id = current_routing->parse_PU(current_routing, (void *) info);
+  RoutingEdgePtr info = new RoutingEdge();
+  info->p_rcComponent = current_routing;
+  info->p_rcType = SURF_NETWORK_ELEMENT_ROUTER;
+  info->p_name = xbt_strdup(router->id);
+  info->m_id = current_routing->parsePU(info);
   xbt_lib_set(as_router_lib, router->id, ROUTING_ASR_LEVEL, (void *) info);
-  XBT_DEBUG("Having set name '%s' id '%d'",router->id,info->id);
+  XBT_DEBUG("Having set name '%s' id '%d'", router->id, info->m_id);
 
   if (router->coord && strcmp(router->coord, "")) {
     unsigned int cursor;
@@ -225,11 +227,11 @@ static void parse_S_router(sg_platf_router_cbarg_t router)
  */
 static void parse_E_route(sg_platf_route_cbarg_t route)
 {
-  xbt_assert(current_routing->parse_route,
+  /*FIXME:REMOVE:xbt_assert(current_routing->parse_route,
              "no defined method \"set_route\" in \"%s\"",
-             current_routing->name);
+             current_routing->name);*/
 
-  current_routing->parse_route(current_routing, route);
+  current_routing->parseRoute(route);
 }
 
 /**
@@ -237,10 +239,10 @@ static void parse_E_route(sg_platf_route_cbarg_t route)
  */
 static void parse_E_ASroute(sg_platf_route_cbarg_t ASroute)
 {
-  xbt_assert(current_routing->parse_ASroute,
+  /*FIXME:REMOVE:xbt_assert(current_routing->parse_ASroute,
              "no defined method \"set_ASroute\" in \"%s\"",
-             current_routing->name);
-  current_routing->parse_ASroute(current_routing, ASroute);
+             current_routing->name);*/
+  current_routing->parseASroute(ASroute);
 }
 
 /**
@@ -248,11 +250,11 @@ static void parse_E_ASroute(sg_platf_route_cbarg_t ASroute)
  */
 static void parse_E_bypassRoute(sg_platf_route_cbarg_t route)
 {
-  xbt_assert(current_routing->parse_bypassroute,
+  /*FIXME:REMOVE:xbt_assert(current_routing->parse_bypassroute,
              "Bypassing mechanism not implemented by routing '%s'",
-             current_routing->name);
+             current_routing->name);*/
 
-  current_routing->parse_bypassroute(current_routing, route);
+  current_routing->parseBypassroute(route);
 }
 
 /**
@@ -260,10 +262,10 @@ static void parse_E_bypassRoute(sg_platf_route_cbarg_t route)
  */
 static void parse_E_bypassASroute(sg_platf_route_cbarg_t ASroute)
 {
-  xbt_assert(current_routing->parse_bypassroute,
+  /*FIXME:REMOVE:xbt_assert(current_routing->parse_bypassroute,
              "Bypassing mechanism not implemented by routing '%s'",
-             current_routing->name);
-  current_routing->parse_bypassroute(current_routing, ASroute);
+             current_routing->name);*/
+  current_routing->parseBypassroute(ASroute);
 }
 
 static void routing_parse_trace(sg_platf_trace_cbarg_t trace)
@@ -336,7 +338,6 @@ static void routing_parse_trace_connect(sg_platf_trace_connect_cbarg_t trace_con
 void routing_AS_begin(sg_platf_AS_cbarg_t AS)
 {
   XBT_DEBUG("routing_AS_begin");
-  AS_t new_as;
   routing_model_description_t model = NULL;
 
   xbt_assert(!xbt_lib_get_or_null
@@ -361,50 +362,50 @@ void routing_AS_begin(sg_platf_AS_cbarg_t AS)
   }
 
   /* make a new routing component */
-  new_as = (AS_t) model->create();
-  new_as->model_desc = model;
-  new_as->hierarchy = SURF_ROUTING_NULL;
-  new_as->name = xbt_strdup(AS->id);
+  AsPtr new_as = model->create();
+
+  new_as->p_modelDesc = model;
+  new_as->p_hierarchy = SURF_ROUTING_NULL;
+  new_as->p_name = xbt_strdup(AS->id);
 
-  sg_routing_edge_t info = NULL;
-  info = xbt_new0(s_routing_edge_t, 1);
+  RoutingEdgePtr info = new RoutingEdge();
 
-  if (current_routing == NULL && routing_platf->root == NULL) {
+  if (current_routing == NULL && routing_platf->p_root == NULL) {
 
     /* it is the first one */
-    new_as->routing_father = NULL;
-    routing_platf->root = new_as;
-    info->id = -1;
-  } else if (current_routing != NULL && routing_platf->root != NULL) {
+    new_as->p_routingFather = NULL;
+    routing_platf->p_root = new_as;
+    info->m_id = -1;
+  } else if (current_routing != NULL && routing_platf->p_root != NULL) {
 
     xbt_assert(!xbt_dict_get_or_null
-               (current_routing->routing_sons, AS->id),
+               (current_routing->p_routingSons, AS->id),
                "The AS \"%s\" already exists", AS->id);
     /* it is a part of the tree */
-    new_as->routing_father = current_routing;
+    new_as->p_routingFather = current_routing;
     /* set the father behavior */
-    if (current_routing->hierarchy == SURF_ROUTING_NULL)
-      current_routing->hierarchy = SURF_ROUTING_RECURSIVE;
+    if (current_routing->p_hierarchy == SURF_ROUTING_NULL)
+      current_routing->p_hierarchy = SURF_ROUTING_RECURSIVE;
     /* add to the sons dictionary */
-    xbt_dict_set(current_routing->routing_sons, AS->id,
+    xbt_dict_set(current_routing->p_routingSons, AS->id,
                  (void *) new_as, NULL);
     /* add to the father element list */
-    info->id = current_routing->parse_AS(current_routing, (void *) info);
+    info->m_id = current_routing->parseAS(info);
   } else {
     THROWF(arg_error, 0, "All defined components must be belong to a AS");
   }
 
-  info->rc_component = new_as->routing_father;
-  info->rc_type = SURF_NETWORK_ELEMENT_AS;
-  info->name = new_as->name;
+  info->p_rcComponent = new_as->p_routingFather;
+  info->p_rcType = SURF_NETWORK_ELEMENT_AS;
+  info->p_name = new_as->p_name;
 
-  xbt_lib_set(as_router_lib, info->name, ROUTING_ASR_LEVEL,
+  xbt_lib_set(as_router_lib, info->p_name, ROUTING_ASR_LEVEL,
               (void *) info);
-  XBT_DEBUG("Having set name '%s' id '%d'",new_as->name,info->id);
+  XBT_DEBUG("Having set name '%s' id '%d'", new_as->p_name, info->m_id);
 
   /* set the new current component of the tree */
   current_routing = new_as;
-  current_routing->net_elem = info;
+  current_routing->p_netElem = info;
 
 }
 
@@ -425,9 +426,9 @@ void routing_AS_end(sg_platf_AS_cbarg_t AS)
   if (current_routing == NULL) {
     THROWF(arg_error, 0, "Close an AS, but none was under construction");
   } else {
-    if (current_routing->model_desc->end)
-      current_routing->model_desc->end(current_routing);
-    current_routing = current_routing->routing_father;
+    if (current_routing->p_modelDesc->end)
+      current_routing->p_modelDesc->end(current_routing);
+    current_routing = current_routing->p_routingFather;
   }
 }
 
@@ -436,10 +437,10 @@ void routing_AS_end(sg_platf_AS_cbarg_t AS)
 /**
  * \brief Get the AS father and the first elements of the chain
  *
- * \param src the source host name 
+ * \param src the source host name
  * \param dst the destination host name
- * 
- * Get the common father of the to processing units, and the first different 
+ *
+ * Get the common father of the to processing units, and the first different
  * father in the chain
  */
 static void elements_father(sg_routing_edge_t src, sg_routing_edge_t dst,
@@ -449,36 +450,36 @@ static void elements_father(sg_routing_edge_t src, sg_routing_edge_t dst,
 {
   xbt_assert(src && dst, "bad parameters for \"elements_father\" method");
 #define ELEMENTS_FATHER_MAXDEPTH 16     /* increase if it is not enough */
-  AS_t src_as, dst_as;
-  AS_t path_src[ELEMENTS_FATHER_MAXDEPTH];
-  AS_t path_dst[ELEMENTS_FATHER_MAXDEPTH];
+  AsPtr src_as, dst_as;
+  AsPtr path_src[ELEMENTS_FATHER_MAXDEPTH];
+  AsPtr path_dst[ELEMENTS_FATHER_MAXDEPTH];
   int index_src = 0;
   int index_dst = 0;
-  AS_t current;
-  AS_t current_src;
-  AS_t current_dst;
-  AS_t father;
+  AsPtr current;
+  AsPtr current_src;
+  AsPtr current_dst;
+  AsPtr father;
 
   /* (1) find the as where the src and dst are located */
   sg_routing_edge_t src_data = src;
   sg_routing_edge_t dst_data = dst;
-  src_as = src_data->rc_component;
-  dst_as = dst_data->rc_component;
+  src_as = src_data->p_rcComponent;
+  dst_as = dst_data->p_rcComponent;
 #ifndef NDEBUG
-  char* src_name = src_data->name;
-  char* dst_name = dst_data->name;
+  char* src_name = src_data->p_name;
+  char* dst_name = dst_data->p_name;
 #endif
 
   xbt_assert(src_as && dst_as,
              "Ask for route \"from\"(%s) or \"to\"(%s) no found", src_name, dst_name);
 
   /* (2) find the path to the root routing component */
-  for (current = src_as; current != NULL; current = current->routing_father) {
+  for (current = src_as; current != NULL; current = current->p_routingFather) {
     if (index_src >= ELEMENTS_FATHER_MAXDEPTH)
       xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_src");
     path_src[index_src++] = current;
   }
-  for (current = dst_as; current != NULL; current = current->routing_father) {
+  for (current = dst_as; current != NULL; current = current->p_routingFather) {
     if (index_dst >= ELEMENTS_FATHER_MAXDEPTH)
       xbt_die("ELEMENTS_FATHER_MAXDEPTH should be increased for path_dst");
     path_dst[index_dst++] = current;
@@ -509,45 +510,46 @@ static void elements_father(sg_routing_edge_t src, sg_routing_edge_t dst,
 /**
  * \brief Recursive function for get_route_latency
  *
- * \param src the source host name 
+ * \param src the source host name
  * \param dst the destination host name
  * \param *route the route where the links are stored. It is either NULL or a ready to use dynar
  * \param *latency the latency, if needed
- * 
+ *
  * This function is called by "get_route" and "get_latency". It allows to walk
  * recursively through the ASes tree.
  */
-static void _get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
+static void _get_route_and_latency(RoutingEdgePtr src, RoutingEdgePtr dst,
                                    xbt_dynar_t * links, double *latency)
 {
   s_sg_platf_route_cbarg_t route;
   memset(&route,0,sizeof(route));
 
   xbt_assert(src && dst, "bad parameters for \"_get_route_latency\" method");
-  XBT_DEBUG("Solve route/latency  \"%s\" to \"%s\"", src->name, dst->name);
+  XBT_DEBUG("Solve route/latency  \"%s\" to \"%s\"", src->p_name, dst->p_name);
 
   /* Find how src and dst are interconnected */
-  AS_t common_father, src_father, dst_father;
+  AsPtr common_father, src_father, dst_father;
   elements_father(src, dst, &common_father, &src_father, &dst_father);
   XBT_DEBUG("elements_father: common father '%s' src_father '%s' dst_father '%s'",
-      common_father->name,src_father->name,dst_father->name);
+      common_father->p_name, src_father->p_name, dst_father->p_name);
 
   /* Check whether a direct bypass is defined */
   sg_platf_route_cbarg_t e_route_bypass = NULL;
-  if (common_father->get_bypass_route)
-    e_route_bypass = common_father->get_bypass_route(common_father, src, dst, latency);
+  //FIXME:REMOVE:if (common_father->get_bypass_route)
+
+  e_route_bypass = common_father->getBypassRoute(src, dst, latency);
 
   /* Common ancestor is kind enough to declare a bypass route from src to dst -- use it and bail out */
   if (e_route_bypass) {
     xbt_dynar_merge(links, &e_route_bypass->link_list);
-    generic_free_route(e_route_bypass);
+    //FIXME:generic_free_route(e_route_bypass);
     return;
   }
 
   /* If src and dst are in the same AS, life is good */
   if (src_father == dst_father) {       /* SURF_ROUTING_BASE */
     route.link_list = *links;
-    common_father->get_route_and_latency(common_father, src, dst, &route,latency);
+    common_father->getRouteAndLatency(src, dst, &route, latency);
     // if vivaldi latency+=vivaldi(src,dst)
     return;
   }
@@ -556,15 +558,14 @@ static void _get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
 
   route.link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
   // Find the net_card corresponding to father
-  sg_routing_edge_t src_father_net_elm = src_father->net_elem;
-  sg_routing_edge_t dst_father_net_elm = dst_father->net_elem;
+  RoutingEdgePtr src_father_net_elm = src_father->p_netElem;
+  RoutingEdgePtr dst_father_net_elm = dst_father->p_netElem;
 
-  common_father->get_route_and_latency(common_father,
-                                       src_father_net_elm, dst_father_net_elm,
-                                       &route, latency);
+  common_father->getRouteAndLatency(src_father_net_elm, dst_father_net_elm,
+                                    &route, latency);
 
   xbt_assert((route.gw_src != NULL) && (route.gw_dst != NULL),
-      "bad gateways for route from \"%s\" to \"%s\"", src->name, dst->name);
+      "bad gateways for route from \"%s\" to \"%s\"", src->p_name, dst->p_name);
 
   sg_routing_edge_t src_gateway_net_elm = route.gw_src;
   sg_routing_edge_t dst_gateway_net_elm = route.gw_dst;
@@ -581,6 +582,15 @@ static void _get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
   // if vivaldi latency+=vivaldi(src_gateway,dst_gateway)
 }
 
+AS_t surf_platf_get_root(routing_platf_t platf){
+  return platf->p_root;
+}
+
+e_surf_network_element_type_t surf_routing_edge_get_rc_type(sg_routing_edge_t edge){
+  return edge->p_rcType;
+}
+
+
 /**
  * \brief Find a route between hosts
  *
@@ -595,28 +605,31 @@ static void _get_route_and_latency(sg_routing_edge_t src, sg_routing_edge_t dst,
  * walk through the routing components tree and find a route between hosts
  * by calling the differents "get_route" functions in each routing component.
  */
-void routing_get_route_and_latency(sg_routing_edge_t src,
-                                   sg_routing_edge_t dst,
-                                   xbt_dynar_t * route, double *latency)
+void RoutingPlatf::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst,
+                                   xbt_dynar_t* route, double *latency)
 {
-  XBT_DEBUG("routing_get_route_and_latency from %s to %s",src->name,dst->name);
+  XBT_DEBUG("routing_get_route_and_latency from %s to %s", src->p_name, dst->p_name);
   if (!*route) {
-    xbt_dynar_reset(routing_platf->last_route);
-    *route = routing_platf->last_route;
+    xbt_dynar_reset(routing_platf->p_lastRoute);
+    *route = routing_platf->p_lastRoute;
   }
 
   _get_route_and_latency(src, dst, route, latency);
 
   xbt_assert(!latency || *latency >= 0.0,
-             "negative latency on route between \"%s\" and \"%s\"", src->name, dst->name);
+             "negative latency on route between \"%s\" and \"%s\"", src->p_name, dst->p_name);
+}
+
+xbt_dynar_t RoutingPlatf::getOneLinkRoutes(){
+  return recursiveGetOneLinkRoutes(p_root);
 }
 
-static xbt_dynar_t recursive_get_onelink_routes(AS_t rc)
+xbt_dynar_t RoutingPlatf::recursiveGetOneLinkRoutes(AsPtr rc)
 {
-  xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
+  xbt_dynar_t ret = xbt_dynar_new(sizeof(OnelinkPtr), xbt_free);
 
   //adding my one link routes
-  xbt_dynar_t onelink_mine = rc->get_onelink_routes(rc);
+  xbt_dynar_t onelink_mine = rc->getOneLinkRoutes();
   if (onelink_mine)
     xbt_dynar_merge(&ret,&onelink_mine);
 
@@ -624,41 +637,35 @@ static xbt_dynar_t recursive_get_onelink_routes(AS_t rc)
   char *key;
   xbt_dict_cursor_t cursor = NULL;
   AS_t rc_child;
-  xbt_dict_foreach(rc->routing_sons, cursor, key, rc_child) {
-    xbt_dynar_t onelink_child = recursive_get_onelink_routes(rc_child);
+  xbt_dict_foreach(rc->p_routingSons, cursor, key, rc_child) {
+    xbt_dynar_t onelink_child = recursiveGetOneLinkRoutes(rc_child);
     if (onelink_child)
       xbt_dynar_merge(&ret,&onelink_child);
   }
   return ret;
 }
 
-static xbt_dynar_t get_onelink_routes(void)
-{
-  return recursive_get_onelink_routes(routing_platf->root);
-}
-
 e_surf_network_element_type_t routing_get_network_element_type(const char *name)
 {
-  sg_routing_edge_t rc = sg_routing_edge_by_name_or_null(name);
+  RoutingEdgePtr rc = sg_routing_edge_by_name_or_null(name);
   if (rc)
-    return rc->rc_type;
+    return rc->p_rcType;
 
   return SURF_NETWORK_ELEMENT_NULL;
 }
 
 /**
  * \brief Generic method: create the global routing schema
- * 
+ *
  * Make a global routing structure and set all the parsing functions.
  */
 void routing_model_create( void *loopback)
 {
   /* config the uniq global routing */
-  routing_platf = xbt_new0(s_routing_platf_t, 1);
-  routing_platf->root = NULL;
-  routing_platf->get_onelink_routes = get_onelink_routes;
-  routing_platf->loopback = loopback;
-  routing_platf->last_route = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
+  routing_platf = new RoutingPlatf();
+  routing_platf->p_root = NULL;
+  routing_platf->p_loopback = loopback;
+  routing_platf->p_lastRoute = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
   /* no current routing at moment */
   current_routing = NULL;
 }
@@ -711,11 +718,11 @@ void routing_model_create( void *loopback)
 /* ************************* GENERIC PARSE FUNCTIONS ************************ */
 
 void routing_cluster_add_backbone(void* bb) {
-  xbt_assert(current_routing->model_desc == &routing_models[SURF_MODEL_CLUSTER],
+  xbt_assert(current_routing->p_modelDesc == &routing_models[SURF_MODEL_CLUSTER],
         "You have to be in model Cluster to use tag backbone!");
-  xbt_assert(!((as_cluster_t)current_routing)->backbone,"The backbone link is already defined!");
-  ((as_cluster_t)current_routing)->backbone = bb;
-  XBT_DEBUG("Add a backbone to AS '%s'",current_routing->name);
+  xbt_assert(!surf_as_cluster_get_backbone(current_routing), "The backbone link is already defined!");
+  surf_as_cluster_set_backbone(current_routing, bb);
+  XBT_DEBUG("Add a backbone to AS '%s'", current_routing->p_name);
 }
 
 static void routing_parse_cabinet(sg_platf_cabinet_cbarg_t cabinet)
@@ -817,7 +824,7 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
   AS.routing = A_surfxml_AS_routing_Cluster;
   sg_platf_new_AS_begin(&AS);
 
-  current_routing->link_up_down_list
+  current_routing->p_linkUpDownList
             = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
 
   //Make all hosts
@@ -905,13 +912,13 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
         info.link_up = xbt_lib_get_or_null(link_lib, link_id, SURF_LINK_LEVEL);
         info.link_down = info.link_up;
       }
-      
-      if(cluster->limiter_link!=0){      
+
+      if(cluster->limiter_link!=0){
         char *tmp_link = bprintf("%s_limiter", link_id);
         XBT_DEBUG("<limiter\tid=\"%s\"\tbw=\"%f\"/>", tmp_link,
                 cluster->limiter_link);
 
-        
+
         memset(&link, 0, sizeof(link));
         link.id = tmp_link;
         link.bandwidth = cluster->limiter_link;
@@ -925,13 +932,13 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
       }else{
         info.limiter_link =NULL;
       }
-      
-      if(cluster->loopback_bw!=0 || cluster->loopback_lat!=0){      
+
+      if(cluster->loopback_bw!=0 || cluster->loopback_lat!=0){
         char *tmp_link = bprintf("%s_loopback", link_id);
         XBT_DEBUG("<loopback\tid=\"%s\"\tbw=\"%f\"/>", tmp_link,
                 cluster->limiter_link);
 
-        
+
         memset(&link, 0, sizeof(link));
         link.id = tmp_link;
         link.bandwidth = cluster->loopback_bw;
@@ -945,8 +952,8 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
       }else{
         info.loopback_link =NULL;
       }
-      
-      xbt_dynar_push(current_routing->link_up_down_list,&info);
+
+      xbt_dynar_push(current_routing->p_linkUpDownList, &info);
       xbt_free(link_id);
       xbt_free(host_id);
     }
@@ -969,7 +976,7 @@ static void routing_parse_cluster(sg_platf_cluster_cbarg_t cluster)
         bprintf("%s%s_router%s", cluster->prefix, cluster->id,
                 cluster->suffix);
   sg_platf_new_router(&router);
-  ((as_cluster_t)current_routing)->router = xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL);
+  ((AsClusterPtr)current_routing)->p_router = (RoutingEdgePtr) xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL);
   free(newid);
 
   //Make the backbone
@@ -1019,8 +1026,7 @@ static void routing_parse_peer(sg_platf_peer_cbarg_t peer)
   AS.routing = A_surfxml_AS_routing_Cluster;
   sg_platf_new_AS_begin(&AS);
 
-  current_routing->link_up_down_list
-            = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
+  current_routing->p_linkUpDownList = xbt_dynar_new(sizeof(s_surf_parsing_link_up_down_t),NULL);
 
   XBT_DEBUG("<host\tid=\"%s\"\tpower=\"%f\"/>", host_id, peer->power);
   s_sg_platf_host_cbarg_t host;
@@ -1073,7 +1079,7 @@ static void routing_parse_peer(sg_platf_peer_cbarg_t peer)
   router.id = router_id;
   router.coord = peer->coord;
   sg_platf_new_router(&router);
-  ((as_cluster_t)current_routing)->router = xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL);
+  static_cast<AsClusterPtr>(current_routing)->p_router = static_cast<RoutingEdgePtr>(xbt_lib_get_or_null(as_router_lib, router.id, ROUTING_ASR_LEVEL));
 
   XBT_DEBUG("</AS>");
   sg_platf_new_AS_end();
@@ -1243,56 +1249,61 @@ void routing_register_callbacks()
  * This fuction is call by "finalize". It allow to finalize the
  * AS or routing components. It delete all the structures.
  */
-static void finalize_rec(AS_t as) {
+static void finalize_rec(AsPtr as) {
   xbt_dict_cursor_t cursor = NULL;
   char *key;
   AS_t elem;
 
-  xbt_dict_foreach(as->routing_sons, cursor, key, elem) {
+  xbt_dict_foreach(as->p_routingSons, cursor, key, elem) {
     finalize_rec(elem);
   }
 
-  as->finalize(as);
+  delete as;;
 }
 
 /** \brief Frees all memory allocated by the routing module */
 void routing_exit(void) {
   if (!routing_platf)
     return;
-  xbt_dynar_free(&routing_platf->last_route);
-  finalize_rec(routing_platf->root);
+  xbt_dynar_free(&routing_platf->p_lastRoute);
+  finalize_rec(routing_platf->p_root);
   xbt_free(routing_platf);
 }
 
 AS_t surf_AS_get_routing_root() {
-  return routing_platf->root;  
+  return routing_platf->p_root;
 }
 
-const char *surf_AS_get_name(AS_t as) {
-  return as->name;
+const char *surf_AS_get_name(AsPtr as) {
+  return as->p_name;
 }
 
-xbt_dict_t surf_AS_get_routing_sons(AS_t as) {
-  return as->routing_sons;
+xbt_dict_t surf_AS_get_routing_sons(AsPtr as) {
+  return as->p_routingSons;
 }
 
-const char *surf_AS_get_model(AS_t as) {
-  return as->model_desc->name;
+const char *surf_AS_get_model(AsPtr as) {
+  return as->p_modelDesc->name;
 }
 
-xbt_dynar_t surf_AS_get_hosts(AS_t as) {
-  xbt_dynar_t elms = as->index_network_elm;
+xbt_dynar_t surf_AS_get_hosts(AsPtr as) {
+  xbt_dynar_t elms = as->p_indexNetworkElm;
   sg_routing_edge_t relm;
   xbt_dictelm_t delm;
   int index;
   int count = xbt_dynar_length(elms);
   xbt_dynar_t res =  xbt_dynar_new(sizeof(xbt_dictelm_t), NULL);
   for (index = 0; index < count; index++) {
-     relm = xbt_dynar_get_as(elms, index, sg_routing_edge_t);
-     delm = xbt_lib_get_elm_or_null(host_lib, relm->name);
+     relm = xbt_dynar_get_as(elms, index, RoutingEdgePtr);
+     delm = xbt_lib_get_elm_or_null(host_lib, relm->p_name);
      if (delm!=NULL) {
        xbt_dynar_push(res, &delm);
      }
   }
   return res;
 }
+
+void surf_AS_get_graph(AS_t as, xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges) {
+  as->getGraph(graph, nodes, edges);
+}
+
diff --git a/src/surf/surf_routing.hpp b/src/surf/surf_routing.hpp
new file mode 100644 (file)
index 0000000..2e5e36b
--- /dev/null
@@ -0,0 +1,93 @@
+#include "surf.hpp"
+
+#ifndef NETWORK_ROUTING_HPP_
+#define NETWORK_ROUTING_HPP_
+
+void routing_model_create( void *loopback);
+
+/***********
+ * Classes *
+ ***********/
+class As;
+typedef As *AsPtr;
+
+class RoutingModelDescription;
+typedef RoutingModelDescription *RoutingModelDescriptionPtr;
+
+class RoutingEdge;
+typedef RoutingEdge *RoutingEdgePtr;
+
+class Onelink;
+typedef Onelink *OnelinkPtr;
+
+class RoutingPlatf;
+typedef RoutingPlatf *RoutingPlatfPtr;
+
+
+/*FIXME:class RoutingModelDescription {
+  const char *p_name;
+  const char *p_desc;
+  AsPtr create();
+  void end(AsPtr as);
+};*/
+
+class As {
+public:
+  xbt_dynar_t p_indexNetworkElm;
+  xbt_dict_t p_bypassRoutes;    /* store bypass routes */
+  routing_model_description_t p_modelDesc;
+  e_surf_routing_hierarchy_t p_hierarchy;
+  char *p_name;
+  AsPtr p_routingFather;
+  xbt_dict_t p_routingSons;
+  RoutingEdgePtr p_netElem;
+  xbt_dynar_t p_linkUpDownList;
+
+  As(){};
+  ~As(){};
+
+  virtual void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency)=0;
+  virtual xbt_dynar_t getOneLinkRoutes()=0;
+  virtual void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges)=0;
+  virtual sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat)=0;
+
+  /* The parser calls the following functions to inform the routing models
+   * that a new element is added to the AS currently built.
+   *
+   * Of course, only the routing model of this AS is informed, not every ones */
+  virtual int parsePU(RoutingEdgePtr elm)=0; /* A host or a router, whatever */
+  virtual int parseAS( RoutingEdgePtr elm)=0;
+  virtual void parseRoute(sg_platf_route_cbarg_t route)=0;
+  virtual void parseASroute(sg_platf_route_cbarg_t route)=0;
+  virtual void parseBypassroute(sg_platf_route_cbarg_t e_route)=0;
+};
+
+class RoutingEdge {
+public:
+  AsPtr p_rcComponent;
+  e_surf_network_element_type_t p_rcType;
+  int m_id;
+  char *p_name;
+};
+
+/*
+ * Link of lenght 1, alongside with its source and destination. This is mainly usefull in the bindings to gtnets and ns3
+ */
+class Onelink {
+public:
+  RoutingEdgePtr p_src;
+  RoutingEdgePtr p_dst;
+  void *p_linkPtr;
+};
+
+class RoutingPlatf {
+public:
+  AsPtr p_root;
+  void *p_loopback;
+  xbt_dynar_t p_lastRoute;
+  xbt_dynar_t getOneLinkRoutes(void);
+  xbt_dynar_t recursiveGetOneLinkRoutes(AsPtr rc);
+  void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, xbt_dynar_t * links, double *latency);
+};
+
+#endif /* NETWORK_ROUTING_HPP_ */
diff --git a/src/surf/surf_routing_cluster.cpp b/src/surf/surf_routing_cluster.cpp
new file mode 100644 (file)
index 0000000..d9cab06
--- /dev/null
@@ -0,0 +1,151 @@
+/* Copyright (c) 2009, 2010, 2011. The SimGrid Team.
+
+/* 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 "surf_routing_cluster.hpp"
+#include "surf_routing_private.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_cluster, surf, "Routing part of surf");
+}
+
+/* This routing is specifically setup to represent clusters, aka homogeneous sets of machines
+ * Note that a router is created, easing the interconnexion with the rest of the world.
+ */
+
+AS_t model_cluster_create(void)
+{
+  return new AsCluster();
+}
+
+/* Creation routing model functions */
+AsCluster::AsCluster() : AsNone()
+{
+  p_backbone = 0;
+  p_loopback = 0;
+  p_router = 0;
+}
+
+/* Business methods */
+void AsCluster::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t route, double *lat)
+{
+  s_surf_parsing_link_up_down_t info;
+  XBT_VERB("cluster_get_route_and_latency from '%s'[%d] to '%s'[%d]",
+            src->p_name, src->m_id, dst->p_name, dst->m_id);
+
+  if (src->p_rcType != SURF_NETWORK_ELEMENT_ROUTER) {    // No specific link for router
+    info = xbt_dynar_get_as(p_linkUpDownList, src->m_id, s_surf_parsing_link_up_down_t);
+
+    if((src->m_id == dst->m_id) && info.loopback_link  ){
+      xbt_dynar_push_as(route->link_list, void *, info.loopback_link);
+      if (lat)
+        *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(info.loopback_link))->getLatency();
+      return;
+    }
+
+
+    if (info.limiter_link)          // limiter for sender
+      xbt_dynar_push_as(route->link_list, void *, info.limiter_link);
+
+    if (info.link_up) {         // link up
+      xbt_dynar_push_as(route->link_list, void *, info.link_up);
+      if (lat)
+        *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(info.link_up))->getLatency();
+    }
+  }
+
+  if (p_backbone) {
+    xbt_dynar_push_as(route->link_list, void *, static_cast<ResourcePtr>(p_backbone));
+    if (lat)
+      *lat += p_backbone->getLatency();
+  }
+
+  if (dst->p_rcType != SURF_NETWORK_ELEMENT_ROUTER) {    // No specific link for router
+    info =
+        xbt_dynar_get_as(p_linkUpDownList, dst->m_id, s_surf_parsing_link_up_down_t);
+    if (info.link_down) {       // link down
+      xbt_dynar_push_as(route->link_list, void *, info.link_down);
+      if (lat)
+        *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(info.link_down))->getLatency();
+    }
+
+    if (info.limiter_link)          // limiter for receiver
+      xbt_dynar_push_as(route->link_list, void *, info.limiter_link);
+
+  }
+}
+
+void AsCluster::getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges)
+{
+  int isrc;
+  int table_size = xbt_dynar_length(p_indexNetworkElm);
+
+  RoutingEdgePtr src;
+  xbt_node_t current, previous, backboneNode = NULL, routerNode;
+  s_surf_parsing_link_up_down_t info;
+
+  xbt_assert(p_router,"Malformed cluster");
+
+  /* create the router */
+  char *link_name = p_router->p_name;
+  routerNode = new_xbt_graph_node(graph, link_name, nodes);
+
+  if(p_backbone) {
+    const char *link_nameR = p_backbone->m_name;
+    backboneNode = new_xbt_graph_node(graph, link_nameR, nodes);
+
+    new_xbt_graph_edge(graph, routerNode, backboneNode, edges);
+  }
+
+  for (isrc = 0; isrc < table_size; isrc++) {
+    src = xbt_dynar_get_as(p_indexNetworkElm, isrc, RoutingEdgePtr);
+
+    if (src->p_rcType != SURF_NETWORK_ELEMENT_ROUTER) {
+      previous = new_xbt_graph_node(graph, src->p_name, nodes);
+
+      info = xbt_dynar_get_as(p_linkUpDownList, src->m_id, s_surf_parsing_link_up_down_t);
+
+      if (info.link_up) {     // link up
+
+        const char *link_name = ((ResourcePtr) info.link_up)->m_name;
+        current = new_xbt_graph_node(graph, link_name, nodes);
+        new_xbt_graph_edge(graph, previous, current, edges);
+
+        if (p_backbone) {
+          new_xbt_graph_edge(graph, current, backboneNode, edges);
+        } else {
+          new_xbt_graph_edge(graph, current, routerNode, edges);
+        }
+
+      }
+
+      if (info.link_down) {    // link down
+        const char *link_name = ((ResourcePtr) info.link_down)->m_name;
+        current = new_xbt_graph_node(graph, link_name, nodes);
+        new_xbt_graph_edge(graph, previous, current, edges);
+
+        if (p_backbone) {
+          new_xbt_graph_edge(graph, current, backboneNode, edges);
+        } else {
+          new_xbt_graph_edge(graph, current, routerNode, edges);
+        }
+      }
+    }
+
+  }
+}
+
+int AsCluster::parsePU(RoutingEdgePtr elm) {
+  XBT_DEBUG("Load process unit \"%s\"", elm->p_name);
+  xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+  return xbt_dynar_length(p_indexNetworkElm)-1;
+}
+
+int AsCluster::parseAS(RoutingEdgePtr elm) {
+  XBT_DEBUG("Load Autonomous system \"%s\"", elm->p_name);
+  xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+  return xbt_dynar_length(p_indexNetworkElm)-1;
+}
+
+
diff --git a/src/surf/surf_routing_cluster.hpp b/src/surf/surf_routing_cluster.hpp
new file mode 100644 (file)
index 0000000..c3e8871
--- /dev/null
@@ -0,0 +1,44 @@
+#include "surf_routing_none.hpp"
+#include "network.hpp"
+
+#ifndef SURF_ROUTING_CLUSTER_HPP_
+#define SURF_ROUTING_CLUSTER_HPP_
+
+/***********
+ * Classes *
+ ***********/
+class AsCluster;
+typedef AsCluster *AsClusterPtr;
+
+
+/* ************************************************** */
+/* **************  Cluster ROUTING   **************** */
+
+class AsCluster: public AsNone {
+public:
+  AsCluster();
+
+  void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
+  //xbt_dynar_t getOneLinkRoutes();
+  //void parseRoute(sg_platf_route_cbarg_t route);
+  //void parseASroute(sg_platf_route_cbarg_t route);
+
+  void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+  //sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+
+  /* The parser calls the following functions to inform the routing models
+   * that a new element is added to the AS currently built.
+   *
+   * Of course, only the routing model of this AS is informed, not every ones */
+  int parsePU(RoutingEdgePtr elm); /* A host or a router, whatever */
+  int parseAS(RoutingEdgePtr elm);
+
+  //virtual void parseBypassroute(sg_platf_route_cbarg_t e_route)=0;
+
+  NetworkCm02LinkPtr p_backbone;
+  void *p_loopback;
+  RoutingEdgePtr p_router;
+};
+
+
+#endif /* SURF_ROUTING_CLUSTER_HPP_ */
similarity index 57%
rename from src/surf/surf_routing_dijkstra.c
rename to src/surf/surf_routing_dijkstra.cpp
index 8d204bc..a90140b 100644 (file)
@@ -4,35 +4,16 @@
 /* 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 "surf_routing_dijkstra.hpp"
 #include "surf_routing_private.h"
+#include "network.hpp"
 
 /* Global vars */
 extern routing_platf_t routing_platf;
 
+extern "C" {
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_dijkstra, surf, "Routing part of surf -- dijkstra routing logic");
-
-typedef struct {
-  s_as_t generic_routing;
-  xbt_graph_t route_graph;      /* xbt_graph */
-  xbt_dict_t graph_node_map;    /* map */
-  xbt_dict_t route_cache;       /* use in cache mode */
-  int cached;
-} s_as_dijkstra_t, *as_dijkstra_t;
-
-
-typedef struct graph_node_data {
-  int id;
-  int graph_id;                 /* used for caching internal graph id's */
-} s_graph_node_data_t, *graph_node_data_t;
-
-typedef struct graph_node_map_element {
-  xbt_node_t node;
-} s_graph_node_map_element_t, *graph_node_map_element_t;
-
-typedef struct route_cache_element {
-  int *pred_arr;
-  int size;
-} s_route_cache_element_t, *route_cache_element_t;
+}
 
 /* Free functions */
 
@@ -60,10 +41,46 @@ static void graph_edge_data_free(void *e) // FIXME: useless code duplication
   }
 }
 
+AS_t model_dijkstra_create(void){
+  return new AsDijkstra(0);
+}
+
+AS_t model_dijkstracache_create(void){
+  return new AsDijkstra(1);
+}
+
+void model_dijkstra_both_end(AS_t as)
+{
+  AsDijkstraPtr THIS_AS = static_cast<AsDijkstraPtr>(as);
+  xbt_node_t node = NULL;
+  unsigned int cursor2;
+  xbt_dynar_t nodes = NULL;
+
+  /* Create the topology graph */
+  if(!THIS_AS->p_routeGraph)
+    THIS_AS->p_routeGraph = xbt_graph_new_graph(1, NULL);
+  if(!THIS_AS->p_graphNodeMap)
+    THIS_AS->p_graphNodeMap = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
+
+  if (THIS_AS->m_cached && !THIS_AS->p_routeCache)
+    THIS_AS->p_routeCache = xbt_dict_new_homogeneous(&route_cache_elem_free);
+
+  /* Add the loopback if needed */
+  if (routing_platf->p_loopback && as->p_hierarchy == SURF_ROUTING_BASE)
+    THIS_AS->addLoopback();
+
+  /* initialize graph indexes in nodes after graph has been built */
+  nodes = xbt_graph_get_nodes(THIS_AS->p_routeGraph);
+
+  xbt_dynar_foreach(nodes, cursor2, node) {
+    graph_node_data_t data = (graph_node_data_t) xbt_graph_node_get_data(node);
+    data->graph_id = cursor2;
+  }
+}
+
 /* Utility functions */
 
-static xbt_node_t route_graph_new_node(as_dijkstra_t as,
-    int id, int graph_id)
+xbt_node_t AsDijkstra::routeGraphNewNode(int id, int graph_id)
 {
   xbt_node_t node = NULL;
   graph_node_data_t data = NULL;
@@ -72,21 +89,20 @@ static xbt_node_t route_graph_new_node(as_dijkstra_t as,
   data = xbt_new0(struct graph_node_data, 1);
   data->id = id;
   data->graph_id = graph_id;
-  node = xbt_graph_new_node(as->route_graph, data);
+  node = xbt_graph_new_node(p_routeGraph, data);
 
   elm = xbt_new0(struct graph_node_map_element, 1);
   elm->node = node;
-  xbt_dict_set_ext(as->graph_node_map, (char *) (&id), sizeof(int),
+  xbt_dict_set_ext(p_graphNodeMap, (char *) (&id), sizeof(int),
       (xbt_set_elm_t) elm, NULL);
 
   return node;
 }
 
-static graph_node_map_element_t
-graph_node_map_search(as_dijkstra_t as, int id)
+graph_node_map_element_t AsDijkstra::nodeMapSearch(int id)
 {
   graph_node_map_element_t elm = (graph_node_map_element_t)
-          xbt_dict_get_or_null_ext(as->graph_node_map,
+          xbt_dict_get_or_null_ext(p_graphNodeMap,
               (char *) (&id),
               sizeof(int));
   return elm;
@@ -94,19 +110,18 @@ graph_node_map_search(as_dijkstra_t as, int id)
 
 /* Parsing */
 
-static void route_new_dijkstra(as_dijkstra_t as, int src_id,
-    int dst_id, sg_platf_route_cbarg_t e_route)
+void AsDijkstra::newRoute(int src_id, int dst_id, sg_platf_route_cbarg_t e_route)
 {
   XBT_DEBUG("Load Route from \"%d\" to \"%d\"", src_id, dst_id);
   xbt_node_t src = NULL;
   xbt_node_t dst = NULL;
 
   graph_node_map_element_t src_elm = (graph_node_map_element_t)
-          xbt_dict_get_or_null_ext(as->graph_node_map,
+          xbt_dict_get_or_null_ext(p_graphNodeMap,
               (char *) (&src_id),
               sizeof(int));
   graph_node_map_element_t dst_elm = (graph_node_map_element_t)
-          xbt_dict_get_or_null_ext(as->graph_node_map,
+          xbt_dict_get_or_null_ext(p_graphNodeMap,
               (char *) (&dst_id),
               sizeof(int));
 
@@ -119,23 +134,23 @@ static void route_new_dijkstra(as_dijkstra_t as, int src_id,
 
   /* add nodes if they don't exist in the graph */
   if (src_id == dst_id && src == NULL && dst == NULL) {
-    src = route_graph_new_node(as, src_id, -1);
+    src = this->routeGraphNewNode(src_id, -1);
     dst = src;
   } else {
     if (src == NULL) {
-      src = route_graph_new_node(as, src_id, -1);
+      src = this->routeGraphNewNode(src_id, -1);
     }
     if (dst == NULL) {
-      dst = route_graph_new_node(as, dst_id, -1);
+      dst = this->routeGraphNewNode(dst_id, -1);
     }
   }
 
   /* add link as edge to graph */
-  xbt_graph_new_edge(as->route_graph, src, dst, e_route);
+  xbt_graph_new_edge(p_routeGraph, src, dst, e_route);
 }
 
-static void add_loopback_dijkstra(as_dijkstra_t as) {
-  xbt_dynar_t nodes = xbt_graph_get_nodes(as->route_graph);
+void AsDijkstra::addLoopback() {
+  xbt_dynar_t nodes = xbt_graph_get_nodes(p_routeGraph);
 
   xbt_node_t node = NULL;
   unsigned int cursor2;
@@ -156,41 +171,38 @@ static void add_loopback_dijkstra(as_dijkstra_t as) {
     if (!found) {
       sg_platf_route_cbarg_t e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
       e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
-      xbt_dynar_push(e_route->link_list, &routing_platf->loopback);
-      xbt_graph_new_edge(as->route_graph, node, node, e_route);
+      xbt_dynar_push(e_route->link_list, &routing_platf->p_loopback);
+      xbt_graph_new_edge(p_routeGraph, node, node, e_route);
     }
   }
 }
 
-static void dijkstra_get_route_and_latency(AS_t as_generic,
-    sg_routing_edge_t src, sg_routing_edge_t dst, sg_platf_route_cbarg_t route, double *lat);
-
-static xbt_dynar_t dijkstra_get_onelink_routes(AS_t as)
+xbt_dynar_t AsDijkstra::getOnelinkRoutes()
 {
-  xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
+  xbt_dynar_t ret = xbt_dynar_new(sizeof(OnelinkPtr), xbt_free);
   sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t,1);
   route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t),NULL);
 
   int src,dst;
-  sg_routing_edge_t src_elm, dst_elm;
-  size_t table_size = xbt_dynar_length(as->index_network_elm);
+  RoutingEdgePtr src_elm, dst_elm;
+  size_t table_size = xbt_dynar_length(p_indexNetworkElm);
   for(src=0; src < table_size; src++) {
     for(dst=0; dst< table_size; dst++) {
       xbt_dynar_reset(route->link_list);
-      src_elm = xbt_dynar_get_as(as->index_network_elm,src,sg_routing_edge_t);
-      dst_elm = xbt_dynar_get_as(as->index_network_elm,dst,sg_routing_edge_t);
-      dijkstra_get_route_and_latency(as, src_elm, dst_elm,route, NULL);
+      src_elm = xbt_dynar_get_as(p_indexNetworkElm, src, RoutingEdgePtr);
+      dst_elm = xbt_dynar_get_as(p_indexNetworkElm, dst, RoutingEdgePtr);
+      this->getRouteAndLatency(src_elm, dst_elm,route, NULL);
 
       if (xbt_dynar_length(route->link_list) == 1) {
         void *link = *(void **) xbt_dynar_get_ptr(route->link_list, 0);
-        onelink_t onelink = xbt_new0(s_onelink_t, 1);
-        onelink->link_ptr = link;
-        if (as->hierarchy == SURF_ROUTING_BASE) {
-          onelink->src = src_elm;
-          onelink->dst = dst_elm;
-        } else if (as->hierarchy == SURF_ROUTING_RECURSIVE) {
-          onelink->src = route->gw_src;
-          onelink->dst = route->gw_dst;
+        OnelinkPtr onelink = new Onelink();
+        onelink->p_linkPtr = link;
+        if (p_hierarchy == SURF_ROUTING_BASE) {
+          onelink->p_src = src_elm;
+          onelink->p_dst = dst_elm;
+        } else if (p_hierarchy == SURF_ROUTING_RECURSIVE) {
+          onelink->p_src = route->gw_src;
+          onelink->p_dst = route->gw_dst;
         }
         xbt_dynar_push(ret, &onelink);
       }
@@ -199,20 +211,17 @@ static xbt_dynar_t dijkstra_get_onelink_routes(AS_t as)
   return ret;
 }
 
-static void dijkstra_get_route_and_latency(AS_t asg,
-    sg_routing_edge_t src, sg_routing_edge_t dst,
-    sg_platf_route_cbarg_t route, double *lat)
+void AsDijkstra::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t route, double *lat)
 {
 
   /* set utils vars */
-  as_dijkstra_t as = (as_dijkstra_t) asg;
 
-  generic_src_dst_check(asg, src, dst);
-  int *src_id = &(src->id);
-  int *dst_id = &(dst->id);
+  srcDstCheck(src, dst);
+  int *src_id = &(src->m_id);
+  int *dst_id = &(dst->m_id);
 
   if (!src_id || !dst_id)
-    THROWF(arg_error,0,"No route from '%s' to '%s'",src->name,dst->name);
+    THROWF(arg_error,0,"No route from '%s' to '%s'",src->p_name,dst->p_name);
 
   int *pred_arr = NULL;
   int src_node_id = 0;
@@ -225,13 +234,11 @@ static void dijkstra_get_route_and_latency(AS_t asg,
   void *link;
   xbt_dynar_t links = NULL;
   route_cache_element_t elm = NULL;
-  xbt_dynar_t nodes = xbt_graph_get_nodes(as->route_graph);
+  xbt_dynar_t nodes = xbt_graph_get_nodes(p_routeGraph);
 
   /* Use the graph_node id mapping set to quickly find the nodes */
-  graph_node_map_element_t src_elm =
-      graph_node_map_search(as, *src_id);
-  graph_node_map_element_t dst_elm =
-      graph_node_map_search(as, *dst_id);
+  graph_node_map_element_t src_elm = nodeMapSearch(*src_id);
+  graph_node_map_element_t dst_elm = nodeMapSearch(*dst_id);
 
   src_node_id = ((graph_node_data_t)
       xbt_graph_node_get_data(src_elm->node))->graph_id;
@@ -243,11 +250,10 @@ static void dijkstra_get_route_and_latency(AS_t asg,
 
     xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_node_id, xbt_node_t);
     xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_node_id, xbt_node_t);
-    xbt_edge_t edge =
-        xbt_graph_get_edge(as->route_graph, node_s_v, node_e_v);
+    xbt_edge_t edge = xbt_graph_get_edge(p_routeGraph, node_s_v, node_e_v);
 
     if (edge == NULL)
-      THROWF(arg_error,0,"No route from '%s' to '%s'",src->name,dst->name);
+      THROWF(arg_error, 0, "No route from '%s' to '%s'", src->p_name, dst->p_name);
 
     e_route = (sg_platf_route_cbarg_t) xbt_graph_edge_get_data(edge);
 
@@ -255,15 +261,15 @@ static void dijkstra_get_route_and_latency(AS_t asg,
     xbt_dynar_foreach(links, cpt, link) {
       xbt_dynar_unshift(route->link_list, &link);
       if (lat)
-        *lat += surf_network_model->extension.network.get_link_latency(link);
+        *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(link))->getLatency();
     }
 
   }
 
-  if (as->cached) {
+  if (m_cached) {
     /*check if there is a cached predecessor list avail */
     elm = (route_cache_element_t)
-            xbt_dict_get_or_null_ext(as->route_cache, (char *) (&src_id),
+            xbt_dict_get_or_null_ext(p_routeCache, (char *) (&src_id),
                 sizeof(int));
   }
 
@@ -298,7 +304,7 @@ static void dijkstra_get_route_and_latency(AS_t asg,
 
     /* apply dijkstra using the indexes from the graph's node array */
     while (xbt_heap_size(pqueue) > 0) {
-      int *v_id = xbt_heap_pop(pqueue);
+      int *v_id = (int *) xbt_heap_pop(pqueue);
       xbt_node_t v_node = xbt_dynar_get_as(nodes, *v_id, xbt_node_t);
       xbt_dynar_t out_edges = xbt_graph_node_get_outedges(v_node);
       xbt_edge_t edge = NULL;
@@ -306,7 +312,7 @@ static void dijkstra_get_route_and_latency(AS_t asg,
 
       xbt_dynar_foreach(out_edges, cursor, edge) {
         xbt_node_t u_node = xbt_graph_edge_get_target(edge);
-        graph_node_data_t data = xbt_graph_node_get_data(u_node);
+        graph_node_data_t data = (graph_node_data_t) xbt_graph_node_get_data(u_node);
         int u_id = data->graph_id;
         sg_platf_route_cbarg_t tmp_e_route = (sg_platf_route_cbarg_t) xbt_graph_edge_get_data(edge);
         int cost_v_u = (tmp_e_route->link_list)->used;    /* count of links, old model assume 1 */
@@ -329,18 +335,18 @@ static void dijkstra_get_route_and_latency(AS_t asg,
   }
 
   /* compose route path with links */
-  sg_routing_edge_t gw_src = NULL, gw_dst, prev_gw_src, first_gw = NULL;
-  sg_routing_edge_t gw_dst_net_elm = NULL, prev_gw_src_net_elm = NULL;
+  RoutingEdgePtr gw_src = NULL, gw_dst, prev_gw_src, first_gw = NULL;
+  RoutingEdgePtr gw_dst_net_elm = NULL, prev_gw_src_net_elm = NULL;
 
   for (v = dst_node_id; v != src_node_id; v = pred_arr[v]) {
     xbt_node_t node_pred_v =
         xbt_dynar_get_as(nodes, pred_arr[v], xbt_node_t);
     xbt_node_t node_v = xbt_dynar_get_as(nodes, v, xbt_node_t);
     xbt_edge_t edge =
-        xbt_graph_get_edge(as->route_graph, node_pred_v, node_v);
+        xbt_graph_get_edge(p_routeGraph, node_pred_v, node_v);
 
     if (edge == NULL)
-      THROWF(arg_error,0,"No route from '%s' to '%s'",src->name,dst->name);
+      THROWF(arg_error, 0, "No route from '%s' to '%s'", src->p_name, dst->p_name);
 
     prev_gw_src = gw_src;
 
@@ -351,18 +357,19 @@ static void dijkstra_get_route_and_latency(AS_t asg,
     if (v == dst_node_id)
       first_gw = gw_dst;
 
-    if (asg->hierarchy == SURF_ROUTING_RECURSIVE && v != dst_node_id
-        && strcmp(gw_dst->name, prev_gw_src->name)) {
+    if (p_hierarchy == SURF_ROUTING_RECURSIVE && v != dst_node_id
+        && strcmp(gw_dst->p_name, prev_gw_src->p_name)) {
       xbt_dynar_t e_route_as_to_as=NULL;
-      routing_get_route_and_latency(gw_dst_net_elm, prev_gw_src_net_elm, &e_route_as_to_as, NULL);
+
+      routing_platf->getRouteAndLatency(gw_dst_net_elm, prev_gw_src_net_elm, &e_route_as_to_as, NULL);
       if (edge == NULL)
-        THROWF(arg_error,0,"No route from '%s' to '%s'",src->name,dst->name);
+        THROWF(arg_error,0,"No route from '%s' to '%s'", src->p_name, dst->p_name);
       links = e_route_as_to_as;
       int pos = 0;
       xbt_dynar_foreach(links, cpt, link) {
         xbt_dynar_insert_at(route->link_list, pos, &link);
         if (lat)
-          *lat += surf_network_model->extension.network.get_link_latency(link);
+          *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(link))->getLatency();
         pos++;
       }
     }
@@ -371,102 +378,89 @@ static void dijkstra_get_route_and_latency(AS_t asg,
     xbt_dynar_foreach(links, cpt, link) {
       xbt_dynar_unshift(route->link_list, &link);
       if (lat)
-        *lat += surf_network_model->extension.network.get_link_latency(link);
+        *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(link))->getLatency();
     }
     size++;
   }
 
-  if (asg->hierarchy == SURF_ROUTING_RECURSIVE) {
+  if (p_hierarchy == SURF_ROUTING_RECURSIVE) {
     route->gw_src = gw_src;
     route->gw_dst = first_gw;
   }
 
-  if (as->cached && elm == NULL) {
+  if (m_cached && elm == NULL) {
     /* add to predecessor list of the current src-host to cache */
     elm = xbt_new0(struct route_cache_element, 1);
     elm->pred_arr = pred_arr;
     elm->size = size;
-    xbt_dict_set_ext(as->route_cache, (char *) (&src_id), sizeof(int),
+    xbt_dict_set_ext(p_routeCache, (char *) (&src_id), sizeof(int),
         (xbt_set_elm_t) elm, NULL);
   }
 
-  if (!as->cached)
+  if (!m_cached)
     xbt_free(pred_arr);
 }
 
-static void dijkstra_finalize(AS_t asg)
+AsDijkstra::~AsDijkstra()
 {
-  as_dijkstra_t as = (as_dijkstra_t) asg;
-
-  xbt_graph_free_graph(as->route_graph, &xbt_free,
+  xbt_graph_free_graph(p_routeGraph, &xbt_free,
       &graph_edge_data_free, &xbt_free);
-  xbt_dict_free(&as->graph_node_map);
-  if (as->cached)
-    xbt_dict_free(&as->route_cache);
-
-  model_generic_finalize(asg);
+  xbt_dict_free(&p_graphNodeMap);
+  if (m_cached)
+    xbt_dict_free(&p_routeCache);
 }
 
 /* Creation routing model functions */
 
-AS_t model_dijkstra_both_create(int cached)
-{
-  as_dijkstra_t new_component = (as_dijkstra_t)
-          model_generic_create_sized(sizeof(s_as_dijkstra_t));
+AsDijkstra::AsDijkstra() : AsGeneric(), m_cached(0) {}
 
-  new_component->generic_routing.parse_route = model_dijkstra_both_parse_route;
+AsDijkstra::AsDijkstra(int cached) : AsGeneric(), m_cached(cached)
+{
+  /*new_component->generic_routing.parse_route = model_dijkstra_both_parse_route;
   new_component->generic_routing.parse_ASroute = model_dijkstra_both_parse_route;
   new_component->generic_routing.get_route_and_latency = dijkstra_get_route_and_latency;
   new_component->generic_routing.get_onelink_routes =
       dijkstra_get_onelink_routes;
   new_component->generic_routing.get_graph = generic_get_graph;
   new_component->generic_routing.finalize = dijkstra_finalize;
-  new_component->cached = cached;
-
-  return (AS_t)new_component;
+  new_component->cached = cached;*/
 }
 
-AS_t model_dijkstra_create(void)
+void AsDijkstra::end()
 {
-  return model_dijkstra_both_create(0);
-}
-
-AS_t model_dijkstracache_create(void)
-{
-  return model_dijkstra_both_create(1);
-}
-
-void model_dijkstra_both_end(AS_t as)
-{
-  as_dijkstra_t THIS_AS = (as_dijkstra_t) as;
-
   xbt_node_t node = NULL;
   unsigned int cursor2;
   xbt_dynar_t nodes = NULL;
 
   /* Create the topology graph */
-  if(!THIS_AS->route_graph)
-    THIS_AS->route_graph = xbt_graph_new_graph(1, NULL);
-  if(!THIS_AS->graph_node_map)
-    THIS_AS->graph_node_map = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
+  if(!p_routeGraph)
+       p_routeGraph = xbt_graph_new_graph(1, NULL);
+  if(!p_graphNodeMap)
+    p_graphNodeMap = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
 
-  if (THIS_AS->cached && !THIS_AS->route_cache)
-    THIS_AS->route_cache = xbt_dict_new_homogeneous(&route_cache_elem_free);
+  if (m_cached && p_routeCache)
+    p_routeCache = xbt_dict_new_homogeneous(&route_cache_elem_free);
 
   /* Add the loopback if needed */
-  if (routing_platf->loopback && as->hierarchy == SURF_ROUTING_BASE)
-    add_loopback_dijkstra(THIS_AS);
+  if (routing_platf->p_loopback && p_hierarchy == SURF_ROUTING_BASE)
+    addLoopback();
 
   /* initialize graph indexes in nodes after graph has been built */
-  nodes = xbt_graph_get_nodes(THIS_AS->route_graph);
+  nodes = xbt_graph_get_nodes(p_routeGraph);
 
   xbt_dynar_foreach(nodes, cursor2, node) {
-    graph_node_data_t data = xbt_graph_node_get_data(node);
+    graph_node_data_t data = (graph_node_data_t) xbt_graph_node_get_data(node);
     data->graph_id = cursor2;
   }
 
 }
-void model_dijkstra_both_parse_route (AS_t asg, sg_platf_route_cbarg_t route)
+
+void AsDijkstra::parseASroute(sg_platf_route_cbarg_t route)
+{
+  parseRoute(route);
+}
+
+void AsDijkstra::parseRoute(sg_platf_route_cbarg_t route)
 {
   char *src = (char*)(route->src);
   char *dst = (char*)(route->dst);
@@ -476,16 +470,15 @@ void model_dijkstra_both_parse_route (AS_t asg, sg_platf_route_cbarg_t route)
     XBT_DEBUG("Load Route from \"%s\" to \"%s\"", src, dst);
   else{
     XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
-        route->gw_src->name, dst, route->gw_dst->name);
+        route->gw_src->p_name, dst, route->gw_dst->p_name);
     as_route = 1;
-    if(route->gw_dst->rc_type == SURF_NETWORK_ELEMENT_NULL)
-      xbt_die("The gw_dst '%s' does not exist!",route->gw_dst->name);
-    if(route->gw_src->rc_type == SURF_NETWORK_ELEMENT_NULL)
-      xbt_die("The gw_src '%s' does not exist!",route->gw_src->name);
+    if(route->gw_dst->p_rcType == SURF_NETWORK_ELEMENT_NULL)
+      xbt_die("The gw_dst '%s' does not exist!",route->gw_dst->p_name);
+    if(route->gw_src->p_rcType == SURF_NETWORK_ELEMENT_NULL)
+      xbt_die("The gw_src '%s' does not exist!",route->gw_src->p_name);
   }
 
-  as_dijkstra_t as = (as_dijkstra_t) asg;
-  sg_routing_edge_t src_net_elm, dst_net_elm;
+  RoutingEdgePtr src_net_elm, dst_net_elm;
 
   src_net_elm = sg_routing_edge_by_name_or_null(src);
   dst_net_elm = sg_routing_edge_by_name_or_null(dst);
@@ -494,16 +487,16 @@ void model_dijkstra_both_parse_route (AS_t asg, sg_platf_route_cbarg_t route)
   xbt_assert(dst_net_elm, "Network elements %s not found", dst);
 
   /* Create the topology graph */
-  if(!as->route_graph)
-    as->route_graph = xbt_graph_new_graph(1, NULL);
-  if(!as->graph_node_map)
-    as->graph_node_map = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
+  if(!p_routeGraph)
+    p_routeGraph = xbt_graph_new_graph(1, NULL);
+  if(!p_graphNodeMap)
+    p_graphNodeMap = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
 
-  if (as->cached && !as->route_cache)
-    as->route_cache = xbt_dict_new_homogeneous(&route_cache_elem_free);
+  if (m_cached && !p_routeCache)
+    p_routeCache = xbt_dict_new_homogeneous(&route_cache_elem_free);
 
-  sg_platf_route_cbarg_t e_route = generic_new_extended_route(asg->hierarchy, route, 1);
-  route_new_dijkstra(as, src_net_elm->id, dst_net_elm->id, e_route);
+  sg_platf_route_cbarg_t e_route = newExtendedRoute(p_hierarchy, route, 1);
+  newRoute(src_net_elm->m_id, dst_net_elm->m_id, e_route);
 
   // Symmetrical YES
   if ( (route->symmetrical == TRUE && as_route == 0)
@@ -514,25 +507,25 @@ void model_dijkstra_both_parse_route (AS_t asg, sg_platf_route_cbarg_t route)
       XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
     else
       XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
-          route->gw_dst->name, src, route->gw_src->name);
+          route->gw_dst->p_name, src, route->gw_src->p_name);
 
-    xbt_dynar_t nodes = xbt_graph_get_nodes(as->route_graph);
-    xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_net_elm->id, xbt_node_t);
-    xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_net_elm->id, xbt_node_t);
+    xbt_dynar_t nodes = xbt_graph_get_nodes(p_routeGraph);
+    xbt_node_t node_s_v = xbt_dynar_get_as(nodes, src_net_elm->m_id, xbt_node_t);
+    xbt_node_t node_e_v = xbt_dynar_get_as(nodes, dst_net_elm->m_id, xbt_node_t);
     xbt_edge_t edge =
-        xbt_graph_get_edge(as->route_graph, node_e_v, node_s_v);
+        xbt_graph_get_edge(p_routeGraph, node_e_v, node_s_v);
 
     if (edge)
       THROWF(arg_error,0,"(AS)Route from '%s' to '%s' already exists",src,dst);
 
     if (route->gw_dst && route->gw_src) {
-      sg_routing_edge_t gw_tmp;
+      RoutingEdgePtr gw_tmp;
       gw_tmp = route->gw_src;
       route->gw_src = route->gw_dst;
       route->gw_dst = gw_tmp;
     }
-    sg_platf_route_cbarg_t link_route_back = generic_new_extended_route(asg->hierarchy, route, 0);
-    route_new_dijkstra(as, dst_net_elm->id, src_net_elm->id, link_route_back);
+    sg_platf_route_cbarg_t link_route_back = newExtendedRoute(p_hierarchy, route, 0);
+    newRoute(dst_net_elm->m_id, src_net_elm->m_id, link_route_back);
   }
   xbt_dynar_free(&route->link_list);
 }
diff --git a/src/surf/surf_routing_dijkstra.hpp b/src/surf/surf_routing_dijkstra.hpp
new file mode 100644 (file)
index 0000000..ef68386
--- /dev/null
@@ -0,0 +1,48 @@
+#include "surf_routing_generic.hpp"
+
+#ifndef SURF_ROUTING_DIJKSTRA_HPP_
+#define SURF_ROUTING_DIJKSTRA_HPP_
+
+typedef struct graph_node_data {
+  int id;
+  int graph_id;                 /* used for caching internal graph id's */
+} s_graph_node_data_t, *graph_node_data_t;
+
+typedef struct graph_node_map_element {
+  xbt_node_t node;
+} s_graph_node_map_element_t, *graph_node_map_element_t;
+
+typedef struct route_cache_element {
+  int *pred_arr;
+  int size;
+} s_route_cache_element_t, *route_cache_element_t;
+
+/***********
+ * Classes *
+ ***********/
+class AsDijkstra;
+typedef AsDijkstra *AsDijkstraPtr;
+
+class AsDijkstra : public AsGeneric {
+public:
+  AsDijkstra();
+  AsDijkstra(int cached);
+  ~AsDijkstra();
+       xbt_node_t routeGraphNewNode(int id, int graph_id);
+       graph_node_map_element_t nodeMapSearch(int id);
+       void newRoute(int src_id, int dst_id, sg_platf_route_cbarg_t e_route);
+       void addLoopback();
+       void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t route, double *lat);
+       xbt_dynar_t getOnelinkRoutes();
+       void getRouteAndLatency(sg_platf_route_cbarg_t route, double *lat);
+       void parseASroute(sg_platf_route_cbarg_t route);
+       void parseRoute(sg_platf_route_cbarg_t route);
+       void end();
+
+  xbt_graph_t p_routeGraph;      /* xbt_graph */
+  xbt_dict_t p_graphNodeMap;    /* map */
+  xbt_dict_t p_routeCache;       /* use in cache mode */
+  int m_cached;
+};
+
+#endif /* SURF_ROUTING_DIJKSTRA_HPP_ */
similarity index 56%
rename from src/surf/surf_routing_floyd.c
rename to src/surf/surf_routing_floyd.cpp
index 0c1d32a..16c2565 100644 (file)
@@ -5,31 +5,48 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "surf_routing_private.h"
+#include "surf_routing_floyd.hpp"
+#include "network.hpp"
 
-/* Global vars */
-extern routing_platf_t routing_platf;
-
+extern "C" {
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_floyd, surf, "Routing part of surf");
+}
 
-#define TO_FLOYD_COST(i,j) (as->cost_table)[(i)+(j)*table_size]
-#define TO_FLOYD_PRED(i,j) (as->predecessor_table)[(i)+(j)*table_size]
-#define TO_FLOYD_LINK(i,j) (as->link_table)[(i)+(j)*table_size]
+#define TO_FLOYD_COST(i,j) (p_costTable)[(i)+(j)*table_size]
+#define TO_FLOYD_PRED(i,j) (p_predecessorTable)[(i)+(j)*table_size]
+#define TO_FLOYD_LINK(i,j) (p_linkTable)[(i)+(j)*table_size]
 
-/* Routing model structure */
+AS_t model_floyd_create(void)
+{
+  return new AsFloyd();
+}
 
-typedef struct {
-  s_as_t generic_routing;
-  /* vars for calculate the floyd algorithm. */
-  int *predecessor_table;
-  double *cost_table;
-  sg_platf_route_cbarg_t *link_table;
-} s_as_floyd_t, *as_floyd_t;
+void model_floyd_end(AS_t current_routing)
+{
+  static_cast<AsFloydPtr>(current_routing)->end();
+}
 
-static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_routing_edge_t dst,
-    sg_platf_route_cbarg_t res, double *lat);
+AsFloyd::AsFloyd(): AsGeneric() {
+}
+
+AsFloyd::~AsFloyd(){
+  int i, j;
+  size_t table_size;
+  table_size = xbt_dynar_length(p_indexNetworkElm);
+    /* Delete link_table */
+    for (i = 0; i < table_size; i++)
+      for (j = 0; j < table_size; j++)
+        generic_free_route(TO_FLOYD_LINK(i, j));
+    xbt_free(p_linkTable);
+    /* Delete bypass dict */
+    xbt_dict_free(&p_bypassRoutes);
+    /* Delete predecessor and cost table */
+    xbt_free(p_predecessorTable);
+    xbt_free(p_costTable);
+}
 
 /* Business methods */
-static xbt_dynar_t floyd_get_onelink_routes(AS_t asg)
+xbt_dynar_t AsFloyd::getOneLinkRoutes()
 {
   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
   sg_platf_route_cbarg_t route =   xbt_new0(s_sg_platf_route_cbarg_t, 1);
@@ -37,22 +54,22 @@ static xbt_dynar_t floyd_get_onelink_routes(AS_t asg)
 
   int src,dst;
   sg_routing_edge_t src_elm, dst_elm;
-  int table_size = xbt_dynar_length(asg->index_network_elm);
+  int table_size = xbt_dynar_length(p_indexNetworkElm);
   for(src=0; src < table_size; src++) {
     for(dst=0; dst< table_size; dst++) {
       xbt_dynar_reset(route->link_list);
-      src_elm = xbt_dynar_get_as(asg->index_network_elm,src,sg_routing_edge_t);
-      dst_elm = xbt_dynar_get_as(asg->index_network_elm,dst,sg_routing_edge_t);
-      floyd_get_route_and_latency(asg, src_elm, dst_elm, route, NULL);
+      src_elm = xbt_dynar_get_as(p_indexNetworkElm, src, RoutingEdgePtr);
+      dst_elm = xbt_dynar_get_as(p_indexNetworkElm, dst, RoutingEdgePtr);
+      this->getRouteAndLatency(src_elm, dst_elm, route, NULL);
 
       if (xbt_dynar_length(route->link_list) == 1) {
         void *link = *(void **) xbt_dynar_get_ptr(route->link_list, 0);
         onelink_t onelink = xbt_new0(s_onelink_t, 1);
         onelink->link_ptr = link;
-        if (asg->hierarchy == SURF_ROUTING_BASE) {
+        if (p_hierarchy == SURF_ROUTING_BASE) {
           onelink->src = src_elm;
           onelink->dst = dst_elm;
-        } else if (asg->hierarchy == SURF_ROUTING_RECURSIVE) {
+        } else if (p_hierarchy == SURF_ROUTING_RECURSIVE) {
           onelink->src = route->gw_src;
           onelink->dst = route->gw_dst;
         }
@@ -64,29 +81,27 @@ static xbt_dynar_t floyd_get_onelink_routes(AS_t asg)
   return ret;
 }
 
-static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_routing_edge_t dst,
-    sg_platf_route_cbarg_t res, double *lat)
+void AsFloyd::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t res, double *lat)
 {
 
   /* set utils vars */
-  as_floyd_t as = (as_floyd_t)asg;
-  size_t table_size = xbt_dynar_length(asg->index_network_elm);
+  size_t table_size = xbt_dynar_length(p_indexNetworkElm);
 
-  generic_src_dst_check(asg, src, dst);
+  this->srcDstCheck(src, dst);
 
   /* create a result route */
   xbt_dynar_t route_stack = xbt_dynar_new(sizeof(sg_platf_route_cbarg_t), NULL);
   int pred;
-  int cur = dst->id;
+  int cur = dst->m_id;
   do {
-    pred = TO_FLOYD_PRED(src->id, cur);
+    pred = TO_FLOYD_PRED(src->m_id, cur);
     if (pred == -1)
-      THROWF(arg_error, 0, "No route from '%s' to '%s'", src->name, dst->name);
+      THROWF(arg_error, 0, "No route from '%s' to '%s'", src->p_name, dst->p_name);
     xbt_dynar_push_as(route_stack, sg_platf_route_cbarg_t, TO_FLOYD_LINK(pred, cur));
     cur = pred;
-  } while (cur != src->id);
+  } while (cur != src->m_id);
 
-  if (asg->hierarchy == SURF_ROUTING_RECURSIVE) {
+  if (p_hierarchy == SURF_ROUTING_RECURSIVE) {
     res->gw_src = xbt_dynar_getlast_as(route_stack, sg_platf_route_cbarg_t)->gw_src;
     res->gw_dst = xbt_dynar_getfirst_as(route_stack, sg_platf_route_cbarg_t)->gw_dst;
   }
@@ -95,11 +110,11 @@ static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_rout
   while (!xbt_dynar_is_empty(route_stack)) {
     sg_platf_route_cbarg_t e_route = xbt_dynar_pop_as(route_stack, sg_platf_route_cbarg_t);
     xbt_dynar_t links;
-    sg_routing_link_t link;
+    void *link;
     unsigned int cpt;
 
-    if (asg->hierarchy == SURF_ROUTING_RECURSIVE && prev_dst_gw != NULL
-        && strcmp(prev_dst_gw->name, e_route->gw_src->name)) {
+    if (p_hierarchy == SURF_ROUTING_RECURSIVE && prev_dst_gw != NULL
+        && strcmp(prev_dst_gw->p_name, e_route->gw_src->p_name)) {
       routing_get_route_and_latency(prev_dst_gw, e_route->gw_src,
                                     &res->link_list, lat);
     }
@@ -108,7 +123,7 @@ static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_rout
     xbt_dynar_foreach(links, cpt, link) {
       xbt_dynar_push_as(res->link_list, sg_routing_link_t, link);
       if (lat)
-        *lat += surf_network_model->extension.network.get_link_latency(link);
+        *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(link))->getLatency();
     }
 
     prev_dst_gw = e_route->gw_dst;
@@ -116,119 +131,24 @@ static void floyd_get_route_and_latency(AS_t asg, sg_routing_edge_t src, sg_rout
   xbt_dynar_free(&route_stack);
 }
 
-static void floyd_finalize(AS_t rc)
-{
-  as_floyd_t as = (as_floyd_t) rc;
-  int i, j;
-  size_t table_size;
-  if (as) {
-    table_size = xbt_dynar_length(as->generic_routing.index_network_elm);
-    /* Delete link_table */
-    for (i = 0; i < table_size; i++)
-      for (j = 0; j < table_size; j++)
-        generic_free_route(TO_FLOYD_LINK(i, j));
-    xbt_free(as->link_table);
-    /* Delete bypass dict */
-    xbt_dict_free(&as->generic_routing.bypassRoutes);
-    /* Delete predecessor and cost table */
-    xbt_free(as->predecessor_table);
-    xbt_free(as->cost_table);
-
-    model_generic_finalize(rc);
-  }
-}
-
-AS_t model_floyd_create(void)
-{
-  as_floyd_t new_component = (as_floyd_t)model_generic_create_sized(sizeof(s_as_floyd_t));
-  new_component->generic_routing.parse_route = model_floyd_parse_route;
-  new_component->generic_routing.parse_ASroute = model_floyd_parse_route;
-  new_component->generic_routing.get_route_and_latency = floyd_get_route_and_latency;
-  new_component->generic_routing.get_onelink_routes =
-      floyd_get_onelink_routes;
-  new_component->generic_routing.get_graph = generic_get_graph;
-  new_component->generic_routing.finalize = floyd_finalize;
-  return (AS_t)new_component;
-}
-
-void model_floyd_end(AS_t current_routing)
-{
-
-  as_floyd_t as =
-      ((as_floyd_t) current_routing);
-
-  unsigned int i, j, a, b, c;
-
-  /* set the size of table routing */
-  size_t table_size = xbt_dynar_length(as->generic_routing.index_network_elm);
-
-  if(!as->link_table)
-  {
-    /* Create Cost, Predecessor and Link tables */
-    as->cost_table = xbt_new0(double, table_size * table_size);       /* link cost from host to host */
-    as->predecessor_table = xbt_new0(int, table_size * table_size);  /* predecessor host numbers */
-    as->link_table = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);    /* actual link between src and dst */
-
-    /* Initialize costs and predecessors */
-    for (i = 0; i < table_size; i++)
-      for (j = 0; j < table_size; j++) {
-        TO_FLOYD_COST(i, j) = DBL_MAX;
-        TO_FLOYD_PRED(i, j) = -1;
-        TO_FLOYD_LINK(i, j) = NULL;       /* fixed, missing in the previous version */
-      }
-  }
-
-  /* Add the loopback if needed */
-  if (routing_platf->loopback && current_routing->hierarchy == SURF_ROUTING_BASE) {
-    for (i = 0; i < table_size; i++) {
-      sg_platf_route_cbarg_t e_route = TO_FLOYD_LINK(i, i);
-      if (!e_route) {
-        e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
-        e_route->gw_src = NULL;
-        e_route->gw_dst = NULL;
-        e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
-        xbt_dynar_push(e_route->link_list, &routing_platf->loopback);
-        TO_FLOYD_LINK(i, i) = e_route;
-        TO_FLOYD_PRED(i, i) = i;
-        TO_FLOYD_COST(i, i) = 1;
-      }
-    }
-  }
-  /* Calculate path costs */
-  for (c = 0; c < table_size; c++) {
-    for (a = 0; a < table_size; a++) {
-      for (b = 0; b < table_size; b++) {
-        if (TO_FLOYD_COST(a, c) < DBL_MAX && TO_FLOYD_COST(c, b) < DBL_MAX) {
-          if (TO_FLOYD_COST(a, b) == DBL_MAX ||
-              (TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b) <
-                  TO_FLOYD_COST(a, b))) {
-            TO_FLOYD_COST(a, b) =
-                TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b);
-            TO_FLOYD_PRED(a, b) = TO_FLOYD_PRED(c, b);
-          }
-        }
-      }
-    }
-  }
-}
-
 static int floyd_pointer_resource_cmp(const void *a, const void *b) {
   return a != b;
 }
 
-//FIXME: kill dupplicates in next function with full routing
+void AsFloyd::parseASroute(sg_platf_route_cbarg_t route){
+  parseRoute(route);
+}
 
-void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route)
+void AsFloyd::parseRoute(sg_platf_route_cbarg_t route)
 {
   char *src = (char*)(route->src);
   char *dst = (char*)(route->dst);
 
   int as_route = 0;
-  as_floyd_t as = (as_floyd_t) rc;
 
   /* set the size of table routing */
-  size_t table_size = xbt_dynar_length(rc->index_network_elm);
-  sg_routing_edge_t src_net_elm, dst_net_elm;
+  size_t table_size = xbt_dynar_length(p_indexNetworkElm);
+  RoutingEdgePtr src_net_elm, dst_net_elm;
 
   src_net_elm = sg_routing_edge_by_name_or_null(src);
   dst_net_elm = sg_routing_edge_by_name_or_null(dst);
@@ -236,13 +156,13 @@ void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route)
   xbt_assert(src_net_elm, "Network elements %s not found", src);
   xbt_assert(dst_net_elm, "Network elements %s not found", dst);
 
-  if(!as->link_table)
+  if(!p_linkTable)
   {
     int i,j;
     /* Create Cost, Predecessor and Link tables */
-    as->cost_table = xbt_new0(double, table_size * table_size);       /* link cost from host to host */
-    as->predecessor_table = xbt_new0(int, table_size * table_size);  /* predecessor host numbers */
-    as->link_table = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);    /* actual link between src and dst */
+    p_costTable = xbt_new0(double, table_size * table_size);       /* link cost from host to host */
+    p_predecessorTable = xbt_new0(int, table_size * table_size);  /* predecessor host numbers */
+    p_linkTable = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);    /* actual link between src and dst */
 
     /* Initialize costs and predecessors */
     for (i = 0; i < table_size; i++)
@@ -257,14 +177,14 @@ void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route)
   else{
     as_route = 1;
     XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", src,
-        route->gw_src->name, dst, route->gw_dst->name);
-    if(route->gw_dst->rc_type == SURF_NETWORK_ELEMENT_NULL)
-      xbt_die("The dst_gateway '%s' does not exist!",route->gw_dst->name);
-    if(route->gw_src->rc_type == SURF_NETWORK_ELEMENT_NULL)
-      xbt_die("The src_gateway '%s' does not exist!",route->gw_src->name);
+        route->gw_src->p_name, dst, route->gw_dst->p_name);
+    if(route->gw_dst->p_rcType == SURF_NETWORK_ELEMENT_NULL)
+      xbt_die("The dst_gateway '%s' does not exist!",route->gw_dst->p_name);
+    if(route->gw_src->p_rcType == SURF_NETWORK_ELEMENT_NULL)
+      xbt_die("The src_gateway '%s' does not exist!",route->gw_src->p_name);
   }
 
-  if(TO_FLOYD_LINK(src_net_elm->id, dst_net_elm->id))
+  if(TO_FLOYD_LINK(src_net_elm->m_id, dst_net_elm->m_id))
   {
 
     char * link_name;
@@ -277,44 +197,44 @@ void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route)
       xbt_dynar_push(link_route_to_test,&link);
     }
     xbt_assert(!xbt_dynar_compare(
-        (void*)TO_FLOYD_LINK(src_net_elm->id, dst_net_elm->id)->link_list,
-        (void*)link_route_to_test,
+        TO_FLOYD_LINK(src_net_elm->m_id, dst_net_elm->m_id)->link_list,
+        link_route_to_test,
         (int_f_cpvoid_cpvoid_t) floyd_pointer_resource_cmp),
         "The route between \"%s\" and \"%s\" already exists", src,dst);
   }
   else
   {
-    TO_FLOYD_LINK(src_net_elm->id, dst_net_elm->id) =
-        generic_new_extended_route(rc->hierarchy, route, 1);
-    TO_FLOYD_PRED(src_net_elm->id, dst_net_elm->id) = src_net_elm->id;
-    TO_FLOYD_COST(src_net_elm->id, dst_net_elm->id) =
-        ((TO_FLOYD_LINK(src_net_elm->id, dst_net_elm->id))->link_list)->used;   /* count of links, old model assume 1 */
+    TO_FLOYD_LINK(src_net_elm->m_id, dst_net_elm->m_id) =
+        newExtendedRoute(p_hierarchy, route, 1);
+    TO_FLOYD_PRED(src_net_elm->m_id, dst_net_elm->m_id) = src_net_elm->m_id;
+    TO_FLOYD_COST(src_net_elm->m_id, dst_net_elm->m_id) =
+        ((TO_FLOYD_LINK(src_net_elm->m_id, dst_net_elm->m_id))->link_list)->used;   /* count of links, old model assume 1 */
   }
 
   if ( (route->symmetrical == TRUE && as_route == 0)
       || (route->symmetrical == TRUE && as_route == 1)
   )
   {
-    if(TO_FLOYD_LINK(dst_net_elm->id, src_net_elm->id))
+    if(TO_FLOYD_LINK(dst_net_elm->m_id, src_net_elm->m_id))
     {
       if(!route->gw_dst && !route->gw_src)
         XBT_DEBUG("See Route from \"%s\" to \"%s\"", dst, src);
       else
         XBT_DEBUG("See ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
-            route->gw_src->name, src, route->gw_dst->name);
+            route->gw_src->p_name, src, route->gw_dst->p_name);
       char * link_name;
       unsigned int i;
       xbt_dynar_t link_route_to_test = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
       for(i=xbt_dynar_length(route->link_list) ;i>0 ;i--)
       {
-        link_name = xbt_dynar_get_as(route->link_list,i-1,void *);
+        link_name = xbt_dynar_get_as(route->link_list,i-1,char *);
         void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
         xbt_assert(link,"Link : '%s' doesn't exists.",link_name);
         xbt_dynar_push(link_route_to_test,&link);
       }
       xbt_assert(!xbt_dynar_compare(
-          (void*)TO_FLOYD_LINK(dst_net_elm->id, src_net_elm->id)->link_list,
-          (void*)link_route_to_test,
+          TO_FLOYD_LINK(dst_net_elm->m_id, src_net_elm->m_id)->link_list,
+          link_route_to_test,
           (int_f_cpvoid_cpvoid_t) floyd_pointer_resource_cmp),
           "The route between \"%s\" and \"%s\" already exists", src,dst);
     }
@@ -332,14 +252,69 @@ void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route)
         XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
       else
         XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"", dst,
-            route->gw_src->name, src, route->gw_dst->name);
+            route->gw_src->p_name, src, route->gw_dst->p_name);
 
-      TO_FLOYD_LINK(dst_net_elm->id, src_net_elm->id) =
-          generic_new_extended_route(rc->hierarchy, route, 0);
-      TO_FLOYD_PRED(dst_net_elm->id, src_net_elm->id) = dst_net_elm->id;
-      TO_FLOYD_COST(dst_net_elm->id, src_net_elm->id) =
-          ((TO_FLOYD_LINK(dst_net_elm->id, src_net_elm->id))->link_list)->used;   /* count of links, old model assume 1 */
+      TO_FLOYD_LINK(dst_net_elm->m_id, src_net_elm->m_id) =
+                newExtendedRoute(p_hierarchy, route, 0);
+      TO_FLOYD_PRED(dst_net_elm->m_id, src_net_elm->m_id) = dst_net_elm->m_id;
+      TO_FLOYD_COST(dst_net_elm->m_id, src_net_elm->m_id) =
+          ((TO_FLOYD_LINK(dst_net_elm->m_id, src_net_elm->m_id))->link_list)->used;   /* count of links, old model assume 1 */
     }
   }
   xbt_dynar_free(&route->link_list);
 }
+
+void AsFloyd::end(){
+  unsigned int i, j, a, b, c;
+
+  /* set the size of table routing */
+  size_t table_size = xbt_dynar_length(p_indexNetworkElm);
+
+  if(!p_linkTable) {
+    /* Create Cost, Predecessor and Link tables */
+    p_costTable = xbt_new0(double, table_size * table_size);       /* link cost from host to host */
+    p_predecessorTable = xbt_new0(int, table_size * table_size);  /* predecessor host numbers */
+    p_linkTable = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);    /* actual link between src and dst */
+
+    /* Initialize costs and predecessors */
+    for (i = 0; i < table_size; i++)
+      for (j = 0; j < table_size; j++) {
+        TO_FLOYD_COST(i, j) = DBL_MAX;
+        TO_FLOYD_PRED(i, j) = -1;
+        TO_FLOYD_LINK(i, j) = NULL;       /* fixed, missing in the previous version */
+      }
+  }
+
+  /* Add the loopback if needed */
+  if (routing_platf->p_loopback && p_hierarchy == SURF_ROUTING_BASE) {
+    for (i = 0; i < table_size; i++) {
+      sg_platf_route_cbarg_t e_route = TO_FLOYD_LINK(i, i);
+      if (!e_route) {
+        e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+        e_route->gw_src = NULL;
+        e_route->gw_dst = NULL;
+        e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
+        xbt_dynar_push(e_route->link_list, &routing_platf->p_loopback);
+        TO_FLOYD_LINK(i, i) = e_route;
+        TO_FLOYD_PRED(i, i) = i;
+        TO_FLOYD_COST(i, i) = 1;
+      }
+    }
+  }
+  /* Calculate path costs */
+  for (c = 0; c < table_size; c++) {
+    for (a = 0; a < table_size; a++) {
+      for (b = 0; b < table_size; b++) {
+        if (TO_FLOYD_COST(a, c) < DBL_MAX && TO_FLOYD_COST(c, b) < DBL_MAX) {
+          if (TO_FLOYD_COST(a, b) == DBL_MAX ||
+              (TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b) <
+                  TO_FLOYD_COST(a, b))) {
+            TO_FLOYD_COST(a, b) =
+                TO_FLOYD_COST(a, c) + TO_FLOYD_COST(c, b);
+            TO_FLOYD_PRED(a, b) = TO_FLOYD_PRED(c, b);
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/src/surf/surf_routing_floyd.hpp b/src/surf/surf_routing_floyd.hpp
new file mode 100644 (file)
index 0000000..56b6805
--- /dev/null
@@ -0,0 +1,45 @@
+#include "surf_routing_generic.hpp"
+
+#ifndef SURF_ROUTING_FLOYD_HPP_
+#define SURF_ROUTING_FLOYD_HPP_
+
+
+/***********
+ * Classes *
+ ***********/
+class AsFloyd;
+typedef AsFloyd *AsFloydPtr;
+
+class AsFloyd: public AsGeneric {
+public:
+  AsFloyd();
+  ~AsFloyd();
+
+  void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
+  xbt_dynar_t getOneLinkRoutes();
+  void parseASroute(sg_platf_route_cbarg_t route);
+  void parseRoute(sg_platf_route_cbarg_t route);
+  void end();
+  //void parseASroute(sg_platf_route_cbarg_t route);
+
+  //void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+  //sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+
+  /* The parser calls the following functions to inform the routing models
+   * that a new element is added to the AS currently built.
+   *
+   * Of course, only the routing model of this AS is informed, not every ones */
+  //int parsePU(RoutingEdgePtr elm); /* A host or a router, whatever */
+  //int parseAS(RoutingEdgePtr elm);
+
+  //virtual void parseBypassroute(sg_platf_route_cbarg_t e_route)=0;
+
+  /* vars for calculate the floyd algorith. */
+  int *p_predecessorTable;
+  double *p_costTable;
+  sg_platf_route_cbarg_t *p_linkTable;
+};
+
+
+
+#endif /* SURF_ROUTING_FLOYD_HPP_ */
similarity index 59%
rename from src/surf/surf_routing_full.c
rename to src/surf/surf_routing_full.cpp
index 89e305f..f0767dc 100644 (file)
@@ -5,45 +5,88 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "surf_routing_private.h"
+#include "surf_routing_full.hpp"
+#include "network.hpp"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_full, surf, "Routing part of surf");
+}
 
 /* Global vars */
 extern routing_platf_t routing_platf;
 extern int surf_parse_lineno;
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_full, surf, "Routing part of surf");
+#define TO_ROUTE_FULL(i,j) p_routingTable[(i)+(j)*table_size]
 
-#define TO_ROUTE_FULL(i,j) routing->routing_table[(i)+(j)*table_size]
+AS_t model_full_create(void)
+{
+  return new AsFull();
+}
 
-/* Routing model structure */
+void model_full_end(AS_t _routing)
+{
+  unsigned int i;
+  sg_platf_route_cbarg_t e_route;
+
+  /* set utils vars */
+  AsFullPtr routing = ((AsFullPtr) _routing);
+  size_t table_size = xbt_dynar_length(routing->p_indexNetworkElm);
 
-typedef struct s_routing_component_full {
-  s_as_t generic_routing;
-  sg_platf_route_cbarg_t *routing_table;
-} s_routing_component_full_t, *routing_component_full_t;
+  /* Create table if necessary */
+  if (!routing->p_routingTable)
+    routing->p_routingTable = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);
 
-/* Business methods */
-static xbt_dynar_t full_get_onelink_routes(AS_t rc)
+  /* Add the loopback if needed */
+  if (routing_platf->p_loopback && routing->p_hierarchy == SURF_ROUTING_BASE) {
+    for (i = 0; i < table_size; i++) {
+      e_route = routing->TO_ROUTE_FULL(i, i);
+      if (!e_route) {
+        e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
+        e_route->gw_src = NULL;
+        e_route->gw_dst = NULL;
+        e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
+        xbt_dynar_push(e_route->link_list, &routing_platf->p_loopback);
+        routing->TO_ROUTE_FULL(i, i) = e_route;
+      }
+    }
+  }
+}
+
+AsFull::AsFull(){
+  p_routingTable = 0;
+}
+
+AsFull::~AsFull(){
+  size_t table_size = xbt_dynar_length(p_indexNetworkElm);
+  int i, j;
+  /* Delete routing table */
+  for (i = 0; i < table_size; i++)
+    for (j = 0; j < table_size; j++)
+      delete TO_ROUTE_FULL(i,j);
+  xbt_free(p_routingTable);
+}
+
+xbt_dynar_t AsFull::getOneLinkRoutes()
 {
   xbt_dynar_t ret = xbt_dynar_new(sizeof(onelink_t), xbt_free);
-  routing_component_full_t routing = (routing_component_full_t) rc;
 
-  int src,dst;
-  int table_size = xbt_dynar_length(rc->index_network_elm);
+  int src, dst;
+  int table_size = xbt_dynar_length(p_indexNetworkElm);
 
   for(src=0; src < table_size; src++) {
     for(dst=0; dst< table_size; dst++) {
-      sg_platf_route_cbarg_t route = TO_ROUTE_FULL(src, dst);
+      sg_platf_route_cbarg_t route = TO_ROUTE_FULL(src,dst);
       if (route) {
         if (xbt_dynar_length(route->link_list) == 1) {
           void *link = *(void **) xbt_dynar_get_ptr(route->link_list, 0);
           onelink_t onelink = xbt_new0(s_onelink_t, 1);
           onelink->link_ptr = link;
-          if (rc->hierarchy == SURF_ROUTING_BASE) {
-            onelink->src = xbt_dynar_get_as(rc->index_network_elm,src,sg_routing_edge_t);
-            onelink->src->id = src;
-            onelink->dst = xbt_dynar_get_as(rc->index_network_elm,dst,sg_routing_edge_t);
-            onelink->dst->id = dst;
-          } else if (rc->hierarchy == SURF_ROUTING_RECURSIVE) {
+          if (p_hierarchy == SURF_ROUTING_BASE) {
+            onelink->src = xbt_dynar_get_as(p_indexNetworkElm, src, sg_routing_edge_t);
+            onelink->src->m_id = src;
+            onelink->dst = xbt_dynar_get_as(p_indexNetworkElm, dst, sg_routing_edge_t);
+            onelink->dst->m_id = dst;
+          } else if (p_hierarchy == SURF_ROUTING_RECURSIVE) {
             onelink->src = route->gw_src;
             onelink->dst = route->gw_dst;
           }
@@ -58,25 +101,22 @@ static xbt_dynar_t full_get_onelink_routes(AS_t rc)
   return ret;
 }
 
-static void full_get_route_and_latency(AS_t rc,
-    sg_routing_edge_t src, sg_routing_edge_t dst,
-    sg_platf_route_cbarg_t res, double *lat)
+void AsFull::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t res, double *lat)
 {
   XBT_DEBUG("full_get_route_and_latency from %s[%d] to %s[%d]",
-      src->name,
-      src->id,
-      dst->name,
-      dst->id  );
+      src->p_name,
+      src->m_id,
+      dst->p_name,
+      dst->m_id  );
 
   /* set utils vars */
-  routing_component_full_t routing = (routing_component_full_t) rc;
-  size_t table_size = xbt_dynar_length(routing->generic_routing.index_network_elm);
+  size_t table_size = xbt_dynar_length(p_indexNetworkElm);
 
   sg_platf_route_cbarg_t e_route = NULL;
   void *link;
   unsigned int cpt = 0;
 
-  e_route = TO_ROUTE_FULL(src->id, dst->id);
+  e_route = TO_ROUTE_FULL(src->m_id, dst->m_id);
 
   if (e_route) {
     res->gw_src = e_route->gw_src;
@@ -84,73 +124,13 @@ static void full_get_route_and_latency(AS_t rc,
     xbt_dynar_foreach(e_route->link_list, cpt, link) {
       xbt_dynar_push(res->link_list, &link);
       if (lat)
-        *lat += surf_network_model->extension.network.get_link_latency(link);
+        *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(link))->getLatency();
     }
   }
 }
 
-static void full_finalize(AS_t rc)
-{
-  routing_component_full_t routing = (routing_component_full_t) rc;
-  size_t table_size = xbt_dynar_length(routing->generic_routing.index_network_elm);
-  int i, j;
-  if (routing) {
-    /* Delete routing table */
-    for (i = 0; i < table_size; i++)
-      for (j = 0; j < table_size; j++)
-        generic_free_route(TO_ROUTE_FULL(i, j));
-    xbt_free(routing->routing_table);
-    model_generic_finalize(rc);
-  }
-}
-
-/* Creation routing model functions */
-
-AS_t model_full_create(void)
-{
-  routing_component_full_t new_component = (routing_component_full_t)
-          model_generic_create_sized(sizeof(s_routing_component_full_t));
-
-  new_component->generic_routing.parse_route = model_full_set_route;
-  new_component->generic_routing.parse_ASroute = model_full_set_route;
-  new_component->generic_routing.get_route_and_latency =
-      full_get_route_and_latency;
-  new_component->generic_routing.get_graph = generic_get_graph;
-
-  new_component->generic_routing.get_onelink_routes = full_get_onelink_routes;
-  new_component->generic_routing.finalize = full_finalize;
-
-  return (AS_t) new_component;
-}
-
-void model_full_end(AS_t current_routing)
-{
-  unsigned int i;
-  sg_platf_route_cbarg_t e_route;
-
-  /* set utils vars */
-  routing_component_full_t routing =
-      ((routing_component_full_t) current_routing);
-  size_t table_size = xbt_dynar_length(routing->generic_routing.index_network_elm);
-
-  /* Create table if necessary */
-  if (!routing->routing_table)
-    routing->routing_table = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);
-
-  /* Add the loopback if needed */
-  if (routing_platf->loopback && current_routing->hierarchy == SURF_ROUTING_BASE) {
-    for (i = 0; i < table_size; i++) {
-      e_route = TO_ROUTE_FULL(i, i);
-      if (!e_route) {
-        e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
-        e_route->gw_src = NULL;
-        e_route->gw_dst = NULL;
-        e_route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
-        xbt_dynar_push(e_route->link_list, &routing_platf->loopback);
-        TO_ROUTE_FULL(i, i) = e_route;
-      }
-    }
-  }
+void AsFull::parseASroute(sg_platf_route_cbarg_t route){
+  parseRoute(route);
 }
 
 static int full_pointer_resource_cmp(const void *a, const void *b)
@@ -158,29 +138,28 @@ static int full_pointer_resource_cmp(const void *a, const void *b)
   return a != b;
 }
 
-void model_full_set_route(AS_t rc, sg_platf_route_cbarg_t route)
+void AsFull::parseRoute(sg_platf_route_cbarg_t route)
 {
   int as_route = 0;
   char *src = (char*)(route->src);
   char *dst = (char*)(route->dst);
-  sg_routing_edge_t src_net_elm, dst_net_elm;
+  RoutingEdgePtr src_net_elm, dst_net_elm;
   src_net_elm = sg_routing_edge_by_name_or_null(src);
   dst_net_elm = sg_routing_edge_by_name_or_null(dst);
 
   xbt_assert(src_net_elm, "Network elements %s not found", src);
   xbt_assert(dst_net_elm, "Network elements %s not found", dst);
 
-  routing_component_full_t routing = (routing_component_full_t) rc;
-  size_t table_size = xbt_dynar_length(routing->generic_routing.index_network_elm);
+  size_t table_size = xbt_dynar_length(p_indexNetworkElm);
 
   xbt_assert(!xbt_dynar_is_empty(route->link_list),
       "Invalid count of links, must be greater than zero (%s,%s)",
       src, dst);
 
-  if (!routing->routing_table)
-    routing->routing_table = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);
+  if (!p_routingTable)
+    p_routingTable = xbt_new0(sg_platf_route_cbarg_t, table_size * table_size);
 
-  if (TO_ROUTE_FULL(src_net_elm->id, dst_net_elm->id)) {
+  if (TO_ROUTE_FULL(src_net_elm->m_id, dst_net_elm->m_id)) {
     char *link_name;
     unsigned int i;
     xbt_dynar_t link_route_to_test =
@@ -190,7 +169,7 @@ void model_full_set_route(AS_t rc, sg_platf_route_cbarg_t route)
       xbt_assert(link, "Link : '%s' doesn't exists.", link_name);
       xbt_dynar_push(link_route_to_test, &link);
     }
-    if (xbt_dynar_compare(TO_ROUTE_FULL(src_net_elm->id, dst_net_elm->id)->link_list,
+    if (xbt_dynar_compare(TO_ROUTE_FULL(src_net_elm->m_id, dst_net_elm->m_id)->link_list,
         link_route_to_test, full_pointer_resource_cmp)) {
       surf_parse_error("A route between \"%s\" and \"%s\" already exists "
           "with a different content. "
@@ -233,15 +212,14 @@ void model_full_set_route(AS_t rc, sg_platf_route_cbarg_t route)
       //                         route->dst_gateway, subas->name);
       as_route = 1;
       XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"",
-          src, route->gw_src->name, dst, route->gw_dst->name);
-      if (route->gw_dst->rc_type == SURF_NETWORK_ELEMENT_NULL)
-        xbt_die("The dst_gateway '%s' does not exist!", route->gw_dst->name);
-      if (route->gw_src->rc_type == SURF_NETWORK_ELEMENT_NULL)
-        xbt_die("The src_gateway '%s' does not exist!", route->gw_src->name);
+          src, route->gw_src->p_name, dst, route->gw_dst->p_name);
+      if (route->gw_dst->p_rcType == SURF_NETWORK_ELEMENT_NULL)
+        xbt_die("The dst_gateway '%s' does not exist!", route->gw_dst->p_name);
+      if (route->gw_src->p_rcType == SURF_NETWORK_ELEMENT_NULL)
+        xbt_die("The src_gateway '%s' does not exist!", route->gw_src->p_name);
     }
-    TO_ROUTE_FULL(src_net_elm->id, dst_net_elm->id) =
-        generic_new_extended_route(rc->hierarchy, route, 1);
-    xbt_dynar_shrink(TO_ROUTE_FULL(src_net_elm->id, dst_net_elm->id)->link_list, 0);
+    TO_ROUTE_FULL(src_net_elm->m_id, dst_net_elm->m_id) = newExtendedRoute(p_hierarchy, route, 1);
+    xbt_dynar_shrink(TO_ROUTE_FULL(src_net_elm->m_id, dst_net_elm->m_id)->link_list, 0);
   }
 
   if ( (route->symmetrical == TRUE && as_route == 0)
@@ -253,18 +231,18 @@ void model_full_set_route(AS_t rc, sg_platf_route_cbarg_t route)
       route->gw_src = route->gw_dst;
       route->gw_dst = gw_tmp;
     }
-    if (TO_ROUTE_FULL(dst_net_elm->id, src_net_elm->id)) {
+    if (TO_ROUTE_FULL(dst_net_elm->m_id, src_net_elm->m_id)) {
       char *link_name;
       unsigned int i;
       xbt_dynar_t link_route_to_test =
           xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
       for (i = xbt_dynar_length(route->link_list); i > 0; i--) {
-        link_name = xbt_dynar_get_as(route->link_list, i - 1, void *);
+        link_name = xbt_dynar_get_as(route->link_list, i - 1, char *);
         void *link = xbt_lib_get_or_null(link_lib, link_name, SURF_LINK_LEVEL);
         xbt_assert(link, "Link : '%s' doesn't exists.", link_name);
         xbt_dynar_push(link_route_to_test, &link);
       }
-      xbt_assert(!xbt_dynar_compare(TO_ROUTE_FULL(dst_net_elm->id, src_net_elm->id)->link_list,
+      xbt_assert(!xbt_dynar_compare(TO_ROUTE_FULL(dst_net_elm->m_id, src_net_elm->m_id)->link_list,
           link_route_to_test,
           full_pointer_resource_cmp),
           "The route between \"%s\" and \"%s\" already exists", src,
@@ -274,11 +252,14 @@ void model_full_set_route(AS_t rc, sg_platf_route_cbarg_t route)
         XBT_DEBUG("Load Route from \"%s\" to \"%s\"", dst, src);
       else
         XBT_DEBUG("Load ASroute from \"%s(%s)\" to \"%s(%s)\"",
-            dst, route->gw_src->name, src, route->gw_dst->name);
-      TO_ROUTE_FULL(dst_net_elm->id, src_net_elm->id) =
-          generic_new_extended_route(rc->hierarchy, route, 0);
-      xbt_dynar_shrink(TO_ROUTE_FULL(dst_net_elm->id, src_net_elm->id)->link_list, 0);
+            dst, route->gw_src->p_name, src, route->gw_dst->p_name);
+      TO_ROUTE_FULL(dst_net_elm->m_id, src_net_elm->m_id) = newExtendedRoute(p_hierarchy, route, 0);
+      xbt_dynar_shrink(TO_ROUTE_FULL(dst_net_elm->m_id, src_net_elm->m_id)->link_list, 0);
     }
   }
   xbt_dynar_free(&route->link_list);
 }
+
+
+
+
diff --git a/src/surf/surf_routing_full.hpp b/src/surf/surf_routing_full.hpp
new file mode 100644 (file)
index 0000000..e3500c7
--- /dev/null
@@ -0,0 +1,38 @@
+#include "surf_routing_generic.hpp"
+
+#ifndef SURF_ROUTING_FULL_HPP_
+#define SURF_ROUTING_FULL_HPP_
+
+/***********
+ * Classes *
+ ***********/
+class AsFull;
+typedef AsFull *AsFullPtr;
+
+class AsFull: public AsGeneric {
+public:
+  sg_platf_route_cbarg_t *p_routingTable;
+
+  AsFull();
+  ~AsFull();
+
+  void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
+  xbt_dynar_t getOneLinkRoutes();
+  void parseRoute(sg_platf_route_cbarg_t route);
+  void parseASroute(sg_platf_route_cbarg_t route);
+
+  //void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+  //sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+
+  /* The parser calls the following functions to inform the routing models
+   * that a new element is added to the AS currently built.
+   *
+   * Of course, only the routing model of this AS is informed, not every ones */
+  //virtual int parsePU(RoutingEdgePtr elm)=0; /* A host or a router, whatever */
+  //virtual int parseAS( RoutingEdgePtr elm)=0;
+
+  //virtual void parseBypassroute(sg_platf_route_cbarg_t e_route)=0;
+};
+
+
+#endif /* SURF_ROUTING_FULL_HPP_ */
similarity index 57%
rename from src/surf/surf_routing_generic.c
rename to src/surf/surf_routing_generic.cpp
index 9c0d4f9..d78421c 100644 (file)
@@ -6,52 +6,59 @@
 
 #include "simgrid/platf_interface.h"    // platform creation API internal interface
 
-#include "surf_routing_private.h"
-#include "surf/surf_routing.h"
-#include "surf/surfxml_parse_values.h"
+#include "surf_routing_generic.hpp"
+#include "network.hpp"
 #include "xbt/graph.h"
 
+extern "C" {
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_routing_generic, surf_route, "Generic implementation of the surf routing");
+}
 
 static int no_bypassroute_declared = 1;
 
-AS_t model_generic_create_sized(size_t childsize) {
-  AS_t new_component = model_none_create_sized(childsize);
-
-  new_component->parse_PU = generic_parse_PU;
-  new_component->parse_AS = generic_parse_AS;
-  new_component->parse_route = NULL;
-  new_component->parse_ASroute = NULL;
-  new_component->parse_bypassroute = generic_parse_bypassroute;
-  new_component->get_route_and_latency = NULL;
-  new_component->get_onelink_routes = NULL;
-  new_component->get_bypass_route =
-      generic_get_bypassroute;
-  new_component->finalize = model_generic_finalize;
-  new_component->bypassRoutes = xbt_dict_new_homogeneous((void (*)(void *)) generic_free_route);
-
-  return new_component;
+void generic_free_route(sg_platf_route_cbarg_t route)
+{
+  if (route) {
+    xbt_dynar_free(&route->link_list);
+    xbt_free(route);
+  }
+}
+
+void AsGeneric::parseRoute(sg_platf_route_cbarg_t route){
+  THROW_IMPOSSIBLE;
+}
+
+void AsGeneric::parseASroute(sg_platf_route_cbarg_t route){
+  THROW_IMPOSSIBLE;
+}
+
+void AsGeneric::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency){
+  THROW_IMPOSSIBLE;
+}
+
+AsGeneric::AsGeneric() {
+  p_bypassRoutes = xbt_dict_new_homogeneous((void (*)(void *)) generic_free_route);
 }
-void model_generic_finalize(AS_t as) {
-  xbt_dict_free(&as->bypassRoutes);
-  model_none_finalize(as);
+
+AsGeneric::~AsGeneric() {
+  xbt_dict_free(&p_bypassRoutes);
 }
 
-int generic_parse_PU(AS_t as, sg_routing_edge_t elm)
+int AsGeneric::parsePU(RoutingEdgePtr elm)
 {
-  XBT_DEBUG("Load process unit \"%s\"", elm->name);
-  xbt_dynar_push_as(as->index_network_elm,sg_routing_edge_t,elm);
-  return xbt_dynar_length(as->index_network_elm)-1;
+  XBT_DEBUG("Load process unit \"%s\"", elm->p_name);
+  xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+  return xbt_dynar_length(p_indexNetworkElm)-1;
 }
 
-int generic_parse_AS(AS_t as, sg_routing_edge_t elm)
+int AsGeneric::parseAS(RoutingEdgePtr elm)
 {
-  XBT_DEBUG("Load Autonomous system \"%s\"", elm->name);
-  xbt_dynar_push_as(as->index_network_elm,sg_routing_edge_t,elm);
-  return xbt_dynar_length(as->index_network_elm)-1;
+  XBT_DEBUG("Load Autonomous system \"%s\"", elm->p_name);
+  xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+  return xbt_dynar_length(p_indexNetworkElm)-1;
 }
 
-void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route)
+void AsGeneric::parseBypassroute(sg_platf_route_cbarg_t e_route)
 {
   char *src = (char*)(e_route->src);
   char *dst = (char*)(e_route->dst);
@@ -60,7 +67,7 @@ void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route)
     XBT_DEBUG("Load bypassASroute from \"%s\" to \"%s\"", src, dst);
   else
     XBT_DEBUG("Load bypassRoute from \"%s\" to \"%s\"", src, dst);
-  xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
+  xbt_dict_t dict_bypassRoutes = p_bypassRoutes;
   char *route_name;
 
   route_name = bprintf("%s#%s", src, dst);
@@ -69,13 +76,13 @@ void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route)
       src, dst);
   xbt_assert(!xbt_dict_get_or_null(dict_bypassRoutes, route_name),
       "The bypass route between \"%s\"(\"%s\") and \"%s\"(\"%s\") already exists",
-      src, e_route->gw_src->name, dst, e_route->gw_dst->name);
+      src, e_route->gw_src->p_name, dst, e_route->gw_dst->p_name);
 
   sg_platf_route_cbarg_t new_e_route = NULL;
   if(e_route->gw_dst)
-    new_e_route =  generic_new_extended_route(SURF_ROUTING_RECURSIVE, e_route, 1);
+    new_e_route =  newExtendedRoute(SURF_ROUTING_RECURSIVE, e_route, 1);
   else
-    new_e_route =  generic_new_extended_route(SURF_ROUTING_BASE, e_route, 1);
+    new_e_route =  newExtendedRoute(SURF_ROUTING_BASE, e_route, 1);
 
   xbt_dynar_free(&(e_route->link_list));
 
@@ -87,7 +94,7 @@ void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route)
 /* ************************************************************************** */
 /* *********************** GENERIC BUSINESS METHODS ************************* */
 
-xbt_dynar_t generic_get_onelink_routes(AS_t rc) { // FIXME: kill that stub
+xbt_dynar_t AsGeneric::getOneLinkRoutes() { // FIXME: kill that stub
   xbt_die("\"generic_get_onelink_routes\" not implemented yet");
   return NULL;
 }
@@ -102,7 +109,7 @@ static const char *instr_node_name(xbt_node_t node)
 xbt_node_t new_xbt_graph_node(xbt_graph_t graph, const char *name,
                               xbt_dict_t nodes)
 {
-  xbt_node_t ret = xbt_dict_get_or_null(nodes, name);
+  xbt_node_t ret = (xbt_node_t) xbt_dict_get_or_null(nodes, name);
   if (ret)
     return ret;
 
@@ -123,10 +130,10 @@ xbt_edge_t new_xbt_graph_edge(xbt_graph_t graph, xbt_node_t s, xbt_node_t d,
 
 
   snprintf(name, len, "%s%s", sn, dn);
-  ret = xbt_dict_get_or_null(edges, name);
+  ret = (xbt_edge_t) xbt_dict_get_or_null(edges, name);
   if (ret == NULL) {
     snprintf(name, len, "%s%s", dn, sn);
-    ret = xbt_dict_get_or_null(edges, name);
+    ret = (xbt_edge_t) xbt_dict_get_or_null(edges, name);
   }
 
   if (ret == NULL) {
@@ -137,28 +144,27 @@ xbt_edge_t new_xbt_graph_edge(xbt_graph_t graph, xbt_node_t s, xbt_node_t d,
   return ret;
 }
 
-void generic_get_graph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges,
-                       AS_t rc)
+void AsGeneric::getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges)
 {
   int src, dst;
-  int table_size = xbt_dynar_length(rc->index_network_elm);
+  int table_size = xbt_dynar_length(p_indexNetworkElm);
 
 
   for (src = 0; src < table_size; src++) {
-    sg_routing_edge_t my_src =
-        xbt_dynar_get_as(rc->index_network_elm, src, sg_routing_edge_t);
+    RoutingEdgePtr my_src =
+        xbt_dynar_get_as(p_indexNetworkElm, src, RoutingEdgePtr);
     for (dst = 0; dst < table_size; dst++) {
       if (src == dst)
         continue;
-      sg_routing_edge_t my_dst =
-          xbt_dynar_get_as(rc->index_network_elm, dst, sg_routing_edge_t);
+      RoutingEdgePtr my_dst =
+          xbt_dynar_get_as(p_indexNetworkElm, dst, RoutingEdgePtr);
 
       sg_platf_route_cbarg_t route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
       route->link_list = xbt_dynar_new(sizeof(sg_routing_link_t), NULL);
 
-      rc->get_route_and_latency(rc, my_src, my_dst, route, NULL);
+      getRouteAndLatency(my_src, my_dst, route, NULL);
 
-      XBT_DEBUG ("get_route_and_latency %s -> %s", my_src->name, my_dst->name);
+      XBT_DEBUG ("get_route_and_latency %s -> %s", my_src->p_name, my_dst->p_name);
 
       unsigned int cpt;
       void *link;
@@ -167,15 +173,15 @@ void generic_get_graph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges,
       const char *previous_name, *current_name;
 
       if (route->gw_src) {
-        previous = new_xbt_graph_node(graph, route->gw_src->name, nodes);
-        previous_name = route->gw_src->name;
+        previous = new_xbt_graph_node(graph, route->gw_src->p_name, nodes);
+        previous_name = route->gw_src->p_name;
       } else {
-        previous = new_xbt_graph_node(graph, my_src->name, nodes);
-        previous_name = my_src->name;
+        previous = new_xbt_graph_node(graph, my_src->p_name, nodes);
+        previous_name = my_src->p_name;
       }
 
       xbt_dynar_foreach(route->link_list, cpt, link) {
-        char *link_name = ((surf_resource_t) link)->name;
+        const char *link_name = ((ResourcePtr) link)->m_name;
         current = new_xbt_graph_node(graph, link_name, nodes);
         current_name = link_name;
         new_xbt_graph_edge(graph, previous, current, edges);
@@ -185,11 +191,11 @@ void generic_get_graph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges,
       }
 
       if (route->gw_dst) {
-        current = new_xbt_graph_node(graph, route->gw_dst->name, nodes);
-        current_name = route->gw_dst->name;
+        current = new_xbt_graph_node(graph, route->gw_dst->p_name, nodes);
+        current_name = route->gw_dst->p_name;
       } else {
-        current = new_xbt_graph_node(graph, my_dst->name, nodes);
-        current_name = my_dst->name;
+        current = new_xbt_graph_node(graph, my_dst->p_name, nodes);
+        current_name = my_dst->p_name;
       }
       new_xbt_graph_edge(graph, previous, current, edges);
       XBT_DEBUG ("  %s -> %s", previous_name, current_name);
@@ -200,67 +206,67 @@ void generic_get_graph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges,
   }
 }
 
-sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src,
-                                               sg_routing_edge_t dst,
+sg_platf_route_cbarg_t AsGeneric::getBypassRoute(RoutingEdgePtr src,
+                                               RoutingEdgePtr dst,
                                                double *lat)
 {
   // If never set a bypass route return NULL without any further computations
-  XBT_DEBUG("generic_get_bypassroute from %s to %s", src->name, dst->name);
+  XBT_DEBUG("generic_get_bypassroute from %s to %s", src->p_name, dst->p_name);
   if (no_bypassroute_declared)
     return NULL;
 
   sg_platf_route_cbarg_t e_route_bypass = NULL;
-  xbt_dict_t dict_bypassRoutes = rc->bypassRoutes;
+  xbt_dict_t dict_bypassRoutes = p_bypassRoutes;
 
-  if(dst->rc_component == rc && src->rc_component == rc ){
-    char *route_name = bprintf("%s#%s", src->name, dst->name);
-    e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
+  if(dst->p_rcComponent == this && src->p_rcComponent == this ){
+    char *route_name = bprintf("%s#%s", src->p_name, dst->p_name);
+    e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(dict_bypassRoutes, route_name);
     if(e_route_bypass)
       XBT_DEBUG("Find bypass route with %ld links",xbt_dynar_length(e_route_bypass->link_list));
     free(route_name);
   }
   else{
-    AS_t src_as, dst_as;
+    AsPtr src_as, dst_as;
     int index_src, index_dst;
     xbt_dynar_t path_src = NULL;
     xbt_dynar_t path_dst = NULL;
-    AS_t current = NULL;
-    AS_t *current_src = NULL;
-    AS_t *current_dst = NULL;
+    AsPtr current = NULL;
+    AsPtr *current_src = NULL;
+    AsPtr *current_dst = NULL;
 
     if (src == NULL || dst == NULL)
       xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
-          src->name, dst->name, rc->name);
+          src->p_name, dst->p_name, p_name);
 
-    src_as = src->rc_component;
-    dst_as = dst->rc_component;
+    src_as = src->p_rcComponent;
+    dst_as = dst->p_rcComponent;
 
     /* (2) find the path to the root routing component */
-    path_src = xbt_dynar_new(sizeof(AS_t), NULL);
+    path_src = xbt_dynar_new(sizeof(AsPtr), NULL);
     current = src_as;
     while (current != NULL) {
       xbt_dynar_push(path_src, &current);
-      current = current->routing_father;
+      current = current->p_routingFather;
     }
-    path_dst = xbt_dynar_new(sizeof(AS_t), NULL);
+    path_dst = xbt_dynar_new(sizeof(AsPtr), NULL);
     current = dst_as;
     while (current != NULL) {
       xbt_dynar_push(path_dst, &current);
-      current = current->routing_father;
+      current = current->p_routingFather;
     }
 
     /* (3) find the common father */
     index_src = path_src->used - 1;
     index_dst = path_dst->used - 1;
-    current_src = xbt_dynar_get_ptr(path_src, index_src);
-    current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
+    current_src = (AsPtr *) xbt_dynar_get_ptr(path_src, index_src);
+    current_dst = (AsPtr *) xbt_dynar_get_ptr(path_dst, index_dst);
     while (index_src >= 0 && index_dst >= 0 && *current_src == *current_dst) {
       xbt_dynar_pop_ptr(path_src);
       xbt_dynar_pop_ptr(path_dst);
       index_src--;
       index_dst--;
-      current_src = xbt_dynar_get_ptr(path_src, index_src);
-      current_dst = xbt_dynar_get_ptr(path_dst, index_dst);
+      current_src = (AsPtr *) xbt_dynar_get_ptr(path_src, index_src);
+      current_dst = (AsPtr *) xbt_dynar_get_ptr(path_dst, index_dst);
     }
 
     int max_index_src = path_src->used - 1;
@@ -273,22 +279,22 @@ sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src,
       for (i = 0; i < max; i++) {
         if (i <= max_index_src && max <= max_index_dst) {
           char *route_name = bprintf("%s#%s",
-              (*(AS_t *)
-                  (xbt_dynar_get_ptr(path_src, i)))->name,
-                  (*(AS_t *)
-                      (xbt_dynar_get_ptr(path_dst, max)))->name);
-          e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
+              (*(AsPtr *)
+                  (xbt_dynar_get_ptr(path_src, i)))->p_name,
+                  (*(AsPtr *)
+                      (xbt_dynar_get_ptr(path_dst, max)))->p_name);
+          e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(dict_bypassRoutes, route_name);
           xbt_free(route_name);
         }
         if (e_route_bypass)
           break;
         if (max <= max_index_src && i <= max_index_dst) {
           char *route_name = bprintf("%s#%s",
-              (*(AS_t *)
-                  (xbt_dynar_get_ptr(path_src, max)))->name,
-                  (*(AS_t *)
-                      (xbt_dynar_get_ptr(path_dst, i)))->name);
-          e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
+              (*(AsPtr *)
+                  (xbt_dynar_get_ptr(path_src, max)))->p_name,
+                  (*(AsPtr *)
+                      (xbt_dynar_get_ptr(path_dst, i)))->p_name);
+          e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(dict_bypassRoutes, route_name);
           xbt_free(route_name);
         }
         if (e_route_bypass)
@@ -300,11 +306,11 @@ sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src,
 
       if (max <= max_index_src && max <= max_index_dst) {
         char *route_name = bprintf("%s#%s",
-            (*(AS_t *)
-                (xbt_dynar_get_ptr(path_src, max)))->name,
-                (*(AS_t *)
-                    (xbt_dynar_get_ptr(path_dst, max)))->name);
-        e_route_bypass = xbt_dict_get_or_null(dict_bypassRoutes, route_name);
+            (*(AsPtr *)
+                (xbt_dynar_get_ptr(path_src, max)))->p_name,
+                (*(AsPtr *)
+                    (xbt_dynar_get_ptr(path_dst, max)))->p_name);
+        e_route_bypass = (sg_platf_route_cbarg_t) xbt_dict_get_or_null(dict_bypassRoutes, route_name);
         xbt_free(route_name);
       }
       if (e_route_bypass)
@@ -317,7 +323,7 @@ sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src,
 
   sg_platf_route_cbarg_t new_e_route = NULL;
   if (e_route_bypass) {
-    void *link;
+    NetworkCm02LinkPtr link;
     unsigned int cpt = 0;
     new_e_route = xbt_new0(s_sg_platf_route_cbarg_t, 1);
     new_e_route->gw_src = e_route_bypass->gw_src;
@@ -327,7 +333,7 @@ sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src,
     xbt_dynar_foreach(e_route_bypass->link_list, cpt, link) {
       xbt_dynar_push(new_e_route->link_list, &link);
       if (lat)
-        *lat += surf_network_model->extension.network.get_link_latency(link);
+        *lat += link->getLatency();
     }
   }
 
@@ -337,9 +343,8 @@ sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc, sg_routing_edge_t src,
 /* ************************************************************************** */
 /* ************************* GENERIC AUX FUNCTIONS ************************** */
 /* change a route containing link names into a route containing link entities */
-sg_platf_route_cbarg_t
-generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
-    sg_platf_route_cbarg_t routearg, int change_order) {
+sg_platf_route_cbarg_t AsGeneric::newExtendedRoute(e_surf_routing_hierarchy_t hierarchy,
+      sg_platf_route_cbarg_t routearg, int change_order) {
 
   sg_platf_route_cbarg_t result;
   char *link_name;
@@ -377,24 +382,17 @@ generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
   return result;
 }
 
-void generic_free_route(sg_platf_route_cbarg_t route)
-{
-  if (route) {
-    xbt_dynar_free(&route->link_list);
-    xbt_free(route);
-  }
-}
 
-static AS_t generic_as_exist(AS_t find_from,
-    AS_t to_find)
+
+AsPtr AsGeneric::asExist(AsPtr to_find)
 {
   //return to_find; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
   xbt_dict_cursor_t cursor = NULL;
   char *key;
   int found = 0;
-  AS_t elem;
-  xbt_dict_foreach(find_from->routing_sons, cursor, key, elem) {
-    if (to_find == elem || generic_as_exist(elem, to_find)) {
+  AsGenericPtr elem;
+  xbt_dict_foreach(p_routingSons, cursor, key, elem) {
+    if (to_find == elem || elem->asExist(to_find)) {
       found = 1;
       break;
     }
@@ -404,24 +402,23 @@ static AS_t generic_as_exist(AS_t find_from,
   return NULL;
 }
 
-AS_t
-generic_autonomous_system_exist(AS_t rc, char *element)
+AsPtr AsGeneric::autonomousSystemExist(char *element)
 {
   //return rc; // FIXME: BYPASSERROR OF FOREACH WITH BREAK
-  AS_t element_as, result, elem;
+  AsPtr element_as, result, elem;
   xbt_dict_cursor_t cursor = NULL;
   char *key;
-  element_as = ((sg_routing_edge_t)
+  element_as = ((RoutingEdgePtr)
       xbt_lib_get_or_null(as_router_lib, element,
-          ROUTING_ASR_LEVEL))->rc_component;
-  result = ((AS_t) - 1);
-  if (element_as != rc)
-    result = generic_as_exist(rc, element_as);
+          ROUTING_ASR_LEVEL))->p_rcComponent;
+  result = ((AsPtr) - 1);
+  if (element_as != this)
+    result = asExist(element_as);
 
   int found = 0;
   if (result) {
-    xbt_dict_foreach(element_as->routing_sons, cursor, key, elem) {
-      found = !strcmp(elem->name, element);
+    xbt_dict_foreach(element_as->p_routingSons, cursor, key, elem) {
+      found = !strcmp(elem->p_name, element);
       if (found)
         break;
     }
@@ -431,47 +428,45 @@ generic_autonomous_system_exist(AS_t rc, char *element)
   return NULL;
 }
 
-AS_t
-generic_processing_units_exist(AS_t rc, char *element)
+AsPtr AsGeneric::processingUnitsExist(char *element)
 {
-  AS_t element_as;
-  element_as = ((sg_routing_edge_t)
+  AsPtr element_as;
+  element_as = ((RoutingEdgePtr)
       xbt_lib_get_or_null(host_lib,
-          element, ROUTING_HOST_LEVEL))->rc_component;
-  if (element_as == rc)
+          element, ROUTING_HOST_LEVEL))->p_rcComponent;
+  if (element_as == this)
     return element_as;
-  return generic_as_exist(rc, element_as);
+  return asExist(element_as);
 }
 
-void generic_src_dst_check(AS_t rc, sg_routing_edge_t src,
-    sg_routing_edge_t dst)
+void AsGeneric::srcDstCheck(RoutingEdgePtr src, RoutingEdgePtr dst)
 {
 
-  sg_routing_edge_t src_data = src;
-  sg_routing_edge_t dst_data = dst;
+  RoutingEdgePtr src_data = src;
+  RoutingEdgePtr dst_data = dst;
 
   if (src_data == NULL || dst_data == NULL)
     xbt_die("Ask for route \"from\"(%s) or \"to\"(%s) no found at AS \"%s\"",
-        src->name,
-        dst->name,
-        rc->name);
+        src->p_name,
+        dst->p_name,
+        p_name);
 
-  AS_t src_as =
-      (src_data)->rc_component;
-  AS_t dst_as =
-      (dst_data)->rc_component;
+  AsPtr src_as =
+      (src_data)->p_rcComponent;
+  AsPtr dst_as =
+      (dst_data)->p_rcComponent;
 
   if (src_as != dst_as)
     xbt_die("The src(%s in %s) and dst(%s in %s) are in differents AS",
-        src->name, src_as->name,
-        dst->name, dst_as->name);
+        src->p_name, src_as->p_name,
+        dst->p_name, dst_as->p_name);
 
-  if (rc != dst_as)
+  if (this != dst_as)
     xbt_die
     ("The routing component of src'%s' and dst'%s' is not the same as the network elements belong (%s?=%s?=%s)",
-        src->name,
-        dst->name,
-        src_as->name,
-        dst_as->name,
-        rc->name);
+        src->p_name,
+        dst->p_name,
+        src_as->p_name,
+        dst_as->p_name,
+        p_name);
 }
diff --git a/src/surf/surf_routing_generic.hpp b/src/surf/surf_routing_generic.hpp
new file mode 100644 (file)
index 0000000..ae6a615
--- /dev/null
@@ -0,0 +1,38 @@
+#include "surf_routing_none.hpp"
+
+#ifndef SURF_ROUTING_GENERIC_HPP_
+#define SURF_ROUTING_GENERIC_HPP_
+
+class AsGeneric;
+typedef AsGeneric *AsGenericPtr;
+
+void generic_free_route(sg_platf_route_cbarg_t route);
+
+class AsGeneric : public AsNone {
+public:
+  AsGeneric();
+  ~AsGeneric();
+
+  virtual void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
+  virtual xbt_dynar_t getOneLinkRoutes();
+  virtual void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+  virtual sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+
+  /* The parser calls the following functions to inform the routing models
+   * that a new element is added to the AS currently built.
+   *
+   * Of course, only the routing model of this AS is informed, not every ones */
+  virtual int parsePU(RoutingEdgePtr elm); /* A host or a router, whatever */
+  virtual int parseAS( RoutingEdgePtr elm);
+  virtual void parseRoute(sg_platf_route_cbarg_t route);
+  virtual void parseASroute(sg_platf_route_cbarg_t route);
+  virtual void parseBypassroute(sg_platf_route_cbarg_t e_route);
+
+  virtual sg_platf_route_cbarg_t newExtendedRoute(e_surf_routing_hierarchy_t hierarchy, sg_platf_route_cbarg_t routearg, int change_order);
+  virtual AsPtr asExist(AsPtr to_find);
+  virtual AsPtr autonomousSystemExist(char *element);
+  virtual AsPtr processingUnitsExist(char *element);
+  virtual void srcDstCheck(RoutingEdgePtr src, RoutingEdgePtr dst);
+};
+
+#endif /* SURF_ROUTING_GENERIC_HPP_ */
diff --git a/src/surf/surf_routing_none.cpp b/src/surf/surf_routing_none.cpp
new file mode 100644 (file)
index 0000000..86dd2e5
--- /dev/null
@@ -0,0 +1,74 @@
+/* Copyright (c) 2009, 2010, 2011. 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 "surf_routing_none.hpp"
+#include "surf_routing_private.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_none, surf, "Routing part of surf");
+}
+
+AS_t model_none_create(void)
+{
+  return new AsNone();
+}
+
+xbt_dynar_t AsNone::getOneLinkRoutes() {
+  return NULL;
+}
+
+void AsNone::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst,
+    sg_platf_route_cbarg_t res, double *lat)
+{
+  *lat = 0.0;
+}
+
+void AsNone::getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges)
+{
+       XBT_INFO("No routing no graph");
+}
+
+sg_platf_route_cbarg_t AsNone::getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat) {
+  return NULL;
+}
+
+int AsNone::parsePU(RoutingEdgePtr elm) {
+  XBT_DEBUG("Load process unit \"%s\"", elm->p_name);
+  xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+  /* don't care about PUs */
+  return -1;
+}
+
+int AsNone::parseAS(RoutingEdgePtr elm) {
+  XBT_DEBUG("Load Autonomous system \"%s\"", elm->p_name);
+  xbt_dynar_push_as(p_indexNetworkElm, RoutingEdgePtr, elm);
+  /* even don't care about sub-ASes -- I'm as nihilist as an old punk*/
+  return -1;
+}
+
+void AsNone::parseRoute(sg_platf_route_cbarg_t route){
+  THROW_IMPOSSIBLE;
+}
+
+void AsNone::parseASroute(sg_platf_route_cbarg_t route){
+  THROW_IMPOSSIBLE;
+}
+void AsNone::parseBypassroute(sg_platf_route_cbarg_t e_route){
+  THROW_IMPOSSIBLE;
+}
+
+/* Creation routing model functions */
+AsNone::AsNone() {
+  p_routingSons = xbt_dict_new_homogeneous(NULL);
+  p_indexNetworkElm = xbt_dynar_new(sizeof(char*),NULL);
+}
+
+AsNone::~AsNone() {
+  xbt_dict_free(&p_routingSons);
+  xbt_dynar_free(&p_indexNetworkElm);
+  xbt_dynar_free(&p_linkUpDownList);
+}
+
diff --git a/src/surf/surf_routing_none.hpp b/src/surf/surf_routing_none.hpp
new file mode 100644 (file)
index 0000000..2e6d24a
--- /dev/null
@@ -0,0 +1,27 @@
+#include "surf_routing.hpp"
+
+#ifndef SURF_ROUTING_NONE_HPP_
+#define SURF_ROUTING_NONE_HPP_
+
+class AsNone : public As {
+public:
+  AsNone();
+  ~AsNone();
+  virtual void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
+  virtual xbt_dynar_t getOneLinkRoutes();
+  virtual void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+  virtual sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+
+  /* The parser calls the following functions to inform the routing models
+   * that a new element is added to the AS currently built.
+   *
+   * Of course, only the routing model of this AS is informed, not every ones */
+  virtual int parsePU(RoutingEdgePtr elm); /* A host or a router, whatever */
+  virtual int parseAS( RoutingEdgePtr elm);
+  virtual void parseRoute(sg_platf_route_cbarg_t route);
+  virtual void parseASroute(sg_platf_route_cbarg_t route);
+  virtual void parseBypassroute(sg_platf_route_cbarg_t e_route);
+};
+
+
+#endif /* SURF_ROUTING_NONE_HPP_ */
index 6c2e754..18c6753 100644 (file)
 #include <float.h>
 #include "internal_config.h"
 
-#include "surf_private.h"
+//#include "surf_private.h"
 #include "xbt/dynar.h"
 #include "xbt/str.h"
 #include "xbt/config.h"
 #include "xbt/graph.h"
 #include "xbt/set.h"
 #include "surf/surfxml_parse.h"
+#include "surf_routing.hpp"
 
 /* ************************************************************************** */
 /* ******************************* NO ROUTING ******************************* */
 /* Only save the AS tree, and forward calls to child ASes */
-AS_t model_none_create(void);
-AS_t model_none_create_sized(size_t childsize);
-void model_none_finalize(AS_t as);
+AsPtr model_none_create(void);
+AsPtr model_none_create_sized(size_t childsize);
+void model_none_finalize(AsPtr as);
 /* ************************************************************************** */
 /* ***************** GENERIC PARSE FUNCTIONS (declarations) ***************** */
-AS_t model_generic_create_sized(size_t childsize);
-void model_generic_finalize(AS_t as);
+AsPtr model_generic_create_sized(size_t childsize);
+void model_generic_finalize(AsPtr as);
 
-int generic_parse_PU(AS_t rc, sg_routing_edge_t elm);
-int generic_parse_AS(AS_t rc, sg_routing_edge_t elm);
-void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route);
+int generic_parse_PU(AsPtr rc, RoutingEdgePtr elm);
+int generic_parse_AS(AsPtr rc, RoutingEdgePtr elm);
+void generic_parse_bypassroute(AsPtr rc, sg_platf_route_cbarg_t e_route);
 
 /* ************************************************************************** */
 /* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
 
-xbt_dynar_t generic_get_onelink_routes(AS_t rc);
-sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc,
-    sg_routing_edge_t src,
-    sg_routing_edge_t dst,
+xbt_dynar_t generic_get_onelink_routes(AsPtr rc);
+sg_platf_route_cbarg_t generic_get_bypassroute(AsPtr rc,
+    RoutingEdgePtr src,
+    RoutingEdgePtr dst,
     double *lat);
 
 /* ************************************************************************** */
@@ -50,51 +51,42 @@ sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc,
  * produced route */
 sg_platf_route_cbarg_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
                                    sg_platf_route_cbarg_t data, int preserve_order);
-AS_t
-generic_autonomous_system_exist(AS_t rc, char *element);
-AS_t
-generic_processing_units_exist(AS_t rc, char *element);
-void generic_src_dst_check(AS_t rc, sg_routing_edge_t src,
-    sg_routing_edge_t dst);
+AsPtr
+generic_autonomous_system_exist(AsPtr rc, char *element);
+AsPtr
+generic_processing_units_exist(AsPtr rc, char *element);
+void generic_src_dst_check(AsPtr rc, RoutingEdgePtr src,
+    RoutingEdgePtr dst);
 
 /* ************************************************************************** */
 /* *************************** FLOYD ROUTING ******************************** */
-AS_t model_floyd_create(void);  /* create structures for floyd routing model */
-void model_floyd_end(AS_t as);      /* finalize the creation of floyd routing model */
-void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route);
+AsPtr model_floyd_create(void);  /* create structures for floyd routing model */
+void model_floyd_end(AsPtr as);      /* finalize the creation of floyd routing model */
+void model_floyd_parse_route(AsPtr rc, sg_platf_route_cbarg_t route);
 
-/* ************************************************** */
-/* **************  Cluster ROUTING   **************** */
-typedef struct {
-  s_as_t generic_routing;
-  void *backbone;
-  void *loopback;
-  sg_routing_edge_t router;
-} s_as_cluster_t, *as_cluster_t;
-
-AS_t model_cluster_create(void);      /* create structures for cluster routing model */
+AsPtr model_cluster_create(void);      /* create structures for cluster routing model */
 
 /* ************************************************** */
 /* **************  Vivaldi ROUTING   **************** */
-AS_t model_vivaldi_create(void);      /* create structures for vivaldi routing model */
+AsPtr model_vivaldi_create(void);      /* create structures for vivaldi routing model */
 #define HOST_PEER(peername) bprintf("peer_%s", peername)
 #define ROUTER_PEER(peername) bprintf("router_%s", peername)
 #define LINK_PEER(peername) bprintf("link_%s", peername)
 
 /* ************************************************************************** */
 /* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
-AS_t model_dijkstra_both_create(int cached);    /* create by calling dijkstra or dijkstracache */
-AS_t model_dijkstra_create(void);       /* create structures for dijkstra routing model */
-AS_t model_dijkstracache_create(void);  /* create structures for dijkstracache routing model */
-void model_dijkstra_both_end(AS_t as);      /* finalize the creation of dijkstra routing model */
-void model_dijkstra_both_parse_route (AS_t rc, sg_platf_route_cbarg_t route);
+AsPtr model_dijkstra_both_create(int cached);    /* create by calling dijkstra or dijkstracache */
+AsPtr model_dijkstra_create(void);       /* create structures for dijkstra routing model */
+AsPtr model_dijkstracache_create(void);  /* create structures for dijkstracache routing model */
+void model_dijkstra_both_end(AsPtr as);      /* finalize the creation of dijkstra routing model */
+void model_dijkstra_both_parse_route (AsPtr rc, sg_platf_route_cbarg_t route);
 
 /* ************************************************************************** */
 /* *************************** FULL ROUTING ********************************* */
-AS_t model_full_create(void);   /* create structures for full routing model */
-void model_full_end(AS_t as);       /* finalize the creation of full routing model */
+AsPtr model_full_create(void);   /* create structures for full routing model */
+void model_full_end(AsPtr as);       /* finalize the creation of full routing model */
 void model_full_set_route(  /* Set the route and ASroute between src and dst */
-    AS_t rc, sg_platf_route_cbarg_t route);
+    AsPtr rc, sg_platf_route_cbarg_t route);
 /* ************************************************************************** */
 /* ************************* GRAPH EXPORTING FUNCTIONS ********************** */
 xbt_node_t new_xbt_graph_node (xbt_graph_t graph, const char *name, xbt_dict_t nodes);
diff --git a/src/surf/surf_routing_private.hpp b/src/surf/surf_routing_private.hpp
new file mode 100644 (file)
index 0000000..e3d718b
--- /dev/null
@@ -0,0 +1,106 @@
+/* Copyright (c) 2009, 2010, 2011. 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. */
+
+#ifndef _SURF_SURF_ROUTING_PRIVATE_H
+#define _SURF_SURF_ROUTING_PRIVATE_H
+
+#include <float.h>
+#include "internal_config.h"
+
+#include "surf.hpp"
+#include "xbt/dynar.h"
+#include "xbt/str.h"
+#include "xbt/config.h"
+#include "xbt/graph.h"
+#include "xbt/set.h"
+#include "surf/surfxml_parse.h"
+
+/* ************************************************************************** */
+/* ******************************* NO ROUTING ******************************* */
+/* Only save the AS tree, and forward calls to child ASes */
+AS_t model_none_create(void);
+AS_t model_none_create_sized(size_t childsize);
+void model_none_finalize(AS_t as);
+/* ************************************************************************** */
+/* ***************** GENERIC PARSE FUNCTIONS (declarations) ***************** */
+AS_t model_generic_create_sized(size_t childsize);
+void model_generic_finalize(AS_t as);
+
+int generic_parse_PU(AS_t rc, sg_routing_edge_t elm);
+int generic_parse_AS(AS_t rc, sg_routing_edge_t elm);
+void generic_parse_bypassroute(AS_t rc, sg_platf_route_cbarg_t e_route);
+
+/* ************************************************************************** */
+/* *************** GENERIC BUSINESS METHODS (declarations) ****************** */
+
+xbt_dynar_t generic_get_onelink_routes(AS_t rc);
+sg_platf_route_cbarg_t generic_get_bypassroute(AS_t rc,
+    sg_routing_edge_t src,
+    sg_routing_edge_t dst,
+    double *lat);
+
+/* ************************************************************************** */
+/* ****************** GENERIC AUX FUNCTIONS (declarations) ****************** */
+
+/* change a route containing link names into a route containing link entities.
+ * If change_order is true, the links are put in reverse order in the
+ * produced route */
+sg_platf_route_cbarg_t generic_new_extended_route(e_surf_routing_hierarchy_t hierarchy,
+                                   sg_platf_route_cbarg_t data, int preserve_order);
+AS_t
+generic_autonomous_system_exist(AS_t rc, char *element);
+AS_t
+generic_processing_units_exist(AS_t rc, char *element);
+void generic_src_dst_check(AS_t rc, sg_routing_edge_t src,
+    sg_routing_edge_t dst);
+
+/* ************************************************************************** */
+/* *************************** FLOYD ROUTING ******************************** */
+AS_t model_floyd_create(void);  /* create structures for floyd routing model */
+void model_floyd_end(AS_t as);      /* finalize the creation of floyd routing model */
+void model_floyd_parse_route(AS_t rc, sg_platf_route_cbarg_t route);
+
+/* ************************************************** */
+/* **************  Cluster ROUTING   **************** */
+class AsCluster : public As {
+public:
+  void *backbone;
+  void *loopback;
+  RoutingEdgePtr p_router;
+};
+typedef AsCluster *AsClusterPtr;
+//FIXME:remove} s_as_cluster_t, *as_cluster_t;
+
+AsPtr model_cluster_create(void);      /* create structures for cluster routing model */
+
+/* ************************************************** */
+/* **************  Vivaldi ROUTING   **************** */
+AS_t model_vivaldi_create(void);      /* create structures for vivaldi routing model */
+#define HOST_PEER(peername) bprintf("peer_%s", peername)
+#define ROUTER_PEER(peername) bprintf("router_%s", peername)
+#define LINK_PEER(peername) bprintf("link_%s", peername)
+
+/* ************************************************************************** */
+/* ********** Dijkstra & Dijkstra Cached ROUTING **************************** */
+AS_t model_dijkstra_both_create(int cached);    /* create by calling dijkstra or dijkstracache */
+AS_t model_dijkstra_create(void);       /* create structures for dijkstra routing model */
+AS_t model_dijkstracache_create(void);  /* create structures for dijkstracache routing model */
+void model_dijkstra_both_end(AS_t as);      /* finalize the creation of dijkstra routing model */
+void model_dijkstra_both_parse_route (AS_t rc, sg_platf_route_cbarg_t route);
+
+/* ************************************************************************** */
+/* *************************** FULL ROUTING ********************************* */
+AS_t model_full_create(void);   /* create structures for full routing model */
+void model_full_end(AS_t as);       /* finalize the creation of full routing model */
+void model_full_set_route(  /* Set the route and ASroute between src and dst */
+    AS_t rc, sg_platf_route_cbarg_t route);
+/* ************************************************************************** */
+/* ************************* GRAPH EXPORTING FUNCTIONS ********************** */
+xbt_node_t new_xbt_graph_node (xbt_graph_t graph, const char *name, xbt_dict_t nodes);
+xbt_edge_t new_xbt_graph_edge (xbt_graph_t graph, xbt_node_t s, xbt_node_t d, xbt_dict_t edges);
+
+
+#endif                          /* _SURF_SURF_ROUTING_PRIVATE_H */
diff --git a/src/surf/surf_routing_vivaldi.cpp b/src/surf/surf_routing_vivaldi.cpp
new file mode 100644 (file)
index 0000000..3b705be
--- /dev/null
@@ -0,0 +1,100 @@
+#include "surf_routing_private.h"
+#include "surf_routing_vivaldi.hpp"
+
+extern "C" {
+  XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_route_vivaldi, surf, "Routing part of surf");
+}
+
+static XBT_INLINE double euclidean_dist_comp(int index, xbt_dynar_t src, xbt_dynar_t dst) {
+  double src_coord, dst_coord;
+
+  src_coord = xbt_dynar_get_as(src, index, double);
+  dst_coord = xbt_dynar_get_as(dst, index, double);
+
+  return (src_coord-dst_coord)*(src_coord-dst_coord);
+}
+
+AS_t model_vivaldi_create(void)
+{
+  return new AsVivaldi();
+}
+
+void AsVivaldi::getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t route, double *lat)
+{
+  s_surf_parsing_link_up_down_t info;
+
+  XBT_DEBUG("vivaldi_get_route_and_latency from '%s'[%d] '%s'[%d]",
+                 src->p_name, src->m_id, dst->p_name, dst->m_id);
+
+  if(src->p_rcType == SURF_NETWORK_ELEMENT_AS) {
+    route->gw_src = (sg_routing_edge_t) xbt_lib_get_or_null(as_router_lib, ROUTER_PEER(src->p_name), ROUTING_ASR_LEVEL);
+    route->gw_dst = (sg_routing_edge_t) xbt_lib_get_or_null(as_router_lib, ROUTER_PEER(dst->p_name), ROUTING_ASR_LEVEL);
+  }
+
+  double euclidean_dist;
+  xbt_dynar_t src_ctn, dst_ctn;
+  char *tmp_src_name, *tmp_dst_name;
+
+  if(src->p_rcType == SURF_NETWORK_ELEMENT_HOST){
+    tmp_src_name = HOST_PEER(src->p_name);
+
+    if(p_linkUpDownList){
+      info = xbt_dynar_get_as(p_linkUpDownList, src->m_id, s_surf_parsing_link_up_down_t);
+      if(info.link_up) { // link up
+        xbt_dynar_push_as(route->link_list, void*, info.link_up);
+        if (lat)
+          *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(info.link_up))->getLatency();
+      }
+    }
+    src_ctn = (xbt_dynar_t) xbt_lib_get_or_null(host_lib, tmp_src_name, COORD_HOST_LEVEL);
+    if(!src_ctn ) src_ctn = (xbt_dynar_t) xbt_lib_get_or_null(host_lib, src->p_name, COORD_HOST_LEVEL);
+  }
+  else if(src->p_rcType == SURF_NETWORK_ELEMENT_ROUTER || src->p_rcType == SURF_NETWORK_ELEMENT_AS){
+    tmp_src_name = ROUTER_PEER(src->p_name);
+    src_ctn = (xbt_dynar_t) xbt_lib_get_or_null(as_router_lib, tmp_src_name, COORD_ASR_LEVEL);
+  }
+  else{
+    THROW_IMPOSSIBLE;
+  }
+
+  if(dst->p_rcType == SURF_NETWORK_ELEMENT_HOST){
+    tmp_dst_name = HOST_PEER(dst->p_name);
+
+    if(p_linkUpDownList){
+      info = xbt_dynar_get_as(p_linkUpDownList, dst->m_id, s_surf_parsing_link_up_down_t);
+      if(info.link_down) { // link down
+        xbt_dynar_push_as(route->link_list,void*,info.link_down);
+        if (lat)
+          *lat += dynamic_cast<NetworkCm02LinkPtr>(static_cast<ResourcePtr>(info.link_down))->getLatency();
+      }
+    }
+    dst_ctn = (xbt_dynar_t) xbt_lib_get_or_null(host_lib, tmp_dst_name, COORD_HOST_LEVEL);
+    if(!dst_ctn ) dst_ctn = (xbt_dynar_t) xbt_lib_get_or_null(host_lib, dst->p_name, COORD_HOST_LEVEL);
+  }
+  else if(dst->p_rcType == SURF_NETWORK_ELEMENT_ROUTER || dst->p_rcType == SURF_NETWORK_ELEMENT_AS){
+    tmp_dst_name = ROUTER_PEER(dst->p_name);
+    dst_ctn = (xbt_dynar_t) xbt_lib_get_or_null(as_router_lib, tmp_dst_name, COORD_ASR_LEVEL);
+  }
+  else{
+    THROW_IMPOSSIBLE;
+  }
+
+  xbt_assert(src_ctn,"No coordinate found for element '%s'",tmp_src_name);
+  xbt_assert(dst_ctn,"No coordinate found for element '%s'",tmp_dst_name);
+  free(tmp_src_name);
+  free(tmp_dst_name);
+
+  euclidean_dist = sqrt (euclidean_dist_comp(0,src_ctn,dst_ctn)+euclidean_dist_comp(1,src_ctn,dst_ctn))
+                      + fabs(xbt_dynar_get_as(src_ctn, 2, double))+fabs(xbt_dynar_get_as(dst_ctn, 2, double));
+
+  if (lat){
+    XBT_DEBUG("Updating latency %f += %f",*lat,euclidean_dist);
+    *lat += euclidean_dist / 1000.0; //From .ms to .s
+  }
+}
+
+int AsVivaldi::parsePU(RoutingEdgePtr elm) {
+  XBT_DEBUG("Load process unit \"%s\"", elm->p_name);
+  xbt_dynar_push_as(p_indexNetworkElm, sg_routing_edge_t, elm);
+  return xbt_dynar_length(p_indexNetworkElm)-1;
+}
diff --git a/src/surf/surf_routing_vivaldi.hpp b/src/surf/surf_routing_vivaldi.hpp
new file mode 100644 (file)
index 0000000..dd066ff
--- /dev/null
@@ -0,0 +1,35 @@
+#include "surf_routing_generic.hpp"
+#include "network.hpp"
+
+#ifndef SURF_ROUTING_VIVALDI_HPP_
+#define SURF_ROUTING_VIVALDI_HPP_
+
+/***********
+ * Classes *
+ ***********/
+class AsVivaldi;
+typedef AsVivaldi *AsVivaldiPtr;
+
+class AsVivaldi: public AsGeneric {
+public:
+  sg_platf_route_cbarg_t *p_routingTable;
+
+  AsVivaldi() : AsGeneric() {};
+  ~AsVivaldi() {};
+
+  void getRouteAndLatency(RoutingEdgePtr src, RoutingEdgePtr dst, sg_platf_route_cbarg_t into, double *latency);
+  //void getGraph(xbt_graph_t graph, xbt_dict_t nodes, xbt_dict_t edges);
+  //sg_platf_route_cbarg_t getBypassRoute(RoutingEdgePtr src, RoutingEdgePtr dst, double *lat);
+
+  /* The parser calls the following functions to inform the routing models
+   * that a new element is added to the AS currently built.
+   *
+   * Of course, only the routing model of this AS is informed, not every ones */
+  int parsePU(RoutingEdgePtr elm); /* A host or a router, whatever */
+  //virtual int parseAS( RoutingEdgePtr elm)=0;
+
+  //virtual void parseBypassroute(sg_platf_route_cbarg_t e_route)=0;
+};
+
+
+#endif /* SURF_ROUTING_VIVALDI_HPP_ */
index cae8e45..2013d9a 100644 (file)
@@ -14,6 +14,7 @@
 #include "xbt/dict.h"
 #include "surf/surfxml_parse.h"
 #include "surf/surf_private.h"
+#include "surf/random_mgr.h"
 #include "simgrid/sg_config.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_parse, surf,
diff --git a/src/surf/workstation.cpp b/src/surf/workstation.cpp
new file mode 100644 (file)
index 0000000..31aef93
--- /dev/null
@@ -0,0 +1,321 @@
+#include "workstation.hpp"
+#include "simgrid/sg_config.h"
+
+extern "C" {
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_workstation, surf,
+                                "Logging specific to the SURF workstation module");
+}
+
+WorkstationModelPtr surf_workstation_model = NULL;
+
+//FIXME:Faire hériter ou composer de cup et network
+
+/*************
+ * CallBacks *
+ *************/
+
+static void workstation_new(sg_platf_host_cbarg_t host){
+  surf_workstation_model->createResource(host->id);
+}
+
+/*********
+ * Model *
+ *********/
+
+void surf_workstation_model_init_current_default(void)
+{
+  surf_workstation_model = new WorkstationModel();
+  xbt_cfg_setdefault_boolean(_sg_cfg_set, "network/crosstraffic", "yes");
+  surf_cpu_model_init_Cas01();
+  surf_network_model_init_LegrandVelho();
+
+  ModelPtr model = static_cast<ModelPtr>(surf_workstation_model);
+  xbt_dynar_push(model_list, &model);
+  sg_platf_host_add_cb(workstation_new);
+}
+
+void surf_workstation_model_init_compound()
+{
+
+  xbt_assert(surf_cpu_model, "No CPU model defined yet!");
+  xbt_assert(surf_network_model, "No network model defined yet!");
+  surf_workstation_model = new WorkstationModel();
+
+  ModelPtr model = static_cast<ModelPtr>(surf_workstation_model);
+  xbt_dynar_push(model_list, &model);
+  sg_platf_host_add_cb(workstation_new);
+}
+
+WorkstationModel::WorkstationModel() : Model("Workstation") {
+}
+
+WorkstationModel::~WorkstationModel() {
+}
+
+void WorkstationModel::parseInit(sg_platf_host_cbarg_t host){
+  createResource(host->id);
+}
+
+WorkstationCLM03Ptr WorkstationModel::createResource(string name){
+
+  WorkstationCLM03Ptr workstation = new WorkstationCLM03(surf_workstation_model, name.c_str(), NULL,
+                 (xbt_dynar_t)xbt_lib_get_or_null(storage_lib, name.c_str(), ROUTING_STORAGE_HOST_LEVEL),
+                 (RoutingEdgePtr)xbt_lib_get_or_null(host_lib, name.c_str(), ROUTING_HOST_LEVEL),
+                 dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(host_lib, name.c_str(), SURF_CPU_LEVEL))));
+  XBT_DEBUG("Create workstation %s with %ld mounted disks", name.c_str(), xbt_dynar_length(workstation->p_storage));
+  xbt_lib_set(host_lib, name.c_str(), SURF_WKS_LEVEL, static_cast<ResourcePtr>(workstation));
+  return workstation;
+}
+
+double WorkstationModel::shareResources(double now){
+  return -1.0;
+}
+
+void WorkstationModel::updateActionsState(double now, double delta){
+  return;
+}
+
+ActionPtr WorkstationModel::executeParallelTask(int workstation_nb,
+                                        void **workstation_list,
+                                        double *computation_amount,
+                                        double *communication_amount,
+                                        double rate){
+#define cost_or_zero(array,pos) ((array)?(array)[pos]:0.0)
+  if ((workstation_nb == 1)
+      && (cost_or_zero(communication_amount, 0) == 0.0))
+    return ((WorkstationCLM03Ptr)workstation_list[0])->execute(computation_amount[0]);
+  else if ((workstation_nb == 1)
+           && (cost_or_zero(computation_amount, 0) == 0.0))
+    return communicate((WorkstationCLM03Ptr)workstation_list[0], (WorkstationCLM03Ptr)workstation_list[0],communication_amount[0], rate);
+  else if ((workstation_nb == 2)
+             && (cost_or_zero(computation_amount, 0) == 0.0)
+             && (cost_or_zero(computation_amount, 1) == 0.0)) {
+    int i,nb = 0;
+    double value = 0.0;
+
+    for (i = 0; i < workstation_nb * workstation_nb; i++) {
+      if (cost_or_zero(communication_amount, i) > 0.0) {
+        nb++;
+        value = cost_or_zero(communication_amount, i);
+      }
+    }
+    if (nb == 1)
+      return communicate((WorkstationCLM03Ptr)workstation_list[0], (WorkstationCLM03Ptr)workstation_list[1],value, rate);
+  }
+#undef cost_or_zero
+
+  THROW_UNIMPLEMENTED;          /* This model does not implement parallel tasks */
+  return NULL;
+}
+
+/* returns an array of network_link_CM02_t */
+xbt_dynar_t WorkstationModel::getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst)
+{
+  XBT_DEBUG("ws_get_route");
+  return surf_network_model->getRoute(src->p_netElm, dst->p_netElm);
+}
+
+ActionPtr WorkstationModel::communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate){
+  return surf_network_model->communicate(src->p_netElm, dst->p_netElm, size, rate);
+}
+
+
+
+/************
+ * Resource *
+ ************/
+WorkstationCLM03::WorkstationCLM03(WorkstationModelPtr model, const char* name, xbt_dict_t properties, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu)
+  : Resource(model, name, properties), p_storage(storage), p_netElm(netElm), p_cpu(cpu) {}
+
+bool WorkstationCLM03::isUsed(){
+  THROW_IMPOSSIBLE;             /* This model does not implement parallel tasks */
+  return -1;
+}
+
+void WorkstationCLM03::updateState(tmgr_trace_event_t event_type, double value, double date){
+  THROW_IMPOSSIBLE;             /* This model does not implement parallel tasks */
+}
+
+ActionPtr WorkstationCLM03::execute(double size) {
+  return p_cpu->execute(size);
+}
+
+ActionPtr WorkstationCLM03::sleep(double duration) {
+  return p_cpu->sleep(duration);
+}
+
+e_surf_resource_state_t WorkstationCLM03::getState() {
+  return p_cpu->getState();
+}
+
+int WorkstationCLM03::getCore(){
+  return p_cpu->getCore();
+}
+
+double WorkstationCLM03::getSpeed(double load){
+  return p_cpu->getSpeed(load);
+}
+
+double WorkstationCLM03::getAvailableSpeed(){
+  return p_cpu->getAvailableSpeed();
+}
+
+double WorkstationCLM03::getCurrentPowerPeak()
+{
+  return p_cpu->getCurrentPowerPeak();
+}
+
+double WorkstationCLM03::getPowerPeakAt(int pstate_index)
+{
+  return p_cpu->getPowerPeakAt(pstate_index);
+}
+
+int WorkstationCLM03::getNbPstates()
+{
+  return p_cpu->getNbPstates();
+}
+
+void WorkstationCLM03::setPowerPeakAt(int pstate_index)
+{
+       p_cpu->setPowerPeakAt(pstate_index);
+}
+
+double WorkstationCLM03::getConsumedEnergy()
+{
+  return p_cpu->getConsumedEnergy();
+}
+
+
+xbt_dict_t WorkstationCLM03::getProperties()
+{
+  return p_cpu->m_properties;
+}
+
+
+StoragePtr WorkstationCLM03::findStorageOnMountList(const char* mount)
+{
+  StoragePtr st = NULL;
+  s_mount_t mnt;
+  unsigned int cursor;
+
+  XBT_DEBUG("Search for storage name '%s' on '%s'", mount, m_name);
+  xbt_dynar_foreach(p_storage,cursor,mnt)
+  {
+    XBT_DEBUG("See '%s'",mnt.name);
+    if(!strcmp(mount,mnt.name)){
+      st = dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(mnt.storage));
+      break;
+    }
+  }
+  if(!st) xbt_die("Can't find mount '%s' for '%s'", mount, m_name);
+  return st;
+}
+
+xbt_dict_t WorkstationCLM03::getStorageList()
+{
+  s_mount_t mnt;
+  unsigned int i;
+  xbt_dict_t storage_list = xbt_dict_new_homogeneous(NULL);
+  char *storage_name = NULL;
+
+  xbt_dynar_foreach(p_storage,i,mnt){
+    storage_name = (char *)dynamic_cast<StoragePtr>(static_cast<ResourcePtr>(mnt.storage))->m_name;
+    xbt_dict_set(storage_list,mnt.name,storage_name,NULL);
+  }
+  return storage_list;
+}
+
+ActionPtr WorkstationCLM03::open(const char* mount, const char* path) {
+  StoragePtr st = findStorageOnMountList(mount);
+  XBT_DEBUG("OPEN on disk '%s'", st->m_name);
+  return st->open(mount, path);
+}
+
+ActionPtr WorkstationCLM03::close(surf_file_t fd) {
+  StoragePtr st = findStorageOnMountList(fd->mount);
+  XBT_DEBUG("CLOSE on disk '%s'",st->m_name);
+  return st->close(fd);
+}
+
+ActionPtr WorkstationCLM03::read(surf_file_t fd, sg_storage_size_t size) {
+  StoragePtr st = findStorageOnMountList(fd->mount);
+  XBT_DEBUG("READ on disk '%s'",st->m_name);
+  return st->read(fd, size);
+}
+
+ActionPtr WorkstationCLM03::write(surf_file_t fd, sg_storage_size_t size) {
+  StoragePtr st = findStorageOnMountList(fd->mount);
+  XBT_DEBUG("WRITE on disk '%s'",st->m_name);
+  return st->write(fd, size);
+}
+
+int WorkstationCLM03::unlink(surf_file_t fd) {
+  if (!fd){
+    XBT_WARN("No such file descriptor. Impossible to unlink");
+    return 0;
+  } else {
+//    XBT_INFO("%s %zu", fd->storage, fd->size);
+    StoragePtr st = findStorageOnMountList(fd->mount);
+    /* Check if the file is on this storage */
+    if (!xbt_dict_get_or_null(st->p_content, fd->name)){
+      XBT_WARN("File %s is not on disk %s. Impossible to unlink", fd->name,
+          st->m_name);
+      return 0;
+    } else {
+      XBT_DEBUG("UNLINK on disk '%s'",st->m_name);
+      st->m_usedSize -= fd->size;
+
+      // Remove the file from storage
+      xbt_dict_remove(st->p_content, fd->name);
+
+      free(fd->name);
+      free(fd->mount);
+      xbt_free(fd);
+      return 1;
+    }
+  }
+}
+
+ActionPtr WorkstationCLM03::ls(const char* mount, const char *path){
+  XBT_DEBUG("LS on mount '%s' and file '%s'", mount, path);
+  StoragePtr st = findStorageOnMountList(mount);
+  return st->ls(path);
+}
+
+sg_storage_size_t WorkstationCLM03::getSize(surf_file_t fd){
+  return fd->size;
+}
+
+xbt_dynar_t WorkstationCLM03::getInfo( surf_file_t fd)
+{
+  StoragePtr st = findStorageOnMountList(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 *, (void *)st->m_name);
+  xbt_dynar_push_as(info, void *, st->p_typeId);
+  xbt_dynar_push_as(info, void *, st->p_contentType);
+
+  return info;
+}
+
+sg_storage_size_t WorkstationCLM03::getFreeSize(const char* name)
+{
+  StoragePtr st = findStorageOnMountList(name);
+  return st->m_size - st->m_usedSize;
+}
+
+sg_storage_size_t WorkstationCLM03::getUsedSize(const char* name)
+{
+  StoragePtr st = findStorageOnMountList(name);
+  return st->m_usedSize;
+}
+
+e_surf_resource_state_t WorkstationCLM03Lmm::getState() {
+  return WorkstationCLM03::getState();
+}
+/**********
+ * Action *
+ **********/
diff --git a/src/surf/workstation.hpp b/src/surf/workstation.hpp
new file mode 100644 (file)
index 0000000..08940e0
--- /dev/null
@@ -0,0 +1,122 @@
+#include "surf.hpp"
+#include "storage.hpp"
+#include "cpu.hpp"
+#include "network.hpp"
+
+#ifndef WORKSTATION_HPP_
+#define WORKSTATION_HPP_
+
+/***********
+ * Classes *
+ ***********/
+
+class WorkstationModel;
+typedef WorkstationModel *WorkstationModelPtr;
+
+class WorkstationCLM03;
+typedef WorkstationCLM03 *WorkstationCLM03Ptr;
+
+class WorkstationCLM03Lmm;
+typedef WorkstationCLM03Lmm *WorkstationCLM03LmmPtr;
+
+class WorkstationAction;
+typedef WorkstationAction *WorkstationActionPtr;
+
+/*FIXME:class WorkstationActionLmm;
+typedef WorkstationActionLmm *WorkstationActionLmmPtr;*/
+
+/*********
+ * Tools *
+ *********/
+extern WorkstationModelPtr surf_workstation_model;
+
+/*********
+ * Model *
+ *********/
+class WorkstationModel : public Model {
+public:
+  WorkstationModel(string name): Model(name) {};
+  WorkstationModel();
+  ~WorkstationModel();
+  virtual void parseInit(sg_platf_host_cbarg_t host);
+  WorkstationCLM03Ptr createResource(string name);
+  double shareResources(double now);
+  void updateActionsState(double now, double delta);
+
+  virtual ActionPtr executeParallelTask(int workstation_nb,
+                                        void **workstation_list,
+                                        double *computation_amount,
+                                        double *communication_amount,
+                                        double rate);
+ virtual xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst);
+ virtual ActionPtr communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate);
+};
+
+/************
+ * Resource *
+ ************/
+
+class WorkstationCLM03 : virtual public Resource {
+public:
+  WorkstationCLM03(WorkstationModelPtr model, const char* name, xbt_dict_t properties, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu);
+
+  void updateState(tmgr_trace_event_t event_type, double value, double date);
+
+  virtual ActionPtr execute(double size);
+  virtual ActionPtr sleep(double duration);
+  e_surf_resource_state_t getState();
+
+  virtual int getCore();
+  virtual double getSpeed(double load);
+  virtual double getAvailableSpeed();
+  virtual double getCurrentPowerPeak();
+  virtual double getPowerPeakAt(int pstate_index);
+  virtual int getNbPstates();
+  virtual void setPowerPeakAt(int pstate_index);
+  virtual double getConsumedEnergy();
+
+  xbt_dict_t getProperties();
+
+  StoragePtr findStorageOnMountList(const char* storage);
+  xbt_dict_t getStorageList();
+  ActionPtr open(const char* mount, const char* path);
+  ActionPtr close(surf_file_t fd);
+  int unlink(surf_file_t fd);
+  ActionPtr ls(const char* mount, const char *path);
+  sg_storage_size_t getSize(surf_file_t fd);
+  ActionPtr read(surf_file_t fd, sg_storage_size_t size);
+  ActionPtr write(surf_file_t fd, sg_storage_size_t size);
+  xbt_dynar_t getInfo( surf_file_t fd);
+  sg_storage_size_t getFreeSize(const char* name);
+  sg_storage_size_t getUsedSize(const char* name);
+
+  bool isUsed();
+  //bool isShared();
+  xbt_dynar_t p_storage;
+  RoutingEdgePtr p_netElm;
+  CpuPtr p_cpu;
+  NetworkCm02LinkPtr p_network;
+};
+
+class WorkstationCLM03Lmm : public WorkstationCLM03, public ResourceLmm {
+public:
+  WorkstationCLM03Lmm(WorkstationModelPtr model, const char* name, xbt_dict_t props, xbt_dynar_t storage, RoutingEdgePtr netElm, CpuPtr cpu):
+         WorkstationCLM03(model, name, props, storage, netElm, cpu){};
+  e_surf_resource_state_t getState();
+};
+
+/**********
+ * Action *
+ **********/
+class WorkstationAction : virtual public Action {
+public:
+  WorkstationAction(ModelPtr model, double cost, bool failed): Action(model, cost, failed) {};
+};
+
+class WorkstationActionLmm : public ActionLmm, public WorkstationAction {
+public:
+  WorkstationActionLmm(ModelPtr model, double cost, bool failed): ActionLmm(model, cost, failed), WorkstationAction(model, cost, failed) {};
+};
+
+
+#endif /* WORKSTATION_HPP_ */
diff --git a/src/surf/workstation_ptask_L07.cpp b/src/surf/workstation_ptask_L07.cpp
new file mode 100644 (file)
index 0000000..507d25e
--- /dev/null
@@ -0,0 +1,861 @@
+/* Copyright (c) 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 "workstation_ptask_L07.hpp"
+#include "cpu.hpp"
+#include "surf_routing.hpp"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_workstation);
+
+static int ptask_host_count = 0;
+static xbt_dict_t ptask_parallel_task_link_set = NULL;
+lmm_system_t ptask_maxmin_system = NULL;
+
+WorkstationL07Model::WorkstationL07Model() : WorkstationModel("Workstation ptask_L07") {
+  if (!ptask_maxmin_system)
+       ptask_maxmin_system = lmm_system_new(1);
+  surf_workstation_model = NULL;
+  surf_network_model = new NetworkL07Model();
+  surf_cpu_model = new CpuL07Model();
+  routing_model_create(p_networkModel->createResource("__loopback__",
+                                                         498000000, NULL,
+                                                         0.000015, NULL,
+                                                         SURF_RESOURCE_ON, NULL,
+                                                         SURF_LINK_FATPIPE, NULL));
+}
+
+WorkstationL07Model::~WorkstationL07Model() {
+  xbt_dict_free(&ptask_parallel_task_link_set);
+
+  delete surf_cpu_model;
+  delete surf_network_model;
+  ptask_host_count = 0;
+
+  if (ptask_maxmin_system) {
+    lmm_system_free(ptask_maxmin_system);
+    ptask_maxmin_system = NULL;
+  }
+}
+
+double WorkstationL07Model::shareResources(double now)
+{
+  void *_action;
+  WorkstationL07ActionLmmPtr action;
+
+  xbt_swag_t running_actions = this->p_runningActionSet;
+  double min = this->shareResourcesMaxMin(running_actions,
+                                              ptask_maxmin_system,
+                                              bottleneck_solve);
+
+  xbt_swag_foreach(_action, running_actions) {
+       action = dynamic_cast<WorkstationL07ActionLmmPtr>(static_cast<ActionPtr>(_action));
+    if (action->m_latency > 0) {
+      if (min < 0) {
+        min = action->m_latency;
+        XBT_DEBUG("Updating min (value) with %p (start %f): %f", action,
+               action->m_start, min);
+      } else if (action->m_latency < min) {
+        min = action->m_latency;
+        XBT_DEBUG("Updating min (latency) with %p (start %f): %f", action,
+               action->m_start, min);
+      }
+    }
+  }
+
+  XBT_DEBUG("min value : %f", min);
+
+  return min;
+}
+
+void WorkstationL07Model::updateActionsState(double now, double delta)
+{
+  double deltap = 0.0;
+  void *_action, *_next_action;
+  WorkstationL07ActionLmmPtr action;
+
+  xbt_swag_foreach_safe(_action, _next_action, p_runningActionSet) {
+    action = dynamic_cast<WorkstationL07ActionLmmPtr>(static_cast<ActionPtr>(_action));
+
+    deltap = delta;
+    if (action->m_latency > 0) {
+      if (action->m_latency > deltap) {
+        double_update(&(action->m_latency), deltap);
+        deltap = 0.0;
+      } else {
+        double_update(&(deltap), action->m_latency);
+        action->m_latency = 0.0;
+      }
+      if ((action->m_latency == 0.0) && (action->m_suspended == 0)) {
+        action->updateBound();
+        lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 1.0);
+      }
+    }
+    XBT_DEBUG("Action (%p) : remains (%g) updated by %g.",
+           action, action->m_remains, lmm_variable_getvalue(action->p_variable) * delta);
+    double_update(&(action->m_remains), lmm_variable_getvalue(action->p_variable) * delta);
+
+    if (action->m_maxDuration != NO_MAX_DURATION)
+      double_update(&(action->m_maxDuration), delta);
+
+    XBT_DEBUG("Action (%p) : remains (%g).",
+           action, action->m_remains);
+    if ((action->m_remains <= 0) &&
+        (lmm_get_variable_weight(action->p_variable) > 0)) {
+      action->m_finish = surf_get_clock();
+      action->setState(SURF_ACTION_DONE);
+    } else if ((action->m_maxDuration != NO_MAX_DURATION) &&
+               (action->m_maxDuration <= 0)) {
+      action->m_finish = surf_get_clock();
+     action->setState(SURF_ACTION_DONE);
+    } else {
+      /* Need to check that none of the model has failed */
+      lmm_constraint_t cnst = NULL;
+      int i = 0;
+      void *constraint_id = NULL;
+
+      while ((cnst = lmm_get_cnst_from_var(ptask_maxmin_system, action->p_variable,
+                                    i++))) {
+        constraint_id = lmm_constraint_id(cnst);
+
+        if (static_cast<WorkstationCLM03LmmPtr>(constraint_id)->p_stateCurrent == SURF_RESOURCE_OFF) {
+          XBT_DEBUG("Action (%p) Failed!!", action);
+          action->m_finish = surf_get_clock();
+          action->setState(SURF_ACTION_FAILED);
+          break;
+        }
+      }
+    }
+  }
+  return;
+}
+
+ActionPtr WorkstationL07Model::executeParallelTask(int workstation_nb,
+                                                   void **workstation_list,
+                                                 double
+                                                 *computation_amount, double
+                                                 *communication_amount,
+                                                 double rate)
+{
+  WorkstationL07ActionLmmPtr action;
+  int i, j;
+  unsigned int cpt;
+  int nb_link = 0;
+  int nb_host = 0;
+  double latency = 0.0;
+
+  if (ptask_parallel_task_link_set == NULL)
+    ptask_parallel_task_link_set = xbt_dict_new_homogeneous(NULL);
+
+  xbt_dict_reset(ptask_parallel_task_link_set);
+
+  /* Compute the number of affected resources... */
+  for (i = 0; i < workstation_nb; i++) {
+    for (j = 0; j < workstation_nb; j++) {
+      xbt_dynar_t route=NULL;
+
+      if (communication_amount[i * workstation_nb + j] > 0) {
+        double lat=0.0;
+        unsigned int cpt;
+        void *_link;
+        LinkL07Ptr link;
+
+        routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
+                                                  static_cast<ResourcePtr>(
+                                                   workstation_list[i]))->p_netElm,
+                                                 dynamic_cast<WorkstationL07Ptr>(
+                                                  static_cast<ResourcePtr>(
+                                                       workstation_list[j]))->p_netElm,
+                                                 &route,
+                                                 &lat);
+        latency = MAX(latency, lat);
+
+        xbt_dynar_foreach(route, cpt, _link) {
+           link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(_link));
+           xbt_dict_set(ptask_parallel_task_link_set, link->m_name, link, NULL);
+        }
+      }
+    }
+  }
+
+  nb_link = xbt_dict_length(ptask_parallel_task_link_set);
+  xbt_dict_reset(ptask_parallel_task_link_set);
+
+  for (i = 0; i < workstation_nb; i++)
+    if (computation_amount[i] > 0)
+      nb_host++;
+
+  action = new WorkstationL07ActionLmm(this, 1, 0);
+  XBT_DEBUG("Creating a parallel task (%p) with %d cpus and %d links.",
+         action, workstation_nb, nb_link);
+  action->m_suspended = 0;        /* Should be useless because of the
+                                   calloc but it seems to help valgrind... */
+  action->m_workstationNb = workstation_nb;
+  action->p_workstationList = (WorkstationCLM03Ptr *) workstation_list;
+  action->p_computationAmount = computation_amount;
+  action->p_communicationAmount = communication_amount;
+  action->m_latency = latency;
+  action->m_rate = rate;
+
+  action->p_variable = lmm_variable_new(ptask_maxmin_system, action, 1.0,
+                       (action->m_rate > 0) ? action->m_rate : -1.0,
+                       workstation_nb + nb_link);
+
+  if (action->m_latency > 0)
+    lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 0.0);
+
+  for (i = 0; i < workstation_nb; i++)
+    lmm_expand(ptask_maxmin_system,
+              static_cast<CpuLmmPtr>(dynamic_cast<WorkstationL07Ptr>(
+                                          static_cast<ResourcePtr>(workstation_list[i]))->p_cpu)->p_constraint,
+               action->p_variable, computation_amount[i]);
+
+  for (i = 0; i < workstation_nb; i++) {
+    for (j = 0; j < workstation_nb; j++) {
+      void *_link;
+      LinkL07Ptr link;
+
+      xbt_dynar_t route=NULL;
+      if (communication_amount[i * workstation_nb + j] == 0.0)
+        continue;
+
+      routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
+                                         static_cast<ResourcePtr>(workstation_list[i]))->p_netElm,
+                                        dynamic_cast<WorkstationL07Ptr>(
+                                         static_cast<ResourcePtr>(workstation_list[j]))->p_netElm,
+                                           &route, NULL);
+
+      xbt_dynar_foreach(route, cpt, _link) {
+        link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(_link));
+        lmm_expand_add(ptask_maxmin_system, link->p_constraint,
+                       action->p_variable,
+                       communication_amount[i * workstation_nb + j]);
+      }
+    }
+  }
+
+  if (nb_link + nb_host == 0) {
+    action->m_cost = 1.0;
+    action->m_remains = 0.0;
+  }
+
+  return static_cast<ActionPtr>(action);
+}
+
+ResourcePtr WorkstationL07Model::createResource(const char *name, double power_scale,
+                               double power_initial,
+                               tmgr_trace_t power_trace,
+                               e_surf_resource_state_t state_initial,
+                               tmgr_trace_t state_trace,
+                               xbt_dict_t cpu_properties)
+{
+  WorkstationL07Ptr wk = NULL;
+  xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)),
+              "Host '%s' declared several times in the platform file.",
+              name);
+
+  wk = new WorkstationL07(this, name, cpu_properties,
+                                 static_cast<RoutingEdgePtr>(xbt_lib_get_or_null(host_lib, name, ROUTING_HOST_LEVEL)),
+                                 dynamic_cast<CpuPtr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(host_lib, name, SURF_CPU_LEVEL))));
+
+  xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, static_cast<ResourcePtr>(wk));
+
+  return wk;//FIXME:xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+ActionPtr WorkstationL07Model::communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst,
+                                       double size, double rate)
+{
+  void **workstation_list = xbt_new0(void *, 2);
+  double *computation_amount = xbt_new0(double, 2);
+  double *communication_amount = xbt_new0(double, 4);
+  ActionPtr res = NULL;
+
+  workstation_list[0] = static_cast<ResourcePtr>(src);
+  workstation_list[1] = static_cast<ResourcePtr>(dst);
+  communication_amount[1] = size;
+
+  res = executeParallelTask(2, workstation_list,
+                                    computation_amount,
+                                    communication_amount, rate);
+
+  return res;
+}
+
+xbt_dynar_t WorkstationL07Model::getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst)
+{
+  xbt_dynar_t route=NULL;
+  routing_platf->getRouteAndLatency(src->p_netElm, dst->p_netElm, &route, NULL);
+  return route;
+}
+
+ResourcePtr CpuL07Model::createResource(const char *name, double power_scale,
+                               double power_initial,
+                               tmgr_trace_t power_trace,
+                               e_surf_resource_state_t state_initial,
+                               tmgr_trace_t state_trace,
+                               xbt_dict_t cpu_properties)
+{
+  CpuL07Ptr cpu = NULL;
+  xbt_assert(!surf_workstation_resource_priv(surf_workstation_resource_by_name(name)),
+              "Host '%s' declared several times in the platform file.",
+              name);
+
+  cpu = new CpuL07(this, name, cpu_properties);
+
+  cpu->p_power.scale = power_scale;
+  xbt_assert(cpu->p_power.scale > 0, "Power has to be >0");
+
+  cpu->m_powerCurrent = power_initial;
+  if (power_trace)
+    cpu->p_power.event =
+        tmgr_history_add_trace(history, power_trace, 0.0, 0, static_cast<ResourcePtr>(cpu));
+
+  cpu->p_stateCurrent = state_initial;
+  if (state_trace)
+    cpu->p_stateEvent =
+        tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(cpu));
+
+  cpu->p_constraint =
+      lmm_constraint_new(ptask_maxmin_system, cpu,
+                         cpu->m_powerCurrent * cpu->p_power.scale);
+
+  xbt_lib_set(host_lib, name, SURF_CPU_LEVEL, static_cast<ResourcePtr>(cpu));
+
+  return cpu;//FIXME:xbt_lib_get_elm_or_null(host_lib, name);
+}
+
+ResourcePtr NetworkL07Model::createResource(const char *name,
+                                 double bw_initial,
+                                 tmgr_trace_t bw_trace,
+                                 double lat_initial,
+                                 tmgr_trace_t lat_trace,
+                                 e_surf_resource_state_t
+                                 state_initial,
+                                 tmgr_trace_t state_trace,
+                                 e_surf_link_sharing_policy_t
+                                 policy, xbt_dict_t properties)
+{
+  LinkL07Ptr nw_link = new LinkL07(this, xbt_strdup(name), properties);
+  xbt_assert(!xbt_lib_get_or_null(link_lib, name, SURF_LINK_LEVEL),
+              "Link '%s' declared several times in the platform file.",
+              name);
+
+  nw_link->m_bwCurrent = bw_initial;
+  if (bw_trace)
+    nw_link->p_bwEvent =
+        tmgr_history_add_trace(history, bw_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
+  nw_link->p_stateCurrent = state_initial;
+  nw_link->m_latCurrent = lat_initial;
+  if (lat_trace)
+    nw_link->p_latEvent =
+        tmgr_history_add_trace(history, lat_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
+  if (state_trace)
+    nw_link->p_stateEvent =
+        tmgr_history_add_trace(history, state_trace, 0.0, 0, static_cast<ResourcePtr>(nw_link));
+
+  nw_link->p_constraint =
+      lmm_constraint_new(ptask_maxmin_system, nw_link,
+                         nw_link->m_bwCurrent);
+
+  if (policy == SURF_LINK_FATPIPE)
+    lmm_constraint_shared(nw_link->p_constraint);
+
+  xbt_lib_set(link_lib, name, SURF_LINK_LEVEL, static_cast<ResourcePtr>(nw_link));
+  return nw_link;
+}
+
+void WorkstationL07Model::addTraces()
+{
+  xbt_dict_cursor_t cursor = NULL;
+  char *trace_name, *elm;
+
+  if (!trace_connect_list_host_avail)
+    return;
+
+  /* Connect traces relative to cpu */
+  xbt_dict_foreach(trace_connect_list_host_avail, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    CpuL07Ptr host = dynamic_cast<CpuL07Ptr>(
+                          static_cast<ResourcePtr>(
+                            surf_cpu_resource_priv(
+                              surf_cpu_resource_by_name(elm))));
+
+    xbt_assert(host, "Host %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    host->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(host));
+  }
+
+  xbt_dict_foreach(trace_connect_list_power, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    CpuL07Ptr host = dynamic_cast<CpuL07Ptr>(
+                          static_cast<ResourcePtr>(
+                            surf_cpu_resource_priv(
+                              surf_cpu_resource_by_name(elm))));
+
+    xbt_assert(host, "Host %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    host->p_power.event = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(host));
+  }
+
+  /* Connect traces relative to network */
+  xbt_dict_foreach(trace_connect_list_link_avail, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    LinkL07Ptr link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+    xbt_assert(link, "Link %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    link->p_stateEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+  }
+
+  xbt_dict_foreach(trace_connect_list_bandwidth, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    LinkL07Ptr link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+    xbt_assert(link, "Link %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    link->p_bwEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+  }
+
+  xbt_dict_foreach(trace_connect_list_latency, cursor, trace_name, elm) {
+    tmgr_trace_t trace = (tmgr_trace_t) xbt_dict_get_or_null(traces_set_list, trace_name);
+    LinkL07Ptr link = dynamic_cast<LinkL07Ptr>(static_cast<ResourcePtr>(xbt_lib_get_or_null(link_lib, elm, SURF_LINK_LEVEL)));
+
+    xbt_assert(link, "Link %s undefined", elm);
+    xbt_assert(trace, "Trace %s undefined", trace_name);
+
+    link->p_latEvent = tmgr_history_add_trace(history, trace, 0.0, 0, static_cast<ResourcePtr>(link));
+  }
+}
+
+/************
+ * Resource *
+ ************/
+
+WorkstationL07::WorkstationL07(WorkstationModelPtr model, const char* name, xbt_dict_t props, RoutingEdgePtr netElm, CpuPtr cpu)
+  : Resource(model, name, props), WorkstationCLM03Lmm(model, name, props, NULL, netElm, cpu)
+{
+}
+
+double WorkstationL07::getPowerPeakAt(int pstate_index)
+{
+       XBT_DEBUG("[ws_get_power_peak_at] Not implemented for workstation_ptask_L07");
+       return 0.0;
+}
+
+int WorkstationL07::getNbPstates()
+{
+       XBT_DEBUG("[ws_get_nb_pstates] Not implemented for workstation_ptask_L07");
+       return 0.0;
+}
+
+void WorkstationL07::setPowerPeakAt(int pstate_index)
+{
+       XBT_DEBUG("[ws_set_power_peak_at] Not implemented for workstation_ptask_L07");
+}
+
+double WorkstationL07::getConsumedEnergy()
+{
+       XBT_DEBUG("[ws_get_consumed_energy] Not implemented for workstation_ptask_L07");
+       return 0.0;
+}
+
+CpuL07::CpuL07(CpuL07ModelPtr model, const char* name, xbt_dict_t props)
+ : Resource(model, name, props), CpuLmm(model, name, props) {
+
+}
+
+LinkL07::LinkL07(NetworkL07ModelPtr model, const char* name, xbt_dict_t props)
+ : Resource(model, name, props), NetworkCm02LinkLmm(model, name, props) {
+
+}
+
+bool CpuL07::isUsed(){
+  return lmm_constraint_used(ptask_maxmin_system, p_constraint);
+}
+
+bool LinkL07::isUsed(){
+  return lmm_constraint_used(ptask_maxmin_system, p_constraint);
+}
+
+void CpuL07::updateState(tmgr_trace_event_t event_type, double value, double date){
+  XBT_DEBUG("Updating cpu %s (%p) with value %g", m_name, this, value);
+  if (event_type == p_power.event) {
+       m_powerCurrent = value;
+    lmm_update_constraint_bound(ptask_maxmin_system, p_constraint, m_powerCurrent * p_power.scale);
+    if (tmgr_trace_event_free(event_type))
+      p_power.event = NULL;
+  } else if (event_type == p_stateEvent) {
+    if (value > 0)
+      p_stateCurrent = SURF_RESOURCE_ON;
+    else
+      p_stateCurrent = SURF_RESOURCE_OFF;
+    if (tmgr_trace_event_free(event_type))
+      p_stateEvent = NULL;
+  } else {
+    XBT_CRITICAL("Unknown event ! \n");
+    xbt_abort();
+  }
+  return;
+}
+
+void LinkL07::updateState(tmgr_trace_event_t event_type, double value, double date){
+  XBT_DEBUG("Updating link %s (%p) with value=%f for date=%g", m_name, this, value, date);
+  if (event_type == p_bwEvent) {
+    m_bwCurrent = value;
+    lmm_update_constraint_bound(ptask_maxmin_system, p_constraint, m_bwCurrent);
+    if (tmgr_trace_event_free(event_type))
+      p_bwEvent = NULL;
+  } else if (event_type == p_latEvent) {
+    lmm_variable_t var = NULL;
+    WorkstationL07ActionLmmPtr action;
+    lmm_element_t elem = NULL;
+
+    m_latCurrent = value;
+    while ((var = lmm_get_var_from_cnst(ptask_maxmin_system, p_constraint, &elem))) {
+      action = (WorkstationL07ActionLmmPtr) lmm_variable_id(var);
+      action->updateBound();
+    }
+    if (tmgr_trace_event_free(event_type))
+      p_latEvent = NULL;
+  } else if (event_type == p_stateEvent) {
+    if (value > 0)
+      p_stateCurrent = SURF_RESOURCE_ON;
+    else
+      p_stateCurrent = SURF_RESOURCE_OFF;
+    if (tmgr_trace_event_free(event_type))
+      p_stateEvent = NULL;
+  } else {
+    XBT_CRITICAL("Unknown event ! \n");
+    xbt_abort();
+  }
+  return;
+}
+
+e_surf_resource_state_t WorkstationL07::getState()
+{
+  return p_cpu->p_stateCurrent;
+}
+
+e_surf_resource_state_t CpuL07::getState()
+{
+  return p_stateCurrent;
+}
+
+double CpuL07::getSpeed(double load)
+{
+  return load * p_power.scale;
+}
+
+double CpuL07::getAvailableSpeed()
+{
+  return m_powerCurrent;
+}
+
+ActionPtr WorkstationL07::execute(double size)
+{
+  void **workstation_list = xbt_new0(void *, 1);
+  double *computation_amount = xbt_new0(double, 1);
+  double *communication_amount = xbt_new0(double, 1);
+
+  workstation_list[0] = static_cast<ResourcePtr>(this);
+  communication_amount[0] = 0.0;
+  computation_amount[0] = size;
+
+  return static_cast<WorkstationL07ModelPtr>(p_model)->executeParallelTask(1, workstation_list,
+                                             computation_amount,
+                                     communication_amount, -1);
+}
+
+ActionPtr WorkstationL07::sleep(double duration)
+{
+  WorkstationL07ActionLmmPtr action = NULL;
+
+  XBT_IN("(%s,%g)", m_name, duration);
+
+  action = dynamic_cast<WorkstationL07ActionLmmPtr>(execute(1.0));
+  action->m_maxDuration = duration;
+  action->m_suspended = 2;
+  lmm_update_variable_weight(ptask_maxmin_system, action->p_variable, 0.0);
+
+  XBT_OUT();
+  return action;
+}
+
+double LinkL07::getBandwidth()
+{
+  return m_bwCurrent;
+}
+
+double LinkL07::getLatency()
+{
+  return m_latCurrent;
+}
+
+bool LinkL07::isShared()
+{
+  return lmm_constraint_is_shared(p_constraint);
+}
+
+/**********
+ * Action *
+ **********/
+
+WorkstationL07ActionLmm::~WorkstationL07ActionLmm(){
+  free(p_workstationList);
+  free(p_communicationAmount);
+  free(p_computationAmount);
+#ifdef HAVE_TRACING
+  xbt_free(p_category);
+#endif
+}
+
+void WorkstationL07ActionLmm::updateBound()
+{
+  double lat_current = 0.0;
+  double lat_bound = -1.0;
+  int i, j;
+
+  for (i = 0; i < m_workstationNb; i++) {
+    for (j = 0; j < m_workstationNb; j++) {
+      xbt_dynar_t route=NULL;
+
+      if (p_communicationAmount[i * m_workstationNb + j] > 0) {
+        double lat = 0.0;
+        routing_platf->getRouteAndLatency(dynamic_cast<WorkstationL07Ptr>(
+                                           static_cast<ResourcePtr>(((void**)p_workstationList)[i]))->p_netElm,
+                                          dynamic_cast<WorkstationL07Ptr>(
+                                           static_cast<ResourcePtr>(((void**)p_workstationList)[j]))->p_netElm,
+                                                         &route, &lat);
+
+        lat_current = MAX(lat_current, lat * p_communicationAmount[i * m_workstationNb + j]);
+      }
+    }
+  }
+  lat_bound = sg_tcp_gamma / (2.0 * lat_current);
+  XBT_DEBUG("action (%p) : lat_bound = %g", this, lat_bound);
+  if ((m_latency == 0.0) && (m_suspended == 0)) {
+    if (m_rate < 0)
+      lmm_update_variable_bound(ptask_maxmin_system, p_variable, lat_bound);
+    else
+      lmm_update_variable_bound(ptask_maxmin_system, p_variable, min(m_rate, lat_bound));
+  }
+}
+
+int WorkstationL07ActionLmm::unref()
+{
+  m_refcount--;
+  if (!m_refcount) {
+    xbt_swag_remove(static_cast<ActionPtr>(this), p_stateSet);
+    if (p_variable)
+      lmm_variable_free(ptask_maxmin_system, p_variable);
+    delete this;
+    return 1;
+  }
+  return 0;
+}
+
+void WorkstationL07ActionLmm::cancel()
+{
+  setState(SURF_ACTION_FAILED);
+  return;
+}
+
+void WorkstationL07ActionLmm::suspend()
+{
+  XBT_IN("(%p))", this);
+  if (m_suspended != 2) {
+    m_suspended = 1;
+    lmm_update_variable_weight(ptask_maxmin_system, p_variable, 0.0);
+  }
+  XBT_OUT();
+}
+
+void WorkstationL07ActionLmm::resume()
+{
+  XBT_IN("(%p)", this);
+  if (m_suspended != 2) {
+    lmm_update_variable_weight(ptask_maxmin_system, p_variable, 1.0);
+    m_suspended = 0;
+  }
+  XBT_OUT();
+}
+
+bool WorkstationL07ActionLmm::isSuspended()
+{
+  return m_suspended == 1;
+}
+
+void WorkstationL07ActionLmm::setMaxDuration(double duration)
+{                               /* FIXME: should inherit */
+  XBT_IN("(%p,%g)", this, duration);
+  m_maxDuration = duration;
+  XBT_OUT();
+}
+
+void WorkstationL07ActionLmm::setPriority(double priority)
+{                               /* FIXME: should inherit */
+  XBT_IN("(%p,%g)", this, priority);
+  m_priority = priority;
+  XBT_OUT();
+}
+
+double WorkstationL07ActionLmm::getRemains()
+{
+  XBT_IN("(%p)", this);
+  XBT_OUT();
+  return m_remains;
+}
+
+
+
+
+
+
+
+
+
+static void ptask_finalize(void)
+{
+  xbt_dict_free(&ptask_parallel_task_link_set);
+
+  delete surf_workstation_model;
+  surf_workstation_model = NULL;
+  delete surf_network_model;
+  surf_network_model = NULL;
+
+  ptask_host_count = 0;
+
+  if (ptask_maxmin_system) {
+    lmm_system_free(ptask_maxmin_system);
+    ptask_maxmin_system = NULL;
+  }
+}
+
+/**************************************/
+/******* Resource Private    **********/
+/**************************************/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************/
+/*** Resource Creation & Destruction **/
+/**************************************/
+
+static void ptask_parse_workstation_init(sg_platf_host_cbarg_t host)
+{
+  double power_peak = xbt_dynar_get_as(host->power_peak, host->pstate, double);
+  //cpu->power_peak = power_peak;
+  xbt_dynar_free(&(host->power_peak));  /* kill memory leak */
+  static_cast<WorkstationL07ModelPtr>(surf_workstation_model)->createResource(
+      host->id,
+      power_peak,
+      host->power_scale,
+      host->power_trace,
+      host->initial_state,
+      host->state_trace,
+      host->properties);
+}
+
+static void ptask_parse_cpu_init(sg_platf_host_cbarg_t host)
+{
+  double power_peak = xbt_dynar_get_as(host->power_peak, host->pstate, double);
+  static_cast<CpuL07ModelPtr>(surf_cpu_model)->createResource(
+      host->id,
+      power_peak,
+      host->power_scale,
+      host->power_trace,
+      host->initial_state,
+      host->state_trace,
+      host->properties);
+}
+
+
+
+static void ptask_parse_link_init(sg_platf_link_cbarg_t link)
+{
+  if (link->policy == SURF_LINK_FULLDUPLEX) {
+    char *link_id;
+    link_id = bprintf("%s_UP", link->id);
+    static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link_id,
+                               link->bandwidth,
+                               link->bandwidth_trace,
+                               link->latency,
+                               link->latency_trace,
+                               link->state,
+                               link->state_trace,
+                               link->policy,
+                               link->properties);
+    xbt_free(link_id);
+    link_id = bprintf("%s_DOWN", link->id);
+    static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link_id,
+                               link->bandwidth,
+                               link->bandwidth_trace,
+                               link->latency,
+                               link->latency_trace,
+                               link->state,
+                               link->state_trace,
+                               link->policy,
+                               NULL); /* FIXME: We need to deep copy the
+                                       * properties or we won't be able to free
+                                       * it */
+    xbt_free(link_id);
+  } else {
+         static_cast<NetworkL07ModelPtr>(surf_network_model)->createResource(link->id,
+                               link->bandwidth,
+                               link->bandwidth_trace,
+                               link->latency,
+                               link->latency_trace,
+                               link->state,
+                               link->state_trace,
+                               link->policy,
+                               link->properties);
+  }
+
+  current_property_set = NULL;
+}
+
+static void ptask_add_traces(){
+  static_cast<WorkstationL07ModelPtr>(surf_workstation_model)->addTraces();
+}
+
+static void ptask_define_callbacks()
+{
+  sg_platf_host_add_cb(ptask_parse_cpu_init);
+  sg_platf_host_add_cb(ptask_parse_workstation_init);
+  sg_platf_link_add_cb(ptask_parse_link_init);
+  sg_platf_postparse_add_cb(ptask_add_traces);
+}
+
+/**************************************/
+/*************** Generic **************/
+/**************************************/
+void surf_workstation_model_init_ptask_L07(void)
+{
+  XBT_INFO("surf_workstation_model_init_ptask_L07");
+  xbt_assert(!surf_cpu_model, "CPU model type already defined");
+  xbt_assert(!surf_network_model, "network model type already defined");
+  ptask_define_callbacks();
+  surf_workstation_model = new WorkstationL07Model();
+  ModelPtr model = static_cast<ModelPtr>(surf_workstation_model);
+  xbt_dynar_push(model_list, &model);
+}
diff --git a/src/surf/workstation_ptask_L07.hpp b/src/surf/workstation_ptask_L07.hpp
new file mode 100644 (file)
index 0000000..0cd7713
--- /dev/null
@@ -0,0 +1,184 @@
+#include "workstation.hpp"
+
+#ifndef WORKSTATION_L07_HPP_
+#define WORKSTATION_L07_HPP_
+
+/***********
+ * Classes *
+ ***********/
+
+class WorkstationL07Model;
+typedef WorkstationL07Model *WorkstationL07ModelPtr;
+
+class CpuL07Model;
+typedef CpuL07Model *CpuL07ModelPtr;
+
+class NetworkL07Model;
+typedef NetworkL07Model *NetworkL07ModelPtr;
+
+class WorkstationL07;
+typedef WorkstationL07 *WorkstationL07Ptr;
+
+class CpuL07;
+typedef CpuL07 *CpuL07Ptr;
+
+class LinkL07;
+typedef LinkL07 *LinkL07Ptr;
+
+class WorkstationL07ActionLmm;
+typedef WorkstationL07ActionLmm *WorkstationL07ActionLmmPtr;
+
+/*FIXME:class WorkstationActionLmm;
+typedef WorkstationActionLmm *WorkstationActionLmmPtr;*/
+
+/*********
+ * Tools *
+ *********/
+
+/*********
+ * Model *
+ *********/
+class WorkstationL07Model : public WorkstationModel {
+public:
+  WorkstationL07Model();
+  ~WorkstationL07Model();
+
+  double shareResources(double now);
+  void updateActionsState(double now, double delta);
+  ResourcePtr createResource(const char *name, double power_scale,
+                                 double power_initial,
+                                 tmgr_trace_t power_trace,
+                                 e_surf_resource_state_t state_initial,
+                                 tmgr_trace_t state_trace,
+                                 xbt_dict_t cpu_properties);
+  ActionPtr executeParallelTask(int workstation_nb,
+                                        void **workstation_list,
+                                        double *computation_amount,
+                                        double *communication_amount,
+                                        double rate);
+  xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst);
+  ActionPtr communicate(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst, double size, double rate);
+  void addTraces();
+  CpuL07ModelPtr p_cpuModel;
+  NetworkL07ModelPtr p_networkModel;
+};
+
+class CpuL07Model : public CpuModel {
+public:
+  CpuL07Model() : CpuModel("cpuL07") {};
+  ~CpuL07Model() {surf_cpu_model = NULL;};
+  ResourcePtr createResource(const char *name, double power_scale,
+                                 double power_initial,
+                                 tmgr_trace_t power_trace,
+                                 e_surf_resource_state_t state_initial,
+                                 tmgr_trace_t state_trace,
+                                 xbt_dict_t cpu_properties);
+  void addTraces() {DIE_IMPOSSIBLE;};
+  WorkstationL07ModelPtr p_workstationModel;
+};
+
+class NetworkL07Model : public NetworkCm02Model {
+public:
+  NetworkL07Model() : NetworkCm02Model(0) {};
+  ~NetworkL07Model() {surf_network_model = NULL;};
+  ResourcePtr createResource(const char *name,
+                                                  double bw_initial,
+                                                  tmgr_trace_t bw_trace,
+                                                  double lat_initial,
+                                                  tmgr_trace_t lat_trace,
+                                                  e_surf_resource_state_t
+                                                  state_initial,
+                                                  tmgr_trace_t state_trace,
+                                                  e_surf_link_sharing_policy_t
+                                                  policy, xbt_dict_t properties);
+
+  xbt_dynar_t getRoute(WorkstationCLM03Ptr src, WorkstationCLM03Ptr dst) {DIE_IMPOSSIBLE;};
+  ActionPtr communicate(RoutingEdgePtr src, RoutingEdgePtr dst, double size, double rate) {DIE_IMPOSSIBLE;};
+  void addTraces() {DIE_IMPOSSIBLE;};
+  WorkstationL07ModelPtr p_workstationModel;
+};
+
+/************
+ * Resource *
+ ************/
+
+class WorkstationL07 : public WorkstationCLM03Lmm {
+public:
+  WorkstationL07(WorkstationModelPtr model, const char* name, xbt_dict_t props, RoutingEdgePtr netElm, CpuPtr cpu);
+  //bool isUsed();
+  bool isUsed() {DIE_IMPOSSIBLE;};
+  void updateState(tmgr_trace_event_t event_type, double value, double date) {DIE_IMPOSSIBLE;};
+  ActionPtr execute(double size);
+  ActionPtr sleep(double duration);
+  e_surf_resource_state_t getState();
+  double getPowerPeakAt(int pstate_index);
+  int getNbPstates();
+  void setPowerPeakAt(int pstate_index);
+  double getConsumedEnergy();
+};
+
+class CpuL07 : public CpuLmm {
+public:
+  CpuL07(CpuL07ModelPtr model, const char* name, xbt_dict_t properties);
+  bool isUsed();
+  //bool isUsed() {DIE_IMPOSSIBLE;};
+  void updateState(tmgr_trace_event_t event_type, double value, double date);
+  e_surf_resource_state_t getState();
+  double getSpeed(double load);
+  double getAvailableSpeed();
+  ActionPtr execute(double size) {DIE_IMPOSSIBLE;};
+  ActionPtr sleep(double duration) {DIE_IMPOSSIBLE;};
+
+  double getCurrentPowerPeak() {};
+  double getPowerPeakAt(int pstate_index) {};
+  int getNbPstates() {};
+  void setPowerPeakAt(int pstate_index) {};
+  double getConsumedEnergy() {};
+
+  double m_powerCurrent;
+};
+
+class LinkL07 : public NetworkCm02LinkLmm {
+public:
+  LinkL07(NetworkL07ModelPtr model, const char* name, xbt_dict_t props);
+  bool isUsed();
+  void updateState(tmgr_trace_event_t event_type, double value, double date);
+  double getBandwidth();
+  double getLatency();
+  bool isShared();
+
+  double m_latCurrent;
+  tmgr_trace_event_t p_latEvent;
+  double m_bwCurrent;
+  tmgr_trace_event_t p_bwEvent;
+};
+
+/**********
+ * Action *
+ **********/
+class WorkstationL07ActionLmm : public WorkstationActionLmm {
+public:
+  WorkstationL07ActionLmm(ModelPtr model, double cost, bool failed)
+  : Action(model, cost, failed), WorkstationActionLmm(model, cost, failed) {};
+ ~WorkstationL07ActionLmm();
+
+  void updateBound();
+
+  int unref();
+  void cancel();
+  void suspend();
+  void resume();
+  bool isSuspended();
+  void setMaxDuration(double duration);
+  void setPriority(double priority);
+  double getRemains();
+
+  int m_workstationNb;
+  WorkstationCLM03Ptr *p_workstationList;
+  double *p_computationAmount;
+  double *p_communicationAmount;
+  double m_latency;
+  double m_rate;
+};
+
+#endif /* WORKSTATION_L07_HPP_ */
index 9d2aee7..fd81fda 100644 (file)
@@ -681,7 +681,6 @@ static void xbt_log_connect_categories(void)
   XBT_LOG_CONNECT(surf_lagrange_dichotomy);
   XBT_LOG_CONNECT(surf_maxmin);
   XBT_LOG_CONNECT(surf_network);
-  XBT_LOG_CONNECT(surf_new_model);
 #ifdef HAVE_GTNETS
   XBT_LOG_CONNECT(surf_network_gtnets);
   XBT_LOG_CONNECT(surf_network_gtnets_interface);
index 47dc3ba..a5430b2 100644 (file)
@@ -14,7 +14,6 @@
 #include "xbt/log.h"
 #include "xbt/swag.h"
 
-
 /** Creates a new swag.
  * \param offset where the hookup is located in the structure
  * \see xbt_swag_offset
index 46ae1b4..0b735e4 100644 (file)
@@ -160,8 +160,8 @@ int main(int argc, char **argv)
 
     // Routers
     xbt_lib_foreach(as_router_lib, cursor_src, key, value1) {
-      if(((sg_routing_edge_t)xbt_lib_get_or_null(as_router_lib, key,
-          ROUTING_ASR_LEVEL))->rc_type == SURF_NETWORK_ELEMENT_ROUTER)
+      if(surf_routing_edge_get_rc_type(xbt_lib_get_or_null(as_router_lib, key,
+          ROUTING_ASR_LEVEL)) == SURF_NETWORK_ELEMENT_ROUTER)
       {
         printf("  <router id=\"%s\"/>\n",key);
       }
@@ -203,7 +203,7 @@ int main(int argc, char **argv)
         {
           void *link = xbt_dynar_get_as(route,i,void *);
 
-          char *link_name = xbt_strdup(((surf_resource_t)link)->name);
+          char *link_name = xbt_strdup(surf_resource_name(link));
           printf("<%s id=\"%s\"/>",link_ctn,link_name);
           free(link_name);
         }
@@ -222,7 +222,7 @@ int main(int argc, char **argv)
           {
             void *link = xbt_dynar_get_as(route,i,void *);
 
-            char *link_name = xbt_strdup(((surf_resource_t)link)->name);
+            char *link_name = xbt_strdup(surf_resource_name(link));
             printf("<%s id=\"%s\"/>",link_ctn,link_name);
             free(link_name);
           }
@@ -248,7 +248,7 @@ int main(int argc, char **argv)
             {
               void *link = xbt_dynar_get_as(route,i,void *);
 
-              char *link_name = xbt_strdup(((surf_resource_t)link)->name);
+              char *link_name = xbt_strdup(surf_resource_name(link));
               printf("<%s id=\"%s\"/>",link_ctn,link_name);
               free(link_name);
             }
@@ -266,7 +266,7 @@ int main(int argc, char **argv)
           {
             void *link = xbt_dynar_get_as(route,i,void *);
 
-            char *link_name = xbt_strdup(((surf_resource_t)link)->name);
+            char *link_name = xbt_strdup(surf_resource_name(link));
             printf("<%s id=\"%s\"/>",link_ctn,link_name);
             free(link_name);
           }
index 1a922a8..1fb6436 100644 (file)
@@ -63,18 +63,18 @@ void test(char *platform)
   cpuB = surf_cpu_resource_by_name("Cpu B");
 
   /* Let's check that those two processors exist */
-  XBT_DEBUG("%s : %p", surf_resource_name(cpuA), cpuA);
-  XBT_DEBUG("%s : %p", surf_resource_name(cpuB), cpuB);
+  XBT_DEBUG("%s : %p", surf_resource_name(surf_cpu_resource_priv(cpuA)), cpuA);
+  XBT_DEBUG("%s : %p", surf_resource_name(surf_cpu_resource_priv(cpuB)), cpuB);
 
   /* Let's do something on it */
-  actionA = surf_cpu_model->extension.cpu.execute(cpuA, 1000.0);
-  actionB = surf_cpu_model->extension.cpu.execute(cpuB, 1000.0);
-  actionC = surf_cpu_model->extension.cpu.sleep(cpuB, 7.32);
+  actionA = surf_cpu_execute(cpuA, 1000.0);
+  actionB = surf_cpu_execute(cpuB, 1000.0);
+  actionC = surf_cpu_sleep(cpuB, 7.32);
 
   /* Use whatever calling style you want... */
-  stateActionA = surf_cpu_model->action_state_get(actionA);     /* When you know actionA model type */
-  stateActionB = actionB->model_type->action_state_get(actionB);        /* If you're unsure about it's model type */
-  stateActionC = surf_cpu_model->action_state_get(actionC);     /* When you know actionA model type */
+  stateActionA = surf_action_get_state(actionA);     /* When you know actionA model type */
+  stateActionB = surf_action_get_state(actionB);        /* If you're unsure about it's model type */
+  stateActionC = surf_action_get_state(actionC);     /* When you know actionA model type */
 
   /* And just look at the state of these tasks */
   XBT_DEBUG("actionA : %p (%s)", actionA, string_action(stateActionA));
@@ -87,12 +87,11 @@ void test(char *platform)
   cardB = sg_routing_edge_by_name_or_null("Cpu B");
 
   /* Let's check that those two processors exist */
-  XBT_DEBUG("%s : %p", surf_resource_name(cardA), cardA);
-  XBT_DEBUG("%s : %p", surf_resource_name(cardB), cardB);
+  XBT_DEBUG("%s : %p", surf_routing_edge_name(cardA), cardA);
+  XBT_DEBUG("%s : %p", surf_routing_edge_name(cardB), cardB);
 
   /* Let's do something on it */
-  surf_network_model->extension.network.communicate(cardA, cardB,
-                                                    150.0, -1.0);
+  surf_network_model_communicate(surf_network_model, cardA, cardB, 150.0, -1.0);
 
   surf_solve(-1.0);                 /* Takes traces into account. Returns 0.0 */
   do {
@@ -101,31 +100,29 @@ void test(char *platform)
     XBT_DEBUG("Next Event : %g", now);
     XBT_DEBUG("\t CPU actions");
     while ((action =
-            xbt_swag_extract(surf_cpu_model->states.failed_action_set))) {
+            xbt_swag_extract(surf_model_failed_action_set((surf_model_t)surf_cpu_model)))) {
       XBT_DEBUG("\t * Failed : %p", action);
-      action->model_type->action_unref(action);
+      surf_action_unref(action);
     }
     while ((action =
-            xbt_swag_extract(surf_cpu_model->states.done_action_set))) {
+            xbt_swag_extract(surf_model_done_action_set((surf_model_t)surf_cpu_model)))) {
       XBT_DEBUG("\t * Done : %p", action);
-      action->model_type->action_unref(action);
+      surf_action_unref(action);
     }
     XBT_DEBUG("\t Network actions");
     while ((action =
-            xbt_swag_extract(surf_network_model->states.
-                             failed_action_set))) {
+            xbt_swag_extract(surf_model_failed_action_set((surf_model_t)surf_network_model)))) {
       XBT_DEBUG("\t * Failed : %p", action);
-      action->model_type->action_unref(action);
+      surf_action_unref(action);
     }
     while ((action =
-            xbt_swag_extract(surf_network_model->states.
-                             done_action_set))) {
+            xbt_swag_extract(surf_model_done_action_set((surf_model_t)surf_network_model)))) {
       XBT_DEBUG("\t * Done : %p", action);
-      action->model_type->action_unref(action);
+      surf_action_unref(action);
     }
 
-  } while ((xbt_swag_size(surf_network_model->states.running_action_set) ||
-            xbt_swag_size(surf_cpu_model->states.running_action_set)) &&
+  } while ((xbt_swag_size(surf_model_running_action_set((surf_model_t)surf_network_model)) ||
+            xbt_swag_size(surf_model_running_action_set((surf_model_t)surf_cpu_model))) &&
            surf_solve(-1.0) >= 0.0);
 
   XBT_DEBUG("Simulation Terminated");
index 896f959..d07a552 100644 (file)
@@ -62,12 +62,11 @@ void test(char *platform)
   XBT_DEBUG("%s : %p", surf_resource_name(workstationB), workstationB);
 
   /* Let's do something on it */
-  surf_workstation_model->extension.workstation.execute(workstationA, 1000.0);
-  surf_workstation_model->extension.workstation.execute(workstationB, 1000.0);
-      surf_workstation_model->extension.workstation.sleep(workstationB, 7.32);
+  surf_workstation_execute(workstationA, 1000.0);
+  surf_workstation_execute(workstationB, 1000.0);
+  surf_workstation_sleep(workstationB, 7.32);
 
-  surf_workstation_model->extension.workstation.
-      communicate(workstationA, workstationB, 150.0, -1.0);
+  surf_workstation_model_communicate(surf_workstation_model, workstationA, workstationB, 150.0, -1.0);
 
   surf_solve(-1.0);                 /* Takes traces into account. Returns 0.0 */
   do {
@@ -80,17 +79,17 @@ void test(char *platform)
     XBT_DEBUG("Next Event : %g", now);
 
     xbt_dynar_foreach(model_list, iter, model) {
-      XBT_DEBUG("\t %s actions", model->name);
-      while ((action = xbt_swag_extract(model->states.failed_action_set))) {
+      XBT_DEBUG("\t %s actions", surf_model_name(model));
+      while ((action = xbt_swag_extract(surf_model_failed_action_set((surf_model_t)model)))) {
         XBT_DEBUG("\t * Failed : %p", action);
-        model->action_unref(action);
+        surf_action_unref(action);
       }
-      while ((action = xbt_swag_extract(model->states.done_action_set))) {
+      while ((action = xbt_swag_extract(surf_model_done_action_set((surf_model_t)model)))) {
         XBT_DEBUG("\t * Done : %p", action);
-        model->action_unref(action);
+        surf_action_unref(action);
       }
-      if (xbt_swag_size(model->states.running_action_set)) {
-        XBT_DEBUG("running %s", model->name);
+      if (xbt_swag_size(surf_model_running_action_set((surf_model_t)model))) {
+        XBT_DEBUG("running %s", surf_model_name(model));
         running = 1;
       }
     }