Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into 'rework-energy-plugin'
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Fri, 27 Sep 2019 22:01:57 +0000 (00:01 +0200)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Fri, 27 Sep 2019 22:01:57 +0000 (00:01 +0200)
# Conflicts:
#   include/simgrid/plugins/energy.h

183 files changed:
.mailmap
CMakeLists.txt
ChangeLog
MANIFEST.in
NEWS
README.coding
README.md
docs/source/Configuring_SimGrid.rst
docs/source/Tutorial_Algorithms.rst
docs/source/XML_Reference.rst
docs/source/app_s4u.rst
docs/source/platform.rst
docs/source/platform_howtos.rst
examples/deprecated/java/io/file/Node.java
examples/deprecated/java/io/file/io-file.tesh
examples/deprecated/java/io/storage/io-storage.tesh
examples/deprecated/simdag/scheduling/sd_scheduling.c
examples/platforms/hosts_with_disks.xml [new file with mode: 0644]
examples/platforms/ns3-big-cluster.xml [new file with mode: 0644]
examples/platforms/storage/content/win_storage_content.txt [deleted file]
examples/platforms/storage/remote_io.xml
examples/platforms/storage/storage.xml
examples/platforms/wifi.xml [new file with mode: 0755]
examples/s4u/CMakeLists.txt
examples/s4u/README.rst
examples/s4u/io-async/s4u-io-async.cpp
examples/s4u/io-async/s4u-io-async.tesh
examples/s4u/io-disk-raw/s4u-io-disk-raw.cpp [new file with mode: 0644]
examples/s4u/io-disk-raw/s4u-io-disk-raw.tesh [new file with mode: 0644]
examples/s4u/io-file-remote/s4u-io-file-remote.cpp
examples/s4u/io-file-remote/s4u-io-file-remote.tesh
examples/s4u/io-file-remote/s4u-io-file-remote_d.xml
examples/s4u/io-file-system/s4u-io-file-system.cpp
examples/s4u/io-file-system/s4u-io-file-system.tesh
examples/s4u/io-storage-raw/s4u-io-storage-raw.cpp [deleted file]
examples/s4u/io-storage-raw/s4u-io-storage-raw.tesh [deleted file]
examples/s4u/replay-io/s4u-replay-io.cpp [moved from examples/s4u/replay-storage/s4u-replay-storage.cpp with 85% similarity]
examples/s4u/replay-io/s4u-replay-io.tesh [new file with mode: 0644]
examples/s4u/replay-io/s4u-replay-io.txt [new file with mode: 0644]
examples/s4u/replay-io/s4u-replay-io_d.xml [moved from examples/s4u/replay-storage/s4u-replay-storage_d.xml with 75% similarity]
examples/s4u/replay-storage/s4u-replay-storage.tesh [deleted file]
examples/s4u/replay-storage/s4u-replay-storage.txt [deleted file]
examples/smpi/ampi_test/ampi_test.tesh
examples/smpi/replay/replay-override-replayer.tesh
examples/smpi/replay/replay.tesh
examples/smpi/trace/trace.tesh
include/simgrid/actor.h
include/simgrid/forward.h
include/simgrid/host.h
include/simgrid/msg.h
include/simgrid/plugins/energy.h
include/simgrid/plugins/file_system.h
include/simgrid/plugins/live_migration.h
include/simgrid/s4u.hpp
include/simgrid/s4u/Disk.hpp [new file with mode: 0644]
include/simgrid/s4u/Engine.hpp
include/simgrid/s4u/Host.hpp
include/simgrid/s4u/Io.hpp
include/simgrid/s4u/Link.hpp
include/simgrid/s4u/Storage.hpp
include/simgrid/simdag.h
include/simgrid/smpi/replay.hpp
include/smpi/sampi.h
include/smpi/smpi.h
include/smpi/smpi_extended_traces.h
include/smpi/smpi_extended_traces_fortran.h
include/smpi/smpi_helpers.h
include/smpi/smpi_helpers_internal.h
include/xbt/Extendable.hpp
include/xbt/asserts.h
include/xbt/base.h
include/xbt/dict.h
include/xbt/dynar.h
include/xbt/ex.h
include/xbt/log.h
src/bindings/java/jxbt_utilities.hpp
src/bindings/lua/lua_platf.cpp
src/bindings/lua/lua_private.hpp
src/include/xxhash.hpp [new file with mode: 0644]
src/instr/instr_config.cpp
src/instr/instr_platform.cpp
src/instr/instr_smpi.hpp
src/kernel/EngineImpl.cpp
src/kernel/activity/IoImpl.cpp
src/kernel/activity/IoImpl.hpp
src/kernel/activity/SleepImpl.cpp
src/kernel/actor/ActorImpl.cpp
src/kernel/actor/ActorImpl.hpp
src/kernel/resource/DiskImpl.cpp [new file with mode: 0644]
src/kernel/resource/DiskImpl.hpp [new file with mode: 0644]
src/mc/Transition.hpp
src/mc/checker/CommunicationDeterminismChecker.cpp
src/mc/checker/LivenessChecker.cpp
src/mc/checker/SafetyChecker.cpp
src/mc/checker/SimcallInspector.hpp
src/mc/mc_state.cpp
src/mc/mc_state.hpp
src/mc/sosp/PageStore.cpp
src/msg/msg_legacy.cpp
src/plugins/file_system/s4u_FileSystem.cpp
src/plugins/host_energy.cpp
src/plugins/link_energy.cpp
src/plugins/vm/VirtualMachineImpl.cpp
src/s4u/s4u_Actor.cpp
src/s4u/s4u_Disk.cpp [new file with mode: 0644]
src/s4u/s4u_Engine.cpp
src/s4u/s4u_Host.cpp
src/s4u/s4u_Io.cpp
src/s4u/s4u_Link.cpp
src/simgrid/sg_config.cpp
src/simix/smx_global.cpp
src/smpi/bindings/smpi_mpi.cpp
src/smpi/bindings/smpi_pmpi.cpp
src/smpi/bindings/smpi_pmpi_coll.cpp
src/smpi/bindings/smpi_pmpi_file.cpp
src/smpi/bindings/smpi_pmpi_group.cpp
src/smpi/bindings/smpi_pmpi_request.cpp
src/smpi/include/private.hpp
src/smpi/include/smpi_actor.hpp
src/smpi/include/smpi_f2c.hpp
src/smpi/include/smpi_group.hpp
src/smpi/include/smpi_request.hpp
src/smpi/internals/instr_smpi.cpp
src/smpi/internals/smpi_actor.cpp
src/smpi/internals/smpi_deployment.cpp
src/smpi/internals/smpi_global.cpp
src/smpi/internals/smpi_memory.cpp
src/smpi/internals/smpi_replay.cpp
src/smpi/mpi/smpi_comm.cpp
src/smpi/mpi/smpi_datatype.cpp
src/smpi/mpi/smpi_group.cpp
src/smpi/mpi/smpi_op.cpp
src/smpi/mpi/smpi_request.cpp
src/surf/HostImpl.cpp
src/surf/HostImpl.hpp
src/surf/disk_s19.cpp [new file with mode: 0644]
src/surf/disk_s19.hpp [new file with mode: 0644]
src/surf/host_clm03.cpp
src/surf/network_cm02.cpp
src/surf/network_interface.hpp
src/surf/network_ns3.cpp
src/surf/ns3/ns3_simulator.cpp
src/surf/sg_platf.cpp
src/surf/surf_c_bindings.cpp
src/surf/surf_interface.cpp
src/surf/surf_interface.hpp
src/surf/xml/platf_private.hpp
src/surf/xml/surfxml_sax_cb.cpp
src/xbt/exception.cpp
src/xbt/mmalloc/mmprivate.h
src/xbt/xbt_log_layout_format.cpp
src/xbt/xbt_main.cpp
teshsuite/msg/io-file-remote/io-file-remote.tesh
teshsuite/msg/io-file-remote/io-file-remote_d.xml
teshsuite/msg/io-file/io-file.c
teshsuite/msg/io-file/io-file.tesh
teshsuite/msg/io-raw-storage/io-raw-storage.tesh
teshsuite/s4u/CMakeLists.txt
teshsuite/s4u/cloud-sharing/cloud-sharing.cpp
teshsuite/s4u/concurrent_rw/concurrent_rw.cpp
teshsuite/s4u/concurrent_rw/concurrent_rw.tesh
teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.cpp [new file with mode: 0644]
teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.tesh [new file with mode: 0644]
teshsuite/s4u/storage_client_server/storage_client_server.cpp
teshsuite/s4u/storage_client_server/storage_client_server.tesh
teshsuite/smpi/io-all-at/io-all-at.tesh
teshsuite/smpi/io-all/io-all.tesh
teshsuite/smpi/io-ordered/io-ordered.tesh
teshsuite/smpi/io-shared/io-shared.tesh
teshsuite/smpi/io-simple-at/io-simple-at.tesh
teshsuite/smpi/io-simple/io-simple.tesh
teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt
teshsuite/smpi/mpich3-test/pt2pt/bsendpending.c
teshsuite/smpi/mpich3-test/pt2pt/rqfreeb.c
teshsuite/smpi/mpich3-test/pt2pt/testlist
teshsuite/surf/CMakeLists.txt
teshsuite/surf/lmm_usage/lmm_usage.cpp
teshsuite/surf/wifi_usage/wifi_usage.cpp [new file with mode: 0644]
teshsuite/surf/wifi_usage/wifi_usage.tesh [new file with mode: 0644]
teshsuite/xbt/mmalloc/mmalloc_test.cpp
tools/cmake/DefinePackages.cmake
tools/cmake/Flags.cmake
tools/jenkins/Coverage.sh

index 9c21520..78ddb54 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -31,6 +31,7 @@ Tom Cornebize <tom.cornebize@ensimag.grenoble-inp.fr> <Ezibenroc@users.noreply.g
 Gabriel Corona <gabriel.corona@loria.fr> <coron00b@barbecue.loria.fr>
 Gabriel Corona <gabriel.corona@loria.fr> <gabriel.corona@enst-bretagne.fr>
 Augustin Degomme <adegomme@gmail.com>
+Augustin Degomme <adegomme@gmail.com> <13270544+adegomme@users.noreply.github.com>
 Augustin Degomme <adegomme@gmail.com> <ad254919@cardamome.intra.cea.fr>
 Augustin Degomme <adegomme@gmail.com> <adegomme@users.noreply.github.com>
 Augustin Degomme <adegomme@gmail.com> <augustin.degomme@imag.fr>
@@ -59,6 +60,7 @@ Arnaud Giersch <arnaud.giersch@univ-fcomte.fr> <agiersch@48e7efb5-ca39-0410-a469
 Arnaud Giersch <arnaud.giersch@univ-fcomte.fr> <arnaud.giersch@free.fr>
 Arnaud Giersch <arnaud.giersch@univ-fcomte.fr> <arnaud.giersch@iut-bm.univ-fcomte.fr>
 Julien Gossa <julien.gossa@unistra.fr> <gossa@unistra.fr>
+Loic Guegan <manzerbredes@mailbox.org> <manzerberdes@gmx.com>
 Marion Guthmuller <marion.guthmuller@inria.fr> <marion.guthmuller@loria.fr>
 Ahmed Harbaoui <amad206@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
 Christian Heinrich <franz-christian.heinrich@inria.fr> <christian.heinrich@livando.com>
index 2ed6e4c..94a78f4 100644 (file)
@@ -411,6 +411,8 @@ if (enable_model-checking AND enable_ns3)
   message(FATAL_ERROR "Cannot activate both model-checking and ns-3 bindings: ns-3 pull too much dependencies for the MC to work")
 endif()
 
+get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
+
 if(enable_smpi)
   SET(HAVE_SMPI 1)
   if(NOT WIN32)
@@ -773,12 +775,18 @@ if(enable_java)
   include(${CMAKE_HOME_DIRECTORY}/tools/cmake/Java.cmake)
 endif()
 
+if (enable_model-checking AND (NOT ("cxx_std_14" IN_LIST known_features)))
+  message(WARNING "C++14 not found. The model-checker will use a slow hash function. You should upgrade your compiler")
+  set(SG_HAVE_CPP14 0)
+else()
+  set(SG_HAVE_CPP14 1)
+  set_property(TARGET simgrid PROPERTY CXX_STANDARD 14)    
+endif()
+
 # Python binding (with pybind11)
 ################
 # Our usage of pybind11::overload_cast mandates C++14
 if((NOT DEFINED enable_python) OR enable_python)
-  get_property(known_features GLOBAL PROPERTY CMAKE_CXX_KNOWN_FEATURES)
-
   if("cxx_std_14" IN_LIST known_features)
 
     if(EXISTS ${CMAKE_HOME_DIRECTORY}/pybind11) # Try to use a local copy of pybind11, if any
index ba6035e..5f5321f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,12 +3,33 @@
 SimGrid (3.23.3) NOT RELEASED YET (v3.24 expected September 23. 7:50 UTC)
 
 S4U:
+ - Introduce a s4u::Disk interface to manage the newly introduced <disk>
+   tag. s4u::Disk is called to supplant s4u::Storage in a near future. It
+   thus becomes the default resource to execute I/O operations. Examples
+   and the file system plugin have been modified to use disks instead of
+   storage elements. Storage can still be used but is doomed to disappear.
+   Users are thus adviced to update their simulators accordingly.
  - Barrier::wait returns SG_BARRIER_SERIAL_THREAD for (only) one actor
    for consistency with pthread_barrier_wait()
  - Host::get_englobing_zone() returns the englobing netzone
  - Actor::on_destruction is now called in the destructor
    Actor::on_termination new signal called when the actor terminates
    its code.
+ - Global signals are now part of the Engine:
+   - on_platform_creation: after config settings, before the XML parsing
+   - on_platform_created: right after the XML parsing
+   - on_time_advance: each time the clock advances
+   - on_simulation_end: after simulation, before cleanups
+   - on_deadlock: as the name implies.
+ - C bindings:
+   - sg_{actor,host,link}_{data,data_set}() now all exist.
+     Use them to attach user data to the object and retrieve it.
+
+Models:
+ - Improved the usability of ns-3. Several bugs were ironed out.
+ - Introduce an experimental Wifi model. It sounds reasonable
+   according to the state of the art, but it still has to be properly
+   validated, at least against ns-3.
 
 MSG:
  - convert a new set of functions to the S4U C interface and move the old MSG
@@ -16,29 +37,47 @@ MSG:
 
 SMPI:
  - Fortran bindings for DVFS have been removed.
- - Add support for MPI_Irsend, MPI_Rsend, MPI_Rsend_init
+ - Add support for MPI_Irsend, MPI_Rsend, MPI_Rsend_init, MPI_Bsend,
+   MPI_Ibsend, MPI_Bsend_init, MPI_Buffer_attach, MPI_Buffer_detach
  - SMPI can now be selected by cmake's find_module(MPI) with
    MPI_C_COMPILER, MPI_CXX_COMPILER, MPI_Fortran_COMPILER variables.
  - Add support for MPI Errhandlers in Comm, File or Win. Default errhandler is now
    MPI_ERRORS_ARE_FATAL, so codes which were sending warnings may start failing.
 
 Model-Checker:
+ - Use the included xxHash as an hash implem when C++14 is usable.
  - Option model-checker/hash was removed. This is always activated now.
  - New option smpi/buffering controls the MPI buffering in MC mode.
- - MPI calls now MC_assert() that no MPI_ERR_* code is returned. 
+ - MPI calls now MC_assert() that no MPI_ERR_* code is returned.
    This is useful to check for MPI compliance.
 
 XBT:
  - xbt_mutex_t and xbt_cond_t are now marked as deprecated, a new C interface
-   on S4U is already available to replace them by sg_mutex_t and sg_cond_t. 
-
-Bugs:
+   on S4U is already available to replace them by sg_mutex_t and sg_cond_t.
+
+XML:
+ - Introduce the <disk> tag as a replacement of the <storage>, <storage_type>,
+   and <mount> tags. The rationale is finish to decouple what should be handle
+   by SimGrid kernel (i.e., resources and activities) from plugins built in
+   user space (e.g., the file system plugin). This new tag currently accepts
+   only three attributes (id, read_bw, and write_bw). All the other information
+   that was declared with the storage related tags now has to be expressed as
+   properties. An example of platform using this new tag is available at
+   examples/platforms/hostsè_with_disks.xml
+
+Fixed bugs (FG#.. -> framagit bugs; FG!.. -> framagit merge requests):
  - FG#28: add sg_actor_self (and other wrappers on this_actor methods)
- - FG#29 and FG#33: provide a new C API to mutexes and condition variables 
+ - FG#29 and FG#33: provide a new C API to mutexes and condition variables
  - FG#30: convert MSG_process_{un}ref to sg_actor_{un}ref
+ - FG#31: per-actor data
  - FG#34: SG_BARRIER_SERIAL_THREAD?
  - FG#35: model-checker does not like buster-produced binaries
-
+ - FG!13: MC: complete workaround in the error msg seen on modern systems
+ - FG!15: execute_flops now logs compute
+ - FG!16: Fix the ns-3 bindings when several flows are simultaneously finishing
+ - FG!17: ns-3: unblock the right number of communications + others issues
+ - FG!18: Improving the performance of the ns-3 bindings
+ - GH#219: Error in the throughput of TCP transfer
 ----------------------------------------------------------------------------
 
 SimGrid (3.23.2) July 8. 2019
index acac576..a7c7aad 100644 (file)
@@ -379,13 +379,13 @@ include examples/s4u/exec-waitany/s4u-exec-waitany.cpp
 include examples/s4u/exec-waitany/s4u-exec-waitany.tesh
 include examples/s4u/io-async/s4u-io-async.cpp
 include examples/s4u/io-async/s4u-io-async.tesh
+include examples/s4u/io-disk-raw/s4u-io-disk-raw.cpp
+include examples/s4u/io-disk-raw/s4u-io-disk-raw.tesh
 include examples/s4u/io-file-remote/s4u-io-file-remote.cpp
 include examples/s4u/io-file-remote/s4u-io-file-remote.tesh
 include examples/s4u/io-file-remote/s4u-io-file-remote_d.xml
 include examples/s4u/io-file-system/s4u-io-file-system.cpp
 include examples/s4u/io-file-system/s4u-io-file-system.tesh
-include examples/s4u/io-storage-raw/s4u-io-storage-raw.cpp
-include examples/s4u/io-storage-raw/s4u-io-storage-raw.tesh
 include examples/s4u/maestro-set/s4u-maestro-set.cpp
 include examples/s4u/maestro-set/s4u-maestro-set.tesh
 include examples/s4u/mc-failing-assert/s4u-mc-failing-assert.cpp
@@ -407,10 +407,10 @@ include examples/s4u/replay-comm/s4u-replay-comm.cpp
 include examples/s4u/replay-comm/s4u-replay-comm.tesh
 include examples/s4u/replay-comm/s4u-replay-comm.txt
 include examples/s4u/replay-comm/s4u-replay-comm_d.xml
-include examples/s4u/replay-storage/s4u-replay-storage.cpp
-include examples/s4u/replay-storage/s4u-replay-storage.tesh
-include examples/s4u/replay-storage/s4u-replay-storage.txt
-include examples/s4u/replay-storage/s4u-replay-storage_d.xml
+include examples/s4u/replay-io/s4u-replay-io.cpp
+include examples/s4u/replay-io/s4u-replay-io.tesh
+include examples/s4u/replay-io/s4u-replay-io.txt
+include examples/s4u/replay-io/s4u-replay-io_d.xml
 include examples/s4u/routing-get-clusters/s4u-routing-get-clusters.cpp
 include examples/s4u/routing-get-clusters/s4u-routing-get-clusters.tesh
 include examples/s4u/synchro-barrier/s4u-synchro-barrier.cpp
@@ -702,6 +702,8 @@ include teshsuite/s4u/concurrent_rw/concurrent_rw.cpp
 include teshsuite/s4u/concurrent_rw/concurrent_rw.tesh
 include teshsuite/s4u/listen_async/listen_async.cpp
 include teshsuite/s4u/listen_async/listen_async.tesh
+include teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.cpp
+include teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.tesh
 include teshsuite/s4u/pid/pid.cpp
 include teshsuite/s4u/pid/pid.tesh
 include teshsuite/s4u/storage_client_server/storage_client_server.cpp
@@ -1653,6 +1655,8 @@ include teshsuite/surf/surf_usage/surf_usage.cpp
 include teshsuite/surf/surf_usage/surf_usage.tesh
 include teshsuite/surf/surf_usage2/surf_usage2.cpp
 include teshsuite/surf/surf_usage2/surf_usage2.tesh
+include teshsuite/surf/wifi_usage/wifi_usage.cpp
+include teshsuite/surf/wifi_usage/wifi_usage.tesh
 include teshsuite/xbt/cmdline/cmdline.c
 include teshsuite/xbt/cmdline/cmdline.tesh
 include teshsuite/xbt/log_large/log_large.c
@@ -1835,8 +1839,10 @@ include examples/platforms/energy_platform.xml
 include examples/platforms/faulty_host.xml
 include examples/platforms/g5k.xml
 include examples/platforms/griffon.xml
+include examples/platforms/hosts_with_disks.xml
 include examples/platforms/meta_cluster.xml
 include examples/platforms/multicore_machine.xml
+include examples/platforms/ns3-big-cluster.xml
 include examples/platforms/onelink.xml
 include examples/platforms/optorsim/gridpp_grid_2004.conf
 include examples/platforms/optorsim/lcg_sept2004_grid.conf
@@ -1869,7 +1875,6 @@ include examples/platforms/small_platform_profile.xml
 include examples/platforms/small_platform_with_routers.xml
 include examples/platforms/storage/content/small_content.txt
 include examples/platforms/storage/content/storage_content.txt
-include examples/platforms/storage/content/win_storage_content.txt
 include examples/platforms/storage/remote_io.xml
 include examples/platforms/storage/storage.xml
 include examples/platforms/syscoord/generate_peer_platform.pl
@@ -1883,6 +1888,7 @@ include examples/platforms/two_hosts_platform_with_availability_included.xml
 include examples/platforms/two_hosts_profiles.xml
 include examples/platforms/two_peers.xml
 include examples/platforms/vivaldi.xml
+include examples/platforms/wifi.xml
 include examples/python/CMakeLists.txt
 include examples/python/actor-create/actor-create_d.xml
 include examples/python/actor-lifetime/actor-lifetime.py
@@ -1946,6 +1952,7 @@ include include/simgrid/s4u/Actor.hpp
 include include/simgrid/s4u/Barrier.hpp
 include include/simgrid/s4u/Comm.hpp
 include include/simgrid/s4u/ConditionVariable.hpp
+include include/simgrid/s4u/Disk.hpp
 include include/simgrid/s4u/Engine.hpp
 include include/simgrid/s4u/Exec.hpp
 include include/simgrid/s4u/Host.hpp
@@ -2082,6 +2089,7 @@ include src/include/surf/surf.hpp
 include src/include/xbt/coverage.h
 include src/include/xbt/mmalloc.h
 include src/include/xbt/parmap.hpp
+include src/include/xxhash.hpp
 include src/instr/instr_config.cpp
 include src/instr/instr_interface.cpp
 include src/instr/instr_paje_containers.cpp
@@ -2146,6 +2154,8 @@ include src/kernel/lmm/maxmin.cpp
 include src/kernel/lmm/maxmin.hpp
 include src/kernel/lmm/maxmin_test.cpp
 include src/kernel/resource/Action.cpp
+include src/kernel/resource/DiskImpl.cpp
+include src/kernel/resource/DiskImpl.hpp
 include src/kernel/resource/Model.cpp
 include src/kernel/resource/Resource.cpp
 include src/kernel/resource/profile/DatedValue.cpp
@@ -2274,6 +2284,7 @@ include src/s4u/s4u_Actor.cpp
 include src/s4u/s4u_Barrier.cpp
 include src/s4u/s4u_Comm.cpp
 include src/s4u/s4u_ConditionVariable.cpp
+include src/s4u/s4u_Disk.cpp
 include src/s4u/s4u_Engine.cpp
 include src/s4u/s4u_Exec.cpp
 include src/s4u/s4u_Host.cpp
@@ -2506,6 +2517,8 @@ include src/surf/cpu_interface.cpp
 include src/surf/cpu_interface.hpp
 include src/surf/cpu_ti.cpp
 include src/surf/cpu_ti.hpp
+include src/surf/disk_s19.cpp
+include src/surf/disk_s19.hpp
 include src/surf/host_clm03.cpp
 include src/surf/host_clm03.hpp
 include src/surf/network_cm02.cpp
diff --git a/NEWS b/NEWS
index efee0e3..c12397d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,10 @@ __   _____ _ __ ___(_) ___  _ __   |___ / |___ \| || |
   \_/ \___|_|  |___/_|\___/|_| |_| |____(_)_____|  |_|
                (not released yet)
 
+ * Introduce an experimental Wifi network model.
+ * TODO: Disk?
+ * TODO: New Energy?
+ * (+ many bug fixes and internal refactorings)
                     _               _____  ____  _____
 __   _____ _ __ ___(_) ___  _ __   |___ / |___ \|___ /
 \ \ / / _ \ '__/ __| |/ _ \| '_ \    |_ \   __) | |_ \
index 6b3d048..44414b9 100644 (file)
@@ -35,6 +35,8 @@ SimGrid4 will follow the these rules:
     - Example: src/kernel/activity/Activity.cpp
                include/simgrid/activity/Activity.hpp
   C
+  - Field getters are named sg_object_field() eg sg_link_name()
+    Field setters are named sg_object_field_set() eg sg_link_data_set()
   - variables and functions are in snake_case()
   - typedefs do not hide the pointers, ie * must be explicit
     char * sg_host_get_name(sg_host_t * host);
index 8f4b40a..ef6d3b1 100644 (file)
--- a/README.md
+++ b/README.md
@@ -3,7 +3,6 @@
 [![Travis Status](https://img.shields.io/travis/simgrid/simgrid/master.svg?logo=travis)](https://travis-ci.org/simgrid/simgrid)
 [![AppVeyor Status](https://ci.appveyor.com/api/projects/status/gvcssh340fwtoc35?svg=true)](https://ci.appveyor.com/project/mquinson/simgrid)
 [![SonarCloud Status](https://sonarcloud.io/api/project_badges/measure?project=simgrid_simgrid&metric=alert_status)](https://sonarcloud.io/dashboard/?id=simgrid_simgrid)
-[![Codacy Badge](https://api.codacy.com/project/badge/Grade/bf1bdba50440485fbda2ac19f462ccc7)](https://www.codacy.com/app/mquinson/simgrid?utm_source=github.com&amp)
 [![Doc](https://readthedocs.org/projects/pip/badge/?version=stable)](https://simgrid.org/doc/latest/)
 [![License: LGPL v2.1][license-badge]](COPYING)
 [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1845/badge)](https://bestpractices.coreinfrastructure.org/projects/1845)
index f1360d2..b525c73 100644 (file)
@@ -183,7 +183,7 @@ Configuring the Platform Models
 Choosing the Platform Models
 ............................
 
-SimGrid comes with several network, CPU and storage models built in,
+SimGrid comes with several network, CPU and disk models built in,
 and you can change the used model at runtime by changing the passed
 configuration. The three main configuration items are given below.
 For each of these items, passing the special ``help`` value gives you
@@ -549,42 +549,51 @@ Specifying the kind of reduction
 ................................
 
 The main issue when using the model-checking is the state space
-explosion. To counter that problem, you can chose a exploration
-reduction techniques with
+explosion. You can activate some reduction technique with
 ``--cfg=model-check/reduction:<technique>``. For now, this
 configuration variable can take 2 values:
 
- - **none:** Do not apply any kind of reduction (mandatory for now for
-   liveness properties)
+ - **none:** Do not apply any kind of reduction (mandatory for
+   liveness properties, as our current DPOR algorithm breaks cycles)
  - **dpor:** Apply Dynamic Partial Ordering Reduction. Only valid if
    you verify local safety properties (default value for safety
    checks).
 
-There is unfortunately no silver bullet here, and the most efficient
-reduction techniques cannot be applied to any properties. In
-particular, the DPOR method cannot be applied on liveness properties
-since our implementation of DPOR may break some cycles, while cycles
-are very important to the soundness of the exploration for liveness
-properties.
+Another way to mitigate the state space explosion is to search for
+cycles in the exploration with the :ref:`cfg=model-check/visited`
+configuration. Note that DPOR and state-equality reduction may not
+play well together. You should choose between them.
+
+Our current DPOR implementation could be improved in may ways. We are
+currently improving its efficiency (both in term of reduction ability
+and computational speed), and future work could make it compatible
+with liveness properties.
 
 .. _cfg=model-check/visited:
 
-Size of Cycle Detection Set
-...........................
+Size of Cycle Detection Set (state equality reduction)
+......................................................
+
+Mc SimGrid can be asked to search for cycles during the exploration,
+i.e. situations where a new explored state is in fact the same state
+than a previous one.. This can prove useful to mitigate the state
+space explosion with safety properties, and this is the crux when
+searching for counter-examples to the liveness properties.
 
-In order to detect cycles, the model checker needs to check if a new
-explored state is in fact the same state than a previous one. For
-that, the model checker can take a snapshot of each visited state:
-this snapshot is then used to compare it with subsequent states in the
-exploration graph.
+Note that this feature may break the current implementation of the
+DPOR reduction technique.
 
 The ``model-check/visited`` item is the maximum number of states which
 are stored in memory. If the maximum number of snapshotted state is
 reached, some states will be removed from the memory and some cycles
 might be missed. Small values can lead to incorrect verifications, but
-large value can exhaust your memory, so choose carefully.
+large values can exhaust your memory and be CPU intensive as each new
+state must be compared to that amount of older saved states.
 
-By default, no state is snapshotted and cycles cannot be detected.
+The default settings depend on the kind of exploration. With safety
+checking, no state is snapshotted and cycles cannot be detected. With
+liveness checking, all states are snapshotted because missing a cycle
+could hinder the exploration soundness.
 
 .. _cfg=model-check/termination:
 
index e8420dd..562a0cc 100644 (file)
@@ -12,7 +12,7 @@ execute user-provided functions. The actors have to explicitly use the
 S4U interface to express their computation, communication, disk usage
 and other |Activities|_, so that they get reflected within the
 simulator. These activities take place on **Resources** (|Hosts|_,
-|Links|_, |Storages|_). SimGrid predicts the time taken by each
+|Links|_, |Disks|_). SimGrid predicts the time taken by each
 activity and orchestrates accordingly the actors waiting for the
 completion of these activities.
 
@@ -33,8 +33,8 @@ between communicating actors.
 .. |Links| replace:: **Links**
 .. _Links: app_s4u.html#s4u-link
 
-.. |Storages| replace:: **Storages**
-.. _Storages: app_s4u.html#s4u-storage
+.. |Disks| replace:: **Disks**
+.. _Disks: app_s4u.html#s4u-disk
 
 .. |VirtualMachines| replace:: **VirtualMachines**
 .. _VirtualMachines: app_s4u.html#s4u-virtualmachine
index 8c39d22..1f509f0 100644 (file)
@@ -63,7 +63,7 @@ name of the flag and ``value`` is what it has to be set to.
 A host is the computing resource on which an actor can run. See :cpp:class:`simgrid::s4u::Host`.
 
 **Parent tags:** :ref:`pf_tag_zone` (only leaf zones, i.e., zones containing neither inner zones nor clusters) |br|
-**Children tags:** :ref:`pf_tag_mount`, :ref:`pf_tag_prop`, :ref:`pf_tag_storage` |br|
+**Children tags:** :ref:`pf_tag_mount`, :ref:`pf_tag_prop`, :ref:`pf_tag_disk` |br|
 **Attributes:**
 
 :``id``: Host name.
@@ -329,11 +329,12 @@ following functions:
 - Cluster: this is a zone, see below.
 - Host: :cpp:func:`simgrid::s4u::Host::get_property` or :cpp:func:`MSG_host_get_property_value`
 - Link: :cpp:func:`simgrid::s4u::Link::get_property`
-- Storage: :cpp:func:`simgrid::s4u::Storage::get_property` or :cpp:func:`MSG_storage_get_property_value`
+- Disk: :cpp:func:`simgrid::s4u::Disk::get_property`
+- Storage :cpp:func:`MSG_storage_get_property_value` (deprecated)
 - Zone: :cpp:func:`simgrid::s4u::Zone::get_property` of :cpp:func:`MSG_zone_get_property_value`
 
 **Parent tags:** :ref:`pf_tag_actor`, :ref:`pf_tag_config`, :ref:`pf_tag_cluster`, :ref:`pf_tag_host`,
-:ref:`pf_tag_link`, :ref:`pf_tag_storage`, :ref:`pf_tag_zone` |br|
+:ref:`pf_tag_link`, :ref:`pf_tag_disk`,:ref:`pf_tag_storage` (deprecated), :ref:`pf_tag_zone` |br|
 **Children tags:** none |br|
 **Attributes:**
 
@@ -373,7 +374,6 @@ particular, they are useful when you want to use the NS3 bindings to
 break the routes that are longer than 1 hop.
 
 **Parent tags:** :ref:`pf_tag_zone` (only leaf zones, i.e., zones containing neither inner zones nor clusters) |br|
-**Children tags:** :ref:`pf_tag_prop`, :ref:`pf_tag_storage` |br|
 **Attributes:**
 
 :``id``: Router name.
index 0f6b24a..885a6a9 100644 (file)
@@ -39,7 +39,7 @@ S4U interface to express their :ref:`computation <API_s4u_Exec>`,
 :ref:`communication <API_s4u_Comm>`, :ref:`disk usage <API_s4u_Io>`,
 and other |API_s4u_Activities|_, so that they get reflected within the
 simulator. These activities take place on resources such as |API_s4u_Hosts|_,
-|API_s4u_Links|_ and |API_s4u_Storages|_. SimGrid predicts the time taken by each
+|API_s4u_Links|_ and |API_s4u_Disks|_. SimGrid predicts the time taken by each
 activity and orchestrates the actors accordingly, waiting for the
 completion of these activities.
 
@@ -75,14 +75,14 @@ provides many helper functions to simplify the code of actors.
 
 - **Platform Elements**
 
+  - :ref:`class s4u::Disk <API_s4u_Disk>`
+    Resource on which actors can write and read data.
   - :ref:`class s4u::Host <API_s4u_Host>`:
     Actor location, providing computational power.
   - :ref:`class s4u::Link <API_s4u_Link>`
     Interconnecting hosts.
   - :ref:`class s4u::NetZone <API_s4u_NetZone>`:
     Sub-region of the platform, containing resources (Hosts, Links, etc).
-  - :ref:`class s4u::Storage <API_s4u_Storage>`
-    Resource on which actors can write and read data.
   - :ref:`class s4u::VirtualMachine <API_s4u_VirtualMachine>`:
     Execution containers that can be moved between Hosts.
 
@@ -94,7 +94,7 @@ provides many helper functions to simplify the code of actors.
   - :ref:`class s4u::Exec <API_s4u_Exec>`
     Computation activity, started on Host and consuming CPU resources.
   - :ref:`class s4u::Io <API_s4u_Io>`
-    I/O activity, started on and consumming Storages.
+    I/O activity, started on and consumming disks.
 
 - **Synchronization Mechanisms**: Classical IPC that actors can use
 
@@ -116,8 +116,8 @@ provides many helper functions to simplify the code of actors.
 .. |API_s4u_Links| replace:: **Links**
 .. _API_s4u_Links: #s4u-link
 
-.. |API_s4u_Storages| replace:: **Storages**
-.. _API_s4u_Storages: #s4u-storage
+.. |API_s4u_Disks| replace:: **Disks**
+.. _API_s4u_Disks: #s4u-disk
 
 .. |API_s4u_VirtualMachine| replace:: **VirtualMachines**
 
@@ -179,8 +179,8 @@ Every kind of activity can be asynchronous:
     :cpp:func:`s4u::Mailbox::put_async() <simgrid::s4u::Mailbox::put_async>` and
     :cpp:func:`s4u::Mailbox::get_async() <simgrid::s4u::Mailbox::get_async>`.
   - :ref:`s4u::IoPtr <API_s4u_Io>` are created with 
-    :cpp:func:`s4u::Storage::read_async() <simgrid::s4u::Storage::read_async>` and
-    :cpp:func:`s4u::Storage::write_async() <simgrid::s4u::Storage::write_async>`.    
+    :cpp:func:`s4u::Disk::read_async() <simgrid::s4u::Disk::read_async>` and
+    :cpp:func:`s4u::Disk::write_async() <simgrid::s4u::Disk::write_async>`.
   - :ref:`s4u::ExecPtr <API_s4u_Exec>` are created with
     :cpp:func:`s4u::Host::exec_async() <simgrid::s4u::Host::exec_async>`.
   - In the future, it will become possible to have asynchronous IPC
@@ -444,6 +444,17 @@ s4u::ConditionVariable
    :protected-members:
    :undoc-members:
 
+.. _API_s4u_Disk:
+
+============
+s4u::Disk
+============
+
+.. doxygenclass:: simgrid::s4u::Disk
+   :members:
+   :protected-members:
+   :undoc-members:
+
 .. _API_s4u_Engine:
 
 ===========
@@ -579,17 +590,6 @@ s4u::Semaphore
    :protected-members:
    :undoc-members:
 
-.. _API_s4u_Storage:
-
-============
-s4u::Storage
-============
-
-.. doxygenclass:: simgrid::s4u::Storage
-   :members:
-   :protected-members:
-   :undoc-members:
-
 .. _API_s4u_VirtualMachine:
 
 ===================
index d7e20e1..bc020e7 100644 (file)
@@ -29,7 +29,7 @@ documentation also contains some :ref:`hints and howtos <howto>`, as well
 as the full :ref:`XML reference guide <platform_reference>`.
 
 
-Any simulated platform must contain **basic elements**, such as hosts, links, storages, etc. SimGrid gives you a great
+Any simulated platform must contain **basic elements**, such as hosts, links, disks, etc. SimGrid gives you a great
 liberty when defining the **routing of your platform**, i.e., the network path taken between each pair of hosts.
 Finally, you may also describe an **experimental scenario**, with qualitative (e.g., bandwidth variations representing
 an external load) and qualitative (e.g., representing how some elements fail and restart over time) changes.
index 5f1fe9a..cd61f10 100644 (file)
@@ -185,3 +185,58 @@ period and another one for the shutdown period.
 
 Of course, this is only one possible way to model these things. YMMV ;)
 
+.. _understanding_lv08
+Understanding the default TCP model
+*****************************
+When simulating a data transfer between two hosts, you may be surprised
+by the obtained simulation time. Lets consider the following platform:
+
+.. code-block:: xml
+
+   <host id="A" speed="1Gf"/>
+   <host id="B" speed="1Gf"/>
+
+   <link id="link1" latency="10ms" bandwidth="1Mbps"/>
+
+   <route src="A" dst="B>
+     <link_ctn id="link1/>
+   </route>
+
+If host `A` sends `100kB` (a hundred kilobytes) to host `B`, one could expect
+that this communication would take `0.81` seconds to complete according to a
+simple latency-plus-size-divided-by-bandwidth model (0.01 + 8e5/1e6 = 0.81).
+However, the default TCP model of SimGrid is a bit more complex than that. It
+accounts for three phenomena that directly impact the simulation time even
+on such a simple example:
+  - The size of a message at the application level (i.e., 100kB in this
+    example) is not the size that will actually be transferred over the
+    network. To mimic the fact that TCP and IP headers are added to each packet of
+    the original payload, the TCP model of SimGrid empirically considers that
+    `only 97% of the nominal bandwidth` are available. In other words, the
+    size of your message is increased by a few percents, whatever this size be.
+
+  - In the real world, the TCP protocol is not able to fully exploit the
+    bandwidth of a link from the emission of the first packet. To reflect this
+    `slow start` phenomenon, the latency declared in the platform file is
+    multiplied by `a factor of 13.01`. Here again, this is an empirically
+    determined value that may not correspond to every TCP implementations on
+    every networks. It can be tuned when more realistic simulated times for
+    short messages are needed though.
+
+  - When data is transferred from A to B, some TCP ACK messages travel in the
+    opposite direction. To reflect the impact of this `cross-traffic`, SimGrid
+    simulates a flow from B to A that represents an additional bandwidth
+    consumption of `0.05`. The route from B to A is implicity declared in the
+    platfrom file and uses the same link `link1` as if the two hosts were
+    connected through a communication bus. The bandwidth share allocated to the
+    flow from A to B is then the available bandwidth of `link1` (i.e., 97% of
+    the nominal bandwidth of 1Mb/s) divided by 1.05 (i.e., the total consumption).
+    This feature, activated by default, can be disabled by adding the
+    `--cfg=network/crosstraffic:0` flag to command line.
+
+As a consequence, the time to transfer 100kB from A to B as simulated by the
+default TCP model of SimGrid is not 0.81 seconds but
+
+.. code-block:: python
+
+    0.01 * 13.01 + 800000 / ((0.97 * 1e6) / 1.05) =  0.996079 seconds.
index d175c6a..8e5c380 100644 (file)
@@ -25,7 +25,7 @@ import org.simgrid.msg.MsgException;
 
 public class Node extends Process {
   private static String file1 = "/doc/simgrid/examples/platforms/g5k.xml";
-  private static String file2 = "\\Windows\\setupact.log";
+  private static String file2 = "/include/surf/simgrid_dtd.h";
   private static String file3 = "/doc/simgrid/examples/platforms/g5k_cabinets.xml";
   private static String file4 = "/doc/simgrid/examples/platforms/nancy.xml";
 
@@ -44,7 +44,7 @@ public class Node extends Process {
         fileName = mount + file1;
       break;
       case 0:
-        mount = "c:";
+        mount = "/tmp";
         fileName = mount + file2;
       break;
       case 2:
index ca3957b..2ee1178 100644 (file)
@@ -3,19 +3,19 @@
 $ ${javacmd:=java} -classpath ${classpath:=.} io/file/Main ${srcdir:=.}/../../platforms/storage/storage.xml
 > [0.000000] [java/INFO] Using regular java threads.
 > [0.000000] [java/INFO] Number of hosts:4
-> [alice:0:(1) 0.000000] [java/INFO] Open file c:\Windows\setupact.log
+> [alice:0:(1) 0.000000] [java/INFO] Open file /tmp/include/surf/simgrid_dtd.h
 > [bob:1:(2) 0.000000] [java/INFO] Open file /home/doc/simgrid/examples/platforms/nancy.xml
 > [carl:2:(3) 0.000000] [java/INFO] Open file /home/doc/simgrid/examples/platforms/g5k_cabinets.xml
 > [denise:3:(4) 0.000000] [java/INFO] Open file /home/doc/simgrid/examples/platforms/g5k.xml
 > [bob:1:(2) 0.000040] [java/INFO] Having read 4028 on /home/doc/simgrid/examples/platforms/nancy.xml
-> [alice:0:(1) 0.000050] [java/INFO] Having read 10000 on c:\Windows\setupact.log
+> [alice:0:(1) 0.000050] [java/INFO] Having read 10000 on /tmp/include/surf/simgrid_dtd.h
 > [denise:3:(4) 0.000050] [java/INFO] Having read 10000 on /home/doc/simgrid/examples/platforms/g5k.xml
 > [carl:2:(3) 0.000100] [java/INFO] Having read 10000 on /home/doc/simgrid/examples/platforms/g5k_cabinets.xml
-> [alice:0:(1) 0.001717] [java/INFO] Having write 100000 on c:\Windows\setupact.log
-> [alice:0:(1) 0.001717] [java/INFO] Seek back to the beginning of c:\Windows\setupact.log
+> [alice:0:(1) 0.001717] [java/INFO] Having write 100000 on /tmp/include/surf/simgrid_dtd.h
+> [alice:0:(1) 0.001717] [java/INFO] Seek back to the beginning of /tmp/include/surf/simgrid_dtd.h
 > [denise:3:(4) 0.001717] [java/INFO] Having write 100000 on /home/doc/simgrid/examples/platforms/g5k.xml
 > [denise:3:(4) 0.001717] [java/INFO] Seek back to the beginning of /home/doc/simgrid/examples/platforms/g5k.xml
-> [alice:0:(1) 0.002267] [java/INFO] Having read 110000 on c:\Windows\setupact.log
+> [alice:0:(1) 0.002267] [java/INFO] Having read 110000 on /tmp/include/surf/simgrid_dtd.h
 > [denise:3:(4) 0.002267] [java/INFO] Having read 110000 on /home/doc/simgrid/examples/platforms/g5k.xml
 > [bob:1:(2) 0.003374] [java/INFO] Having write 100000 on /home/doc/simgrid/examples/platforms/nancy.xml
 > [bob:1:(2) 0.003374] [java/INFO] Seek back to the beginning of /home/doc/simgrid/examples/platforms/nancy.xml
index 4c3177e..9f7fc35 100644 (file)
@@ -5,8 +5,8 @@ $ ${javacmd:=java} -classpath ${classpath:=.} io/storage/Main ${srcdir:=.}/../..
 > [denise:0:(1) 0.000000] [java/INFO] ------------------------------------
 > [denise:0:(1) 0.000000] [java/INFO] Disk name: Disk2
 > [denise:0:(1) 0.000000] [java/INFO] Size: 536870912000 bytes.
-> [denise:0:(1) 0.000000] [java/INFO] Free Size: 534479374867 bytes.
-> [denise:0:(1) 0.000000] [java/INFO] Used Size: 2391537133 bytes.
+> [denise:0:(1) 0.000000] [java/INFO] Free Size: 536857690006 bytes.
+> [denise:0:(1) 0.000000] [java/INFO] Used Size: 13221994 bytes.
 > [denise:0:(1) 0.000000] [java/INFO] ------------------------------------
 > [denise:0:(1) 0.000000] [java/INFO] Disk name: Disk4
 > [denise:0:(1) 0.000000] [java/INFO] Size: 536870912000 bytes.
index fb39c8a..17972b6 100644 (file)
@@ -24,26 +24,26 @@ struct _HostAttribute {
 
 static double sg_host_get_available_at(sg_host_t host)
 {
-  HostAttribute attr = (HostAttribute) sg_host_user(host);
+  HostAttribute attr = (HostAttribute)sg_host_data(host);
   return attr->available_at;
 }
 
 static void sg_host_set_available_at(sg_host_t host, double time)
 {
-  HostAttribute attr = (HostAttribute) sg_host_user(host);
+  HostAttribute attr = (HostAttribute)sg_host_data(host);
   attr->available_at = time;
-  sg_host_user_set(host, attr);
+  sg_host_data_set(host, attr);
 }
 
 static SD_task_t sg_host_get_last_scheduled_task( sg_host_t host){
-  HostAttribute attr = (HostAttribute) sg_host_user(host);
+  HostAttribute attr = (HostAttribute)sg_host_data(host);
   return attr->last_scheduled_task;
 }
 
 static void sg_host_set_last_scheduled_task(sg_host_t host, SD_task_t task){
-  HostAttribute attr = (HostAttribute) sg_host_user(host);
+  HostAttribute attr       = (HostAttribute)sg_host_data(host);
   attr->last_scheduled_task=task;
-  sg_host_user_set(host, attr);
+  sg_host_data_set(host, attr);
 }
 
 static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax)
@@ -155,11 +155,11 @@ int main(int argc, char **argv)
   SD_create_environment(argv[1]);
 
   /*  Allocating the host attribute */
-  int total_nhosts = sg_host_count();
+  unsigned int total_nhosts = sg_host_count();
   sg_host_t *hosts = sg_host_list();
 
   for (cursor = 0; cursor < total_nhosts; cursor++)
-    sg_host_user_set(hosts[cursor], xbt_new0(struct _HostAttribute, 1));
+    sg_host_data_set(hosts[cursor], xbt_new0(struct _HostAttribute, 1));
 
   /* load the DAX file */
   xbt_dynar_t dax = SD_daxload(argv[2]);
@@ -246,8 +246,8 @@ int main(int argc, char **argv)
   xbt_dynar_free_container(&dax);
 
   for (cursor = 0; cursor < total_nhosts; cursor++) {
-    free(sg_host_user(hosts[cursor]));
-    sg_host_user_set(hosts[cursor], NULL);
+    free(sg_host_data(hosts[cursor]));
+    sg_host_data_set(hosts[cursor], NULL);
   }
 
   xbt_free(hosts);
diff --git a/examples/platforms/hosts_with_disks.xml b/examples/platforms/hosts_with_disks.xml
new file mode 100644 (file)
index 0000000..cb22063
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+  <zone id="AS0" routing="Full">
+    <host id="bob" speed="1Gf">
+      <disk id="Disk1" read_bw="100MBps" write_bw="40MBps">
+        <prop id="size" value="500GiB"/>
+        <prop id="mount" value="/scratch"/>
+        <prop id="content" value="storage/content/storage_content.txt"/>
+      </disk>
+      <disk id="Disk2" read_bw="200MBps" write_bw="80MBps"/>
+    </host>
+
+    <host id="alice" speed="1Gf">
+      <disk id="Disk1" read_bw="200MBps" write_bw="80MBps">
+        <prop id="content" value="storage/content/small_content.txt"/>
+      </disk>
+    </host>
+
+    <host id="carl" speed="1Gf">
+      <prop id="remote_disk" value="/scratch:Disk1:bob"/>
+    </host>
+
+    <link id="link1" bandwidth="125MBps" latency="150us" />
+    <link id="link2" bandwidth="125MBps" latency="150us" />
+    <link id="link3" bandwidth="125MBps" latency="150us" />
+
+    <route src="bob" dst="alice">
+      <link_ctn id="link1" />
+    </route>
+    <route src="bob" dst="carl">
+      <link_ctn id="link2" />
+    </route>
+    <route src="alice" dst="carl">
+      <link_ctn id="link3" />
+    </route>
+  </zone>
+</platform>
diff --git a/examples/platforms/ns3-big-cluster.xml b/examples/platforms/ns3-big-cluster.xml
new file mode 100644 (file)
index 0000000..8d63663
--- /dev/null
@@ -0,0 +1,182 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
+<platform version="4.1">
+  <zone id="AS0" routing="Floyd"> 
+
+    <host id="c-01.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-02.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-03.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-04.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-05.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-06.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-07.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-08.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-09.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-10.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-11.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-12.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-13.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-14.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-15.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-16.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-17.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-18.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-19.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-20.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-21.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-22.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-23.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-24.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-25.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-26.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-27.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-28.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-29.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-30.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-31.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-32.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-33.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-34.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-35.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-36.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-37.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-38.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-39.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-40.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-41.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-42.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-43.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-44.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-45.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-46.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-47.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-48.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-49.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-50.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-51.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-52.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-53.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-54.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-55.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-56.rennes" core="6" speed="21.496E9f"/>
+    <host id="c-57.rennes" core="6" speed="21.496E9f"/>
+  
+    <router id="router1"/>
+
+    <link id="link01" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link02" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link03" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link04" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link05" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link06" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link07" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link08" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link09" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link10" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link11" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link12" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link13" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link14" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link15" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link16" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link17" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link18" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link19" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link20" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link21" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link22" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link23" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link24" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link25" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link26" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link27" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link28" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link29" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link30" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link31" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link32" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link33" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link34" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link35" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link36" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link37" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link38" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link39" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link40" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link41" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link42" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link43" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link44" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link45" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link46" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link47" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link48" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link49" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link50" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link51" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link52" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link53" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link54" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link55" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link56" bandwidth="1.25GBps" latency="2.5ms"/>
+    <link id="link57" bandwidth="1.25GBps" latency="2.5ms"/>
+
+    <route src="router1" dst="c-01.rennes"><link_ctn id="link01"/></route>
+    <route src="router1" dst="c-02.rennes"><link_ctn id="link02"/></route>
+    <route src="router1" dst="c-03.rennes"><link_ctn id="link03"/></route>
+    <route src="router1" dst="c-04.rennes"><link_ctn id="link04"/></route>
+    <route src="router1" dst="c-05.rennes"><link_ctn id="link05"/></route>
+    <route src="router1" dst="c-06.rennes"><link_ctn id="link06"/></route>
+    <route src="router1" dst="c-07.rennes"><link_ctn id="link07"/></route>
+    <route src="router1" dst="c-08.rennes"><link_ctn id="link08"/></route>
+    <route src="router1" dst="c-09.rennes"><link_ctn id="link09"/></route>
+    <route src="router1" dst="c-10.rennes"><link_ctn id="link10"/></route>
+    <route src="router1" dst="c-11.rennes"><link_ctn id="link11"/></route>
+    <route src="router1" dst="c-12.rennes"><link_ctn id="link12"/></route>
+    <route src="router1" dst="c-13.rennes"><link_ctn id="link13"/></route>
+    <route src="router1" dst="c-14.rennes"><link_ctn id="link14"/></route>
+    <route src="router1" dst="c-15.rennes"><link_ctn id="link15"/></route>
+    <route src="router1" dst="c-16.rennes"><link_ctn id="link16"/></route>
+    <route src="router1" dst="c-17.rennes"><link_ctn id="link17"/></route>
+    <route src="router1" dst="c-18.rennes"><link_ctn id="link18"/></route>
+    <route src="router1" dst="c-19.rennes"><link_ctn id="link19"/></route>
+    <route src="router1" dst="c-20.rennes"><link_ctn id="link20"/></route>
+    <route src="router1" dst="c-21.rennes"><link_ctn id="link21"/></route>
+    <route src="router1" dst="c-22.rennes"><link_ctn id="link22"/></route>
+    <route src="router1" dst="c-23.rennes"><link_ctn id="link23"/></route>
+    <route src="router1" dst="c-24.rennes"><link_ctn id="link24"/></route>
+    <route src="router1" dst="c-25.rennes"><link_ctn id="link25"/></route>
+    <route src="router1" dst="c-26.rennes"><link_ctn id="link26"/></route>
+    <route src="router1" dst="c-27.rennes"><link_ctn id="link27"/></route>
+    <route src="router1" dst="c-28.rennes"><link_ctn id="link28"/></route>
+    <route src="router1" dst="c-29.rennes"><link_ctn id="link29"/></route>
+    <route src="router1" dst="c-30.rennes"><link_ctn id="link30"/></route>
+    <route src="router1" dst="c-31.rennes"><link_ctn id="link31"/></route>
+    <route src="router1" dst="c-32.rennes"><link_ctn id="link32"/></route>
+    <route src="router1" dst="c-33.rennes"><link_ctn id="link33"/></route>
+    <route src="router1" dst="c-34.rennes"><link_ctn id="link34"/></route>
+    <route src="router1" dst="c-35.rennes"><link_ctn id="link35"/></route>
+    <route src="router1" dst="c-36.rennes"><link_ctn id="link36"/></route>
+    <route src="router1" dst="c-37.rennes"><link_ctn id="link37"/></route>
+    <route src="router1" dst="c-38.rennes"><link_ctn id="link38"/></route>
+    <route src="router1" dst="c-39.rennes"><link_ctn id="link39"/></route>
+    <route src="router1" dst="c-40.rennes"><link_ctn id="link40"/></route>
+    <route src="router1" dst="c-41.rennes"><link_ctn id="link41"/></route>
+    <route src="router1" dst="c-42.rennes"><link_ctn id="link42"/></route>
+    <route src="router1" dst="c-43.rennes"><link_ctn id="link43"/></route>
+    <route src="router1" dst="c-44.rennes"><link_ctn id="link44"/></route>
+    <route src="router1" dst="c-45.rennes"><link_ctn id="link45"/></route>
+    <route src="router1" dst="c-46.rennes"><link_ctn id="link46"/></route>
+    <route src="router1" dst="c-47.rennes"><link_ctn id="link47"/></route>
+    <route src="router1" dst="c-48.rennes"><link_ctn id="link48"/></route>
+    <route src="router1" dst="c-49.rennes"><link_ctn id="link49"/></route>
+    <route src="router1" dst="c-50.rennes"><link_ctn id="link50"/></route>
+    <route src="router1" dst="c-51.rennes"><link_ctn id="link51"/></route>
+    <route src="router1" dst="c-52.rennes"><link_ctn id="link52"/></route>
+    <route src="router1" dst="c-53.rennes"><link_ctn id="link53"/></route>
+    <route src="router1" dst="c-54.rennes"><link_ctn id="link54"/></route>
+    <route src="router1" dst="c-55.rennes"><link_ctn id="link55"/></route>
+    <route src="router1" dst="c-56.rennes"><link_ctn id="link56"/></route>
+    <route src="router1" dst="c-57.rennes"><link_ctn id="link57"/></route>
+  </zone>
+</platform>
diff --git a/examples/platforms/storage/content/win_storage_content.txt b/examples/platforms/storage/content/win_storage_content.txt
deleted file mode 100644 (file)
index 48972ca..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-\Windows\avastSS.scr 41664\r
-\Windows\bfsvc.exe 75264\r
-\Windows\bootstat.dat 67584\r
-\Windows\CoreSingleLanguage.xml 31497\r
-\Windows\csup.txt 12\r
-\Windows\dchcfg64.exe 335464\r
-\Windows\dcmdev64.exe 93288\r
-\Windows\DirectX.log 10486\r
-\Windows\DPINST.LOG 18944\r
-\Windows\DtcInstall.log 1955\r
-\Windows\explorer.exe 2380944\r
-\Windows\font1.sii 4907\r
-\Windows\font2.sii 8698\r
-\Windows\hapint.exe 382056\r
-\Windows\HelpPane.exe 883712\r
-\Windows\hh.exe 17408\r
-\Windows\MEMORY.DMP 2384027342\r
-\Windows\mib.bin 43131\r
-\Windows\notepad.exe 243712\r
-\Windows\PFRO.log 6770\r
-\Windows\Professional.xml 31881\r
-\Windows\regedit.exe 159232\r
-\Windows\setupact.log 101663\r
-\Windows\setuperr.log 0\r
-\Windows\splwow64.exe 126464\r
-\Windows\Starter.xml 31537\r
-\Windows\system.ini 219\r
-\Windows\twain_32.dll 50176\r
-\Windows\vmgcoinstall.log 1585\r
-\Windows\win.ini 92\r
-\Windows\WindowsUpdate.log 1518934\r
-\Windows\winhlp32.exe 10752\r
-\Windows\WLXPGSS.SCR 322048\r
-\Windows\WMSysPr9.prx 316640\r
-\Windows\write.exe 10752\r
-\Windows\_isusr32.dll 180320
\ No newline at end of file
index c19c354..da1a035 100644 (file)
     <storage id="Disk1" typeId="SATA-II_HDD" attach="carl"/>
 
     <storage id="Disk2" typeId="SATA-II_HDD" attach="dave"
-             content="content/win_storage_content.txt" />
+             content="content/storage_content.txt" />
 
     <host id="alice" speed="1Gf">
-      <mount storageId="Disk2" name="c:"/>
+      <mount storageId="Disk2" name="/tmp"/>
     </host>
     <host id="bob" speed="1Gf">
       <mount storageId="Disk1" name="/scratch"/>
@@ -26,7 +26,7 @@
       <mount storageId="Disk1" name="/scratch"/>
     </host>
     <host id="dave" speed="1Gf">
-      <mount storageId="Disk2" name="c:"/>
+      <mount storageId="Disk2" name="/tmp"/>
     </host>
 
     <link id="link1" bandwidth="125MBps" latency="50us"/>
index 8d99f5c..ca64a72 100644 (file)
@@ -18,7 +18,7 @@
 
     <storage id="Disk1" typeId="single_HDD" attach="bob" />
     <storage id="Disk2" typeId="single_SSD" attach="alice"
-             content="content/win_storage_content.txt"/>
+             content="content/small_content.txt"/>
     <storage id="Disk3" typeId="single_HDD" attach="carl" />
     <storage id="Disk4" typeId="single_SSD" attach="denise"
              content="content/small_content.txt" />
       <mount storageId="Disk1" name="/home"/>
     </host>
     <host id="alice" speed="1Gf">
-      <mount storageId="Disk2" name="c:"/>
+      <mount storageId="Disk2" name="/tmp"/>
     </host>
     <host id="carl" speed="1Gf">
       <mount storageId="Disk3" name="/home"/>
     </host>
     <host id="denise" speed="1Gf">
-      <mount storageId="Disk2" name="c:"/>
+      <mount storageId="Disk2" name="/tmp"/>
       <mount storageId="Disk4" name="/home"/>
     </host>
 
diff --git a/examples/platforms/wifi.xml b/examples/platforms/wifi.xml
new file mode 100755 (executable)
index 0000000..fed5614
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version='1.0'?>
+
+<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+  <zone id="world" routing="Full">
+
+    <zone id="WIFI zone" routing="Cluster">
+        <!-- First declare the Access Point (ie, the wifi media) -->
+        <link id="AP1" sharing_policy="WIFI" bandwidth="54Mbps" latency="0ms" />
+
+        <!-- Two stations in the wifi zone -->
+        <host id="Station 1" speed="100.0Mf,50.0Mf,20.0Mf" />
+        <host id="Station 2" speed="100.0Mf,50.0Mf,20.0Mf" />
+
+        <!-- Specify that stations use the WIFI link for every communication (incoming or outgoing) -->
+        <host_link id="Station 1" up="AP1" down="AP1"/>
+        <host_link id="Station 2" up="AP1" down="AP1"/>
+
+        <router id="WIFI router"/>
+    </zone>
+
+
+    <!-- NODE1 AS -->
+    <zone id="Wired zone" routing="Full">
+      <host id="NODE1" speed="100.0Mf,50.0Mf,20.0Mf" />
+    </zone>
+    
+
+    <!-- AS Routing -->
+    <link id="Collector" sharing_policy="SHARED" bandwidth="100Mbps" latency="0ms" />
+    <zoneRoute src="WIFI zone" dst="Wired zone" gw_src="WIFI router" gw_dst="NODE1">
+      <link_ctn id="Collector" />
+    </zoneRoute>
+    
+  </zone>
+</platform>
index e8d52f6..034f340 100644 (file)
@@ -10,10 +10,10 @@ foreach (example actor-create actor-daemon actor-exiting actor-join actor-kill
                  energy-exec energy-boot energy-link energy-vm energy-exec-ptask
                  engine-filtering
                  exec-async exec-basic exec-dvfs exec-ptask exec-remote exec-waitany
-                 io-async io-file-system io-file-remote io-storage-raw
+                 io-async io-file-system io-file-remote io-disk-raw
                  platform-failures platform-profile platform-properties
                  plugin-hostload
-                 replay-comm replay-storage
+                 replay-comm replay-io
                  routing-get-clusters
                  synchro-barrier synchro-mutex synchro-semaphore)
   add_executable       (s4u-${example} EXCLUDE_FROM_ALL ${example}/s4u-${example}.cpp)
@@ -181,12 +181,12 @@ set(xml_files     ${xml_files}    ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u-a
                                   ${CMAKE_CURRENT_SOURCE_DIR}/platform-failures/s4u-platform-failures_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/replay-comm/s4u-replay-comm-split_d.xml
                                   ${CMAKE_CURRENT_SOURCE_DIR}/replay-comm/s4u-replay-comm_d.xml
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/replay-storage/s4u-replay-storage_d.xml
+                                  ${CMAKE_CURRENT_SOURCE_DIR}/replay-io/s4u-replay-io_d.xml
                   PARENT_SCOPE)
 set(bin_files     ${bin_files}    ${CMAKE_CURRENT_SOURCE_DIR}/dht-kademlia/generate.py                     PARENT_SCOPE)
 set(txt_files     ${txt_files}    ${CMAKE_CURRENT_SOURCE_DIR}/replay-comm/s4u-replay-comm-split-p0.txt
                                   ${CMAKE_CURRENT_SOURCE_DIR}/replay-comm/s4u-replay-comm-split-p1.txt
                                   ${CMAKE_CURRENT_SOURCE_DIR}/replay-comm/s4u-replay-comm.txt
-                                  ${CMAKE_CURRENT_SOURCE_DIR}/replay-storage/s4u-replay-storage.txt
+                                  ${CMAKE_CURRENT_SOURCE_DIR}/replay-io/s4u-replay-io.txt
                                   ${CMAKE_CURRENT_SOURCE_DIR}/README.rst                                   PARENT_SCOPE)
 
index df88b03..027d3b8 100644 (file)
@@ -149,7 +149,7 @@ also the tesh files in the example directories for details.
   - **I/O replay:**
     Presents a set of event handlers reproducing classical I/O
     primitives (open, read, close).
-    |br| `examples/s4u/replay-storage/s4u-replay-storage.cpp  <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/replay-storage/s4u-replay-storage.cpp>`_
+    |br| `examples/s4u/replay-io/s4u-replay-io.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/replay-io/s4u-replay-io.cpp>`_
 
 ==========================
 Activities: what Actors do
@@ -241,13 +241,13 @@ I/O on Disks and Files
 ----------------------
 
 SimGrid provides two levels of abstraction to interact with the
-simulated storages. At the simplest level, you simply create read and
-write actions on the storage resources.
+simulated disks. At the simplest level, you simply create read and
+write actions on the disk resources.
 
-  - **Access to raw storage devices:**
+  - **Access to raw disk devices:**
     This example illustrates how to simply read and write data on a
-    simulated storage resource.
-    |br| `examples/s4u/io-storage-raw/s4u-io-storage-raw.cpp  <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/io-storage-raw/s4u-io-storage-raw.cpp>`_
+    simulated disk resource.
+    |br| `examples/s4u/io-disk-raw/s4u-io-disk-raw.cpp  <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/io-disk-raw/s4u-io-disk-raw.cpp>`_
 
 The FileSystem plugin provides a more detailed view, with the
 classical operations over files: open, move, unlink, and of course
index 13304cc..597284f 100644 (file)
@@ -9,10 +9,10 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example")
 
 static void test(sg_size_t size)
 {
-  simgrid::s4u::Storage* storage = simgrid::s4u::Storage::by_name("Disk1");
-  XBT_INFO("Hello! read %llu bytes from Storage %s", size, storage->get_cname());
+  simgrid::s4u::Disk* disk = simgrid::s4u::Host::current()->get_disks().front();
+  XBT_INFO("Hello! read %llu bytes from %s", size, disk->get_cname());
 
-  simgrid::s4u::IoPtr activity = storage->io_init(size, simgrid::s4u::Io::OpType::READ);
+  simgrid::s4u::IoPtr activity = disk->io_init(size, simgrid::s4u::Io::OpType::READ);
   activity->start();
   activity->wait();
 
@@ -21,10 +21,10 @@ static void test(sg_size_t size)
 
 static void test_cancel(sg_size_t size)
 {
-  simgrid::s4u::Storage* storage = simgrid::s4u::Storage::by_name("Disk2");
-  XBT_INFO("Hello! write %llu bytes from Storage %s", size, storage->get_cname());
+  simgrid::s4u::Disk* disk = simgrid::s4u::Host::current()->get_disks().front();
+  XBT_INFO("Hello! write %llu bytes from %s", size, disk->get_cname());
 
-  simgrid::s4u::IoPtr activity = storage->write_async(size);
+  simgrid::s4u::IoPtr activity = disk->write_async(size);
   simgrid::s4u::this_actor::sleep_for(0.5);
   XBT_INFO("I changed my mind, cancel!");
   activity->cancel();
index d2a6acb..0ff50eb 100644 (file)
@@ -1,8 +1,8 @@
 #!/usr/bin/env tesh
 
-$ ${bindir:=.}/s4u-io-async ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
-> [  0.000000] (1:test@bob) Hello! read 20000000 bytes from Storage Disk1
-> [  0.000000] (2:test_cancel@alice) Hello! write 50000000 bytes from Storage Disk2
+$ ${bindir:=.}/s4u-io-async ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:test@bob) Hello! read 20000000 bytes from Disk1
+> [  0.000000] (2:test_cancel@alice) Hello! write 50000000 bytes from Disk1
 > [  0.200000] (1:test@bob) Goodbye now!
 > [  0.500000] (2:test_cancel@alice) I changed my mind, cancel!
 > [  0.500000] (2:test_cancel@alice) Goodbye now!
diff --git a/examples/s4u/io-disk-raw/s4u-io-disk-raw.cpp b/examples/s4u/io-disk-raw/s4u-io-disk-raw.cpp
new file mode 100644 (file)
index 0000000..2152a10
--- /dev/null
@@ -0,0 +1,57 @@
+/* Copyright (c) 2017-2019. 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 "simgrid/s4u.hpp"
+#include <string>
+#include <unordered_map>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(disk, "Messages specific for this simulation");
+
+static void host()
+{
+  /* - Display information on the disks mounted by the current host */
+  XBT_INFO("*** Storage info on %s ***", simgrid::s4u::Host::current()->get_cname());
+
+  /* - Retrieve all disks from current host */
+  std::vector<simgrid::s4u::Disk*> const& disk_list = simgrid::s4u::Host::current()->get_disks();
+
+  /* - For each disk mounted on host, display disk name and mount point */
+  for (auto disk : disk_list)
+    XBT_INFO("Disk name: %s", disk->get_cname());
+
+  /* - Write 400,000 bytes on Disk1 */
+  simgrid::s4u::Disk* disk = disk_list.front();
+  sg_size_t write          = disk->write(400000);
+  XBT_INFO("Wrote %llu bytes on '%s'", write, disk->get_cname());
+
+  /*  - Now read 200,000 bytes */
+  sg_size_t read = disk->read(200000);
+  XBT_INFO("Read %llu bytes on '%s'", read, disk->get_cname());
+
+  /* - Attach some user data to disk1 */
+  XBT_INFO("*** Get/set data for storage element: Disk1 ***");
+
+  std::string* data = static_cast<std::string*>(disk->get_data());
+
+  XBT_INFO("Get storage data: '%s'", data ? data->c_str() : "No user data");
+
+  disk->set_data(new std::string("Some user data"));
+  data = static_cast<std::string*>(disk->get_data());
+  XBT_INFO("Set and get data: '%s'", data->c_str());
+  delete data;
+}
+
+int main(int argc, char** argv)
+{
+  simgrid::s4u::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+
+  simgrid::s4u::Actor::create("", simgrid::s4u::Host::by_name("bob"), host);
+
+  e.run();
+  XBT_INFO("Simulated time: %g", simgrid::s4u::Engine::get_clock());
+
+  return 0;
+}
diff --git a/examples/s4u/io-disk-raw/s4u-io-disk-raw.tesh b/examples/s4u/io-disk-raw/s4u-io-disk-raw.tesh
new file mode 100644 (file)
index 0000000..f1906a8
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/env tesh
+
+$ ${bindir}/s4u-io-disk-raw ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:@bob) *** Storage info on bob ***
+> [  0.000000] (1:@bob) Disk name: Disk1
+> [  0.000000] (1:@bob) Disk name: Disk2
+> [  0.010000] (1:@bob) Wrote 400000 bytes on 'Disk1'
+> [  0.012000] (1:@bob) Read 200000 bytes on 'Disk1'
+> [  0.012000] (1:@bob) *** Get/set data for storage element: Disk1 ***
+> [  0.012000] (1:@bob) Get storage data: 'No user data'
+> [  0.012000] (1:@bob) Set and get data: 'Some user data'
+> [  0.012000] (0:maestro@) Simulated time: 0.012
index b4e6350..3579324 100644 (file)
@@ -17,33 +17,21 @@ static int host(int argc, char* argv[])
   const char* filename = file.get_path();
   XBT_INFO("Opened file '%s'", filename);
   file.dump();
-
-  XBT_INFO("Try to read %llu from '%s'", file.size(), filename);
-  sg_size_t read = file.read(file.size());
-  XBT_INFO("Have read %llu from '%s'. Offset is now at: %llu", read, filename, file.tell());
-  XBT_INFO("Seek back to the beginning of the stream...");
-  file.seek(0, SEEK_SET);
-  XBT_INFO("Offset is now at: %llu", file.tell());
-
-  if (argc > 5) {
-    simgrid::s4u::File remoteFile(argv[2], nullptr);
-    filename = remoteFile.get_path();
-    XBT_INFO("Opened file '%s'", filename);
-    XBT_INFO("Try to write %llu MiB to '%s'", remoteFile.size() / 1024, filename);
-    sg_size_t write = remoteFile.write(remoteFile.size() * 1024);
-    XBT_INFO("Have written %llu bytes to '%s'.", write, filename);
-
-    if (std::stoi(argv[5]) != 0) {
-      XBT_INFO("Move '%s' (of size %llu) from '%s' to '%s'", filename, remoteFile.size(),
-               simgrid::s4u::Host::current()->get_cname(), argv[3]);
-      remoteFile.remote_move(simgrid::s4u::Host::by_name(argv[3]), argv[4]);
+  XBT_INFO("Try to write %llu MiB to '%s'", file.size() / 1024, filename);
+  sg_size_t write = file.write(file.size() * 1024);
+  XBT_INFO("Have written %llu MiB to '%s'.", write / (1024 * 1024), filename);
+
+  if (argc > 4) {
+    if (std::stoi(argv[4]) != 0) {
+      XBT_INFO("Move '%s' (of size %llu) from '%s' to '%s'", filename, file.size(),
+               simgrid::s4u::Host::current()->get_cname(), argv[2]);
+      file.remote_move(simgrid::s4u::Host::by_name(argv[2]), argv[3]);
     } else {
-      XBT_INFO("Copy '%s' (of size %llu) from '%s' to '%s'", filename, remoteFile.size(),
-               simgrid::s4u::Host::current()->get_cname(), argv[3]);
-      remoteFile.remote_copy(simgrid::s4u::Host::by_name(argv[3]), argv[4]);
+      XBT_INFO("Copy '%s' (of size %llu) from '%s' to '%s'", filename, file.size(),
+               simgrid::s4u::Host::current()->get_cname(), argv[2]);
+      file.remote_copy(simgrid::s4u::Host::by_name(argv[2]), argv[3]);
     }
   }
-
   return 0;
 }
 
@@ -54,18 +42,20 @@ int main(int argc, char** argv)
   e.load_platform(argv[1]);
   e.register_function("host", host);
   e.load_deployment(argv[2]);
-  std::vector<simgrid::s4u::Storage*> allStorages = e.get_all_storages();
+  std::vector<simgrid::s4u::Host*> all_hosts = e.get_all_hosts();
 
-  for (auto const& s : allStorages) {
-    XBT_INFO("Init: %llu/%llu MiB used/free on '%s'", sg_storage_get_size_used(s) / INMEGA,
-             sg_storage_get_size_free(s) / INMEGA, s->get_cname());
+  for (auto const& h : all_hosts) {
+    for (auto const& d : h->get_disks())
+      XBT_INFO("Init: %s: %llu/%llu MiB used/free on '%s@%s'", h->get_cname(), sg_disk_get_size_used(d) / INMEGA,
+               sg_disk_get_size_free(d) / INMEGA, d->get_cname(), d->get_host()->get_cname());
   }
 
   e.run();
 
-  for (auto const& s : allStorages) {
-    XBT_INFO("End: %llu/%llu MiB used/free on '%s'", sg_storage_get_size_used(s) / INMEGA,
-             sg_storage_get_size_free(s) / INMEGA, s->get_cname());
+  for (auto const& h : all_hosts) {
+    for (auto const& d : h->get_disks())
+      XBT_INFO("End: %llu/%llu MiB used/free on '%s@%s'", sg_disk_get_size_used(d) / INMEGA,
+               sg_disk_get_size_free(d) / INMEGA, d->get_cname(), h->get_cname());
   }
 
   XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
index 1f5c26c..180ba09 100644 (file)
@@ -1,64 +1,43 @@
 #!/usr/bin/env tesh
 
-$ ${bindir:=.}/s4u-io-file-remote ${platfdir}/storage/remote_io.xml s4u-io-file-remote_d.xml "--log=root.fmt:[%10.6r]%e(%i@%5h)%e%m%n"
-> [  0.000000] (0@     ) Init: 12/476824 MiB used/free on 'Disk1'
-> [  0.000000] (0@     ) Init: 2280/474556 MiB used/free on 'Disk2'
-> [  0.000000] (1@alice) Opened file 'c:\Windows\setupact.log'
+$ ${bindir:=.}/s4u-io-file-remote ${platfdir}/hosts_with_disks.xml s4u-io-file-remote_d.xml "--log=root.fmt:[%10.6r]%e(%i@%5h)%e%m%n"
+> [  0.000000] (0@     ) Init: alice: 12/511987 MiB used/free on 'Disk1@alice'
+> [  0.000000] (0@     ) Init: bob: 35/511964 MiB used/free on 'Disk1@bob'
+> [  0.000000] (0@     ) Init: bob: 0/512000 MiB used/free on 'Disk2@bob'
+> [  0.000000] (0@     ) Init: carl: 35/511964 MiB used/free on 'Disk1@bob'
+> [  0.000000] (1@alice) Opened file '/include/surf/simgrid_dtd.h'
 > [  0.000000] (1@alice) File Descriptor information:
->              Full path: 'c:\Windows\setupact.log'
->              Size: 101663
->              Mount point: 'c:'
->              Storage Id: 'Disk2'
->              Storage Type: 'SATA-II_HDD'
+>              Full path: '/include/surf/simgrid_dtd.h'
+>              Size: 23583
+>              Mount point: '/'
+>              Disk Id: 'Disk1'
+>              Host Id: 'alice'
 >              File Descriptor Id: 0
-> [  0.000000] (1@alice) Try to read 101663 from 'c:\Windows\setupact.log'
-> [  0.000000] (2@  bob) Opened file '/scratch/lib/libsimgrid.so.3.6.2'
+> [  0.000000] (1@alice) Try to write 23 MiB to '/include/surf/simgrid_dtd.h'
+> [  0.000000] (2@  bob) Opened file '/scratch/doc/simgrid/examples/platforms/g5k.xml'
 > [  0.000000] (2@  bob) File Descriptor information:
->              Full path: '/scratch/lib/libsimgrid.so.3.6.2'
->              Size: 12710497
+>              Full path: '/scratch/doc/simgrid/examples/platforms/g5k.xml'
+>              Size: 17028
 >              Mount point: '/scratch'
->              Storage Id: 'Disk1'
->              Storage Type: 'SATA-II_HDD'
+>              Disk Id: 'Disk1'
+>              Host Id: 'bob'
 >              File Descriptor Id: 0
-> [  0.000000] (2@  bob) Try to read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'
-> [  0.000000] (3@ carl) Opened file '/scratch/lib/libsimgrid.so.3.6.2'
+> [  0.000000] (2@  bob) Try to write 16 MiB to '/scratch/doc/simgrid/examples/platforms/g5k.xml'
+> [  0.000000] (3@ carl) Opened file '/scratch/include/surf/simgrid_dtd.h'
 > [  0.000000] (3@ carl) File Descriptor information:
->              Full path: '/scratch/lib/libsimgrid.so.3.6.2'
->              Size: 12710497
+>              Full path: '/scratch/include/surf/simgrid_dtd.h'
+>              Size: 23583
 >              Mount point: '/scratch'
->              Storage Id: 'Disk1'
->              Storage Type: 'SATA-II_HDD'
+>              Disk Id: 'Disk1'
+>              Host Id: 'bob'
 >              File Descriptor Id: 0
-> [  0.000000] (3@ carl) Try to read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'
-> [  0.000000] (4@ dave) Opened file 'c:\Windows\bootstat.dat'
-> [  0.000000] (4@ dave) File Descriptor information:
->              Full path: 'c:\Windows\bootstat.dat'
->              Size: 67584
->              Mount point: 'c:'
->              Storage Id: 'Disk2'
->              Storage Type: 'SATA-II_HDD'
->              File Descriptor Id: 0
-> [  0.000000] (4@ dave) Try to read 67584 from 'c:\Windows\bootstat.dat'
-> [  0.001469] (4@ dave) Have read 67584 from 'c:\Windows\bootstat.dat'. Offset is now at: 67584
-> [  0.001469] (4@ dave) Seek back to the beginning of the stream...
-> [  0.001469] (4@ dave) Offset is now at: 0
-> [  0.001469] (4@ dave) Opened file 'c:\Windows\Professional.xml'
-> [  0.001469] (4@ dave) Try to write 31 MiB to 'c:\Windows\Professional.xml'
-> [  0.003741] (1@alice) Have read 101663 from 'c:\Windows\setupact.log'. Offset is now at: 101663
-> [  0.003741] (1@alice) Seek back to the beginning of the stream...
-> [  0.003741] (1@alice) Offset is now at: 0
-> [  0.276315] (3@ carl) Have read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'. Offset is now at: 12710497
-> [  0.276315] (3@ carl) Seek back to the beginning of the stream...
-> [  0.276315] (3@ carl) Offset is now at: 0
-> [  0.387036] (2@  bob) Have read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'. Offset is now at: 12710497
-> [  0.387036] (2@  bob) Seek back to the beginning of the stream...
-> [  0.387036] (2@  bob) Offset is now at: 0
-> [  0.387036] (2@  bob) Opened file '/scratch/doc/simgrid/examples/platforms/g5k.xml'
-> [  0.387036] (2@  bob) Try to write 16 MiB to '/scratch/doc/simgrid/examples/platforms/g5k.xml'
-> [  0.528211] (4@ dave) Have written 32646144 bytes to 'c:\Windows\Professional.xml'.
-> [  0.528211] (4@ dave) Move 'c:\Windows\Professional.xml' (of size 32646144) from 'dave' to 'carl'
-> [  0.819921] (2@  bob) Have written 17436672 bytes to '/scratch/doc/simgrid/examples/platforms/g5k.xml'.
-> [  0.819921] (2@  bob) Copy '/scratch/doc/simgrid/examples/platforms/g5k.xml' (of size 17436672) from 'bob' to 'alice'
-> [  1.843969] (0@     ) End: 60/476776 MiB used/free on 'Disk1'
-> [  1.843969] (0@     ) End: 2297/474539 MiB used/free on 'Disk2'
-> [  1.843969] (0@     ) Simulation time 1.84397
+> [  0.000000] (3@ carl) Try to write 23 MiB to '/scratch/include/surf/simgrid_dtd.h'
+> [  0.301862] (1@alice) Have written 23 MiB to '/include/surf/simgrid_dtd.h'.
+> [  0.301862] (1@alice) Move '/include/surf/simgrid_dtd.h' (of size 24148992) from 'alice' to 'bob'
+> [  0.660757] (2@  bob) Have written 16 MiB to '/scratch/doc/simgrid/examples/platforms/g5k.xml'.
+> [  0.660757] (2@  bob) Copy '/scratch/doc/simgrid/examples/platforms/g5k.xml' (of size 17436672) from 'bob' to 'alice'
+> [  1.234522] (3@ carl) Have written 23 MiB to '/scratch/include/surf/simgrid_dtd.h'.
+> [  1.643366] (0@     ) End: 29/511970 MiB used/free on 'Disk1@alice'
+> [  1.643366] (0@     ) End: 97/511902 MiB used/free on 'Disk1@bob'
+> [  1.643366] (0@     ) End: 0/512000 MiB used/free on 'Disk2@bob'
+> [  1.643366] (0@     ) Simulation time 1.64337
index 3b3f1ab..d14901b 100644 (file)
@@ -2,23 +2,18 @@
 <!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
 <platform version="4.1">
   <actor host="alice" function="host">
-    <argument value = "c:\Windows\setupact.log"/>
+    <argument value = "/include/surf/simgrid_dtd.h"/>
+    <argument value = "bob"/>
+    <argument value = "/scratch/include/surf/simgrid_dtd.h"/>
+    <argument value = "1"/>
   </actor>
   <actor host="bob" function="host">
-    <argument value = "/scratch/lib/libsimgrid.so.3.6.2"/>
     <argument value = "/scratch/doc/simgrid/examples/platforms/g5k.xml"/>
     <argument value = "alice"/>
-    <argument value = "c:\Windows\Platforms\g5k.xml"/>
+    <argument value = "/tmp/platforms/g5k.xml"/>
     <argument value = "0"/>
   </actor>
   <actor host="carl" function="host">
-    <argument value = "/scratch/lib/libsimgrid.so.3.6.2"/>
-  </actor>
-  <actor host="dave" function="host">
-    <argument value = "c:\Windows\bootstat.dat"/>
-    <argument value = "c:\Windows\Professional.xml"/>
-    <argument value = "carl"/>
-    <argument value = "/scratch/mailbox/Professional.xml"/>
-    <argument value = "1"/>
+    <argument value = "/scratch/include/surf/simgrid_dtd.h"/>
   </actor>
 </platform>
index c706b97..4c91e69 100644 (file)
@@ -4,7 +4,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include <string>
-#include <unordered_map>
+#include <vector>
 
 #include "simgrid/plugins/file_system.h"
 #include "simgrid/s4u.hpp"
@@ -13,36 +13,32 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
 
 class MyHost {
 public:
-  void show_info(std::unordered_map<std::string, simgrid::s4u::Storage*> const& mounts)
+  void show_info(std::vector<simgrid::s4u::Disk*> const& disks)
   {
     XBT_INFO("Storage info on %s:", simgrid::s4u::Host::current()->get_cname());
 
-    for (auto const& kv : mounts) {
-      std::string mountpoint         = kv.first;
-      simgrid::s4u::Storage* storage = kv.second;
-
+    for (auto const& d : disks) {
       // Retrieve disk's information
-      XBT_INFO("    %s (%s) Used: %llu; Free: %llu; Total: %llu.", storage->get_cname(), mountpoint.c_str(),
-               sg_storage_get_size_used(storage), sg_storage_get_size_free(storage), sg_storage_get_size(storage));
+      XBT_INFO("    %s (%s) Used: %llu; Free: %llu; Total: %llu.", d->get_cname(), sg_disk_get_mount_point(d),
+               sg_disk_get_size_used(d), sg_disk_get_size_free(d), sg_disk_get_size(d));
     }
   }
 
   void operator()()
   {
-    std::unordered_map<std::string, simgrid::s4u::Storage*> const& mounts =
-        simgrid::s4u::Host::current()->get_mounted_storages();
+    std::vector<simgrid::s4u::Disk*> const& disks = simgrid::s4u::Host::current()->get_disks();
 
-    show_info(mounts);
+    show_info(disks);
 
     // Open an non-existing file to create it
-    std::string filename     = "/home/tmp/data.txt";
+    std::string filename     = "/scratch/tmp/data.txt";
     simgrid::s4u::File* file = new simgrid::s4u::File(filename, nullptr);
 
     sg_size_t write = file->write(200000); // Write 200,000 bytes
-    XBT_INFO("Create a %llu bytes file named '%s' on /sd1", write, filename.c_str());
+    XBT_INFO("Create a %llu bytes file named '%s' on /scratch", write, filename.c_str());
 
     // check that sizes have changed
-    show_info(mounts);
+    show_info(disks);
 
     // Now retrieve the size of created file and read it completely
     const sg_size_t file_size = file->size();
@@ -54,10 +50,8 @@ public:
     write = file->write(100000); // Write 100,000 bytes
     XBT_INFO("Write %llu bytes on %s", write, filename.c_str());
 
-    simgrid::s4u::Storage* storage = simgrid::s4u::Storage::by_name("Disk4");
-
     // Now rename file from ./tmp/data.txt to ./tmp/simgrid.readme
-    std::string newpath = "/home/tmp/simgrid.readme";
+    std::string newpath = "/scratch/tmp/simgrid.readme";
     XBT_INFO("Move '%s' to '%s'", file->get_path(), newpath.c_str());
     file->move(newpath);
 
@@ -70,23 +64,15 @@ public:
     // Close the file
     delete file;
 
-    // Now attach some user data to disk1
-    XBT_INFO("Get/set data for storage element: %s", storage->get_cname());
-    XBT_INFO("    Uninitialized storage data: '%s'", static_cast<char*>(storage->get_data()));
-
-    storage->set_data(new std::string("Some user data"));
-    std::string* storage_data = static_cast<std::string*>(storage->get_data());
-    XBT_INFO("    Set and get data: '%s'", storage_data->c_str());
-
-    delete storage_data;
+    show_info(disks);
 
     // Reopen the file and then unlink it
-    file = new simgrid::s4u::File("/home/tmp/simgrid.readme", nullptr);
+    file = new simgrid::s4u::File("/scratch/tmp/simgrid.readme", nullptr);
     XBT_INFO("Unlink file: '%s'", file->get_path());
     file->unlink();
     delete file; // Unlinking the file on "disk" does not free the object
 
-    show_info(mounts);
+    show_info(disks);
   }
 };
 
@@ -95,7 +81,7 @@ int main(int argc, char** argv)
   simgrid::s4u::Engine e(&argc, argv);
   sg_storage_file_system_init();
   e.load_platform(argv[1]);
-  simgrid::s4u::Actor::create("host", simgrid::s4u::Host::by_name("denise"), MyHost());
+  simgrid::s4u::Actor::create("host", simgrid::s4u::Host::by_name("bob"), MyHost());
   e.run();
 
   return 0;
index 54e4fa3..b2ad152 100644 (file)
@@ -1,21 +1,21 @@
 #!/usr/bin/env tesh
 
-$ ${bindir:=.}/s4u-io-file-system ${platfdir}/storage/storage.xml
-> [denise:host:(1) 0.000000] [s4u_test/INFO] Storage info on denise:
-> [denise:host:(1) 0.000000] [s4u_test/INFO]     Disk2 (c:) Used: 2391537133; Free: 534479374867; Total: 536870912000.
-> [denise:host:(1) 0.000000] [s4u_test/INFO]     Disk4 (/home) Used: 13221994; Free: 536857690006; Total: 536870912000.
-> [denise:host:(1) 0.003333] [s4u_test/INFO] Create a 200000 bytes file named '/home/tmp/data.txt' on /sd1
-> [denise:host:(1) 0.003333] [s4u_test/INFO] Storage info on denise:
-> [denise:host:(1) 0.003333] [s4u_test/INFO]     Disk2 (c:) Used: 2391537133; Free: 534479374867; Total: 536870912000.
-> [denise:host:(1) 0.003333] [s4u_test/INFO]     Disk4 (/home) Used: 13421994; Free: 536857490006; Total: 536870912000.
-> [denise:host:(1) 0.004333] [s4u_test/INFO] Read 200000 bytes on /home/tmp/data.txt
-> [denise:host:(1) 0.006000] [s4u_test/INFO] Write 100000 bytes on /home/tmp/data.txt
-> [denise:host:(1) 0.006000] [s4u_test/INFO] Move '/home/tmp/data.txt' to '/home/tmp/simgrid.readme'
-> [denise:host:(1) 0.006000] [s4u_test/INFO] User data attached to the file: 777
-> [denise:host:(1) 0.006000] [s4u_test/INFO] Get/set data for storage element: Disk4
-> [denise:host:(1) 0.006000] [s4u_test/INFO]     Uninitialized storage data: '(null)'
-> [denise:host:(1) 0.006000] [s4u_test/INFO]     Set and get data: 'Some user data'
-> [denise:host:(1) 0.006000] [s4u_test/INFO] Unlink file: '/home/tmp/simgrid.readme'
-> [denise:host:(1) 0.006000] [s4u_test/INFO] Storage info on denise:
-> [denise:host:(1) 0.006000] [s4u_test/INFO]     Disk2 (c:) Used: 2391537133; Free: 534479374867; Total: 536870912000.
-> [denise:host:(1) 0.006000] [s4u_test/INFO]     Disk4 (/home) Used: 13221994; Free: 536857690006; Total: 536870912000.
+$ ${bindir:=.}/s4u-io-file-system ${platfdir}/hosts_with_disks.xml
+> [bob:host:(1) 0.000000] [s4u_test/INFO] Storage info on bob:
+> [bob:host:(1) 0.000000] [s4u_test/INFO]     Disk1 (/scratch) Used: 36933331; Free: 536833978669; Total: 536870912000.
+> [bob:host:(1) 0.000000] [s4u_test/INFO]     Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000.
+> [bob:host:(1) 0.005000] [s4u_test/INFO] Create a 200000 bytes file named '/scratch/tmp/data.txt' on /scratch
+> [bob:host:(1) 0.005000] [s4u_test/INFO] Storage info on bob:
+> [bob:host:(1) 0.005000] [s4u_test/INFO]     Disk1 (/scratch) Used: 37133331; Free: 536833778669; Total: 536870912000.
+> [bob:host:(1) 0.005000] [s4u_test/INFO]     Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000.
+> [bob:host:(1) 0.007000] [s4u_test/INFO] Read 200000 bytes on /scratch/tmp/data.txt
+> [bob:host:(1) 0.009500] [s4u_test/INFO] Write 100000 bytes on /scratch/tmp/data.txt
+> [bob:host:(1) 0.009500] [s4u_test/INFO] Move '/scratch/tmp/data.txt' to '/scratch/tmp/simgrid.readme'
+> [bob:host:(1) 0.009500] [s4u_test/INFO] User data attached to the file: 777
+> [bob:host:(1) 0.009500] [s4u_test/INFO] Storage info on bob:
+> [bob:host:(1) 0.009500] [s4u_test/INFO]     Disk1 (/scratch) Used: 37233331; Free: 536833678669; Total: 536870912000.
+> [bob:host:(1) 0.009500] [s4u_test/INFO]     Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000.
+> [bob:host:(1) 0.009500] [s4u_test/INFO] Unlink file: '/scratch/tmp/simgrid.readme'
+> [bob:host:(1) 0.009500] [s4u_test/INFO] Storage info on bob:
+> [bob:host:(1) 0.009500] [s4u_test/INFO]     Disk1 (/scratch) Used: 36933331; Free: 536833978669; Total: 536870912000.
+> [bob:host:(1) 0.009500] [s4u_test/INFO]     Disk2 (/) Used: 0; Free: 536870912000; Total: 536870912000.
diff --git a/examples/s4u/io-storage-raw/s4u-io-storage-raw.cpp b/examples/s4u/io-storage-raw/s4u-io-storage-raw.cpp
deleted file mode 100644 (file)
index d076f87..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright (c) 2017-2019. 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 "simgrid/s4u.hpp"
-#include <string>
-#include <unordered_map>
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(storage, "Messages specific for this simulation");
-
-static void host()
-{
-  /* - Display information on the disks mounted by the current host */
-  XBT_INFO("*** Storage info on %s ***", simgrid::s4u::Host::current()->get_cname());
-
-  /* - Retrieve all mount points of current host */
-  std::unordered_map<std::string, simgrid::s4u::Storage*> const& storage_list =
-      simgrid::s4u::Host::current()->get_mounted_storages();
-
-  /* - For each disk mounted on host, display disk name and mount point */
-  for (auto const& kv : storage_list)
-    XBT_INFO("Storage name: %s, mount name: %s", kv.second->get_cname(), kv.first.c_str());
-
-  /* - Write 200,000 bytes on Disk4 */
-  simgrid::s4u::Storage* storage = simgrid::s4u::Storage::by_name("Disk4");
-  sg_size_t write                = storage->write(200000);
-  XBT_INFO("Wrote %llu bytes on 'Disk4'", write);
-
-  /*  - Now read 200,000 bytes */
-  sg_size_t read = storage->read(200000);
-  XBT_INFO("Read %llu bytes on 'Disk4'", read);
-
-  /* - Attach some user data to disk1 */
-  XBT_INFO("*** Get/set data for storage element: Disk4 ***");
-
-  std::string* data = static_cast<std::string*>(storage->get_data());
-
-  XBT_INFO("Get storage data: '%s'", data ? data->c_str() : "No user data");
-
-  storage->set_data(new std::string("Some user data"));
-  data = static_cast<std::string*>(storage->get_data());
-  XBT_INFO("Set and get data: '%s'", data->c_str());
-  delete data;
-}
-
-int main(int argc, char** argv)
-{
-  simgrid::s4u::Engine e(&argc, argv);
-  e.load_platform(argv[1]);
-
-  simgrid::s4u::Actor::create("", simgrid::s4u::Host::by_name("denise"), host);
-
-  e.run();
-  XBT_INFO("Simulated time: %g", simgrid::s4u::Engine::get_clock());
-
-  return 0;
-}
diff --git a/examples/s4u/io-storage-raw/s4u-io-storage-raw.tesh b/examples/s4u/io-storage-raw/s4u-io-storage-raw.tesh
deleted file mode 100644 (file)
index 2f507ce..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env tesh
-
-$ ${bindir}/s4u-io-storage-raw ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
-> [  0.000000] (1:@denise) *** Storage info on denise ***
-> [  0.000000] (1:@denise) Storage name: Disk2, mount name: c:
-> [  0.000000] (1:@denise) Storage name: Disk4, mount name: /home
-> [  0.003333] (1:@denise) Wrote 200000 bytes on 'Disk4'
-> [  0.004333] (1:@denise) Read 200000 bytes on 'Disk4'
-> [  0.004333] (1:@denise) *** Get/set data for storage element: Disk4 ***
-> [  0.004333] (1:@denise) Get storage data: 'No user data'
-> [  0.004333] (1:@denise) Set and get data: 'Some user data'
-> [  0.004333] (0:maestro@) Simulated time: 0.00433333
 
 #include <boost/algorithm/string/join.hpp>
 
-XBT_LOG_NEW_DEFAULT_CATEGORY(replay_storage, "Messages specific for this example");
+XBT_LOG_NEW_DEFAULT_CATEGORY(replay_io, "Messages specific for this example");
 
 static std::unordered_map<std::string, simgrid::s4u::File*> opened_files;
 
 #define ACT_DEBUG(...)                                                                                                 \
-  if (XBT_LOG_ISENABLED(replay_storage, xbt_log_priority_verbose)) {                                                   \
+  if (XBT_LOG_ISENABLED(replay_io, xbt_log_priority_verbose)) {                                                        \
     std::string NAME = boost::algorithm::join(action, " ");                                                            \
     XBT_DEBUG(__VA_ARGS__);                                                                                            \
   } else                                                                                                               \
-  ((void)0)
+    ((void)0)
 
 static void log_action(simgrid::xbt::ReplayAction& action, double date)
 {
-  if (XBT_LOG_ISENABLED(replay_storage, xbt_log_priority_verbose)) {
+  if (XBT_LOG_ISENABLED(replay_io, xbt_log_priority_verbose)) {
     std::string s = boost::algorithm::join(action, " ");
     XBT_VERB("%s %f", s.c_str(), date);
   }
@@ -97,10 +97,11 @@ int main(int argc, char* argv[])
   simgrid::s4u::Engine e(&argc, argv);
   sg_storage_file_system_init();
 
-  xbt_assert(argc > 3, "Usage: %s platform_file deployment_file [action_files]\n"
-                       "\texample: %s platform.xml deployment.xml actions # if all actions are in the same file\n"
-                       "\t# if actions are in separate files, specified in deployment\n"
-                       "\texample: %s platform.xml deployment.xml",
+  xbt_assert(argc > 3,
+             "Usage: %s platform_file deployment_file [action_files]\n"
+             "\texample: %s platform.xml deployment.xml actions # if all actions are in the same file\n"
+             "\t# if actions are in separate files, specified in deployment\n"
+             "\texample: %s platform.xml deployment.xml",
              argv[0], argv[0], argv[0]);
 
   e.load_platform(argv[1]);
diff --git a/examples/s4u/replay-io/s4u-replay-io.tesh b/examples/s4u/replay-io/s4u-replay-io.tesh
new file mode 100644 (file)
index 0000000..31b4f0e
--- /dev/null
@@ -0,0 +1,6 @@
+! output sort 19
+$ ${bindir:=.}/s4u-replay-io --log=replay_io.thres=verbose ${platfdir}/hosts_with_disks.xml s4u-replay-io_d.xml s4u-replay-io.txt "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
+> [  0.000000] (p0@alice) p0 open /lib/libsimgrid.so.3.6.2 0.000000
+> [  0.063552] (p0@alice) p0 read /lib/libsimgrid.so.3.6.2 12710497 0.063552
+> [  0.063552] (p0@alice) p0 close /lib/libsimgrid.so.3.6.2 0.000000
+> [  0.063552] (maestro@) Simulation time 0.0635525
diff --git a/examples/s4u/replay-io/s4u-replay-io.txt b/examples/s4u/replay-io/s4u-replay-io.txt
new file mode 100644 (file)
index 0000000..0748847
--- /dev/null
@@ -0,0 +1,3 @@
+p0 open /lib/libsimgrid.so.3.6.2
+p0 read /lib/libsimgrid.so.3.6.2 12710497
+p0 close /lib/libsimgrid.so.3.6.2
@@ -1,5 +1,5 @@
 <?xml version='1.0'?>
 <!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
 <platform version="4.1">
-  <actor host="denise" function="p0"/>
+  <actor host="alice" function="p0"/>
 </platform>
diff --git a/examples/s4u/replay-storage/s4u-replay-storage.tesh b/examples/s4u/replay-storage/s4u-replay-storage.tesh
deleted file mode 100644 (file)
index a7a63a1..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-! output sort 19
-$ ${bindir:=.}/s4u-replay-storage --log=replay_storage.thres=verbose ${platfdir}/storage/storage.xml s4u-replay-storage_d.xml s4u-replay-storage.txt "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
-> [  0.000000] (p0@denise) p0 open /home/lib/libsimgrid.so.3.6.2 0.000000
-> [  0.063552] (p0@denise) p0 read /home/lib/libsimgrid.so.3.6.2 12710497 0.063552
-> [  0.063552] (p0@denise) p0 close /home/lib/libsimgrid.so.3.6.2 0.000000
-> [  0.063552] (maestro@) Simulation time 0.0635525
diff --git a/examples/s4u/replay-storage/s4u-replay-storage.txt b/examples/s4u/replay-storage/s4u-replay-storage.txt
deleted file mode 100644 (file)
index cc9142a..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-p0 open /home/lib/libsimgrid.so.3.6.2  
-p0 read /home/lib/libsimgrid.so.3.6.2 12710497
-p0 close /home/lib/libsimgrid.so.3.6.2
index e44a2e7..79f55d9 100644 (file)
@@ -4,7 +4,7 @@ $ rm -rf ${bindir:=.}/smpi_trace.trace ${bindir:=.}/smpi_trace.trace_files
 
 $ ../../smpi_script/bin/smpirun -trace-ti --cfg=tracing/filename:${bindir:=.}/smpi_trace.trace --cfg=tracing/smpi/format/ti-one-file:yes -no-privatize -replay ${srcdir:=.}/replay/actions_bcast.txt --log=replay.thresh:critical --log=smpi_replay.thresh:verbose --log=no_loc --cfg=smpi/simulate-computation:no -np 3 -platform ${srcdir:=.}/../platforms/small_platform.xml -hostfile ${srcdir:=.}/hostfile ./ampi_test/smpi_ampi_test --log=smpi_kernel.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/wtime:0
 
-$ bash -c "cat ${bindir:=.}/smpi_trace.trace_files/*"
+$ sh -c "cat ${bindir:=.}/smpi_trace.trace_files/*"
 > 0 init
 > 0 iteration_in
 > 0 iteration_out
index 2707a55..e5e50ac 100644 (file)
@@ -153,10 +153,10 @@ $ tail -n +3 ./simgrid_override.trace
 > 4 4 0 1 1 MIGRATE_LINK
 > 2 5 1 MIGRATE_STATE
 > 6 0.000000 1 1 0 "rank-0"
-> 5 6 2 computing "0 1 1"
-> 5 7 2 smpi_replay_run_init "0 1 0"
 > 6 0.000000 2 1 0 "rank-1"
 > 6 0.000000 3 1 0 "rank-2"
+> 5 6 2 computing "0 1 1"
+> 5 7 2 smpi_replay_run_init "0 1 0"
 > 5 8 2 action_bcast "0 0.78 0.39"
 > 12 0.000000 2 1 7
 > 13 0.000000 2 1
index 8768e56..87686b4 100644 (file)
@@ -153,10 +153,10 @@ $ tail -n +3 ./simgrid.trace
 > 4 4 0 1 1 MIGRATE_LINK
 > 2 5 1 MIGRATE_STATE
 > 6 0.000000 1 1 0 "rank-0"
-> 5 6 2 computing "0 1 1"
-> 5 7 2 smpi_replay_run_init "0 1 0"
 > 6 0.000000 2 1 0 "rank-1"
 > 6 0.000000 3 1 0 "rank-2"
+> 5 6 2 computing "0 1 1"
+> 5 7 2 smpi_replay_run_init "0 1 0"
 > 5 8 2 action_bcast "0 0.78 0.39"
 > 12 0.000000 2 1 7
 > 13 0.000000 2 1
index 9b07381..a527b6e 100644 (file)
@@ -1339,8 +1339,8 @@ $ tail -n +3 ${bindir:=.}/smpi_trace.trace
 > 13 11.906032 2 3
 > 12 11.906032 2 3 18
 > 13 11.906032 2 3
-> 7 11.906032 1 1
-> 7 11.906032 1 2
+> 7 11.904056 1 1
+> 7 11.905518 1 2
 > 7 11.906032 1 3
 $ rm -f ${bindir:=.}/smpi_trace.trace
 
index e13893e..9b38ab5 100644 (file)
@@ -49,6 +49,8 @@ XBT_PUBLIC const char* sg_actor_self_get_name();
 XBT_PUBLIC void sg_actor_self_execute(double flops);
 XBT_PUBLIC void sg_actor_ref(sg_actor_t actor);
 XBT_PUBLIC void sg_actor_unref(sg_actor_t actor);
+XBT_PUBLIC void* sg_actor_data(sg_actor_t actor);
+XBT_PUBLIC void sg_actor_data_set(sg_actor_t actor, void* userdata);
 
 SG_END_DECL()
 
index 85eff8e..8ce7d7b 100644 (file)
@@ -81,6 +81,7 @@ typedef boost::intrusive_ptr<Semaphore> SemaphorePtr;
 XBT_PUBLIC void intrusive_ptr_release(Semaphore* m);
 XBT_PUBLIC void intrusive_ptr_add_ref(Semaphore* m);
 
+class Disk;
 class Storage;
 } // namespace s4u
 
@@ -140,6 +141,8 @@ class CpuModel;
 class NetworkModel;
 class LinkImpl;
 class NetworkAction;
+class DiskImpl;
+class DiskModel;
 class StorageImpl;
 class StorageType;
 class StorageModel;
@@ -183,6 +186,7 @@ typedef simgrid::s4u::File s4u_File;
 typedef simgrid::s4u::ConditionVariable s4u_ConditionVariable;
 typedef simgrid::s4u::Mutex s4u_Mutex;
 typedef simgrid::s4u::Semaphore s4u_Semaphore;
+typedef simgrid::s4u::Disk s4u_Disk;
 typedef simgrid::s4u::Storage s4u_Storage;
 typedef simgrid::s4u::NetZone s4u_NetZone;
 typedef simgrid::s4u::VirtualMachine s4u_VM;
@@ -205,6 +209,7 @@ typedef struct s4u_File s4u_File;
 typedef struct s4u_ConditionVariable s4u_ConditionVariable;
 typedef struct s4u_Mutex s4u_Mutex;
 typedef struct s4u_Semaphore s4u_Semaphore;
+typedef struct s4u_Disk s4u_Disk;
 typedef struct s4u_Storage s4u_Storage;
 typedef struct s4u_NetZone s4u_NetZone;
 typedef struct s4u_VM s4u_VM;
@@ -226,6 +231,7 @@ typedef s4u_Semaphore* sg_sem_t;
 typedef s4u_NetZone* sg_netzone_t;
 typedef s4u_Host* sg_host_t;
 typedef s4u_Link* sg_link_t;
+typedef s4u_Disk* sg_disk_t;
 typedef s4u_Storage* sg_storage_t;
 typedef s4u_File* sg_file_t;
 typedef s4u_VM* sg_vm_t;
index bdb3d89..fad40cd 100644 (file)
@@ -47,15 +47,18 @@ XBT_PUBLIC const char* sg_host_get_name(sg_host_t host);
 // ========== User Data ==============
 /** @brief Return the user data of a #sg_host_t.
  *
- * This functions returns the user data associated to @a host if it is possible.
+ * This functions returns the user data associated to @a host if any.
  */
-XBT_PUBLIC void* sg_host_user(sg_host_t host);
+XBT_PUBLIC void* sg_host_data(sg_host_t host);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data()") XBT_PUBLIC void* sg_host_user(sg_host_t host);
 /** @brief Set the user data of a #sg_host_t.
  *
- * This functions attach @a data to @a host if it is possible.
+ * This functions attach @a data to @a host.
  */
-XBT_PUBLIC void sg_host_user_set(sg_host_t host, void* userdata);
-XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
+XBT_PUBLIC void sg_host_data_set(sg_host_t host, void* userdata);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data_set()") XBT_PUBLIC
+    void sg_host_user_set(sg_host_t host, void* userdata);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data_set(h, NULL)") XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
 
 // ========= storage related functions ============
 /** @brief Return the list of mount point names on an host.
index 91c438d..60aad3b 100644 (file)
@@ -279,7 +279,7 @@ XBT_PUBLIC void MSG_config(const char* key, const char* value);
 #define MSG_init(argc, argv)                                                                                           \
   do {                                                                                                                 \
     sg_version_check(SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR, SIMGRID_VERSION_PATCH);                             \
-    MSG_init_nocheck(argc, argv);                                                                                      \
+    MSG_init_nocheck((argc), (argv));                                                                                  \
   } while (0)
 
 XBT_PUBLIC void MSG_init_nocheck(int* argc, char** argv);
@@ -369,7 +369,7 @@ XBT_ATTRIB_DEPRECATED_v325("Getting a task from a specific host is no longer sup
 XBT_PUBLIC msg_error_t MSG_task_receive_with_timeout(msg_task_t* task, const char* alias, double timeout);
 
 XBT_PUBLIC msg_error_t MSG_task_receive(msg_task_t* task, const char* alias);
-#define MSG_task_recv(t,a) MSG_task_receive(t,a)
+#define MSG_task_recv(t, a) MSG_task_receive((t), (a))
 
 XBT_PUBLIC msg_error_t MSG_task_receive_ext_bounded(msg_task_t* task, const char* alias, double timeout,
                                                     msg_host_t host, double rate);
@@ -377,7 +377,7 @@ XBT_PUBLIC msg_error_t MSG_task_receive_ext_bounded(msg_task_t* task, const char
 XBT_PUBLIC msg_error_t MSG_task_receive_with_timeout_bounded(msg_task_t* task, const char* alias, double timeout,
                                                              double rate);
 XBT_PUBLIC msg_error_t MSG_task_receive_bounded(msg_task_t* task, const char* alias, double rate);
-#define MSG_task_recv_bounded(t,a,r) MSG_task_receive_bounded(t,a,r)
+#define MSG_task_recv_bounded(t, a, r) MSG_task_receive_bounded((t), (a), (r))
 
 XBT_PUBLIC msg_comm_t MSG_task_isend(msg_task_t task, const char* alias);
 XBT_PUBLIC msg_comm_t MSG_task_isend_bounded(msg_task_t task, const char* alias, double maxrate);
index c8ad348..7b08818 100644 (file)
@@ -27,9 +27,9 @@ XBT_PUBLIC int sg_link_energy_is_inited();
 
 #define MSG_host_energy_plugin_init() sg_host_energy_plugin_init()
 #define MSG_host_get_consumed_energy(host) sg_host_get_consumed_energy(host)
-#define MSG_host_get_wattmin_at(host,pstate) sg_host_get_wattmin_at(host,pstate)
-#define MSG_host_get_wattmax_at(host,pstate) sg_host_get_wattmax_at(host,pstate)
-#define MSG_host_get_power_range_slope_at(host,pstate) sg_host_get_power_range_slope_at(host,pstate)
+#define MSG_host_get_wattmin_at(host,pstate) sg_host_get_wattmin_at((host), (pstate))
+#define MSG_host_get_wattmax_at(host,pstate) sg_host_get_wattmax_at((host), (pstate))
+#define MSG_host_get_power_range_slope_at(host,pstate) sg_host_get_power_range_slope_at((host), (pstate))
 #define MSG_host_get_current_consumption(host) sg_host_get_current_consumption(host)
 
 SG_END_DECL()
index 099cf33..feb2a74 100644 (file)
@@ -41,6 +41,11 @@ XBT_PUBLIC void sg_file_unlink(sg_file_t fd);
 XBT_PUBLIC int sg_file_rcopy(sg_file_t file, sg_host_t host, const char* fullpath);
 XBT_PUBLIC int sg_file_rmove(sg_file_t file, sg_host_t host, const char* fullpath);
 
+XBT_PUBLIC sg_size_t sg_disk_get_size_free(sg_disk_t d);
+XBT_PUBLIC sg_size_t sg_disk_get_size_used(sg_disk_t d);
+XBT_PUBLIC sg_size_t sg_disk_get_size(sg_disk_t d);
+XBT_PUBLIC const char* sg_disk_get_mount_point(sg_disk_t d);
+
 XBT_PUBLIC sg_size_t sg_storage_get_size_free(sg_storage_t st);
 XBT_PUBLIC sg_size_t sg_storage_get_size_used(sg_storage_t st);
 XBT_PUBLIC sg_size_t sg_storage_get_size(sg_storage_t st);
@@ -48,21 +53,21 @@ XBT_PUBLIC xbt_dict_t sg_storage_get_content(sg_storage_t storage);
 
 XBT_PUBLIC xbt_dict_t sg_host_get_storage_content(sg_host_t host);
 
-#define MSG_file_open(fullpath, data) sg_file_open(fullpath, data)
-#define MSG_file_read(fd, size) sg_file_read(fd, size)
-#define MSG_file_write(fd, size) sg_file_write(fd, size)
+#define MSG_file_open(fullpath, data) sg_file_open((fullpath), (data))
+#define MSG_file_read(fd, size) sg_file_read((fd), (size))
+#define MSG_file_write(fd, size) sg_file_write((fd), (size))
 #define MSG_file_close(fd) sg_file_close(fd)
 #define MSG_file_get_name(fd) sg_file_get_name(fd)
 #define MSG_file_get_size(fd) sg_file_get_size(fd)
 #define MSG_file_dump(fd) sg_file_dump(fd)
 #define MSG_file_get_data(fd) sg_file_get_data(fd)
-#define MSG_file_set_data(fd, data) sg_file_set_data(fd, data)
-#define MSG_file_seek(fd, offset, origin) sg_file_seek(fd, offset, origin)
+#define MSG_file_set_data(fd, data) sg_file_set_data((fd), (data))
+#define MSG_file_seek(fd, offset, origin) sg_file_seek((fd), (offset), (origin))
 #define MSG_file_tell(fd) sg_file_tell(fd)
-#define MSG_file_move(fd, fullpath) sg_file_get_size(fd, fullpath)
+#define MSG_file_move(fd, fullpath) sg_file_get_size((fd), (fullpath))
 #define MSG_file_unlink(fd) sg_file_unlink(fd)
-#define MSG_file_rcopy(file, host, fullpath) sg_file_rcopy(file, host, fullpath)
-#define MSG_file_rmove(file, host, fullpath) sg_file_rmove(file, host, fullpath)
+#define MSG_file_rcopy(file, host, fullpath) sg_file_rcopy((file), (host), (fullpath))
+#define MSG_file_rmove(file, host, fullpath) sg_file_rmove((file), (host), (fullpath))
 
 #define MSG_storage_file_system_init() sg_storage_file_system_init()
 #define MSG_storage_get_free_size(st) sg_storage_get_size_free(st)
@@ -126,7 +131,8 @@ public:
   void dump();
 
   int desc_id = 0;
-  Storage* local_storage_;
+  Disk* local_disk_       = nullptr;
+  Storage* local_storage_ = nullptr;
   std::string mount_point_;
 
 private:
@@ -137,6 +143,33 @@ private:
   void* userdata_             = nullptr;
 };
 
+class XBT_PUBLIC FileSystemDiskExt {
+public:
+  static simgrid::xbt::Extension<Disk, FileSystemDiskExt> EXTENSION_ID;
+  explicit FileSystemDiskExt(Disk* ptr);
+  FileSystemDiskExt(const FileSystemDiskExt&) = delete;
+  FileSystemDiskExt& operator=(const FileSystemDiskExt&) = delete;
+  std::map<std::string, sg_size_t>* parse_content(const std::string& filename);
+  std::map<std::string, sg_size_t>* get_content() const { return content_.get(); }
+  const char* get_mount_point() { return mount_point_.c_str(); }
+  const char* get_mount_point(s4u::Host* remote_host) { return remote_mount_points_[remote_host].c_str(); }
+  void add_remote_mount(Host* host, const std::string& mount_point)
+  {
+    remote_mount_points_.insert({host, mount_point});
+  }
+  sg_size_t get_size() const { return size_; }
+  sg_size_t get_used_size() const { return used_size_; }
+  void decr_used_size(sg_size_t size) { used_size_ -= size; }
+  void incr_used_size(sg_size_t size) { used_size_ += size; }
+
+private:
+  std::unique_ptr<std::map<std::string, sg_size_t>> content_;
+  std::map<Host*, std::string> remote_mount_points_;
+  std::string mount_point_;
+  sg_size_t used_size_ = 0;
+  sg_size_t size_      = static_cast<sg_size_t>(500 * 1024) * 1024 * 1024;
+};
+
 class XBT_PUBLIC FileSystemStorageExt {
 public:
   static simgrid::xbt::Extension<Storage, FileSystemStorageExt> EXTENSION_ID;
index 6b6a4cd..085c03b 100644 (file)
@@ -31,10 +31,10 @@ XBT_PUBLIC sg_vm_t sg_vm_create_migratable(sg_host_t pm, const char* name, int c
 #define MSG_vm_live_migration_plugin_init() sg_vm_live_migration_plugin_init()
 
 #define MSG_vm_create_migratable(pm, name, coreAmount, ramsize, mig_netspeed, dp_intensity)                            \
-  sg_vm_create_migratable(pm, name, coreAmount, ramsize, mig_netspeed, dp_intensity)
+  sg_vm_create_migratable((pm), (name), (coreAmount), (ramsize), (mig_netspeed), (dp_intensity))
 
 #define MSG_vm_is_migrating(vm) sg_vm_is_migrating(vm)
-#define MSG_vm_migrate(vm, dst_pm) sg_vm_migrate(vm, dst_pm)
+#define MSG_vm_migrate(vm, dst_pm) sg_vm_migrate((vm), (dst_pm))
 
 SG_END_DECL()
 
index dcbc463..7dc4005 100644 (file)
@@ -13,6 +13,7 @@
 #include <simgrid/s4u/Barrier.hpp>
 #include <simgrid/s4u/Comm.hpp>
 #include <simgrid/s4u/ConditionVariable.hpp>
+#include <simgrid/s4u/Disk.hpp>
 #include <simgrid/s4u/Engine.hpp>
 #include <simgrid/s4u/Exec.hpp>
 #include <simgrid/s4u/Host.hpp>
diff --git a/include/simgrid/s4u/Disk.hpp b/include/simgrid/s4u/Disk.hpp
new file mode 100644 (file)
index 0000000..106da72
--- /dev/null
@@ -0,0 +1,74 @@
+/* Copyright (c) 2019. 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 INCLUDE_SIMGRID_S4U_DISK_HPP_
+#define INCLUDE_SIMGRID_S4U_DISK_HPP_
+
+#include <simgrid/forward.h>
+#include <simgrid/s4u/Io.hpp>
+#include <xbt/Extendable.hpp>
+#include <xbt/base.h>
+#include <xbt/signal.hpp>
+
+#include <map>
+#include <string>
+#include <unordered_map>
+
+namespace simgrid {
+namespace s4u {
+
+/** Disk represent the disk resources associated to a host
+ *
+ * By default, SimGrid does not keep track of the actual data being written but
+ * only computes the time taken by the corresponding data movement.
+ */
+
+class XBT_PUBLIC Disk : public xbt::Extendable<Disk> {
+  friend Engine;
+  friend Io;
+  friend kernel::resource::DiskImpl;
+
+public:
+  explicit Disk(const std::string& name, kernel::resource::DiskImpl* pimpl) : pimpl_(pimpl), name_(name) {}
+
+protected:
+  virtual ~Disk() = default;
+
+public:
+  /** @brief Callback signal fired when a new Disk is created */
+  static xbt::signal<void(Disk&)> on_creation;
+  /** @brief Callback signal fired when a Disk is destroyed */
+  static xbt::signal<void(Disk const&)> on_destruction;
+  /** @brief Callback signal fired when a Disk's state changes */
+  static xbt::signal<void(Disk const&)> on_state_change;
+
+  /** @brief Retrieves the name of that disk as a C++ string */
+  std::string const& get_name() const { return name_; }
+  /** @brief Retrieves the name of that disk as a C string */
+  const char* get_cname() const { return name_.c_str(); }
+
+  const std::unordered_map<std::string, std::string>* get_properties() const;
+  const char* get_property(const std::string& key) const;
+  void set_property(const std::string&, const std::string& value);
+  Host* get_host();
+
+  IoPtr io_init(sg_size_t size, s4u::Io::OpType type);
+
+  IoPtr read_async(sg_size_t size);
+  sg_size_t read(sg_size_t size);
+
+  IoPtr write_async(sg_size_t size);
+  sg_size_t write(sg_size_t size);
+  kernel::resource::DiskImpl* get_impl() const { return pimpl_; }
+
+private:
+  kernel::resource::DiskImpl* const pimpl_;
+  std::string name_;
+};
+
+} // namespace s4u
+} // namespace simgrid
+
+#endif /* INCLUDE_SIMGRID_S4U_DISK_HPP_ */
index 941b7cd..ea53d1c 100644 (file)
@@ -87,6 +87,7 @@ protected:
 #ifndef DOXYGEN
   friend Host;
   friend Link;
+  friend Disk;
   friend Storage;
   friend kernel::routing::NetPoint;
   friend kernel::routing::NetZoneImpl;
@@ -154,27 +155,27 @@ public:
    */
   void set_config(const std::string& str);
 
-private:
-  kernel::EngineImpl* const pimpl;
-  static Engine* instance_;
-};
+  /** Callback fired when the platform is created (ie, the xml file parsed),
+   * right before the actual simulation starts. */
+  static xbt::signal<void()> on_platform_created;
 
-/** Callback fired when the platform is created (ie, the xml file parsed),
* right before the actual simulation starts. */
-extern XBT_PUBLIC xbt::signal<void()> on_platform_created;
+  /** Callback fired when the platform is about to be created
  * (ie, after any configuration change and just before the resource creation) */
+  static xbt::signal<void()> on_platform_creation;
 
-/** Callback fired when the platform is about to be created
- * (ie, after any configuration change and just before the resource creation) */
-extern XBT_PUBLIC xbt::signal<void()> on_platform_creation;
+  /** Callback fired when the main simulation loop ends, just before the end of Engine::run() */
+  static xbt::signal<void()> on_simulation_end;
 
-/** Callback fired when the main simulation loop ends, just before the end of Engine::run() */
-extern XBT_PUBLIC xbt::signal<void()> on_simulation_end;
+  /** Callback fired when the time jumps into the future */
+  static xbt::signal<void(double)> on_time_advance;
 
-/** Callback fired when the time jumps into the future */
-extern XBT_PUBLIC xbt::signal<void(double)> on_time_advance;
+  /** Callback fired when the time cannot advance because of inter-actors deadlock */
+  static xbt::signal<void(void)> on_deadlock;
 
-/** Callback fired when the time cannot advance because of inter-actors deadlock */
-extern XBT_PUBLIC xbt::signal<void(void)> on_deadlock;
+private:
+  kernel::EngineImpl* const pimpl;
+  static Engine* instance_;
+};
 
 #ifndef DOXYGEN /* Internal use only, no need to expose it */
 template <class T> XBT_PRIVATE void get_filtered_netzones_recursive(s4u::NetZone* current, std::vector<T*>* whereto)
index 7702d6b..7679ffa 100644 (file)
@@ -115,6 +115,10 @@ public:
   void set_pstate(int pstate_index);
   int get_pstate() const;
 
+  std::vector<Disk*> get_disks() const;
+  void add_disk(Disk* disk);
+  void remove_disk(const std::string& disk_name);
+
   std::vector<const char*> get_attached_storages() const;
 
   /** Get an associative list [mount point]->[Storage] of all local mount points.
@@ -157,6 +161,4 @@ public:
 } // namespace s4u
 } // namespace simgrid
 
-extern int USER_HOST_LEVEL;
-
 #endif /* SIMGRID_S4U_HOST_HPP */
index d486b34..0ca0145 100644 (file)
@@ -17,7 +17,7 @@ namespace s4u {
 
 /** I/O Activity, representing the asynchronous disk access.
  *
- * They are generated from Storage::io_init() or Storage::read() and Storage::write().
+ * They are generated from Disk::io_init(), Disk::read() Disk::read_async(), Disk::write() and Disk::write_async().
  */
 
 class XBT_PUBLIC Io : public Activity {
@@ -26,17 +26,20 @@ public:
 
 private:
   Storage* storage_ = nullptr;
+  Disk* disk_       = nullptr;
   sg_size_t size_   = 0;
   OpType type_      = OpType::READ;
   std::string name_ = "";
   std::atomic_int_fast32_t refcount_{0};
 
   explicit Io(sg_storage_t storage, sg_size_t size, OpType type);
+  explicit Io(sg_disk_t disk, sg_size_t size, OpType type);
 
 public:
 #ifndef DOXYGEN
   friend XBT_PUBLIC void intrusive_ptr_release(simgrid::s4u::Io* i);
   friend XBT_PUBLIC void intrusive_ptr_add_ref(simgrid::s4u::Io* i);
+  friend Disk;    // Factory of IOs
   friend Storage; // Factory of IOs
 #endif
 
index 3ef6cee..8d788ed 100644 (file)
@@ -64,9 +64,6 @@ public:
   bool is_on() const;
   void turn_off();
 
-  void* get_data(); /** Should be used only from the C interface. Prefer extensions in C++ */
-  void set_data(void* d);
-
 #ifndef DOXYGEN
   XBT_ATTRIB_DEPRECATED_v325("Please use Link::set_state_profile()") void set_state_trace(
       kernel::profile::Profile* profile)
index 9bfa5ad..3099a47 100644 (file)
@@ -60,9 +60,6 @@ public:
   const char* get_property(const std::string& key) const;
   void set_property(const std::string&, const std::string& value);
 
-  void set_data(void* data) { userdata_ = data; }
-  void* get_data() { return userdata_; }
-
   IoPtr io_init(sg_size_t size, s4u::Io::OpType type);
 
   IoPtr read_async(sg_size_t size);
@@ -76,7 +73,6 @@ private:
   Host* attached_to_ = nullptr;
   kernel::resource::StorageImpl* const pimpl_;
   std::string name_;
-  void* userdata_ = nullptr;
 };
 
 } // namespace s4u
index fc162d6..5031939 100644 (file)
@@ -144,7 +144,7 @@ XBT_PUBLIC int SD_task_dependency_exists(SD_task_t src, SD_task_t dst);
 #define SD_init(argc, argv)                                                                                            \
   do {                                                                                                                 \
     sg_version_check(SIMGRID_VERSION_MAJOR, SIMGRID_VERSION_MINOR, SIMGRID_VERSION_PATCH);                             \
-    SD_init_nocheck(argc, argv);                                                                                       \
+    SD_init_nocheck((argc), (argv));                                                                                   \
   } while (0)
 
 XBT_PUBLIC void SD_init_nocheck(int* argc, char** argv);
index 27aceab..169d71c 100644 (file)
 
 #define CHECK_ACTION_PARAMS(action, mandatory, optional)                                                               \
   {                                                                                                                    \
-    if (action.size() < static_cast<unsigned long>(mandatory + 2)) {                                                   \
+    if ((action).size() < static_cast<unsigned long>((mandatory) + 2)) {                                               \
       std::stringstream ss;                                                                                            \
       ss << __func__ << " replay failed.\n"                                                                            \
-         << action.size() << " items were given on the line. First two should be process_id and action.  "             \
-         << "This action needs after them " << mandatory << " mandatory arguments, and accepts " << optional           \
+         << (action).size() << " items were given on the line. First two should be process_id and action.  "           \
+         << "This action needs after them " << (mandatory) << " mandatory arguments, and accepts " << (optional)       \
          << " optional ones. \n"                                                                                       \
          << "The full line that was given is:\n   ";                                                                   \
-      for (const auto& elem : action) {                                                                                \
+      for (const auto& elem : (action)) {                                                                              \
         ss << elem << " ";                                                                                             \
       }                                                                                                                \
       ss << "\nPlease contact the Simgrid team if support is needed";                                                  \
index a8923b1..e7c7d7c 100644 (file)
@@ -16,8 +16,8 @@
 #ifndef HAVE_SMPI
 // Internally disable these overrides (HAVE_SMPI is only defined when building the library)
 #define malloc(nbytes) _sampi_malloc(nbytes)
-#define calloc(n_elm,elm_size) _sampi_calloc(n_elm,elm_size)
-#define realloc(ptr,nbytes) _sampi_realloc(ptr,nbytes)
+#define calloc(n_elm, elm_size) _sampi_calloc((n_elm), (elm_size))
+#define realloc(ptr, nbytes) _sampi_realloc((ptr), (nbytes))
 #define free(ptr) _sampi_free(ptr)
 #endif
 
index c4e27b8..5af6d62 100644 (file)
@@ -410,6 +410,14 @@ typedef int MPI_Grequest_cancel_function(void *extra_state, int complete);
 typedef int (MPI_Datarep_extent_function)(MPI_Datatype, MPI_Aint *, void *);
 typedef int (MPI_Datarep_conversion_function)(void *, MPI_Datatype, int, void *, MPI_Offset, void *);
 
+typedef void MPI_Handler_function(MPI_Comm*, int*, ...);
+typedef void MPI_Comm_errhandler_function(MPI_Comm *, int *, ...);
+typedef void MPI_File_errhandler_function(MPI_File *, int *, ...);
+typedef void MPI_Win_errhandler_function(MPI_Win *, int *, ...);
+typedef MPI_Comm_errhandler_function MPI_Comm_errhandler_fn;
+typedef MPI_File_errhandler_function MPI_File_errhandler_fn;
+typedef MPI_Win_errhandler_function MPI_Win_errhandler_fn;
+
 MPI_CALL(XBT_PUBLIC int, MPI_Init, (int* argc, char*** argv));
 MPI_CALL(XBT_PUBLIC int, MPI_Finalize, (void));
 MPI_CALL(XBT_PUBLIC int, MPI_Finalized, (int* flag));
@@ -425,10 +433,12 @@ MPI_CALL(XBT_PUBLIC int, MPI_Alloc_mem, (MPI_Aint size, MPI_Info info, void* bas
 MPI_CALL(XBT_PUBLIC int, MPI_Free_mem, (void* base));
 MPI_CALL(XBT_PUBLIC double, MPI_Wtime, (void));
 MPI_CALL(XBT_PUBLIC double, MPI_Wtick, (void));
-
+MPI_CALL(XBT_PUBLIC int, MPI_Buffer_attach, (void* buffer, int size));
+MPI_CALL(XBT_PUBLIC int, MPI_Buffer_detach, (void* buffer, int* size));
 MPI_CALL(XBT_PUBLIC int, MPI_Address, (const void* location, MPI_Aint* address));
 MPI_CALL(XBT_PUBLIC int, MPI_Get_address, (const void* location, MPI_Aint* address));
 MPI_CALL(XBT_PUBLIC int, MPI_Error_class, (int errorcode, int* errorclass));
+MPI_CALL(XBT_PUBLIC int, MPI_Error_string, (int errorcode, char* string, int* resultlen));
 
 MPI_CALL(XBT_PUBLIC int, MPI_Attr_delete, (MPI_Comm comm, int keyval));
 MPI_CALL(XBT_PUBLIC int, MPI_Attr_get, (MPI_Comm comm, int keyval, void* attr_value, int* flag));
@@ -557,6 +567,11 @@ MPI_CALL(XBT_PUBLIC int, MPI_Send, (const void* buf, int count, MPI_Datatype dat
 MPI_CALL(XBT_PUBLIC int, MPI_Ssend, (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm));
 MPI_CALL(XBT_PUBLIC int, MPI_Ssend_init,
          (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
+MPI_CALL(XBT_PUBLIC int, MPI_Bsend, (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm));
+MPI_CALL(XBT_PUBLIC int, MPI_Bsend_init,
+         (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
+MPI_CALL(XBT_PUBLIC int, MPI_Ibsend,
+         (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
 MPI_CALL(XBT_PUBLIC int, MPI_Issend,
          (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
 MPI_CALL(XBT_PUBLIC int, MPI_Sendrecv,
@@ -790,7 +805,24 @@ MPI_CALL(XBT_PUBLIC int, MPI_File_seek_shared, (MPI_File fh, MPI_Offset offset,
 MPI_CALL(XBT_PUBLIC int, MPI_File_get_position_shared, (MPI_File fh, MPI_Offset* offset));
 MPI_CALL(XBT_PUBLIC int, MPI_File_sync, (MPI_File fh));
 
-
+MPI_CALL(XBT_PUBLIC int, MPI_Errhandler_set, (MPI_Comm comm, MPI_Errhandler errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Errhandler_create, (MPI_Handler_function * function, MPI_Errhandler* errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Errhandler_free, (MPI_Errhandler * errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Errhandler_get, (MPI_Comm comm, MPI_Errhandler* errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Comm_set_errhandler, (MPI_Comm comm, MPI_Errhandler errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Comm_get_errhandler, (MPI_Comm comm, MPI_Errhandler* errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Comm_create_errhandler, (MPI_Comm_errhandler_fn * function, MPI_Errhandler* errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Comm_call_errhandler, (MPI_Comm comm, int errorcode));
+MPI_CALL(XBT_PUBLIC int, MPI_Win_set_errhandler, (MPI_Win win, MPI_Errhandler errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Win_get_errhandler, (MPI_Win win, MPI_Errhandler* errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Win_create_errhandler, (MPI_Win_errhandler_fn * function, MPI_Errhandler* errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_Win_call_errhandler, (MPI_Win win, int errorcode));MPI_CALL(XBT_PUBLIC int, MPI_Type_get_envelope,
+         (MPI_Datatype datatype, int* num_integers, int* num_addresses, int* num_datatypes, int* combiner));
+MPI_CALL(XBT_PUBLIC int, MPI_File_call_errhandler, (MPI_File fh, int errorcode));
+MPI_CALL(XBT_PUBLIC int, MPI_File_create_errhandler,
+         (MPI_File_errhandler_function * function, MPI_Errhandler* errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_File_set_errhandler, (MPI_File file, MPI_Errhandler errhandler));
+MPI_CALL(XBT_PUBLIC int, MPI_File_get_errhandler, (MPI_File file, MPI_Errhandler* errhandler));
 //FIXME: these are not yet implemented
 
 typedef enum MPIR_Combiner_enum{
@@ -815,19 +847,12 @@ typedef enum MPIR_Combiner_enum{
   MPI_COMBINER_HINDEXED_BLOCK
 }MPIR_Combiner_enum;
 
-typedef void MPI_Handler_function(MPI_Comm*, int*, ...);
 typedef void* MPI_Message;
-typedef void MPI_Comm_errhandler_function(MPI_Comm *, int *, ...);
-typedef void MPI_File_errhandler_function(MPI_File *, int *, ...);
-typedef void MPI_Win_errhandler_function(MPI_Win *, int *, ...);
 #define MPI_DUP_FN 1
 
 #define MPI_WIN_DUP_FN ((MPI_Win_copy_attr_function*)MPI_DUP_FN)
 #define MPI_TYPE_DUP_FN ((MPI_Type_copy_attr_function*)MPI_DUP_FN)
 #define MPI_COMM_DUP_FN  ((MPI_Comm_copy_attr_function *)MPI_DUP_FN)
-typedef MPI_Comm_errhandler_function MPI_Comm_errhandler_fn;
-typedef MPI_File_errhandler_function MPI_File_errhandler_fn;
-typedef MPI_Win_errhandler_function MPI_Win_errhandler_fn;
 #define MPI_INFO_ENV smpi_process_info_env()
 XBT_PUBLIC_DATA const MPI_Datatype MPI_PACKED;
 XBT_PUBLIC_DATA MPI_Errhandler MPI_ERRORS_RETURN;
@@ -844,30 +869,14 @@ MPI_CALL(XBT_PUBLIC int, MPI_Graph_neighbors, (MPI_Comm comm, int rank, int maxn
 MPI_CALL(XBT_PUBLIC int, MPI_Graph_neighbors_count, (MPI_Comm comm, int rank, int* nneighbors));
 MPI_CALL(XBT_PUBLIC int, MPI_Graphdims_get, (MPI_Comm comm, int* nnodes, int* nedges));
 MPI_CALL(XBT_PUBLIC int, MPI_Topo_test, (MPI_Comm comm, int* top_type));
-MPI_CALL(XBT_PUBLIC int, MPI_Errhandler_create, (MPI_Handler_function * function, MPI_Errhandler* errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Errhandler_free, (MPI_Errhandler * errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Errhandler_get, (MPI_Comm comm, MPI_Errhandler* errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Error_string, (int errorcode, char* string, int* resultlen));
-MPI_CALL(XBT_PUBLIC int, MPI_Errhandler_set, (MPI_Comm comm, MPI_Errhandler errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Comm_set_errhandler, (MPI_Comm comm, MPI_Errhandler errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Comm_get_errhandler, (MPI_Comm comm, MPI_Errhandler* errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Comm_create_errhandler, (MPI_Comm_errhandler_fn * function, MPI_Errhandler* errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Comm_call_errhandler, (MPI_Comm comm, int errorcode));
 MPI_CALL(XBT_PUBLIC int, MPI_Add_error_class, (int* errorclass));
 MPI_CALL(XBT_PUBLIC int, MPI_Add_error_code, (int errorclass, int* errorcode));
 MPI_CALL(XBT_PUBLIC int, MPI_Add_error_string, (int errorcode, char* string));
 MPI_CALL(XBT_PUBLIC int, MPI_Cancel, (MPI_Request * request));
-MPI_CALL(XBT_PUBLIC int, MPI_Buffer_attach, (void* buffer, int size));
-MPI_CALL(XBT_PUBLIC int, MPI_Buffer_detach, (void* buffer, int* size));
 MPI_CALL(XBT_PUBLIC int, MPI_Comm_test_inter, (MPI_Comm comm, int* flag));
 MPI_CALL(XBT_PUBLIC int, MPI_Intercomm_create,
          (MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm* comm_out));
 MPI_CALL(XBT_PUBLIC int, MPI_Intercomm_merge, (MPI_Comm comm, int high, MPI_Comm* comm_out));
-MPI_CALL(XBT_PUBLIC int, MPI_Bsend, (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm));
-MPI_CALL(XBT_PUBLIC int, MPI_Bsend_init,
-         (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
-MPI_CALL(XBT_PUBLIC int, MPI_Ibsend,
-         (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
 MPI_CALL(XBT_PUBLIC int, MPI_Comm_remote_group, (MPI_Comm comm, MPI_Group* group));
 MPI_CALL(XBT_PUBLIC int, MPI_Comm_remote_size, (MPI_Comm comm, int* size));
 MPI_CALL(XBT_PUBLIC int, MPI_Rsend, (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm));
@@ -877,12 +886,6 @@ MPI_CALL(XBT_PUBLIC int, MPI_Irsend,
          (const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request));
 MPI_CALL(XBT_PUBLIC int, MPI_Get_elements, (MPI_Status * status, MPI_Datatype datatype, int* elements));
 MPI_CALL(XBT_PUBLIC int, MPI_Pcontrol, (const int level, ...));
-
-MPI_CALL(XBT_PUBLIC int, MPI_Win_set_errhandler, (MPI_Win win, MPI_Errhandler errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Win_get_errhandler, (MPI_Win win, MPI_Errhandler* errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Win_create_errhandler, (MPI_Win_errhandler_fn * function, MPI_Errhandler* errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_Win_call_errhandler, (MPI_Win win, int errorcode));MPI_CALL(XBT_PUBLIC int, MPI_Type_get_envelope,
-         (MPI_Datatype datatype, int* num_integers, int* num_addresses, int* num_datatypes, int* combiner));
 MPI_CALL(XBT_PUBLIC int, MPI_Type_get_contents,
          (MPI_Datatype datatype, int max_integers, int max_addresses, int max_datatypes, int* array_of_integers,
           MPI_Aint* array_of_addresses, MPI_Datatype* array_of_datatypes));
@@ -917,11 +920,6 @@ MPI_CALL(XBT_PUBLIC MPI_File, MPI_File_f2c, (MPI_Fint file));
 MPI_CALL(XBT_PUBLIC int, MPI_Register_datarep, (char* datarep, MPI_Datarep_conversion_function* read_conversion_fn,
                                                 MPI_Datarep_conversion_function* write_conversion_fn,
                                                 MPI_Datarep_extent_function* dtype_file_extent_fn, void* extra_state));
-MPI_CALL(XBT_PUBLIC int, MPI_File_call_errhandler, (MPI_File fh, int errorcode));
-MPI_CALL(XBT_PUBLIC int, MPI_File_create_errhandler,
-         (MPI_File_errhandler_function * function, MPI_Errhandler* errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_File_set_errhandler, (MPI_File file, MPI_Errhandler errhandler));
-MPI_CALL(XBT_PUBLIC int, MPI_File_get_errhandler, (MPI_File file, MPI_Errhandler* errhandler));
 MPI_CALL(XBT_PUBLIC int, MPI_File_set_size, (MPI_File fh, MPI_Offset size));
 MPI_CALL(XBT_PUBLIC int, MPI_File_preallocate, (MPI_File fh, MPI_Offset size));
 MPI_CALL(XBT_PUBLIC int, MPI_File_set_view,
@@ -1008,27 +1006,31 @@ XBT_PUBLIC void smpi_trace_set_call_location__(const char* file, int* line);
 
 #define SMPI_ITER_NAME1(line) _XBT_CONCAT(iter_count, line)
 #define SMPI_ITER_NAME(line) SMPI_ITER_NAME1(line)
-#define SMPI_SAMPLE_LOOP(loop_init, loop_end, loop_iter, global, iters, thres)\
-  int SMPI_ITER_NAME(__LINE__)=0;\
-  {loop_init;\
-  while(loop_end){\
-    SMPI_ITER_NAME(__LINE__)++;\
-    loop_iter;\
-  }}                                                                         \
-  for(loop_init; \
-      loop_end ? (smpi_sample_1(global, __FILE__, __LINE__, iters, thres), (smpi_sample_2(global, __FILE__, __LINE__, SMPI_ITER_NAME(__LINE__)))) :\
-      smpi_sample_exit(global, __FILE__, __LINE__, SMPI_ITER_NAME(__LINE__));\
-      smpi_sample_3(global, __FILE__, __LINE__),loop_iter)
-#define SMPI_SAMPLE_LOCAL(loop_init, loop_end, loop_iter, iters, thres) SMPI_SAMPLE_LOOP(loop_init, loop_end, loop_iter, 0, iters, thres)
-#define SMPI_SAMPLE_GLOBAL(loop_init, loop_end, loop_iter,iters, thres) SMPI_SAMPLE_LOOP(loop_init, loop_end, loop_iter, 1, iters, thres)
+#define SMPI_SAMPLE_LOOP(loop_init, loop_end, loop_iter, global, iters, thres)                                         \
+  int SMPI_ITER_NAME(__LINE__) = 0;                                                                                    \
+  {                                                                                                                    \
+    loop_init;                                                                                                         \
+    while (loop_end) {                                                                                                 \
+      SMPI_ITER_NAME(__LINE__)++;                                                                                      \
+      (loop_iter);                                                                                                     \
+    }                                                                                                                  \
+  }                                                                                                                    \
+  for (loop_init; (loop_end) ? (smpi_sample_1((global), __FILE__, __LINE__, (iters), (thres)),                         \
+                                (smpi_sample_2((global), __FILE__, __LINE__, SMPI_ITER_NAME(__LINE__))))               \
+                             : smpi_sample_exit((global), __FILE__, __LINE__, SMPI_ITER_NAME(__LINE__));               \
+       smpi_sample_3((global), __FILE__, __LINE__), (loop_iter))
+#define SMPI_SAMPLE_LOCAL(loop_init, loop_end, loop_iter, iters, thres)                                                \
+  SMPI_SAMPLE_LOOP(loop_init, (loop_end), (loop_iter), 0, (iters), (thres))
+#define SMPI_SAMPLE_GLOBAL(loop_init, loop_end, loop_iter, iters, thres)                                               \
+  SMPI_SAMPLE_LOOP(loop_init, (loop_end), (loop_iter), 1, (iters), (thres))
 #define SMPI_SAMPLE_DELAY(duration) for(smpi_execute(duration); 0; )
 #define SMPI_SAMPLE_FLOPS(flops) for(smpi_execute_flops(flops); 0; )
 
 XBT_PUBLIC void* smpi_shared_malloc(size_t size, const char* file, int line);
-#define SMPI_SHARED_MALLOC(size) smpi_shared_malloc(size, __FILE__, __LINE__)
+#define SMPI_SHARED_MALLOC(size) smpi_shared_malloc((size), __FILE__, __LINE__)
 XBT_PUBLIC void* smpi_shared_malloc_partial(size_t size, size_t* shared_block_offsets, int nb_shared_blocks);
 #define SMPI_PARTIAL_SHARED_MALLOC(size, shared_block_offsets, nb_shared_blocks)                                       \
-  smpi_shared_malloc_partial(size, shared_block_offsets, nb_shared_blocks)
+  smpi_shared_malloc_partial((size), (shared_block_offsets), (nb_shared_blocks))
 
 XBT_PUBLIC void smpi_shared_free(void* data);
 #define SMPI_SHARED_FREE(data) smpi_shared_free(data)
@@ -1037,9 +1039,9 @@ XBT_PUBLIC int smpi_shared_known_call(const char* func, const char* input);
 XBT_PUBLIC void* smpi_shared_get_call(const char* func, const char* input);
 XBT_PUBLIC void* smpi_shared_set_call(const char* func, const char* input, void* data);
 #define SMPI_SHARED_CALL(func, input, ...)                                                                             \
-  (smpi_shared_known_call(_XBT_STRINGIFY(func), input)                                                                 \
-       ? smpi_shared_get_call(_XBT_STRINGIFY(func), input)                                                             \
-       : smpi_shared_set_call(_XBT_STRINGIFY(func), input, (func(__VA_ARGS__))))
+  (smpi_shared_known_call(_XBT_STRINGIFY(func), (input))                                                               \
+       ? smpi_shared_get_call(_XBT_STRINGIFY(func), (input))                                                           \
+       : smpi_shared_set_call(_XBT_STRINGIFY(func), (input), ((func)(__VA_ARGS__))))
 
 /* Fortran specific stuff */
 
index 96f7bee..b17bb99 100644 (file)
 #define MPI_Free_mem(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Free_mem(__VA_ARGS__); })
 #define MPI_Wtime(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Wtime(__VA_ARGS__); })
 #define MPI_Wtick(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Wtick(__VA_ARGS__); })
+#define MPI_Buffer_attach(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Buffer_attach(__VA_ARGS__); })
+#define MPI_Buffer_detach(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Buffer_detach(__VA_ARGS__); })
 #define MPI_Address(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Address(__VA_ARGS__); })
 #define MPI_Get_address(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Get_address(__VA_ARGS__); })
 #define MPI_Error_class(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Error_class(__VA_ARGS__); })
+#define MPI_Error_string(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Error_string(__VA_ARGS__); })
 #define MPI_Attr_delete(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Attr_delete(__VA_ARGS__); })
 #define MPI_Attr_get(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Attr_get(__VA_ARGS__); })
 #define MPI_Attr_put(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Attr_put(__VA_ARGS__); })
 #define MPI_Send(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Send(__VA_ARGS__); })
 #define MPI_Ssend(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ssend(__VA_ARGS__); })
 #define MPI_Ssend_init(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ssend_init(__VA_ARGS__); })
+#define MPI_Bsend(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Bsend(__VA_ARGS__); })
+#define MPI_Bsend_init(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Bsend_init(__VA_ARGS__); })
+#define MPI_Ibsend(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ibsend(__VA_ARGS__); })
 #define MPI_Issend(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Issend(__VA_ARGS__); })
 #define MPI_Sendrecv(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Sendrecv(__VA_ARGS__); })
 #define MPI_Sendrecv_replace(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Sendrecv_replace(__VA_ARGS__); })
 #define MPI_File_seek_shared(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_seek_shared(__VA_ARGS__); })
 #define MPI_File_get_position_shared(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_get_position_shared(__VA_ARGS__); })
 #define MPI_File_sync(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_sync(__VA_ARGS__); })
+#define MPI_Errhandler_set(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_set(__VA_ARGS__); })
+#define MPI_Errhandler_create(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_create(__VA_ARGS__); })
+#define MPI_Errhandler_free(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_free(__VA_ARGS__); })
+#define MPI_Errhandler_get(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_get(__VA_ARGS__); })
+#define MPI_Comm_set_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_set_errhandler(__VA_ARGS__); })
+#define MPI_Comm_get_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_get_errhandler(__VA_ARGS__); })
+#define MPI_Comm_create_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_create_errhandler(__VA_ARGS__); })
+#define MPI_Comm_call_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_call_errhandler(__VA_ARGS__); })
+#define MPI_Win_set_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Win_set_errhandler(__VA_ARGS__); })
+#define MPI_Win_get_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Win_get_errhandler(__VA_ARGS__); })
+#define MPI_Win_create_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Win_create_errhandler(__VA_ARGS__); })
+#define MPI_Win_call_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Win_call_errhandler(__VA_ARGS__); })
+#define MPI_File_call_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_call_errhandler(__VA_ARGS__); })
+#define MPI_File_create_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_create_errhandler(__VA_ARGS__); })
+#define MPI_File_set_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_set_errhandler(__VA_ARGS__); })
+#define MPI_File_get_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_get_errhandler(__VA_ARGS__); })
 #define MPI_Errhandler_f2c(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_f2c(__VA_ARGS__); })
 #define MPI_Errhandler_c2f(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_c2f(__VA_ARGS__); })
 #define MPI_Cart_map(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Cart_map(__VA_ARGS__); })
 #define MPI_Graph_neighbors_count(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Graph_neighbors_count(__VA_ARGS__); })
 #define MPI_Graphdims_get(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Graphdims_get(__VA_ARGS__); })
 #define MPI_Topo_test(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Topo_test(__VA_ARGS__); })
-#define MPI_Errhandler_create(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_create(__VA_ARGS__); })
-#define MPI_Errhandler_free(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_free(__VA_ARGS__); })
-#define MPI_Errhandler_get(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_get(__VA_ARGS__); })
-#define MPI_Error_string(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Error_string(__VA_ARGS__); })
-#define MPI_Errhandler_set(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Errhandler_set(__VA_ARGS__); })
-#define MPI_Comm_set_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_set_errhandler(__VA_ARGS__); })
-#define MPI_Comm_get_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_get_errhandler(__VA_ARGS__); })
-#define MPI_Comm_create_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_create_errhandler(__VA_ARGS__); })
-#define MPI_Comm_call_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_call_errhandler(__VA_ARGS__); })
 #define MPI_Add_error_class(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Add_error_class(__VA_ARGS__); })
 #define MPI_Add_error_code(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Add_error_code(__VA_ARGS__); })
 #define MPI_Add_error_string(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Add_error_string(__VA_ARGS__); })
 #define MPI_Cancel(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Cancel(__VA_ARGS__); })
-#define MPI_Buffer_attach(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Buffer_attach(__VA_ARGS__); })
-#define MPI_Buffer_detach(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Buffer_detach(__VA_ARGS__); })
 #define MPI_Comm_test_inter(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_test_inter(__VA_ARGS__); })
 #define MPI_Intercomm_create(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Intercomm_create(__VA_ARGS__); })
 #define MPI_Intercomm_merge(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Intercomm_merge(__VA_ARGS__); })
-#define MPI_Bsend(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Bsend(__VA_ARGS__); })
-#define MPI_Bsend_init(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Bsend_init(__VA_ARGS__); })
-#define MPI_Ibsend(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ibsend(__VA_ARGS__); })
 #define MPI_Comm_remote_group(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_remote_group(__VA_ARGS__); })
 #define MPI_Comm_remote_size(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Comm_remote_size(__VA_ARGS__); })
 #define MPI_Rsend(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Rsend(__VA_ARGS__); })
 #define MPI_Irsend(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Irsend(__VA_ARGS__); })
 #define MPI_Get_elements(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Get_elements(__VA_ARGS__); })
 #define MPI_Pcontrol(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Pcontrol(__VA_ARGS__); })
-#define MPI_Win_set_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Win_set_errhandler(__VA_ARGS__); })
-#define MPI_Win_get_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Win_get_errhandler(__VA_ARGS__); })
-#define MPI_Win_create_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Win_create_errhandler(__VA_ARGS__); })
-#define MPI_Win_call_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Win_call_errhandler(__VA_ARGS__); })
 #define MPI_Type_get_contents(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Type_get_contents(__VA_ARGS__); })
 #define MPI_Type_create_darray(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Type_create_darray(__VA_ARGS__); })
 #define MPI_Pack_external_size(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Pack_external_size(__VA_ARGS__); })
 #define MPI_File_c2f(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_c2f(__VA_ARGS__); })
 #define MPI_File_f2c(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_f2c(__VA_ARGS__); })
 #define MPI_Register_datarep(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Register_datarep(__VA_ARGS__); })
-#define MPI_File_call_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_call_errhandler(__VA_ARGS__); })
-#define MPI_File_create_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_create_errhandler(__VA_ARGS__); })
-#define MPI_File_set_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_set_errhandler(__VA_ARGS__); })
-#define MPI_File_get_errhandler(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_get_errhandler(__VA_ARGS__); })
 #define MPI_File_set_size(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_set_size(__VA_ARGS__); })
 #define MPI_File_preallocate(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_preallocate(__VA_ARGS__); })
 #define MPI_File_set_view(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_File_set_view(__VA_ARGS__); })
index 1de6c29..b1d58c8 100644 (file)
 #define MPI_WTIME smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wtime
 #define mpi_wtick smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wtick
 #define MPI_WTICK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Wtick
+#define mpi_buffer_attach smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_attach
+#define MPI_BUFFER_ATTACH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_attach
+#define mpi_buffer_detach smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_detach
+#define MPI_BUFFER_DETACH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_detach
 #define mpi_address smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Address
 #define MPI_ADDRESS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Address
 #define mpi_get_address smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_address
 #define MPI_GET_ADDRESS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_address
 #define mpi_error_class smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_class
 #define MPI_ERROR_CLASS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_class
+#define mpi_error_string smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_string
+#define MPI_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_string
 #define mpi_attr_delete smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_delete
 #define MPI_ATTR_DELETE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_delete
 #define mpi_attr_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Attr_get
 #define MPI_SSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ssend
 #define mpi_ssend_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ssend_init
 #define MPI_SSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ssend_init
+#define mpi_bsend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend
+#define MPI_BSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend
+#define mpi_bsend_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend_init
+#define MPI_BSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend_init
+#define mpi_ibsend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibsend
+#define MPI_IBSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibsend
 #define mpi_issend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Issend
 #define MPI_ISSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Issend
 #define mpi_sendrecv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Sendrecv
 #define MPI_FILE_GET_POSITION_SHARED smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_position_shared
 #define mpi_file_sync smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_sync
 #define MPI_FILE_SYNC smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_sync
+#define mpi_errhandler_set smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_set
+#define MPI_ERRHANDLER_SET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_set
+#define mpi_errhandler_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_create
+#define MPI_ERRHANDLER_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_create
+#define mpi_errhandler_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_free
+#define MPI_ERRHANDLER_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_free
+#define mpi_errhandler_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_get
+#define MPI_ERRHANDLER_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_get
+#define mpi_comm_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_errhandler
+#define MPI_COMM_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_errhandler
+#define mpi_comm_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_errhandler
+#define MPI_COMM_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_errhandler
+#define mpi_comm_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_errhandler
+#define MPI_COMM_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_errhandler
+#define mpi_comm_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_call_errhandler
+#define MPI_COMM_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_call_errhandler
+#define mpi_win_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_errhandler
+#define MPI_WIN_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_errhandler
+#define mpi_win_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_errhandler
+#define MPI_WIN_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_errhandler
+#define mpi_win_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_errhandler
+#define MPI_WIN_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_errhandler
+#define mpi_win_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_call_errhandler
+#define MPI_WIN_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_call_errhandler
+#define mpi_file_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_call_errhandler
+#define MPI_FILE_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_call_errhandler
+#define mpi_file_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_create_errhandler
+#define MPI_FILE_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_create_errhandler
+#define mpi_file_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_errhandler
+#define MPI_FILE_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_errhandler
+#define mpi_file_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_errhandler
+#define MPI_FILE_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_errhandler
 #define mpi_errhandler_f2c smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_f2c
 #define MPI_ERRHANDLER_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_f2c
 #define mpi_errhandler_c2f smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_c2f
 #define MPI_GRAPHDIMS_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Graphdims_get
 #define mpi_topo_test smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Topo_test
 #define MPI_TOPO_TEST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Topo_test
-#define mpi_errhandler_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_create
-#define MPI_ERRHANDLER_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_create
-#define mpi_errhandler_free smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_free
-#define MPI_ERRHANDLER_FREE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_free
-#define mpi_errhandler_get smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_get
-#define MPI_ERRHANDLER_GET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_get
-#define mpi_error_string smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_string
-#define MPI_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Error_string
-#define mpi_errhandler_set smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_set
-#define MPI_ERRHANDLER_SET smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Errhandler_set
-#define mpi_comm_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_errhandler
-#define MPI_COMM_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_set_errhandler
-#define mpi_comm_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_errhandler
-#define MPI_COMM_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_get_errhandler
-#define mpi_comm_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_errhandler
-#define MPI_COMM_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_create_errhandler
-#define mpi_comm_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_call_errhandler
-#define MPI_COMM_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_call_errhandler
 #define mpi_add_error_class smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_class
 #define MPI_ADD_ERROR_CLASS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_class
 #define mpi_add_error_code smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_code
 #define MPI_ADD_ERROR_STRING smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Add_error_string
 #define mpi_cancel smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cancel
 #define MPI_CANCEL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Cancel
-#define mpi_buffer_attach smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_attach
-#define MPI_BUFFER_ATTACH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_attach
-#define mpi_buffer_detach smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_detach
-#define MPI_BUFFER_DETACH smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Buffer_detach
 #define mpi_comm_test_inter smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_test_inter
 #define MPI_COMM_TEST_INTER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_test_inter
 #define mpi_intercomm_create smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Intercomm_create
 #define MPI_INTERCOMM_CREATE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Intercomm_create
 #define mpi_intercomm_merge smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Intercomm_merge
 #define MPI_INTERCOMM_MERGE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Intercomm_merge
-#define mpi_bsend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend
-#define MPI_BSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend
-#define mpi_bsend_init smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend_init
-#define MPI_BSEND_INIT smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bsend_init
-#define mpi_ibsend smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibsend
-#define MPI_IBSEND smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibsend
 #define mpi_comm_remote_group smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_remote_group
 #define MPI_COMM_REMOTE_GROUP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_remote_group
 #define mpi_comm_remote_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Comm_remote_size
 #define MPI_GET_ELEMENTS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Get_elements
 #define mpi_pcontrol smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pcontrol
 #define MPI_PCONTROL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Pcontrol
-#define mpi_win_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_errhandler
-#define MPI_WIN_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_set_errhandler
-#define mpi_win_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_errhandler
-#define MPI_WIN_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_get_errhandler
-#define mpi_win_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_errhandler
-#define MPI_WIN_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_create_errhandler
-#define mpi_win_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_call_errhandler
-#define MPI_WIN_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Win_call_errhandler
 #define mpi_type_get_contents smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_contents
 #define MPI_TYPE_GET_CONTENTS smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_get_contents
 #define mpi_type_create_darray smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Type_create_darray
 #define MPI_FILE_F2C smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_f2c
 #define mpi_register_datarep smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Register_datarep
 #define MPI_REGISTER_DATAREP smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Register_datarep
-#define mpi_file_call_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_call_errhandler
-#define MPI_FILE_CALL_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_call_errhandler
-#define mpi_file_create_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_create_errhandler
-#define MPI_FILE_CREATE_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_create_errhandler
-#define mpi_file_set_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_errhandler
-#define MPI_FILE_SET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_errhandler
-#define mpi_file_get_errhandler smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_errhandler
-#define MPI_FILE_GET_ERRHANDLER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_get_errhandler
 #define mpi_file_set_size smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_size
 #define MPI_FILE_SET_SIZE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_set_size
 #define mpi_file_preallocate smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_File_preallocate
index be15a24..6739870 100644 (file)
 
 #define sleep(x) smpi_sleep(x)
 #define usleep(x) smpi_usleep(x)
-#define gettimeofday(x, y) smpi_gettimeofday(x, 0)
+#define gettimeofday(x, y) smpi_gettimeofday((x), 0)
 #if _POSIX_TIMERS > 0
-#define nanosleep(x, y) smpi_nanosleep(x, y)
-#define clock_gettime(x, y) smpi_clock_gettime(x, y)
+#define nanosleep(x, y) smpi_nanosleep((x), (y))
+#define clock_gettime(x, y) smpi_clock_gettime((x), (y))
 #endif
 
-#define getopt(x,y,z) smpi_getopt(x,y,z)
-#define getopt_long(x,y,z,a,b) smpi_getopt_long(x,y,z,a,b)
-#define getopt_long_only(x,y,z,a,b) smpi_getopt_long_only(x,y,z,a,b)
+#define getopt(x, y, z) smpi_getopt((x), (y), (z))
+#define getopt_long(x, y, z, a, b) smpi_getopt_long((x), (y), (z), (a), (b))
+#define getopt_long_only(x, y, z, a, b) smpi_getopt_long_only((x), (y), (z), (a), (b))
 
 #endif
index 5a3e4b6..6c226fb 100644 (file)
@@ -7,6 +7,8 @@
 #define SMPI_HELPERS_INTERNAL_H
 
 #include <getopt.h>
+#include <stdio.h>  /* for getopt(), don't remove */
+#include <stdlib.h> /* for getopt(), don't remove */
 #include <unistd.h>
 
 #include <sys/time.h>
index 37946b6..d95d186 100644 (file)
@@ -52,6 +52,9 @@ private:
 public:
   static size_t extension_create(void (*deleter)(void*))
   {
+    if (deleters_.empty()) { // Save space for void* user data
+      deleters_.push_back(nullptr);
+    }
     deleters_.push_back(deleter);
     return deleters_.size() - 1;
   }
@@ -65,7 +68,7 @@ public:
   {
     return Extension<T, U>(extension_create([](void* p) { delete static_cast<U*>(p); }));
   }
-  Extendable() : extensions_(deleters_.size(), nullptr) {}
+  Extendable() : extensions_((deleters_.size() > 0 ? deleters_.size() : 1), nullptr) {}
   Extendable(const Extendable&) = delete;
   Extendable& operator=(const Extendable&) = delete;
   ~Extendable()
@@ -76,7 +79,7 @@ public:
      * an extension A, the subsystem of B might depend on the subsystem on A and
      * an extension of B might need to have the extension of A around when executing
      * its cleanup function/destructor. */
-    for (std::size_t i = extensions_.size(); i > 0; --i)
+    for (std::size_t i = extensions_.size(); i > 1; --i) // rank=0 is the spot of user's void*
       if (extensions_[i - 1] != nullptr && deleters_[i - 1] != nullptr)
         deleters_[i - 1](extensions_[i - 1]);
   }
@@ -103,7 +106,13 @@ public:
   {
     extension_set(rank.id(), value, use_dtor);
   }
-
+  // void* version, for C users and nostalgics
+  void set_data(void* data){
+    extensions_[0]=data;
+  }
+  void* get_data(){
+    return extensions_[0];
+  }
   // Convenience extension access when the type has a associated EXTENSION ID:
   template <class U> U* extension() const { return extension<U>(U::EXTENSION_ID); }
   template<class U> void extension_set(U* p) { extension_set<U>(U::EXTENSION_ID, p); }
index b455627..585b123 100644 (file)
@@ -35,8 +35,7 @@ XBT_PUBLIC void xbt_backtrace_display_current();
    @hideinitializer  */
 #define xbt_assert(...) \
   _XBT_IF_ONE_ARG(_xbt_assert_ARG1, _xbt_assert_ARGN, __VA_ARGS__)(__VA_ARGS__)
-#define _xbt_assert_ARG1(cond) \
-  _xbt_assert_ARGN(cond, "Assertion %s failed", #cond)
+#define _xbt_assert_ARG1(cond) _xbt_assert_ARGN((cond), "Assertion %s failed", #cond)
 #define _xbt_assert_ARGN(cond, ...)                                                                                    \
   do {                                                                                                                 \
     if (!(cond)) {                                                                                                     \
index e0d787e..1f49c1b 100644 (file)
 #ifdef __MINGW32__
 #  include <stdio.h>
 
-#  define XBT_ATTRIB_PRINTF( format_idx, arg_idx )    \
-     __attribute__((__format__ (__MINGW_PRINTF_FORMAT, format_idx, arg_idx)))
-#  define XBT_ATTRIB_SCANF( format_idx, arg_idx )     \
-     __attribute__((__MINGW_SCANF_FORMAT (__scanf__, format_idx, arg_idx)))
+#define XBT_ATTRIB_PRINTF(format_idx, arg_idx)                                                                         \
+  __attribute__((__format__(__MINGW_PRINTF_FORMAT, (format_idx), (arg_idx))))
+#define XBT_ATTRIB_SCANF(format_idx, arg_idx) __attribute__((__MINGW_SCANF_FORMAT(__scanf__, (format_idx), (arg_idx))))
 #else
-#  define XBT_ATTRIB_PRINTF( format_idx, arg_idx )    \
-     __attribute__((__format__ (__printf__, format_idx, arg_idx)))
-#  define XBT_ATTRIB_SCANF( format_idx, arg_idx )     \
-     __attribute__((__format__ (__scanf__, format_idx, arg_idx)))
+#define XBT_ATTRIB_PRINTF(format_idx, arg_idx) __attribute__((__format__(__printf__, (format_idx), (arg_idx))))
+#define XBT_ATTRIB_SCANF(format_idx, arg_idx) __attribute__((__format__(__scanf__, (format_idx), (arg_idx))))
 #endif
 
 #if defined(__cplusplus)
index 589af4a..f27f5d3 100644 (file)
@@ -158,10 +158,9 @@ xbt_dict_foreach(head, cursor, key, data) {
 }
 @endcode
  */
-#  define xbt_dict_foreach(dict,cursor,key,data)                       \
-    for (cursor=NULL, xbt_dict_cursor_first((dict),&(cursor)) ;        \
-         xbt_dict_cursor_get_or_free(&(cursor),(char**)&(key),(void**)(&data));\
-         xbt_dict_cursor_step(cursor) )
+#define xbt_dict_foreach(dict, cursor, key, data)                                                                      \
+  for ((cursor) = NULL, xbt_dict_cursor_first((dict), &(cursor));                                                      \
+       xbt_dict_cursor_get_or_free(&(cursor), (char**)&(key), (void**)&(data)); xbt_dict_cursor_step(cursor))
 
 /** @} */
 
index b7529f3..9df2eca 100644 (file)
@@ -151,26 +151,23 @@ XBT_PUBLIC void* xbt_dynar_pop_ptr(xbt_dynar_t const dynar);
           (*(type*)xbt_dynar_get_ptr((dynar),(idx)))
 /** @brief Quick setting of scalar content
  *  @hideinitializer */
-#  define xbt_dynar_set_as(dynar,idx,type,val) \
-         (*(type*)xbt_dynar_set_at_ptr((dynar),(idx))) = val
-  /** @brief Quick retrieval of scalar content
-   *  @hideinitializer */
+#define xbt_dynar_set_as(dynar, idx, type, val) (*(type*)xbt_dynar_set_at_ptr((dynar), (idx))) = (val)
+/** @brief Quick retrieval of scalar content
+ *  @hideinitializer */
 #  define xbt_dynar_getlast_as(dynar,type) \
           (*(type*)xbt_dynar_get_ptr((dynar),xbt_dynar_length(dynar)-1))
-  /** @brief Quick retrieval of scalar content
  *  @hideinitializer */
+/** @brief Quick retrieval of scalar content
+ *  @hideinitializer */
 #  define xbt_dynar_getfirst_as(dynar,type) \
           (*(type*)xbt_dynar_get_ptr((dynar),0))
-  /** @brief Quick insertion of scalar content
-   *  @hideinitializer */
-#  define xbt_dynar_insert_at_as(dynar,idx,type,value) \
-          *(type*)xbt_dynar_insert_at_ptr(dynar,idx)=value
-  /** @brief Quick insertion of scalar content
-   *  @hideinitializer */
-#  define xbt_dynar_push_as(dynar,type,value) \
-          *(type*)xbt_dynar_push_ptr(dynar)=value
-  /** @brief Quick removal of scalar content
-   *  @hideinitializer */
+/** @brief Quick insertion of scalar content
+ *  @hideinitializer */
+#define xbt_dynar_insert_at_as(dynar, idx, type, value) *(type*)xbt_dynar_insert_at_ptr((dynar), (idx)) = (value)
+/** @brief Quick insertion of scalar content
+ *  @hideinitializer */
+#define xbt_dynar_push_as(dynar, type, value) *(type*)xbt_dynar_push_ptr(dynar) = (value)
+/** @brief Quick removal of scalar content
+ *  @hideinitializer */
 #  define xbt_dynar_pop_as(dynar,type) \
            (*(type*)xbt_dynar_pop_ptr(dynar))
 
@@ -237,21 +234,18 @@ xbt_dynar_foreach (dyn,cpt,str) {
  * Note that underneath, that's a simple for loop with no real black  magic involved. It's perfectly safe to interrupt
  * a foreach with a break or a return statement.
  */
-#define xbt_dynar_foreach(_dynar,_cursor,_data) \
-       for ( (_cursor) = 0      ; \
-             _xbt_dynar_cursor_get(_dynar,_cursor,&_data) ; \
-             (_cursor)++         )
+#define xbt_dynar_foreach(_dynar, _cursor, _data)                                                                      \
+  for ((_cursor) = 0; _xbt_dynar_cursor_get((_dynar), (_cursor), &(_data)); (_cursor)++)
 
 #ifndef __cplusplus
-#define xbt_dynar_foreach_ptr(_dynar,_cursor,_ptr) \
-       for ((_cursor) = 0       ; \
-            (_ptr = _cursor < _dynar->used ? xbt_dynar_get_ptr(_dynar,_cursor) : NULL) ; \
-            (_cursor)++         )
+#define xbt_dynar_foreach_ptr(_dynar, _cursor, _ptr)                                                                   \
+  for ((_cursor) = 0; ((_ptr) = (_cursor) < (_dynar)->used ? xbt_dynar_get_ptr((_dynar), (_cursor)) : NULL);           \
+       (_cursor)++)
 #else
-#define xbt_dynar_foreach_ptr(_dynar,_cursor,_ptr) \
-       for ((_cursor) = 0       ; \
-            (_ptr = _cursor < _dynar->used ? (decltype(_ptr)) xbt_dynar_get_ptr(_dynar,_cursor) : NULL) ; \
-            (_cursor)++         )
+#define xbt_dynar_foreach_ptr(_dynar, _cursor, _ptr)                                                                   \
+  for ((_cursor) = 0;                                                                                                  \
+       ((_ptr) = (_cursor) < (_dynar)->used ? (decltype(_ptr))xbt_dynar_get_ptr((_dynar), (_cursor)) : NULL);          \
+       (_cursor)++)
 #endif
 /** @} */
 SG_END_DECL()
index 0cbbb9d..dc31878 100644 (file)
@@ -30,13 +30,13 @@ XBT_ATTRIB_NORETURN XBT_PUBLIC void _xbt_throw(char* message, int value, const c
  *  @ingroup XBT_ex_c
  *  @hideinitializer
  */
-#define THROW(v) _xbt_throw(NULL, v, __FILE__, __LINE__, __func__)
+#define THROW(v) _xbt_throw(NULL, (v), __FILE__, __LINE__, __func__)
 
 /** Builds and throws an exception with a printf-like formatted message
  *  @ingroup XBT_ex_c
  *  @hideinitializer
  */
-#define THROWF(v, ...) _xbt_throw(bprintf(__VA_ARGS__), v, __FILE__, __LINE__, __func__)
+#define THROWF(v, ...) _xbt_throw(bprintf(__VA_ARGS__), (v), __FILE__, __LINE__, __func__)
 
 XBT_ATTRIB_NORETURN void xbt_throw_impossible(const char* file, int line, const char* func);
 /** Throw an exception because something impossible happened
index 98e04df..1df2b5c 100644 (file)
@@ -117,7 +117,7 @@ typedef enum {
       NULL /* firstChild */,                                                                                           \
       NULL /* nextSibling */,                                                                                          \
       _XBT_STRINGIFY(catName),                                                                                         \
-      desc,                                                                                                            \
+      (desc),                                                                                                          \
       0 /*initialized */,                                                                                              \
       xbt_log_priority_uninitialized /* threshold */,                                                                  \
       1 /* isThreshInherited */,                                                                                       \
@@ -135,9 +135,9 @@ typedef enum {
  *
  * Defines a new subcategory of the parent.
  */
-#define XBT_LOG_NEW_SUBCATEGORY(catName, parent, desc)    \
-  XBT_LOG_EXTERNAL_CATEGORY(parent);                      \
-  XBT_LOG_NEW_SUBCATEGORY_helper(catName, parent, desc)
+#define XBT_LOG_NEW_SUBCATEGORY(catName, parent, desc)                                                                 \
+  XBT_LOG_EXTERNAL_CATEGORY(parent);                                                                                   \
+  XBT_LOG_NEW_SUBCATEGORY_helper(catName, parent, (desc))
 
 /**
  * @ingroup XBT_log
@@ -147,8 +147,7 @@ typedef enum {
  *
  * Creates a new subcategory of the root category.
  */
-# define XBT_LOG_NEW_CATEGORY(catName,desc)  \
-   XBT_LOG_NEW_SUBCATEGORY_helper(catName, XBT_LOG_ROOT_CAT, desc)
+#define XBT_LOG_NEW_CATEGORY(catName, desc) XBT_LOG_NEW_SUBCATEGORY_helper(catName, XBT_LOG_ROOT_CAT, (desc))
 
 /**
  * @ingroup XBT_log
@@ -174,9 +173,9 @@ typedef enum {
  * Creates a new subcategory of the root category and makes it the default (used by macros that don't explicitly
  * specify a category).
  */
-# define XBT_LOG_NEW_DEFAULT_CATEGORY(cname,desc)        \
-    XBT_LOG_NEW_CATEGORY(cname,desc);                   \
-    XBT_LOG_DEFAULT_CATEGORY(cname)
+#define XBT_LOG_NEW_DEFAULT_CATEGORY(cname, desc)                                                                      \
+  XBT_LOG_NEW_CATEGORY(cname, (desc));                                                                                 \
+  XBT_LOG_DEFAULT_CATEGORY(cname)
 
 /**
  * @ingroup XBT_log
@@ -188,9 +187,9 @@ typedef enum {
  * Creates a new subcategory of the parent category and makes it the default
  * (used by macros that don't explicitly specify a category).
  */
-#define XBT_LOG_NEW_DEFAULT_SUBCATEGORY(cname, parent, desc) \
-    XBT_LOG_NEW_SUBCATEGORY(cname, parent, desc);            \
-    XBT_LOG_DEFAULT_CATEGORY(cname)
+#define XBT_LOG_NEW_DEFAULT_SUBCATEGORY(cname, parent, desc)                                                           \
+  XBT_LOG_NEW_SUBCATEGORY(cname, parent, (desc));                                                                      \
+  XBT_LOG_DEFAULT_CATEGORY(cname)
 
 /**
  * @ingroup XBT_log
@@ -336,8 +335,7 @@ extern xbt_log_layout_t xbt_log_default_layout;
  * If you have expensive expressions that are computed outside of the log command and used only within it, you should
  * make its evaluation conditional using this macro.
  */
-#define XBT_LOG_ISENABLED(catName, priority) \
-            _XBT_LOG_ISENABLEDV(_XBT_LOGV(catName), priority)
+#define XBT_LOG_ISENABLED(catName, priority) _XBT_LOG_ISENABLEDV(_XBT_LOGV(catName), (priority))
 
 /*
  * Helper function that implements XBT_LOG_ISENABLED.
@@ -346,10 +344,9 @@ extern xbt_log_layout_t xbt_log_default_layout;
  * First part is a compile-time constant.
  * Call to xbt_log_cat_init only happens once.
  */
-#define _XBT_LOG_ISENABLEDV(catv, priority)                  \
-       (priority >= XBT_LOG_STATIC_THRESHOLD                 \
-        && ((catv).initialized || _xbt_log_cat_init(&(catv), priority)) \
-        && priority >= (catv).threshold)
+#define _XBT_LOG_ISENABLEDV(catv, priority)                                                                            \
+  ((priority) >= XBT_LOG_STATIC_THRESHOLD && ((catv).initialized || _xbt_log_cat_init(&(catv), (priority))) &&         \
+   (priority) >= (catv).threshold)
 
 /*
  * Internal Macros
@@ -376,7 +373,7 @@ extern xbt_log_layout_t xbt_log_default_layout;
 
 #define XBT_CLOG(category, prio, ...)                                                                                  \
   do {                                                                                                                 \
-    if (_XBT_LOG_ISENABLEDV((category), prio)) {                                                                       \
+    if (_XBT_LOG_ISENABLEDV((category), (prio))) {                                                                     \
       s_xbt_log_event_t _log_ev;                                                                                       \
       _log_ev.cat          = &(category);                                                                              \
       _log_ev.priority     = (prio);                                                                                   \
@@ -387,7 +384,7 @@ extern xbt_log_layout_t xbt_log_default_layout;
     }                                                                                                                  \
   } while (0)
 
-#define XBT_LOG(prio, ...) XBT_CLOG(*_simgrid_log_category__default, prio, __VA_ARGS__)
+#define XBT_LOG(prio, ...) XBT_CLOG(*_simgrid_log_category__default, (prio), __VA_ARGS__)
 
 #endif
 
@@ -468,10 +465,8 @@ extern xbt_log_layout_t xbt_log_default_layout;
 
 #define _XBT_IN_OUT(...) \
   _XBT_IF_ONE_ARG(_XBT_IN_OUT_ARG1, _XBT_IN_OUT_ARGN, __VA_ARGS__)(__VA_ARGS__)
-#define _XBT_IN_OUT_ARG1(fmt) \
-  XBT_LOG(xbt_log_priority_trace, fmt, __func__)
-#define _XBT_IN_OUT_ARGN(fmt, ...) \
-  XBT_LOG(xbt_log_priority_trace, fmt, __func__, __VA_ARGS__)
+#define _XBT_IN_OUT_ARG1(fmt) XBT_LOG(xbt_log_priority_trace, (fmt), __func__)
+#define _XBT_IN_OUT_ARGN(fmt, ...) XBT_LOG(xbt_log_priority_trace, (fmt), __func__, __VA_ARGS__)
 
 /** @ingroup XBT_log
  *  @hideinitializer
index 177bce3..48b1e70 100644 (file)
@@ -35,16 +35,16 @@ jfieldID jxbt_get_sfield(JNIEnv* env, const char* classname, const char* name, c
 
 #define jxbt_check_res(fun, res, allowed_exceptions, detail)                                                           \
   do {                                                                                                                 \
-    if (res != MSG_OK && (res | allowed_exceptions)) {                                                                 \
-      xbt_die("%s failed with error code %d, which is not an allowed exception. Please fix me.", fun, res);            \
-    } else if (res == MSG_HOST_FAILURE) {                                                                              \
-      jxbt_throw_host_failure(env, detail);                                                                            \
-    } else if (res == MSG_TRANSFER_FAILURE) {                                                                          \
-      jxbt_throw_transfer_failure(env, detail);                                                                        \
-    } else if (res == MSG_TIMEOUT) {                                                                                   \
-      jxbt_throw_time_out_failure(env, detail);                                                                        \
-    } else if (res == MSG_TASK_CANCELED) {                                                                             \
-      jxbt_throw_task_cancelled(env, detail);                                                                          \
+    if ((res) != MSG_OK && ((res) | (allowed_exceptions))) {                                                           \
+      xbt_die("%s failed with error code %d, which is not an allowed exception. Please fix me.", (fun), (res));        \
+    } else if ((res) == MSG_HOST_FAILURE) {                                                                            \
+      jxbt_throw_host_failure(env, (detail));                                                                          \
+    } else if ((res) == MSG_TRANSFER_FAILURE) {                                                                        \
+      jxbt_throw_transfer_failure(env, (detail));                                                                      \
+    } else if ((res) == MSG_TIMEOUT) {                                                                                 \
+      jxbt_throw_time_out_failure(env, (detail));                                                                      \
+    } else if ((res) == MSG_TASK_CANCELED) {                                                                           \
+      jxbt_throw_task_cancelled(env, (detail));                                                                        \
     }                                                                                                                  \
   } while (0)
 
index eba4663..404887f 100644 (file)
@@ -65,14 +65,14 @@ static simgrid::s4u::Link::SharingPolicy link_policy_get_by_name(const char* pol
 int console_open(lua_State*)
 {
   sg_platf_init();
-  simgrid::s4u::on_platform_creation();
+  simgrid::s4u::Engine::on_platform_creation();
 
   return 0;
 }
 
 int console_close(lua_State*)
 {
-  simgrid::s4u::on_platform_created();
+  simgrid::s4u::Engine::on_platform_created();
   sg_platf_exit();
   return 0;
 }
index 6893f5f..30db85b 100644 (file)
@@ -17,7 +17,7 @@ msg_host_t sglua_check_host(lua_State* L, int index);
 void sglua_register_platf_functions(lua_State* L);
 
 #define lua_ensure(...) _XBT_IF_ONE_ARG(_lua_ensure_ARG1, _lua_ensure_ARGN, __VA_ARGS__)(__VA_ARGS__)
-#define _lua_ensure_ARG1(cond) _lua_ensure_ARGN(cond, "Assertion " _XBT_STRINGIFY(cond) " failed")
+#define _lua_ensure_ARG1(cond) _lua_ensure_ARGN((cond), "Assertion " _XBT_STRINGIFY(cond) " failed")
 #define _lua_ensure_ARGN(cond, ...)                                                                                    \
   do {                                                                                                                 \
     if (!(cond)) {                                                                                                     \
diff --git a/src/include/xxhash.hpp b/src/include/xxhash.hpp
new file mode 100644 (file)
index 0000000..81e8207
--- /dev/null
@@ -0,0 +1,719 @@
+#pragma once
+#include <cstdint>
+#include <cstring>
+#include <array>
+#include <type_traits>
+#include <cstdint>
+#include <vector>
+#include <string>
+
+#include <iostream>
+
+/*
+xxHash - Extremely Fast Hash algorithm
+Header File
+Copyright (C) 2012-2018, Yann Collet.
+Copyright (C) 2017-2018, Piotr Pliszka.
+All rights reserved.
+
+BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+You can contact the author at :
+- xxHash source repository : https://github.com/Cyan4973/xxHash
+- xxHash C++ port repository : https://github.com/RedSpah/xxhash_cpp
+*/
+
+/* *************************************
+*  Tuning parameters
+***************************************/
+/*!XXH_FORCE_MEMORY_ACCESS :
+* By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
+* Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
+* The below switch allow to select different access method for improved performance.
+* Method 0 (default) : use `memcpy()`. Safe and portable.
+* Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
+*            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
+* Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
+*            It can generate buggy code on targets which do not support unaligned memory accesses.
+*            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
+* See http://stackoverflow.com/a/32095106/646947 for details.
+* Prefer these methods in priority order (0 > 1 > 2)
+*/
+#ifndef XXH_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */
+#  if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
+#    define XXH_FORCE_MEMORY_ACCESS 2
+#  elif defined(__INTEL_COMPILER) || (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
+#    define XXH_FORCE_MEMORY_ACCESS 1
+#  endif
+#endif
+
+
+/*!XXH_FORCE_NATIVE_FORMAT :
+* By default, xxHash library provides endian-independent Hash values, based on little-endian convention.
+* Results are therefore identical for little-endian and big-endian CPU.
+* This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
+* Should endian-independence be of no importance for your application, you may set the #define below to 1,
+* to improve speed for Big-endian CPU.
+* This option has no impact on Little_Endian CPU.
+*/
+#if !defined(XXH_FORCE_NATIVE_FORMAT) || (XXH_FORCE_NATIVE_FORMAT == 0)  /* can be defined externally */
+#      define XXH_FORCE_NATIVE_FORMAT 0
+#      define XXH_CPU_LITTLE_ENDIAN 1
+#endif
+
+
+/*!XXH_FORCE_ALIGN_CHECK :
+* This is a minor performance trick, only useful with lots of very small keys.
+* It means : check for aligned/unaligned input.
+* The check costs one initial branch per hash;
+* set it to 0 when the input is guaranteed to be aligned,
+* or when alignment doesn't matter for performance.
+*/
+#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
+#      if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+#              define XXH_FORCE_ALIGN_CHECK 0
+#      else
+#              define XXH_FORCE_ALIGN_CHECK 1
+#      endif
+#endif
+
+/*!XXH_CPU_LITTLE_ENDIAN :
+* This is a CPU endian detection macro, will be
+* automatically set to 1 (little endian) if XXH_FORCE_NATIVE_FORMAT
+* is left undefined, XXH_FORCE_NATIVE_FORMAT is defined to 0, or if an x86/x86_64 compiler macro is defined.
+* If left undefined, endianness will be determined at runtime, at the cost of a slight one-time overhead
+* and a larger overhead due to get_endian() not being constexpr.
+*/
+#ifndef XXH_CPU_LITTLE_ENDIAN
+#      if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+#              define XXH_CPU_LITTLE_ENDIAN 1
+#      endif
+#endif
+
+/* *************************************
+*  Compiler Specific Options
+***************************************/
+#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+namespace xxh
+{
+       /* *************************************
+       *  Version
+       ***************************************/
+       constexpr int cpp_version_major = 0;
+       constexpr int cpp_version_minor = 6;
+       constexpr int cpp_version_release = 5;
+       constexpr uint32_t version_number() { return cpp_version_major * 10000 + cpp_version_minor * 100 + cpp_version_release; }
+
+       namespace hash_t_impl
+       {
+               /* *************************************
+               *  Basic Types - Detail
+               ***************************************/
+
+               using _hash32_underlying = uint32_t;
+               using _hash64_underlying = uint64_t;
+
+               template <size_t N>
+               struct hash_type { using type = void; };
+               template <>
+               struct hash_type<32> { using type = _hash32_underlying; };
+               template <>
+               struct hash_type<64> { using type = _hash64_underlying; };
+       }
+
+       /* *************************************
+       *  Basic Types - Public
+       ***************************************/
+
+       template <size_t N>
+       using hash_t = typename hash_t_impl::hash_type<N>::type;
+       using hash32_t = hash_t<32>;
+       using hash64_t = hash_t<64>;
+
+       /* *************************************
+       *  Bit Functions - Public
+       ***************************************/
+
+       namespace bit_ops
+       {
+               /* ****************************************
+               *  Intrinsics and Bit Operations
+               ******************************************/
+
+#if defined(_MSC_VER)
+               inline uint32_t rotl32(uint32_t x, int32_t r) { return _rotl(x, r); }
+               inline uint64_t rotl64(uint64_t x, int32_t r) { return _rotl64(x, r); }
+#else
+               inline uint32_t rotl32(uint32_t x, int32_t r) { return ((x << r) | (x >> (32 - r))); }
+               inline uint64_t rotl64(uint64_t x, int32_t r) { return ((x << r) | (x >> (64 - r))); }
+#endif
+
+#if defined(_MSC_VER)     /* Visual Studio */
+               inline uint32_t swap32(uint32_t x) { return _byteswap_ulong(x); }
+               inline uint64_t swap64(uint64_t x) { return _byteswap_uint64(x); }
+#elif XXH_GCC_VERSION >= 403
+               inline uint32_t swap32(uint32_t x) { return __builtin_bswap32(x); }
+               inline uint64_t swap64(uint64_t x) { return __builtin_bswap64(x); }
+#else
+               inline uint32_t swap32(uint32_t x) { return ((x << 24) & 0xff000000) | ((x << 8) & 0x00ff0000) | ((x >> 8) & 0x0000ff00) | ((x >> 24) & 0x000000ff); }
+               inline uint64_t swap64(uint64_t x) { return ((x << 56) & 0xff00000000000000ULL) | ((x << 40) & 0x00ff000000000000ULL) | ((x << 24) & 0x0000ff0000000000ULL) | ((x << 8) & 0x000000ff00000000ULL) | ((x >> 8) & 0x00000000ff000000ULL) | ((x >> 24) & 0x0000000000ff0000ULL) | ((x >> 40) & 0x000000000000ff00ULL) | ((x >> 56) & 0x00000000000000ffULL); }
+#endif
+               template <size_t N>
+               inline hash_t<N> rotl(hash_t<N> n, int32_t r) {};
+
+               template <>
+               inline hash_t<32> rotl<32>(hash_t<32> n, int32_t r)
+               {
+                       return rotl32(n, r);
+               };
+
+               template <>
+               inline hash_t<64> rotl<64>(hash_t<64> n, int32_t r)
+               {
+                       return rotl64(n, r);
+               };
+
+               template <size_t N>
+               inline hash_t<N> swap(hash_t<N> n) {};
+
+               template <>
+               inline hash_t<32> swap<32>(hash_t<32> n)
+               {
+                       return swap32(n);
+               };
+
+               template <>
+               inline hash_t<64> swap<64>(hash_t<64> n)
+               {
+                       return swap64(n);
+               };
+       }
+
+       /* *************************************
+       *  Memory Functions - Public
+       ***************************************/
+
+       enum class alignment : uint8_t { aligned, unaligned };
+       enum class endianness : uint8_t { big_endian = 0, little_endian = 1, unspecified = 2 };
+
+       namespace mem_ops
+       {
+               /* *************************************
+               *  Memory Access
+               ***************************************/
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+               /* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
+               template <size_t N>
+               inline hash_t<N> read_unaligned(const void* memPtr) { return *(const hash_t<N>*)memPtr; }
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+               /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
+               /* currently only defined for gcc and icc */
+               template <size_t N>
+               using unalign = union { hash_t<N> uval; } __attribute((packed));
+
+               template <size_t N>
+               inline hash_t<N> read_unaligned(const void* memPtr) { return ((const unalign*)memPtr)->uval; }
+#else
+
+               /* portable and safe solution. Generally efficient.
+               * see : http://stackoverflow.com/a/32095106/646947
+               */
+               template <size_t N>
+               inline hash_t<N> read_unaligned(const void* memPtr)
+               {
+                       hash_t<N> val;
+                       memcpy(&val, memPtr, sizeof(val));
+                       return val;
+               }
+
+#endif   /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+               inline hash_t<32> read32(const void* memPtr) { return read_unaligned<32>(memPtr); }
+               inline hash_t<64> read64(const void* memPtr) { return read_unaligned<64>(memPtr); }
+
+               /* *************************************
+               *  Architecture Macros
+               ***************************************/
+
+               /* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
+
+#ifndef XXH_CPU_LITTLE_ENDIAN
+
+               inline endianness get_endian(endianness endian)
+               {
+                       static struct _dummy_t
+                       {
+                               std::array<endianness, 3> endian_lookup = { endianness::big_endian, endianness::little_endian, endianness::unspecified };
+                               const int g_one = 1;
+                               _dummy_t()
+                               {
+                                       endian_lookup[2] = static_cast<endianness>(*(const char*)(&g_one));
+                               }
+                       } _dummy;
+
+                       return _dummy.endian_lookup[(uint8_t)endian];
+               }
+
+               inline bool is_little_endian()
+               {
+                       return get_endian(endianness::unspecified) == endianness::little_endian;
+               }
+
+#else
+               constexpr endianness get_endian(endianness endian)
+               {
+                       constexpr std::array<endianness, 3> endian_lookup = { endianness::big_endian, endianness::little_endian, (XXH_CPU_LITTLE_ENDIAN) ? endianness::little_endian : endianness::big_endian };
+                       return endian_lookup[static_cast<uint8_t>(endian)];
+               }
+
+               constexpr bool is_little_endian()
+               {
+                       return get_endian(endianness::unspecified) == endianness::little_endian;
+               }
+
+#endif
+
+
+
+               /* ***************************
+               *  Memory reads
+               *****************************/
+
+
+               template <size_t N>
+               inline hash_t<N> readLE_align(const void* ptr, endianness endian, alignment align)
+               {
+                       if (align == alignment::unaligned)
+                       {
+                               return endian == endianness::little_endian ? read_unaligned<N>(ptr) : bit_ops::swap<N>(read_unaligned<N>(ptr));
+                       }
+                       else
+                       {
+                               return endian == endianness::little_endian ? *reinterpret_cast<const hash_t<N>*>(ptr) : bit_ops::swap<N>(*reinterpret_cast<const hash_t<N>*>(ptr));
+                       }
+               }
+
+               template <size_t N>
+               inline hash_t<N> readLE(const void* ptr, endianness endian)
+               {
+                       return readLE_align<N>(ptr, endian, alignment::unaligned);
+               }
+
+               template <size_t N>
+               inline hash_t<N> readBE(const void* ptr)
+               {
+                       return is_little_endian() ? bit_ops::swap<N>(read_unaligned<N>(ptr)) : read_unaligned<N>(ptr);
+               }
+
+               template <size_t N>
+               inline alignment get_alignment(const void* input)
+               {
+                       return ((XXH_FORCE_ALIGN_CHECK) && ((reinterpret_cast<uintptr_t>(input) & ((N / 8) - 1)) == 0)) ? xxh::alignment::aligned : xxh::alignment::unaligned;
+               }
+       }
+
+       /* *******************************************************************
+       *  Hash functions
+       *********************************************************************/
+
+       namespace detail
+       {
+               /* *******************************************************************
+               *  Hash functions - Implementation
+               *********************************************************************/
+
+               constexpr static std::array<hash32_t, 5> primes32 = { 2654435761U, 2246822519U, 3266489917U, 668265263U, 374761393U };
+               constexpr static std::array<hash64_t, 5> primes64 = { 11400714785074694791ULL, 14029467366897019727ULL, 1609587929392839161ULL, 9650029242287828579ULL, 2870177450012600261ULL };
+
+               template <size_t N>
+               constexpr hash_t<N> PRIME(int32_t n) {};
+
+               template <>
+               constexpr hash32_t PRIME<32>(int32_t n)
+               {
+                       return primes32[n - 1];
+               }
+
+               template <>
+               constexpr hash64_t PRIME<64>(int32_t n)
+               {
+                       return primes64[n - 1];
+               }
+
+               template <size_t N>
+               inline hash_t<N> round(hash_t<N> seed, hash_t<N> input)
+               {
+                       seed += input * PRIME<N>(2);
+                       seed = bit_ops::rotl<N>(seed, ((N == 32) ? 13 : 31));
+                       seed *= PRIME<N>(1);
+                       return seed;
+               }
+
+               inline hash64_t mergeRound64(hash64_t acc, hash64_t val)
+               {
+                       val = round<64>(0, val);
+                       acc ^= val;
+                       acc = acc * PRIME<64>(1) + PRIME<64>(4);
+                       return acc;
+               }
+
+               template <size_t N>
+               inline void endian_align_sub_mergeround([[maybe_unused]] hash_t<N>& hash_ret, hash_t<N> v1, hash_t<N> v2, hash_t<N> v3, hash_t<N> v4) {};
+
+               template <>
+               inline void endian_align_sub_mergeround<64>(hash_t<64>& hash_ret, hash_t<64> v1, hash_t<64> v2, hash_t<64> v3, hash_t<64> v4)
+               {
+                       hash_ret = mergeRound64(hash_ret, v1);
+                       hash_ret = mergeRound64(hash_ret, v2);
+                       hash_ret = mergeRound64(hash_ret, v3);
+                       hash_ret = mergeRound64(hash_ret, v4);
+               }
+
+               template <size_t N>
+               inline hash_t<N> endian_align_sub_ending(hash_t<N> hash_ret, const uint8_t* p, const uint8_t* bEnd, xxh::endianness endian, xxh::alignment align) {};
+
+               template <>
+               inline hash_t<32> endian_align_sub_ending<32>(hash_t<32> hash_ret, const uint8_t* p, const uint8_t* bEnd, xxh::endianness endian, xxh::alignment align)
+               {
+                       while ((p + 4) <= bEnd)
+                       {
+                               hash_ret += mem_ops::readLE_align<32>(p, endian, align) * PRIME<32>(3);
+                               hash_ret = bit_ops::rotl<32>(hash_ret, 17) * PRIME<32>(4);
+                               p += 4;
+                       }
+
+                       while (p < bEnd)
+                       {
+                               hash_ret += (*p) * PRIME<32>(5);
+                               hash_ret = bit_ops::rotl<32>(hash_ret, 11) * PRIME<32>(1);
+                               p++;
+                       }
+
+                       hash_ret ^= hash_ret >> 15;
+                       hash_ret *= PRIME<32>(2);
+                       hash_ret ^= hash_ret >> 13;
+                       hash_ret *= PRIME<32>(3);
+                       hash_ret ^= hash_ret >> 16;
+
+                       return hash_ret;
+               }
+
+               template <>
+               inline hash_t<64> endian_align_sub_ending<64>(hash_t<64> hash_ret, const uint8_t* p, const uint8_t* bEnd, xxh::endianness endian, xxh::alignment align)
+               {
+                       while (p + 8 <= bEnd)
+                       {
+                               const hash64_t k1 = round<64>(0, mem_ops::readLE_align<64>(p, endian, align));
+                               hash_ret ^= k1;
+                               hash_ret = bit_ops::rotl<64>(hash_ret, 27) * PRIME<64>(1) + PRIME<64>(4);
+                               p += 8;
+                       }
+
+                       if (p + 4 <= bEnd)
+                       {
+                               hash_ret ^= static_cast<hash64_t>(mem_ops::readLE_align<32>(p, endian, align)) * PRIME<64>(1);
+                               hash_ret = bit_ops::rotl<64>(hash_ret, 23) * PRIME<64>(2) + PRIME<64>(3);
+                               p += 4;
+                       }
+
+                       while (p < bEnd)
+                       {
+                               hash_ret ^= (*p) * PRIME<64>(5);
+                               hash_ret = bit_ops::rotl<64>(hash_ret, 11) * PRIME<64>(1);
+                               p++;
+                       }
+
+                       hash_ret ^= hash_ret >> 33;
+                       hash_ret *= PRIME<64>(2);
+                       hash_ret ^= hash_ret >> 29;
+                       hash_ret *= PRIME<64>(3);
+                       hash_ret ^= hash_ret >> 32;
+
+                       return hash_ret;
+               }
+
+               template <size_t N>
+               inline hash_t<N> endian_align(const void* input, size_t len, hash_t<N> seed, xxh::endianness endian, xxh::alignment align)
+               {
+                       static_assert(!(N != 32 && N != 64), "You can only call endian_align in 32 or 64 bit mode.");
+
+                       const uint8_t* p = static_cast<const uint8_t*>(input);
+                       const uint8_t* bEnd = p + len;
+                       hash_t<N> hash_ret;
+
+                       if (len >= (N / 2))
+                       {
+                               const uint8_t* const limit = bEnd - (N / 2);
+                               hash_t<N> v1 = seed + PRIME<N>(1) + PRIME<N>(2);
+                               hash_t<N> v2 = seed + PRIME<N>(2);
+                               hash_t<N> v3 = seed + 0;
+                               hash_t<N> v4 = seed - PRIME<N>(1);
+
+                               do
+                               {
+                                       v1 = round<N>(v1, mem_ops::readLE_align<N>(p, endian, align)); p += (N / 8);
+                                       v2 = round<N>(v2, mem_ops::readLE_align<N>(p, endian, align)); p += (N / 8);
+                                       v3 = round<N>(v3, mem_ops::readLE_align<N>(p, endian, align)); p += (N / 8);
+                                       v4 = round<N>(v4, mem_ops::readLE_align<N>(p, endian, align)); p += (N / 8);
+                               } while (p <= limit);
+
+                               hash_ret = bit_ops::rotl<N>(v1, 1) + bit_ops::rotl<N>(v2, 7) + bit_ops::rotl<N>(v3, 12) + bit_ops::rotl<N>(v4, 18);
+
+                               endian_align_sub_mergeround<N>(hash_ret, v1, v2, v3, v4);
+                       }
+                       else { hash_ret = seed + PRIME<N>(5); }
+
+                       hash_ret += static_cast<hash_t<N>>(len);
+
+                       return endian_align_sub_ending<N>(hash_ret, p, bEnd, endian, align);
+               }
+       }
+
+       template <size_t N>
+       hash_t<N> xxhash(const void* input, size_t len, hash_t<N> seed = 0, endianness endian = endianness::unspecified)
+       {
+               static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode.");
+               return detail::endian_align<N>(input, len, seed, mem_ops::get_endian(endian), mem_ops::get_alignment<N>(input));
+       }
+
+       template <size_t N, typename T>
+       hash_t<N> xxhash(const std::basic_string<T>& input, hash_t<N> seed = 0, endianness endian = endianness::unspecified)
+       {
+               static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode.");
+               return detail::endian_align<N>(static_cast<const void*>(input.data()), input.length() * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment<N>(static_cast<const void*>(input.data())));
+       }
+
+       template <size_t N, typename ContiguousIterator>
+       hash_t<N> xxhash(ContiguousIterator begin, ContiguousIterator end, hash_t<N> seed = 0, endianness endian = endianness::unspecified)
+       {
+               static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode.");
+               using T = typename std::decay_t<decltype(*end)>;
+               return detail::endian_align<N>(static_cast<const void*>(&*begin), (end - begin) * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment<N>(static_cast<const void*>(&*begin)));
+       }
+
+       template <size_t N, typename T>
+       hash_t<N> xxhash(const std::vector<T>& input, hash_t<N> seed = 0, endianness endian = endianness::unspecified)
+       {
+               static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode.");
+               return detail::endian_align<N>(static_cast<const void*>(input.data()), input.size() * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment<N>(static_cast<const void*>(input.data())));
+       }
+
+       template <size_t N, typename T, size_t AN>
+       hash_t<N> xxhash(const std::array<T, AN>& input, hash_t<N> seed = 0, endianness endian = endianness::unspecified)
+       {
+               static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode.");
+               return detail::endian_align<N>(static_cast<const void*>(input.data()), AN * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment<N>(static_cast<const void*>(input.data())));
+       }
+
+       template <size_t N, typename T>
+       hash_t<N> xxhash(const std::initializer_list<T>& input, hash_t<N> seed = 0, endianness endian = endianness::unspecified)
+       {
+               static_assert(!(N != 32 && N != 64), "You can only call xxhash in 32 or 64 bit mode.");
+               return detail::endian_align<N>(static_cast<const void*>(input.begin()), input.size() * sizeof(T), seed, mem_ops::get_endian(endian), mem_ops::get_alignment<N>(static_cast<const void*>(input.begin())));
+       }
+
+
+       /* *******************************************************************
+       *  Hash streaming
+       *********************************************************************/
+       enum class error_code : uint8_t { ok = 0, error };
+
+       template <size_t N>
+       class hash_state_t {
+
+               uint64_t total_len = 0;
+               hash_t<N> v1 = 0, v2 = 0, v3 = 0, v4 = 0;
+               std::array<hash_t<N>, 4> mem = {{ 0,0,0,0 }};
+               uint32_t memsize = 0;
+
+               inline error_code _update_impl(const void* input, size_t length, endianness endian)
+               {
+                       const uint8_t* p = reinterpret_cast<const uint8_t*>(input);
+                       const uint8_t* const bEnd = p + length;
+
+                       if (!input) { return xxh::error_code::error; }
+
+                       total_len += length;
+
+                       if (memsize + length < (N / 2))
+                       {   /* fill in tmp buffer */
+                               memcpy(reinterpret_cast<uint8_t*>(mem.data()) + memsize, input, length);
+                               memsize += static_cast<uint32_t>(length);
+                               return error_code::ok;
+                       }
+
+                       if (memsize)
+                       {   /* some data left from previous update */
+                               memcpy(reinterpret_cast<uint8_t*>(mem.data()) + memsize, input, (N / 2) - memsize);
+
+                               const hash_t<N>* ptr = mem.data();
+                               v1 = detail::round<N>(v1, mem_ops::readLE<N>(ptr, endian)); ptr++;
+                               v2 = detail::round<N>(v2, mem_ops::readLE<N>(ptr, endian)); ptr++;
+                               v3 = detail::round<N>(v3, mem_ops::readLE<N>(ptr, endian)); ptr++;
+                               v4 = detail::round<N>(v4, mem_ops::readLE<N>(ptr, endian));
+
+                               p += (N / 2) - memsize;
+                               memsize = 0;
+                       }
+
+                       if (p <= bEnd - (N / 2))
+                       {
+                               const uint8_t* const limit = bEnd - (N / 2);
+
+                               do
+                               {
+                                       v1 = detail::round<N>(v1, mem_ops::readLE<N>(p, endian)); p += (N / 8);
+                                       v2 = detail::round<N>(v2, mem_ops::readLE<N>(p, endian)); p += (N / 8);
+                                       v3 = detail::round<N>(v3, mem_ops::readLE<N>(p, endian)); p += (N / 8);
+                                       v4 = detail::round<N>(v4, mem_ops::readLE<N>(p, endian)); p += (N / 8);
+                               } while (p <= limit);
+                       }
+
+                       if (p < bEnd)
+                       {
+                               memcpy(mem.data(), p, static_cast<size_t>(bEnd - p));
+                               memsize = static_cast<uint32_t>(bEnd - p);
+                       }
+
+                       return error_code::ok;
+               }
+
+               inline hash_t<N> _digest_impl(endianness endian) const
+               {
+                       const uint8_t* p = reinterpret_cast<const uint8_t*>(mem.data());
+                       const uint8_t* const bEnd = reinterpret_cast<const uint8_t*>(mem.data()) + memsize;
+                       hash_t<N> hash_ret;
+
+                       if (total_len > (N / 2))
+                       {
+                               hash_ret = bit_ops::rotl<N>(v1, 1) + bit_ops::rotl<N>(v2, 7) + bit_ops::rotl<N>(v3, 12) + bit_ops::rotl<N>(v4, 18);
+
+                               detail::endian_align_sub_mergeround<N>(hash_ret, v1, v2, v3, v4);
+                       }
+                       else { hash_ret = v3 + detail::PRIME<N>(5); }
+
+                       hash_ret += static_cast<hash_t<N>>(total_len);
+
+                       return detail::endian_align_sub_ending<N>(hash_ret, p, bEnd, endian, alignment::unaligned);
+               }
+
+       public:
+               hash_state_t(hash_t<N> seed = 0)
+               {
+                       static_assert(!(N != 32 && N != 64), "You can only stream hashing in 32 or 64 bit mode.");
+                       v1 = seed + detail::PRIME<N>(1) + detail::PRIME<N>(2);
+                       v2 = seed + detail::PRIME<N>(2);
+                       v3 = seed + 0;
+                       v4 = seed - detail::PRIME<N>(1);
+               };
+
+               hash_state_t operator=(hash_state_t<N>& other)
+               {
+                       memcpy(this, other, sizeof(hash_state_t<N>));
+               }
+
+               error_code reset(hash_t<N> seed = 0)
+               {
+                       memset(this, 0, sizeof(hash_state_t<N>));
+                       v1 = seed + detail::PRIME<N>(1) + detail::PRIME<N>(2);
+                       v2 = seed + detail::PRIME<N>(2);
+                       v3 = seed + 0;
+                       v4 = seed - detail::PRIME<N>(1);
+                       return error_code::ok;
+               }
+
+               error_code update(const void* input, size_t length, endianness endian = endianness::unspecified)
+               {
+                       return _update_impl(input, length, mem_ops::get_endian(endian));
+               }
+
+               template <typename T>
+               error_code update(const std::basic_string<T>& input, endianness endian = endianness::unspecified)
+               {
+                       return _update_impl(static_cast<const void*>(input.data()), input.length() * sizeof(T), mem_ops::get_endian(endian));
+               }
+
+               template <typename ContiguousIterator>
+               error_code update(ContiguousIterator begin, ContiguousIterator end, endianness endian = endianness::unspecified)
+               {
+                       using T = typename std::decay_t<decltype(*end)>;
+                       return _update_impl(static_cast<const void*>(&*begin), (end - begin) * sizeof(T), mem_ops::get_endian(endian));
+               }
+
+               template <typename T>
+               error_code update(const std::vector<T>& input, endianness endian = endianness::unspecified)
+               {
+                       return _update_impl(static_cast<const void*>(input.data()), input.size() * sizeof(T), mem_ops::get_endian(endian));
+               }
+
+               template <typename T, size_t AN>
+               error_code update(const std::array<T, AN>& input, endianness endian = endianness::unspecified)
+               {
+                       return _update_impl(static_cast<const void*>(input.data()), AN * sizeof(T), mem_ops::get_endian(endian));
+               }
+
+               template <typename T>
+               error_code update(const std::initializer_list<T>& input, endianness endian = endianness::unspecified)
+               {
+                       return _update_impl(static_cast<const void*>(input.begin()), input.size() * sizeof(T), mem_ops::get_endian(endian));
+               }
+
+               hash_t<N> digest(endianness endian = endianness::unspecified)
+               {
+                       return _digest_impl(mem_ops::get_endian(endian));
+               }
+       };
+
+       using hash_state32_t = hash_state_t<32>;
+       using hash_state64_t = hash_state_t<64>;
+
+
+       /* *******************************************************************
+       *  Canonical
+       *********************************************************************/
+
+       template <size_t N>
+       struct canonical_t
+       {
+               std::array<uint8_t, N / 8> digest;\
+
+
+
+               canonical_t(hash_t<N> hash)
+               {
+                       if (mem_ops::is_little_endian()) { hash = bit_ops::swap<N>(hash); }
+                       memcpy(digest.data(), &hash, sizeof(canonical_t<N>));
+               }
+
+               hash_t<N> get_hash() const
+               {
+                       return mem_ops::readBE<N>(&digest);
+               }
+       };
+
+       using canonical32_t = canonical_t<32>;
+       using canonical64_t = canonical_t<64>;
+}
index 415e3ba..ff20f26 100644 (file)
@@ -294,9 +294,9 @@ void TRACE_global_init()
                                      6);
 
   /* Connect callbacks */
-  simgrid::s4u::on_platform_creation.connect(TRACE_start);
-  simgrid::s4u::on_deadlock.connect(TRACE_end);
-  simgrid::s4u::on_simulation_end.connect(TRACE_end);
+  simgrid::s4u::Engine::on_platform_creation.connect(TRACE_start);
+  simgrid::s4u::Engine::on_deadlock.connect(TRACE_end);
+  simgrid::s4u::Engine::on_simulation_end.connect(TRACE_end);
 }
 
 static void print_line(const char* option, const char* desc, const char* longdesc)
index 9ce839a..fa042a8 100644 (file)
@@ -355,7 +355,7 @@ void instr_define_callbacks()
   // always need the callbacks to zones (we need only the root zone), to create the rootContainer and the rootType
   // properly
   if (TRACE_needs_platform()) {
-    simgrid::s4u::on_platform_created.connect(instr_on_platform_created);
+    simgrid::s4u::Engine::on_platform_created.connect(instr_on_platform_created);
     simgrid::s4u::Host::on_creation.connect(instr_host_on_creation);
     simgrid::s4u::Host::on_speed_change.connect(instr_host_on_speed_change);
     simgrid::s4u::Link::on_creation.connect(instr_link_on_creation);
index 4ac56a9..f5f7f9f 100644 (file)
@@ -25,7 +25,6 @@ XBT_PRIVATE void TRACE_smpi_comm_out(int rank);
 XBT_PRIVATE void TRACE_smpi_send(int rank, int src, int dst, int tag, int size);
 XBT_PRIVATE void TRACE_smpi_recv(int src, int dst, int tag);
 XBT_PRIVATE void TRACE_smpi_init(int rank);
-XBT_PRIVATE void TRACE_smpi_finalize(int rank);
 /* SMPI + LB (load balancer) */
 XBT_PRIVATE void TRACE_smpi_process_change_host(int rank, sg_host_t new_host);
 
index 3a96a57..4d98ab4 100644 (file)
@@ -7,6 +7,7 @@
 #include "simgrid/kernel/routing/NetPoint.hpp"
 #include "simgrid/kernel/routing/NetZoneImpl.hpp"
 #include "simgrid/s4u/Host.hpp"
+#include "src/kernel/resource/DiskImpl.hpp"
 #include "src/surf/StorageImpl.hpp"
 #include "src/surf/network_interface.hpp"
 
index 6022c2d..63f5381 100644 (file)
@@ -7,6 +7,7 @@
 #include "simgrid/Exception.hpp"
 #include "simgrid/kernel/resource/Action.hpp"
 #include "simgrid/s4u/Host.hpp"
+#include "src/kernel/resource/DiskImpl.hpp"
 #include "src/mc/mc_replay.hpp"
 #include "src/simix/smx_private.hpp"
 #include "src/surf/StorageImpl.hpp"
@@ -44,6 +45,12 @@ IoImpl& IoImpl::set_size(sg_size_t size)
   return *this;
 }
 
+IoImpl& IoImpl::set_disk(resource::DiskImpl* disk)
+{
+  disk_ = disk;
+  return *this;
+}
+
 IoImpl& IoImpl::set_storage(resource::StorageImpl* storage)
 {
   storage_ = storage;
@@ -53,7 +60,10 @@ IoImpl& IoImpl::set_storage(resource::StorageImpl* storage)
 IoImpl* IoImpl::start()
 {
   state_       = SIMIX_RUNNING;
-  surf_action_ = storage_->io_start(size_, type_);
+  if (storage_)
+    surf_action_ = storage_->io_start(size_, type_);
+  else
+    surf_action_ = disk_->io_start(size_, type_);
   surf_action_->set_activity(this);
 
   XBT_DEBUG("Create IO synchro %p %s", this, get_cname());
@@ -66,7 +76,7 @@ void IoImpl::post()
 {
   performed_ioops_ = surf_action_->get_cost();
   if (surf_action_->get_state() == resource::Action::State::FAILED) {
-    if (storage_ && not storage_->is_on())
+    if ((storage_ && not storage_->is_on()) || (disk_ && not disk_->is_on()))
       state_ = SIMIX_FAILED;
     else
       state_ = SIMIX_CANCELED;
index 2ab4ff7..8d8f04c 100644 (file)
@@ -16,6 +16,7 @@ namespace activity {
 
 class XBT_PUBLIC IoImpl : public ActivityImpl_T<IoImpl> {
   resource::StorageImpl* storage_ = nullptr;
+  resource::DiskImpl* disk_       = nullptr;
   sg_size_t size_                 = 0;
   s4u::Io::OpType type_           = s4u::Io::OpType::READ;
   sg_size_t performed_ioops_      = 0;
@@ -24,6 +25,7 @@ public:
   IoImpl& set_size(sg_size_t size);
   IoImpl& set_type(s4u::Io::OpType type);
   IoImpl& set_storage(resource::StorageImpl* storage);
+  IoImpl& set_disk(resource::DiskImpl* disk);
 
   sg_size_t get_performed_ioops() { return performed_ioops_; }
 
index e20cdf7..dc94cff 100644 (file)
@@ -62,7 +62,7 @@ void SleepImpl::finish()
     if (simcall->issuer_->is_suspended()) {
       XBT_DEBUG("Wait! This process is suspended and can't wake up now.");
       simcall->issuer_->suspended_ = false;
-      simcall->issuer_->suspend(simcall->issuer_);
+      simcall->issuer_->suspend();
     } else {
       simcall->issuer_->simcall_answer();
     }
index e57a46e..4c83228 100644 (file)
@@ -297,7 +297,7 @@ void ActorImpl::yield()
 
     xbt_assert(exception_ == nullptr, "Gasp! This exception may be lost by subsequent calls.");
     suspended_ = false;
-    suspend(this);
+    suspend();
   }
 
   if (exception_ != nullptr) {
@@ -357,7 +357,7 @@ s4u::Actor* ActorImpl::restart()
   return actor->ciface();
 }
 
-void ActorImpl::suspend(ActorImpl* issuer)
+void ActorImpl::suspend()
 {
   if (suspended_) {
     XBT_DEBUG("Actor '%s' is already suspended", get_cname());
index a560305..ee082de 100644 (file)
@@ -79,11 +79,14 @@ public:
   int get_refcount() { return refcount_; }
   friend void intrusive_ptr_add_ref(ActorImpl* actor)
   {
-    // std::memory_order_relaxed ought to be enough here instead of std::memory_order_seq_cst
-    // But then, we have a threading issue when an actor commits a suicide:
-    //  it seems that in this case, the worker thread kills the last occurrence of the actor
-    //  while usually, the maestro does so. FIXME: we should change how actors suicide
-    actor->refcount_.fetch_add(1, std::memory_order_seq_cst);
+    // This whole memory consistency semantic drives me nuts.
+    // std::memory_order_relaxed proves to not be enough: There is a threading issue when actors commit suicide.
+    //   My guess is that the maestro context wants to propagate changes to the actor's fields after the
+    //   actor context frees that memory area or something. But I'm not 100% certain of what's going on.
+    // std::memory_order_seq_cst works but that's rather demanding.
+    // AFAIK, std::memory_order_acq_rel works on all tested platforms, so let's stick to it.
+    // Reducing the requirements to _relaxed would require to fix our suicide procedure, which is a messy piece of code.
+    actor->refcount_.fetch_add(1, std::memory_order_acq_rel);
   }
   friend void intrusive_ptr_release(ActorImpl* actor)
   {
@@ -123,7 +126,7 @@ public:
   void daemonize();
   bool is_suspended() { return suspended_; }
   s4u::Actor* restart();
-  void suspend(ActorImpl* issuer);
+  void suspend();
   void resume();
   activity::ActivityImplPtr join(ActorImpl* actor, double timeout);
   activity::ActivityImplPtr sleep(double duration);
diff --git a/src/kernel/resource/DiskImpl.cpp b/src/kernel/resource/DiskImpl.cpp
new file mode 100644 (file)
index 0000000..f2877f2
--- /dev/null
@@ -0,0 +1,105 @@
+/* Copyright (c) 2019. 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 "DiskImpl.hpp"
+
+#include "simgrid/s4u/Engine.hpp"
+#include "src/kernel/EngineImpl.hpp"
+#include "src/kernel/lmm/maxmin.hpp"
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(disk_kernel, surf, "Logging specific to the disk kernel resource");
+
+simgrid::kernel::resource::DiskModel* surf_disk_model = nullptr;
+
+namespace simgrid {
+namespace kernel {
+namespace resource {
+
+/*********
+ * Model *
+ *********/
+
+DiskModel::DiskModel() : Model(Model::UpdateAlgo::FULL)
+{
+  set_maxmin_system(new simgrid::kernel::lmm::System(true /* selective update */));
+}
+
+DiskModel::~DiskModel()
+{
+  surf_disk_model = nullptr;
+}
+
+/************
+ * Resource *
+ ************/
+
+DiskImpl::DiskImpl(kernel::resource::Model* model, const std::string& name, kernel::lmm::System* maxminSystem,
+                   double read_bw, double write_bw)
+    : Resource(model, name, maxminSystem->constraint_new(this, std::max(read_bw, write_bw))), piface_(name, this)
+{
+  DiskImpl::turn_on();
+  XBT_DEBUG("Create resource with read_bw '%f' write_bw '%f'", read_bw, write_bw);
+  constraint_read_  = maxminSystem->constraint_new(this, read_bw);
+  constraint_write_ = maxminSystem->constraint_new(this, write_bw);
+}
+
+DiskImpl::~DiskImpl()
+{
+  xbt_assert(currently_destroying_, "Don't delete Disks directly. Call destroy() instead.");
+}
+
+/** @brief Fire the required callbacks and destroy the object
+ *
+ * Don't delete directly a Disk, call d->destroy() instead.
+ */
+void DiskImpl::destroy()
+{
+  if (not currently_destroying_) {
+    currently_destroying_ = true;
+    s4u::Disk::on_destruction(this->piface_);
+    delete this;
+  }
+}
+
+bool DiskImpl::is_used()
+{
+  THROW_UNIMPLEMENTED;
+}
+
+void DiskImpl::apply_event(kernel::profile::Event* /*event*/, double /*value*/)
+{
+  THROW_UNIMPLEMENTED;
+}
+
+void DiskImpl::turn_on()
+{
+  if (not is_on()) {
+    Resource::turn_on();
+    s4u::Disk::on_state_change(this->piface_);
+  }
+}
+void DiskImpl::turn_off()
+{
+  if (is_on()) {
+    Resource::turn_off();
+    s4u::Disk::on_state_change(this->piface_);
+  }
+}
+
+xbt::signal<void(DiskAction const&, kernel::resource::Action::State, kernel::resource::Action::State)>
+    DiskAction::on_state_change;
+
+/**********
+ * Action *
+ **********/
+void DiskAction::set_state(Action::State state)
+{
+  Action::State old = get_state();
+  Action::set_state(state);
+  on_state_change(*this, old, state);
+}
+} // namespace resource
+} // namespace kernel
+} // namespace simgrid
diff --git a/src/kernel/resource/DiskImpl.hpp b/src/kernel/resource/DiskImpl.hpp
new file mode 100644 (file)
index 0000000..80ae7a6
--- /dev/null
@@ -0,0 +1,118 @@
+/* Copyright (c) 2019. 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 "simgrid/kernel/resource/Action.hpp"
+#include "simgrid/kernel/resource/Model.hpp"
+#include "simgrid/kernel/resource/Resource.hpp"
+#include "simgrid/s4u/Disk.hpp"
+#include "simgrid/s4u/Io.hpp"
+#include "src/surf/PropertyHolder.hpp"
+#include "src/surf/surf_interface.hpp"
+
+#include <map>
+
+#ifndef DISK_INTERFACE_HPP_
+#define DISK_INTERFACE_HPP_
+
+/*********
+ * Model *
+ *********/
+
+XBT_PUBLIC_DATA simgrid::kernel::resource::DiskModel* surf_disk_model;
+
+namespace simgrid {
+namespace kernel {
+namespace resource {
+/***********
+ * Classes *
+ ***********/
+
+class DiskAction;
+
+/*********
+ * Model *
+ *********/
+class DiskModel : public kernel::resource::Model {
+public:
+  DiskModel();
+  DiskModel(const DiskModel&) = delete;
+  DiskModel& operator=(const DiskModel&) = delete;
+  ~DiskModel();
+
+  virtual DiskImpl* createDisk(const std::string& id, double read_bw, double write_bw) = 0;
+};
+
+/************
+ * Resource *
+ ************/
+class DiskImpl : public Resource, public surf::PropertyHolder {
+  bool currently_destroying_ = false;
+  s4u::Host* host_           = nullptr;
+
+public:
+  DiskImpl(Model* model, const std::string& name, kernel::lmm::System* maxmin_system, double read_bw, double bwrite_bw);
+  DiskImpl(const DiskImpl&) = delete;
+  DiskImpl& operator=(const DiskImpl&) = delete;
+
+  ~DiskImpl() override;
+
+  /** @brief Public interface */
+  s4u::Disk piface_;
+  s4u::Disk* get_iface() { return &piface_; }
+  /** @brief Check if the Storage is used (if an action currently uses its resources) */
+  bool is_used() override;
+
+  void apply_event(profile::Event* event, double value) override;
+
+  void turn_on() override;
+  void turn_off() override;
+
+  s4u::Host* get_host() { return host_; }
+  void set_host(s4u::Host* host) { host_ = host; }
+
+  void destroy(); // Must be called instead of the destructor
+  virtual DiskAction* io_start(sg_size_t size, s4u::Io::OpType type) = 0;
+  virtual DiskAction* read(sg_size_t size)                           = 0;
+  virtual DiskAction* write(sg_size_t size)                          = 0;
+
+  lmm::Constraint* constraint_write_; /* Constraint for maximum write bandwidth*/
+  lmm::Constraint* constraint_read_;  /* Constraint for maximum write bandwidth*/
+};
+
+/**********
+ * Action *
+ **********/
+
+class DiskAction : public Action {
+public:
+  static xbt::signal<void(DiskAction const&, Action::State, Action::State)> on_state_change;
+
+  DiskAction(Model* model, double cost, bool failed, DiskImpl* disk, s4u::Io::OpType type)
+      : Action(model, cost, failed), type_(type), disk_(disk){};
+
+  /**
+   * @brief diskAction constructor
+   *
+   * @param model The StorageModel associated to this DiskAction
+   * @param cost The cost of this DiskAction in bytes
+   * @param failed [description]
+   * @param var The lmm variable associated to this DiskAction if it is part of a LMM component
+   * @param storage The Storage associated to this DiskAction
+   * @param type [description]
+   */
+  DiskAction(kernel::resource::Model* model, double cost, bool failed, kernel::lmm::Variable* var, DiskImpl* disk,
+             s4u::Io::OpType type)
+      : Action(model, cost, failed, var), type_(type), disk_(disk){};
+
+  void set_state(simgrid::kernel::resource::Action::State state) override;
+
+  s4u::Io::OpType type_;
+  DiskImpl* disk_;
+};
+
+} // namespace resource
+} // namespace kernel
+} // namespace simgrid
+#endif /* DISK_INTERFACE_HPP_ */
index 39f8a83..a0a2813 100644 (file)
@@ -33,7 +33,7 @@ public:
   int argument_ = 0;
 };
 
-}
-}
+} // namespace mc
+} // namespace simgrid
 
 #endif
index a4b48c9..1302502 100644 (file)
@@ -425,7 +425,7 @@ void CommunicationDeterminismChecker::real_run()
     mc_model_checker->visited_states++;
 
     if (stack_.size() <= (std::size_t)_sg_mc_max_depth)
-      req = MC_state_get_request(cur_state);
+      req = MC_state_choose_request(cur_state);
     else
       req = nullptr;
 
index 4f6000f..bbced3a 100644 (file)
@@ -379,7 +379,7 @@ void LivenessChecker::run()
       }
     }
 
-    smx_simcall_t req = MC_state_get_request(current_pair->graph_state.get());
+    smx_simcall_t req = MC_state_choose_request(current_pair->graph_state.get());
     int req_num       = current_pair->graph_state->transition_.argument_;
 
     if (dot_output != nullptr) {
index ecc8ca3..c08ecaa 100644 (file)
@@ -113,7 +113,7 @@ void SafetyChecker::run()
 
     // Search an enabled transition in the current state; backtrack if the interleave set is empty
     // get_request also sets state.transition to be the one corresponding to the returned req
-    smx_simcall_t req = MC_state_get_request(state);
+    smx_simcall_t req = MC_state_choose_request(state);
     // req is now the transition of the process that was selected to be executed
 
     if (req == nullptr) {
index 940578c..525f3a5 100644 (file)
@@ -13,20 +13,20 @@ namespace mc {
 
 class SimcallInspector {
 public:
-  /** whether this transition can currently be taken without blocking.
+  /** Whether this transition can currently be taken without blocking.
    *
    * For example, a mutex_lock is not enabled when the mutex is not free.
    * A comm_receive is not enabled before the corresponding send has been issued.
    */
   virtual bool is_enabled() { return true; }
 
-  /** Execute the simcall, from the kernel POV.
+  /** Prepare the simcall to be executed
    *
-   * Most of the time, this action is in charge of doing what the perf models would have done if not in MC mode.
-   * For example, if it's a random(), choose the value to explore next. If it's a waitany, choose the terminated
-   * communication to consider now.
+   * Do the choices that the platform would have done in non-MC settings.
+   * For example if it's a waitany, pick the communication that should finish first.
+   * If it's a random(), choose the next value to explore.
    */
-  virtual void fire() = 0;
+  virtual void arm() {}
 
   /** Some simcalls may only be observable under some circomstances.
    * Most simcalls are not visible from the MC because they don't have an inspector at all. */
index 0106b84..535dae9 100644 (file)
@@ -60,7 +60,7 @@ Transition State::get_transition() const
  * Things can get muddled with the WAITANY and TESTANY simcalls, that are rewritten on the fly to a bunch of WAIT
  * (resp TEST) transitions using the transition.argument field to remember what was the last returned sub-transition.
  */
-static inline smx_simcall_t MC_state_get_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
+static inline smx_simcall_t MC_state_choose_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
 {
   /* reset the outgoing transition */
   simgrid::mc::ActorState* procstate   = &state->actor_states_[actor->get_pid()];
@@ -202,14 +202,14 @@ static inline smx_simcall_t MC_state_get_request_for_process(simgrid::mc::State*
   return req;
 }
 
-smx_simcall_t MC_state_get_request(simgrid::mc::State* state)
+smx_simcall_t MC_state_choose_request(simgrid::mc::State* state)
 {
   for (auto& actor : mc_model_checker->process().actors()) {
     /* Only consider the actors that were marked as interleaving by the checker algorithm */
     if (not state->actor_states_[actor.copy.get_buffer()->get_pid()].is_todo())
       continue;
 
-    smx_simcall_t res = MC_state_get_request_for_process(state, actor.copy.get_buffer());
+    smx_simcall_t res = MC_state_choose_request_for_process(state, actor.copy.get_buffer());
     if (res)
       return res;
   }
index 96b5910..4123468 100644 (file)
@@ -130,6 +130,6 @@ public:
 }
 }
 
-XBT_PRIVATE smx_simcall_t MC_state_get_request(simgrid::mc::State* state);
+XBT_PRIVATE smx_simcall_t MC_state_choose_request(simgrid::mc::State* state);
 
 #endif
index 6cb9b5e..ce53075 100644 (file)
 #include "xbt/log.h"
 #include "xbt/sysdep.h"
 
-#include "src/mc/sosp/PageStore.hpp"
+#ifdef SG_HAVE_CPP14
+#include "src/include/xxhash.hpp"
+#endif
 #include "src/mc/mc_mmu.hpp"
+#include "src/mc/sosp/PageStore.hpp"
 
 #include <cstring> // memcpy, memcmp
 #include <unistd.h>
@@ -33,6 +36,9 @@ namespace mc {
  */
 static XBT_ALWAYS_INLINE PageStore::hash_type mc_hash_page(const void* data)
 {
+#ifdef SG_HAVE_CPP14
+  return xxh::xxhash<64>(data, xbt_pagesize);
+#else
   const std::uint64_t* values = (const uint64_t*)data;
   std::size_t n               = xbt_pagesize / sizeof(uint64_t);
 
@@ -41,6 +47,7 @@ static XBT_ALWAYS_INLINE PageStore::hash_type mc_hash_page(const void* data)
   for (std::size_t i = 0; i != n; ++i)
     hash = ((hash << 5) + hash) + values[i];
   return hash;
+#endif
 }
 
 // ***** snapshot_page_manager
index ab142c8..cd258f3 100644 (file)
@@ -282,11 +282,11 @@ const char* MSG_host_get_name(sg_host_t host)
 }
 void* MSG_host_get_data(sg_host_t host)
 {
-  return sg_host_user(host);
+  return sg_host_data(host);
 }
 void MSG_host_set_data(sg_host_t host, void* data)
 {
-  return sg_host_user_set(host, data);
+  return sg_host_data_set(host, data);
 }
 xbt_dict_t MSG_host_get_mounted_storage_list(sg_host_t host)
 {
index b32fd51..67e7ffd 100644 (file)
@@ -5,7 +5,9 @@
 
 #include "simgrid/plugins/file_system.h"
 #include "simgrid/s4u/Actor.hpp"
+#include "simgrid/s4u/Engine.hpp"
 #include "src/surf/HostImpl.hpp"
+#include "src/surf/xml/platf_private.hpp"
 #include "xbt/config.hpp"
 
 #include <algorithm>
@@ -20,6 +22,7 @@ int sg_storage_max_file_descriptors = 1024;
 
 namespace simgrid {
 namespace s4u {
+simgrid::xbt::Extension<Disk, FileSystemDiskExt> FileSystemDiskExt::EXTENSION_ID;
 simgrid::xbt::Extension<Storage, FileSystemStorageExt> FileSystemStorageExt::EXTENSION_ID;
 simgrid::xbt::Extension<Host, FileDescriptorHostExt> FileDescriptorHostExt::EXTENSION_ID;
 
@@ -28,27 +31,56 @@ File::File(const std::string& fullpath, void* userdata) : File(fullpath, Host::c
 File::File(const std::string& fullpath, sg_host_t host, void* userdata) : fullpath_(fullpath), userdata_(userdata)
 {
   // this cannot fail because we get a xbt_die if the mountpoint does not exist
-  Storage* st                  = nullptr;
-  size_t longest_prefix_length = 0;
-  XBT_DEBUG("Search for storage name for '%s' on '%s'", fullpath_.c_str(), host->get_cname());
-
-  for (auto const& mnt : host->get_mounted_storages()) {
-    XBT_DEBUG("See '%s'", mnt.first.c_str());
-    mount_point_ = fullpath_.substr(0, mnt.first.length());
-
-    if (mount_point_ == mnt.first && mnt.first.length() > longest_prefix_length) {
-      /* The current mount name is found in the full path and is bigger than the previous*/
-      longest_prefix_length = mnt.first.length();
-      st                    = mnt.second;
+  if (not host->get_mounted_storages().empty()) {
+    Storage* st                  = nullptr;
+    size_t longest_prefix_length = 0;
+    XBT_DEBUG("Search for storage name for '%s' on '%s'", fullpath_.c_str(), host->get_cname());
+
+    for (auto const& mnt : host->get_mounted_storages()) {
+      XBT_DEBUG("See '%s'", mnt.first.c_str());
+      mount_point_ = fullpath_.substr(0, mnt.first.length());
+
+      if (mount_point_ == mnt.first && mnt.first.length() > longest_prefix_length) {
+        /* The current mount name is found in the full path and is bigger than the previous*/
+        longest_prefix_length = mnt.first.length();
+        st                    = mnt.second;
+      }
     }
-  }
-  if (longest_prefix_length > 0) { /* Mount point found, split fullpath_ into mount_name and path+filename*/
-    mount_point_ = fullpath_.substr(0, longest_prefix_length);
-    path_        = fullpath_.substr(longest_prefix_length, fullpath_.length());
-  } else
-    xbt_die("Can't find mount point for '%s' on '%s'", fullpath_.c_str(), host->get_cname());
+    if (longest_prefix_length > 0) { /* Mount point found, split fullpath_ into mount_name and path+filename*/
+      mount_point_ = fullpath_.substr(0, longest_prefix_length);
+      path_        = fullpath_.substr(longest_prefix_length, fullpath_.length());
+    } else
+      xbt_die("Can't find mount point for '%s' on '%s'", fullpath_.c_str(), host->get_cname());
 
-  local_storage_ = st;
+    local_storage_ = st;
+  }
+  if (not host->get_disks().empty()) {
+    Disk* d                      = nullptr;
+    size_t longest_prefix_length = 0;
+    for (auto const& disk : host->get_disks()) {
+      std::string current_mount;
+      if (disk->get_host() != host)
+        current_mount = disk->extension<FileSystemDiskExt>()->get_mount_point(disk->get_host());
+      else
+        current_mount = disk->extension<FileSystemDiskExt>()->get_mount_point();
+      mount_point_              = fullpath_.substr(0, current_mount.length());
+      if (mount_point_ == current_mount && current_mount.length() > longest_prefix_length) {
+        /* The current mount name is found in the full path and is bigger than the previous*/
+        longest_prefix_length = current_mount.length();
+        d                     = disk;
+      }
+      if (longest_prefix_length > 0) { /* Mount point found, split fullpath_ into mount_name and path+filename*/
+        mount_point_ = fullpath_.substr(0, longest_prefix_length);
+        if (mount_point_ == std::string("/"))
+          path_ = fullpath_;
+        else
+          path_ = fullpath_.substr(longest_prefix_length, fullpath_.length());
+        XBT_DEBUG("%s + %s", mount_point_.c_str(), path_.c_str());
+      } else
+        xbt_die("Can't find mount point for '%s' on '%s'", fullpath_.c_str(), host->get_cname());
+    }
+    local_disk_ = d;
+  }
 
   // assign a file descriptor id to the newly opened File
   FileDescriptorHostExt* ext = host->extension<simgrid::s4u::FileDescriptorHostExt>();
@@ -61,15 +93,23 @@ File::File(const std::string& fullpath, sg_host_t host, void* userdata) : fullpa
   ext->file_descriptor_table->pop_back();
 
   XBT_DEBUG("\tOpen file '%s'", path_.c_str());
-  std::map<std::string, sg_size_t>* content = local_storage_->extension<FileSystemStorageExt>()->get_content();
+  std::map<std::string, sg_size_t>* content = nullptr;
+  if (local_storage_)
+    content = local_storage_->extension<FileSystemStorageExt>()->get_content();
+
+  if (local_disk_)
+    content = local_disk_->extension<FileSystemDiskExt>()->get_content();
+
   // if file does not exist create an empty file
-  auto sz = content->find(path_);
-  if (sz != content->end()) {
-    size_ = sz->second;
-  } else {
-    size_ = 0;
-    content->insert({path_, size_});
-    XBT_DEBUG("File '%s' was not found, file created.", path_.c_str());
+  if (content) {
+    auto sz = content->find(path_);
+    if (sz != content->end()) {
+      size_ = sz->second;
+    } else {
+      size_ = 0;
+      content->insert({path_, size_});
+      XBT_DEBUG("File '%s' was not found, file created.", path_.c_str());
+    }
   }
 }
 
@@ -80,29 +120,52 @@ File::~File()
 
 void File::dump()
 {
-  XBT_INFO("File Descriptor information:\n"
-           "\t\tFull path: '%s'\n"
-           "\t\tSize: %llu\n"
-           "\t\tMount point: '%s'\n"
-           "\t\tStorage Id: '%s'\n"
-           "\t\tStorage Type: '%s'\n"
-           "\t\tFile Descriptor Id: %d",
-           get_path(), size_, mount_point_.c_str(), local_storage_->get_cname(), local_storage_->get_type(), desc_id);
+  if (local_storage_)
+    XBT_INFO("File Descriptor information:\n"
+             "\t\tFull path: '%s'\n"
+             "\t\tSize: %llu\n"
+             "\t\tMount point: '%s'\n"
+             "\t\tStorage Id: '%s'\n"
+             "\t\tStorage Type: '%s'\n"
+             "\t\tFile Descriptor Id: %d",
+             get_path(), size_, mount_point_.c_str(), local_storage_->get_cname(), local_storage_->get_type(), desc_id);
+  if (local_disk_)
+    XBT_INFO("File Descriptor information:\n"
+             "\t\tFull path: '%s'\n"
+             "\t\tSize: %llu\n"
+             "\t\tMount point: '%s'\n"
+             "\t\tDisk Id: '%s'\n"
+             "\t\tHost Id: '%s'\n"
+             "\t\tFile Descriptor Id: %d",
+             get_path(), size_, mount_point_.c_str(), local_disk_->get_cname(), local_disk_->get_host()->get_cname(),
+             desc_id);
 }
 
 sg_size_t File::read(sg_size_t size)
 {
   if (size_ == 0) /* Nothing to read, return */
     return 0;
+  sg_size_t read_size = 0;
+  Host* host          = nullptr;
+  if (local_storage_) {
+    /* Find the host where the file is physically located and read it */
+    host = local_storage_->get_host();
+    XBT_DEBUG("READ %s on disk '%s'", get_path(), local_storage_->get_cname());
+    // if the current position is close to the end of the file, we may not be able to read the requested size
+    read_size = local_storage_->read(std::min(size, size_ - current_position_));
+    current_position_ += read_size;
+  }
 
-  /* Find the host where the file is physically located and read it */
-  Host* host = local_storage_->get_host();
-  XBT_DEBUG("READ %s on disk '%s'", get_path(), local_storage_->get_cname());
-  // if the current position is close to the end of the file, we may not be able to read the requested size
-  sg_size_t read_size = local_storage_->read(std::min(size, size_ - current_position_));
-  current_position_ += read_size;
+  if (local_disk_) {
+    /* Find the host where the file is physically located and read it */
+    host = local_disk_->get_host();
+    XBT_DEBUG("READ %s on disk '%s'", get_path(), local_disk_->get_cname());
+    // if the current position is close to the end of the file, we may not be able to read the requested size
+    read_size = local_disk_->read(std::min(size, size_ - current_position_));
+    current_position_ += read_size;
+  }
 
-  if (host->get_name() != Host::current()->get_name() && read_size > 0) {
+  if (host && host->get_name() != Host::current()->get_name() && read_size > 0) {
     /* the file is hosted on a remote host, initiate a communication between src and dest hosts for data transfer */
     XBT_DEBUG("File is on %s remote host, initiate data transfer of %llu bytes.", host->get_cname(), read_size);
     host->send_to(Host::current(), read_size);
@@ -120,39 +183,70 @@ sg_size_t File::write(sg_size_t size, int write_inside)
 {
   if (size == 0) /* Nothing to write, return */
     return 0;
+  sg_size_t write_size = 0;
+  Host* host           = nullptr;
 
   /* Find the host where the file is physically located (remote or local)*/
-  Host* host = local_storage_->get_host();
+  if (local_storage_)
+    host = local_storage_->get_host();
+  if (local_disk_)
+    host = local_disk_->get_host();
 
-  if (host->get_name() != Host::current()->get_name()) {
+  if (host && host->get_name() != Host::current()->get_name()) {
     /* the file is hosted on a remote host, initiate a communication between src and dest hosts for data transfer */
     XBT_DEBUG("File is on %s remote host, initiate data transfer of %llu bytes.", host->get_cname(), size);
     Host::current()->send_to(host, size);
   }
 
-  XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu' '%llu:%llu'", get_path(), local_storage_->get_cname(), size, size_, sg_storage_get_size_used(local_storage_), sg_storage_get_size(local_storage_));
-  // If the storage is full before even starting to write
-   if (sg_storage_get_size_used(local_storage_) >= sg_storage_get_size(local_storage_))
-     return 0;
-  sg_size_t write_size=0;
-  if(write_inside==0){
-    /* Substract the part of the file that might disappear from the used sized on the storage element */
-    local_storage_->extension<FileSystemStorageExt>()->decr_used_size(size_ - current_position_);
-    write_size = local_storage_->write(size);
-    local_storage_->extension<FileSystemStorageExt>()->incr_used_size(write_size);
-    current_position_ += write_size;
-    size_ = current_position_;
-  }else {
-    write_size = local_storage_->write(size);
-    current_position_ += write_size;
-    if(current_position_>size_)
+  if (local_storage_) {
+    XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu' '%llu:%llu'", get_path(), local_storage_->get_cname(), size,
+              size_, sg_storage_get_size_used(local_storage_), sg_storage_get_size(local_storage_));
+    // If the storage is full before even starting to write
+    if (sg_storage_get_size_used(local_storage_) >= sg_storage_get_size(local_storage_))
+      return 0;
+    if (write_inside == 0) {
+      /* Substract the part of the file that might disappear from the used sized on the storage element */
+      local_storage_->extension<FileSystemStorageExt>()->decr_used_size(size_ - current_position_);
+      write_size = local_storage_->write(size);
+      local_storage_->extension<FileSystemStorageExt>()->incr_used_size(write_size);
+      current_position_ += write_size;
       size_ = current_position_;
+    } else {
+      write_size = local_storage_->write(size);
+      current_position_ += write_size;
+      if (current_position_ > size_)
+        size_ = current_position_;
+    }
+    std::map<std::string, sg_size_t>* content = local_storage_->extension<FileSystemStorageExt>()->get_content();
+
+    content->erase(path_);
+    content->insert({path_, size_});
   }
-  std::map<std::string, sg_size_t>* content = local_storage_->extension<FileSystemStorageExt>()->get_content();
 
-  content->erase(path_);
-  content->insert({path_, size_});
+  if (local_disk_) {
+    XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu' '%llu:%llu'", get_path(), local_disk_->get_cname(), size, size_,
+              sg_disk_get_size_used(local_disk_), sg_disk_get_size(local_disk_));
+    // If the storage is full before even starting to write
+    if (sg_disk_get_size_used(local_disk_) >= sg_disk_get_size(local_disk_))
+      return 0;
+    if (write_inside == 0) {
+      /* Substract the part of the file that might disappear from the used sized on the storage element */
+      local_disk_->extension<FileSystemDiskExt>()->decr_used_size(size_ - current_position_);
+      write_size = local_disk_->write(size);
+      local_disk_->extension<FileSystemDiskExt>()->incr_used_size(write_size);
+      current_position_ += write_size;
+      size_ = current_position_;
+    } else {
+      write_size = local_disk_->write(size);
+      current_position_ += write_size;
+      if (current_position_ > size_)
+        size_ = current_position_;
+    }
+    std::map<std::string, sg_size_t>* content = local_disk_->extension<FileSystemDiskExt>()->get_content();
 
+    content->erase(path_);
+    content->insert({path_, size_});
+  }
   return write_size;
 }
 
@@ -192,16 +286,22 @@ void File::move(const std::string& fullpath)
 {
   /* Check if the new full path is on the same mount point */
   if (fullpath.compare(0, mount_point_.length(), mount_point_) == 0) {
-    std::map<std::string, sg_size_t>* content = local_storage_->extension<FileSystemStorageExt>()->get_content();
-    auto sz = content->find(path_);
-    if (sz != content->end()) { // src file exists
-      sg_size_t new_size = sz->second;
-      content->erase(path_);
-      std::string path = fullpath.substr(mount_point_.length(), fullpath.length());
-      content->insert({path.c_str(), new_size});
-      XBT_DEBUG("Move file from %s to %s, size '%llu'", path_.c_str(), fullpath.c_str(), new_size);
-    } else {
-      XBT_WARN("File %s doesn't exist", path_.c_str());
+    std::map<std::string, sg_size_t>* content = nullptr;
+    if (local_storage_)
+      content = local_storage_->extension<FileSystemStorageExt>()->get_content();
+    if (local_disk_)
+      content = local_disk_->extension<FileSystemDiskExt>()->get_content();
+    if (content) {
+      auto sz = content->find(path_);
+      if (sz != content->end()) { // src file exists
+        sg_size_t new_size = sz->second;
+        content->erase(path_);
+        std::string path = fullpath.substr(mount_point_.length(), fullpath.length());
+        content->insert({path.c_str(), new_size});
+        XBT_DEBUG("Move file from %s to %s, size '%llu'", path_.c_str(), fullpath.c_str(), new_size);
+      } else {
+        XBT_WARN("File %s doesn't exist", path_.c_str());
+      }
     }
   } else {
     XBT_WARN("New full path %s is not on the same mount point: %s.", fullpath.c_str(), mount_point_.c_str());
@@ -211,14 +311,28 @@ void File::move(const std::string& fullpath)
 int File::unlink()
 {
   /* Check if the file is on local storage */
-  std::map<std::string, sg_size_t>* content = local_storage_->extension<FileSystemStorageExt>()->get_content();
+  std::map<std::string, sg_size_t>* content = nullptr;
+  const char* name = "";
+  if (local_storage_) {
+    content = local_storage_->extension<FileSystemStorageExt>()->get_content();
+    name    = local_storage_->get_cname();
+  }
+  if (local_disk_) {
+    content = local_disk_->extension<FileSystemDiskExt>()->get_content();
+    name    = local_disk_->get_cname();
+  }
 
-  if (content->find(path_) == content->end()) {
-    XBT_WARN("File %s is not on disk %s. Impossible to unlink", path_.c_str(), local_storage_->get_cname());
+  if (not content || content->find(path_) == content->end()) {
+    XBT_WARN("File %s is not on disk %s. Impossible to unlink", path_.c_str(), name);
     return -1;
   } else {
-    XBT_DEBUG("UNLINK %s on disk '%s'", path_.c_str(), local_storage_->get_cname());
-    local_storage_->extension<FileSystemStorageExt>()->decr_used_size(size_);
+    XBT_DEBUG("UNLINK %s on disk '%s'", path_.c_str(), name);
+
+    if (local_storage_)
+      local_storage_->extension<FileSystemStorageExt>()->decr_used_size(size_);
+
+    if (local_disk_)
+      local_disk_->extension<FileSystemDiskExt>()->decr_used_size(size_);
 
     // Remove the file from storage
     content->erase(fullpath_);
@@ -230,45 +344,86 @@ int File::unlink()
 int File::remote_copy(sg_host_t host, const char* fullpath)
 {
   /* Find the host where the file is physically located and read it */
-  Storage* storage_src = local_storage_;
-  Host* src_host       = storage_src->get_host();
+  Host* src_host = nullptr;
+  if (local_storage_) {
+    src_host = local_storage_->get_host();
+    XBT_DEBUG("READ %s on disk '%s'", get_path(), local_storage_->get_cname());
+  }
+
+  if (local_disk_) {
+    src_host = local_disk_->get_host();
+    XBT_DEBUG("READ %s on disk '%s'", get_path(), local_disk_->get_cname());
+  }
+
   seek(0, SEEK_SET);
-  XBT_DEBUG("READ %s on disk '%s'", get_path(), local_storage_->get_cname());
   // if the current position is close to the end of the file, we may not be able to read the requested size
-  sg_size_t read_size = local_storage_->read(size_);
+  sg_size_t read_size = 0;
+  if (local_storage_)
+    read_size = local_storage_->read(size_);
+  if (local_disk_)
+    read_size = local_disk_->read(size_);
+
   current_position_ += read_size;
 
-  /* Find the host that owns the storage where the file has to be copied */
-  Storage* storage_dest = nullptr;
-  Host* dst_host;
-  size_t longest_prefix_length = 0;
-
-  for (auto const& elm : host->get_mounted_storages()) {
-    std::string mount_point = std::string(fullpath).substr(0, elm.first.size());
-    if (mount_point == elm.first && elm.first.length() > longest_prefix_length) {
-      /* The current mount name is found in the full path and is bigger than the previous*/
-      longest_prefix_length = elm.first.length();
-      storage_dest          = elm.second;
+  Host* dst_host = host;
+  if (local_storage_) {
+    /* Find the host that owns the storage where the file has to be copied */
+    Storage* storage_dest        = nullptr;
+    size_t longest_prefix_length = 0;
+
+    for (auto const& elm : host->get_mounted_storages()) {
+      std::string mount_point = std::string(fullpath).substr(0, elm.first.size());
+      if (mount_point == elm.first && elm.first.length() > longest_prefix_length) {
+        /* The current mount name is found in the full path and is bigger than the previous*/
+        longest_prefix_length = elm.first.length();
+        storage_dest          = elm.second;
+      }
+    }
+
+    if (storage_dest != nullptr) {
+      /* Mount point found, retrieve the host the storage is attached to */
+      dst_host = storage_dest->get_host();
+    } else {
+      XBT_WARN("Can't find mount point for '%s' on destination host '%s'", fullpath, host->get_cname());
+      return -1;
     }
   }
 
-  if (storage_dest != nullptr) {
-    /* Mount point found, retrieve the host the storage is attached to */
-    dst_host = storage_dest->get_host();
-  } else {
-    XBT_WARN("Can't find mount point for '%s' on destination host '%s'", fullpath, host->get_cname());
-    return -1;
+  if (local_disk_) {
+    size_t longest_prefix_length = 0;
+    Disk* dst_disk               = nullptr;
+
+    for (auto const& disk : host->get_disks()) {
+      std::string current_mount = disk->extension<FileSystemDiskExt>()->get_mount_point();
+      std::string mount_point   = std::string(fullpath).substr(0, current_mount.length());
+      if (mount_point == current_mount && current_mount.length() > longest_prefix_length) {
+        /* The current mount name is found in the full path and is bigger than the previous*/
+        longest_prefix_length = current_mount.length();
+        dst_disk              = disk;
+      }
+    }
+
+    if (dst_disk == nullptr) {
+      XBT_WARN("Can't find mount point for '%s' on destination host '%s'", fullpath, host->get_cname());
+      return -1;
+    }
   }
 
-  XBT_DEBUG("Initiate data transfer of %llu bytes between %s and %s.", read_size, src_host->get_cname(),
-            storage_dest->get_host()->get_cname());
-  src_host->send_to(dst_host, read_size);
+  if (src_host) {
+    XBT_DEBUG("Initiate data transfer of %llu bytes between %s and %s.", read_size, src_host->get_cname(),
+              dst_host->get_cname());
+    src_host->send_to(dst_host, read_size);
+  }
 
   /* Create file on remote host, write it and close it */
   File* fd = new File(fullpath, dst_host, nullptr);
-  sg_size_t write_size = fd->local_storage_->write(read_size);
-  fd->local_storage_->extension<FileSystemStorageExt>()->incr_used_size(write_size);
-  (*(fd->local_storage_->extension<FileSystemStorageExt>()->get_content()))[path_] = size_;
+  if (local_storage_) {
+    sg_size_t write_size = fd->local_storage_->write(read_size);
+    fd->local_storage_->extension<FileSystemStorageExt>()->incr_used_size(write_size);
+    (*(fd->local_storage_->extension<FileSystemStorageExt>()->get_content()))[path_] = size_;
+  }
+  if (local_disk_)
+    fd->write(read_size);
   delete fd;
   return 0;
 }
@@ -280,12 +435,56 @@ int File::remote_move(sg_host_t host, const char* fullpath)
   return res;
 }
 
+FileSystemDiskExt::FileSystemDiskExt(simgrid::s4u::Disk* ptr)
+{
+  const char* size_str    = ptr->get_property("size");
+  if (size_str)
+    size_ = surf_parse_get_size(size_str, "disk size", ptr->get_name());
+
+  const char* current_mount_str = ptr->get_property("mount");
+  if (current_mount_str)
+    mount_point_ = std::string(current_mount_str);
+  else
+    mount_point_ = std::string("/");
+
+  const char* content_str = ptr->get_property("content");
+  if (content_str)
+    content_.reset(parse_content(content_str));
+}
+
 FileSystemStorageExt::FileSystemStorageExt(simgrid::s4u::Storage* ptr)
 {
   content_.reset(parse_content(ptr->get_impl()->content_name_));
   size_    = ptr->get_impl()->size_;
 }
 
+std::map<std::string, sg_size_t>* FileSystemDiskExt::parse_content(const std::string& filename)
+{
+  if (filename.empty())
+    return nullptr;
+
+  std::map<std::string, sg_size_t>* parse_content = new std::map<std::string, sg_size_t>();
+
+  std::ifstream* fs = surf_ifsopen(filename);
+
+  std::string line;
+  std::vector<std::string> tokens;
+  do {
+    std::getline(*fs, line);
+    boost::trim(line);
+    if (line.length() > 0) {
+      boost::split(tokens, line, boost::is_any_of(" \t"), boost::token_compress_on);
+      xbt_assert(tokens.size() == 2, "Parse error in %s: %s", filename.c_str(), line.c_str());
+      sg_size_t size = std::stoull(tokens.at(1));
+
+      used_size_ += size;
+      parse_content->insert({tokens.front(), size});
+    }
+  } while (not fs->eof());
+  delete fs;
+  return parse_content;
+}
+
 std::map<std::string, sg_size_t>* FileSystemStorageExt::parse_content(const std::string& filename)
 {
   if (filename.empty())
@@ -315,9 +514,14 @@ std::map<std::string, sg_size_t>* FileSystemStorageExt::parse_content(const std:
 }
 }
 
-using simgrid::s4u::FileSystemStorageExt;
 using simgrid::s4u::FileDescriptorHostExt;
+using simgrid::s4u::FileSystemDiskExt;
+using simgrid::s4u::FileSystemStorageExt;
 
+static void on_disk_creation(simgrid::s4u::Disk& d)
+{
+  d.extension_set(new FileSystemDiskExt(&d));
+}
 static void on_storage_creation(simgrid::s4u::Storage& st)
 {
   st.extension_set(new FileSystemStorageExt(&st));
@@ -328,6 +532,51 @@ static void on_host_creation(simgrid::s4u::Host& host)
   host.extension_set<FileDescriptorHostExt>(new FileDescriptorHostExt());
 }
 
+static void on_platform_created()
+{
+  for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
+    const char* remote_disk_str = host->get_property("remote_disk");
+    if (remote_disk_str) {
+      std::vector<std::string> tokens;
+      boost::split(tokens, remote_disk_str, boost::is_any_of(":"));
+      std::string mount_point         = tokens[0];
+      simgrid::s4u::Host* remote_host = simgrid::s4u::Host::by_name_or_null(tokens[2]);
+      xbt_assert(remote_host, "You're trying to access a host that does not exist. Please check your platform file");
+
+      simgrid::s4u::Disk* disk = nullptr;
+      for (auto const& d : remote_host->get_disks())
+        if (d->get_name() == tokens[1]) {
+          disk = d;
+          break;
+        }
+
+      xbt_assert(disk, "You're trying to mount a disk that does not exist. Please check your platform file");
+      disk->extension<FileSystemDiskExt>()->add_remote_mount(remote_host, mount_point);
+      host->add_disk(disk);
+
+      XBT_DEBUG("Host '%s' wants to mount a remote disk: %s of %s mounted on %s", host->get_cname(), disk->get_cname(),
+                remote_host->get_cname(), mount_point.c_str());
+      XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size());
+    }
+  }
+}
+
+static void on_simulation_end()
+{
+  XBT_DEBUG("Simulation is over, time to unregister remote disks if any");
+  for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
+    const char* remote_disk_str = host->get_property("remote_disk");
+    if (remote_disk_str) {
+      std::vector<std::string> tokens;
+      boost::split(tokens, remote_disk_str, boost::is_any_of(":"));
+      XBT_DEBUG("Host '%s' wants to unmount a remote disk: %s of %s mounted on %s", host->get_cname(),
+                tokens[1].c_str(), tokens[2].c_str(), tokens[0].c_str());
+      host->remove_disk(tokens[1]);
+      XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size());
+    }
+  }
+}
+
 /* **************************** Public interface *************************** */
 void sg_storage_file_system_init()
 {
@@ -340,10 +589,17 @@ void sg_storage_file_system_init()
     simgrid::s4u::Storage::on_creation.connect(&on_storage_creation);
   }
 
+  if (not FileSystemDiskExt::EXTENSION_ID.valid()) {
+    FileSystemDiskExt::EXTENSION_ID = simgrid::s4u::Disk::extension_create<FileSystemDiskExt>();
+    simgrid::s4u::Disk::on_creation.connect(&on_disk_creation);
+  }
+
   if (not FileDescriptorHostExt::EXTENSION_ID.valid()) {
     FileDescriptorHostExt::EXTENSION_ID = simgrid::s4u::Host::extension_create<FileDescriptorHostExt>();
     simgrid::s4u::Host::on_creation.connect(&on_host_creation);
   }
+  simgrid::s4u::Engine::on_platform_created.connect(&on_platform_created);
+  simgrid::s4u::Engine::on_simulation_end.connect(&on_simulation_end);
 }
 
 sg_file_t sg_file_open(const char* fullpath, void* data)
@@ -447,6 +703,26 @@ int sg_file_rmove(sg_file_t file, sg_host_t host, const char* fullpath)
   return file->remote_move(host, fullpath);
 }
 
+sg_size_t sg_disk_get_size_free(sg_disk_t d)
+{
+  return d->extension<FileSystemDiskExt>()->get_size() - d->extension<FileSystemDiskExt>()->get_used_size();
+}
+
+sg_size_t sg_disk_get_size_used(sg_disk_t d)
+{
+  return d->extension<FileSystemDiskExt>()->get_used_size();
+}
+
+sg_size_t sg_disk_get_size(sg_disk_t d)
+{
+  return d->extension<FileSystemDiskExt>()->get_size();
+}
+
+const char* sg_disk_get_mount_point(sg_disk_t d)
+{
+  return d->extension<FileSystemDiskExt>()->get_mount_point();
+}
+
 sg_size_t sg_storage_get_size_free(sg_storage_t st)
 {
   return st->extension<FileSystemStorageExt>()->get_size() - st->extension<FileSystemStorageExt>()->get_used_size();
index dd95c9f..b3cb2a7 100644 (file)
@@ -469,7 +469,7 @@ void sg_host_energy_plugin_init()
   simgrid::s4u::Host::on_state_change.connect(&on_host_change);
   simgrid::s4u::Host::on_speed_change.connect(&on_host_change);
   simgrid::s4u::Host::on_destruction.connect(&on_host_destruction);
-  simgrid::s4u::on_simulation_end.connect(&on_simulation_end);
+  simgrid::s4u::Engine::on_simulation_end.connect(&on_simulation_end);
   simgrid::kernel::resource::CpuAction::on_state_change.connect(&on_action_state_change);
   // We may only have one actor on a node. If that actor executes something like
   //   compute -> recv -> compute
index bdf842b..20c9873 100644 (file)
@@ -186,7 +186,6 @@ int sg_link_energy_is_inited()
  */
 void sg_link_energy_plugin_init()
 {
-
   if (LinkEnergy::EXTENSION_ID.valid())
     return;
   LinkEnergy::EXTENSION_ID = simgrid::s4u::Link::extension_create<LinkEnergy>();
@@ -213,7 +212,7 @@ void sg_link_energy_plugin_init()
   });
 
   simgrid::s4u::Link::on_communicate.connect(&on_communicate);
-  simgrid::s4u::on_simulation_end.connect(&on_simulation_end);
+  simgrid::s4u::Engine::on_simulation_end.connect(&on_simulation_end);
 }
 
 /** @ingroup plugin_energy
index b7b2002..deecf72 100644 (file)
@@ -185,7 +185,7 @@ void VirtualMachineImpl::suspend(smx_actor_t issuer)
 
   for (auto& smx_process : process_list_) {
     XBT_DEBUG("suspend %s", smx_process.get_cname());
-    smx_process.suspend(issuer);
+    smx_process.suspend();
   }
 
   XBT_DEBUG("suspend all processes on the VM done done");
index 360cc93..7187920 100644 (file)
@@ -190,7 +190,7 @@ void Actor::suspend()
   auto target = pimpl_;
   s4u::Actor::on_suspend(*this);
   kernel::actor::simcall_blocking<void>([issuer, target]() {
-    target->suspend(issuer);
+    target->suspend();
     if (target != issuer) {
       /* If we are suspending ourselves, then just do not finish the simcall now */
       issuer->simcall_answer();
@@ -441,7 +441,9 @@ Host* get_host()
 
 void suspend()
 {
-  SIMIX_process_self()->iface()->suspend();
+  kernel::actor::ActorImpl* self = SIMIX_process_self();
+  s4u::Actor::on_suspend(*self->ciface());
+  kernel::actor::simcall_blocking<void>([self] { self->suspend(); });
 }
 
 void resume()
@@ -738,3 +740,14 @@ void sg_actor_unref(sg_actor_t actor)
 {
   intrusive_ptr_release(actor);
 }
+
+/** @brief Return the user data of a #sg_actor_t */
+void* sg_actor_data(sg_actor_t actor)
+{
+  return actor->get_data();
+}
+/** @brief Set the user data of a #sg_actor_t */
+void sg_actor_data_set(sg_actor_t actor, void* userdata)
+{
+  actor->set_data(userdata);
+}
diff --git a/src/s4u/s4u_Disk.cpp b/src/s4u/s4u_Disk.cpp
new file mode 100644 (file)
index 0000000..562e742
--- /dev/null
@@ -0,0 +1,70 @@
+/* Copyright (c) 2019. 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 "simgrid/s4u/Disk.hpp"
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/s4u/Host.hpp"
+#include "simgrid/s4u/Io.hpp"
+#include "src/kernel/resource/DiskImpl.hpp"
+
+namespace simgrid {
+namespace xbt {
+template class Extendable<s4u::Disk>;
+} // namespace xbt
+
+namespace s4u {
+
+xbt::signal<void(Disk&)> Disk::on_creation;
+xbt::signal<void(Disk const&)> Disk::on_destruction;
+xbt::signal<void(Disk const&)> Disk::on_state_change;
+
+Host* Disk::get_host()
+{
+  return pimpl_->get_host();
+}
+
+const std::unordered_map<std::string, std::string>* Disk::get_properties() const
+{
+  return pimpl_->get_properties();
+}
+
+const char* Disk::get_property(const std::string& key) const
+{
+  return this->pimpl_->get_property(key);
+}
+
+void Disk::set_property(const std::string& key, const std::string& value)
+{
+  kernel::actor::simcall([this, &key, &value] { this->pimpl_->set_property(key, value); });
+}
+
+IoPtr Disk::io_init(sg_size_t size, Io::OpType type)
+{
+  return IoPtr(new Io(this, size, type));
+}
+
+IoPtr Disk::read_async(sg_size_t size)
+{
+  return IoPtr(io_init(size, Io::OpType::READ))->start();
+}
+
+sg_size_t Disk::read(sg_size_t size)
+{
+  return IoPtr(io_init(size, Io::OpType::READ))->start()->wait()->get_performed_ioops();
+}
+
+IoPtr Disk::write_async(sg_size_t size)
+{
+
+  return IoPtr(io_init(size, Io::OpType::WRITE)->start());
+}
+
+sg_size_t Disk::write(sg_size_t size)
+{
+  return IoPtr(io_init(size, Io::OpType::WRITE))->start()->wait()->get_performed_ioops();
+}
+
+} // namespace s4u
+} // namespace simgrid
index 64cb7f6..1d12c11 100644 (file)
@@ -8,6 +8,7 @@
 #include "mc/mc.h"
 #include "simgrid/kernel/routing/NetPoint.hpp"
 #include "simgrid/kernel/routing/NetZoneImpl.hpp"
+#include "simgrid/s4u/Disk.hpp"
 #include "simgrid/s4u/Engine.hpp"
 #include "simgrid/s4u/Host.hpp"
 #include "simgrid/s4u/Mailbox.hpp"
@@ -28,11 +29,11 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_engine, s4u, "Logging specific to S4U (engin
 
 namespace simgrid {
 namespace s4u {
-xbt::signal<void()> on_platform_creation;
-xbt::signal<void()> on_platform_created;
-xbt::signal<void()> on_simulation_end;
-xbt::signal<void(double)> on_time_advance;
-xbt::signal<void(void)> on_deadlock;
+xbt::signal<void()> Engine::on_platform_creation;
+xbt::signal<void()> Engine::on_platform_created;
+xbt::signal<void()> Engine::on_simulation_end;
+xbt::signal<void(double)> Engine::on_time_advance;
+xbt::signal<void(void)> Engine::on_deadlock;
 
 Engine* Engine::instance_ = nullptr; /* That singleton is awful, but I don't see no other solution right now. */
 
index 29eb24b..5cb23b1 100644 (file)
@@ -18,8 +18,6 @@
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_host, s4u, "Logging specific to the S4U hosts");
 XBT_LOG_EXTERNAL_CATEGORY(surf_route);
 
-int USER_HOST_LEVEL = -1;
-
 namespace simgrid {
 namespace xbt {
 template class Extendable<s4u::Host>;
@@ -284,6 +282,20 @@ int Host::get_pstate() const
   return this->pimpl_cpu->get_pstate();
 }
 
+std::vector<Disk*> Host::get_disks() const
+{
+  return kernel::actor::simcall([this] { return this->pimpl_->get_disks(); });
+}
+
+void Host::add_disk(Disk* disk)
+{
+  kernel::actor::simcall([this, disk] { this->pimpl_->add_disk(disk); });
+}
+
+void Host::remove_disk(const std::string& disk_name)
+{
+  kernel::actor::simcall([this, disk_name] { this->pimpl_->remove_disk(disk_name); });
+}
 /**
  * @ingroup simix_storage_management
  * @brief Returns the list of storages attached to a host.
@@ -387,17 +399,25 @@ xbt_dynar_t sg_hosts_as_dynar()
 // ========= Layering madness ==============*
 
 // ========== User data Layer ==========
-void* sg_host_user(sg_host_t host)
+void* sg_host_data(sg_host_t host)
+{
+  return host->get_data();
+}
+void sg_host_data_set(sg_host_t host, void* userdata)
+{
+  host->set_data(userdata);
+}
+void* sg_host_user(sg_host_t host) // deprecated
 {
-  return host->extension(USER_HOST_LEVEL);
+  return host->get_data();
 }
-void sg_host_user_set(sg_host_t host, void* userdata)
+void sg_host_user_set(sg_host_t host, void* userdata) // deprecated
 {
-  host->extension_set(USER_HOST_LEVEL, userdata);
+  host->set_data(userdata);
 }
-void sg_host_user_destroy(sg_host_t host)
+void sg_host_user_destroy(sg_host_t host) // deprecated
 {
-  host->extension_set(USER_HOST_LEVEL, nullptr);
+  host->set_data(nullptr);
 }
 
 // ========= storage related functions ============
index 924dfec..4cf33bc 100644 (file)
@@ -3,6 +3,7 @@
 /* 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 "simgrid/s4u/Disk.hpp"
 #include "simgrid/s4u/Io.hpp"
 #include "simgrid/s4u/Storage.hpp"
 #include "src/kernel/activity/IoImpl.hpp"
@@ -13,6 +14,12 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_io, s4u_activity, "S4U asynchronous IOs");
 namespace simgrid {
 namespace s4u {
 
+Io::Io(sg_disk_t disk, sg_size_t size, OpType type) : disk_(disk), size_(size), type_(type)
+{
+  Activity::set_remaining(size_);
+  pimpl_ = kernel::activity::IoImplPtr(new kernel::activity::IoImpl());
+}
+
 Io::Io(sg_storage_t storage, sg_size_t size, OpType type) : storage_(storage), size_(size), type_(type)
 {
   Activity::set_remaining(size_);
@@ -22,12 +29,21 @@ Io::Io(sg_storage_t storage, sg_size_t size, OpType type) : storage_(storage), s
 Io* Io::start()
 {
   kernel::actor::simcall([this] {
-    (*boost::static_pointer_cast<kernel::activity::IoImpl>(pimpl_))
-        .set_name(name_)
-        .set_storage(storage_->get_impl())
-        .set_size(size_)
-        .set_type(type_)
-        .start();
+    if (storage_) {
+      (*boost::static_pointer_cast<kernel::activity::IoImpl>(pimpl_))
+          .set_name(name_)
+          .set_storage(storage_->get_impl())
+          .set_size(size_)
+          .set_type(type_)
+          .start();
+    } else {
+      (*boost::static_pointer_cast<kernel::activity::IoImpl>(pimpl_))
+          .set_name(name_)
+          .set_disk(disk_->get_impl())
+          .set_size(size_)
+          .set_type(type_)
+          .start();
+    }
   });
   state_ = State::STARTED;
   return this;
index 4fecbd4..bb48a1b 100644 (file)
@@ -83,15 +83,6 @@ bool Link::is_on() const
   return this->pimpl_->is_on();
 }
 
-void* Link::get_data()
-{
-  return this->pimpl_->get_data();
-}
-void Link::set_data(void* d)
-{
-  simgrid::kernel::actor::simcall([this, d]() { this->pimpl_->set_data(d); });
-}
-
 void Link::set_state_profile(kernel::profile::Profile* profile)
 {
   simgrid::kernel::actor::simcall([this, profile]() { this->pimpl_->set_state_profile(profile); });
index 1bf0f9f..2acb020 100644 (file)
@@ -171,8 +171,20 @@ static void _sg_cfg_cb__optimization_mode(const std::string& value)
   find_model_description(surf_optimization_mode_description, value);
 }
 
+static void _sg_cfg_cb__disk_model(const std::string& value)
+{
+  xbt_assert(_sg_cfg_init_status < 2, "Cannot change the model after the initialization");
+
+  if (value == "help") {
+    model_help("disk", surf_disk_model_description);
+    exit(0);
+  }
+
+  find_model_description(surf_disk_model_description, value);
+}
+
 /* callback of the cpu/model variable */
-static void _sg_cfg_cb__storage_mode(const std::string& value)
+static void _sg_cfg_cb__storage_model(const std::string& value)
 {
   xbt_assert(_sg_cfg_init_status < 2, "Cannot change the model after the initialization");
 
@@ -243,7 +255,10 @@ void sg_config_init(int *argc, char **argv)
   declare_model_flag("cpu/model", "Cas01", &_sg_cfg_cb__cpu_model, surf_cpu_model_description, "model",
                      "The model to use for the CPU");
 
-  declare_model_flag("storage/model", "default", &_sg_cfg_cb__storage_mode, surf_storage_model_description, "model",
+  declare_model_flag("disk/model", "default", &_sg_cfg_cb__disk_model, surf_disk_model_description, "model",
+                     "The model to use for the disk");
+
+  declare_model_flag("storage/model", "default", &_sg_cfg_cb__storage_model, surf_storage_model_description, "model",
                      "The model to use for the storage");
 
   declare_model_flag("network/model", "LV08", &_sg_cfg_cb__network_model, surf_network_model_description, "model",
index 30f3d47..4028e9a 100644 (file)
@@ -238,7 +238,7 @@ void SIMIX_global_init(int *argc, char **argv)
 #endif
     /* register a function to be called by SURF after the environment creation */
     sg_platf_init();
-    simgrid::s4u::on_platform_created.connect(surf_presolve);
+    simgrid::s4u::Engine::on_platform_created.connect(surf_presolve);
 
     simgrid::s4u::Storage::on_creation.connect([](simgrid::s4u::Storage const& storage) {
       sg_storage_t s = simgrid::s4u::Storage::by_name(storage.get_name());
@@ -522,10 +522,10 @@ void SIMIX_run()
       XBT_CRITICAL("Oops! Deadlock or code not perfectly clean.");
     }
     SIMIX_display_process_status();
-    simgrid::s4u::on_deadlock();
+    simgrid::s4u::Engine::on_deadlock();
     xbt_abort();
   }
-  simgrid::s4u::on_simulation_end();
+  simgrid::s4u::Engine::on_simulation_end();
 }
 
 double SIMIX_timer_next()
index 873537a..8a44988 100644 (file)
@@ -39,12 +39,12 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi, smpi, "Logging specific to SMPI ,(mpi)
       char error_string[MPI_MAX_ERROR_STRING];                                                                         \
       int error_size;                                                                                                  \
       PMPI_Error_string(ret, error_string, &error_size);                                                               \
-      if(errhan==nullptr || errhan->errhandler()==MPI_ERRORS_RETURN)                                                                         \
+      if ((errhan) == nullptr || (errhan)->errhandler() == MPI_ERRORS_RETURN)                                          \
         XBT_WARN("%s - returned %.*s instead of MPI_SUCCESS", __func__, error_size, error_string);                     \
-      else if(errhan->errhandler()==MPI_ERRORS_ARE_FATAL)                                                                 \
+      else if ((errhan)->errhandler() == MPI_ERRORS_ARE_FATAL)                                                         \
         xbt_die("%s - returned %.*s instead of MPI_SUCCESS", __func__, error_size, error_string);                      \
       else                                                                                                             \
-        errhan->errhandler()->call(errhan, ret);                                                                \
+        (errhan)->errhandler()->call((errhan), ret);                                                                   \
       MC_assert(not MC_is_active()); /* Only fail in MC mode */                                                        \
     }                                                                                                                  \
     XBT_VERB("SMPI - Leaving %s", __func__);                                                                           \
@@ -92,6 +92,10 @@ WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Attr_get,(MPI_Comm comm, int keyval, v
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Attr_put,(MPI_Comm comm, int keyval, void* attr_value) ,(comm, keyval, attr_value))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Barrier,(MPI_Comm comm),(comm))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Bcast,(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm),(buf, count, datatype, root, comm))
+WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Bsend_init,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request),(buf, count, datatype, dest, tag, comm, request))
+WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Bsend,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) ,(buf, count, datatype, dest, tag, comm))
+WRAPPED_PMPI_CALL(int,MPI_Buffer_attach,(void* buffer, int size) ,(buffer, size))
+WRAPPED_PMPI_CALL(int,MPI_Buffer_detach,(void* buffer, int* size) ,(buffer, size))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Cart_coords,(MPI_Comm comm, int rank, int maxdims, int* coords) ,(comm, rank, maxdims, coords))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Cart_create,(MPI_Comm comm, int ndims, const int* dims, const int* periods, int reorder, MPI_Comm* comm_cart) ,(comm, ndims, dims, periods, reorder, comm_cart))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Cartdim_get,(MPI_Comm comm, int* ndims) ,(comm, ndims))
@@ -195,6 +199,7 @@ WRAPPED_PMPI_CALL(int,MPI_Init_thread,(int *argc, char ***argv, int required, in
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Iprobe,(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status) ,(source, tag, comm, flag, status))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Irecv,(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request * request),(buf, count, datatype, src, tag, comm, request))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Isend,(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request * request),(buf, count, datatype, dst, tag, comm, request))
+WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Ibsend,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) ,(buf, count, datatype, dest, tag, comm, request))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Issend,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) ,(buf, count, datatype, dest, tag, comm, request))
 WRAPPED_PMPI_CALL_ERRHANDLER_COMM(int,MPI_Irsend,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request),(buf, count, datatype, dest, tag, comm, request))
 WRAPPED_PMPI_CALL(int,MPI_Is_thread_main,(int *flag),(flag))
@@ -369,10 +374,6 @@ WRAPPED_PMPI_CALL_ERRHANDLER_FILE(int, MPI_File_get_errhandler,( MPI_File fh, MP
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Add_error_class,( int *errorclass),( errorclass))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Add_error_code,(int errorclass, int *errorcode),(errorclass, errorcode))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Add_error_string,( int errorcode, char *string),(errorcode, string))
-UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Bsend_init,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request),(buf, count, datatype, dest, tag, comm, request))
-UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Bsend,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) ,(buf, count, datatype, dest, tag, comm))
-UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Buffer_attach,(void* buffer, int size) ,(buffer, size))
-UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Buffer_detach,(void* buffer, int* size) ,(buffer, size))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Cart_map,(MPI_Comm comm_old, int ndims, const int* dims, const int* periods, int* newrank) ,(comm_old, ndims, dims, periods, newrank))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Close_port,(const char *port_name),( port_name))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Comm_accept,(const char *port_name, MPI_Info info, int root, MPI_Comm comm, MPI_Comm *newcomm),( port_name, info, root, comm, newcomm))
@@ -424,7 +425,6 @@ UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Graph_get,(MPI_Comm comm, int maxindex,
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Graph_map,(MPI_Comm comm_old, int nnodes, const int* index, const int* edges, int* newrank) ,(comm_old, nnodes, index, edges, newrank))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Graph_neighbors_count,(MPI_Comm comm, int rank, int* nneighbors) ,(comm, rank, nneighbors))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Graph_neighbors,(MPI_Comm comm, int rank, int maxneighbors, int* neighbors) ,(comm, rank, maxneighbors, neighbors))
-UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Ibsend,(const void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request* request) ,(buf, count, datatype, dest, tag, comm, request))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Intercomm_create,(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag,MPI_Comm* comm_out) ,(local_comm, local_leader, peer_comm, remote_leader, tag, comm_out))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Intercomm_merge,(MPI_Comm comm, int high, MPI_Comm* comm_out) ,(comm, high, comm_out))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Lookup_name,( char *service_name, MPI_Info info, char *port_name),( service_name, info, port_name))
index 2b8f28e..7b40665 100644 (file)
@@ -244,3 +244,18 @@ MPI_Fint PMPI_Errhandler_c2f(MPI_Errhandler errhan){
     return -1;
   return errhan->c2f();
 }
+
+int PMPI_Buffer_attach(void *buf, int size){
+  if(buf==nullptr)
+    return MPI_ERR_BUFFER;
+  if(size<0)
+    return MPI_ERR_ARG;
+  smpi_process()->set_bsend_buffer(buf, size);
+  return MPI_SUCCESS;
+}
+
+int PMPI_Buffer_detach(void* buffer, int* size){
+  smpi_process()->bsend_buffer((void**)buffer, size);
+  smpi_process()->set_bsend_buffer(nullptr, 0);
+  return MPI_SUCCESS;
+}
index b487d2b..7f6f627 100644 (file)
@@ -16,7 +16,7 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
 #define CHECK_ARGS(test, errcode, ...)                                                                                 \
   if (test) {                                                                                                          \
     XBT_WARN(__VA_ARGS__);                                                                                             \
-    return errcode;                                                                                                    \
+    return (errcode);                                                                                                  \
   }
 
 /* PMPI User level calls */
index 41e1a38..3680ca9 100644 (file)
@@ -38,19 +38,36 @@ int PMPI_File_close(MPI_File *fh){
   smpi_bench_begin();
   return ret;
 }
-#define CHECK_FILE(fh) if(fh==MPI_FILE_NULL) return MPI_ERR_FILE;
-#define CHECK_BUFFER(buf, count)  if (buf==nullptr && count > 0) return MPI_ERR_BUFFER;
-#define CHECK_COUNT(count)  if (count < 0) return MPI_ERR_COUNT;
-#define CHECK_OFFSET(offset)  if (offset < 0) return MPI_ERR_DISP;
-#define CHECK_DATATYPE(datatype, count) if (datatype == MPI_DATATYPE_NULL && count > 0) return MPI_ERR_TYPE;
-#define CHECK_STATUS(status) if (status == nullptr) return MPI_ERR_ARG;
-#define CHECK_FLAGS(fh) if (fh->flags() & MPI_MODE_SEQUENTIAL) return MPI_ERR_AMODE;
-#define CHECK_RDONLY(fh) if (fh->flags() & MPI_MODE_RDONLY ) return MPI_ERR_AMODE;
-
-#define PASS_ZEROCOUNT(count) if (count == 0) {\
-status->count=0;\
-return MPI_SUCCESS;\
-}
+#define CHECK_FILE(fh)                                                                                                 \
+  if ((fh) == MPI_FILE_NULL)                                                                                           \
+    return MPI_ERR_FILE;
+#define CHECK_BUFFER(buf, count)                                                                                       \
+  if ((buf) == nullptr && (count) > 0)                                                                                 \
+    return MPI_ERR_BUFFER;
+#define CHECK_COUNT(count)                                                                                             \
+  if ((count) < 0)                                                                                                     \
+    return MPI_ERR_COUNT;
+#define CHECK_OFFSET(offset)                                                                                           \
+  if ((offset) < 0)                                                                                                    \
+    return MPI_ERR_DISP;
+#define CHECK_DATATYPE(datatype, count)                                                                                \
+  if ((datatype) == MPI_DATATYPE_NULL && (count) > 0)                                                                  \
+    return MPI_ERR_TYPE;
+#define CHECK_STATUS(status)                                                                                           \
+  if ((status) == nullptr)                                                                                             \
+    return MPI_ERR_ARG;
+#define CHECK_FLAGS(fh)                                                                                                \
+  if ((fh)->flags() & MPI_MODE_SEQUENTIAL)                                                                             \
+    return MPI_ERR_AMODE;
+#define CHECK_RDONLY(fh)                                                                                               \
+  if ((fh)->flags() & MPI_MODE_RDONLY)                                                                                 \
+    return MPI_ERR_AMODE;
+
+#define PASS_ZEROCOUNT(count)                                                                                          \
+  if ((count) == 0) {                                                                                                  \
+    status->count = 0;                                                                                                 \
+    return MPI_SUCCESS;                                                                                                \
+  }
 
 int PMPI_File_seek(MPI_File fh, MPI_Offset offset, int whence){
   CHECK_FILE(fh);
index 83b08ed..e038ca7 100644 (file)
@@ -59,7 +59,7 @@ int PMPI_Group_translate_ranks(MPI_Group group1, int n, const int *ranks1, MPI_G
       if(ranks1[i]==MPI_PROC_NULL){
         ranks2[i]=MPI_PROC_NULL;
       }else{
-        simgrid::s4u::ActorPtr actor = group1->actor(ranks1[i]);
+        simgrid::s4u::Actor* actor = group1->actor(ranks1[i]);
         ranks2[i] = group2->rank(actor);
       }
     }
index 571d4a2..af333ec 100644 (file)
@@ -175,6 +175,7 @@ int PMPI_Request_free(MPI_Request * request)
   smpi_bench_end();
   if (*request != MPI_REQUEST_NULL) {
     simgrid::smpi::Request::unref(request);
+    *request = MPI_REQUEST_NULL;
     retval = MPI_SUCCESS;
   }
   smpi_bench_begin();
@@ -405,6 +406,130 @@ int PMPI_Rsend(const void* buf, int count, MPI_Datatype datatype, int dst, int t
   return PMPI_Send(buf, count, datatype, dst, tag, comm);
 }
 
+int PMPI_Bsend(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
+{
+  int retval = 0;
+
+  smpi_bench_end();
+
+  if (comm == MPI_COMM_NULL) {
+    retval = MPI_ERR_COMM;
+  } else if (dst == MPI_PROC_NULL) {
+    retval = MPI_SUCCESS;
+  } else if (dst >= comm->group()->size() || dst <0){
+    retval = MPI_ERR_RANK;
+  } else if ((count < 0) || (buf == nullptr && count > 0)) {
+    retval = MPI_ERR_COUNT;
+  } else if (datatype==MPI_DATATYPE_NULL || not datatype->is_valid()) {
+    retval = MPI_ERR_TYPE;
+  } else if(tag < 0 && tag !=  MPI_ANY_TAG){
+    retval = MPI_ERR_TAG;
+  } else {
+    int my_proc_id         = simgrid::s4u::this_actor::get_pid();
+    int dst_traced         = getPid(comm, dst);
+    int bsend_buf_size = 0;
+    void* bsend_buf = nullptr;
+    smpi_process()->bsend_buffer(&bsend_buf, &bsend_buf_size);
+    int size = datatype->get_extent() * count;
+    if(bsend_buf==nullptr || bsend_buf_size < size + MPI_BSEND_OVERHEAD )
+      return MPI_ERR_BUFFER;
+    TRACE_smpi_comm_in(my_proc_id, __func__,
+                       new simgrid::instr::Pt2PtTIData("bsend", dst,
+                                                       datatype->is_replayable() ? count : count * datatype->size(),
+                                                       tag, simgrid::smpi::Datatype::encode(datatype)));
+    if (not TRACE_smpi_view_internals()) {
+      TRACE_smpi_send(my_proc_id, my_proc_id, dst_traced, tag, count * datatype->size());
+    }
+
+    simgrid::smpi::Request::bsend(buf, count, datatype, dst, tag, comm);
+    retval = MPI_SUCCESS;
+
+    TRACE_smpi_comm_out(my_proc_id);
+  }
+
+  smpi_bench_begin();
+  return retval;
+}
+
+int PMPI_Ibsend(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
+{
+  int retval = 0;
+
+  smpi_bench_end();
+  if (request == nullptr) {
+    retval = MPI_ERR_ARG;
+  } else if (comm == MPI_COMM_NULL) {
+    retval = MPI_ERR_COMM;
+  } else if (dst == MPI_PROC_NULL) {
+    *request = MPI_REQUEST_NULL;
+    retval = MPI_SUCCESS;
+  } else if (dst >= comm->group()->size() || dst <0){
+    retval = MPI_ERR_RANK;
+  } else if ((count < 0) || (buf==nullptr && count > 0)) {
+    retval = MPI_ERR_COUNT;
+  } else if (datatype==MPI_DATATYPE_NULL || not datatype->is_valid()) {
+    retval = MPI_ERR_TYPE;
+  } else if(tag<0 && tag !=  MPI_ANY_TAG){
+    retval = MPI_ERR_TAG;
+  } else {
+    int my_proc_id = simgrid::s4u::this_actor::get_pid();
+    int trace_dst = getPid(comm, dst);
+    int bsend_buf_size = 0;
+    void* bsend_buf = nullptr;
+    smpi_process()->bsend_buffer(&bsend_buf, &bsend_buf_size);
+    int size = datatype->get_extent() * count;
+    if(bsend_buf==nullptr || bsend_buf_size < size + MPI_BSEND_OVERHEAD )
+      return MPI_ERR_BUFFER;
+    TRACE_smpi_comm_in(my_proc_id, __func__,
+                       new simgrid::instr::Pt2PtTIData("ibsend", dst,
+                                                       datatype->is_replayable() ? count : count * datatype->size(),
+                                                       tag, simgrid::smpi::Datatype::encode(datatype)));
+
+    TRACE_smpi_send(my_proc_id, my_proc_id, trace_dst, tag, count * datatype->size());
+
+    *request = simgrid::smpi::Request::ibsend(buf, count, datatype, dst, tag, comm);
+    retval = MPI_SUCCESS;
+
+    TRACE_smpi_comm_out(my_proc_id);
+  }
+
+  smpi_bench_begin();
+  if (retval != MPI_SUCCESS && request!=nullptr)
+    *request = MPI_REQUEST_NULL;
+  return retval;
+}
+
+int PMPI_Bsend_init(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request* request)
+{
+
+  int retval = 0;
+
+  smpi_bench_end();
+  if (request == nullptr) {
+    retval = MPI_ERR_ARG;
+  } else if (comm == MPI_COMM_NULL) {
+    retval = MPI_ERR_COMM;
+  } else if (datatype==MPI_DATATYPE_NULL || not datatype->is_valid()) {
+    retval = MPI_ERR_TYPE;
+  } else if (dst == MPI_PROC_NULL) {
+    retval = MPI_SUCCESS;
+  } else {
+    int bsend_buf_size = 0;
+    void* bsend_buf = nullptr;
+    smpi_process()->bsend_buffer(&bsend_buf, &bsend_buf_size);
+    if( bsend_buf==nullptr || bsend_buf_size < datatype->get_extent() * count + MPI_BSEND_OVERHEAD ) {
+      retval = MPI_ERR_BUFFER;
+    } else {
+      *request = simgrid::smpi::Request::bsend_init(buf, count, datatype, dst, tag, comm);
+      retval   = MPI_SUCCESS;
+    }
+  }
+  smpi_bench_begin();
+  if (retval != MPI_SUCCESS && request != nullptr)
+    *request = MPI_REQUEST_NULL;
+  return retval;
+}
+
 int PMPI_Ssend(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm) {
   int retval = 0;
 
index 1791625..73a6556 100644 (file)
@@ -26,6 +26,7 @@ constexpr unsigned MPI_REQ_RMA            = 0x200;
 constexpr unsigned MPI_REQ_ACCUMULATE     = 0x400;
 constexpr unsigned MPI_REQ_GENERALIZED    = 0x800;
 constexpr unsigned MPI_REQ_COMPLETE       = 0x1000;
+constexpr unsigned MPI_REQ_BSEND          = 0x2000;
 
 enum class SmpiProcessState { UNINITIALIZED, INITIALIZING, INITIALIZED /*(=MPI_Init called)*/, FINALIZED };
 
@@ -58,10 +59,11 @@ extern XBT_PUBLIC int mpi_statuses_ignore_;
 #define FORT_ADDR(addr, val, val2)                                         \
   (((void *)(addr) == (void*) &(val2))                  \
    ? (val) : (void *)(addr))
-#define FORT_BOTTOM(addr)          FORT_ADDR(addr, MPI_BOTTOM, mpi_bottom_)
-#define FORT_IN_PLACE(addr)        FORT_ADDR(addr, MPI_IN_PLACE, mpi_in_place_)
-#define FORT_STATUS_IGNORE(addr)   static_cast<MPI_Status*>(FORT_ADDR(addr, MPI_STATUS_IGNORE, mpi_status_ignore_))
-#define FORT_STATUSES_IGNORE(addr) static_cast<MPI_Status*>(FORT_ADDR(addr, MPI_STATUSES_IGNORE, mpi_statuses_ignore_))
+#define FORT_BOTTOM(addr) FORT_ADDR((addr), MPI_BOTTOM, mpi_bottom_)
+#define FORT_IN_PLACE(addr) FORT_ADDR((addr), MPI_IN_PLACE, mpi_in_place_)
+#define FORT_STATUS_IGNORE(addr) static_cast<MPI_Status*>(FORT_ADDR((addr), MPI_STATUS_IGNORE, mpi_status_ignore_))
+#define FORT_STATUSES_IGNORE(addr)                                                                                     \
+  static_cast<MPI_Status*>(FORT_ADDR((addr), MPI_STATUSES_IGNORE, mpi_statuses_ignore_))
 
 extern XBT_PRIVATE MPI_Comm MPI_COMM_UNINITIALIZED;
 
@@ -75,8 +77,7 @@ XBT_PRIVATE simgrid::smpi::ActorExt* smpi_process();
 XBT_PRIVATE simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor);
 XBT_PRIVATE int smpi_get_universe_size();
 
-XBT_PRIVATE void smpi_deployment_register_process(const std::string& instance_id, int rank,
-                                                  simgrid::s4u::ActorPtr actor);
+XBT_PRIVATE void smpi_deployment_register_process(const std::string& instance_id, int rank, simgrid::s4u::Actor* actor);
 XBT_PRIVATE void smpi_deployment_unregister_process(const std::string& instance_id);
 
 XBT_PRIVATE MPI_Comm* smpi_deployment_comm_world(const std::string& instance_id);
index 6528fc9..de11f68 100644 (file)
@@ -28,7 +28,7 @@ class ActorExt {
   std::string instance_id_;
   bool replaying_ = false; /* is the process replaying a trace */
   smpi_trace_call_location_t trace_call_loc_;
-  s4u::ActorPtr actor_                           = nullptr;
+  s4u::Actor* actor_                             = nullptr;
   smpi_privatization_region_t privatized_region_ = nullptr;
 #ifdef __linux__
   int optind_                                     = 0; /*for getopt replacement */
@@ -37,14 +37,18 @@ class ActorExt {
 #endif
   std::string tracing_category_                  = "";
   MPI_Info info_env_;
-
+  void* bsend_buffer_ = nullptr; 
+  int bsend_buffer_size_ = 0; 
+  
 #if HAVE_PAPI
   /** Contains hardware data as read by PAPI **/
   int papi_event_set_;
   papi_counter_t papi_counter_data_;
 #endif
 public:
-  explicit ActorExt(s4u::ActorPtr actor);
+  static simgrid::xbt::Extension<simgrid::s4u::Actor, ActorExt> EXTENSION_ID;
+
+  explicit ActorExt(s4u::Actor* actor);
   ActorExt(const ActorExt&) = delete;
   ActorExt& operator=(const ActorExt&) = delete;
   ~ActorExt();
@@ -81,6 +85,8 @@ public:
   int get_optind();
   void set_optind(int optind);
   MPI_Info info_env();
+  void bsend_buffer(void** buf, int* size);
+  void set_bsend_buffer(void* buf, int size);
 };
 
 } // namespace smpi
index 509771e..455973c 100644 (file)
@@ -23,12 +23,14 @@ class F2C {
     // Beware of collisions if id in mpif.h is not unique
     static std::unordered_map<std::string, F2C*>* f2c_lookup_;
     static int f2c_id_;
+    int my_f2c_id_;
+
   protected:
     static std::unordered_map<std::string, F2C*>* f2c_lookup();
     static void set_f2c_lookup(std::unordered_map<std::string, F2C*>* map);
     static int f2c_id();
     static void f2c_id_increment();
-    int my_f2c_id_;
+
   public:
     char* get_my_key(char* key);
     static char* get_key(char* key, int id);
index e033edc..c0fa3fe 100644 (file)
@@ -20,8 +20,8 @@ class Group : public F2C{
   /* This is actually a map from int to int. We could use std::map here, but looking up a value there costs O(log(n)).
    * For a vector, this costs O(1). We hence go with the vector.
    */
-  std::vector<s4u::ActorPtr> rank_to_actor_map_;
-  std::map<s4u::ActorPtr, int> actor_to_rank_map_;
+  std::vector<s4u::Actor*> rank_to_actor_map_;
+  std::map<s4u::Actor*, int> actor_to_rank_map_;
   std::vector<int> index_to_rank_map_;
 
   int refcount_ = 1; /* refcount_: start > 0 so that this group never gets freed */
@@ -30,10 +30,10 @@ public:
   explicit Group(int size) : size_(size), rank_to_actor_map_(size, nullptr), index_to_rank_map_(size, MPI_UNDEFINED) {}
   explicit Group(Group* origin);
 
-  void set_mapping(s4u::ActorPtr actor, int rank);
+  void set_mapping(s4u::Actor* actor, int rank);
   int rank(int index);
-  s4u::ActorPtr actor(int rank);
-  int rank(const s4u::ActorPtr process);
+  s4u::Actor* actor(int rank);
+  int rank(s4u::Actor* process);
   void ref();
   static void unref(MPI_Group group);
   int size() { return size_; }
index d16e050..cc64583 100644 (file)
@@ -74,6 +74,7 @@ public:
   static void finish_wait(MPI_Request* request, MPI_Status* status);
   static void unref(MPI_Request* request);
   static int wait(MPI_Request* req, MPI_Status* status);
+  static MPI_Request bsend_init(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static MPI_Request send_init(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static MPI_Request isend_init(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static MPI_Request ssend_init(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
@@ -83,11 +84,13 @@ public:
   static MPI_Request rma_recv_init(void* buf, int count, MPI_Datatype datatype, int src, int dst, int tag,
                                    MPI_Comm comm, MPI_Op op);
   static MPI_Request irecv_init(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm);
+  static MPI_Request ibsend(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static MPI_Request isend(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static MPI_Request issend(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static MPI_Request irecv(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm);
 
   static void recv(void* buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status* status);
+  static void bsend(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static void send(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static void ssend(const void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
 
index 50112e0..30b9bf1 100644 (file)
@@ -151,7 +151,10 @@ void TRACE_smpi_init(int rank)
   if (not TRACE_smpi_is_enabled())
     return;
 
+  auto self = simgrid::s4u::Actor::self();
+
   TRACE_smpi_setup_container(rank, sg_host_self());
+  simgrid::s4u::this_actor::on_exit([self](bool) { smpi_container(self->get_pid())->remove_from_parent(); });
 #if HAVE_PAPI
   container_t container   = smpi_container(rank);
   papi_counter_t counters = smpi_process()->papi_counters();
@@ -166,14 +169,6 @@ void TRACE_smpi_init(int rank)
 #endif
 }
 
-void TRACE_smpi_finalize(int rank)
-{
-  if (not TRACE_smpi_is_enabled())
-    return;
-
-  smpi_container(rank)->remove_from_parent();
-}
-
 void TRACE_smpi_computing_init(int rank)
 {
  //first use, initialize the color in the trace
index c918f1a..eae4244 100644 (file)
@@ -19,9 +19,13 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_process, smpi, "Logging specific to SMPI (k
 
 namespace simgrid {
 namespace smpi {
+simgrid::xbt::Extension<simgrid::s4u::Actor, ActorExt> ActorExt::EXTENSION_ID;
 
-ActorExt::ActorExt(s4u::ActorPtr actor) : actor_(actor)
+ActorExt::ActorExt(s4u::Actor* actor) : actor_(actor)
 {
+  if (not simgrid::smpi::ActorExt::EXTENSION_ID.valid())
+    simgrid::smpi::ActorExt::EXTENSION_ID = simgrid::s4u::Actor::extension_create<simgrid::smpi::ActorExt>();
+
   mailbox_         = s4u::Mailbox::by_name("SMPI-" + std::to_string(actor_->get_pid()));
   mailbox_small_   = s4u::Mailbox::by_name("small-" + std::to_string(actor_->get_pid()));
   mailboxes_mutex_ = s4u::Mutex::create();
@@ -51,8 +55,6 @@ ActorExt::ActorExt(s4u::ActorPtr actor) : actor_(actor)
 
 ActorExt::~ActorExt()
 {
-  TRACE_smpi_finalize(actor_->get_pid());
-
   if (comm_self_ != MPI_COMM_NULL)
     simgrid::smpi::Comm::destroy(comm_self_);
   if (comm_intra_ != MPI_COMM_NULL)
@@ -211,7 +213,7 @@ void ActorExt::init()
   xbt_assert(smpi_get_universe_size() != 0, "SimGrid was not initialized properly before entering MPI_Init. "
                                             "Aborting, please check compilation process and use smpirun.");
 
-  simgrid::s4u::ActorPtr self = simgrid::s4u::Actor::self();
+  simgrid::s4u::Actor* self = simgrid::s4u::Actor::self();
   // cheinrich: I'm not sure what the impact of the SMPI_switch_data_segment on this call is. I moved
   // this up here so that I can set the privatized region before the switch.
   ActorExt* ext = smpi_process();
@@ -236,7 +238,7 @@ void ActorExt::init()
 
   // set the process attached to the mailbox
   ext->mailbox_small_->set_receiver(ext->actor_);
-  XBT_DEBUG("<%ld> SMPI process has been initialized: %p", ext->actor_->get_pid(), ext->actor_.get());
+  XBT_DEBUG("<%ld> SMPI process has been initialized: %p", ext->actor_->get_pid(), ext->actor_);
 }
 
 int ActorExt::get_optind()
@@ -249,5 +251,17 @@ void ActorExt::set_optind(int new_optind)
   optind_ = new_optind;
 }
 
+void ActorExt::bsend_buffer(void** buf, int* size)
+{
+  *buf  = bsend_buffer_;
+  *size = bsend_buffer_size_;
+}
+
+void ActorExt::set_bsend_buffer(void* buf, int size)
+{
+  bsend_buffer_     = buf;
+  bsend_buffer_size_= size;
+}
+
 } // namespace smpi
 } // namespace simgrid
index 54f42e1..5cf91eb 100644 (file)
@@ -34,7 +34,6 @@ public:
 
   const std::string name_;
   unsigned int size_;
-  std::vector<simgrid::s4u::ActorPtr> present_processes_;
   unsigned int finalized_ranks_ = 0;
   MPI_Comm comm_world_;
 };
@@ -61,22 +60,14 @@ void SMPI_app_instance_register(const char *name, xbt_main_func_t code, int num_
   if (code != nullptr) // When started with smpirun, we will not execute a function
     simgrid::s4u::Engine::get_instance()->register_function(name, code);
 
-  static bool already_called = false;
-  if (not already_called) {
-    already_called = true;
-    for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts())
-      host->extension_set(new simgrid::smpi::Host(host));
-  }
-
   Instance instance(std::string(name), num_processes, MPI_COMM_NULL);
 
   smpi_instances.insert(std::pair<std::string, Instance>(name, instance));
 }
 
-void smpi_deployment_register_process(const std::string& instance_id, int rank, simgrid::s4u::ActorPtr actor)
+void smpi_deployment_register_process(const std::string& instance_id, int rank, simgrid::s4u::Actor* actor)
 {
   Instance& instance = smpi_instances.at(instance_id);
-  instance.present_processes_.push_back(actor);
   instance.comm_world_->group()->set_mapping(actor, rank);
 }
 
@@ -86,7 +77,6 @@ void smpi_deployment_unregister_process(const std::string& instance_id)
   instance.finalized_ranks_++;
 
   if (instance.finalized_ranks_ == instance.size_) {
-    instance.present_processes_.clear();
     simgrid::smpi::Comm::destroy(instance.comm_world_);
     smpi_instances.erase(instance_id);
   }
@@ -106,7 +96,6 @@ void smpi_deployment_cleanup_instances(){
   for (auto const& item : smpi_instances) {
     XBT_CINFO(smpi, "Stalling SMPI instance: %s. Do all your MPI ranks call MPI_Finalize()?", item.first.c_str());
     Instance instance = item.second;
-    instance.present_processes_.clear();
     simgrid::smpi::Comm::destroy(instance.comm_world_);
   }
   smpi_instances.clear();
index 8144ad9..c1d5476 100644 (file)
@@ -82,7 +82,6 @@ std::map</* computation unit name */ std::string, papi_process_data> units2papi_
 
 std::unordered_map<std::string, double> location2speedup;
 
-static std::map</*process_id*/ simgrid::s4u::Actor const*, simgrid::smpi::ActorExt*> process_data;
 static int smpi_exit_status = 0;
 extern double smpi_total_benched_time;
 xbt_os_timer_t global_timer;
@@ -114,14 +113,14 @@ simgrid::smpi::ActorExt* smpi_process()
   if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...)
     return nullptr;
 
-  return process_data.at(me.get());
+  return me->extension<simgrid::smpi::ActorExt>();
 }
 
 simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor)
 {
   if (actor.get() == nullptr)
     return nullptr;
-  return process_data.at(actor.get());
+  return actor->extension<simgrid::smpi::ActorExt>();
 }
 
 MPI_Comm smpi_process_comm_self(){
@@ -620,10 +619,11 @@ int smpi_main(const char* executable, int argc, char* argv[])
   TRACE_global_init();
   SIMIX_global_init(&argc, argv);
 
+  auto engine              = simgrid::s4u::Engine::get_instance();
   SMPI_switch_data_segment = &smpi_switch_data_segment;
   sg_storage_file_system_init();
   // parse the platform file: get the host list
-  simgrid::s4u::Engine::get_instance()->load_platform(argv[1]);
+  engine->load_platform(argv[1]);
   SIMIX_comm_set_copy_data_callback(smpi_comm_copy_buffer_callback);
 
   smpi_init_options();
@@ -633,9 +633,16 @@ int smpi_main(const char* executable, int argc, char* argv[])
     smpi_init_privatization_no_dlopen(executable);
 
   SMPI_init();
-  simgrid::s4u::Engine::get_instance()->load_deployment(argv[2]);
-  SMPI_app_instance_register(smpi_default_instance_name.c_str(), nullptr,
-                             process_data.size()); // This call has a side effect on process_count...
+
+  /* This is a ... heavy way to count the MPI ranks */
+  int rank_counts = 0;
+  simgrid::s4u::Actor::on_creation.connect([&rank_counts](simgrid::s4u::Actor& actor) {
+    if (not actor.is_daemon())
+      rank_counts++;
+  });
+  engine->load_deployment(argv[2]);
+
+  SMPI_app_instance_register(smpi_default_instance_name.c_str(), nullptr, rank_counts);
   MPI_COMM_WORLD = *smpi_deployment_comm_world(smpi_default_instance_name);
 
   /* Clean IO before the run */
@@ -669,20 +676,13 @@ int smpi_main(const char* executable, int argc, char* argv[])
 // Called either directly from the user code, or from the code called by smpirun
 void SMPI_init(){
   simgrid::s4u::Actor::on_creation.connect([](simgrid::s4u::Actor& actor) {
-    if (not actor.is_daemon()) {
-      process_data.insert({&actor, new simgrid::smpi::ActorExt(&actor)});
-    }
-  });
-  simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::Actor const& actor) {
-    XBT_DEBUG("Delete the extension of actor %s", actor.get_cname());
-    auto it = process_data.find(&actor);
-    if (it != process_data.end()) {
-      delete it->second;
-      process_data.erase(it);
-    }
+    if (not actor.is_daemon())
+      actor.extension_set<simgrid::smpi::ActorExt>(new simgrid::smpi::ActorExt(&actor));
   });
   simgrid::s4u::Host::on_creation.connect(
       [](simgrid::s4u::Host& host) { host.extension_set(new simgrid::smpi::Host(&host)); });
+  for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts())
+    host->extension_set(new simgrid::smpi::Host(host));
 
   smpi_init_options();
   if (not MC_is_active()) {
index de20019..18cdacb 100644 (file)
@@ -107,7 +107,7 @@ static void* asan_safe_memcpy(void* dest, void* src, size_t n)
   return dest;
 }
 #else
-#define asan_safe_memcpy(dest, src, n) memcpy(dest, src, n)
+#define asan_safe_memcpy(dest, src, n) memcpy((dest), (src), (n))
 #endif
 
 /** Map a given SMPI privatization segment (make a SMPI process active)
index 1aad150..b901e96 100644 (file)
@@ -795,7 +795,6 @@ void smpi_replay_main(int rank, const char* trace_filename)
   smpi_process()->finalize();
 
   TRACE_smpi_comm_out(simgrid::s4u::this_actor::get_pid());
-  TRACE_smpi_finalize(simgrid::s4u::this_actor::get_pid());
 }
 
 /** @brief chain a replay initialization and a replay start */
index 8571f38..ed24882 100644 (file)
@@ -275,7 +275,7 @@ MPI_Comm Comm::split(int color, int key)
           group_root = group_out; /* Save root's group */
         }
         for (unsigned j = 0; j < rankmap.size(); j++) {
-          s4u::ActorPtr actor = group->actor(rankmap[j].second);
+          s4u::Actor* actor = group->actor(rankmap[j].second);
           group_out->set_mapping(actor, j);
         }
         MPI_Request* requests = xbt_new(MPI_Request, rankmap.size());
@@ -345,7 +345,7 @@ MPI_Comm Comm::find_intra_comm(int * leader){
   int min_index           = INT_MAX; // the minimum index will be the leader
   for (auto& actor : process_list) {
     int index = actor.get_pid();
-    if (this->group()->rank(actor.iface()) != MPI_UNDEFINED) { // Is this process in the current group?
+    if (this->group()->rank(actor.ciface()) != MPI_UNDEFINED) { // Is this process in the current group?
       intra_comm_size++;
       if (index < min_index)
         min_index = index;
@@ -355,8 +355,8 @@ MPI_Comm Comm::find_intra_comm(int * leader){
   MPI_Group group_intra = new  Group(intra_comm_size);
   int i = 0;
   for (auto& actor : process_list) {
-    if (this->group()->rank(actor.iface()) != MPI_UNDEFINED) {
-      group_intra->set_mapping(actor.iface(), i);
+    if (this->group()->rank(actor.ciface()) != MPI_UNDEFINED) {
+      group_intra->set_mapping(actor.ciface(), i);
       i++;
     }
   }
@@ -426,7 +426,7 @@ void Comm::init_smp(){
   if(MPI_COMM_WORLD!=MPI_COMM_UNINITIALIZED && this!=MPI_COMM_WORLD){
     //create leader_communicator
     for (i=0; i< leader_group_size;i++)
-      leaders_group->set_mapping(s4u::Actor::by_pid(leader_list[i]), i);
+      leaders_group->set_mapping(s4u::Actor::by_pid(leader_list[i]).get(), i);
     leader_comm = new  Comm(leaders_group, nullptr,1);
     this->set_leaders_comm(leader_comm);
     this->set_intra_comm(comm_intra);
@@ -434,7 +434,7 @@ void Comm::init_smp(){
     // create intracommunicator
   }else{
     for (i=0; i< leader_group_size;i++)
-      leaders_group->set_mapping(s4u::Actor::by_pid(leader_list[i]), i);
+      leaders_group->set_mapping(s4u::Actor::by_pid(leader_list[i]).get(), i);
 
     if(this->get_leaders_comm()==MPI_COMM_NULL){
       leader_comm = new  Comm(leaders_group, nullptr,1);
index a22b3d4..d4257b1 100644 (file)
@@ -18,18 +18,18 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_datatype, smpi, "Logging specific to SMPI (
 static std::unordered_map<std::string, simgrid::smpi::Datatype*> id2type_lookup;
 
 #define CREATE_MPI_DATATYPE(name, id, type)                                                                            \
-  static simgrid::smpi::Datatype _XBT_CONCAT(mpi_, name)((char*)_XBT_STRINGIFY(name), id, sizeof(type), /* size */     \
-                                                         0,                                             /* lb */       \
+  static simgrid::smpi::Datatype _XBT_CONCAT(mpi_, name)((char*)_XBT_STRINGIFY(name), (id), sizeof(type), /* size */   \
+                                                         0,                                               /* lb */     \
                                                          sizeof(type), /* ub = lb + size */                            \
                                                          DT_FLAG_BASIC /* flags */                                     \
                                                          );                                                            \
   const MPI_Datatype name = &_XBT_CONCAT(mpi_, name);
 
 #define CREATE_MPI_DATATYPE_NULL(name, id)                                                                             \
-  static simgrid::smpi::Datatype _XBT_CONCAT(mpi_, name)((char*)_XBT_STRINGIFY(name), id, 0, /* size */                \
-                                                         0,                                  /* lb */                  \
-                                                         0,                                  /* ub = lb + size */      \
-                                                         DT_FLAG_BASIC                       /* flags */               \
+  static simgrid::smpi::Datatype _XBT_CONCAT(mpi_, name)((char*)_XBT_STRINGIFY(name), (id), 0, /* size */              \
+                                                         0,                                    /* lb */                \
+                                                         0,                                    /* ub = lb + size */    \
+                                                         DT_FLAG_BASIC                         /* flags */             \
                                                          );                                                            \
   const MPI_Datatype name = &_XBT_CONCAT(mpi_, name);
 
index 68d86f8..cbd973a 100644 (file)
@@ -28,7 +28,7 @@ Group::Group(Group* origin)
   }
 }
 
-void Group::set_mapping(s4u::ActorPtr actor, int rank)
+void Group::set_mapping(s4u::Actor* actor, int rank)
 {
   if (0 <= rank && rank < size_) {
     int index                = actor->get_pid();
@@ -39,9 +39,7 @@ void Group::set_mapping(s4u::ActorPtr actor, int rank)
     }
 
     rank_to_actor_map_[rank] = actor;
-    if (actor != nullptr) {
-      actor_to_rank_map_.insert({actor, rank});
-    }
+    actor_to_rank_map_.insert({actor, rank});
   }
 }
 
@@ -56,7 +54,7 @@ int Group::rank(int index)
   return rank;
 }
 
-s4u::ActorPtr Group::actor(int rank)
+s4u::Actor* Group::actor(int rank)
 {
   if (0 <= rank && rank < size_)
     return rank_to_actor_map_[rank];
@@ -64,7 +62,7 @@ s4u::ActorPtr Group::actor(int rank)
     return nullptr;
 }
 
-int Group::rank(const s4u::ActorPtr actor)
+int Group::rank(s4u::Actor* actor)
 {
   auto iterator = actor_to_rank_map_.find(actor);
   return (iterator == actor_to_rank_map_.end()) ? MPI_UNDEFINED : (*iterator).second;
@@ -92,7 +90,7 @@ int Group::compare(MPI_Group group2)
     result = MPI_UNEQUAL;
   } else {
     for (int i = 0; i < size_; i++) {
-      s4u::ActorPtr actor = this->actor(i);
+      s4u::Actor* actor = this->actor(i);
       int rank = group2->rank(actor);
       if (rank == MPI_UNDEFINED) {
         result = MPI_UNEQUAL;
@@ -118,7 +116,7 @@ int Group::incl(int n, const int* ranks, MPI_Group* newgroup)
   } else {
     *newgroup = new Group(n);
     for (i = 0; i < n; i++) {
-      s4u::ActorPtr actor = this->actor(ranks[i]); // ranks[] was passed as a param!
+      s4u::Actor* actor = this->actor(ranks[i]); // ranks[] was passed as a param!
       (*newgroup)->set_mapping(actor, i);
     }
   }
@@ -130,7 +128,7 @@ int Group::group_union(MPI_Group group2, MPI_Group* newgroup)
   int size1 = size_;
   int size2 = group2->size();
   for (int i = 0; i < size2; i++) {
-    s4u::ActorPtr actor = group2->actor(i);
+    s4u::Actor* actor = group2->actor(i);
     int proc1 = this->rank(actor);
     if (proc1 == MPI_UNDEFINED) {
       size1++;
@@ -142,11 +140,11 @@ int Group::group_union(MPI_Group group2, MPI_Group* newgroup)
     *newgroup = new  Group(size1);
     size2 = this->size();
     for (int i = 0; i < size2; i++) {
-      s4u::ActorPtr actor1 = this->actor(i);
+      s4u::Actor* actor1 = this->actor(i);
       (*newgroup)->set_mapping(actor1, i);
     }
     for (int i = size2; i < size1; i++) {
-      s4u::ActorPtr actor = group2->actor(i - size2);
+      s4u::Actor* actor = group2->actor(i - size2);
       (*newgroup)->set_mapping(actor, i);
     }
   }
@@ -157,7 +155,7 @@ int Group::intersection(MPI_Group group2, MPI_Group* newgroup)
 {
   int size2 = group2->size();
   for (int i = 0; i < size2; i++) {
-    s4u::ActorPtr actor = group2->actor(i);
+    s4u::Actor* actor = group2->actor(i);
     int proc1 = this->rank(actor);
     if (proc1 == MPI_UNDEFINED) {
       size2--;
@@ -169,7 +167,7 @@ int Group::intersection(MPI_Group group2, MPI_Group* newgroup)
     *newgroup = new  Group(size2);
     int j=0;
     for (int i = 0; i < group2->size(); i++) {
-      s4u::ActorPtr actor = group2->actor(i);
+      s4u::Actor* actor = group2->actor(i);
       int proc1 = this->rank(actor);
       if (proc1 != MPI_UNDEFINED) {
         (*newgroup)->set_mapping(actor, j);
@@ -185,7 +183,7 @@ int Group::difference(MPI_Group group2, MPI_Group* newgroup)
   int newsize = size_;
   int size2 = size_;
   for (int i = 0; i < size2; i++) {
-    s4u::ActorPtr actor = this->actor(i);
+    s4u::Actor* actor = this->actor(i);
     int proc2 = group2->rank(actor);
     if (proc2 != MPI_UNDEFINED) {
       newsize--;
@@ -196,7 +194,7 @@ int Group::difference(MPI_Group group2, MPI_Group* newgroup)
   } else {
     *newgroup = new  Group(newsize);
     for (int i = 0; i < size2; i++) {
-      s4u::ActorPtr actor = this->actor(i);
+      s4u::Actor* actor = this->actor(i);
       int proc2 = group2->rank(actor);
       if (proc2 == MPI_UNDEFINED) {
         (*newgroup)->set_mapping(actor, i);
@@ -218,7 +216,7 @@ int Group::excl(int n, const int *ranks, MPI_Group * newgroup){
   int j = 0;
   for (int i = 0; i < oldsize; i++) {
     if(to_exclude[i]==0){
-      s4u::ActorPtr actor = this->actor(i);
+      s4u::Actor* actor = this->actor(i);
       (*newgroup)->set_mapping(actor, j);
       j++;
     }
@@ -257,7 +255,7 @@ int Group::range_incl(int n, int ranges[][3], MPI_Group * newgroup){
     for (int rank = ranges[i][0];                    /* First */
          rank >= 0 && rank < size_; /* Last */
          ) {
-      s4u::ActorPtr actor = this->actor(rank);
+      s4u::Actor* actor = this->actor(rank);
       (*newgroup)->set_mapping(actor, j);
       j++;
       if(rank == ranges[i][1]){/*already last ?*/
@@ -309,7 +307,7 @@ int Group::range_excl(int n, int ranges[][3], MPI_Group * newgroup){
         }
       }
       if(add==1){
-        s4u::ActorPtr actor = this->actor(oldrank);
+        s4u::Actor* actor = this->actor(oldrank);
         (*newgroup)->set_mapping(actor, newrank);
         newrank++;
       }
index 008839b..4a18f6e 100644 (file)
@@ -13,17 +13,27 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_op, smpi, "Logging specific to SMPI (op)");
 #define MAX_OP(a, b)  (b) = (a) < (b) ? (b) : (a)
 #define MIN_OP(a, b)  (b) = (a) < (b) ? (a) : (b)
 #define SUM_OP(a, b)  (b) += (a)
-#define SUM_OP_COMPLEX(a, b) {(b.value) += (a.value);(b.index) += (a.index);}
+#define SUM_OP_COMPLEX(a, b)                                                                                           \
+  {                                                                                                                    \
+    ((b).value) += ((a).value);                                                                                        \
+    ((b).index) += ((a).index);                                                                                        \
+  }
 #define PROD_OP(a, b) (b) *= (a)
-#define PROD_OP_COMPLEX(a, b) {(b.value) *= (a.value);(b.index) *= (a.index);}
+#define PROD_OP_COMPLEX(a, b)                                                                                          \
+  {                                                                                                                    \
+    ((b).value) *= ((a).value);                                                                                        \
+    ((b).index) *= ((a).index);                                                                                        \
+  }
 #define LAND_OP(a, b) (b) = (a) && (b)
 #define LOR_OP(a, b)  (b) = (a) || (b)
 #define LXOR_OP(a, b) (b) = (not(a) && (b)) || ((a) && not(b))
 #define BAND_OP(a, b) (b) &= (a)
 #define BOR_OP(a, b)  (b) |= (a)
 #define BXOR_OP(a, b) (b) ^= (a)
-#define MAXLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (b) : ((a.value) == (b.value) ? ((a.index) < (b.index) ? (a) : (b)) : (a))
-#define MINLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (a) : ((a.value) == (b.value) ? ((a.index) < (b.index) ? (a) : (b)) : (b))
+#define MAXLOC_OP(a, b)                                                                                                \
+  (b) = ((a).value) < ((b).value) ? (b) : (((a).value) == ((b).value) ? (((a).index) < ((b).index) ? (a) : (b)) : (a))
+#define MINLOC_OP(a, b)                                                                                                \
+  (b) = ((a).value) < ((b).value) ? (a) : (((a).value) == ((b).value) ? (((a).index) < ((b).index) ? (a) : (b)) : (b))
 
 #define APPLY_FUNC(a, b, length, type, func) \
 {                                          \
@@ -35,11 +45,10 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_op, smpi, "Logging specific to SMPI (op)");
   }                                        \
 }
 
-#define APPLY_OP_LOOP(dtype, type, op) \
-  if (*datatype == dtype) {\
-    APPLY_FUNC(a, b, length, type, op)\
-  } else \
-
+#define APPLY_OP_LOOP(dtype, type, op)                                                                                 \
+  if (*datatype == (dtype)) {                                                                                          \
+    APPLY_FUNC(a, b, length, type, op)                                                                                 \
+  } else
 
 #define APPLY_BASIC_OP_LOOP(op)\
 APPLY_OP_LOOP(MPI_CHAR, char,op)\
index bb5199b..c5e7c52 100644 (file)
@@ -170,6 +170,14 @@ void Request::print_request(const char *message)
 
 
 /* factories, to hide the internal flags from the caller */
+MPI_Request Request::bsend_init(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
+{
+
+  return new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
+                     comm->group()->actor(dst)->get_pid(), tag, comm,
+                     MPI_REQ_PERSISTENT | MPI_REQ_SEND | MPI_REQ_PREPARED | MPI_REQ_BSEND);
+}
+
 MPI_Request Request::send_init(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
 {
 
@@ -242,6 +250,16 @@ MPI_Request Request::irecv_init(void *buf, int count, MPI_Datatype datatype, int
                      MPI_REQ_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PREPARED);
 }
 
+MPI_Request Request::ibsend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
+{
+  MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
+  request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
+                        comm->group()->actor(dst)->get_pid(), tag, comm,
+                        MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND | MPI_REQ_BSEND);
+  request->start();
+  return request;
+}
+
 MPI_Request Request::isend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
 {
   MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
@@ -281,6 +299,17 @@ void Request::recv(void *buf, int count, MPI_Datatype datatype, int src, int tag
   request = nullptr;
 }
 
+void Request::bsend(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
+{
+  MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
+  request = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, simgrid::s4u::this_actor::get_pid(),
+                        comm->group()->actor(dst)->get_pid(), tag, comm, MPI_REQ_NON_PERSISTENT | MPI_REQ_SEND | MPI_REQ_BSEND);
+
+  request->start();
+  wait(&request, MPI_STATUS_IGNORE);
+  request = nullptr;
+}
+
 void Request::send(const void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
 {
   MPI_Request request = nullptr; /* MC needs the comm to be set to nullptr during the call */
@@ -407,7 +436,7 @@ void Request::start()
 
     void* buf = buf_;
     if ((flags_ & MPI_REQ_SSEND) == 0 &&
-        ((flags_ & MPI_REQ_RMA) != 0 ||
+        ((flags_ & MPI_REQ_RMA) != 0 || (flags_ & MPI_REQ_BSEND) != 0 ||
          static_cast<int>(size_) < simgrid::config::get_value<int>("smpi/send-is-detached-thresh"))) {
       void *oldbuf = nullptr;
       detached_    = true;
@@ -422,6 +451,8 @@ void Request::start()
             XBT_DEBUG("Privatization : We are sending from a zone inside global memory. Switch data segment ");
             smpi_switch_data_segment(simgrid::s4u::Actor::by_pid(src_));
           }
+          //we need this temporary buffer even for bsend, as it will be released in the copy callback and we don't have a way to differentiate it
+          //so actually ... don't use manually attached buffer space.
           buf = xbt_malloc(size_);
           memcpy(buf,oldbuf,size_);
           XBT_DEBUG("buf %p copied into %p",oldbuf,buf);
index e598461..c5817fe 100644 (file)
@@ -92,6 +92,9 @@ HostImpl::~HostImpl()
   for (auto const& arg : actors_at_boot_)
     delete arg;
   actors_at_boot_.clear();
+
+  for (auto const& d : disks_)
+    d->destroy();
 }
 
 /** Re-starts all the actors that are marked as restartable.
@@ -147,6 +150,32 @@ size_t HostImpl::get_actor_count()
 {
   return process_list_.size();
 }
+
+std::vector<s4u::Disk*> HostImpl::get_disks()
+{
+  std::vector<s4u::Disk*> disks;
+  for (auto const& d : disks_)
+    disks.push_back(&d->piface_);
+  return disks;
+}
+
+void HostImpl::add_disk(s4u::Disk* disk)
+{
+  disks_.push_back(disk->get_impl());
+}
+
+void HostImpl::remove_disk(const std::string& disk_name)
+{
+  auto position = disks_.begin();
+  for (auto const& d : disks_) {
+    if (d->get_name() == disk_name) {
+      disks_.erase(position);
+      break;
+    }
+    position++;
+  }
+}
+
 std::vector<const char*> HostImpl::get_attached_storages()
 {
   std::vector<const char*> storages;
index 628569b..6583e66 100644 (file)
@@ -7,6 +7,7 @@
 #define SURF_HOST_INTERFACE_HPP_
 
 #include "src/kernel/actor/ActorImpl.hpp"
+#include "src/kernel/resource/DiskImpl.hpp"
 #include "src/surf/PropertyHolder.hpp"
 #include "src/surf/StorageImpl.hpp"
 #include "src/surf/cpu_interface.hpp"
@@ -47,10 +48,16 @@ public:
   explicit HostImpl(s4u::Host* host);
   virtual ~HostImpl();
 
+  std::vector<s4u::Disk*> get_disks();
+  void add_disk(s4u::Disk* disk);
+  void remove_disk(const std::string& disk_name);
+
   /** @brief Get the vector of storages (by names) attached to the Host */
   virtual std::vector<const char*> get_attached_storages();
 
   std::map<std::string, kernel::resource::StorageImpl*> storage_;
+  std::vector<kernel::resource::DiskImpl*> disks_;
+
   s4u::Host* piface_ = nullptr;
 
   void turn_on();
diff --git a/src/surf/disk_s19.cpp b/src/surf/disk_s19.cpp
new file mode 100644 (file)
index 0000000..4198e10
--- /dev/null
@@ -0,0 +1,145 @@
+/* Copyright (c) 2013-2019. 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 "disk_s19.hpp"
+#include "simgrid/kernel/routing/NetPoint.hpp"
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/s4u/Host.hpp"
+#include "src/kernel/lmm/maxmin.hpp"
+#include "src/surf/xml/platf.hpp"
+#include "surf/surf.hpp"
+
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(disk_kernel);
+
+/*********
+ * Model *
+ *********/
+
+void surf_disk_model_init_default()
+{
+  surf_disk_model = new simgrid::kernel::resource::DiskS19Model();
+}
+
+namespace simgrid {
+namespace kernel {
+namespace resource {
+
+DiskS19Model::DiskS19Model()
+{
+  all_existing_models.push_back(this);
+}
+
+DiskImpl* DiskS19Model::createDisk(const std::string& id, double read_bw, double write_bw)
+{
+  XBT_DEBUG("SURF disk create resource\n\t\tid '%s'\n\t\tread_bw '%f'\n", id.c_str(), read_bw);
+
+  return new DiskS19(this, id, get_maxmin_system(), read_bw, write_bw);
+}
+
+double DiskS19Model::next_occuring_event(double now)
+{
+  return DiskModel::next_occuring_event_full(now);
+}
+
+void DiskS19Model::update_actions_state(double /*now*/, double delta)
+{
+  for (auto it = std::begin(*get_started_action_set()); it != std::end(*get_started_action_set());) {
+    auto& action = *it;
+    ++it; // increment iterator here since the following calls to action.finish() may invalidate it
+    action.update_remains(lrint(action.get_variable()->get_value() * delta));
+    action.update_max_duration(delta);
+
+    if (((action.get_remains_no_update() <= 0) && (action.get_variable()->get_penalty() > 0)) ||
+        ((action.get_max_duration() != NO_MAX_DURATION) && (action.get_max_duration() <= 0))) {
+      action.finish(Action::State::FINISHED);
+    }
+  }
+}
+
+/************
+ * Resource *
+ ************/
+
+DiskS19::DiskS19(DiskModel* model, const std::string& name, lmm::System* maxminSystem, double read_bw, double write_bw)
+    : DiskImpl(model, name, maxminSystem, read_bw, write_bw)
+{
+  XBT_DEBUG("Create resource with read_bw '%f' write_bw '%f'", read_bw, write_bw);
+}
+
+DiskAction* DiskS19::io_start(sg_size_t size, s4u::Io::OpType type)
+{
+  return new DiskS19Action(get_model(), size, not is_on(), this, type);
+}
+
+DiskAction* DiskS19::read(sg_size_t size)
+{
+  return new DiskS19Action(get_model(), size, not is_on(), this, s4u::Io::OpType::READ);
+}
+
+DiskAction* DiskS19::write(sg_size_t size)
+{
+  return new DiskS19Action(get_model(), size, not is_on(), this, s4u::Io::OpType::WRITE);
+}
+
+/**********
+ * Action *
+ **********/
+
+DiskS19Action::DiskS19Action(Model* model, double cost, bool failed, DiskImpl* disk, s4u::Io::OpType type)
+    : DiskAction(model, cost, failed, model->get_maxmin_system()->variable_new(this, 1.0, -1.0, 3), disk, type)
+{
+  XBT_IN("(%s,%g", disk->get_cname(), cost);
+
+  // Must be less than the max bandwidth for all actions
+  model->get_maxmin_system()->expand(disk->get_constraint(), get_variable(), 1.0);
+  switch (type) {
+    case s4u::Io::OpType::READ:
+      model->get_maxmin_system()->expand(disk->constraint_read_, get_variable(), 1.0);
+      break;
+    case s4u::Io::OpType::WRITE:
+      model->get_maxmin_system()->expand(disk->constraint_write_, get_variable(), 1.0);
+      break;
+    default:
+      THROW_UNIMPLEMENTED;
+  }
+  XBT_OUT();
+}
+
+void DiskS19Action::cancel()
+{
+  set_state(Action::State::FAILED);
+}
+
+void DiskS19Action::suspend()
+{
+  XBT_IN("(%p)", this);
+  if (is_running()) {
+    get_model()->get_maxmin_system()->update_variable_penalty(get_variable(), 0.0);
+    set_suspend_state(Action::SuspendStates::SUSPENDED);
+  }
+  XBT_OUT();
+}
+
+void DiskS19Action::resume()
+{
+  THROW_UNIMPLEMENTED;
+}
+
+void DiskS19Action::set_max_duration(double /*duration*/)
+{
+  THROW_UNIMPLEMENTED;
+}
+
+void DiskS19Action::set_sharing_penalty(double)
+{
+  THROW_UNIMPLEMENTED;
+}
+void DiskS19Action::update_remains_lazy(double /*now*/)
+{
+  THROW_IMPOSSIBLE;
+}
+} // namespace resource
+} // namespace kernel
+} // namespace simgrid
diff --git a/src/surf/disk_s19.hpp b/src/surf/disk_s19.hpp
new file mode 100644 (file)
index 0000000..5b537ef
--- /dev/null
@@ -0,0 +1,69 @@
+/* Copyright (c) 2013-2019. 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/base.h>
+
+#include "src/kernel/resource/DiskImpl.hpp"
+
+#ifndef DISK_S19_HPP_
+#define DISK_S19_HPP_
+
+namespace simgrid {
+namespace kernel {
+namespace resource {
+
+/***********
+ * Classes *
+ ***********/
+
+class XBT_PRIVATE DiskS19Model;
+class XBT_PRIVATE DiskS19;
+class XBT_PRIVATE DiskS19Action;
+
+/*********
+ * Model *
+ *********/
+
+class DiskS19Model : public DiskModel {
+public:
+  DiskS19Model();
+  DiskImpl* createDisk(const std::string& id, double read_bw, double write_bw) override;
+  double next_occuring_event(double now) override;
+  void update_actions_state(double now, double delta) override;
+};
+
+/************
+ * Resource *
+ ************/
+
+class DiskS19 : public DiskImpl {
+public:
+  DiskS19(DiskModel* model, const std::string& name, kernel::lmm::System* maxminSystem, double read_bw,
+          double write_bw);
+  virtual ~DiskS19() = default;
+  DiskAction* io_start(sg_size_t size, s4u::Io::OpType type) override;
+  DiskAction* read(sg_size_t size) override;
+  DiskAction* write(sg_size_t size) override;
+};
+
+/**********
+ * Action *
+ **********/
+
+class DiskS19Action : public DiskAction {
+public:
+  DiskS19Action(Model* model, double cost, bool failed, DiskImpl* disk, s4u::Io::OpType type);
+  void suspend() override;
+  void cancel() override;
+  void resume() override;
+  void set_max_duration(double duration) override;
+  void set_sharing_penalty(double sharing_penalty) override;
+  void update_remains_lazy(double now) override;
+};
+
+} // namespace resource
+} // namespace kernel
+} // namespace simgrid
+#endif /* DISK_S19_HPP_ */
index 7aa840b..955e6b8 100644 (file)
@@ -36,17 +36,19 @@ double HostCLM03Model::next_occuring_event(double now)
   double min_by_net =
       surf_network_model->next_occuring_event_is_idempotent() ? surf_network_model->next_occuring_event(now) : -1;
   double min_by_sto = surf_storage_model->next_occuring_event(now);
+  double min_by_dsk = surf_disk_model->next_occuring_event(now);
 
-  XBT_DEBUG("model %p, %s min_by_cpu %f, %s min_by_net %f, %s min_by_sto %f",
-      this, typeid(surf_cpu_model_pm).name(), min_by_cpu,
-      typeid(surf_network_model).name(), min_by_net,
-      typeid(surf_storage_model).name(), min_by_sto);
+  XBT_DEBUG("model %p, %s min_by_cpu %f, %s min_by_net %f, %s min_by_sto %f, %s min_by_dsk %f", this,
+            typeid(surf_cpu_model_pm).name(), min_by_cpu, typeid(surf_network_model).name(), min_by_net,
+            typeid(surf_storage_model).name(), min_by_sto, typeid(surf_disk_model).name(), min_by_dsk);
 
   double res = min_by_cpu;
   if (res < 0 || (min_by_net >= 0.0 && min_by_net < res))
     res = min_by_net;
   if (res < 0 || (min_by_sto >= 0.0 && min_by_sto < res))
     res = min_by_sto;
+  if (res < 0 || (min_by_dsk >= 0.0 && min_by_dsk < res))
+    res = min_by_dsk;
   return res;
 }
 
index 8ef0680..9945dbd 100644 (file)
@@ -239,25 +239,18 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz
   for (auto const& link : route) {
     // Handle WIFI links
     if (link->get_sharing_policy() == s4u::Link::SharingPolicy::WIFI) {
-      xbt_assert(!cfg_crosstraffic,
-                 "Cross-traffic is not yet supported when using WIFI. Please use --cfg=network/crosstraffic:0");
       NetworkWifiLink* wifi_link = static_cast<NetworkWifiLink*>(link);
 
       double src_rate = wifi_link->get_host_rate(src);
       double dst_rate = wifi_link->get_host_rate(dst);
-
-      // TODO: What do to when src and dst are on the same AP ? (for the moment we use src rate)
-      if (src_rate != -1 && dst_rate != -1) {
+      xbt_assert(
+          !(src_rate == -1 && dst_rate == -1),
+          "Some Stations are not associated to any Access Point. Make sure to call set_host_rate on all Stations.");
+      if (src_rate != -1)
         get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0 / src_rate);
-      } else {
-        xbt_assert(
-            !(src_rate == -1 && dst_rate == -1),
-            "Some Stations are not associated to any Access Point. Make sure to call set_host_rate on all Stations.");
-        if (src_rate != -1)
-          get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0 / src_rate);
-        else
-          get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0 / dst_rate);
-      }
+      else
+        get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0 / dst_rate);
+
     } else {
       get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0);
     }
@@ -265,8 +258,27 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz
 
   if (cfg_crosstraffic) {
     XBT_DEBUG("Crosstraffic active: adding backward flow using 5%% of the available bandwidth");
-    for (auto const& link : back_route)
-      get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), .05);
+    bool wifi_dst_assigned = false; // Used by wifi crosstraffic
+    for (auto const& link : back_route) {
+      if (link->get_sharing_policy() == s4u::Link::SharingPolicy::WIFI) {
+        NetworkWifiLink* wifi_link = static_cast<NetworkWifiLink*>(link);
+        /**
+         * For wifi links we should add 0.05/rate.
+         * However since we are using the "back_route" we should encounter in
+         * the first place the dst wifi link.
+         */
+        if (!wifi_dst_assigned && (wifi_link->get_host_rate(dst) != -1)) {
+          get_maxmin_system()->expand(link->get_constraint(), action->get_variable(),
+                                      .05 / wifi_link->get_host_rate(dst));
+          wifi_dst_assigned = true;
+        } else {
+          get_maxmin_system()->expand(link->get_constraint(), action->get_variable(),
+                                      .05 / wifi_link->get_host_rate(src));
+        }
+      } else {
+        get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), .05);
+      }
+    }
 
     // Change concurrency_share here, if you want that cross-traffic is included in the SURF concurrency
     // (You would also have to change simgrid::kernel::lmm::Element::get_concurrency())
index d112d2b..c473874 100644 (file)
@@ -109,7 +109,6 @@ public:
  */
 class LinkImpl : public Resource, public surf::PropertyHolder {
   bool currently_destroying_ = false;
-  void* userdata_            = nullptr;
 
 protected:
   LinkImpl(NetworkModel* model, const std::string& name, lmm::Constraint* constraint);
@@ -119,8 +118,6 @@ protected:
 
 public:
   void destroy(); // Must be called instead of the destructor
-  void* get_data() { return userdata_; }
-  void set_data(void* d) { userdata_ = d; }
 
   /** @brief Public interface */
   s4u::Link piface_;
index e176c81..d5a4ecc 100644 (file)
@@ -17,6 +17,8 @@
 #include <ns3/ipv4-address-helper.h>
 #include <ns3/packet-sink-helper.h>
 #include <ns3/point-to-point-helper.h>
+#include <ns3/application-container.h>
+#include <ns3/event-id.h>
 
 #include "network_ns3.hpp"
 #include "ns3/ns3_simulator.hpp"
@@ -39,6 +41,7 @@ std::vector<std::string> IPV4addr;
  *****************/
 
 extern std::map<std::string, SgFlow*> flow_from_sock;
+extern std::map<std::string, ns3::ApplicationContainer> sink_from_sock;
 
 static ns3::InternetStackHelper stack;
 static ns3::NodeContainer nodes;
@@ -165,7 +168,7 @@ NetworkNS3Model::NetworkNS3Model() : NetworkModel(Model::UpdateAlgo::FULL)
   });
   surf::on_cluster.connect(&clusterCreation_cb);
 
-  s4u::on_platform_created.connect(&postparse_cb);
+  s4u::Engine::on_platform_created.connect(&postparse_cb);
   s4u::NetZone::on_route_creation.connect(&routeCreation_cb);
 }
 
@@ -190,18 +193,26 @@ Action* NetworkNS3Model::communicate(s4u::Host* src, s4u::Host* dst, double size
 
 double NetworkNS3Model::next_occuring_event(double now)
 {
-  double time_to_next_flow_completion;
+  double time_to_next_flow_completion = 0.0;
   XBT_DEBUG("ns3_next_occuring_event");
 
   //get the first relevant value from the running_actions list
+
+  // If there is no comms in NS-3, then we do not move it forward.
+  // We will synchronize NS-3 with SimGrid when starting a new communication.
+  // (see NetworkNS3Action::NetworkNS3Action() for more details on this point)
   if (get_started_action_set()->empty() || now == 0.0)
     return -1.0;
 
-  do {
-    ns3_simulator(now);
-    time_to_next_flow_completion = ns3::Simulator::Now().GetSeconds() - surf_get_clock();
-  } while (double_equals(time_to_next_flow_completion, 0, sg_surf_precision));
-
+  XBT_DEBUG("doing a ns3 simulation for a duration of %f", now);
+  ns3_simulator(now);  
+  time_to_next_flow_completion = ns3::Simulator::Now().GetSeconds() - surf_get_clock();
+  // NS-3 stops as soon as a flow ends,
+  // but it does not process the other flows that may finish at the same (simulated) time.
+  // If another flow ends at the same time, time_to_next_flow_completion = 0
+  if(double_equals(time_to_next_flow_completion, 0, sg_surf_precision))
+    time_to_next_flow_completion = 0.0; 
   XBT_DEBUG("min       : %f", now);
   XBT_DEBUG("ns3  time : %f", ns3::Simulator::Now().GetSeconds());
   XBT_DEBUG("surf time : %f", surf_get_clock());
@@ -214,22 +225,19 @@ void NetworkNS3Model::update_actions_state(double now, double delta)
 {
   static std::vector<std::string> socket_to_destroy;
 
-  /* If there are no running flows, advance the ns-3 simulator and return */
-  if (get_started_action_set()->empty()) {
-
-    while(double_positive(now - ns3::Simulator::Now().GetSeconds(), sg_surf_precision))
-      ns3_simulator(now-ns3::Simulator::Now().GetSeconds());
-
-    return;
-  }
-
   std::string ns3_socket;
   for (const auto& elm : flow_from_sock) {
     ns3_socket                = elm.first;
     SgFlow* sgFlow            = elm.second;
     NetworkNS3Action * action = sgFlow->action_;
     XBT_DEBUG("Processing socket %p (action %p)",sgFlow,action);
-    action->set_remains(action->get_cost() - sgFlow->sent_bytes_);
+    // Because NS3 stops as soon as a flow is finished, the other flows that ends at the same time may remains in an inconsistant state
+    // (i.e. remains_ == 0 but finished_ == false).
+    // However, SimGrid considers sometimes that an action with remains_ == 0 is finished.
+    // Thus, to avoid inconsistencies between SimGrid and NS3, set remains to 0 only when the flow is finished in NS3
+    int remains = action->get_cost() - sgFlow->sent_bytes_;
+    if(remains > 0)
+      action->set_remains(remains);
 
     if (TRACE_is_enabled() && action->get_state() == kernel::resource::Action::State::STARTED) {
       double data_delta_sent = sgFlow->sent_bytes_ - action->last_sent_;
@@ -247,6 +255,7 @@ void NetworkNS3Model::update_actions_state(double now, double delta)
     if(sgFlow->finished_){
       socket_to_destroy.push_back(ns3_socket);
       XBT_DEBUG("Destroy socket %p of action %p", ns3_socket.c_str(), action);
+      action->set_remains(0);
       action->finish(kernel::resource::Action::State::FINISHED);
     } else {
       XBT_DEBUG("Socket %p sent %u bytes out of %u (%u remaining)", ns3_socket.c_str(), sgFlow->sent_bytes_,
@@ -263,6 +272,7 @@ void NetworkNS3Model::update_actions_state(double now, double delta)
     }
     delete flow;
     flow_from_sock.erase(ns3_socket);
+    sink_from_sock.erase(ns3_socket);
   }
 }
 
@@ -301,6 +311,15 @@ void LinkNS3::set_latency_profile(profile::Profile*)
 NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* src, s4u::Host* dst)
     : NetworkAction(model, totalBytes, false), src_(src), dst_(dst)
 {
+  
+  // If there is no other started actions, we need to move NS-3 forward to be sync with SimGrid
+  if (model->get_started_action_set()->size()==1){
+    while(double_positive(surf_get_clock() - ns3::Simulator::Now().GetSeconds(), sg_surf_precision)){
+      XBT_DEBUG("Synchronizing NS-3 (time %f) with SimGrid (time %f)", ns3::Simulator::Now().GetSeconds(), surf_get_clock());
+      ns3_simulator(surf_get_clock() - ns3::Simulator::Now().GetSeconds());
+    }
+  }
+
   XBT_DEBUG("Communicate from %s to %s", src->get_cname(), dst->get_cname());
 
   static int port_number = 1025; // Port number is limited from 1025 to 65 000
@@ -319,17 +338,22 @@ NetworkNS3Action::NetworkNS3Action(Model* model, double totalBytes, s4u::Host* s
 
   XBT_DEBUG("ns3: Create flow of %.0f Bytes from %u to %u with Interface %s", totalBytes, node1, node2, addr.c_str());
   ns3::PacketSinkHelper sink("ns3::TcpSocketFactory", ns3::InetSocketAddress(ns3::Ipv4Address::GetAny(), port_number));
-  sink.Install(dst_node);
+  ns3::ApplicationContainer apps = sink.Install(dst_node);
 
   ns3::Ptr<ns3::Socket> sock = ns3::Socket::CreateSocket(src_node, ns3::TcpSocketFactory::GetTypeId());
 
   flow_from_sock.insert({transform_socket_ptr(sock), new SgFlow(totalBytes, this)});
+  sink_from_sock.insert({transform_socket_ptr(sock), apps});
 
   sock->Bind(ns3::InetSocketAddress(port_number));
 
   ns3::Simulator::ScheduleNow(&start_flow, sock, addr.c_str(), port_number);
 
   port_number++;
+  if(port_number > 65000){
+    port_number = 1025;
+    XBT_WARN("Too many connections! Port number is saturated. Trying to use the oldest ports.");
+  }
   xbt_assert(port_number <= 65000, "Too many connections! Port number is saturated.");
 
   s4u::Link::on_communicate(*this, src, dst);
@@ -358,10 +382,16 @@ void NetworkNS3Action::update_remains_lazy(double /*now*/)
 
 void ns3_simulator(double maxSeconds)
 {
+  ns3::EventId id; 
   if (maxSeconds > 0.0) // If there is a maximum amount of time to run
-    ns3::Simulator::Stop(ns3::Seconds(maxSeconds));
+    id = ns3::Simulator::Schedule(ns3::Seconds(maxSeconds), &ns3::Simulator::Stop);
+
   XBT_DEBUG("Start simulator for at most %fs (current time: %f)", maxSeconds, surf_get_clock());
   ns3::Simulator::Run ();
+  XBT_DEBUG("Simulator stopped at %fs", ns3::Simulator::Now().GetSeconds());
+
+  if(maxSeconds > 0.0)
+    id.Cancel();
 }
 
 // initialize the ns-3 interface and environment
index 019ef94..72171b3 100644 (file)
@@ -9,10 +9,15 @@
 
 #include <ns3/ipv4-address-helper.h>
 #include <ns3/point-to-point-helper.h>
+#include <ns3/application-container.h>
+#include <ns3/ptr.h>
+#include <ns3/callback.h>
+#include <ns3/packet-sink.h>
 
 #include <algorithm>
 
 std::map<std::string, SgFlow*> flow_from_sock; // ns3::sock -> SgFlow
+std::map<std::string, ns3::ApplicationContainer> sink_from_sock; // ns3::sock -> ns3::PacketSink
 
 static void receive_callback(ns3::Ptr<ns3::Socket> socket);
 static void datasent_cb(ns3::Ptr<ns3::Socket> socket, uint32_t dataSent);
@@ -32,6 +37,12 @@ static SgFlow* getFlowFromSocket(ns3::Ptr<ns3::Socket> socket)
   return (it == flow_from_sock.end()) ? nullptr : it->second;
 }
 
+static ns3::ApplicationContainer* getSinkFromSocket(ns3::Ptr<ns3::Socket> socket)
+{
+  auto it = sink_from_sock.find(transform_socket_ptr(socket));
+  return (it == sink_from_sock.end()) ? nullptr : &(it->second);
+}
+
 static void receive_callback(ns3::Ptr<ns3::Socket> socket)
 {
   SgFlow* flow = getFlowFromSocket(socket);
@@ -41,14 +52,14 @@ static void receive_callback(ns3::Ptr<ns3::Socket> socket)
     flow->finished_ = true;
     XBT_DEBUG("recv_cb of F[%p, %p, %u]", flow, flow->action_, flow->total_bytes_);
     XBT_DEBUG("Stop simulator at %f seconds", ns3::Simulator::Now().GetSeconds());
-    ns3::Simulator::Stop(ns3::Seconds(0.0));
-    ns3::Simulator::Run();
+    ns3::Simulator::Stop();
   }
 }
 
 static void send_cb(ns3::Ptr<ns3::Socket> sock, uint32_t txSpace)
 {
   SgFlow* flow = getFlowFromSocket(sock);
+  ns3::ApplicationContainer* sink = getSinkFromSocket(sock);
   XBT_DEBUG("Asked to write on F[%p, total: %u, remain: %u]", flow, flow->total_bytes_, flow->remaining_);
 
   if (flow->remaining_ == 0) // all data was already buffered (and socket was already closed)
@@ -74,8 +85,18 @@ static void send_cb(ns3::Ptr<ns3::Socket> sock, uint32_t txSpace)
               flow->remaining_);
   }
 
-  if (flow->buffered_bytes_ >= flow->total_bytes_)
+  if (flow->buffered_bytes_ >= flow->total_bytes_){
+    XBT_DEBUG("Closing Sockets of flow %p", flow);
+    // Closing the sockets of the receiving application
+    ns3::Ptr<ns3::PacketSink> app = ns3::DynamicCast<ns3::PacketSink, ns3::Application>(sink->Get(0));
+    ns3::Ptr<ns3::Socket> listening_sock = app->GetListeningSocket();
+    listening_sock->Close();
+    listening_sock->SetRecvCallback(ns3::MakeNullCallback<void, ns3::Ptr<ns3::Socket>>());
+    for(ns3::Ptr<ns3::Socket> accepted_sock : app->GetAcceptedSockets())
+      accepted_sock->Close();
+    // Closing the socket of the sender
     sock->Close();
+  }
 }
 
 static void datasent_cb(ns3::Ptr<ns3::Socket> socket, uint32_t dataSent)
@@ -127,8 +148,6 @@ void start_flow(ns3::Ptr<ns3::Socket> sock, const char* to, uint16_t port_number
   // tell the tcp implementation to call send_cb again
   // if we blocked and new tx buffer space becomes available
   sock->SetSendCallback(MakeCallback(&send_cb));
-  // Notice when the send is over
-  sock->SetRecvCallback(MakeCallback(&receive_callback));
   // Notice when we actually sent some data (mostly for the TRACING module)
   sock->SetDataSentCallback(MakeCallback(&datasent_cb));
 
index 4201ba0..67a3538 100644 (file)
@@ -19,6 +19,7 @@
 #include "src/include/simgrid/sg_config.hpp"
 #include "src/include/surf/surf.hpp"
 #include "src/kernel/EngineImpl.hpp"
+#include "src/kernel/resource/DiskImpl.hpp"
 #include "src/kernel/resource/profile/Profile.hpp"
 #include "src/simix/smx_private.hpp"
 #include "src/surf/HostImpl.hpp"
@@ -51,13 +52,13 @@ static simgrid::kernel::routing::NetZoneImpl* routing_get_current()
 /** Module management function: creates all internal data structures */
 void sg_platf_init()
 {
-  simgrid::s4u::on_platform_created.connect(check_disk_attachment);
+  simgrid::s4u::Engine::on_platform_created.connect(check_disk_attachment);
 }
 
 /** Module management function: frees all internal data structures */
 void sg_platf_exit() {
   simgrid::surf::on_cluster.disconnect_slots();
-  simgrid::s4u::on_platform_created.disconnect_slots();
+  simgrid::s4u::Engine::on_platform_created.disconnect_slots();
 
   /* make sure that we will reinit the models while loading the platf once reinited */
   surf_parse_models_setup_already_called = 0;
@@ -80,6 +81,10 @@ void sg_platf_new_host(simgrid::kernel::routing::HostCreationArgs* args)
   host->pimpl_->storage_ = mount_list;
   mount_list.clear();
 
+  host->pimpl_->disks_ = std::move(args->disks);
+  for (auto d : host->pimpl_->disks_)
+    d->set_host(host);
+
   /* Change from the defaults */
   if (args->state_trace)
     host->pimpl_cpu->set_state_profile(args->state_trace);
@@ -331,6 +336,17 @@ void sg_platf_new_cabinet(simgrid::kernel::routing::CabinetCreationArgs* cabinet
   delete cabinet->radicals;
 }
 
+simgrid::kernel::resource::DiskImpl* sg_platf_new_disk(simgrid::kernel::routing::DiskCreationArgs* disk)
+{
+  simgrid::kernel::resource::DiskImpl* d = surf_disk_model->createDisk(disk->id, disk->read_bw, disk->write_bw);
+  if (disk->properties) {
+    d->set_properties(*disk->properties);
+    delete disk->properties;
+  }
+  simgrid::s4u::Disk::on_creation(*d->get_iface());
+  return d;
+}
+
 void sg_platf_new_storage(simgrid::kernel::routing::StorageCreationArgs* storage)
 {
   xbt_assert(std::find(known_storages.begin(), known_storages.end(), storage->id) == known_storages.end(),
@@ -502,6 +518,7 @@ static void surf_config_models_setup()
   std::string host_model_name    = simgrid::config::get_value<std::string>("host/model");
   std::string network_model_name = simgrid::config::get_value<std::string>("network/model");
   std::string cpu_model_name     = simgrid::config::get_value<std::string>("cpu/model");
+  std::string disk_model_name    = simgrid::config::get_value<std::string>("disk/model");
   std::string storage_model_name = simgrid::config::get_value<std::string>("storage/model");
 
   /* The compound host model is needed when using non-default net/cpu models */
@@ -530,6 +547,10 @@ static void surf_config_models_setup()
   XBT_DEBUG("Call vm_model_init");
   surf_vm_model_init_HL13();
 
+  XBT_DEBUG("Call disk_model_init");
+  int disk_id = find_model_description(surf_disk_model_description, disk_model_name);
+  surf_disk_model_description[disk_id].model_init_preparse();
+
   XBT_DEBUG("Call storage_model_init");
   int storage_id = find_model_description(surf_storage_model_description, storage_model_name);
   surf_storage_model_description[storage_id].model_init_preparse();
@@ -548,7 +569,7 @@ static void surf_config_models_setup()
 simgrid::kernel::routing::NetZoneImpl* sg_platf_new_Zone_begin(simgrid::kernel::routing::ZoneCreationArgs* zone)
 {
   if (not surf_parse_models_setup_already_called) {
-    simgrid::s4u::on_platform_creation();
+    simgrid::s4u::Engine::on_platform_creation();
 
     /* Initialize the surf models. That must be done after we got all config, and before we need the models.
      * That is, after the last <config> tag, if any, and before the first of cluster|peer|zone|trace|trace_connect
index b0a8280..f559bb2 100644 (file)
@@ -6,6 +6,7 @@
 #include "simgrid/s4u/Engine.hpp"
 #include "src/include/surf/surf.hpp"
 #include "src/instr/instr_private.hpp"
+#include "src/kernel/resource/DiskImpl.hpp"
 #include "src/kernel/resource/profile/FutureEvtSet.hpp"
 #include "src/plugins/vm/VirtualMachineImpl.hpp"
 
@@ -71,7 +72,7 @@ double surf_solve(double max_date)
 
   for (auto const& model : all_existing_models) {
     if (model != surf_host_model && model != surf_vm_model && model != surf_network_model &&
-        model != surf_storage_model) {
+        model != surf_storage_model && model != surf_disk_model) {
       double next_event_model = model->next_occuring_event(NOW);
       if ((time_delta < 0.0 || next_event_model < time_delta) && next_event_model >= 0.0)
         time_delta = next_event_model;
@@ -143,7 +144,7 @@ double surf_solve(double max_date)
   for (auto const& model : all_existing_models)
     model->update_actions_state(NOW, time_delta);
 
-  simgrid::s4u::on_time_advance(time_delta);
+  simgrid::s4u::Engine::on_time_advance(time_delta);
 
   TRACE_paje_dump_buffer(false);
 
index b657ce6..0b2ea3c 100644 (file)
@@ -12,6 +12,7 @@
 #include "src/simgrid/version.h"
 #include "src/surf/HostImpl.hpp"
 #include "src/surf/xml/platf.hpp"
+#include "src/xbt_modinter.h" /* whether initialization was already done */
 #include "surf/surf.hpp"
 #include "xbt/module.h"
 
@@ -111,6 +112,10 @@ const std::vector<surf_model_description_t> surf_optimization_mode_description =
     {"Full", "Full update of remaining and variables. Slow but may be useful when debugging.", nullptr},
 };
 
+const std::vector<surf_model_description_t> surf_disk_model_description = {
+    {"default", "Simplistic disk model.", &surf_disk_model_init_default},
+};
+
 const std::vector<surf_model_description_t> surf_storage_model_description = {
     {"default", "Simplistic storage model.", &surf_storage_model_init_default},
 };
@@ -287,12 +292,9 @@ void sg_version()
 
 void surf_init(int *argc, char **argv)
 {
-  if (USER_HOST_LEVEL != -1) // Already initialized
+  if (xbt_initialized > 0)
     return;
 
-  XBT_DEBUG("Create all Libs");
-  USER_HOST_LEVEL = simgrid::s4u::Host::extension_create(nullptr);
-
   xbt_init(argc, argv);
 
   sg_config_init(argc, argv);
index b9f2233..ca08c21 100644 (file)
@@ -173,6 +173,8 @@ XBT_PUBLIC void surf_host_model_init_ptask_L07();
  */
 XBT_PUBLIC void surf_storage_model_init_default();
 
+XBT_PUBLIC void surf_disk_model_init_default();
+
 /* --------------------
  *  Model Descriptions
  * -------------------- */
@@ -189,7 +191,7 @@ XBT_PUBLIC void model_help(const char* category, const std::vector<surf_model_de
 #define SIMGRID_REGISTER_PLUGIN(id, desc, init)                                                                        \
   static void XBT_ATTRIB_CONSTRUCTOR(800) _XBT_CONCAT3(simgrid_, id, _plugin_register)()                               \
   {                                                                                                                    \
-    simgrid_add_plugin_description(_XBT_STRINGIFY(id), desc, init);                                                    \
+    simgrid_add_plugin_description(_XBT_STRINGIFY(id), (desc), (init));                                                \
   }
 
 XBT_PUBLIC void simgrid_add_plugin_description(const char* name, const char* description, void_f_void_t init_fun);
@@ -203,6 +205,8 @@ XBT_PUBLIC_DATA const std::vector<surf_model_description_t> surf_optimization_mo
 XBT_PUBLIC_DATA const std::vector<surf_model_description_t> surf_cpu_model_description;
 /** @brief The list of all network models (pick one with --cfg=network/model) */
 XBT_PUBLIC_DATA const std::vector<surf_model_description_t> surf_network_model_description;
+/** @brief The list of all disk models (pick one with --cfg=disk/model) */
+XBT_PUBLIC_DATA const std::vector<surf_model_description_t> surf_disk_model_description;
 /** @brief The list of all storage models (pick one with --cfg=storage/model) */
 XBT_PUBLIC_DATA const std::vector<surf_model_description_t> surf_storage_model_description;
 /** @brief The list of all host models (pick one with --cfg=host/model:) */
index 09aaaad..679a312 100644 (file)
@@ -41,6 +41,7 @@ struct HostCreationArgs {
   profile::Profile* state_trace                            = nullptr;
   std::string coord                                        = "";
   std::unordered_map<std::string, std::string>* properties = nullptr;
+  std::vector<simgrid::kernel::resource::DiskImpl*> disks;
 };
 
 class HostLinkCreationArgs {
@@ -138,6 +139,14 @@ public:
   sg_size_t size;
 };
 
+class DiskCreationArgs {
+public:
+  std::string id;
+  std::unordered_map<std::string, std::string>* properties;
+  double read_bw;
+  double write_bw;
+};
+
 class MountCreationArgs {
 public:
   std::string storageId;
@@ -203,6 +212,9 @@ XBT_PUBLIC void sg_platf_new_bypassRoute(simgrid::kernel::routing::RouteCreation
 
 XBT_PUBLIC void sg_platf_new_trace(simgrid::kernel::routing::ProfileCreationArgs* trace);
 
+XBT_PUBLIC simgrid::kernel::resource::DiskImpl*
+sg_platf_new_disk(simgrid::kernel::routing::DiskCreationArgs* disk); // Add a disk to the current host
+
 XBT_PUBLIC void sg_platf_new_storage(simgrid::kernel::routing::StorageCreationArgs* storage); // Add a storage to the current Zone
 XBT_PUBLIC void sg_platf_new_storage_type(simgrid::kernel::routing::StorageTypeCreationArgs* storage_type);
 XBT_PUBLIC void sg_platf_new_mount(simgrid::kernel::routing::MountCreationArgs* mount);
index e5f1c15..86ab5cb 100644 (file)
@@ -28,8 +28,8 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_parse, surf, "Logging specific to the SURF
 
 static std::string surf_parsed_filename; // Currently parsed file (for the error messages)
 std::vector<simgrid::kernel::resource::LinkImpl*>
-    parsed_link_list; /* temporary store of current list link of a route */
-
+    parsed_link_list; /* temporary store of current link list of a route */
+std::vector<simgrid::kernel::resource::DiskImpl*> parsed_disk_list; /* temporary store of current disk list of a host */
 /*
  * Helping functions
  */
@@ -409,7 +409,7 @@ void STag_surfxml_platform() {
              surf_parsed_filename.c_str(), version);
 }
 void ETag_surfxml_platform(){
-  simgrid::s4u::on_platform_created();
+  simgrid::s4u::Engine::on_platform_created();
 }
 
 void STag_surfxml_host(){
@@ -458,14 +458,27 @@ void ETag_surfxml_host()    {
                          : nullptr;
   host.pstate      = surf_parse_get_int(A_surfxml_host_pstate);
   host.coord       = A_surfxml_host_coordinates;
+  host.disks.swap(parsed_disk_list);
 
   sg_platf_new_host(&host);
 }
 
 void STag_surfxml_disk() {
-  THROW_UNIMPLEMENTED;
+  ZONE_TAG = 0;
+  xbt_assert(current_property_set == nullptr,
+             "Someone forgot to reset the property set to nullptr in its closing tag (or XML malformed)");
 }
+
 void ETag_surfxml_disk() {
+  simgrid::kernel::routing::DiskCreationArgs disk;
+  disk.properties      = current_property_set;
+  current_property_set = nullptr;
+
+  disk.id       = A_surfxml_disk_id;
+  disk.read_bw  = surf_parse_get_bandwidth(A_surfxml_disk_read___bw, "read_bw of disk ", disk.id);
+  disk.write_bw = surf_parse_get_bandwidth(A_surfxml_disk_write___bw, "write_bw of disk ", disk.id);
+
+  parsed_disk_list.push_back(sg_platf_new_disk(&disk));
 }
 
 void STag_surfxml_host___link(){
index 94661db..c89f325 100644 (file)
@@ -140,7 +140,8 @@ void install_exception_handler()
 void xbt_throw_impossible(const char* file, int line, const char* func)
 {
   std::stringstream ss;
-  ss << file << ":" << line << ":" << func << ": The Impossible Did Happen (yet again). Please report this bug.";
+  ss << file << ":" << line << ":" << func
+     << ": The Impossible Did Happen (yet again). Please report this bug (after reading https://xkcd.com/2200 :)";
   throw simgrid::xbt::ImpossibleError(ss.str());
 }
 void xbt_throw_unimplemented(const char* file, int line, const char* func)
index 9e1c9b0..46fe161 100644 (file)
@@ -286,8 +286,8 @@ XBT_PUBLIC void* mmorecore(struct mdesc* mdp, ssize_t size);
  * in a model-checking enabled tree. Without this protection, our malloc
  * implementation will not like multi-threading AT ALL.
  */
-#define LOCK(mdp) pthread_mutex_lock(&mdp->mutex)
-#define UNLOCK(mdp) pthread_mutex_unlock(&mdp->mutex)
+#define LOCK(mdp) pthread_mutex_lock(&(mdp)->mutex)
+#define UNLOCK(mdp) pthread_mutex_unlock(&(mdp)->mutex)
 
 XBT_PRIVATE int malloc_use_mmalloc(void);
 
index daec92c..6a675dd 100644 (file)
@@ -40,32 +40,33 @@ static constexpr const char* ERRMSG =
     }                                                                   \
   } else (void)0
 
-#define show_it(data, letter)                                           \
-  if (1) {                                                              \
-    int len;                                                            \
-    int wd;                                                             \
-    if (length == -1) {                                                 \
-      wd = 0;                                                           \
-    } else {                                                            \
-      wd = length;                                                      \
-      length = -1;                                                      \
-    }                                                                   \
-    if (precision == -1) {                                              \
-      len = snprintf(p, rem_size, "%*" letter, wd, data);               \
-    } else {                                                            \
-      len = snprintf(p, rem_size, "%*.*" letter, wd, precision, data);  \
-      precision = -1;                                                   \
-    }                                                                   \
-    check_overflow(len);                                                \
-  } else (void)0
+#define show_it(data, letter)                                                                                          \
+  if (1) {                                                                                                             \
+    int len;                                                                                                           \
+    int wd;                                                                                                            \
+    if (length == -1) {                                                                                                \
+      wd = 0;                                                                                                          \
+    } else {                                                                                                           \
+      wd     = length;                                                                                                 \
+      length = -1;                                                                                                     \
+    }                                                                                                                  \
+    if (precision == -1) {                                                                                             \
+      len = snprintf(p, rem_size, "%*" letter, wd, (data));                                                            \
+    } else {                                                                                                           \
+      len       = snprintf(p, rem_size, "%*.*" letter, wd, precision, (data));                                         \
+      precision = -1;                                                                                                  \
+    }                                                                                                                  \
+    check_overflow(len);                                                                                               \
+  } else                                                                                                               \
+  (void)0
 
 #define show_string(data)                                               \
   if (1) {                                                              \
     const char *show_string_data = (data);                              \
     show_it(show_string_data ? show_string_data : "(null)", "s");       \
   } else (void)0
-#define show_int(data)    show_it(data, "d")
-#define show_double(data) show_it(data, "f")
+#define show_int(data) show_it((data), "d")
+#define show_double(data) show_it((data), "f")
 
 static int xbt_log_layout_format_doit(xbt_log_layout_t l, xbt_log_event_t ev, const char* msg_fmt)
 {
index d60ccb0..bfdf869 100644 (file)
@@ -116,14 +116,14 @@ static void xbt_postexit()
 /** @brief Initialize the xbt mechanisms. */
 void xbt_init(int *argc, char **argv)
 {
-  simgrid::xbt::install_exception_handler();
-
   xbt_initialized++;
   if (xbt_initialized > 1) {
     XBT_DEBUG("XBT has been initialized %d times.", xbt_initialized);
     return;
   }
 
+  simgrid::xbt::install_exception_handler();
+
   xbt_binary_name = argv[0];
   xbt_cmdline     = xbt_dynar_new(sizeof(char*), NULL);
   for (int i = 0; i < *argc; i++)
index 298dda1..a3127a0 100644 (file)
@@ -2,16 +2,16 @@
 
 $ ${bindir:=.}/io-file-remote ${platfdir:=.}/storage/remote_io.xml ${srcdir:=.}/io-file-remote_d.xml "--log=root.fmt:[%10.6r]%e(%i@%5h)%e%m%n"
 > [  0.000000] (0@     ) Init: 12/476824 MiB used/free on 'Disk1'
-> [  0.000000] (0@     ) Init: 2280/474556 MiB used/free on 'Disk2'
-> [  0.000000] (1@alice) Opened file 'c:\Windows\setupact.log'
+> [  0.000000] (0@     ) Init: 35/476801 MiB used/free on 'Disk2'
+> [  0.000000] (1@alice) Opened file '/tmp/doc/simgrid/examples/msg/chord/chord10k.xml'
 > [  0.000000] (1@alice) File Descriptor information:
->              Full path: 'c:\Windows\setupact.log'
->              Size: 101663
->              Mount point: 'c:'
+>              Full path: '/tmp/doc/simgrid/examples/msg/chord/chord10k.xml'
+>              Size: 1624671
+>              Mount point: '/tmp'
 >              Storage Id: 'Disk2'
 >              Storage Type: 'SATA-II_HDD'
 >              File Descriptor Id: 0
-> [  0.000000] (1@alice) Try to read 101663 from 'c:\Windows\setupact.log'
+> [  0.000000] (1@alice) Try to read 1624671 from '/tmp/doc/simgrid/examples/msg/chord/chord10k.xml'
 > [  0.000000] (2@  bob) Opened file '/scratch/lib/libsimgrid.so.3.6.2'
 > [  0.000000] (2@  bob) File Descriptor information:
 >              Full path: '/scratch/lib/libsimgrid.so.3.6.2'
@@ -30,23 +30,23 @@ $ ${bindir:=.}/io-file-remote ${platfdir:=.}/storage/remote_io.xml ${srcdir:=.}/
 >              Storage Type: 'SATA-II_HDD'
 >              File Descriptor Id: 0
 > [  0.000000] (3@ carl) Try to read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'
-> [  0.000000] (4@ dave) Opened file 'c:\Windows\bootstat.dat'
+> [  0.000000] (4@ dave) Opened file '/tmp/doc/simgrid/examples/simdag/dax/Montage_50.xml'
 > [  0.000000] (4@ dave) File Descriptor information:
->              Full path: 'c:\Windows\bootstat.dat'
->              Size: 67584
->              Mount point: 'c:'
+>              Full path: '/tmp/doc/simgrid/examples/simdag/dax/Montage_50.xml'
+>              Size: 48868
+>              Mount point: '/tmp'
 >              Storage Id: 'Disk2'
 >              Storage Type: 'SATA-II_HDD'
 >              File Descriptor Id: 0
-> [  0.000000] (4@ dave) Try to read 67584 from 'c:\Windows\bootstat.dat'
-> [  0.001469] (4@ dave) Have read 67584 from 'c:\Windows\bootstat.dat'. Offset is now at: 67584
-> [  0.001469] (4@ dave) Seek back to the begining of the stream...
-> [  0.001469] (4@ dave) Offset is now at: 0
-> [  0.001469] (4@ dave) Opened file 'c:\Windows\Professional.xml'
-> [  0.001469] (4@ dave) Try to write 31 MiB to 'c:\Windows\Professional.xml'
-> [  0.003741] (1@alice) Have read 101663 from 'c:\Windows\setupact.log'. Offset is now at: 101663
-> [  0.003741] (1@alice) Seek back to the begining of the stream...
-> [  0.003741] (1@alice) Offset is now at: 0
+> [  0.000000] (4@ dave) Try to read 48868 from '/tmp/doc/simgrid/examples/simdag/dax/Montage_50.xml'
+> [  0.001062] (4@ dave) Have read 48868 from '/tmp/doc/simgrid/examples/simdag/dax/Montage_50.xml'. Offset is now at: 48868
+> [  0.001062] (4@ dave) Seek back to the begining of the stream...
+> [  0.001062] (4@ dave) Offset is now at: 0
+> [  0.001062] (4@ dave) Opened file '/tmp/doc/simgrid/examples/simdag/scheduling/Montage_25.xml'
+> [  0.001062] (4@ dave) Try to write 22 MiB to '/tmp/doc/simgrid/examples/simdag/scheduling/Montage_25.xml'
+> [  0.050039] (1@alice) Have read 1624671 from '/tmp/doc/simgrid/examples/msg/chord/chord10k.xml'. Offset is now at: 1624671
+> [  0.050039] (1@alice) Seek back to the begining of the stream...
+> [  0.050039] (1@alice) Offset is now at: 0
 > [  0.276315] (3@ carl) Have read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'. Offset is now at: 12710497
 > [  0.276315] (3@ carl) Seek back to the begining of the stream...
 > [  0.276315] (3@ carl) Offset is now at: 0
@@ -55,10 +55,10 @@ $ ${bindir:=.}/io-file-remote ${platfdir:=.}/storage/remote_io.xml ${srcdir:=.}/
 > [  0.387036] (2@  bob) Offset is now at: 0
 > [  0.387036] (2@  bob) Opened file '/scratch/doc/simgrid/examples/platforms/g5k.xml'
 > [  0.387036] (2@  bob) Try to write 16 MiB to '/scratch/doc/simgrid/examples/platforms/g5k.xml'
-> [  0.528211] (4@ dave) Have written 32646144 bytes to 'c:\Windows\Professional.xml'.
-> [  0.528211] (4@ dave) Move 'c:\Windows\Professional.xml' (of size 32646144) from 'dave' to 'carl'
+> [  0.391211] (4@ dave) Have written 23641088 bytes to '/tmp/doc/simgrid/examples/simdag/scheduling/Montage_25.xml'.
+> [  0.391211] (4@ dave) Move '/tmp/doc/simgrid/examples/simdag/scheduling/Montage_25.xml' (of size 23641088) from 'dave' to 'carl'
 > [  0.819921] (2@  bob) Have written 17436672 bytes to '/scratch/doc/simgrid/examples/platforms/g5k.xml'.
 > [  0.819921] (2@  bob) Copy '/scratch/doc/simgrid/examples/platforms/g5k.xml' (of size 17436672) from 'bob' to 'alice'
-> [  1.843969] (0@     ) End: 60/476776 MiB used/free on 'Disk1'
-> [  1.843969] (0@     ) End: 2297/474539 MiB used/free on 'Disk2'
-> [  1.843969] (0@     ) Simulation time 1.84397
+> [  1.598229] (0@     ) End: 51/476785 MiB used/free on 'Disk1'
+> [  1.598229] (0@     ) End: 51/476785 MiB used/free on 'Disk2'
+> [  1.598229] (0@     ) Simulation time 1.59823
index 3b3f1ab..1200d95 100644 (file)
@@ -2,23 +2,23 @@
 <!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
 <platform version="4.1">
   <actor host="alice" function="host">
-    <argument value = "c:\Windows\setupact.log"/>
+    <argument value = "/tmp/doc/simgrid/examples/msg/chord/chord10k.xml"/>
   </actor>
   <actor host="bob" function="host">
     <argument value = "/scratch/lib/libsimgrid.so.3.6.2"/>
     <argument value = "/scratch/doc/simgrid/examples/platforms/g5k.xml"/>
     <argument value = "alice"/>
-    <argument value = "c:\Windows\Platforms\g5k.xml"/>
+    <argument value = "/tmp/doc/simgrid/examples/g5k_2.xml"/>
     <argument value = "0"/>
   </actor>
   <actor host="carl" function="host">
     <argument value = "/scratch/lib/libsimgrid.so.3.6.2"/>
   </actor>
   <actor host="dave" function="host">
-    <argument value = "c:\Windows\bootstat.dat"/>
-    <argument value = "c:\Windows\Professional.xml"/>
+    <argument value = "/tmp/doc/simgrid/examples/simdag/dax/Montage_50.xml"/>
+    <argument value = "/tmp/doc/simgrid/examples/simdag/scheduling/Montage_25.xml"/>
     <argument value = "carl"/>
-    <argument value = "/scratch/mailbox/Professional.xml"/>
+    <argument value = "/scratch/doc/simgrid/examples/simdag/dax/Montage_25.xml"/>
     <argument value = "1"/>
   </actor>
 </platform>
index 5910d5b..a2feefc 100644 (file)
@@ -20,7 +20,7 @@ static int host(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
 
   switch (MSG_process_self_PID()) {
     case 1:
-      file    = MSG_file_open("c:\\Windows\\setupact.log", NULL);
+      file    = MSG_file_open("/tmp/include/surf/simgrid_dtd.h", NULL);
       st_name = "Disk2";
       break;
     case 2:
index 636d10e..87589ec 100644 (file)
@@ -2,8 +2,8 @@
 
 $ ${bindir:=.}/io-file ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
 > [  0.000000] (0:maestro@) Number of host '4'
-> [  0.000000] (1:host@alice)  Open file 'c:\Windows\setupact.log'
-> [  0.000000] (1:host@alice)  Capacity of the storage element 'c:\Windows\setupact.log' is stored on: 2391537133 / 536870912000
+> [  0.000000] (1:host@alice)  Open file '/tmp/include/surf/simgrid_dtd.h'
+> [  0.000000] (1:host@alice)  Capacity of the storage element '/tmp/include/surf/simgrid_dtd.h' is stored on: 13221994 / 536870912000
 > [  0.000000] (2:host@bob)    Open file '/home/doc/simgrid/examples/platforms/nancy.xml'
 > [  0.000000] (2:host@bob)    Capacity of the storage element '/home/doc/simgrid/examples/platforms/nancy.xml' is stored on: 36933331 / 536870912000
 > [  0.000000] (3:host@carl)   Open file '/home/doc/simgrid/examples/platforms/g5k_cabinets.xml'
@@ -19,18 +19,18 @@ $ ${bindir:=.}/io-file ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%
 > [  0.000000] (4:host@denise)         Capacity of the storage element '/home/doc/simgrid/examples/platforms/g5k.xml' is stored on: 13221994 / 536870912000
 > [  0.000040] (2:host@bob)    Have read 4028 from '/home/doc/simgrid/examples/platforms/nancy.xml'
 > [  0.000085] (4:host@denise)         Have read 17028 from '/home/doc/simgrid/examples/platforms/g5k.xml'
+> [  0.000118] (1:host@alice)  Have read 23583 from '/tmp/include/surf/simgrid_dtd.h'
 > [  0.000226] (3:host@carl)   Have read 22645 from '/home/doc/simgrid/examples/platforms/g5k_cabinets.xml'
-> [  0.000508] (1:host@alice)  Have read 101663 from 'c:\Windows\setupact.log'
 > [  0.001752] (4:host@denise)         Have written 100000 in '/home/doc/simgrid/examples/platforms/g5k.xml'. Size now is: 117028
 > [  0.001752] (4:host@denise)         Capacity of the storage element '/home/doc/simgrid/examples/platforms/g5k.xml' is stored on: 13321994 / 536870912000
 > [  0.001752] (4:host@denise)         Coming back to the beginning of the stream for file '/home/doc/simgrid/examples/platforms/g5k.xml'
-> [  0.002175] (1:host@alice)  Have written 100000 in 'c:\Windows\setupact.log'. Size now is: 201663
-> [  0.002175] (1:host@alice)  Capacity of the storage element 'c:\Windows\setupact.log' is stored on: 2391637133 / 536870912000
-> [  0.002175] (1:host@alice)  Coming back to the beginning of the stream for file 'c:\Windows\setupact.log'
+> [  0.001785] (1:host@alice)  Have written 100000 in '/tmp/include/surf/simgrid_dtd.h'. Size now is: 123583
+> [  0.001785] (1:host@alice)  Capacity of the storage element '/tmp/include/surf/simgrid_dtd.h' is stored on: 13321994 / 536870912000
+> [  0.001785] (1:host@alice)  Coming back to the beginning of the stream for file '/tmp/include/surf/simgrid_dtd.h'
 > [  0.002302] (4:host@denise)         Have read 110000 from '/home/doc/simgrid/examples/platforms/g5k.xml' (of size 117028)
 > [  0.002302] (4:host@denise)         Coming back to the beginning of the stream for file '/home/doc/simgrid/examples/platforms/g5k.xml'
-> [  0.002725] (1:host@alice)  Have read 110000 from 'c:\Windows\setupact.log' (of size 201663)
-> [  0.002725] (1:host@alice)  Coming back to the beginning of the stream for file 'c:\Windows\setupact.log'
+> [  0.002335] (1:host@alice)  Have read 110000 from '/tmp/include/surf/simgrid_dtd.h' (of size 123583)
+> [  0.002335] (1:host@alice)  Coming back to the beginning of the stream for file '/tmp/include/surf/simgrid_dtd.h'
 > [  0.003374] (2:host@bob)    Have written 100000 in '/home/doc/simgrid/examples/platforms/nancy.xml'. Size now is: 104028
 > [  0.003374] (2:host@bob)    Capacity of the storage element '/home/doc/simgrid/examples/platforms/nancy.xml' is stored on: 37033331 / 536870912000
 > [  0.003374] (2:host@bob)    Coming back to the beginning of the stream for file '/home/doc/simgrid/examples/platforms/nancy.xml'
@@ -40,11 +40,11 @@ $ ${bindir:=.}/io-file ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%
 > [  0.004135] (4:host@denise)         Have written 110000 in '/home/doc/simgrid/examples/platforms/g5k.xml'. Size now is: 110000
 > [  0.004135] (4:host@denise)         Capacity of the storage element '/home/doc/simgrid/examples/platforms/g5k.xml' is stored on: 13314966 / 536870912000
 > [  0.004135] (4:host@denise)         Close file '/home/doc/simgrid/examples/platforms/g5k.xml'
+> [  0.004168] (1:host@alice)  Have written 110000 in '/tmp/include/surf/simgrid_dtd.h'. Size now is: 110000
+> [  0.004168] (1:host@alice)  Capacity of the storage element '/tmp/include/surf/simgrid_dtd.h' is stored on: 13308411 / 536870912000
+> [  0.004168] (1:host@alice)  Unlink file '/tmp/include/surf/simgrid_dtd.h'
 > [  0.004414] (2:host@bob)    Have read 104028 from '/home/doc/simgrid/examples/platforms/nancy.xml' (of size 104028)
 > [  0.004414] (2:host@bob)    Coming back to the beginning of the stream for file '/home/doc/simgrid/examples/platforms/nancy.xml'
-> [  0.004558] (1:host@alice)  Have written 110000 in 'c:\Windows\setupact.log'. Size now is: 110000
-> [  0.004558] (1:host@alice)  Capacity of the storage element 'c:\Windows\setupact.log' is stored on: 2391545470 / 536870912000
-> [  0.004558] (1:host@alice)  Unlink file 'c:\Windows\setupact.log'
 > [  0.004660] (3:host@carl)   Have read 110000 from '/home/doc/simgrid/examples/platforms/g5k_cabinets.xml' (of size 122645)
 > [  0.004660] (3:host@carl)   Coming back to the beginning of the stream for file '/home/doc/simgrid/examples/platforms/g5k_cabinets.xml'
 > [  0.008081] (2:host@bob)    Have written 110000 in '/home/doc/simgrid/examples/platforms/nancy.xml'. Size now is: 110000
index efad219..d94788e 100644 (file)
@@ -2,7 +2,7 @@
 
 $ ${bindir}/io-raw-storage ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
 > [  0.000000] (1:@denise) *** Storage info on denise ***
-> [  0.000000] (1:@denise) Storage name: Disk2, mount name: c:
+> [  0.000000] (1:@denise) Storage name: Disk2, mount name: /tmp
 > [  0.000000] (1:@denise) Storage name: Disk4, mount name: /home
 > [  0.003333] (1:@denise) Wrote 200000 bytes on 'Disk4'
 > [  0.004333] (1:@denise) Read 200000 bytes on 'Disk4'
index 049d6ba..2109376 100644 (file)
@@ -28,7 +28,21 @@ endforeach()
 # The output is not relevant
 ADD_TEST(tesh-s4u-comm-pt2pt    ${CMAKE_BINARY_DIR}/teshsuite/s4u/comm-pt2pt/comm-pt2pt    ${CMAKE_HOME_DIRECTORY}/examples/platforms/cluster_backbone.xml)
 
+# NS-3 specific tests
+if(SIMGRID_HAVE_NS3)
+  foreach(x ns3-simultaneous-send-rcv)
+    add_executable       (${x}  EXCLUDE_FROM_ALL ${x}/${x}.cpp)
+    target_link_libraries(${x}  simgrid)
+    set_target_properties(${x}  PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x})
+    add_dependencies(tests ${x})
+    ADD_TESH(tesh-s4u-${x} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_BINARY_DIR}/teshsuite/s4u/${x} ${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x}/${x}.tesh)
+  endforeach()
+endif()
 
+foreach(x ns3-simultaneous-send-rcv)
+  set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.cpp)
+  set(tesh_files    ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.tesh)
+endforeach()
 
 set(teshsuite_src ${teshsuite_src}  PARENT_SCOPE)
 set(tesh_files    ${tesh_files}     PARENT_SCOPE)
index 03294d0..b9c1d9f 100644 (file)
@@ -12,7 +12,7 @@
 XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this msg example");
 
 const int FAIL_ON_ERROR = 0;
-const int flop_amount = 100000000;
+const int flop_amount   = 100000000; // 100Mf, so that computing this on a 1Gf core takes exactly 0.1s
 int failed_test = 0;
 
 double energy = 0;
index 9cb7c06..1261137 100644 (file)
@@ -9,22 +9,22 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u test");
 
 static void host()
 {
-  simgrid::s4u::Storage* storage = simgrid::s4u::Storage::by_name("Disk1");
-  int id                         = simgrid::s4u::this_actor::get_pid();
+  simgrid::s4u::Disk* disk = simgrid::s4u::this_actor::get_host()->get_disks().front(); // Disk1
+  int id                   = simgrid::s4u::this_actor::get_pid();
   XBT_INFO("process %d is writing!", id);
-  storage->write(3000000);
+  disk->write(4000000);
   XBT_INFO("process %d goes to sleep for %d seconds", id, id);
   simgrid::s4u::this_actor::sleep_for(id);
   XBT_INFO("process %d is writing again!", id);
-  storage->write(3000000);
+  disk->write(4000000);
   XBT_INFO("process %d goes to sleep for %d seconds", id, 6 - id);
   simgrid::s4u::this_actor::sleep_for(6 - id);
   XBT_INFO("process %d is reading!", id);
-  storage->read(3000000);
+  disk->read(4000000);
   XBT_INFO("process %d goes to sleep for %d seconds", id, id);
   simgrid::s4u::this_actor::sleep_for(id);
   XBT_INFO("process %d is reading again!", id);
-  storage->read(3000000);
+  disk->read(4000000);
 }
 
 int main(int argc, char** argv)
index 89994b3..89e43ce 100644 (file)
@@ -1,4 +1,4 @@
-$ ./concurrent_rw ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
+$ ./concurrent_rw ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
 > [  0.000000] (host@bob) process 1 is writing!
 > [  0.000000] (host@bob) process 2 is writing!
 > [  0.000000] (host@bob) process 3 is writing!
@@ -24,14 +24,14 @@ $ ./concurrent_rw ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%e(%P@
 > [  6.600000] (host@bob) process 3 is reading!
 > [  6.600000] (host@bob) process 4 is reading!
 > [  6.600000] (host@bob) process 5 is reading!
-> [  6.750000] (host@bob) process 1 goes to sleep for 1 seconds
-> [  6.750000] (host@bob) process 2 goes to sleep for 2 seconds
-> [  6.750000] (host@bob) process 3 goes to sleep for 3 seconds
-> [  6.750000] (host@bob) process 4 goes to sleep for 4 seconds
-> [  6.750000] (host@bob) process 5 goes to sleep for 5 seconds
-> [  7.750000] (host@bob) process 1 is reading again!
-> [  8.750000] (host@bob) process 2 is reading again!
-> [  9.750000] (host@bob) process 3 is reading again!
-> [ 10.750000] (host@bob) process 4 is reading again!
-> [ 11.750000] (host@bob) process 5 is reading again!
-> [ 11.780000] (maestro@) Simulation time 11.78
+> [  6.800000] (host@bob) process 1 goes to sleep for 1 seconds
+> [  6.800000] (host@bob) process 2 goes to sleep for 2 seconds
+> [  6.800000] (host@bob) process 3 goes to sleep for 3 seconds
+> [  6.800000] (host@bob) process 4 goes to sleep for 4 seconds
+> [  6.800000] (host@bob) process 5 goes to sleep for 5 seconds
+> [  7.800000] (host@bob) process 1 is reading again!
+> [  8.800000] (host@bob) process 2 is reading again!
+> [  9.800000] (host@bob) process 3 is reading again!
+> [ 10.800000] (host@bob) process 4 is reading again!
+> [ 11.800000] (host@bob) process 5 is reading again!
+> [ 11.840000] (maestro@) Simulation time 11.84
diff --git a/teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.cpp b/teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.cpp
new file mode 100644 (file)
index 0000000..b7a4de5
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright (c) 2019. 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. */
+
+/* This test checks that ns-3 behave correctly when multiple flows finish   */
+/* at the exact same time. Given the amount of simultaneous senders, it     */
+/* also serves as a (small) crash test for ns-3.                            */
+
+#include "simgrid/s4u.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u tests");
+
+const int payload            = 1000;
+const int nb_message_to_send = 5;
+const double sleep_time      = 5;
+const int nb_sender          = 100;
+
+int nb_messages_sent = 0;
+
+simgrid::s4u::Mailbox* box;
+
+static void test_send(){
+  for (int nb_message = 0; nb_message < nb_message_to_send; nb_message++) {
+    nb_messages_sent++;
+    XBT_VERB("start sending test #%i", nb_messages_sent);
+    box->put(new int(nb_messages_sent), payload);
+    XBT_VERB("done sending test #%i", nb_messages_sent);
+    simgrid::s4u::this_actor::sleep_until(sleep_time * (nb_message + 1));
+  }
+}
+
+static void test_receive(){
+  for (int nb_message = 0; nb_message < nb_message_to_send * nb_sender; nb_message++) {
+    XBT_VERB("waiting for messages");
+    int id = *(int*)(box->get());
+    XBT_VERB("received messages #%i", id);
+  }
+  XBT_INFO("Done receiving from %d senders, each of them sending %d messages", nb_sender, nb_message_to_send);
+}
+
+
+int main(int argc, char *argv[])
+{
+  simgrid::s4u::Engine e(&argc, argv);
+  e.load_platform(argv[1]);
+
+  simgrid::s4u::ActorPtr receiver = simgrid::s4u::Actor::create("receiver", e.get_all_hosts()[0], test_receive);
+  for (int i = 0; i < nb_sender; i++)
+    simgrid::s4u::Actor::create("sender_" + std::to_string(i), e.get_all_hosts()[i % (e.get_host_count() - 1) + 1],
+                                test_send);
+
+  box = simgrid::s4u::Mailbox::by_name("test");
+  box->set_receiver(receiver);
+
+  e.run();
+
+  return 0;
+}
diff --git a/teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.tesh b/teshsuite/s4u/ns3-simultaneous-send-rcv/ns3-simultaneous-send-rcv.tesh
new file mode 100644 (file)
index 0000000..61b0e9c
--- /dev/null
@@ -0,0 +1,6 @@
+p In the ns-3 tests, the timings are not shown because the exact values may vary with your ns-3 version.
+p We just want to check that the ns-3 bindings of SimGrid are working correctly, we don't want to thoroughly test ns-3.
+
+$ ./ns3-simultaneous-send-rcv ${platfdir}/ns3-big-cluster.xml --cfg=network/model:ns-3 "--log=root.fmt:[%h:%P(%i)]%e[%c/%p]%e%m%n"
+> [:maestro(0)] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3'
+> [c-01.rennes:receiver(1)] [s4u_test/INFO] Done receiving from 100 senders, each of them sending 5 messages
index 8beb1e2..4803505 100644 (file)
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(storage, "Messages specific for this simulation");
 
-static void display_storage_properties(simgrid::s4u::Storage* storage)
+static void display_disk_properties(simgrid::s4u::Disk* disk)
 {
-  const std::unordered_map<std::string, std::string>* props = storage->get_properties();
+  const std::unordered_map<std::string, std::string>* props = disk->get_properties();
   if (not props->empty()) {
-    XBT_INFO("\tProperties of mounted storage: %s", storage->get_cname());
+    XBT_INFO("  Properties of disk: %s", disk->get_cname());
 
     for (auto const& elm : *props) {
       XBT_INFO("    %s->%s", elm.first.c_str(), elm.second.c_str());
     }
   } else {
-    XBT_INFO("\tNo property attached.");
+    XBT_INFO("  No property attached.");
   }
 }
 
@@ -57,80 +57,73 @@ static void hsm_put(const std::string& remote_host, const std::string& src, cons
   simgrid::s4u::this_actor::sleep_for(.4);
 }
 
-static void display_storage_content(simgrid::s4u::Storage* storage)
+static void display_disk_content(simgrid::s4u::Disk* disk)
 {
-  XBT_INFO("Print the content of the storage element: %s", storage->get_cname());
-  std::map<std::string, sg_size_t>* content = storage->extension<simgrid::s4u::FileSystemStorageExt>()->get_content();
+  XBT_INFO("*** Dump a disk ***");
+  XBT_INFO("Print the content of the disk: %s", disk->get_cname());
+  std::map<std::string, sg_size_t>* content = disk->extension<simgrid::s4u::FileSystemDiskExt>()->get_content();
   if (not content->empty()) {
     for (auto const& entry : *content)
-      XBT_INFO("\t%s size: %llu bytes", entry.first.c_str(), entry.second);
+      XBT_INFO("  %s size: %llu bytes", entry.first.c_str(), entry.second);
   } else {
-    XBT_INFO("\tNo content.");
+    XBT_INFO("  No content.");
   }
 }
 
-static void dump_storage_by_name(const std::string& name)
+static void get_set_disk_data(simgrid::s4u::Disk* disk)
 {
-  XBT_INFO("*** Dump a storage element ***");
-  simgrid::s4u::Storage* storage = simgrid::s4u::Storage::by_name(name);
-  display_storage_content(storage);
-}
-
-static void get_set_storage_data(const std::string& storage_name)
-{
-  XBT_INFO("*** GET/SET DATA for storage element: %s ***", storage_name.c_str());
-  simgrid::s4u::Storage* storage = simgrid::s4u::Storage::by_name(storage_name);
+  XBT_INFO("*** GET/SET DATA for disk: %s ***", disk->get_cname());
 
-  std::string* data = static_cast<std::string*>(storage->get_data());
+  std::string* data = static_cast<std::string*>(disk->get_data());
   XBT_INFO("Get data: '%s'", data ? data->c_str() : "No User Data");
-  storage->set_data(new std::string("Some data"));
-  data = static_cast<std::string*>(storage->get_data());
-  XBT_INFO("\tSet and get data: '%s'", data->c_str());
+  disk->set_data(new std::string("Some data"));
+  data = static_cast<std::string*>(disk->get_data());
+  XBT_INFO("  Set and get data: '%s'", data->c_str());
   delete data;
 }
 
-static void dump_platform_storages()
+static void dump_platform_disks()
 {
-  std::vector<simgrid::s4u::Storage*> storages = simgrid::s4u::Engine::get_instance()->get_all_storages();
 
-  for (auto const& s : storages) {
-    XBT_INFO("Storage %s is attached to %s", s->get_cname(), s->get_host()->get_cname());
-    s->set_property("other usage", "gpfs");
-  }
+  for (auto const& h : simgrid::s4u::Engine::get_instance()->get_all_hosts())
+    for (auto const& d : h->get_disks()) {
+      if (h == d->get_host())
+        XBT_INFO("%s is attached to %s", d->get_cname(), d->get_host()->get_cname());
+      d->set_property("other usage", "gpfs");
+    }
 }
 
-static void storage_info(simgrid::s4u::Host* host)
+static void disk_info(simgrid::s4u::Host* host)
 {
-  XBT_INFO("*** Storage info on %s ***", host->get_cname());
+  XBT_INFO("*** Disk info on %s ***", host->get_cname());
 
-  for (auto const& elm : host->get_mounted_storages()) {
-    const std::string& mount_name  = elm.first;
-    simgrid::s4u::Storage* storage = elm.second;
-    XBT_INFO("\tStorage name: %s, mount name: %s", storage->get_cname(), mount_name.c_str());
+  for (auto const& disk : host->get_disks()) {
+    const char* mount_name = sg_disk_get_mount_point(disk);
+    XBT_INFO("  Disk name: %s, mount name: %s", disk->get_cname(), mount_name);
 
-    XBT_INFO("\t\tFree size: %llu bytes", sg_storage_get_size_free(storage));
-    XBT_INFO("\t\tUsed size: %llu bytes", sg_storage_get_size_used(storage));
+    XBT_INFO("    Free size: %llu bytes", sg_disk_get_size_free(disk));
+    XBT_INFO("    Used size: %llu bytes", sg_disk_get_size_used(disk));
 
-    display_storage_properties(storage);
-    dump_storage_by_name(storage->get_cname());
+    display_disk_properties(disk);
+    display_disk_content(disk);
   }
 }
 
 static void client()
 {
-  hsm_put("alice", "/home/doc/simgrid/examples/msg/icomms/small_platform.xml", "c:\\Windows\\toto.cxx");
-  hsm_put("alice", "/home/doc/simgrid/examples/msg/parallel_task/test_ptask_deployment.xml", "c:\\Windows\\titi.xml");
-  hsm_put("alice", "/home/doc/simgrid/examples/msg/alias/masterslave_forwarder_with_alias.c", "c:\\Windows\\tata.c");
+  hsm_put("alice", "/scratch/doc/simgrid/examples/msg/icomms/small_platform.xml", "/tmp/toto.xml");
+  hsm_put("alice", "/scratch/doc/simgrid/examples/msg/parallel_task/test_ptask_deployment.xml", "/tmp/titi.xml");
+  hsm_put("alice", "/scratch/doc/simgrid/examples/msg/alias/masterslave_forwarder_with_alias.c", "/tmp/tata.c");
 
   simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name("alice");
   mailbox->put(new std::string("finalize"), 0);
 
-  get_set_storage_data("Disk1");
+  get_set_disk_data(simgrid::s4u::Host::current()->get_disks().front()); // Disk1
 }
 
 static void server()
 {
-  storage_info(simgrid::s4u::this_actor::get_host());
+  disk_info(simgrid::s4u::this_actor::get_host());
   simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(simgrid::s4u::this_actor::get_host()->get_cname());
 
   XBT_INFO("Server waiting for transfers ...");
@@ -148,8 +141,8 @@ static void server()
     }
   }
 
-  storage_info(simgrid::s4u::this_actor::get_host());
-  dump_platform_storages();
+  disk_info(simgrid::s4u::this_actor::get_host());
+  dump_platform_disks();
 }
 
 int main(int argc, char* argv[])
index 6d097a8..b4d2841 100644 (file)
-$ ./storage_client_server ${platfdir}/storage/storage.xml "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
-> [  0.000000] (server@alice) *** Storage info on alice ***
-> [  0.000000] (server@alice)  Storage name: Disk2, mount name: c:
-> [  0.000000] (server@alice)          Free size: 534479374867 bytes
-> [  0.000000] (server@alice)          Used size: 2391537133 bytes
-> [  0.000000] (server@alice)  No property attached.
-> [  0.000000] (server@alice) *** Dump a storage element ***
-> [  0.000000] (server@alice) Print the content of the storage element: Disk2
-> [  0.000000] (server@alice)  \Windows\CoreSingleLanguage.xml size: 31497 bytes
-> [  0.000000] (server@alice)  \Windows\DPINST.LOG size: 18944 bytes
-> [  0.000000] (server@alice)  \Windows\DirectX.log size: 10486 bytes
-> [  0.000000] (server@alice)  \Windows\DtcInstall.log size: 1955 bytes
-> [  0.000000] (server@alice)  \Windows\HelpPane.exe size: 883712 bytes
-> [  0.000000] (server@alice)  \Windows\MEMORY.DMP size: 2384027342 bytes
-> [  0.000000] (server@alice)  \Windows\PFRO.log size: 6770 bytes
-> [  0.000000] (server@alice)  \Windows\Professional.xml size: 31881 bytes
-> [  0.000000] (server@alice)  \Windows\Starter.xml size: 31537 bytes
-> [  0.000000] (server@alice)  \Windows\WLXPGSS.SCR size: 322048 bytes
-> [  0.000000] (server@alice)  \Windows\WMSysPr9.prx size: 316640 bytes
-> [  0.000000] (server@alice)  \Windows\WindowsUpdate.log size: 1518934 bytes
-> [  0.000000] (server@alice)  \Windows\_isusr32.dll size: 180320 bytes
-> [  0.000000] (server@alice)  \Windows\avastSS.scr size: 41664 bytes
-> [  0.000000] (server@alice)  \Windows\bfsvc.exe size: 75264 bytes
-> [  0.000000] (server@alice)  \Windows\bootstat.dat size: 67584 bytes
-> [  0.000000] (server@alice)  \Windows\csup.txt size: 12 bytes
-> [  0.000000] (server@alice)  \Windows\dchcfg64.exe size: 335464 bytes
-> [  0.000000] (server@alice)  \Windows\dcmdev64.exe size: 93288 bytes
-> [  0.000000] (server@alice)  \Windows\explorer.exe size: 2380944 bytes
-> [  0.000000] (server@alice)  \Windows\font1.sii size: 4907 bytes
-> [  0.000000] (server@alice)  \Windows\font2.sii size: 8698 bytes
-> [  0.000000] (server@alice)  \Windows\hapint.exe size: 382056 bytes
-> [  0.000000] (server@alice)  \Windows\hh.exe size: 17408 bytes
-> [  0.000000] (server@alice)  \Windows\mib.bin size: 43131 bytes
-> [  0.000000] (server@alice)  \Windows\notepad.exe size: 243712 bytes
-> [  0.000000] (server@alice)  \Windows\regedit.exe size: 159232 bytes
-> [  0.000000] (server@alice)  \Windows\setupact.log size: 101663 bytes
-> [  0.000000] (server@alice)  \Windows\setuperr.log size: 0 bytes
-> [  0.000000] (server@alice)  \Windows\splwow64.exe size: 126464 bytes
-> [  0.000000] (server@alice)  \Windows\system.ini size: 219 bytes
-> [  0.000000] (server@alice)  \Windows\twain_32.dll size: 50176 bytes
-> [  0.000000] (server@alice)  \Windows\vmgcoinstall.log size: 1585 bytes
-> [  0.000000] (server@alice)  \Windows\win.ini size: 92 bytes
-> [  0.000000] (server@alice)  \Windows\winhlp32.exe size: 10752 bytes
-> [  0.000000] (server@alice)  \Windows\write.exe size: 10752 bytes
+$ ./storage_client_server ${platfdir}/hosts_with_disks.xml "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
+> [  0.000000] (server@alice) *** Disk info on alice ***
+> [  0.000000] (server@alice)   Disk name: Disk1, mount name: /
+> [  0.000000] (server@alice)     Free size: 536857690006 bytes
+> [  0.000000] (server@alice)     Used size: 13221994 bytes
+> [  0.000000] (server@alice)   Properties of disk: Disk1
+> [  0.000000] (server@alice)     content->storage/content/small_content.txt
+> [  0.000000] (server@alice) *** Dump a disk ***
+> [  0.000000] (server@alice) Print the content of the disk: Disk1
+> [  0.000000] (server@alice)   /bin/smpicc size: 918 bytes
+> [  0.000000] (server@alice)   /bin/tesh size: 356434 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/msg/README size: 4805 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/msg/alias/masterslave_forwarder_with_alias.c size: 6217 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/msg/icomms/small_platform.xml size: 972 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/msg/parallel_task/test_ptask_deployment.xml size: 654 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/msg/trace/test9.xml size: 598 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/platforms/g5k.xml size: 17028 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/DT/README size: 999 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/EP/README size: 347 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/EP/randlc.c size: 3300 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/FT/README size: 276 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/MG/README size: 5465 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/MPI_dummy/README size: 2406 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/README size: 1857 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/SP/README size: 926 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/common/randdp.c size: 1441 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/NAS/sys/README size: 1461 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/smpi/mc_bugged2.c size: 1387 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/examples/xbt/sem_basic.c size: 1970 bytes
+> [  0.000000] (server@alice)   /doc/simgrid/html/group__XBT__str.html size: 36192 bytes
+> [  0.000000] (server@alice)   /include/instr/instr.h size: 5750 bytes
+> [  0.000000] (server@alice)   /include/mc/modelchecker.h size: 96 bytes
+> [  0.000000] (server@alice)   /include/msg/datatypes.h size: 4635 bytes
+> [  0.000000] (server@alice)   /include/simdag/simdag.h size: 10325 bytes
+> [  0.000000] (server@alice)   /include/simix/simix.h size: 13003 bytes
+> [  0.000000] (server@alice)   /include/smpi/mpif.h size: 4826 bytes
+> [  0.000000] (server@alice)   /include/surf/simgrid_dtd.h size: 23583 bytes
+> [  0.000000] (server@alice)   /include/xbt/fifo.h size: 3626 bytes
+> [  0.000000] (server@alice)   /lib/libsimgrid.so.3.6.2 size: 12710497 bytes
 > [  0.000000] (server@alice) Server waiting for transfers ...
-> [  0.000010] (client@bob) client has read 972 on /home/doc/simgrid/examples/msg/icomms/small_platform.xml
+> [  0.000010] (client@bob) client has read 972 on /scratch/doc/simgrid/examples/msg/icomms/small_platform.xml
 > [  0.000010] (client@bob) client sends 972 to alice
-> [  0.001986] (server@alice) 972 bytes on 972 bytes have been written by server on /sd1
-> [  0.401976] (client@bob) client has read 654 on /home/doc/simgrid/examples/msg/parallel_task/test_ptask_deployment.xml
+> [  0.001982] (server@alice) 972 bytes on 972 bytes have been written by server on /sd1
+> [  0.401976] (client@bob) client has read 654 on /scratch/doc/simgrid/examples/msg/parallel_task/test_ptask_deployment.xml
 > [  0.401976] (client@bob) client sends 654 to alice
-> [  0.403944] (server@alice) 654 bytes on 654 bytes have been written by server on /sd1
-> [  0.803996] (client@bob) client has read 6217 on /home/doc/simgrid/examples/msg/alias/masterslave_forwarder_with_alias.c
+> [  0.403942] (server@alice) 654 bytes on 654 bytes have been written by server on /sd1
+> [  0.803996] (client@bob) client has read 6217 on /scratch/doc/simgrid/examples/msg/alias/masterslave_forwarder_with_alias.c
 > [  0.803996] (client@bob) client sends 6217 to alice
-> [  0.806104] (server@alice) 6217 bytes on 6217 bytes have been written by server on /sd1
-> [  1.207952] (server@alice) *** Storage info on alice ***
-> [  1.207952] (server@alice)  Storage name: Disk2, mount name: c:
-> [  1.207952] (server@alice)          Free size: 534479367024 bytes
-> [  1.207952] (server@alice)          Used size: 2391544976 bytes
-> [  1.207952] (server@alice)  No property attached.
-> [  1.207952] (server@alice) *** Dump a storage element ***
-> [  1.207952] (server@alice) Print the content of the storage element: Disk2
-> [  1.207952] (server@alice)  \Windows\CoreSingleLanguage.xml size: 31497 bytes
-> [  1.207952] (server@alice)  \Windows\DPINST.LOG size: 18944 bytes
-> [  1.207952] (server@alice)  \Windows\DirectX.log size: 10486 bytes
-> [  1.207952] (server@alice)  \Windows\DtcInstall.log size: 1955 bytes
-> [  1.207952] (server@alice)  \Windows\HelpPane.exe size: 883712 bytes
-> [  1.207952] (server@alice)  \Windows\MEMORY.DMP size: 2384027342 bytes
-> [  1.207952] (server@alice)  \Windows\PFRO.log size: 6770 bytes
-> [  1.207952] (server@alice)  \Windows\Professional.xml size: 31881 bytes
-> [  1.207952] (server@alice)  \Windows\Starter.xml size: 31537 bytes
-> [  1.207952] (server@alice)  \Windows\WLXPGSS.SCR size: 322048 bytes
-> [  1.207952] (server@alice)  \Windows\WMSysPr9.prx size: 316640 bytes
-> [  1.207952] (server@alice)  \Windows\WindowsUpdate.log size: 1518934 bytes
-> [  1.207952] (server@alice)  \Windows\_isusr32.dll size: 180320 bytes
-> [  1.207952] (server@alice)  \Windows\avastSS.scr size: 41664 bytes
-> [  1.207952] (server@alice)  \Windows\bfsvc.exe size: 75264 bytes
-> [  1.207952] (server@alice)  \Windows\bootstat.dat size: 67584 bytes
-> [  1.207952] (server@alice)  \Windows\csup.txt size: 12 bytes
-> [  1.207952] (server@alice)  \Windows\dchcfg64.exe size: 335464 bytes
-> [  1.207952] (server@alice)  \Windows\dcmdev64.exe size: 93288 bytes
-> [  1.207952] (server@alice)  \Windows\explorer.exe size: 2380944 bytes
-> [  1.207952] (server@alice)  \Windows\font1.sii size: 4907 bytes
-> [  1.207952] (server@alice)  \Windows\font2.sii size: 8698 bytes
-> [  1.207952] (server@alice)  \Windows\hapint.exe size: 382056 bytes
-> [  1.207952] (server@alice)  \Windows\hh.exe size: 17408 bytes
-> [  1.207952] (server@alice)  \Windows\mib.bin size: 43131 bytes
-> [  1.207952] (server@alice)  \Windows\notepad.exe size: 243712 bytes
-> [  1.207952] (server@alice)  \Windows\regedit.exe size: 159232 bytes
-> [  1.207952] (server@alice)  \Windows\setupact.log size: 101663 bytes
-> [  1.207952] (server@alice)  \Windows\setuperr.log size: 0 bytes
-> [  1.207952] (server@alice)  \Windows\splwow64.exe size: 126464 bytes
-> [  1.207952] (server@alice)  \Windows\system.ini size: 219 bytes
-> [  1.207952] (server@alice)  \Windows\tata.c size: 6217 bytes
-> [  1.207952] (server@alice)  \Windows\titi.xml size: 654 bytes
-> [  1.207952] (server@alice)  \Windows\toto.cxx size: 972 bytes
-> [  1.207952] (server@alice)  \Windows\twain_32.dll size: 50176 bytes
-> [  1.207952] (server@alice)  \Windows\vmgcoinstall.log size: 1585 bytes
-> [  1.207952] (server@alice)  \Windows\win.ini size: 92 bytes
-> [  1.207952] (server@alice)  \Windows\winhlp32.exe size: 10752 bytes
-> [  1.207952] (server@alice)  \Windows\write.exe size: 10752 bytes
-> [  1.207952] (server@alice) Storage Disk1 is attached to bob
-> [  1.207952] (client@bob) *** GET/SET DATA for storage element: Disk1 ***
+> [  0.806079] (server@alice) 6217 bytes on 6217 bytes have been written by server on /sd1
+> [  1.207952] (server@alice) *** Disk info on alice ***
+> [  1.207952] (server@alice)   Disk name: Disk1, mount name: /
+> [  1.207952] (server@alice)     Free size: 536857682163 bytes
+> [  1.207952] (server@alice)     Used size: 13229837 bytes
+> [  1.207952] (server@alice)   Properties of disk: Disk1
+> [  1.207952] (server@alice)     content->storage/content/small_content.txt
+> [  1.207952] (server@alice) *** Dump a disk ***
+> [  1.207952] (server@alice) Print the content of the disk: Disk1
+> [  1.207952] (server@alice)   /bin/smpicc size: 918 bytes
+> [  1.207952] (server@alice)   /bin/tesh size: 356434 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/msg/README size: 4805 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/msg/alias/masterslave_forwarder_with_alias.c size: 6217 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/msg/icomms/small_platform.xml size: 972 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/msg/parallel_task/test_ptask_deployment.xml size: 654 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/msg/trace/test9.xml size: 598 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/platforms/g5k.xml size: 17028 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/DT/README size: 999 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/EP/README size: 347 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/EP/randlc.c size: 3300 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/FT/README size: 276 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/MG/README size: 5465 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/MPI_dummy/README size: 2406 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/README size: 1857 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/SP/README size: 926 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/common/randdp.c size: 1441 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/NAS/sys/README size: 1461 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/smpi/mc_bugged2.c size: 1387 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/examples/xbt/sem_basic.c size: 1970 bytes
+> [  1.207952] (server@alice)   /doc/simgrid/html/group__XBT__str.html size: 36192 bytes
+> [  1.207952] (server@alice)   /include/instr/instr.h size: 5750 bytes
+> [  1.207952] (server@alice)   /include/mc/modelchecker.h size: 96 bytes
+> [  1.207952] (server@alice)   /include/msg/datatypes.h size: 4635 bytes
+> [  1.207952] (server@alice)   /include/simdag/simdag.h size: 10325 bytes
+> [  1.207952] (server@alice)   /include/simix/simix.h size: 13003 bytes
+> [  1.207952] (server@alice)   /include/smpi/mpif.h size: 4826 bytes
+> [  1.207952] (server@alice)   /include/surf/simgrid_dtd.h size: 23583 bytes
+> [  1.207952] (server@alice)   /include/xbt/fifo.h size: 3626 bytes
+> [  1.207952] (server@alice)   /lib/libsimgrid.so.3.6.2 size: 12710497 bytes
+> [  1.207952] (server@alice)   /tmp/tata.c size: 6217 bytes
+> [  1.207952] (server@alice)   /tmp/titi.xml size: 654 bytes
+> [  1.207952] (server@alice)   /tmp/toto.xml size: 972 bytes
+> [  1.207952] (client@bob) *** GET/SET DATA for disk: Disk1 ***
 > [  1.207952] (client@bob) Get data: 'No User Data'
-> [  1.207952] (client@bob)    Set and get data: 'Some data'
-> [  1.207952] (server@alice) Storage Disk2 is attached to alice
-> [  1.207952] (server@alice) Storage Disk3 is attached to carl
-> [  1.207952] (server@alice) Storage Disk4 is attached to denise
+> [  1.207952] (client@bob)   Set and get data: 'Some data'
+> [  1.207952] (server@alice) Disk1 is attached to alice
+> [  1.207952] (server@alice) Disk1 is attached to bob
+> [  1.207952] (server@alice) Disk2 is attached to bob
 > [  1.207952] (maestro@) Simulated time: 1.20795
index 67a7278..57f3e23 100644 (file)
@@ -1,6 +1,6 @@
 # Test for MPI_File_read and MPI_File_write
 ! output sort
-$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/storage/remote_io.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-all-at
+$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-all-at
 > You requested to use 4 ranks, but there is only 2 processes in your hostfile...
 > [rank 0] -> bob
 > [rank 1] -> carl
index 1e90e16..d60d27e 100644 (file)
@@ -1,6 +1,6 @@
 # Test for MPI_File_read and MPI_File_write
 ! output sort
-$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/storage/remote_io.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-all
+$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-all
 > You requested to use 4 ranks, but there is only 2 processes in your hostfile...
 > [rank 0] -> bob
 > [rank 1] -> carl
index db52534..dedb550 100644 (file)
@@ -1,6 +1,6 @@
 # Test for MPI_File_read and MPI_File_write
 ! output sort
-$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/storage/remote_io.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-ordered
+$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-ordered
 > You requested to use 4 ranks, but there is only 2 processes in your hostfile...
 > [rank 0] -> bob
 > [rank 1] -> carl
index 3fffd2c..8dba085 100644 (file)
@@ -1,6 +1,6 @@
 # Test for MPI_File_read and MPI_File_write
 ! output sort
-$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/storage/remote_io.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-shared
+$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-shared
 > You requested to use 4 ranks, but there is only 2 processes in your hostfile...
 > [rank 0] -> bob
 > [rank 1] -> carl
@@ -13,29 +13,28 @@ $ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -p
 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0
 > (0@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4
 > (0@bob) Position after write in MPI_File /scratch/testfile : 4
-> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 4
+> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0
+> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0
 > (2@bob) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4
-> (2@bob) Position after write in MPI_File /scratch/testfile : 8
-> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 8
+> (2@bob) Position after write in MPI_File /scratch/testfile : 4
+> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0
+> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0
 > (3@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4
-> (3@carl) Position after write in MPI_File /scratch/testfile : 12
-> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 12
+> (3@carl) Position after write in MPI_File /scratch/testfile : 4
+> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4
 > (1@carl) Write in MPI_File /scratch/testfile, 4 bytes written, readsize 4 bytes, movesize 4
-> (1@carl) Position after write in MPI_File /scratch/testfile : 16
-> (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0
-> (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 0
+> (1@carl) Position after write in MPI_File /scratch/testfile : 8
 > (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 0
 > (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 0
 > (0@bob) Seeking in MPI_File /scratch/testfile, setting offset 0
 > (0@bob) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4
 > (0@bob) Position after read in MPI_File /scratch/testfile : 4
 > (2@bob) Seeking in MPI_File /scratch/testfile, setting offset 4
-> (2@bob) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4
-> (2@bob) Position after read in MPI_File /scratch/testfile : 8
-> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 8
-> (3@carl) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4
-> (3@carl) Position after read in MPI_File /scratch/testfile : 12
-> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 12
+> (2@bob) Read in MPI_File /scratch/testfile, 0 bytes read, readsize 4 bytes, movesize 4
+> (2@bob) Position after read in MPI_File /scratch/testfile : 4
+> (3@carl) Seeking in MPI_File /scratch/testfile, setting offset 4
+> (3@carl) Read in MPI_File /scratch/testfile, 0 bytes read, readsize 4 bytes, movesize 4
+> (3@carl) Position after read in MPI_File /scratch/testfile : 4
+> (1@carl) Seeking in MPI_File /scratch/testfile, setting offset 4
 > (1@carl) Read in MPI_File /scratch/testfile, 4 bytes read, readsize 4 bytes, movesize 4
-> (1@carl) Position after read in MPI_File /scratch/testfile : 16
-
+> (1@carl) Position after read in MPI_File /scratch/testfile : 8
index 5f6e87d..f8ff027 100644 (file)
@@ -1,6 +1,6 @@
 # Test for MPI_File_read and MPI_File_write
 ! output sort
-$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/storage/remote_io.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-simple-at
+$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-simple-at
 > You requested to use 4 ranks, but there is only 2 processes in your hostfile...
 > [rank 0] -> bob
 > [rank 1] -> carl
index 2bb8598..bd56168 100644 (file)
@@ -1,6 +1,6 @@
 # Test for MPI_File_read and MPI_File_write
 ! output sort
-$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/storage/remote_io.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-simple
+$ ${bindir:=.}/../../../smpi_script/bin/smpirun -map -hostfile ../hostfile_io -platform ../../../examples/platforms/hosts_with_disks.xml -np 4 --log=xbt_cfg.thres:critical --log=smpi_kernel.thres:warning --log=smpi_mpi.thres:error --log=smpi_io.thres:verbose "--log=root.fmt:(%P@%h)%e%m%n" --cfg=smpi/simulate-computation:0 ${bindir:=.}/io-simple
 > You requested to use 4 ranks, but there is only 2 processes in your hostfile...
 > [rank 0] -> bob
 > [rank 1] -> carl
index 46fce23..90931a6 100644 (file)
@@ -10,9 +10,9 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/")
 
   foreach(file anyall bottom eagerdt huge_anysrc huge_underflow inactivereq isendself isendirecv isendselfprobe issendselfcancel cancelanysrc pingping probenull
-          dtype_send greq1 probe-unexp rqstatus sendall sendflood sendrecv1 sendrecv2 sendrecv3 waitany-null waittestnull many_isend manylmt recv_any sendself scancel scancel2 rcancel)
-    # not compiled files: big_count_status bsend1 bsend2 bsend3 bsend4 bsend5 bsendalign bsendfrag bsendpending mprobe
-    # cancelrecv  icsend large_message pscancel  rqfreeb   scancel_unmatch
+          dtype_send greq1 probe-unexp rqstatus sendall sendflood sendrecv1 sendrecv2 sendrecv3 waitany-null waittestnull many_isend manylmt recv_any sendself scancel scancel2 rcancel bsend1 bsend2 bsend3 bsend4 bsend5 bsendalign bsendfrag bsendpending rqfreeb)
+    # not compiled files: big_count_status mprobe
+    # cancelrecv  icsend large_message pscancel     scancel_unmatch
     add_executable(${file} EXCLUDE_FROM_ALL ${file}.c)
     add_dependencies(tests ${file})
     target_link_libraries(${file} simgrid mtest_c)
index 77d7c16..bf89ff1 100644 (file)
@@ -86,7 +86,7 @@ int main(int argc, char *argv[])
             free(buf);
         }
         else if (rank == dest) {
-            double tstart;
+/*            double tstart;*/
 
             /* Clear the message buffers */
             for (i = 0; i < msgsize; i++) {
@@ -100,9 +100,9 @@ int main(int argc, char *argv[])
                          NULL, 0, MPI_UNSIGNED_CHAR, source, 10, comm, MPI_STATUS_IGNORE);
 
             /* Wait 2 seconds */
-            tstart = MPI_Wtime();
-            while (MPI_Wtime() - tstart < 2.0);
-
+/*            tstart = MPI_Wtime();*/
+/*            while (MPI_Wtime() - tstart < 2.0);*/
+            sleep(2);
             /* Now receive the messages */
             MPI_Recv(msg1, msgsize, MPI_UNSIGNED_CHAR, source, 0, comm, &status1);
             MPI_Recv(msg2, msgsize, MPI_UNSIGNED_CHAR, source, 0, comm, &status2);
index c6abf8a..0af8ea4 100644 (file)
@@ -7,7 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "mpitest.h"
-
+#define USE_STRICT_MPI 1 
 /* Test Ibsend and Request_free */
 int main(int argc, char *argv[])
 {
index 0e47cb1..626d088 100644 (file)
@@ -8,24 +8,22 @@ anyall 2
 eagerdt 2
 pingping 2
 bottom 2
-#needs MPI_Bsend
-#bsend1 1
-#bsend2 1
-#bsend3 1
-#bsend4 1
+bsend1 1
+bsend2 1
+bsend3 1
+bsend4 1
+#needs MPI_Intercomm_create
 #bsend5 4
-#bsendalign 2
-#bsendpending 2
+bsendalign 2
+bsendpending 2
 isendself 1
 #issendselfcancel 1
 isendirecv 10   
-#needs MPI_Buffer_attach, MPI_Bsend, MPI_Buffer_detach
-#bsendfrag 2
+bsendfrag 2
 #needs MPI_Intercomm_create
 #icsend 4
 rqstatus 2
-#needs MPI_Pack, MPI_Buffer_attach, MPI_Buffer_detach, MPI_Ibsend
-#rqfreeb 4
+rqfreeb 4
 #needs MPI_Grequest_start MPI_Grequest_complete
 greq1 1
 probe-unexp 4
index ab86688..fcedf0d 100644 (file)
@@ -1,4 +1,4 @@
-foreach(x lmm_usage surf_usage surf_usage2)
+foreach(x lmm_usage surf_usage surf_usage2 wifi_usage)
   add_executable       (${x}  EXCLUDE_FROM_ALL ${x}/${x}.cpp)
   target_link_libraries(${x}  simgrid)
   set_target_properties(${x}  PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x})
@@ -7,6 +7,8 @@ foreach(x lmm_usage surf_usage surf_usage2)
 
   set(tesh_files    ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.tesh)
   set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.cpp)
+
+  ADD_TESH(tesh-surf-${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/surf/${x} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/surf/${x} ${x}.tesh)
 endforeach()
 
 add_executable       (maxmin_bench EXCLUDE_FROM_ALL maxmin_bench/maxmin_bench.cpp)
@@ -22,10 +24,6 @@ endforeach()
 set(tesh_files     ${tesh_files}                                                               PARENT_SCOPE)
 set(teshsuite_src  ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/maxmin_bench/maxmin_bench.cpp  PARENT_SCOPE)
 
-foreach(x lmm_usage surf_usage surf_usage2)
-  ADD_TESH(tesh-surf-${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/surf/${x} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/surf/${x} ${x}.tesh)
-endforeach()
-
 foreach(x small medium large)
   ADD_TESH(tesh-surf-maxmin-${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/surf/maxmin_bench --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/surf/maxmin_bench maxmin_bench_${x}.tesh)
 endforeach()
index 6e7761c..62b886b 100644 (file)
@@ -19,7 +19,7 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(surf_test, "Messages specific for surf example");
 namespace lmm = simgrid::kernel::lmm;
 
 #define PRINT_VAR(var) XBT_DEBUG(_XBT_STRINGIFY(var) " = %g", (var)->get_value())
-#define SHOW_EXPR(expr) XBT_DEBUG(_XBT_STRINGIFY(expr) " = %g", expr)
+#define SHOW_EXPR(expr) XBT_DEBUG(_XBT_STRINGIFY(expr) " = %g", (expr))
 
 /*        ______                 */
 /*  ==l1==  L2  ==L3==           */
diff --git a/teshsuite/surf/wifi_usage/wifi_usage.cpp b/teshsuite/surf/wifi_usage/wifi_usage.cpp
new file mode 100644 (file)
index 0000000..a081c0b
--- /dev/null
@@ -0,0 +1,83 @@
+/* Copyright (c) 2019. 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 "simgrid/s4u.hpp"
+#include "xbt/log.h"
+
+#include "simgrid/msg.h"
+#include "src/surf/network_cm02.hpp"
+#include <exception>
+#include <iostream>
+#include <random>
+#include <string>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(simulator, "[usage] wifi_usage <platform-file>");
+
+void run_ping_test(const char* src, const char* dest, int data_size);
+
+/* We need a separate actor so that it can sleep after each test */
+static void main_dispatcher()
+{
+  bool crosstraffic = simgrid::kernel::resource::NetworkModel::cfg_crosstraffic;
+
+  XBT_INFO("TEST: Send from a station to a node on the wired network after the AP.");
+  XBT_INFO("----------------------------------------------------------------------");
+  XBT_INFO("Since AP1 is the limiting link, we have the following constraint for AP1:");
+  if (crosstraffic) {
+    XBT_INFO("1.05/r_STA1 * rho_STA1 <= 1   (1.05 instead of 1 because of cross-traffic)");
+    XBT_INFO("We should thus have:");
+    XBT_INFO("  mu = 1 / [ 1/1 * 1.05/54Mbps ] = 51428571");
+    XBT_INFO("  simulation_time = 1000*8 / mu = 0.0001555556s (rounded to 0.000156s in SimGrid)");
+  } else {
+    XBT_INFO("1/r_STA1 * rho_STA1 <= 1  (there is no cross-traffic)");
+    XBT_INFO("We should thus have:");
+    XBT_INFO("  mu = 1 / [ 1/1 * 1/54Mbps ] = 5.4e+07");
+    XBT_INFO("  simulation_time = 1000*8 / mu = 0.0001481481s");
+  }
+  run_ping_test("Station 1", "NODE1", 1000);
+
+  XBT_INFO("TEST: Send from a station to another station on the same AP.");
+  XBT_INFO("------------------------------------------------------------");
+  XBT_INFO("We have the following constraint for AP1:");
+  if (crosstraffic) {
+    XBT_INFO("1.05/r_STA1 * rho_STA1 + 1.05/r_STA2 * rho_2 <= 1     (1.05 instead of 1 because of cross-traffic)");
+    XBT_INFO("We should thus have:");
+    XBT_INFO("  mu = 1 / [ 1/2 * 1.05/54Mbps + 1.05/54Mbps ] =  51428571");
+    XBT_INFO("  simulation_time = 1000*8 / [ mu / 2 ] = 0.0003111111s");
+  } else {
+    XBT_INFO("1/r_STA1 * rho_STA1 +    1/r_STA2 * rho_2 <= 1   (there is no cross-traffic)");
+    XBT_INFO("  mu = 1 / [ 1/2 * 1/54Mbps + 1/54Mbps ] = 5.4e+07");
+    XBT_INFO("  simulation_time = 1000*8 / [ mu / 2 ] = 0.0002962963s");
+  }
+  run_ping_test("Station 1", "Station 2", 1000);
+}
+int main(int argc, char** argv)
+{
+  simgrid::s4u::Engine engine(&argc, argv);
+  engine.load_platform(argv[1]);
+  simgrid::s4u::Actor::create("dispatcher", simgrid::s4u::Host::by_name("NODE1"), main_dispatcher);
+  engine.run();
+
+  return 0;
+}
+
+void run_ping_test(const char* src, const char* dest, int data_size)
+{
+  auto* mailbox = simgrid::s4u::Mailbox::by_name("Test");
+
+  simgrid::s4u::Actor::create("sender", simgrid::s4u::Host::by_name(src), [mailbox, dest, data_size]() {
+    double start_time = simgrid::s4u::Engine::get_clock();
+    static char message[] = "message";
+    mailbox->put(message, data_size);
+    double end_time = simgrid::s4u::Engine::get_clock();
+    XBT_INFO("Actual result: Sending %d bytes from '%s' to '%s' takes %f seconds.", data_size,
+             simgrid::s4u::this_actor::get_host()->get_cname(), dest, end_time - start_time);
+  });
+  simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name(dest), [mailbox]() { mailbox->get(); });
+  auto* l = (simgrid::kernel::resource::NetworkWifiLink*)simgrid::s4u::Link::by_name("AP1")->get_impl();
+  l->set_host_rate(simgrid::s4u::Host::by_name(src), 0);
+  simgrid::s4u::this_actor::sleep_for(10);
+  XBT_INFO("\n");
+}
diff --git a/teshsuite/surf/wifi_usage/wifi_usage.tesh b/teshsuite/surf/wifi_usage/wifi_usage.tesh
new file mode 100644 (file)
index 0000000..007fa0c
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/bin/env tesh
+
+p Test WITH crosstraffic
+$ ${bindir:=.}/wifi_usage ${platfdir}/wifi.xml --log=root.fmt=%m%n
+> TEST: Send from a station to a node on the wired network after the AP.
+> ----------------------------------------------------------------------
+> Since AP1 is the limiting link, we have the following constraint for AP1:
+> 1.05/r_STA1 * rho_STA1 <= 1   (1.05 instead of 1 because of cross-traffic)
+> We should thus have:
+>   mu = 1 / [ 1/1 * 1.05/54Mbps ] = 51428571
+>   simulation_time = 1000*8 / mu = 0.0001555556s (rounded to 0.000156s in SimGrid)
+> Actual result: Sending 1000 bytes from 'Station 1' to 'NODE1' takes 0.000156 seconds.
+>
+>
+> TEST: Send from a station to another station on the same AP.
+> ------------------------------------------------------------
+> We have the following constraint for AP1:
+> 1.05/r_STA1 * rho_STA1 + 1.05/r_STA2 * rho_2 <= 1     (1.05 instead of 1 because of cross-traffic)
+> We should thus have:
+>   mu = 1 / [ 1/2 * 1.05/54Mbps + 1.05/54Mbps ] =  51428571
+>   simulation_time = 1000*8 / [ mu / 2 ] = 0.0003111111s
+> Actual result: Sending 1000 bytes from 'Station 1' to 'Station 2' takes 0.000311 seconds.
+
+p Test WITHOUT crosstraffic
+$ ${bindir:=.}/wifi_usage ${platfdir}/wifi.xml --log=root.fmt=%m%n --cfg=network/crosstraffic:0
+> Configuration change: Set 'network/crosstraffic' to '0'
+> TEST: Send from a station to a node on the wired network after the AP.
+> ----------------------------------------------------------------------
+> Since AP1 is the limiting link, we have the following constraint for AP1:
+> 1/r_STA1 * rho_STA1 <= 1  (there is no cross-traffic)
+> We should thus have:
+>   mu = 1 / [ 1/1 * 1/54Mbps ] = 5.4e+07
+>   simulation_time = 1000*8 / mu = 0.0001481481s
+> Actual result: Sending 1000 bytes from 'Station 1' to 'NODE1' takes 0.000148 seconds.
+>
+>
+> TEST: Send from a station to another station on the same AP.
+> ------------------------------------------------------------
+> We have the following constraint for AP1:
+> 1/r_STA1 * rho_STA1 +    1/r_STA2 * rho_2 <= 1   (there is no cross-traffic)
+>   mu = 1 / [ 1/2 * 1/54Mbps + 1/54Mbps ] = 5.4e+07
+>   simulation_time = 1000*8 / [ mu / 2 ] = 0.0002962963s
+> Actual result: Sending 1000 bytes from 'Station 1' to 'Station 2' takes 0.000296 seconds.
index 9b11df4..9217257 100644 (file)
@@ -20,7 +20,7 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(test,"this test");
 constexpr int BUFFSIZE = 204800;
 constexpr int TESTSIZE = 100;
 
-#define size_of_block(i) (((i % 50)+1)* 100)
+#define size_of_block(i) ((((i) % 50) + 1) * 100)
 
 static void check_block(const unsigned char* p, unsigned char b, int n)
 {
index 2be9a38..642e972 100644 (file)
@@ -11,6 +11,7 @@ set(EXTRA_DIST
   src/include/xbt/parmap.hpp
   src/include/xbt/mmalloc.h
   src/include/catch.hpp
+  src/include/xxhash.hpp
   src/mc/mc_mmu.hpp
   src/mc/mc_record.hpp
   src/msg/msg_private.hpp
@@ -48,6 +49,7 @@ set(EXTRA_DIST
   src/surf/xml/simgrid_dtd.c
   src/surf/xml/surfxml_sax_cb.cpp
 
+  src/surf/disk_s19.hpp
   src/surf/StorageImpl.hpp
   src/surf/storage_n11.hpp
   src/surf/surf_interface.hpp
@@ -313,6 +315,8 @@ set(SURF_SRC
   src/kernel/resource/Action.cpp
   src/kernel/resource/Model.cpp
   src/kernel/resource/Resource.cpp
+  src/kernel/resource/DiskImpl.cpp
+  src/kernel/resource/DiskImpl.hpp
 
   src/kernel/resource/profile/DatedValue.cpp
   src/kernel/resource/profile/DatedValue.hpp
@@ -341,6 +345,7 @@ set(SURF_SRC
   src/surf/cpu_cas01.cpp
   src/surf/cpu_interface.cpp
   src/surf/cpu_ti.cpp
+  src/surf/disk_s19.cpp
   src/surf/network_cm02.cpp
   src/surf/network_constant.cpp
   src/surf/network_interface.cpp
@@ -438,6 +443,7 @@ set(S4U_SRC
   src/s4u/s4u_Barrier.cpp
   src/s4u/s4u_ConditionVariable.cpp
   src/s4u/s4u_Comm.cpp
+  src/s4u/s4u_Disk.cpp
   src/s4u/s4u_Engine.cpp
   src/s4u/s4u_Exec.cpp
   src/s4u/s4u_Host.cpp
@@ -707,6 +713,7 @@ set(headers_to_install
   include/simgrid/s4u/Barrier.hpp
   include/simgrid/s4u/Comm.hpp
   include/simgrid/s4u/ConditionVariable.hpp
+  include/simgrid/s4u/Disk.hpp
   include/simgrid/s4u/Engine.hpp
   include/simgrid/s4u/Exec.hpp
   include/simgrid/s4u/Host.hpp
@@ -1131,8 +1138,10 @@ set(PLATFORMS_EXAMPLES
   examples/platforms/faulty_host.xml
   examples/platforms/g5k.xml
   examples/platforms/griffon.xml
+  examples/platforms/hosts_with_disks.xml
   examples/platforms/meta_cluster.xml
   examples/platforms/multicore_machine.xml
+  examples/platforms/ns3-big-cluster.xml
   examples/platforms/onelink.xml
   examples/platforms/prop.xml
   examples/platforms/routing_cluster.xml
@@ -1141,7 +1150,6 @@ set(PLATFORMS_EXAMPLES
   examples/platforms/simulacrum_7_hosts.xml
   examples/platforms/storage/content/small_content.txt
   examples/platforms/storage/content/storage_content.txt
-  examples/platforms/storage/content/win_storage_content.txt
   examples/platforms/storage/remote_io.xml
   examples/platforms/storage/storage.xml
   examples/platforms/small_platform.xml
@@ -1163,6 +1171,7 @@ set(PLATFORMS_EXAMPLES
   examples/platforms/two_hosts_platform_with_availability_included.xml
   examples/platforms/two_peers.xml
   examples/platforms/vivaldi.xml
+  examples/platforms/wifi.xml
   )
 
 set(generated_src_files
index 99f5976..cb7a0c2 100644 (file)
@@ -60,6 +60,9 @@ endif()
 if(enable_compile_warnings AND enable_debug)
   set(warnCFLAGS "${warnCFLAGS} -Werror")
   set(warnCXXFLAGS "${warnCXXFLAGS} -Werror")
+  if(CMAKE_Fortran_COMPILER_ID MATCHES "GCC")
+    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Werror -Werror=format-security")
+  endif()
 endif()
 
 # Activate the warnings on #if FOOBAR when FOOBAR has no value
index ae1f81b..d2f54c1 100755 (executable)
@@ -102,18 +102,4 @@ if [ -f Testing/TAG ] ; then
    #generate sloccount report
    sloccount --duplicates --wide --details $WORKSPACE | grep -v -e '.git' -e 'mpich3-test' -e 'sloccount.sc' -e 'isp/umpire' -e 'build/' -e 'xml_coverage.xml' -e 'CTestResults_memcheck.xml' -e 'DynamicAnalysis.xml' > $WORKSPACE/sloccount.sc
 
-   #upload files to codacy. CODACY_PROJECT_TOKEN must be setup !
-   if ! [ -z $CODACY_PROJECT_TOKEN ]
-   then 
-     for report in $BUILDFOLDER/java_cov*
-     do
-       if [ ! -e "$report" ]; then continue; fi
-       java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l Java -r $report --partial
-     done
-     java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar final
-
-     java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l Python -r $BUILDFOLDER/python_coverage.xml
-     java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l C -f -r $BUILDFOLDER/xml_coverage.xml
-     java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l CPP -f -r $BUILDFOLDER/xml_coverage.xml
-   fi
 fi || exit 42