Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://framagit.org/simgrid/simgrid into CRTP
authorFrederic Suter <frederic.suter@cc.in2p3.fr>
Tue, 2 Apr 2019 11:24:56 +0000 (13:24 +0200)
committerFrederic Suter <frederic.suter@cc.in2p3.fr>
Tue, 2 Apr 2019 11:24:56 +0000 (13:24 +0200)
233 files changed:
CMakeLists.txt
COPYING
ChangeLog
NEWS
doc/Doxyfile.in
doc/doxygen/platform.doc
docs/source/Doxyfile
docs/source/Tutorial_Algorithms.rst
docs/source/Tutorial_MPI_Applications.rst
docs/source/app_s4u.rst
docs/source/conf.py
docs/source/index.rst
docs/source/platform.rst
docs/source/platform_examples.rst [deleted file]
docs/source/platform_howtos.rst
docs/source/platform_reference.rst
examples/deprecated/java/energy/pstate/energy-pstate.tesh
examples/deprecated/msg/mc/CMakeLists.txt
examples/deprecated/msg/mc/bugged1_liveness_visited.tesh
examples/deprecated/msg/platform-failures/platform-failures.tesh
examples/python/CMakeLists.txt
examples/python/actor-create/actor-create.py
examples/python/actor-join/actor-join.tesh
examples/python/actor-lifetime/actor-lifetime.py
examples/python/async-wait/async-wait.py [new file with mode: 0644]
examples/python/async-wait/async-wait.tesh [new file with mode: 0644]
examples/python/async-wait/async-wait_d.xml [new file with mode: 0644]
examples/python/async-waitall/async-waitall.py [new file with mode: 0644]
examples/python/async-waitall/async-waitall.tesh [new file with mode: 0644]
examples/python/async-waitall/async-waitall_d.xml [new file with mode: 0644]
examples/python/async-waitany/async-waitany.py [new file with mode: 0644]
examples/python/async-waitany/async-waitany.tesh [new file with mode: 0644]
examples/python/async-waitany/async-waitany_d.xml [new file with mode: 0644]
examples/python/exec-async/exec-async.py [new file with mode: 0644]
examples/python/exec-async/exec-async.tesh [new file with mode: 0644]
examples/python/exec-basic/exec-basic.py
examples/python/exec-dvfs/exec-dvfs.py [new file with mode: 0644]
examples/python/exec-dvfs/exec-dvfs.tesh [new file with mode: 0644]
examples/python/exec-remote/exec-remote.py [new file with mode: 0644]
examples/python/exec-remote/exec-remote.tesh [new file with mode: 0644]
examples/s4u/CMakeLists.txt
examples/s4u/README.rst
examples/s4u/actor-exiting/s4u-actor-exiting.cpp
examples/s4u/async-waitall/s4u-async-waitall.cpp
examples/s4u/async-waitany/s4u-async-waitany.cpp
examples/s4u/exec-async/s4u-exec-async.cpp
examples/s4u/exec-async/s4u-exec-async.tesh
examples/s4u/exec-dvfs/s4u-exec-dvfs.cpp
examples/s4u/exec-dvfs/s4u-exec-dvfs.tesh
examples/s4u/exec-monitor/s4u-exec-monitor.cpp [deleted file]
examples/s4u/exec-monitor/s4u-exec-monitor.tesh [deleted file]
examples/s4u/exec-ptask/s4u-exec-ptask.cpp
examples/s4u/exec-ptask/s4u-exec-ptask.tesh
examples/s4u/platform-failures/s4u-platform-failures.cpp
examples/s4u/platform-failures/s4u-platform-failures.tesh
examples/smpi/energy/f77/energy.tesh
examples/smpi/energy/f90/energy.tesh
include/simgrid/forward.h
include/simgrid/kernel/resource/Resource.hpp
include/simgrid/kernel/routing/NetPoint.hpp
include/simgrid/kernel/routing/NetZoneImpl.hpp
include/simgrid/msg.h
include/simgrid/s4u/Actor.hpp
include/simgrid/s4u/Comm.hpp
include/simgrid/s4u/Exec.hpp
include/simgrid/s4u/Host.hpp
include/simgrid/s4u/Link.hpp
include/simgrid/s4u/Mailbox.hpp
include/simgrid/s4u/NetZone.hpp
include/simgrid/s4u/Storage.hpp
include/simgrid/s4u/VirtualMachine.hpp
include/simgrid/simix.h
include/simgrid/simix.hpp
include/smpi/smpi.h
include/smpi/smpi_extended_traces.h
include/smpi/smpi_extended_traces_fortran.h
include/xbt/Extendable.hpp
include/xbt/base.h
include/xbt/ex.h
include/xbt/functional.hpp
include/xbt/log.h
include/xbt/str.h
sonar-project.properties
src/bindings/lua/lua_debug.cpp [deleted file]
src/bindings/lua/lua_utils.cpp [new file with mode: 0644]
src/bindings/lua/lua_utils.hpp
src/bindings/python/simgrid_python.cpp
src/include/xbt/parmap.hpp
src/instr/instr_paje_containers.cpp
src/instr/instr_paje_containers.hpp
src/instr/instr_paje_events.cpp
src/instr/instr_paje_events.hpp
src/instr/instr_paje_trace.cpp
src/instr/instr_platform.cpp
src/instr/instr_private.hpp
src/kernel/EngineImpl.hpp
src/kernel/activity/ActivityImpl.cpp
src/kernel/activity/ActivityImpl.hpp
src/kernel/activity/CommImpl.cpp
src/kernel/activity/CommImpl.hpp
src/kernel/activity/ConditionVariableImpl.cpp
src/kernel/activity/ExecImpl.cpp
src/kernel/activity/ExecImpl.hpp
src/kernel/activity/IoImpl.cpp
src/kernel/activity/IoImpl.hpp
src/kernel/activity/MailboxImpl.cpp
src/kernel/activity/MutexImpl.cpp
src/kernel/activity/SemaphoreImpl.cpp
src/kernel/activity/SleepImpl.cpp
src/kernel/activity/SleepImpl.hpp
src/kernel/activity/SynchroRaw.cpp
src/kernel/activity/SynchroRaw.hpp
src/kernel/actor/ActorImpl.cpp
src/kernel/actor/ActorImpl.hpp
src/kernel/context/Context.cpp
src/kernel/context/ContextBoost.cpp
src/kernel/context/ContextBoost.hpp
src/kernel/context/ContextRaw.cpp
src/kernel/context/ContextRaw.hpp
src/kernel/context/ContextUnix.cpp
src/kernel/context/ContextUnix.hpp
src/kernel/lmm/lagrange.cpp
src/kernel/lmm/maxmin.hpp
src/kernel/resource/Action.cpp
src/kernel/resource/Resource.cpp
src/kernel/routing/NetPoint.cpp
src/kernel/routing/NetZoneImpl.cpp
src/mc/mc_base.cpp
src/mc/mc_dwarf.cpp
src/mc/mc_request.cpp
src/mc/mc_state.cpp
src/msg/msg_global.cpp
src/msg/msg_private.hpp
src/msg/msg_process.cpp
src/msg/msg_task.cpp
src/plugins/dirty_page_tracking.cpp
src/plugins/file_system/s4u_FileSystem.cpp
src/plugins/host_dvfs.cpp
src/plugins/host_energy.cpp
src/plugins/host_load.cpp
src/plugins/link_energy.cpp
src/plugins/vm/VirtualMachineImpl.cpp
src/plugins/vm/VirtualMachineImpl.hpp
src/plugins/vm/VmLiveMigration.cpp
src/plugins/vm/s4u_VirtualMachine.cpp
src/s4u/s4u_Actor.cpp
src/s4u/s4u_Comm.cpp
src/s4u/s4u_Exec.cpp
src/s4u/s4u_Host.cpp
src/s4u/s4u_Io.cpp
src/s4u/s4u_Link.cpp
src/s4u/s4u_Netzone.cpp
src/s4u/s4u_Storage.cpp
src/simdag/sd_dotloader.cpp
src/simgrid/sg_config.cpp
src/simix/libsmx.cpp
src/simix/simcalls.py
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_op.cpp
src/smpi/bindings/smpi_pmpi_request.cpp
src/smpi/colls/alltoall/alltoall-basic-linear.cpp
src/smpi/colls/alltoallv/alltoallv-ompi-basic-linear.cpp
src/smpi/colls/smpi_coll.cpp
src/smpi/colls/smpi_default_selector.cpp
src/smpi/colls/smpi_nbc_impl.cpp [new file with mode: 0644]
src/smpi/include/private.hpp
src/smpi/include/smpi_coll.hpp
src/smpi/include/smpi_op.hpp
src/smpi/include/smpi_request.hpp
src/smpi/include/smpi_status.hpp
src/smpi/internals/smpi_actor.cpp
src/smpi/internals/smpi_global.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/smpi/mpi/smpi_status.cpp
src/smpi/mpi/smpi_win.cpp
src/smpi/plugins/ampi/ampi.cpp
src/smpi/plugins/ampi/ampi.hpp
src/smpi/plugins/sampi_loadbalancer.cpp
src/smpi/smpirun.in
src/surf/StorageImpl.cpp
src/surf/StorageImpl.hpp
src/surf/cpu_cas01.cpp
src/surf/cpu_cas01.hpp
src/surf/cpu_interface.cpp
src/surf/cpu_interface.hpp
src/surf/cpu_ti.cpp
src/surf/cpu_ti.hpp
src/surf/network_cm02.cpp
src/surf/network_constant.cpp
src/surf/network_ib.cpp
src/surf/network_interface.cpp
src/surf/network_interface.hpp
src/surf/network_ns3.cpp
src/surf/network_ns3.hpp
src/surf/ptask_L07.cpp
src/surf/ptask_L07.hpp
src/surf/sg_platf.cpp
src/surf/xml/platf_private.hpp
src/xbt/log.cpp
src/xbt/xbt_log_appender_file.cpp
src/xbt/xbt_log_layout_format.cpp
src/xbt/xbt_log_layout_simple.cpp
src/xbt/xbt_str.cpp
src/xbt/xbt_str_test.cpp
teshsuite/lua/CMakeLists.txt [new file with mode: 0644]
teshsuite/msg/energy-pstate/energy-pstate.tesh
teshsuite/msg/host_on_off_processes/host_on_off_processes.tesh
teshsuite/s4u/activity-lifecycle/activity-lifecycle.cpp
teshsuite/simdag/CMakeLists.txt
teshsuite/smpi/mpich3-test/CMakeLists.txt
teshsuite/smpi/mpich3-test/coll/CMakeLists.txt
teshsuite/smpi/mpich3-test/coll/alltoallw1.c
teshsuite/smpi/mpich3-test/coll/nonblocking2.c
teshsuite/smpi/mpich3-test/coll/testlist
teshsuite/smpi/mpich3-test/pt2pt/CMakeLists.txt
teshsuite/smpi/mpich3-test/pt2pt/testlist
teshsuite/surf/lmm_usage/lmm_usage.cpp
teshsuite/xbt/log_usage/log_usage.tesh
tools/appveyor-irc-notify.py
tools/cmake/DefinePackages.cmake
tools/cmake/MaintainerMode.cmake
tools/cmake/Tests.cmake
tools/sg_xml_unit_converter.py
tools/simgrid_convert_TI_traces.py
tools/tesh/tesh.py

index 681c4cf..ad1dd5b 100644 (file)
@@ -91,7 +91,7 @@ endif()
 #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
 
 set(SIMGRID_VERSION_MAJOR "3")
-set(SIMGRID_VERSION_MINOR "21")
+set(SIMGRID_VERSION_MINOR "22")
 set(SIMGRID_VERSION_PATCH "90")
 set(SIMGRID_VERSION_EXTRA "-DEVEL") # Extra words to add to version string (e.g. -rc1)
 
@@ -461,42 +461,23 @@ file(REMOVE test_stackgrowth)
 ## GIT version check
 ##
 if(EXISTS ${CMAKE_HOME_DIRECTORY}/.git/)
-  execute_process(
-     COMMAND git remote
-     COMMAND head -n 1
-     WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/.git/
-     OUTPUT_VARIABLE remote
+  execute_process(COMMAND git rev-parse --verify --short HEAD
+     WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}
+     OUTPUT_VARIABLE GIT_VERSION
      OUTPUT_STRIP_TRAILING_WHITESPACE)
-  #message(STATUS "Git remote: ${remote}")
-  execute_process(COMMAND git config --get remote.${remote}.url
-     WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/.git/
-     OUTPUT_VARIABLE url
-     OUTPUT_STRIP_TRAILING_WHITESPACE)
-  #message(STATUS "Git url: ${url}")
-  if(url)
-    execute_process(COMMAND git --git-dir=${CMAKE_HOME_DIRECTORY}/.git log --pretty=oneline --abbrev-commit -1
-       WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/.git/
-       OUTPUT_VARIABLE GIT_VERSION
-       OUTPUT_STRIP_TRAILING_WHITESPACE)
-    message(STATUS "Git version: ${GIT_VERSION}")
-
-    execute_process(COMMAND git --git-dir=${CMAKE_HOME_DIRECTORY}/.git log -n 1 --pretty=format:%ai .
-       WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/.git/
-       OUTPUT_VARIABLE GIT_DATE 
-       OUTPUT_STRIP_TRAILING_WHITESPACE)
-    message(STATUS "Git date: ${GIT_DATE}")
-    string(REGEX REPLACE " .*" "" GIT_VERSION "${GIT_VERSION}")
-
-    execute_process(COMMAND git --git-dir=${CMAKE_HOME_DIRECTORY}/.git log --pretty=format:%H -1
-       WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/.git/
-       OUTPUT_VARIABLE SIMGRID_GITHASH
-       OUTPUT_STRIP_TRAILING_WHITESPACE)
+  # Check for uncommitted changes
+  execute_process(COMMAND git diff --name-only HEAD
+    WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}
+    OUTPUT_VARIABLE files_changed)
+  if(files_changed)
+    set(GIT_VERSION "${GIT_VERSION}-dirty")
   endif()
 elseif(EXISTS ${CMAKE_HOME_DIRECTORY}/.gitversion)
   FILE(STRINGS ${CMAKE_HOME_DIRECTORY}/.gitversion GIT_VERSION)
 else()
   set(GIT_VERSION "none, release version")
 endif()
+message(STATUS "Git version: ${GIT_VERSION}")
 
 ### Define source packages for Libs
 include(${CMAKE_HOME_DIRECTORY}/tools/cmake/DefinePackages.cmake)
diff --git a/COPYING b/COPYING
index be4700e..a879a3e 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -1,4 +1,4 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: SimGrid
 Source: https://simgrid.org/
 
index 28d9dd1..0fa7201 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,17 +1,40 @@
-SimGrid (3.22) NOT RELEASED (Release Target: December 21. 2018, 22:23 UTC)
+SimGrid (3.23) NOT RELEASED (Release Target: June 21. 2019, 15:54 UTC)
 
-Java:
- - Process termination which was broken at version 3.21 has been repaired.
- - Expose host load plugin: loadInit, getCurrentLoad, getComputedFlops, getAvgLoad
- - Hide the examples into examples/deprecated. New users should use Python.
+----------------------------------------------------------------------------
 
-Core:
- - Replace our own code to display a backtrace (that was forking addr2line)
+SimGrid (3.22) April 1. 2019
+
+The Easter Chrismas Release (this one is somewhat late).
+
+Python:
+ - We are excited to introduce the SimGrid/S4U interface to your neighborhood
+ - Not complete yet: asynchronous activities (amongst others) are still missing
+ - Still ongoing: the interface may change in the future. We need more
+   testers! Please report any glitches.
+ - No new project using Java should start now. Please switch to Python.
+
+General:
+ - Some of the internal cleanups may lead to speed improvements:
+   - The hard limitation on the amount of simulated actors with
+     Java+Mac was removed. Now, the  available memory is the only limit.
+   - Our refcounting was tidyied, leading to 10% speedups in some cases.
+ - We are still working on making our code robust to the actor kills
+   and hosts' churn. Things are improving, but it's not perfect yet.
+ - Replaced our own code to display a backtrace (that was forking addr2line)
    with the Boost.Stacktrace library.
    You won't see your backtraces without this optional dependency.
  - Bump cmake dependency to 3.5 (provided by Ubuntu 16.04).
  - Stop setting random seed with srand() at initialization.
 
+XML
+ - In <host> and <peer>, 'availability_file' is now 'speed_file'.
+   XML file version remains 4.2 since old files are still compatible.
+
+Java:
+ - Process termination which was broken at version 3.21 has been repaired.
+ - Expose host load plugin: loadInit, getCurrentLoad, getComputedFlops, getAvgLoad
+ - Hide the examples into examples/deprecated. New users should use Python.
+
 MSG:
  - Drop MSG_process_create_from_stdfunc() from the API.
    This C++ function was a pimple in the C API, made necessary at some
@@ -23,6 +46,19 @@ MSG:
    Now use (int,void*) callbacks instead of (void*,void*) ones.
    The implementation was ways too messy to actually work, I guess.
 
+SMPI:
+ - Change the way SMPI_SAMPLE_* macros work to avoid invalidating cache
+   too often and provide more accurate timings.
+ - Add -gdb, -lldb, and -vgdb shortcuts to help debug MPI codes with smpirun
+ - MPI_Alltoallw support
+ - Partial MPI nonblocking collectives implementation: MPI_Ibcast, MPI_Ibarrier,
+   MPI_Iallgather, MPI_Iallgatherv, MPI_Ialltoall, MPI_Ialltoallv, MPI_Igather,
+   MPI_Igatherv, MPI_Iscatter, MPI_Iscatterv, MPI_Ialltoallw.
+ - MPI_Request_get_status, MPI_Status_set_cancelled, MPI_Status_set_elements
+   support
+ - Basic implementation of generalized requests (SMPI doesn't
+   allow MPI_THREAD_MULTIPLE) : MPI_Grequest_complete, MPI_Grequest_start
+
 XBT:
  - Drop sg_cmdline. Please use xbt_cmdline instead.
  - Drop the C xbt_os_mutex_t; Use the C++11 std::mutex.
@@ -35,23 +71,22 @@ XBT:
    -fsplit-stack is the way to go nowadays when using threads.
  - Drop the xbt_os_thread_t module (now unused)
  - Drop xbt_ex_display(), use simgrid::xbt::log_exception() instead.
+ - Drop xbt_str_join_array().
  - Drop cunit, use Catch2 instead.
 
-XML
- - In <host> and <peer>, availability_file is now speed_file.
-   XML file version remains 4.2 since old files are still compatible.
-
-Internal:
+Kernel:
  - Many cleanups in the kernel::activity namespace. This was long
    overdue, and shall open the path to many future endeavors.
 
 Fixed bugs:
- - #132: Java : a process can not shut down its own host
+ - #132: Java: a process can not shut down its own host
+ - #220: S4U: detached send causes exception if sender terminates soon after sending
  - #261: Document the parameters of parallel execution's constructor
  - #300: [s4u] BarrierPtr is missing
  - #314: SMPI args internal cleanup
  - #316: Fix a bug related to the CPU utilization of multi-core VM
  - #318: Invalid trace file when using option --cfg=tracing/smpi/display-sizes:yes
+ - #324: S4U: Attempting to create an actor on turned off host segfaults instead of throwing
  - #325: Turning off a host has different behavior on sleeping actors and computing actors
 
 ----------------------------------------------------------------------------
diff --git a/NEWS b/NEWS
index c5a113b..144460b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,23 @@
+                    _               _____  ____  _____
+__   _____ _ __ ___(_) ___  _ __   |___ / |___ \|___ /
+\ \ / / _ \ '__/ __| |/ _ \| '_ \    |_ \   __) | |_ \
+ \ V /  __/ |  \__ \ | (_) | | | |  ___) | / __/ ___) |
+  \_/ \___|_|  |___/_|\___/|_| |_| |____(_)_____|____/
+               (not released)
+
                     _               _____  ____  ____
 __   _____ _ __ ___(_) ___  _ __   |___ / |___ \|___ \
 \ \ / / _ \ '__/ __| |/ _ \| '_ \    |_ \   __) | __) |
  \ V /  __/ |  \__ \ | (_) | | | |  ___) | / __/ / __/
   \_/ \___|_|  |___/_|\___/|_| |_| |____(_)_____|_____|
-               (not released)
+               April 1. 2019
+
+The Easter Chrismas Release (this one is somewhat late).
 
+ * Introducing the Python bindings (still beta)
+ * Doc: SMPI tutorial and platform description ported to RTD
+ * Many internal cleanups leading to some user-level speedups
+ * (+ the classical bug fixes and internal refactorings)
                     _               _____  ____  _
 __   _____ _ __ ___(_) ___  _ __   |___ / |___ \/ |
 \ \ / / _ \ '__/ __| |/ _ \| '_ \    |_ \   __) | |
index 0a43e36..a35a726 100644 (file)
@@ -928,25 +928,6 @@ HTML_OUTPUT            = html
 
 HTML_FILE_EXTENSION    = .html
 
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header. Note that when using a custom header you are responsible
-#  for the proper inclusion of any scripts and style sheets that doxygen
-# needs, which is dependent on the configuration options used.
-# It is advised to generate a default header using "doxygen -w html
-# header.html footer.html stylesheet.css YourConfigFile" and then modify
-# that header. Note that the header is subject to change so you typically
-# have to redo this when upgrading to a newer version of doxygen or when
-# changing the value of configuration settings such as GENERATE_TREEVIEW!
-
-HTML_HEADER            = @CMAKE_HOME_DIRECTORY@/doc/doxygen/header.html
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER            = @CMAKE_HOME_DIRECTORY@/doc/doxygen/footer.html
-
 # The HTML_STYLESHEET tag can be used to specify a user-defined cascading
 # style sheet that is used by each HTML page. It can be used to
 # fine-tune the look of the HTML output. If the tag is left blank doxygen
@@ -1463,7 +1444,8 @@ PREDEFINED             = __cplusplus \
                         XBT_ATTRIB_UNUSED= \
                          XBT_ATTRIB_DEPRECATED_v323(m)= \
                          XBT_ATTRIB_DEPRECATED_v324(m)= \
-                         XBT_ATTRIB_DEPRECATED_v325(m)=
+                         XBT_ATTRIB_DEPRECATED_v325(m)= \
+                         XBT_ATTRIB_DEPRECATED_v326(m)=
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
 # this tag can be used to specify a list of macro names that should be expanded.
index 21121e1..66e93c9 100644 (file)
 /*! @page platform Describing the virtual platform
 
 
-
-As usual, SimGrid is a versatile framework, and you should find the
-way of describing your platform that best fits your experimental
-practice. 
-
-@section pf_first_example First Platform Example 
-
-Here is a very simple platform file, containing 3 resources (two hosts
-and one link), and explicitly giving the route between the hosts.
-
-@code{.xml}
-<?xml version='1.0'?>
-<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
-<platform version="4.1">
-  <zone id="first zone" routing="Full">
-    <!-- the resources -->
-    <host id="host1" speed="1Mf"/>
-    <host id="host2" speed="2Mf"/>
-    <link id="link1" bandwidth="125MBps" latency="100us"/>
-    <!-- the routing: specify how the hosts are interconnected -->
-    <route src="host1" dst="host2">
-      <link_ctn id="link1"/>
-    </route>
-  </zone>
-</platform>
-@endcode
-
-
-Then, every resource (specified with @ref pf_tag_host, @ref
-pf_tag_link or others) must be located within a given **networking
-zone**.  Each zone is in charge of the routing between its
-resources. It means that when an host wants to communicate with
-another host of the same zone, it is the zone's duty to find the list
-of links that are involved in the communication. Here, since the @ref
-pf_tag_zone tag has **Full** as a **routing attribute**, all routes
-must be explicitely given using the @ref pf_tag_route and @ref
-pf_tag_linkctn tags (this @ref pf_rm "routing model" is both simple
-and inefficient :) It is OK to not specify the route between two
-hosts, as long as the processes located on them never try to
-communicate together.
-
-A zone can contain several zones itself, leading to a hierarchical
-decomposition of the platform. This can be more efficient (as the
-inter-zone routing gets factorized with @ref pf_tag_zoneroute), and
-allows to have more than one routing model in your platform. For
-example, you could have a coordinate-based routing for the WAN parts
-of your platforms, a full routing within each datacenter, and a highly
-optimized routing within each cluster of the datacenter.  In this
-case, determining the route between two given hosts gets @ref
-routing_basics "somewhat more complex" but SimGrid still computes
-these routes for you in a time- and space-efficient manner.
-Here is an illustration of these concepts:
-
-![A hierarchy of networking zones.](AS_hierarchy.png)
-
-Circles represent processing units and squares represent network
-routers. Bold lines represent communication links. The zone "AS2"
-models the core of a national network interconnecting a small flat
-cluster (AS4) and a larger hierarchical cluster (AS5), a subset of a
-LAN (AS6), and a set of peers scattered around the world (AS7).
-
 @section pf_res Resource description
 
 @subsection pf_res_computing Computing Resources
 
-@subsubsection pf_tag_host &lt;host&gt;
-
-An host is the computing resource on which an actor can execute.
-
-Attribute         | Values                                 | Description
------------------ | -------------------------------------- | -----------
-id                | String (mandatory)                     | The identifier of the host. facilitates referring to this AS.
-speed             | double (mandatory)                     | Computational power of every core of this host in FLOPS (must be positive)
-core              | int (defaults to 1)                    | Number of cores (see @ref howto_multicore)
-availability_file | File name (optional) | (Relative or absolute) filename to use as input; must contain availability traces for this host. The syntax of this file is defined below.
-state_file        | File name (optional) |  File to use as a state profile (see @ref howto_churn)
-coordinates       | String (mandatory when using Vivaldi routing) | The coordinates of this host (see @ref pf_P2P_tags).
-pstate     | Double (Defaults to 0) | FIXME: Not yet documented.
-
-#### Included tags ####
-
- - @ref pf_tag_mount Specifies the storages mounted on that host
- - @ref pf_tag_prop Specifies a user-defined property of that host, that you can retrieve with MSG_host_get_property_value() or simgrid::s4u::Host::property().
-
-#### Examples ####
-
-@code{.xml}
-<host id="host1" speed="1000000000"/>
-<host id="host2" speed="1000000000">
-   <prop id="color" value="blue"/>
-   <prop id="rendershape" value="square"/>
-</host>
-@endcode
-
-@anchor pf_host_dynamism
-### Expressing dynamism ###
-
-SimGrid provides mechanisms to change a hosts' availability over
-time, using the ``availability_file`` attribute to the ``@<host@>`` tag
-and a separate text file whose syntax is exemplified below.
-
-#### Adding a trace file ####
-
-@verbatim
-<platform version="4">
-  <host id="bob" speed="500Gf" availability_file="bob.trace" />
-</platform>
-@endverbatim
-
-#### Example of "bob.trace" file ####
-
-~~~~~~~~~~~~~~{.py}
-PERIODICITY 1.0
-  0.0 1.0
-  11.0 0.5
-  20.0 0.8
-~~~~~~~~~~~~~~
-
-Let us begin to explain this example by looking at line 2. (Line 1 will become clear soon).
-The first column describes points in time, in this case, time 0. The second column
-describes the relative amount of power this host is able to deliver (relative
-to the maximum performance specified in the ``@<host@>`` tag). (Clearly, the
-second column needs to contain values that are not smaller than 0 and not larger than 1).
-In this example, our host will deliver 500 Mflop/s at time 0, as 500 Mflop/s is the
-maximum performance of this host. At time 11.0, it will
-deliver half of its maximum performance, i.e., 250 Mflop/s until time 20.0 when it will
-will start delivering 80@% of its power. In this example, this amounts to 400 Mflop/s.
-
-Since the periodicity in line 1 was set to be 1.0, i.e., 1 timestep, this host will
-continue to provide 500 Mflop/s from time 21. From time 32 it will provide 250 MFlop/s and so on.
 
 @subsubsection pf_tag_cluster &lt;cluster&gt;
 
@@ -285,40 +159,6 @@ The hosts generated in the above example are named host-1.cluster, host-2.cluste
 etc.
 
 
-@subsubsection pf_peer &lt;peer&gt; (Vivaldi netzones only)
-
-This tag represents a peer, as in Peer-to-Peer (P2P) networks. This
-can only be used in Vivaldi NetZones. It creates the following
-resources to the NetZone:
-
-@li A host
-@li Two links: One for download and one for upload. This is
-    convenient to use and simulate stuff under the last mile model (e.g., ADSL peers).
-@li It connects the two links to the host
-
-#### Attributes ####
-
-Attribute name  | Mandatory | Values | Description
---------------- | --------- | ------ | -----------
-id              | yes       | string | The identifier of the peer. Facilitates referring to this peer.
-speed           | yes       | int    | See the description of the ``host`` tag for this attribute
-bw_in           | yes       | int    | Bandwidth of the private downstream link
-bw_out          | yes       | int    | Bandwidth of the private upstream link
-coordinates     | no        | string | Coordinates of the gateway for this peer. Example value: 12.8 14.4 6.4
-sharing_policy  | no        | SHARED@|SPLITDUPLEX (default: SPLITDUPLEX) | Sharing policy for links. See <b>link</b> description for details.
-availability_file| no       | string | Availability file for the peer. Same as host availability file. See <b>host</b> description for details.
-state_file      | no        | string | State file for the peer. Same as host state file. See <b>host</b> description for details.
-
-
-The communication latency between an host A=(xA,yA,zA) and an host
-B=(xB,yB,zB) is computed as follows:
- latency = sqrt( (xA-xB)² + (yA-yB)² ) + zA + zB
-
-See the documentation of simgrid::kernel::routing::VivaldiZone for
-details on how the latency is computed from the coordinate, and on the
-the up and down bandwidth are used.
-
 @subsection pf_ne Network equipments
 
 There are two tags at all times available to represent network entities and
@@ -345,24 +185,6 @@ several other tags that are available only in certain contexts.
     If you want to represent an entity like a switch, you must use ``<link>`` (see section). Routers are used
     to run some routing algorithm and determine routes (see Section @ref pf_routing for details).
 
-@subsubsection pf_router &lt;router/&gt;
-
-As said before, <b>router</b> is used only to give some information
-for routing algorithms. So, it does not have any attributes except:
-
-#### Attributes ####
-
-Attribute name  | Mandatory | Values | Description
---------------- | --------- | ------ | -----------
-id              | yes       | string | The identifier of the router to be used when referring to it.
-coordinates     | no        | string | Must be provided when choosing the Vivaldi, coordinate-based routing model for the network zone the router belongs to. More details can be found in the Section @ref pf_P2P_tags.
-
-#### Example ####
-
-@verbatim
- <router id="gw_dc1_horizdist"/>
-@endverbatim
-
 @subsubsection pf_tag_link &lt;link&gt;
 
 Network links can represent one-hop network connections. They are
@@ -817,29 +639,6 @@ the shortest paths.
 
 @subsection  pf_tag_zone &lt;zone&gt;
 
-Before SimGrid v3.16, networking zones used to be called Autonomous
-Systems, but this was misleading as zones may include other zones in a
-hierarchical manner. If you find any remaining reference to network
-zones, please report this as a bug.
-
-Attribute   | Value                                             | Description
------------ | ------------------------------------------------- | ----------------------------------------------
-id          | String (mandatory)                                | The identifier of this zone (must be unique)
-routing     | One of the existing routing algorithm (mandatory) | See Section @ref pf_rm for details.
-
-<b>Example:</b>
-@code
-<zone id="zone0" routing="Full">
-   <host id="host1" speed="1000000000"/>
-   <host id="host2" speed="1000000000"/>
-   <link id="link1" bandwidth="125000000" latency="0.000100"/>
-   <route src="host1" dst="host2"><link_ctn id="link1"/></route>
-</zone>
-@endcode
-
-In this example, zone0 contains two hosts (host1 and host2). The route
-between the hosts goes through link1.
-
 @subsection pf_rm Routing models
 
 For each network zone, you must define explicitly which routing model will
index 22c250d..fa84973 100644 (file)
@@ -42,4 +42,5 @@ PREDEFINED             += \
     XBT_ATTRIB_UNUSED= \
     XBT_ATTRIB_DEPRECATED_v323(m)= \
     XBT_ATTRIB_DEPRECATED_v324(m)= \
-    XBT_ATTRIB_DEPRECATED_v325(m)=
+    XBT_ATTRIB_DEPRECATED_v325(m)= \
+    XBT_ATTRIB_DEPRECATED_v326(m)=
index feb034a..bff4f27 100644 (file)
@@ -346,7 +346,7 @@ Debian and Ubuntu for example, you can get them as follows:
    sudo apt install simgrid pajeng cmake g++ vite
 
 For R analysis of the produced traces, you may want to install R, 
-and the `pajengr<https://github.com/schnorr/pajengr#installation/>_ package.
+and the `pajengr<https://github.com/schnorr/pajengr#installation/>`_ package.
 
 .. code-block:: shell
 
@@ -364,7 +364,7 @@ everything as follows:
    # (exporting SimGrid_PATH is only needed if SimGrid is installed in a non-standard path)
    export SimGrid_PATH=/where/to/simgrid
    
-   git clone https://framagit.org/simgrid/simgrid.git
+   git clone https://framagit.org/simgrid/simgrid-template-s4u.git
    cd simgrid-template-s4u/
    cmake . 
    make
index f33253c..673d4ea 100644 (file)
@@ -81,21 +81,26 @@ examples.
 Simple Example with 3 hosts
 ...........................
 
-At the most basic level, you can describe your simulated platform as a
-graph of hosts and network links. For instance:
+Imagine you want to describe a little platform with three hosts,
+interconnected as follows:
 
 .. image:: /tuto_smpi/3hosts.png
    :align: center
 
+This can be done with the following platform file, that considers the
+simulated platform as a graph of hosts and network links.
+          
 .. literalinclude:: /tuto_smpi/3hosts.xml
    :language: xml
 
-Note the way in which hosts, links, and routes are defined in
-this XML. All hosts are defined with a speed (in Gflops), and links
-with a latency (in us) and bandwidth (in MBytes per second). Other
-units are possible and written as expected. Routes specify the list of
-links encountered from one route to another. Routes are symmetrical by
-default.
+The elements basic elements (with :ref:`pf_tag_host` and
+:ref:`pf_tag_link`) are described first, and then the routes between
+any pair of hosts are explicitely given with :ref:`pf_tag_route`. Any
+host must be given a computational speed (in flops) while links must
+be given a latency (in seconds) and a bandwidth (in bytes per
+second). Note that you can write 1Gflops instead of 1000000000flops,
+and similar. Last point: :ref:`pf_tag_route`s are symmetrical by
+default (but this can be changed).
 
 Cluster with a Crossbar
 .......................
@@ -304,7 +309,7 @@ Debian and Ubuntu for example, you can get them as follows:
    sudo apt install simgrid pajeng make gcc g++ gfortran vite
 
 For R analysis of the produced traces, you may want to install R, 
-and the `pajengr<https://github.com/schnorr/pajengr#installation/>_ package.
+and the `pajengr<https://github.com/schnorr/pajengr#installation/>`_ package.
 
 .. code-block:: shell
 
index 3c8c206..3f6767b 100644 (file)
@@ -592,6 +592,13 @@ Class Actor
 .. autoclass:: simgrid.Actor
    :members:
 
+==========
+Class Comm
+==========
+
+.. autoclass:: simgrid.Comm
+   :members:
+
 ============
 Class Engine
 ============
@@ -599,6 +606,13 @@ Class Engine
 .. autoclass:: simgrid.Engine
    :members:
 
+==========
+Class Exec
+==========
+
+.. autoclass:: simgrid.Exec
+   :members:
+
 ==========
 Class Host
 ==========
index 227dfcf..ffffe01 100644 (file)
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
 #
-import os, subprocess
+import os
+import subprocess
 
 # Search for our extensions too
 import sys
 sys.path.append(os.path.abspath('_ext'))
 
 # -- Run doxygen on readthedocs.org ------------------------------------------
-import subprocess, os
 
 read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True'
 
@@ -35,9 +35,9 @@ copyright = u'2002-2019, The SimGrid Team'
 author = u'The SimGrid Team'
 
 # The short X.Y version
-version = u'alpha 3.22'
+version = u'alpha 3.23'
 # The full version, including alpha/beta/rc tags
-release = u'alpha 3.22'
+release = u'alpha 3.23'
 
 
 # -- General configuration ---------------------------------------------------
@@ -52,10 +52,10 @@ release = u'alpha 3.22'
 extensions = [
     'sphinx.ext.todo',
     'breathe',
-#    'exhale',
+    #    'exhale',
     'sphinx.ext.autodoc',
     'sphinx.ext.intersphinx',
-#    'sphinx.ext.napoleon',
+    #    'sphinx.ext.napoleon',
     'sphinx.ext.autosummary',
     'hidden_code_block',
     'javasphinx',
@@ -63,19 +63,19 @@ extensions = [
 
 todo_include_todos = True
 
-breathe_projects = { 'simgrid': '../build/xml' }
+breathe_projects = {'simgrid': '../build/xml'}
 breathe_default_project = "simgrid"
 
 # Setup the exhale extension
 
 exhale_args = {
     # These arguments are required
-    "containmentFolder":     "./api",
-    "rootFileName":          "library_root.rst",
-    "rootFileTitle":         "SimGrid Full API",
-    "doxygenStripFromPath":  "..",
+    "containmentFolder": "./api",
+    "rootFileName": "library_root.rst",
+    "rootFileTitle": "SimGrid Full API",
+    "doxygenStripFromPath": "..",
     # Suggested optional arguments
-    "createTreeView":        True,
+    "createTreeView": True,
     "exhaleExecutesDoxygen": False,
     # "exhaleUseDoxyfile":     True,
 }
@@ -122,7 +122,7 @@ html_theme = 'sphinx_rtd_theme'
 # documentation.
 #
 html_theme_options = {
-    'navigation_depth' : 4,
+    'navigation_depth': 4,
     'sticky_navigation': True,
     'display_version': True,
     'includehidden': True,
@@ -151,11 +151,10 @@ htmlhelp_basename = 'SimGrid-doc'
 # -- Options for GitLab integration ------------------------------------------
 
 html_context = {
-    "display_gitlab": True, # Integrate Gitlab
+    "display_gitlab": True,  # Integrate Gitlab
     "gitlab_host": "framagit.org",
     "gitlab_user": "simgrid",
     "gitlab_repo": "simgrid",
-    "gitlab_version": "master", # Version
-    "conf_py_path": "/docs/source/", # Path in the checkout to the docs root
+    "gitlab_version": "master",  # Version
+    "conf_py_path": "/docs/source/",  # Path in the checkout to the docs root
 }
-
index 3718fc1..91fd582 100644 (file)
@@ -30,7 +30,6 @@ Welcome to SimGrid's documentation!
       Â Â Â The MSG Interface <app_msg.rst>
       Â Â Â The Java Bindings <app_java.rst>
       Describing the Simulated Platform <platform.rst>
-      Â Â Â Examples <platform_examples.rst>
       Â Â Â Modeling Hints <platform_howtos.rst>
       Â Â Â DTD Reference <platform_reference.rst>
       Describing the Experimental Scenario <scenario.rst>
index 5c99228..1909927 100644 (file)
@@ -23,35 +23,89 @@ work. When XML is too limiting, you may describe your platforms using
 the :ref:`lua bindings <platform_lua>` (it is not yet possible to do so in
 python or directly in C++).
 
-Since we know that writing platform description files is not trivial,
-we included :ref:`many examples <platform_examples>` in the archive. This
+We understand that writing a complex platform description can be tricky, we thus included 
+:ref:`many examples <platform_examples>` in the archive. This
 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 liberty when defining
-**routing of your platform**, ie the path taken between each pair of
-hosts.  Finally, you may also describe an **experimental scenario**,
-with qualitative changes (e.g., bandwidth changes representing an
-external load) and qualitative changes (representing how some elements
-fail and restart over time).
+Any simulated platform must contain **basic elements**, such as hosts, links, storages, 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.
 
 
+First Example
+*************
 
-Defining Basic Elements
-***********************
+Imagine you want to describe a little platform with three hosts,
+interconnected as follows:
 
-These are the components of your platform.
+.. image:: /tuto_smpi/3hosts.png
+   :align: center
 
+This can be done with the following platform file, that considers the
+simulated platform as a graph of hosts and network links.
+          
+.. literalinclude:: /tuto_smpi/3hosts.xml
+   :language: xml
+
+The most important elements are the basic ones: :ref:`pf_tag_host`,
+:ref:`pf_tag_link`, and similar. Then come the routes between any pair
+of hosts, that are given explicitely with :ref:`pf_tag_route` (routes
+are symmetrical by default). Any host must be given a computational
+speed (in flops) while links must be given a latency (in seconds) and
+a bandwidth (in bytes per second). Note that you can write 1Gflops
+instead of 1000000000flops, and similar.
+
+Every platform element must be located within a given **networking
+zone** .  Zones are in
+charge of the routing, see below.
+
+The last thing you must know on SimGrid platform files is that the
+root tag must be :ref:`pf_tag_platform`. If the ``version`` attribute
+does not match what SimGrid expects, you will be hinted to use to the
+``simgrid_update_xml`` utility to update your file.
 
-There is not much to say about the definition of basic elements. Just
-use the appropriate tags: :ref:`pf_tag_host`, :ref:`pf_tag_link` and
-:ref:`pf_tag_storage`.
 
 Defining a Routing
 ******************
 
+Networking zones (:ref:`pf_tag_zone`) are used to factorize the description
+to reduce the size of your platform on disk and in memory. Then, when
+a host wants to communicate with another host belonging to the same
+zone, it is the zone's duty to find the list of links that are
+involved in the communication. In the above example, since we use
+``routing="Full"``, all routes must be explicitly given using the
+:ref:`pf_tag_route` and :ref:`pf_tag_link_ctn` tags (this :ref:`routing
+model <pf_rm>` is both simple and inefficient :) It is OK to not
+specify each and every route between hosts, as long as you do not try
+to start a communication on any of the missing routes during your
+simulation.
+
+Any zone may contain sub-zones, allowing for a hierarchical
+decomposition of the platform. Routing can be made more efficient (as the
+inter-zone routing gets factored with :ref:`pf_tag_zoneroute`), and
+allows you to have more than one routing model in your platform. For
+example, you can have a coordinate-based routing for the WAN parts
+of your platforms, a full routing within each datacenter, and a highly
+optimized routing within each cluster of the datacenter.  In this
+case, determining the route between two given hosts gets :ref:`routing_basics`
+"somewhat more complex" but SimGrid still computes
+these routes for you in a time- and space-efficient manner.
+Here is an illustration of these concepts:
+
+.. image:: img/zone_hierarchy.png
+
+Circles represent processing units and squares represent network
+routers. Bold lines represent communication links. The zone "AS2" models the core of a national network interconnecting a
+small flat cluster (AS4) and a larger hierarchical cluster (AS5), a
+subset of a LAN (AS6), and a set of peers scattered around the world
+(AS7).
+
+.. todo:: Add more examples, such as the cloud example described in
+          previous paragraph
+
 Performance Profiles and Churn
 ******************************
 
diff --git a/docs/source/platform_examples.rst b/docs/source/platform_examples.rst
deleted file mode 100644 (file)
index 93996b2..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-.. raw:: html
-
-   <object id="TOC" data="graphical-toc.svg" width="100%" type="image/svg+xml"></object>
-   <script>
-   window.onload=function() { // Wait for the SVG to be loaded before changing it
-     var elem=document.querySelector("#TOC").contentDocument.getElementById("PlatformBox")
-     elem.style="opacity:0.93999999;fill:#ff0000;fill-opacity:0.1;stroke:#000000;stroke-width:0.35277778;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1";
-   }
-   </script>
-   <br/>
-   <br/>
-
-.. _platform_examples:
-   
-Platform Examples
-=================
-
-Here is a very simple platform file, containing 3 resources (two hosts
-and one link), and explicitly giving the route between the hosts.
-
-.. literalinclude:: ../../examples/platforms/two_hosts.xml
-   :language: xml   
-
-The root tag must be ``<platform>``, and its ``version`` attribute
-specifies the used DTD version. When the DTD evolutions introduce
-backward-incompatible changes, this number gets updated. Use the
-``simgrid_update_xml`` utility to upgrade your platform files on need.
-
-
-Then, every platform element must be located within a given
-**networking zone** introduced with the :ref:`pf_tag_zone` tag.  Zones
-are in charge of the routing: an host wants to communicate with
-another host of the same zone, it is the zone's duty to find the list
-of links that are involved in the communication. Here, since we use
-``routing="Full"``, all routes must be explicitly given using the
-:ref:`pf_tag_route` and :ref:`pf_tag_linkctn` tags (this :ref:`routing
-model <pf_rm>` is both simple and inefficient :) It is OK to not
-specify each and every route between hosts, as long as you don't start
-at runtime any communications on the missing routes.
-
-Any zone may contain sub-zones itself, leading to a hierarchical
-decomposition of the platform. This can be more efficient (as the
-inter-zone routing gets factorized with :ref:`pf_tag_zoneroute`), and
-allows to have more than one routing model in your platform. For
-example, you could have a coordinate-based routing for the WAN parts
-of your platforms, a full routing within each datacenter, and a highly
-optimized routing within each cluster of the datacenter.  In this
-case, determining the route between two given hosts gets @ref
-routing_basics "somewhat more complex" but SimGrid still computes
-these routes for you in a time- and space-efficient manner.
-Here is an illustration of these concepts:
-
-.. image:: img/zone_hierarchy.png
-
-The zone "AS2" models the core of a national network interconnecting a
-small flat cluster (AS4) and a larger hierarchical cluster (AS5), a
-subset of a LAN (AS6), and a set of peers scattered around the world
-(AS7).
-
-.. todo:: Add more examples, such as the cloud example descibed in
-         previous paragraph
-   
index 5c68aca..1c4eaca 100644 (file)
 Modeling Hints
 ##############
 
-There is no perfect model, but only models that are adapted to the
-specific study that you want to do. SimGrid provide several advanced
+There is no perfect model. Only models that are adapted to the
+specific study that you want to do. SimGrid provides several advanced
 mechanisms that you can adapt to model the situation that you are
-interested into, and it is often uneasy to see where to start with.
+interested in, and it is often uneasy to see where to start with.
 This page collects several hints and tricks on modeling situations.
 Even if you are looking for a very advanced, specific use case, these
 examples may help you to design the solution you need.
@@ -31,9 +31,9 @@ Doing Science with SimGrid
 **************************
 
 Many users are using SimGrid as a scientific instrument for their
-research. This tool was indeed invented to that extend, and we strive
+research. This tool was indeed invented to that extent, and we strive
 to streamline this kind of usage. But SimGrid is no magical tool, and
-it is of your responsability that the tool actually provides sensible
+it is of your responsibility that the tool actually provides sensible
 results. Fortunately, there is a vast literature on how to avoid
 Modeling & Simulations pitfalls. We review here some specific works.
 
@@ -55,12 +55,12 @@ specific. Here are the listed pitfalls: (1) Don't know whether it's
 modeling or simulation, (2) No separation of concerns, (3) No clear
 scientific question, (4) Implementing everything from scratch, (5)
 Unsupported claims, (6) Toy duck approach, and (7) The tunnel view. As
-you can see, this article is a must read. It's a pitty that it's not
+you can see, this article is a must read. It's a pity that it's not
 freely available, though.
 
 .. _howto_churn:
 
-Modeling Churn (e.g. in P2P)
+Modeling Churn (e.g., in P2P)
 ****************************
 
 One of the biggest challenges in P2P settings is to cope with the
@@ -72,27 +72,26 @@ directly.
 
 This can be done through the XML file, using the ``state_file``
 attribute of :ref:`pf_tag_host`, :ref:`pf_tag_cluster` or
-:ref:`pf_tag_link`. Every lines (but the last) of such files describe
+:ref:`pf_tag_link`. Every line (but the last) of such files describes
 timed events with the form "date value". Example:
 
 .. code-block:: python
-               
+
    1 0
    2 1
    LOOPAFTER 8
 
-- At time t=1, the host is turned off (value 0 means OFF)
-- At time t=2, it is turned back on (other values means ON)
-- At time t=10, the history is reset (because that's 8 seconds after
-  the last event). So the host will be turned off again at t=11.
+  - At time t = 1, the host is turned off (a zero value means OFF)
+  - At time t = 2, the host is turned back on (any other value than zero means ON)
+  - At time t = 10, the profile is reset (as we are 8 seconds after the last event). Then the host will be turned off 
+    again at time t = 11.
 
-If your trace does not contain a LOOPAFTER line, then your profile is
-only executed once and not repetitively.
+   If your profile does not contain any LOOPAFTER line, then it will be executed only once and not in a repetitive way.
 
 Another possibility is to use the
 :cpp:func:`simgrid::s4u::Host::set_state_profile()` or 
 :cpp:func:`simgrid::s4u::Link::set_state_profile()` functions. These
-functions take a profile, that can be an fixed profile exhaustively
+functions take a profile, that can be a fixed profile exhaustively
 listing the events, or something else if you wish.
 
 .. _howto_multicore:
@@ -103,23 +102,23 @@ Modeling Multicore Machines
 Default Model
 =============
 
-Multicore machines are very complex, and there is many way to model
+Multicore machines are very complex, and there are many ways to model
 them. The default models of SimGrid are coarse grain and capture some
 elements of this reality. Here is how to declare simple multicore hosts:
 
 .. code-block:: xml
-               
+
    <host id="mymachine" speed="8Gf" core="4"/>
 
-It declares a 4-cores host called "mymachine", each core computing 8
-GFlops per second. If you put one activity of 8 GFlop on this host, it
+It declares a 4-core host called "mymachine", each core computing 8
+GFlops per second. If you put one activity of 8 GFlops on this host, it
 will be computed in 1 second (by default, activities are
 single-threaded and cannot leverage the computing power of more than
-one core). If you put two of them together, they will still be
-computed in one second, and so on up to 4 tasks. If you put 5 tasks,
-they will share the total computing resource, and all tasks will be
-computed at 5/4 = 1.25 second. That's a very simple model, but that's
-all what you will get by default from SimGrid.
+one core). If you run two such activities simultaneously, they will still be
+computed in one second, and so on up to 4 activities. If you start 5 activities,
+they will share the total computing power, and each activity will be
+computed in 5/4 = 1.25 seconds. This is a very simple model, but that is
+all what you get by default from SimGrid.
 
 Pinning tasks to cores
 ======================
@@ -127,47 +126,47 @@ Pinning tasks to cores
 The default model does not account for task pinning, where you
 manually select on which core each of the existing activity should
 execute. The best solution to model this is probably to model your
-4-core processor as 4 separte hosts, and assigning the activities to
+4-core processor as 4 distinct hosts, and assigning the activities to
 cores by migrating them to the declared hosts. In some sense, this 
 takes the whole Network-On-Chip idea really seriously.
 
-Some extra complications may arise here. If you have more tasks than
-cores, you'll have to `schedule your tasks
+Some extra complications may arise here. If you have more activities than
+cores, you'll have to `schedule your activities
 <https://en.wikipedia.org/wiki/Scheduling_%28computing%29#Operating_system_process_scheduler_implementations)>`_
 yourself on the cores (so you'd better avoid this complexity). Since
 you cannot have more than one network model in a given SimGrid
-simulation, you will end up with a TCP connexion between your cores. A
+simulation, you will end up with a TCP connection between your cores. A
 possible work around is to never start any simulated communication
 between the cores and have the same routes from each core to the
 rest of the external network.
 
 Modeling a multicore CPU as a set of SimGrid hosts may seem strange
 and unconvincing, but some users achieved very realistic simulations
-of multi-core and GPU machines this way.
+of multicore and GPU machines this way.
 
-Modeling machine bootup and shutdown periods
+Modeling machine boot and shutdown periods
 ********************************************
 
 When a physical host boots up, a lot of things happen. It takes time
 during which the machine is not usable but dissipates energy, and
-programs actually die and restart during a reboot. Since there is many
+programs actually die and restart during a reboot. Since there are many
 ways to model it, SimGrid does not do any modeling choice for you but
 the most obvious ones.
 
-Any actor (or process in MSG) running on an host that is shut down
+Any actor (or process in MSG) running on a host that is shut down
 will be killed and all its activities (tasks in MSG) will be
-automatically canceled. If killed the actor was marked as
+automatically canceled. If the actor killed was marked as
 auto-restartable (with
 :cpp:func:`simgrid::s4u::Actor::set_auto_restart` or with
 :cpp:func:`MSG_process_auto_restart_set`), it will start anew with the
 same parameters when the host boots back up.
 
-By default, shutdowns and bootups are instantaneous. If you want to
-add an extra delay, you have to do that yourself, for example from an
-`controler` actor that runs on another host. The best way to do so is
-to declare a fictionous pstate where the CPU delivers 0 flop per
+By default, shutdowns and boots are instantaneous. If you want to
+add an extra delay, you have to do that yourself, for example from a
+`controller` actor that runs on another host. The best way to do so is
+to declare a fictional pstate where the CPU delivers 0 flop per
 second (so every activity on that host will be frozen when the host is
-in this pstate). When you want to switch the host off, your controler
+in this pstate). When you want to switch the host off, your controller
 switches the host to that specific pstate (with
 :cpp:func:`simgrid::s4u::Host::set_pstate`), waits for the amount of
 time that you decided necessary for your host to shut down, and turns
@@ -181,7 +180,7 @@ the energy consumed is equal to the instantaneous consumption
 multiplied by the time in which the host keeps in that state. Do the
 maths, and set the right instantaneous consumption to your pstate, and
 you'll get the whole boot period to consume the amount of energy that
-you want. You may want to have one fictionous pstate for the bootup
+you want. You may want to have one fictional pstate for the boot
 period and another one for the shutdown period.
 
 Of course, this is only one possible way to model these things. YMMV ;)
index 70496ce..4e729a5 100644 (file)
 DTD Reference
 *************
 
-Your platform description should follow the specification presented in
-the `simgrid.dtd <https://simgrid.org/simgrid.dtd>`_
-DTD file. The same DTD is used for both the platform and deployment
-files. 
+Your platform description should follow the specification presented in the 
+`simgrid.dtd <https://simgrid.org/simgrid.dtd>`_ DTD file. The same DTD is used for both platform and deployment files. 
 
 .. _pf_tag_config:
 
@@ -26,11 +24,12 @@ files.
 <config>
 ------------------------------------------------------------------
 
-Adding configuration flags into the platform file is particularly
-useful when the described platform is best used with specific
-flags. For example, you could finely tune SMPI in your platform file
-directly.  Almost all :ref:`command-line configuration items <options_list>`
-can be configured this way.
+Adding configuration flags directly into the platform file becomes particularly useful when the realism of the described
+platform depends on some specific flags. For example, this could help you to finely tune SMPI. Almost all
+:ref:`command-line configuration items <options_list>` can be configured this way.
+
+Each configuration flag is described as a :ref:`pf_tag_prop` whose 'id' is the name of the flag and 'value' is what it
+has to be set to.
 
 **Parent tags:** :ref:`pf_tag_platform` (must appear before any other tags) |br|
 **Children tags:** :ref:`pf_tag_prop` |br|
@@ -38,30 +37,31 @@ can be configured this way.
 
 .. code-block:: xml
 
-   <?xml version='1.0'?>
+   <?xml version = '1.0'?>
    <!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
-   <platform version="4.1">
-   <config>
-       <prop id="maxmin/precision" value="0.000010" />
-       <prop id="cpu/optim" value="TI" />
-       <prop id="network/model" value="SMPI" />
-       <prop id="smpi/bw-factor" value="65472:0.940694;15424:0.697866;9376:0.58729" />
-   </config>
-
-   <!-- The rest of your platform -->
+   <platform version = "4.1">
+     <config>
+       <prop id = "maxmin/precision" value = "0.000010" />
+       <prop id = "cpu/optim" value = "TI" />
+       <prop id = "network/model" value = "SMPI" />
+       <prop id = "smpi/bw-factor" value = "65472:0.940694;15424:0.697866;9376:0.58729" />
+     </config>
+
+     <!-- The rest of your platform -->
    </platform>
 
-
+|hr|
+   
 .. _pf_tag_host:
 
 ------------------------------------------------------------------
 <host>
 ------------------------------------------------------------------
 
-An host is the computing resource on which an actor can execute. See :cpp:class:`simgrid::s4u::Host`.
+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 no inner zones nor clusters) |br|
-**Children tags:** :ref:`pf_tag_prop`, :ref:`pf_tag_storage` |br|
+**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|
 **Attributes:**
 
 :``id``: Host name.
@@ -80,72 +80,70 @@ An host is the computing resource on which an actor can execute. See :cpp:class:
       1 0.5
       2 0.2
       5 1
-      LOOPAFTER 8
+      LOOPAFTER 5
 
-   - At time t=1, half of its power is taken by some background
-     computations, so only 50% of its initial power remains available
-     (0.5 means 50%). 
-   - At time t=2, the available power drops at 20% of the total.
-   - At time t=5, the host computes back at full speed.
-   - At time t=10, the history is reset (because that's 5 seconds after
-     the last event). So the available speed will drop at t=11.
+   - At time t = 1, half of the host computational power (0.5 means 50%) is used to process some background load, hence 
+     only 50% of this initial power remains available to your own simulation. 
+   - At time t = 2, the available power drops at 20% of the initial value.
+   - At time t = 5, the host can compute at full speed again.
+   - At time t = 10, the profile is reset (as we are 5 seconds after the last event). Then the available speed will drop
+     again to 50% at time t = 11.
 
-   If your trace does not contain a LOOPAFTER line, then your profile
-   is only executed once and not repetitively.
+   If your profile does not contain any LOOPAFTER line, then it will be executed only once and not in a repetitive way.
 
-   .. warning:: Don't get fooled: Bandwidth and Latency profiles of a
-      :ref:`pf_tag_link` are absolute values, but Availability
-      profiles of :ref:`pf_tag_host` are ratio.
+   .. warning:: Don't get fooled: Bandwidth and Latency profiles of a :ref:`pf_tag_link` contain absolute values, while
+      Availability profiles of a :ref:`pf_tag_host` contain ratios.
 :``state_file``: File containing the state profile.
    Almost every lines of such files describe timed events as ``date boolean``.
    Example:
 
    .. code-block:: python
-                  
+
       1 0
       2 1
       LOOPAFTER 8
 
-   - At time t=1, the host is turned off (value 0 means OFF)
-   - At time t=2, it is turned back on (other values means ON)
-   - At time t=10, the history is reset (because that's 8 seconds after
-     the last event). So the host will be turned off again at t=11.
+   - At time t = 1, the host is turned off (a zero value means OFF)
+   - At time t = 2, the host is turned back on (any other value than zero means ON)
+   - At time t = 10, the profile is reset (as we are 8 seconds after the last event). Then the host will be turned off 
+     again at time t = 11.
 
-   If your trace does not contain a LOOPAFTER line, then your profile
-   is only executed once and not repetitively.
+   If your profile does not contain any LOOPAFTER line, then it will be executed only once and not in a repetitive way.
 
-:``coordinates``: Vivaldi coordinates (Vivaldi zones only).
+:``coordinates``: Vivaldi coordinates (meaningful for Vivaldi zones only).
    See :ref:`pf_tag_peer`.
 :``pstate``: Initial pstate (default: 0, the first one).
    See :ref:`howto_dvfs`.
 
+|hr|
+   
 .. _pf_tag_link:
 
 ------------------------------------------------------------------
 <link>
 ------------------------------------------------------------------
 
-Network links can represent one-hop network connections. See :cpp:class:`simgrid::s4u::Link`.
+SimGrid links usually represent one-hop network connections (see :cpp:class:`simgrid::s4u::Link`), i.e., a single wire. 
+They can also be used to abstract a larger network interconnect, e.g., the entire transcontinental network, into a 
+single element.
 
 **Parent tags:** :ref:`pf_tag_zone` (both leaf zones and inner zones) |br|
 **Children tags:** :ref:`pf_tag_prop` |br|
 **Attributes:**
 
 :``id``:  Link name. Must be unique over the whole platform.
-:``bandwidth``: Maximum bandwidth for this link. You must specify the
-   unit as follows.
+:``bandwidth``: Maximum bandwidth for this link. You must specify a unit as follows.
 
-   **Units in bytes and powers of 2** (1 KiBps = 1024 Bps):
-      Bps, KiBps, MiBps, GiBps, TiBps, PiBps, EiBps |br|
+   **Units in bytes and powers of 2** (1 KiBps = 1,024 Bps):
+     Bps, KiBps, MiBps, GiBps, TiBps, PiBps, or EiBps. |br|
    **Units in bits  and powers of 2** (1 Bps = 8 bps):
-      bps, Kibps, Mibps, Gibps, Tibps, Pibps, Eibps |br|
-   **Units in bytes and powers of 10:**  (1 KBps = 1000 Bps)
-      Bps, KBps, MBps, GBps, TBps, PBps, EBps |br|
+     bps, Kibps, Mibps, Gibps, Tibps, Pibps, or Eibps. |br|
+   **Units in bytes and powers of 10**  (1 KBps = 1,000 Bps):
+     Bps, KBps, MBps, GBps, TBps, PBps, or EBps. |br|
    **Units in bits  and powers of 10:**
-      'Ebps', 'Pbps', 'Tbps', 'Gbps', 'Mbps', 'kbps', 'bps'
+     bps, Kbps, Mbps, Gbps, Tbps, Pbps, or Ebps.
 
-:``latency``: Latency for this link (default: 0.0). You must specify
-   the unit as follows.
+:``latency``: Latency for this link (default: 0.0). You must specify a unit as follows.
 
    ==== =========== ======================
    Unit Meaning     Duration in seconds
@@ -160,27 +158,24 @@ Network links can represent one-hop network connections. See :cpp:class:`simgrid
    d    day         60 * 60 * 24
    w    week        60 * 60 * 24 * 7
    ==== =========== ======================
-   
-                     
-:``sharing_policy``: Sharing policy for the link. 
-   Either ``SHARED``, ``FATPIPE`` or ``SPLITDUPLEX`` (default: ``SHARED``).
 
-   If set to ``SHARED``, the available bandwidth is shared fairly
-   between all flows traversing this link. This tend to model the
-   sharing behavior of UDP or TCP.
+:``sharing_policy``: Sharing policy for the link. Possible values are ``SHARED``, ``FATPIPE`` or ``SPLITDUPLEX``
+   (default: ``SHARED``).
 
-   If set to ``FATPIPE``, the flows have no mutual impact, and each
-   flow can obtain the full bandwidth of this link. This is intended
-   to model the internet backbones that cannot get saturated by your
-   application: you mostly experience their latency.
+   If set to ``SHARED``, the available bandwidth is fairly shared among all the flows traversing this link. This tend to
+   model the bandwidth sharing behavior of the UDP or TCP protocols.
+
+   If set to ``FATPIPE``, flows have no impact on each other, hence each flow can exploit the full bandwidth of this
+   link. This aims at modeling the behavior of the Internet backbones that cannot get saturated by your application.
+   What you experience of such networks usually is their latency only.
 
    If set to ``SPLITDUPLEX``, the link models cross-traffic
    effects. Under the ``SHARED`` policy, two flows of reverse
    direction share the same resource, and can only get half of the
    bandwidth each. But TCP connections are full duplex, meaning that
-   all both directions can get the full bandwidth. To model this, any
-   link under the ``SPLITDUPLEX`` policy is split in two links (their
-   names are suffixed with "_UP" and "_DOWN"). You must then specify
+   both directions can get the full bandwidth. To model this, any
+   link under the ``SPLITDUPLEX`` policy is split in two links (whose
+   names are suffixed with "_UP" and "_DOWN"). Then you must specify
    which direction gets actually used when referring to that link in a
    :ref:`pf_tag_link_ctn`.
        
@@ -195,13 +190,13 @@ Network links can represent one-hop network connections. See :cpp:class:`simgrid
       8.0 60000000
       LOOPAFTER 12.0
 
-   - At time t=4, the bandwidth is of 40 MBps.
-   - At time t=8, it raises to 60MBps.
-   - At time t=24, it drops at 40 MBps again.
+   - At time t = 4, the bandwidth is of 40 MBps.
+   - At time t = 8, it raises to 60MBps.
+   - At time t = 24, it drops at 40 MBps again.
+
+   .. warning:: Don't get fooled: Bandwidth and Latency profiles of a :ref:`pf_tag_link` contain absolute values, while
+      Availability profiles of a :ref:`pf_tag_host` contain ratios.
 
-   .. warning:: Don't get fooled: Bandwidth and Latency profiles of a
-      :ref:`pf_tag_link` are absolute values, but Availability
-      profiles of :ref:`pf_tag_host` are ratio.
 :``latency_file``: File containing the latency profile.
    Almost every lines of such files describe timed events as ``date
    latency`` (in seconds).
@@ -213,19 +208,39 @@ Network links can represent one-hop network connections. See :cpp:class:`simgrid
       3.0 0.1
       LOOPAFTER 5.0
 
-   - At time t=1, the latency is of 1ms (0.001 second)
-   - At time t=3, the latency is of 100ms (0.1 second)
-   - At time t=8 (5 seconds after the last event), the profile loops.
-   - At time t=9 (1 second after the loop reset), the latency is back at 1ms.
-      
-   If your trace does not contain a LOOPAFTER line, then your profile
-   is only executed once and not repetitively.
-  
-   .. warning:: Don't get fooled: Bandwidth and Latency profiles of a
-      :ref:`pf_tag_link` are absolute values, but Availability
-      profiles of :ref:`pf_tag_host` are ratio.
+   - At time t = 1, the latency is of 1ms (0.001 second)
+   - At time t = 3, the latency is of 100ms (0.1 second)
+   - At time t = 8 (5 seconds after the last event), the profile loops.
+   - At time t = 9 (1 second after the loop reset), the latency is back at 1ms.
+
+   If your profile does not contain any LOOPAFTER line, then it will be executed only once and not in a repetitive way.
+
+  .. warning:: Don't get fooled: Bandwidth and Latency profiles of a :ref:`pf_tag_link` contain absolute values, while
+      Availability profiles of a :ref:`pf_tag_host` contain ratios.
+
 :``state_file``: File containing the state profile. See :ref:`pf_tag_host`.
-   
+
+|hr|
+           
+.. _pf_tag_link_ctn:
+
+------------------------------------------------------------------
+<link_ctn>
+------------------------------------------------------------------
+
+An element in a route, representing a previously defined link.
+
+**Parent tags:** :ref:`pf_tag_route` |br| 
+**Children tags:** none |br|
+**Attributes:**
+
+:``id``: Link that is to be included in this route.
+:``direction``: Whether to use the uplink (with ``UP``) or downlink
+               (with ``DOWN``) of the link. This is only valid if the
+               link has ``sharing=SPLITDUPLEX``.
+
+|hr|
+
 .. _pf_tag_peer:
 
 ------------------------------------------------------------------
@@ -234,7 +249,7 @@ Network links can represent one-hop network connections. See :cpp:class:`simgrid
 
 This tag represents a peer, as in Peer-to-Peer (P2P) networks. It is
 handy to model situations where hosts have an asymmetric
-connectivity. Computers connected through set-to-boxes usually have a
+connectivity. Computers connected through set-top-boxes usually have a
 much better download rate than their upload rate.  To model this,
 <peer> creates and connects several elements: an host, an upload link
 and a download link.
@@ -253,20 +268,21 @@ and a download link.
 :``lat``: Latency of both private links. See :ref:`pf_tag_link`.
 :``coordinates``: Coordinates of the gateway for this peer.
 
-   The communication latency between an host A=(xA,yA,zA) and an host
-   B=(xB,yB,zB) is computed as follows:
+   The communication latency between a host A = (xA,yA,zA) and a host B = (xB,yB,zB) is computed as follows:
  
    latency = sqrt( (xA-xB)² + (yA-yB)² ) + zA + zB
 
    See the documentation of
    :cpp:class:`simgrid::kernel::routing::VivaldiZone` for details on
-   how the latency is computed from the coordinate, and on the the up
+   how the latency is computed from the coordinates, and on how the up
    and down bandwidth are used.
 :``availability_file``: File containing the availability profile.
    See the full description in :ref:`pf_tag_host`
 :``state_file``: File containing the state profile.
    See the full description in :ref:`pf_tag_host`
 
+|hr|
+
 .. _pf_tag_platform:
 
 ------------------------------------------------------------------
@@ -283,9 +299,10 @@ and a download link.
              This versionning allow future evolutions, even if we
              avoid backward-incompatible changes. The current version
              is **4.1**. The ``simgrid_update_xml`` program can
-             upgrade most of the past platform files to the recent
+             upgrade most of the past platform files to the most recent
              formalism.
 
+|hr|
              
 .. _pf_tag_prop:
 
@@ -316,18 +333,40 @@ following functions:
 :``id``: Name of the defined property.
 :``value``: Value of the defined property.
 
+|hr|
+           
+.. _pf_tag_route:
+
+------------------------------------------------------------------
+<route>
+------------------------------------------------------------------
+
+A path between two network locations, composed of several :ref:`pf_tag_link`s. 
+
+**Parent tags:** :ref:`pf_tag_zone` |br| 
+**Children tags:** :ref:`pf_tag_link_ctn` |br|
+**Attributes:**
+
+:``src``: Host from which this route starts. Must be an existing host.
+:``dst``: Host to which this route leads. Must be an existing host.
+:``symmetrical``: Whether this route is symmetrical, ie, whether we
+                 are defining the route ``dst -> src`` at the same
+                 time. Valid values: ``yes``, ``no``,``YES``, ``NO``.
+
+|hr|
+
 .. _pf_tag_router:
 
 ------------------------------------------------------------------
 <router>
 ------------------------------------------------------------------
 
-A router is similar to an :ref:`pf_tag_host`, but it cannot contain
+A router is similar to a :ref:`pf_tag_host`, but it cannot contain
 any actor. It is only useful to some routing algorithms. In
 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 no inner zones nor clusters) |br|
+**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:**
 
@@ -335,6 +374,32 @@ break the routes that are longer than 1 hop.
    No other host or router may have the same name over the whole platform.
 :``coordinates``: Vivaldi coordinates. See :ref:`pf_tag_peer`.     
 
+|hr|
+
+.. _pf_tag_zone:
+
+------------------------------------------------------------------
+<zone>
+------------------------------------------------------------------
+
+A networking zone is an area in which elements are located. See :cpp:class:`simgrid::s4u::Zone`.
+
+**Parent tags:** :ref:`pf_tag_platform`, :ref:`pf_tag_zone` (only internal nodes, i.e., zones
+containing only inner zones or clusters but no basic
+elements such as host or peer) |br| 
+**Children tags (if internal zone):** :ref:`pf_tag_cluster`, :ref:`pf_tag_link`, :ref:`pf_tag_zone` |br|
+**Children tags (if leaf zone):** :ref:`pf_tag_host`, :ref:`pf_tag_link`, :ref:`pf_tag_peer` |br|
+**Attributes:**
+
+:``id``: Zone name.
+   No other zone may have the same name over the whole platform.
+:``routing``: Routing algorithm to use. 
+
+
 .. |br| raw:: html
 
    <br />
+
+.. |hr| raw:: html
+
+   <hr />
index 6691356..38db7a6 100644 (file)
@@ -7,8 +7,8 @@ $ ${javacmd:=java} -classpath ${classpath:=.} energy/pstate/Main ${srcdir:=.}/..
 > [MyHost2:dvfs_test:(3) 0.000000] [java/INFO] Count of Processor states=3
 > [MyHost2:dvfs_test:(3) 0.000000] [java/INFO] Current power peak=1.0E8
 > [MyHost1:dvfs_test:(2) 1.000000] [java/INFO] Task1 simulation time: 1.0
-> [MyHost2:dvfs_test:(3) 1.000000] [java/INFO] Task1 simulation time: 1.0
 > [MyHost1:dvfs_test:(2) 1.000000] [java/INFO] Changing power peak value to 2.0E7 (at index 2)
+> [MyHost2:dvfs_test:(3) 1.000000] [java/INFO] Task1 simulation time: 1.0
 > [MyHost2:dvfs_test:(3) 1.000000] [java/INFO] Changing power peak value to 2.0E7 (at index 2)
 > [MyHost1:dvfs_test:(2) 1.000000] [java/INFO] Current power peak=2.0E7
 > [MyHost2:dvfs_test:(3) 1.000000] [java/INFO] Current power peak=2.0E7
index c97451b..c9cc7ed 100644 (file)
@@ -20,6 +20,23 @@ if(SIMGRID_HAVE_MC)
     set_target_properties(bugged1_liveness_cleaner_off PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fno-stack-cleaner")
     add_dependencies(tests bugged1_liveness_cleaner_off)
   endif()
+
+  ADD_TESH_FACTORIES(mc-bugged1                "ucontext;raw" --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1.tesh)
+  ADD_TESH_FACTORIES(mc-bugged2                "ucontext;raw" --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged2.tesh)
+  IF(HAVE_UCONTEXT_CONTEXTS AND SIMGRID_PROCESSOR_x86_64) # liveness model-checking works only on 64bits (for now ...)
+    ADD_TESH(mc-bugged1-liveness-ucontext         --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1_liveness.tesh)
+    ADD_TESH(mc-bugged1-liveness-ucontext-sparse  --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1_liveness_sparse.tesh)
+    ADD_TESH(mc-bugged1-liveness-visited-ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1_liveness_visited.tesh)
+    ADD_TESH(mc-bugged1-liveness-visited-ucontext-sparse --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1_liveness_visited_sparse.tesh)
+    IF(HAVE_C_STACK_CLEANER)
+      # This test checks if the stack cleaner is making a difference:
+      ADD_TEST(mc-bugged1-liveness-stack-cleaner ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc/bugged1_liveness_stack_cleaner ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc/ ${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc/)
+    ENDIF()
+  ENDIF()
+
+  if (enable_coverage)
+    SET_TESTS_PROPERTIES(mc-bugged1-liveness-visited-ucontext PROPERTIES RUN_SERIAL "TRUE")
+  endif()
 endif()
 
 set(tesh_files   ${tesh_files}    ${CMAKE_CURRENT_SOURCE_DIR}/bugged1.tesh
index 971ad4c..f8c4584 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/env tesh
 
 ! expect return 2
-! timeout 20
+! timeout 30
 ! output ignore
 $ ${bindir:=.}/../../../../bin/simgrid-mc ${bindir:=.}/bugged1_liveness ${srcdir:=.}/../../../platforms/small_platform.xml ${srcdir:=.}/deploy_bugged1_liveness_visited.xml --log=xbt_cfg.thresh:warning "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=contexts/factory:ucontext --cfg=model-check/visited:100 --cfg=contexts/stack-size:256  --cfg=model-check/property:promela_bugged1_liveness
 > [  0.000000] (0:maestro@) Check the liveness property promela_bugged1_liveness
index 9c64e17..b903537 100644 (file)
@@ -19,9 +19,7 @@ $ $SG_TEST_EXENV ${bindir:=.}/platform-failures$EXEEXT --log=xbt_cfg.thres:criti
 > [  1.000000] (7:worker@Fafard) Waiting a message on worker-2
 > [  1.000000] (1:master@Tremblay) Mmh. Something went wrong with 'worker-1'. Nevermind. Let's keep going!
 > [  1.000000] (1:master@Tremblay) Send a message to worker-2
-> [  1.000000] (3:worker@Jupiter) Gloups. The cpu on which I'm running just turned off!. See you!
 > [  2.000000] (1:master@Tremblay) Mmh. Something went wrong with 'worker-2'. Nevermind. Let's keep going!
-> [  2.000000] (7:worker@Fafard) Gloups. The cpu on which I'm running just turned off!. See you!
 > [  2.000000] (0:maestro@) Restart processes on host Jupiter
 > [  2.000000] (1:master@Tremblay) Send a message to worker-3
 > [  2.000000] (8:worker@Jupiter) Waiting a message on worker-1
@@ -126,12 +124,10 @@ $ $SG_TEST_EXENV ${bindir:=.}/platform-failures$EXEEXT --log=xbt_cfg.thres:criti
 > [  1.000000] (7:worker@Fafard) Waiting a message on worker-2
 > [  1.000000] (1:master@Tremblay) Mmh. Something went wrong with 'worker-1'. Nevermind. Let's keep going!
 > [  1.000000] (1:master@Tremblay) Send a message to worker-2
-> [  1.000000] (3:worker@Jupiter) Gloups. The cpu on which I'm running just turned off!. See you!
 > [  2.000000] (0:maestro@) Restart processes on host Jupiter
 > [  2.000000] (8:worker@Jupiter) Waiting a message on worker-1
 > [  2.000000] (1:master@Tremblay) Mmh. Something went wrong with 'worker-2'. Nevermind. Let's keep going!
 > [  2.000000] (1:master@Tremblay) Send a message to worker-3
-> [  2.000000] (7:worker@Fafard) Gloups. The cpu on which I'm running just turned off!. See you!
 > [  2.010825] (2:worker@Tremblay) Execution complete.
 > [  2.010825] (2:worker@Tremblay) Waiting a message on worker-0
 > [  3.082474] (5:worker@Ginette) Start execution...
index cd933ff..3077640 100644 (file)
@@ -1,5 +1,6 @@
 foreach(example actor-create actor-daemon actor-join actor-kill actor-migrate actor-suspend actor-yield # actor-lifetime
-                exec-basic)
+                async-wait async-waitall async-waitany
+                exec-async exec-basic exec-dvfs exec-remote)
   set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh)
   set(examples_src  ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.py)
 
@@ -18,5 +19,8 @@ set(tesh_files    examples/python/actor-create/actor-create_d.xml
                   examples/python/actor-lifetime/actor-lifetime_d.xml
                  examples/python/actor-lifetime/actor-lifetime.py     # example broken so far
                  examples/python/actor-lifetime/actor-lifetime.tesh
+                 examples/python/async-wait/async-wait_d.xml
+                 examples/python/async-waitall/async-waitall_d.xml
+                 examples/python/async-waitany/async-waitany_d.xml
                   ${tesh_files}    PARENT_SCOPE)
 set(examples_src  ${examples_src}  PARENT_SCOPE)
index 4bb1d52..2c03dfa 100644 (file)
@@ -59,7 +59,7 @@ class Sender:
     Later, this actor class is instantiated twice in the simulation.
     """
 
-    def __init__(self, msg = "GaBuZoMeu", mbox = "mb42"):
+    def __init__(self, msg="GaBuZoMeu", mbox="mb42"):
         self.msg = msg
         self.mbox = mbox
 
index 824ec05..a9f6a31 100644 (file)
@@ -1,4 +1,4 @@
-$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/actor-join.py ${platfdir}/small_platform.xml
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/actor-join.py ${platfdir}/small_platform.xml
 > [Tremblay:master:(1) 0.000000] [python/INFO] Start sleeper
 > [Tremblay:sleeper from master:(2) 0.000000] [python/INFO] Sleeper started
 > [Tremblay:master:(1) 0.000000] [python/INFO] Join the sleeper (timeout 2)
index f408dc1..7c9f569 100644 (file)
@@ -14,7 +14,8 @@ class Sleeper:
     """This actor just sleeps until termination"""
 
     def __init__(self, *args):
-        this_actor.on_exit(lambda: print("BAAA")) # sys.exit(1); simgrid.info("Exiting now (done sleeping or got killed)."))
+        # sys.exit(1); simgrid.info("Exiting now (done sleeping or got killed)."))
+        this_actor.on_exit(lambda: print("BAAA"))
 
     def __call__(self):
         this_actor.info("Hello! I go to sleep.")
diff --git a/examples/python/async-wait/async-wait.py b/examples/python/async-wait/async-wait.py
new file mode 100644 (file)
index 0000000..39ab1ea
--- /dev/null
@@ -0,0 +1,87 @@
+# Copyright (c) 2010-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.
+
+import sys
+from simgrid import *
+
+# This example shows how to use simgrid::s4u::this_actor::wait() to wait for a given communication.
+#
+# As for the other asynchronous examples, the sender initiate all the messages it wants to send and
+# pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently.
+#
+# The sender then loops until there is no ongoing communication.
+
+
+class Sender:
+    def __init__(self, *args):
+        if len(args) != 3:
+            raise AssertionError(
+                "Actor sender requires 3 parameters, but got {:d}".format(len(args)))
+        self.messages_count = int(args[0])  # number of tasks
+        self.msg_size = int(args[1])  # communication cost (in bytes)
+        self.receivers_count = int(args[2])  # number of receivers
+
+    def __call__(self):
+        # List in which we store all ongoing communications
+        pending_comms = []
+
+        # Vector of the used mailboxes
+        mboxes = [Mailbox.by_name("receiver-{:d}".format(i)) for i in range(0, self.receivers_count)]
+
+        # Start dispatching all messages to receivers, in a round robin fashion
+        for i in range(0, self.messages_count):
+            content = "Message {:d}".format(i)
+            mbox = mboxes[i % self.receivers_count]
+
+            this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
+
+            # Create a communication representing the ongoing communication, and store it in pending_comms
+            comm = mbox.put_async(content, self.msg_size)
+            pending_comms.append(comm)
+
+        # Start sending messages to let the workers know that they should stop
+        for i in range(0, self.receivers_count):
+            mbox = mboxes[i]
+            this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
+            comm = mbox.put_async("finalize", 0)
+            pending_comms.append(comm)
+
+        this_actor.info("Done dispatching all messages")
+
+        # Now that all message exchanges were initiated, wait for their completion, in order of creation.
+        for comm in pending_comms:
+            comm.wait()
+        this_actor.info("Goodbye now!")
+
+
+class Receiver:
+    def __init__(self, *args):
+        if len(args) != 1:  # Receiver actor expects 1 argument: its ID
+            raise AssertionError("Actor receiver requires 1 parameter, but got {:d}".format(len(args)))
+        self.id = int(args[0])
+
+    def __call__(self):
+        # FIXME: It should be ok to initialize self.mbox from __init__, but it's currently failing on the OS X Jenkins slave.
+        self.mbox = Mailbox.by_name("receiver-{:d}".format(self.id))
+        this_actor.info("Wait for my first message")
+        while True:
+            received = self.mbox.get()
+            this_actor.info("I got a '{:s}'.".format(received))
+            if received == "finalize":
+                break  # If it's a finalize message, we're done.
+
+
+if __name__ == '__main__':
+    e = Engine(sys.argv)
+
+    e.load_platform(sys.argv[1])             # Load the platform description
+
+    # Register the classes representing the actors
+    e.register_actor("sender", Sender)
+    e.register_actor("receiver", Receiver)
+
+    e.load_deployment(sys.argv[2])
+
+    e.run()
diff --git a/examples/python/async-wait/async-wait.tesh b/examples/python/async-wait/async-wait.tesh
new file mode 100644 (file)
index 0000000..77ef002
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/async-wait.py ${platfdir}/small_platform_fatpipe.xml async-wait_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:sender@Tremblay) Send 'Message 0' to 'Mailbox(receiver-0)'
+> [  0.000000] (2:receiver@Ruby) Wait for my first message
+> [  0.000000] (1:sender@Tremblay) Send 'Message 1' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Send 'Message 2' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Done dispatching all messages
+> [  0.105458] (2:receiver@Ruby) I got a 'Message 0'.
+> [  0.210917] (2:receiver@Ruby) I got a 'Message 1'.
+> [  0.316375] (2:receiver@Ruby) I got a 'Message 2'.
+> [  0.318326] (2:receiver@Ruby) I got a 'finalize'.
+> [  0.318326] (1:sender@Tremblay) Goodbye now!
\ No newline at end of file
diff --git a/examples/python/async-wait/async-wait_d.xml b/examples/python/async-wait/async-wait_d.xml
new file mode 100644 (file)
index 0000000..def2e5c
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+  <!-- The master actor (with some arguments) -->
+  <actor host="Tremblay" function="sender">
+    <argument value="3"/>       <!-- Number of tasks -->
+    <argument value="50000000"/>  <!-- Computation size of tasks -->
+    <argument value="1"/>         <!-- Number of receivers -->
+  </actor>
+  <!-- The receiver processes --> 
+  <actor host="Ruby" function="receiver">
+    <argument value="0"/> <!-- id -->
+  </actor>
+</platform>
diff --git a/examples/python/async-waitall/async-waitall.py b/examples/python/async-waitall/async-waitall.py
new file mode 100644 (file)
index 0000000..46cd50c
--- /dev/null
@@ -0,0 +1,87 @@
+# Copyright (c) 2010-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.
+
+import sys
+from simgrid import *
+
+# This example shows how to block on the completion of a set of communications.
+#
+# As for the other asynchronous examples, the sender initiate all the messages it wants to send and
+# pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently.
+#
+# The sender then blocks until all ongoing communication terminate, using simgrid.Comm.wait_all()
+
+
+class Sender:
+    def __init__(self, *args):
+        if len(args) != 3:
+            raise AssertionError("Actor sender requires 3 parameters, but got {:d}".format(len(args)))
+        self.messages_count = int(args[0])  # number of tasks
+        self.msg_size = int(args[1])  # communication cost (in bytes)
+        self.receivers_count = int(args[2])  # number of receivers
+
+    def __call__(self):
+        # List in which we store all ongoing communications
+        pending_comms = []
+
+        # Vector of the used mailboxes
+        mboxes = [Mailbox.by_name("receiver-{:d}".format(i))
+                  for i in range(0, self.receivers_count)]
+
+        # Start dispatching all messages to receivers, in a round robin fashion
+        for i in range(0, self.messages_count):
+            content = "Message {:d}".format(i)
+            mbox = mboxes[i % self.receivers_count]
+
+            this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
+
+            # Create a communication representing the ongoing communication, and store it in pending_comms
+            comm = mbox.put_async(content, self.msg_size)
+            pending_comms.append(comm)
+
+        # Start sending messages to let the workers know that they should stop
+        for i in range(0, self.receivers_count):
+            mbox = mboxes[i]
+            this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
+            comm = mbox.put_async("finalize", 0)
+            pending_comms.append(comm)
+
+        this_actor.info("Done dispatching all messages")
+
+        # Now that all message exchanges were initiated, wait for their completion in one single call
+        Comm.wait_all(pending_comms)
+
+        this_actor.info("Goodbye now!")
+
+
+class Receiver:
+    def __init__(self, *args):
+        if len(args) != 1:  # Receiver actor expects 1 argument: its ID
+            raise AssertionError(
+                "Actor receiver requires 1 parameter, but got {:d}".format(len(args)))
+        self.mbox = Mailbox.by_name("receiver-{:s}".format(args[0]))
+
+    def __call__(self):
+        this_actor.info("Wait for my first message")
+        while True:
+            received = self.mbox.get()
+            this_actor.info("I got a '{:s}'.".format(received))
+            if received == "finalize":
+                break  # If it's a finalize message, we're done.
+
+
+if __name__ == '__main__':
+    e = Engine(sys.argv)
+
+    # Load the platform description
+    e.load_platform(sys.argv[1])
+
+    # Register the classes representing the actors
+    e.register_actor("sender", Sender)
+    e.register_actor("receiver", Receiver)
+
+    e.load_deployment(sys.argv[2])
+
+    e.run()
diff --git a/examples/python/async-waitall/async-waitall.tesh b/examples/python/async-waitall/async-waitall.tesh
new file mode 100644 (file)
index 0000000..5a66704
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/async-waitall.py ${platfdir}/small_platform_fatpipe.xml async-waitall_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:sender@Tremblay) Send 'Message 0' to 'Mailbox(receiver-0)'
+> [  0.000000] (2:receiver@Ruby) Wait for my first message
+> [  0.000000] (3:receiver@Perl) Wait for my first message
+> [  0.000000] (1:sender@Tremblay) Send 'Message 1' to 'Mailbox(receiver-1)'
+> [  0.000000] (1:sender@Tremblay) Send 'Message 2' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Send 'Message 3' to 'Mailbox(receiver-1)'
+> [  0.000000] (1:sender@Tremblay) Send 'Message 4' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-1)'
+> [  0.000000] (1:sender@Tremblay) Done dispatching all messages
+> [  0.004022] (2:receiver@Ruby) I got a 'Message 0'.
+> [  0.004022] (3:receiver@Perl) I got a 'Message 1'.
+> [  0.008043] (2:receiver@Ruby) I got a 'Message 2'.
+> [  0.008043] (3:receiver@Perl) I got a 'Message 3'.
+> [  0.009995] (3:receiver@Perl) I got a 'finalize'.
+> [  0.012065] (2:receiver@Ruby) I got a 'Message 4'.
+> [  0.014016] (2:receiver@Ruby) I got a 'finalize'.
+> [  0.014016] (1:sender@Tremblay) Goodbye now!
diff --git a/examples/python/async-waitall/async-waitall_d.xml b/examples/python/async-waitall/async-waitall_d.xml
new file mode 100644 (file)
index 0000000..8e51eff
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+  <!-- The master actor (with some arguments) -->
+  <actor host="Tremblay" function="sender">
+    <argument value="5"/>         <!-- Number of messages -->
+    <argument value="1000000"/>   <!-- Size of messages -->
+    <argument value="2"/>         <!-- Number of receivers -->
+  </actor>
+  <!-- The receiver processes. -->
+  <actor host="Ruby" function="receiver">
+    <argument value="0"/>
+  </actor>
+  <actor host="Perl" function="receiver">
+    <argument value="1"/>
+  </actor>
+</platform>
diff --git a/examples/python/async-waitany/async-waitany.py b/examples/python/async-waitany/async-waitany.py
new file mode 100644 (file)
index 0000000..274b96a
--- /dev/null
@@ -0,0 +1,101 @@
+# Copyright (c) 2010-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.
+
+import sys
+from simgrid import *
+
+# This example shows how to block on the completion of a set of communications.
+#
+# As for the other asynchronous examples, the sender initiate all the messages it wants to send and
+# pack the resulting simgrid.Comm objects in a list. All messages thus occur concurrently.
+#
+# The sender then loops until there is no ongoing communication. Using wait_any() ensures that the sender
+# will notice events as soon as they occur even if it does not follow the order of the container.
+#
+# Here, finalize messages will terminate earlier because their size is 0, so they travel faster than the
+# other messages of this application.  As expected, the trace shows that the finalize of worker 1 is
+# processed before 'Message 5' that is sent to worker 0.
+
+
+class Sender:
+    def __init__(self, *args):
+        if len(args) != 3:
+            raise AssertionError("Actor sender requires 3 parameters, but got {:d}".format(len(args)))
+        self.messages_count = int(args[0])  # number of tasks
+        self.msg_size = int(args[1])  # communication cost (in bytes)
+        self.receivers_count = int(args[2])  # number of receivers
+
+    def __call__(self):
+        # List in which we store all ongoing communications
+        pending_comms = []
+
+        # Vector of the used mailboxes
+        mboxes = [Mailbox.by_name("receiver-{:d}".format(i))
+                  for i in range(0, self.receivers_count)]
+
+        # Start dispatching all messages to receivers, in a round robin fashion
+        for i in range(0, self.messages_count):
+            content = "Message {:d}".format(i)
+            mbox = mboxes[i % self.receivers_count]
+
+            this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
+
+            # Create a communication representing the ongoing communication, and store it in pending_comms
+            comm = mbox.put_async(content, self.msg_size)
+            pending_comms.append(comm)
+
+        # Start sending messages to let the workers know that they should stop
+        for i in range(0, self.receivers_count):
+            mbox = mboxes[i]
+            this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
+            comm = mbox.put_async("finalize", 0)
+            pending_comms.append(comm)
+
+        this_actor.info("Done dispatching all messages")
+
+        # Now that all message exchanges were initiated, wait for their completion, in order of completion.
+        #
+        # This loop waits for first terminating message with wait_any() and remove it with del, until all comms are
+        # terminated.
+        # Even in this simple example, the pending comms do not terminate in the exact same order of creation.
+        while pending_comms:
+            changed_pos = Comm.wait_any(pending_comms)
+            del pending_comms[changed_pos]
+            if (changed_pos != 0):
+                this_actor.info(
+                    "Remove the {:d}th pending comm: it terminated earlier than another comm that was initiated first.".format(changed_pos))
+
+        this_actor.info("Goodbye now!")
+
+
+class Receiver:
+    def __init__(self, *args):
+        if len(args) != 1:  # Receiver actor expects 1 argument: its ID
+            raise AssertionError(
+                "Actor receiver requires 1 parameter, but got {:d}".format(len(args)))
+        self.mbox = Mailbox.by_name("receiver-{:s}".format(args[0]))
+
+    def __call__(self):
+        this_actor.info("Wait for my first message")
+        while True:
+            received = self.mbox.get()
+            this_actor.info("I got a '{:s}'.".format(received))
+            if received == "finalize":
+                break  # If it's a finalize message, we're done.
+
+
+if __name__ == '__main__':
+    e = Engine(sys.argv)
+
+    # Load the platform description
+    e.load_platform(sys.argv[1])
+
+    # Register the classes representing the actors
+    e.register_actor("sender", Sender)
+    e.register_actor("receiver", Receiver)
+
+    e.load_deployment(sys.argv[2])
+
+    e.run()
diff --git a/examples/python/async-waitany/async-waitany.tesh b/examples/python/async-waitany/async-waitany.tesh
new file mode 100644 (file)
index 0000000..4a1381a
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/env tesh
+
+p Testing Comm.wait_any()
+
+! output sort 19
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/async-waitany.py ${platfdir}/small_platform.xml async-waitany_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:sender@Tremblay) Send 'Message 0' to 'Mailbox(receiver-0)'
+> [  0.000000] (2:receiver@Fafard) Wait for my first message
+> [  0.000000] (3:receiver@Jupiter) Wait for my first message
+> [  0.000000] (1:sender@Tremblay) Send 'Message 1' to 'Mailbox(receiver-1)'
+> [  0.000000] (1:sender@Tremblay) Send 'Message 2' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Send 'Message 3' to 'Mailbox(receiver-1)'
+> [  0.000000] (1:sender@Tremblay) Send 'Message 4' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Send 'Message 5' to 'Mailbox(receiver-1)'
+> [  0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-0)'
+> [  0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-1)'
+> [  0.000000] (1:sender@Tremblay) Done dispatching all messages
+> [  0.158397] (2:receiver@Fafard) I got a 'Message 0'.
+> [  0.169155] (3:receiver@Jupiter) I got a 'Message 1'.
+> [  0.316794] (2:receiver@Fafard) I got a 'Message 2'.
+> [  0.338309] (3:receiver@Jupiter) I got a 'Message 3'.
+> [  0.475190] (2:receiver@Fafard) I got a 'Message 4'.
+> [  0.500898] (2:receiver@Fafard) I got a 'finalize'.
+> [  0.500898] (1:sender@Tremblay) Remove the 1th pending comm: it terminated earlier than another comm that was initiated first.
+> [  0.507464] (3:receiver@Jupiter) I got a 'Message 5'.
+> [  0.526478] (3:receiver@Jupiter) I got a 'finalize'.
+> [  0.526478] (1:sender@Tremblay) Goodbye now!
diff --git a/examples/python/async-waitany/async-waitany_d.xml b/examples/python/async-waitany/async-waitany_d.xml
new file mode 100644 (file)
index 0000000..4b4161d
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+  <!-- The master actor (with some arguments) -->
+  <actor host="Tremblay" function="sender">
+    <argument value="6"/>         <!-- Number of messages -->
+    <argument value="1000000"/>   <!-- Size of messages -->
+    <argument value="2"/>         <!-- Number of receivers -->
+  </actor>
+  <!-- The receiver processes -->
+  <actor host="Fafard" function="receiver">
+    <argument value="0"/>       <!-- My name -->
+  </actor>
+  <actor host="Jupiter" function="receiver">
+    <argument value="1"/>       <!-- My name -->
+  </actor>
+</platform>
diff --git a/examples/python/exec-async/exec-async.py b/examples/python/exec-async/exec-async.py
new file mode 100644 (file)
index 0000000..42313ea
--- /dev/null
@@ -0,0 +1,66 @@
+# Copyright (c) 2018-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.
+
+import sys
+from simgrid import *
+
+
+class Waiter:
+    """ This actor simply waits for its task completion after starting it. That's exactly equivalent to synchronous execution. """
+
+    def __call__(self):
+        computation_amount = this_actor.get_host().speed
+        this_actor.info("Execute {:.0f} flops, should take 1 second.".format(computation_amount))
+        activity = this_actor.exec_init(computation_amount)
+        activity.start()
+        activity.wait()
+
+        this_actor.info("Goodbye now!")
+
+
+class Monitor:
+    """This actor tests the ongoing execution until its completion, and don't wait before it's terminated."""
+
+    def __call__(self):
+        computation_amount = this_actor.get_host().speed
+        this_actor.info("Execute {:.0f} flops, should take 1 second.".format(computation_amount))
+        activity = this_actor.exec_init(computation_amount).start()
+
+        while not activity.test():
+            this_actor.info("Remaining amount of flops: {:.0f} ({:.0f}%)".format(
+                activity.remaining, 100 * activity.remaining_ratio))
+            this_actor.sleep_for(0.3)
+        activity.wait()
+
+        this_actor.info("Goodbye now!")
+
+
+class Canceller:
+    """This actor cancels the ongoing execution after a while."""
+
+    def __call__(self):
+        computation_amount = this_actor.get_host().speed
+        this_actor.info("Execute {:.0f} flops, should take 1 second.".format(computation_amount))
+        activity = this_actor.exec_init(computation_amount).start()
+
+        this_actor.sleep_for(0.5)
+        this_actor.info("I changed my mind, cancel!")
+        activity.cancel()
+
+        this_actor.info("Goodbye now!")
+
+
+if __name__ == '__main__':
+    e = Engine(sys.argv)
+    if len(sys.argv) < 2:
+        raise AssertionError("Usage: exec-async.py platform_file [other parameters]")
+
+    e.load_platform(sys.argv[1])
+
+    Actor.create("wait", Host.by_name("Fafard"), Waiter())
+    Actor.create("monitor", Host.by_name("Ginette"), Monitor())
+    Actor.create("cancel", Host.by_name("Boivin"), Canceller())
+
+    e.run()
diff --git a/examples/python/exec-async/exec-async.tesh b/examples/python/exec-async/exec-async.tesh
new file mode 100644 (file)
index 0000000..d18f11c
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/exec-async.py ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:wait@Fafard) Execute 76296000 flops, should take 1 second.
+> [  0.000000] (2:monitor@Ginette) Execute 48492000 flops, should take 1 second.
+> [  0.000000] (3:cancel@Boivin) Execute 98095000 flops, should take 1 second.
+> [  0.000000] (2:monitor@Ginette) Remaining amount of flops: 48492000 (100%)
+> [  0.300000] (2:monitor@Ginette) Remaining amount of flops: 33944400 (70%)
+> [  0.500000] (3:cancel@Boivin) I changed my mind, cancel!
+> [  0.500000] (3:cancel@Boivin) Goodbye now!
+> [  0.600000] (2:monitor@Ginette) Remaining amount of flops: 19396800 (40%)
+> [  0.900000] (2:monitor@Ginette) Remaining amount of flops: 4849200 (10%)
+> [  1.000000] (1:wait@Fafard) Goodbye now!
+> [  1.200000] (2:monitor@Ginette) Goodbye now!
index fa001b9..7d08847 100644 (file)
@@ -34,7 +34,7 @@ i = 0
 if "--" in sys.argv:
     i = sys.argv.index("--")
 e = Engine(sys.argv[0:i])
-e.load_platform(sys.argv[i+1])
+e.load_platform(sys.argv[i + 1])
 
 Actor.create("executor", Host.by_name("Tremblay"), executor)
 Actor.create("privileged", Host.by_name("Tremblay"), privileged)
diff --git a/examples/python/exec-dvfs/exec-dvfs.py b/examples/python/exec-dvfs/exec-dvfs.py
new file mode 100644 (file)
index 0000000..b04e0b9
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright (c) 2007-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.
+
+import sys
+from simgrid import *
+
+
+class Dvfs:
+    def __call__(self):
+        workload = 100E6
+        host = this_actor.get_host()
+
+        nb = host.get_pstate_count()
+        this_actor.info("Count of Processor states={:d}".format(nb))
+
+        this_actor.info("Current power peak={:f}".format(host.speed))
+
+        # Run a task
+        this_actor.execute(workload)
+
+        task_time = Engine.get_clock()
+        this_actor.info("Task1 duration: {:.2f}".format(task_time))
+
+        # Change power peak
+        new_pstate = 2
+
+        this_actor.info("Changing power peak value to {:f} (at index {:d})".format( host.get_pstate_speed(new_pstate), new_pstate))
+
+        host.pstate = new_pstate
+
+        this_actor.info("Current power peak={:f}".format(host.speed))
+
+        # Run a second task
+        this_actor.execute(workload)
+
+        task_time = Engine.get_clock() - task_time
+        this_actor.info("Task2 duration: {:.2f}".format(task_time))
+
+        # Verify that the default pstate is set to 0
+        host2 = Host.by_name("MyHost2")
+        this_actor.info("Count of Processor states={:d}".format(host2.get_pstate_count()))
+
+        this_actor.info("Current power peak={:f}".format(host2.speed))
+
+if __name__ == '__main__':
+    e = Engine(sys.argv)
+    if len(sys.argv) < 2:
+        raise AssertionError("Usage: exec-dvfs.py platform_file [other parameters] (got {:d} params)".format(len(sys.argv)))
+
+    e.load_platform(sys.argv[1])
+    Actor.create("dvfs_test", Host.by_name("MyHost1"), Dvfs())
+    Actor.create("dvfs_test", Host.by_name("MyHost2"), Dvfs())
+
+    e.run()
diff --git a/examples/python/exec-dvfs/exec-dvfs.tesh b/examples/python/exec-dvfs/exec-dvfs.tesh
new file mode 100644 (file)
index 0000000..215897b
--- /dev/null
@@ -0,0 +1,39 @@
+#!/usr/bin/env tesh
+
+p Testing the DVFS-related functions
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/exec-dvfs.py ${platfdir}/energy_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:dvfs_test@MyHost1) Count of Processor states=3
+> [  0.000000] (1:dvfs_test@MyHost1) Current power peak=100000000.000000
+> [  0.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
+> [  0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000
+> [  1.000000] (1:dvfs_test@MyHost1) Task1 duration: 1.00
+> [  1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2)
+> [  1.000000] (2:dvfs_test@MyHost2) Task1 duration: 1.00
+> [  1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2)
+> [  1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
+> [  1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
+> [  6.000000] (1:dvfs_test@MyHost1) Task2 duration: 5.00
+> [  6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3
+> [  6.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
+> [  6.000000] (2:dvfs_test@MyHost2) Task2 duration: 5.00
+> [  6.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
+> [  6.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/exec-dvfs.py ${platfdir}/energy_cluster.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:dvfs_test@MyHost1) Count of Processor states=3
+> [  0.000000] (1:dvfs_test@MyHost1) Current power peak=100000000.000000
+> [  0.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
+> [  0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000
+> [  1.000000] (1:dvfs_test@MyHost1) Task1 duration: 1.00
+> [  1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2)
+> [  1.000000] (2:dvfs_test@MyHost2) Task1 duration: 1.00
+> [  1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2)
+> [  1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
+> [  1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
+> [  6.000000] (1:dvfs_test@MyHost1) Task2 duration: 5.00
+> [  6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3
+> [  6.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
+> [  6.000000] (2:dvfs_test@MyHost2) Task2 duration: 5.00
+> [  6.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
+> [  6.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
diff --git a/examples/python/exec-remote/exec-remote.py b/examples/python/exec-remote/exec-remote.py
new file mode 100644 (file)
index 0000000..ffb834e
--- /dev/null
@@ -0,0 +1,61 @@
+# Copyright (c) 2018-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.
+
+import sys
+from simgrid import *
+
+
+class Wizard:
+    def __call__(self):
+
+        fafard = Host.by_name("Fafard")
+        ginette = Host.by_name("Ginette")
+        boivin = Host.by_name("Boivin")
+
+        this_actor.info("I'm a wizard! I can run a task on the Ginette host from the Fafard one! Look!")
+        activity = this_actor.exec_init(48.492e6)
+        activity.host = ginette
+        activity.start()
+        this_actor.info("It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).")
+
+        this_actor.sleep_for(0.1)
+        this_actor.info("Loads in flops/s: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format(boivin.load, fafard.load,
+                                                                                                ginette.load))
+        activity.wait()
+        this_actor.info("Done!")
+
+        this_actor.info("And now, harder. Start a remote task on Ginette and move it to Boivin after 0.5 sec")
+        activity = this_actor.exec_init(73293500)
+        activity.host = ginette
+        activity.start()
+
+        this_actor.sleep_for(0.5)
+        this_actor.info(
+            "Loads before the move: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format(
+                boivin.load,
+                fafard.load,
+                ginette.load))
+
+        activity.host = boivin
+
+        this_actor.sleep_for(0.1)
+        this_actor.info(
+            "Loads after the move: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format(
+                boivin.load,
+                fafard.load,
+                ginette.load))
+
+        activity.wait()
+        this_actor.info("Done!")
+
+
+if __name__ == '__main__':
+    e = Engine(sys.argv)
+
+    e.load_platform(sys.argv[1])
+
+    Actor.create("test", Host.by_name("Fafard"), Wizard())
+
+    e.run()
diff --git a/examples/python/exec-remote/exec-remote.tesh b/examples/python/exec-remote/exec-remote.tesh
new file mode 100644 (file)
index 0000000..400b4dd
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/exec-remote.py ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [  0.000000] (1:test@Fafard) I'm a wizard! I can run a task on the Ginette host from the Fafard one! Look!
+> [  0.000000] (1:test@Fafard) It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).
+> [  0.100000] (1:test@Fafard) Loads in flops/s: Boivin=0; Fafard=0; Ginette=48492000
+> [  1.000000] (1:test@Fafard) Done!
+> [  1.000000] (1:test@Fafard) And now, harder. Start a remote task on Ginette and move it to Boivin after 0.5 sec
+> [  1.500000] (1:test@Fafard) Loads before the move: Boivin=0; Fafard=0; Ginette=48492000
+> [  1.600000] (1:test@Fafard) Loads after the move: Boivin=98095000; Fafard=0; Ginette=0
+> [  2.000000] (1:test@Fafard) Done!
index 3942d21..9596c01 100644 (file)
@@ -9,7 +9,7 @@ foreach (example actor-create actor-daemon actor-exiting actor-join actor-kill
                  cloud-capping cloud-migration cloud-simple
                  energy-exec energy-boot energy-link energy-vm
                  engine-filtering
-                 exec-async exec-basic exec-dvfs exec-monitor exec-ptask exec-remote
+                 exec-async exec-basic exec-dvfs exec-ptask exec-remote
                  io-async io-file-system io-file-remote io-storage-raw
                  platform-failures platform-profile platform-properties
                  plugin-hostload
index d7f8291..8fce725 100644 (file)
@@ -155,24 +155,33 @@ Communications on the Network
  - **Basic asynchronous communications:**
    Illustrates how to have non-blocking communications, that are
    communications running in the background leaving the process free
-   to do something else during their completion. The main functions
-   involved are :cpp:func:`simgrid::s4u::Mailbox::put_async()` and 
-   :cpp:func:`simgrid::s4u::Comm::wait()`.
-   |br| `examples/s4u/async-wait/s4u-async-wait.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-wait/s4u-async-wait.cpp>`_
+   to do something else during their completion. 
+   
+   - |cpp| `examples/s4u/async-wait/s4u-async-wait.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-wait/s4u-async-wait.cpp>`_
+     :cpp:func:`simgrid::s4u::Mailbox::put_async()` and :cpp:func:`simgrid::s4u::Comm::wait()`
+   - |py|  `examples/python/async-wait/async-wait.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/async-wait/async-wait.py>`_
+     :py:func:`simgrid.Mailbox.put_async()` :py:func:`simgrid.Comm.wait()`
 
  - **Waiting for all communications in a set:**
-   The :cpp:func:`simgrid::s4u::Comm::wait_all()` function is useful
-   when you want to block until all activities in a given set have
-   completed. 
-   |br| `examples/s4u/async-waitall/s4u-async-waitall.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-waitall/s4u-async-waitall.cpp>`_
+   The `wait_all()` function is useful when you want to block until
+   all activities in a given set have completed. 
+   
+   - |cpp| `examples/s4u/async-waitall/s4u-async-waitall.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-waitall/s4u-async-waitall.cpp>`_
+     :cpp:func:`simgrid::s4u::Comm::wait_all()`
+   - |py| `examples/python/async-waitall/async-waitall.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/async-waitall/async-waitall.py>`_
+     :py:func:`simgrid.Comm.wait_all()`
 
  - **Waiting for the first completed communication in a set:**
-   The :cpp:func:`simgrid::s4u::Comm::wait_any()` function is useful
+   The `wait_any()` function is useful
    when you want to block until one activity of the set completes, no
-   matter which terminates first.    
-   |br| `examples/s4u/async-waitany/s4u-async-waitany.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-waitany/s4u-async-waitany.cpp>`_
-
-.. todo:: add the `ready` example here
+   matter which terminates first.
+   
+   - |cpp| `examples/s4u/async-waitany/s4u-async-waitany.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-waitany/s4u-async-waitany.cpp>`_
+     :cpp:func:`simgrid::s4u::Comm::wait_any()`
+   - |py| `examples/python/async-waitany/async-waitany.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/async-waitany/async-waitany.py>`_
+     :py:func:`simgrid.Comm.wait_any()`
+     
+.. todo:: review the `ready` and `waituntil` examples and add them here.
    
 .. _s4u_ex_execution:
 
@@ -192,28 +201,33 @@ Executions on the CPU
   - **Asynchronous execution:**
     You can start asynchronous executions, just like you would fire
     background threads.
-    |br| `examples/s4u/exec-async/s4u-exec-async.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-async/s4u-exec-async.cpp>`_
     
-  - **Monitoring asynchronous executions:**
-    This example shows how to start an asynchronous execution, and
-    monitor its status.
-    |br| `examples/s4u/exec-monitor/s4u-exec-monitor.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-monitor/s4u-exec-monitor.cpp>`_
+    - |cpp| `examples/s4u/exec-async/s4u-exec-async.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-async/s4u-exec-async.cpp>`_
+    - |py|  `examples/python/exec-async/exec-async.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/exec-async/exec-async.py>`_
     
   - **Remote execution:**
-    Before its start, you can change the host on which a given execution will occur.
-    |br| `examples/s4u/exec-remote/s4u-exec-remote.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-remote/s4u-exec-remote.cpp>`_
-
-  - **Using Pstates on a host:**
-    Shows how define a set of pstatesfor a host in the XML, and how the current
-    pstate can be accessed/changed with :cpp:func:`simgrid::s4u::Host::get_pstate_speed` and :cpp:func:`simgrid::s4u::Host::set_pstate`.
-    |br| `examples/s4u/exec-dvfs/s4u-exec-dvfs.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-dvfs/s4u-exec-dvfs.cpp>`_
-    |br| `examples/platforms/energy_platform.xml <https://framagit.org/simgrid/simgrid/tree/master/examples/platforms/energy_platform.xml>`_
+    You can start executions on remote hosts, or even change the host
+    on which they occur during their execution.
+    
+    - |cpp| `examples/s4u/exec-remote/s4u-exec-remote.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-remote/s4u-exec-remote.cpp>`_
+    - |py| `examples/python/exec-remote/exec-remote.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/exec-remote/exec-remote.py>`_
 
   - **Parallel executions:**
     These objects are convenient abstractions of parallel
     computational kernels that span over several machines, such as a
-    PDGEM and the other ScaLAPACK routines.
+    PDGEM and the other ScaLAPACK routines. Note that this only works
+    with the "ptask_L07" host model (``--cfg=host/model:ptask_L07``).
     |br| `examples/s4u/exec-ptask/s4u-exec-ptask.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-ptask/s4u-exec-ptask.cpp>`_
+    
+  - **Using Pstates on a host:**
+    `examples/platforms/energy_platform.xml <https://framagit.org/simgrid/simgrid/tree/master/examples/platforms/energy_platform.xml>`_
+    shows how define a set of pstates in the XML. The current pstate
+    of an host can then be accessed and changed from the program.
+
+    - |cpp| `examples/s4u/exec-dvfs/s4u-exec-dvfs.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-dvfs/s4u-exec-dvfs.cpp>`_
+      :cpp:func:`simgrid::s4u::Host::get_pstate_speed` and :cpp:func:`simgrid::s4u::Host::set_pstate`.
+    - |py|  `examples/python/exec-dvfs/exec-dvfs.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/exec-dvfs/exec-dvfs.py>`_
+      :py:func:`Host.get_pstate_speed` and :py:func:`Host.set_pstate`.
 
 I/O on Disks and Files
 ----------------------
index d24aab7..9895d9f 100644 (file)
@@ -51,7 +51,7 @@ int main(int argc, char* argv[])
 
   /* Register a callback in the Actor::on_destruction signal. It will be called for every terminated actors */
   simgrid::s4u::Actor::on_destruction.connect(
-      [](simgrid::s4u::ActorPtr actor) { XBT_INFO("Actor %s stops now", actor->get_cname()); });
+      [](simgrid::s4u::Actor const& actor) { XBT_INFO("Actor %s stops now", actor.get_cname()); });
 
   /* Create some actors */
   simgrid::s4u::Actor::create("A", simgrid::s4u::Host::by_name("Tremblay"), actor_a);
index e3d83cf..0b6f83f 100644 (file)
@@ -6,7 +6,7 @@
 /* This example shows how to block on the completion of a set of communications.
  *
  * As for the other asynchronous examples, the sender initiate all the messages it wants to send and
- * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently.
+ * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occur concurrently.
  *
  * The sender then blocks until all ongoing communication terminate, using simgrid::s4u::Comm::wait_all()
  *
index 4d3b1fa..ca5c085 100644 (file)
@@ -6,7 +6,7 @@
 /* This example shows how to use simgrid::s4u::this_actor::wait_any() to wait for the first occurring event.
  *
  * As for the other asynchronous examples, the sender initiate all the messages it wants to send and
- * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently.
+ * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occur concurrently.
  *
  * The sender then loops until there is no ongoing communication. Using wait_any() ensures that the sender
  * will notice events as soon as they occur even if it does not follow the order of the container.
index 94f1782..05b9a33 100644 (file)
@@ -7,20 +7,43 @@
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
 
-static void test(double computation_amount, double priority)
+/* This actor simply waits for its task completion after starting it.
+ * That's exactly equivalent to synchronous execution. */
+static void waiter()
 {
-  XBT_INFO("Hello! Execute %g flops with priority %g", computation_amount, priority);
+  double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed();
+  XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
   simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_init(computation_amount);
-  activity->set_priority(priority);
   activity->start();
   activity->wait();
 
   XBT_INFO("Goodbye now!");
 }
 
-static void test_cancel(double computation_amount)
+/* This actor tests the ongoing execution until its completion, and don't wait before it's terminated. */
+static void monitor()
 {
-  XBT_INFO("Hello! Execute %g flops, should take 1 second", computation_amount);
+  double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed();
+  XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
+  simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_init(computation_amount);
+  activity->start();
+
+  while (not activity->test()) {
+    XBT_INFO("Remaining amount of flops: %g (%.0f%%)", activity->get_remaining(),
+             100 * activity->get_remaining_ratio());
+    simgrid::s4u::this_actor::sleep_for(0.3);
+  }
+  activity->wait();
+
+  XBT_INFO("Goodbye now!");
+}
+
+/* This actor cancels the ongoing execution after a while. */
+static void canceller()
+{
+  double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed();
+
+  XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
   simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_async(computation_amount);
   simgrid::s4u::this_actor::sleep_for(0.5);
   XBT_INFO("I changed my mind, cancel!");
@@ -33,9 +56,14 @@ int main(int argc, char* argv[])
 {
   simgrid::s4u::Engine e(&argc, argv);
   e.load_platform(argv[1]);
-  simgrid::s4u::Actor::create("test", simgrid::s4u::Host::by_name("Fafard"), test, 7.6296e+07, 1.0);
-  simgrid::s4u::Actor::create("test", simgrid::s4u::Host::by_name("Fafard"), test, 7.6296e+07, 2.0);
-  simgrid::s4u::Actor::create("test_cancel", simgrid::s4u::Host::by_name("Boivin"), test_cancel, 98.095e+07);
+
+  simgrid::s4u::Host* fafard  = simgrid::s4u::Host::by_name("Fafard");
+  simgrid::s4u::Host* ginette = simgrid::s4u::Host::by_name("Ginette");
+  simgrid::s4u::Host* boivin  = simgrid::s4u::Host::by_name("Boivin");
+
+  simgrid::s4u::Actor::create("wait", fafard, waiter);
+  simgrid::s4u::Actor::create("monitor", ginette, monitor);
+  simgrid::s4u::Actor::create("cancel", boivin, canceller);
 
   e.run();
 
index 3246fae..7b58519 100644 (file)
@@ -1,12 +1,15 @@
 #!/usr/bin/env tesh
 
-! output sort 19
 $ $SG_TEST_EXENV ${bindir:=.}/s4u-exec-async$EXEEXT ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
-> [  0.000000] (1:test@Fafard) Hello! Execute 7.6296e+07 flops with priority 1
-> [  0.000000] (2:test@Fafard) Hello! Execute 7.6296e+07 flops with priority 2
-> [  0.000000] (3:test_cancel@Boivin) Hello! Execute 9.8095e+08 flops, should take 1 second
-> [  0.500000] (3:test_cancel@Boivin) I changed my mind, cancel!
-> [  0.500000] (3:test_cancel@Boivin) Goodbye now!
-> [  1.500000] (2:test@Fafard) Goodbye now!
-> [  2.000000] (0:maestro@) Simulation time 2
-> [  2.000000] (1:test@Fafard) Goodbye now!
+> [  0.000000] (1:wait@Fafard) Execute 7.6296e+07 flops, should take 1 second.
+> [  0.000000] (2:monitor@Ginette) Execute 4.8492e+07 flops, should take 1 second.
+> [  0.000000] (3:cancel@Boivin) Execute 9.8095e+07 flops, should take 1 second.
+> [  0.000000] (2:monitor@Ginette) Remaining amount of flops: 4.8492e+07 (100%)
+> [  0.300000] (2:monitor@Ginette) Remaining amount of flops: 3.39444e+07 (70%)
+> [  0.500000] (3:cancel@Boivin) I changed my mind, cancel!
+> [  0.500000] (3:cancel@Boivin) Goodbye now!
+> [  0.600000] (2:monitor@Ginette) Remaining amount of flops: 1.93968e+07 (40%)
+> [  0.900000] (2:monitor@Ginette) Remaining amount of flops: 4.8492e+06 (10%)
+> [  1.000000] (1:wait@Fafard) Goodbye now!
+> [  1.200000] (2:monitor@Ginette) Goodbye now!
+> [  1.200000] (0:maestro@) Simulation time 1.2
index 7b89ba8..5fde1fd 100644 (file)
@@ -21,7 +21,7 @@ static int dvfs()
   simgrid::s4u::this_actor::execute(workload);
 
   double task_time = simgrid::s4u::Engine::get_clock();
-  XBT_INFO("Task1 simulation time: %e", task_time);
+  XBT_INFO("Task1 duration: %.2f", task_time);
 
   // Change power peak
   int new_pstate = 2;
@@ -36,7 +36,7 @@ static int dvfs()
   simgrid::s4u::this_actor::execute(workload);
 
   task_time = simgrid::s4u::Engine::get_clock() - task_time;
-  XBT_INFO("Task2 simulation time: %e", task_time);
+  XBT_INFO("Task2 duration: %.2f", task_time);
 
   // Verify that the default pstate is set to 0
   host = simgrid::s4u::Host::by_name_or_null("MyHost2");
index 4ac2d9b..3b8a702 100644 (file)
@@ -7,16 +7,16 @@ $ ${bindir:=.}/s4u-exec-dvfs$EXEEXT ${platfdir}/energy_platform.xml "--log=root.
 > [  0.000000] (1:dvfs_test@MyHost1) Current power peak=100000000.000000
 > [  0.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
 > [  0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000
-> [  1.000000] (1:dvfs_test@MyHost1) Task1 simulation time: 1.000000e+00
-> [  1.000000] (2:dvfs_test@MyHost2) Task1 simulation time: 1.000000e+00
+> [  1.000000] (1:dvfs_test@MyHost1) Task1 duration: 1.00
 > [  1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2)
+> [  1.000000] (2:dvfs_test@MyHost2) Task1 duration: 1.00
 > [  1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2)
 > [  1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
 > [  1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
-> [  6.000000] (1:dvfs_test@MyHost1) Task2 simulation time: 5.000000e+00
+> [  6.000000] (1:dvfs_test@MyHost1) Task2 duration: 5.00
 > [  6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3
 > [  6.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
-> [  6.000000] (2:dvfs_test@MyHost2) Task2 simulation time: 5.000000e+00
+> [  6.000000] (2:dvfs_test@MyHost2) Task2 duration: 5.00
 > [  6.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
 > [  6.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
 > [  6.000000] (0:maestro@) Total simulation time: 6.000000e+00
@@ -26,16 +26,16 @@ $ ${bindir:=.}/s4u-exec-dvfs$EXEEXT ${platfdir}/energy_cluster.xml "--log=root.f
 > [  0.000000] (1:dvfs_test@MyHost1) Current power peak=100000000.000000
 > [  0.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
 > [  0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000
-> [  1.000000] (1:dvfs_test@MyHost1) Task1 simulation time: 1.000000e+00
-> [  1.000000] (2:dvfs_test@MyHost2) Task1 simulation time: 1.000000e+00
+> [  1.000000] (1:dvfs_test@MyHost1) Task1 duration: 1.00
 > [  1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2)
+> [  1.000000] (2:dvfs_test@MyHost2) Task1 duration: 1.00
 > [  1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2)
 > [  1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
 > [  1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
-> [  6.000000] (1:dvfs_test@MyHost1) Task2 simulation time: 5.000000e+00
+> [  6.000000] (1:dvfs_test@MyHost1) Task2 duration: 5.00
 > [  6.000000] (1:dvfs_test@MyHost1) Count of Processor states=3
 > [  6.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
-> [  6.000000] (2:dvfs_test@MyHost2) Task2 simulation time: 5.000000e+00
+> [  6.000000] (2:dvfs_test@MyHost2) Task2 duration: 5.00
 > [  6.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
 > [  6.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
 > [  6.000000] (0:maestro@) Total simulation time: 6.000000e+00
diff --git a/examples/s4u/exec-monitor/s4u-exec-monitor.cpp b/examples/s4u/exec-monitor/s4u-exec-monitor.cpp
deleted file mode 100644 (file)
index 65fd8ac..0000000
+++ /dev/null
@@ -1,49 +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"
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
-
-static void monitor(simgrid::s4u::ExecPtr activity)
-{
-  while (not activity->test()) {
-    XBT_INFO("activity remaining duration: %g (%.0f%%)", activity->get_remaining(),
-             100 * activity->get_remaining_ratio());
-    simgrid::s4u::this_actor::sleep_for(5);
-  }
-  XBT_INFO("My task is over.");
-}
-
-static void executor()
-{
-  XBT_INFO("Create one monitored task, and wait for it");
-  simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_async(1e9);
-  simgrid::s4u::Actor::create("monitor 1", simgrid::s4u::Host::by_name("Tremblay"), monitor, activity);
-  activity->wait(); // This blocks until the activity is over
-  XBT_INFO("The monitored task is over. Let's start 3 of them now.");
-  simgrid::s4u::Actor::create("monitor 2", simgrid::s4u::Host::by_name("Jupiter"), monitor,
-                              simgrid::s4u::this_actor::exec_async(1e9));
-  simgrid::s4u::Actor::create("monitor 3", simgrid::s4u::Host::by_name("Ginette"), monitor,
-                              simgrid::s4u::this_actor::exec_async(1e9));
-  simgrid::s4u::Actor::create("monitor 4", simgrid::s4u::Host::by_name("Bourassa"), monitor,
-                              simgrid::s4u::this_actor::exec_async(1e9));
-  XBT_INFO("All activities are started; finish now");
-  // Waiting execution activities is not mandatory: they go to completion once started
-
-  // No memory is leaked here: activities are automatically refcounted, thanks to C++ smart pointers
-}
-
-int main(int argc, char* argv[])
-{
-  simgrid::s4u::Engine e(&argc, argv);
-  e.load_platform(argv[1]);
-
-  simgrid::s4u::Actor::create("executor", simgrid::s4u::Host::by_name("Fafard"), executor);
-
-  e.run();
-
-  return 0;
-}
diff --git a/examples/s4u/exec-monitor/s4u-exec-monitor.tesh b/examples/s4u/exec-monitor/s4u-exec-monitor.tesh
deleted file mode 100644 (file)
index 45de5dd..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env tesh
-
-p Start several asynchronous tasks and monitor them
-
-$ $SG_TEST_EXENV ${bindir:=.}/s4u-exec-monitor$EXEEXT ${platfdir}/small_platform.xml
-> [Fafard:executor:(1) 0.000000] [s4u_test/INFO] Create one monitored task, and wait for it
-> [Tremblay:monitor 1:(2) 0.000000] [s4u_test/INFO] activity remaining duration: 1e+09 (100%)
-> [Tremblay:monitor 1:(2) 5.000000] [s4u_test/INFO] activity remaining duration: 6.1852e+08 (62%)
-> [Tremblay:monitor 1:(2) 10.000000] [s4u_test/INFO] activity remaining duration: 2.3704e+08 (24%)
-> [Fafard:executor:(1) 13.106847] [s4u_test/INFO] The monitored task is over. Let's start 3 of them now.
-> [Jupiter:monitor 2:(3) 13.106847] [s4u_test/INFO] activity remaining duration: 1e+09 (100%)
-> [Fafard:executor:(1) 13.106847] [s4u_test/INFO] All activities are started; finish now
-> [Ginette:monitor 3:(4) 13.106847] [s4u_test/INFO] activity remaining duration: 1e+09 (100%)
-> [Bourassa:monitor 4:(5) 13.106847] [s4u_test/INFO] activity remaining duration: 1e+09 (100%)
-> [Tremblay:monitor 1:(2) 15.000000] [s4u_test/INFO] My task is over.
-> [Bourassa:monitor 4:(5) 18.106847] [s4u_test/INFO] activity remaining duration: 8.7284e+08 (87%)
-> [Ginette:monitor 3:(4) 18.106847] [s4u_test/INFO] activity remaining duration: 8.7284e+08 (87%)
-> [Jupiter:monitor 2:(3) 18.106847] [s4u_test/INFO] activity remaining duration: 8.7284e+08 (87%)
-> [Jupiter:monitor 2:(3) 23.106847] [s4u_test/INFO] activity remaining duration: 7.4568e+08 (75%)
-> [Ginette:monitor 3:(4) 23.106847] [s4u_test/INFO] activity remaining duration: 7.4568e+08 (75%)
-> [Bourassa:monitor 4:(5) 23.106847] [s4u_test/INFO] activity remaining duration: 7.4568e+08 (75%)
-> [Bourassa:monitor 4:(5) 28.106847] [s4u_test/INFO] activity remaining duration: 6.1852e+08 (62%)
-> [Ginette:monitor 3:(4) 28.106847] [s4u_test/INFO] activity remaining duration: 6.1852e+08 (62%)
-> [Jupiter:monitor 2:(3) 28.106847] [s4u_test/INFO] activity remaining duration: 6.1852e+08 (62%)
-> [Jupiter:monitor 2:(3) 33.106847] [s4u_test/INFO] activity remaining duration: 4.9136e+08 (49%)
-> [Ginette:monitor 3:(4) 33.106847] [s4u_test/INFO] activity remaining duration: 4.9136e+08 (49%)
-> [Bourassa:monitor 4:(5) 33.106847] [s4u_test/INFO] activity remaining duration: 4.9136e+08 (49%)
-> [Bourassa:monitor 4:(5) 38.106847] [s4u_test/INFO] activity remaining duration: 3.642e+08 (36%)
-> [Ginette:monitor 3:(4) 38.106847] [s4u_test/INFO] activity remaining duration: 3.642e+08 (36%)
-> [Jupiter:monitor 2:(3) 38.106847] [s4u_test/INFO] activity remaining duration: 3.642e+08 (36%)
-> [Jupiter:monitor 2:(3) 43.106847] [s4u_test/INFO] activity remaining duration: 2.3704e+08 (24%)
-> [Ginette:monitor 3:(4) 43.106847] [s4u_test/INFO] activity remaining duration: 2.3704e+08 (24%)
-> [Bourassa:monitor 4:(5) 43.106847] [s4u_test/INFO] activity remaining duration: 2.3704e+08 (24%)
-> [Bourassa:monitor 4:(5) 48.106847] [s4u_test/INFO] activity remaining duration: 1.0988e+08 (11%)
-> [Ginette:monitor 3:(4) 48.106847] [s4u_test/INFO] activity remaining duration: 1.0988e+08 (11%)
-> [Jupiter:monitor 2:(3) 48.106847] [s4u_test/INFO] activity remaining duration: 1.0988e+08 (11%)
-> [Jupiter:monitor 2:(3) 53.106847] [s4u_test/INFO] My task is over.
-> [Ginette:monitor 3:(4) 53.106847] [s4u_test/INFO] My task is over.
-> [Bourassa:monitor 4:(5) 53.106847] [s4u_test/INFO] My task is over.
index c243494..c3f804b 100644 (file)
  * Please note that you must have the LV07 platform model enabled to use such constructs.
  */
 
-#include "simgrid/plugins/energy.h"
 #include <simgrid/s4u.hpp>
 
-XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_energyptask, "Messages specific for this s4u example");
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_ptask, "Messages specific for this s4u example");
 
 static void runner()
 {
@@ -36,8 +35,8 @@ static void runner()
   std::vector<double> communication_amounts;
 
   /* ------[ test 1 ]----------------- */
-  computation_amounts.assign(hosts.size(), 1e9 /*1Gflop*/);
-  communication_amounts.assign(hosts.size() * hosts.size(), 0);
+  computation_amounts.assign(hosts_count, 1e9 /*1Gflop*/);
+  communication_amounts.assign(hosts_count * hosts_count, 0);
   for (size_t i = 0; i < hosts_count; i++)
     for (size_t j = i + 1; j < hosts_count; j++)
       communication_amounts[i * hosts_count + j] = 1e7; // 10 MB
@@ -45,51 +44,33 @@ static void runner()
   simgrid::s4u::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
 
   /* ------[ test 2 ]----------------- */
-  XBT_INFO("We can do the same with a timeout of one second enabled.");
-  computation_amounts.assign(hosts.size(), 1e9 /*1Gflop*/);
-  communication_amounts.assign(hosts.size() * hosts.size(), 0);
+  XBT_INFO("We can do the same with a timeout of 10 seconds enabled.");
+  computation_amounts.assign(hosts_count, 1e9 /*1Gflop*/);
+  communication_amounts.assign(hosts_count * hosts_count, 0);
   for (size_t i = 0; i < hosts_count; i++)
     for (size_t j = i + 1; j < hosts_count; j++)
       communication_amounts[i * hosts_count + j] = 1e7; // 10 MB
 
   try {
     simgrid::s4u::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts,
-                                               1.0 /* timeout (in seconds)*/);
-    XBT_WARN("Woops, this did not timeout as expected... Please report that bug.");
-  } catch (xbt_ex& e) {
-    /* Do nothing this exception on timeout was expected */
-    XBT_DEBUG("Caught expected exception: %s", e.what());
+                                               10.0 /* timeout (in seconds)*/);
+    xbt_die("Woops, this did not timeout as expected... Please report that bug.");
+  } catch (simgrid::TimeoutError& e) {
+    XBT_INFO("Caught the expected timeout exception.");
   }
 
   /* ------[ test 3 ]----------------- */
-  XBT_INFO("Then, build a parallel task involving only computations and no communication (1 Gflop per node)");
-  computation_amounts.assign(hosts.size(), 1e9 /*1Gflop*/);
-  communication_amounts.clear(); /* no comm */
+  XBT_INFO("Then, build a parallel task involving only computations (of different amounts) and no communication");
+  computation_amounts = {3e8, 6e8, 1e9}; // 300Mflop, 6Mflop, 1Gflop
+  communication_amounts.clear();         // no comm
   simgrid::s4u::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
 
   /* ------[ test 4 ]----------------- */
-  XBT_INFO("Then, build a parallel task involving only heterogeneous computations and no communication");
-  computation_amounts.resize(hosts.size());
-  for (size_t i = 0; i < hosts_count; i++)
-    computation_amounts[i] = 5 * (i + 1) * 1e8; // 500Mflop, 1Gflop, 1.5Gflop
-  communication_amounts.clear();                /* no comm */
-  simgrid::s4u::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
-
-  /* ------[ test 5 ]----------------- */
   XBT_INFO("Then, build a parallel task with no computation nor communication (synchro only)");
   computation_amounts.clear();
   communication_amounts.clear();
   simgrid::s4u::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
 
-  /* ------[ test 6 ]----------------- */
-  XBT_INFO("Finally, trick the ptask to do a 'remote execution', on host %s", hosts[1]->get_cname());
-  std::vector<simgrid::s4u::Host*> remote;
-  remote.push_back(hosts[1]);
-  computation_amounts.assign(1, 1e9);
-  communication_amounts.clear();
-
-  simgrid::s4u::this_actor::parallel_execute(remote, computation_amounts, communication_amounts);
-
   XBT_INFO("Goodbye now!");
 }
 
@@ -97,15 +78,9 @@ int main(int argc, char* argv[])
 {
   simgrid::s4u::Engine e(&argc, argv);
 
-  xbt_assert(argc <= 3, "1Usage: %s <platform file> [--energy]", argv[0]);
-  xbt_assert(argc >= 2, "2Usage: %s <platform file> [--energy]", argv[0]);
-
-  if (argc == 3 && argv[2][2] == 'e')
-    sg_host_energy_plugin_init();
+  xbt_assert(argc == 2, "Usage: %s <platform file>", argv[0]);
 
   e.load_platform(argv[1]);
-
-  /* Pick a process, no matter which, from the platform file */
   simgrid::s4u::Actor::create("test", simgrid::s4u::Host::by_name("MyHost1"), runner);
 
   e.run();
index 40d34e6..e8dde98 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/env tesh
 
-$ ${bindir:=.}/s4u-exec-ptask$EXEEXT ${platfdir}/energy_platform.xml --energy --cfg=host/model:ptask_L07 --cfg=tracing:yes --cfg=tracing/uncategorized:yes --log=instr_resource.t:debug --log=no_loc "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+$ ${bindir:=.}/s4u-exec-ptask$EXEEXT ${platfdir}/energy_platform.xml --cfg=host/model:ptask_L07 --cfg=tracing:yes --cfg=tracing/uncategorized:yes --log=instr_resource.t:debug --log=no_loc "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
 > [  0.000000] (0:maestro@) Configuration change: Set 'host/model' to 'ptask_L07'
 > [  0.000000] (0:maestro@) Configuration change: Set 'tracing' to 'yes'
 > [  0.000000] (0:maestro@) Configuration change: Set 'tracing/uncategorized' to 'yes'
@@ -10,21 +10,12 @@ $ ${bindir:=.}/s4u-exec-ptask$EXEEXT ${platfdir}/energy_platform.xml --energy --
 > [300.000000] (0:maestro@) UNCAT HOST [0.000000 - 300.000000] MyHost2 speed_used 3333333.333333
 > [300.000000] (0:maestro@) UNCAT HOST [0.000000 - 300.000000] MyHost3 speed_used 3333333.333333
 > [300.000000] (0:maestro@) UNCAT LINK [0.000000 - 300.000000] bus bandwidth_used 100000.000000
-> [300.000000] (1:test@MyHost1) We can do the same with a timeout of one second enabled.
-> [301.000000] (1:test@MyHost1) Then, build a parallel task involving only computations and no communication (1 Gflop per node)
-> [311.000000] (0:maestro@) UNCAT HOST [301.000000 - 311.000000] MyHost1 speed_used 100000000.000000
-> [311.000000] (0:maestro@) UNCAT HOST [301.000000 - 311.000000] MyHost2 speed_used 100000000.000000
-> [311.000000] (0:maestro@) UNCAT HOST [301.000000 - 311.000000] MyHost3 speed_used 100000000.000000
-> [311.000000] (1:test@MyHost1) Then, build a parallel task involving only heterogeneous computations and no communication
-> [326.000000] (0:maestro@) UNCAT HOST [311.000000 - 326.000000] MyHost1 speed_used 33333333.333333
-> [326.000000] (0:maestro@) UNCAT HOST [311.000000 - 326.000000] MyHost2 speed_used 66666666.666667
-> [326.000000] (0:maestro@) UNCAT HOST [311.000000 - 326.000000] MyHost3 speed_used 100000000.000000
-> [326.000000] (1:test@MyHost1) Then, build a parallel task with no computation nor communication (synchro only)
-> [326.000000] (1:test@MyHost1) Finally, trick the ptask to do a 'remote execution', on host MyHost2
-> [336.000000] (0:maestro@) UNCAT HOST [326.000000 - 336.000000] MyHost2 speed_used 100000000.000000
-> [336.000000] (1:test@MyHost1) Goodbye now!
-> [336.000000] (0:maestro@) Total energy consumption: 165494.222222 Joules (used hosts: 165494.222222 Joules; unused/idle hosts: 0.000000)
-> [336.000000] (0:maestro@) Simulation done.
-> [336.000000] (0:maestro@) Energy consumption of host MyHost1: 32094.222222 Joules
-> [336.000000] (0:maestro@) Energy consumption of host MyHost2: 67200.000000 Joules
-> [336.000000] (0:maestro@) Energy consumption of host MyHost3: 66200.000000 Joules
+> [300.000000] (1:test@MyHost1) We can do the same with a timeout of 10 seconds enabled.
+> [310.000000] (1:test@MyHost1) Caught the expected timeout exception.
+> [310.000000] (1:test@MyHost1) Then, build a parallel task involving only computations (of different amounts) and no communication
+> [320.000000] (0:maestro@) UNCAT HOST [310.000000 - 320.000000] MyHost1 speed_used 30000000.000000
+> [320.000000] (0:maestro@) UNCAT HOST [310.000000 - 320.000000] MyHost2 speed_used 60000000.000000
+> [320.000000] (0:maestro@) UNCAT HOST [310.000000 - 320.000000] MyHost3 speed_used 100000000.000000
+> [320.000000] (1:test@MyHost1) Then, build a parallel task with no computation nor communication (synchro only)
+> [320.000000] (1:test@MyHost1) Goodbye now!
+> [320.000000] (0:maestro@) Simulation done.
index f0150d8..75669f5 100644 (file)
@@ -40,9 +40,6 @@ static int master(int argc, char* argv[])
       XBT_INFO("Send a message to %s", mailbox->get_cname());
       mailbox->put(payload, comm_size, 10.0);
       XBT_INFO("Send to %s completed", mailbox->get_cname());
-    } catch (simgrid::HostFailureException& e) {
-      XBT_INFO("Gloups. The cpu on which I'm running just turned off!. See you!");
-      return -1;
     } catch (simgrid::TimeoutError& e) {
       delete payload;
       XBT_INFO("Mmh. Got timeouted while speaking to '%s'. Nevermind. Let's keep going!", mailbox->get_cname());
index 9d30015..b1acb0b 100644 (file)
@@ -19,9 +19,7 @@ $ $SG_TEST_EXENV ${bindir:=.}/s4u-platform-failures$EXEEXT --log=xbt_cfg.thres:c
 > [  1.000000] (7:worker@Fafard) Waiting a message on worker-2
 > [  1.000000] (1:master@Tremblay) Mmh. The communication with 'worker-1' failed. Nevermind. Let's keep going!
 > [  1.000000] (1:master@Tremblay) Send a message to worker-2
-> [  1.000000] (3:worker@Jupiter) Gloups. The cpu on which I'm running just turned off!. See you!
 > [  2.000000] (1:master@Tremblay) Mmh. The communication with 'worker-2' failed. Nevermind. Let's keep going!
-> [  2.000000] (7:worker@Fafard) Gloups. The cpu on which I'm running just turned off!. See you!
 > [  2.000000] (0:maestro@) Restart processes on host Jupiter
 > [  2.000000] (1:master@Tremblay) Send a message to worker-3
 > [  2.000000] (8:worker@Jupiter) Waiting a message on worker-1
@@ -126,12 +124,10 @@ $ $SG_TEST_EXENV ${bindir:=.}/s4u-platform-failures$EXEEXT --log=xbt_cfg.thres:c
 > [  1.000000] (7:worker@Fafard) Waiting a message on worker-2
 > [  1.000000] (1:master@Tremblay) Mmh. The communication with 'worker-1' failed. Nevermind. Let's keep going!
 > [  1.000000] (1:master@Tremblay) Send a message to worker-2
-> [  1.000000] (3:worker@Jupiter) Gloups. The cpu on which I'm running just turned off!. See you!
 > [  2.000000] (0:maestro@) Restart processes on host Jupiter
 > [  2.000000] (8:worker@Jupiter) Waiting a message on worker-1
 > [  2.000000] (1:master@Tremblay) Mmh. The communication with 'worker-2' failed. Nevermind. Let's keep going!
 > [  2.000000] (1:master@Tremblay) Send a message to worker-3
-> [  2.000000] (7:worker@Fafard) Gloups. The cpu on which I'm running just turned off!. See you!
 > [  2.010825] (2:worker@Tremblay) Execution complete.
 > [  2.010825] (2:worker@Tremblay) Waiting a message on worker-0
 > [  3.082474] (5:worker@Ginette) Start execution...
index a311eb6..3b4e9e1 100644 (file)
@@ -2,12 +2,12 @@ p Test smpi bindings for dvfs functions (Fortran 77 example)
 
 $ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platform ${srcdir:=.}/../../platforms/energy_platform.xml --cfg=smpi/simulate-computation:no ${bindir:=.}/f77/sef --cfg=plugin:host_energy --log=smpi_kernel.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/wtime:0
 > [     0.00000000] [rank  0]  3 pstates available
-> [     0.00000000] [rank  1]  3 pstates available
 > [     0.00000000] [rank  0] Power:  100000000.0000
-> [     0.00000000] [rank  1] Power:  100000000.0000
 > [     0.00000000] [rank  0] Power:   50000000.0000
-> [     0.00000000] [rank  1] Power:   50000000.0000
 > [     0.00000000] [rank  0] Power:   20000000.0000
+> [     0.00000000] [rank  1]  3 pstates available
+> [     0.00000000] [rank  1] Power:  100000000.0000
+> [     0.00000000] [rank  1] Power:   50000000.0000
 > [     0.00000000] [rank  1] Power:   20000000.0000
 > [     0.00000000] [rank  0] Current pstate:  0; Current power:  100000000.0000
 > [     0.00000000] [rank  1] Current pstate:  0; Current power:  100000000.0000
index 033b99d..1b759d4 100644 (file)
@@ -2,12 +2,12 @@ p Test smpi bindings for dvfs functions (Fortran 90 example)
 
 $ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platform ${srcdir:=.}/../../platforms/energy_platform.xml --cfg=smpi/simulate-computation:no ${bindir:=.}/f90/sef90 --cfg=plugin:host_energy --log=smpi_kernel.thres:warning --log=xbt_cfg.thres:warning --cfg=smpi/wtime:0
 > [     0.00000000] [rank  0]  3 pstates available
-> [     0.00000000] [rank  1]  3 pstates available
 > [     0.00000000] [rank  0] Power:  100000000.0000
-> [     0.00000000] [rank  1] Power:  100000000.0000
 > [     0.00000000] [rank  0] Power:   50000000.0000
-> [     0.00000000] [rank  1] Power:   50000000.0000
 > [     0.00000000] [rank  0] Power:   20000000.0000
+> [     0.00000000] [rank  1]  3 pstates available
+> [     0.00000000] [rank  1] Power:  100000000.0000
+> [     0.00000000] [rank  1] Power:   50000000.0000
 > [     0.00000000] [rank  1] Power:   20000000.0000
 > [     0.00000000] [rank  0] Current pstate:  0; Current power:  100000000.0000
 > [     0.00000000] [rank  1] Current pstate:  0; Current power:  100000000.0000
index e92b3a7..9facab2 100644 (file)
@@ -49,7 +49,9 @@ typedef boost::intrusive_ptr<Exec> ExecPtr;
 XBT_PUBLIC void intrusive_ptr_release(Exec* e);
 XBT_PUBLIC void intrusive_ptr_add_ref(Exec* e);
 class ExecSeq;
+typedef boost::intrusive_ptr<ExecSeq> ExecSeqPtr;
 class ExecPar;
+typedef boost::intrusive_ptr<ExecPar> ExecParPtr;
 
 class Host;
 
index 2ab078f..ebab496 100644 (file)
@@ -30,19 +30,22 @@ public:
    * @param name The name of the Resource
    * @param constraint The lmm constraint associated to this Resource if it is part of a LMM component
    */
-  Resource(Model* model, const std::string& name, lmm::Constraint* constraint);
+  Resource(Model* model, const std::string& name, lmm::Constraint* constraint)
+      : name_(name), model_(model), constraint_(constraint)
+  {
+  }
 
   virtual ~Resource();
 
   /** @brief Get the Model of the current Resource */
-  Model* get_model() const;
+  Model* get_model() const { return model_; }
 
   /** @brief Get the name of the current Resource */
-  const std::string& get_name() const;
+  const std::string& get_name() const { return name_; }
   /** @brief Get the name of the current Resource */
-  const char* get_cname() const;
+  const char* get_cname() const { return name_.c_str(); }
 
-  bool operator==(const Resource& other) const;
+  bool operator==(const Resource& other) const { return name_ == other.name_; }
 
   /** @brief Apply an event of external load event to that resource */
   virtual void apply_event(profile::Event* event, double value) = 0;
@@ -53,16 +56,16 @@ public:
   /** @brief returns the current load due to activities (in flops per second, byte per second or similar)
    *
    * The load due to external usages modeled by profile files is ignored.*/
-  virtual double get_load();
+  virtual double get_load() const;
 
   /** @brief Check if the current Resource is active */
-  virtual bool is_on() const;
+  virtual bool is_on() const { return is_on_; }
   /** @brief Check if the current Resource is shut down */
-  XBT_ATTRIB_DEPRECATED_v325("Please use !is_on()") virtual bool is_off() const;
+  XBT_ATTRIB_DEPRECATED_v325("Please use !is_on()") virtual bool is_off() const { return not is_on_; }
   /** @brief Turn on the current Resource */
-  virtual void turn_on();
+  virtual void turn_on() { is_on_ = true; }
   /** @brief Turn off the current Resource */
-  virtual void turn_off();
+  virtual void turn_off() { is_on_ = false; }
   /** @brief setup the profile file with states events (ON or OFF). The profile must contain boolean values. */
   virtual void set_state_profile(profile::Profile* profile);
 
@@ -78,7 +81,7 @@ private:
 
 public: /* LMM */
   /** @brief Get the lmm constraint associated to this Resource if it is part of a LMM component (or null if none) */
-  lmm::Constraint* get_constraint() const;
+  lmm::Constraint* get_constraint() const { return constraint_; }
 
 private:
   kernel::lmm::Constraint* const constraint_;
index 7984766..0b239f7 100644 (file)
@@ -36,11 +36,11 @@ public:
   /** @brief the NetZone in which this NetPoint is included */
   NetZoneImpl* get_englobing_zone() { return englobing_zone_; }
 
-  bool is_netzone() { return component_type_ == Type::NetZone; }
-  bool is_host() { return component_type_ == Type::Host; }
-  bool is_router() { return component_type_ == Type::Router; }
+  bool is_netzone() const { return component_type_ == Type::NetZone; }
+  bool is_host() const { return component_type_ == Type::Host; }
+  bool is_router() const { return component_type_ == Type::Router; }
 
-  static simgrid::xbt::signal<void(NetPoint*)> on_creation;
+  static simgrid::xbt::signal<void(NetPoint&)> on_creation;
 
   bool operator<(const NetPoint& rhs) const { return name_ < rhs.name_; }
 
index 21a2788..eaad97d 100644 (file)
@@ -60,7 +60,7 @@ public:
   s4u::NetZone* get_iface() { return &piface_; }
 
   /** @brief Make a host within that NetZone */
-  simgrid::s4u::Host* create_host(const char* name, std::vector<double>* speed_per_pstate, int core_count,
+  simgrid::s4u::Host* create_host(const char* name, const std::vector<double>& speed_per_pstate, int core_count,
                                   std::map<std::string, std::string>* props);
   /** @brief Creates a new route in this NetZone */
   virtual void add_bypass_route(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst,
index 821228b..d9d09d0 100644 (file)
@@ -308,6 +308,7 @@ XBT_PUBLIC double MSG_get_clock();
 XBT_PUBLIC unsigned long int MSG_get_sent_msg();
 
 /************************** Process handling *********************************/
+XBT_PUBLIC void MSG_process_userdata_init();
 XBT_PUBLIC msg_process_t MSG_process_create(const char* name, xbt_main_func_t code, void* data, msg_host_t host);
 XBT_PUBLIC msg_process_t MSG_process_create_with_arguments(const char* name, xbt_main_func_t code, void* data,
                                                            msg_host_t host, int argc, char** argv);
index 1ccfd6a..e5f1878 100644 (file)
@@ -145,23 +145,23 @@ public:
   static ActorPtr self();
 
   /** Signal to others that a new actor has been created **/
-  static xbt::signal<void(ActorPtr)> on_creation;
+  static xbt::signal<void(Actor&)> on_creation;
   /** Signal to others that an actor has been suspended**/
-  static xbt::signal<void(ActorPtr)> on_suspend;
+  static xbt::signal<void(Actor const&)> on_suspend;
   /** Signal to others that an actor has been resumed **/
-  static xbt::signal<void(ActorPtr)> on_resume;
+  static xbt::signal<void(Actor const&)> on_resume;
   /** Signal to others that an actor is sleeping **/
-  static xbt::signal<void(ActorPtr)> on_sleep;
+  static xbt::signal<void(Actor const&)> on_sleep;
   /** Signal to others that an actor wakes up for a sleep **/
-  static xbt::signal<void(ActorPtr)> on_wake_up;
+  static xbt::signal<void(Actor const&)> on_wake_up;
   /** Signal to others that an actor is going to migrated to another host**/
-  static xbt::signal<void(ActorPtr)> on_migration_start;
+  static xbt::signal<void(Actor const&)> on_migration_start;
   /** Signal to others that an actor is has been migrated to another host **/
-  static xbt::signal<void(ActorPtr)> on_migration_end;
+  static xbt::signal<void(Actor const&)> on_migration_end;
   /** Signal indicating that an actor is about to disappear.
    *  This signal is fired for any dying actor, which is mostly useful when designing plugins and extensions. If you
    *  want to register to the termination of a given actor, use this_actor::on_exit() instead.*/
-  static xbt::signal<void(ActorPtr)> on_destruction;
+  static xbt::signal<void(Actor const&)> on_destruction;
 
   /** Create an actor from a std::function<void()>
    *
@@ -207,7 +207,7 @@ public:
   /** Retrieves the name of that actor as a C string */
   const char* get_cname() const;
   /** Retrieves the host on which that actor is running */
-  Host* get_host();
+  Host* get_host() const;
   /** Retrieves the actor ID of that actor */
   aid_t get_pid() const;
   /** Retrieves the actor ID of that actor's creator */
@@ -236,7 +236,7 @@ public:
    * It will be set to true if the actor was killed or failed because of an exception,
    * while it will remain to false if the actor terminated gracefully.
    */
-  void on_exit(const std::function<void(bool /*failed*/)>& fun);
+  void on_exit(const std::function<void(bool /*failed*/)>& fun) const;
 
   /** Sets the time at which that actor should be killed */
   void set_kill_time(double time);
@@ -286,7 +286,7 @@ public:
   static void kill_all();
 
   /** Returns the internal implementation of this actor */
-  kernel::actor::ActorImpl* get_impl();
+  kernel::actor::ActorImpl* get_impl() const { return pimpl_; }
 
   /** Retrieve the property value (or nullptr if not set) */
   std::unordered_map<std::string, std::string>*
index abf147a..7cb8725 100644 (file)
@@ -44,9 +44,9 @@ public:
 
   virtual ~Comm();
 
-  static xbt::signal<void(ActorPtr)> on_sender_start;
-  static xbt::signal<void(ActorPtr)> on_receiver_start;
-  static xbt::signal<void(ActorPtr)> on_completion;
+  static xbt::signal<void(Actor const&)> on_sender_start;
+  static xbt::signal<void(Actor const&)> on_receiver_start;
+  static xbt::signal<void(Actor const&)> on_completion;
 
   /*! take a vector s4u::CommPtr and return when one of them is finished.
    * The return value is the rank of the first finished CommPtr. */
index 73f3d23..e7e9610 100644 (file)
@@ -41,8 +41,8 @@ public:
   friend ExecPar;
   friend XBT_PUBLIC void intrusive_ptr_release(Exec* e);
   friend XBT_PUBLIC void intrusive_ptr_add_ref(Exec* e);
-  static xbt::signal<void(ActorPtr)> on_start;
-  static xbt::signal<void(ActorPtr)> on_completion;
+  static xbt::signal<void(Actor const&)> on_start;
+  static xbt::signal<void(Actor const&)> on_completion;
 
   virtual Exec* start() override          = 0;
   virtual double get_remaining_ratio()    = 0;
index dd31bcf..81a031e 100644 (file)
@@ -53,12 +53,12 @@ public:
   /*** Called on each newly created host */
   static xbt::signal<void(Host&)> on_creation;
   /*** Called just before destructing a host */
-  static xbt::signal<void(Host&)> on_destruction;
+  static xbt::signal<void(Host const&)> on_destruction;
   /*** Called when the machine is turned on or off (called AFTER the change) */
-  static xbt::signal<void(Host&)> on_state_change;
+  static xbt::signal<void(Host const&)> on_state_change;
   /*** Called when the speed of the machine is changed (called AFTER the change)
    * (either because of a pstate switch or because of an external load event coming from the profile) */
-  static xbt::signal<void(Host&)> on_speed_change;
+  static xbt::signal<void(Host const&)> on_speed_change;
 
   virtual void destroy();
   // No copy/move
@@ -126,6 +126,8 @@ public:
   void set_pstate(int pstate_index);
   int get_pstate() const;
 
+  std::vector<const char*> get_attached_storages() const;
+
 #ifndef DOXYGEN
   /** @deprecated See Host::get_speed() */
   XBT_ATTRIB_DEPRECATED_v323("Please use Host::get_speed() instead.") double getSpeed() { return get_speed(); }
@@ -134,8 +136,6 @@ public:
   {
     return get_pstate_speed(pstate_index);
   }
-
-  std::vector<const char*> get_attached_storages() const;
   XBT_ATTRIB_DEPRECATED_v323("Please use Host::get_attached_storages() instead.") void getAttachedStorages(
       std::vector<const char*>* storages);
 #endif
index be6dfb2..8a9c723 100644 (file)
@@ -45,10 +45,10 @@ public:
   const char* get_cname() const;
 
   /** @brief Get the bandwidth in bytes per second of current Link */
-  double get_bandwidth();
+  double get_bandwidth() const;
 
   /** @brief Get the latency in seconds of current Link */
-  double get_latency();
+  double get_latency() const;
 
   /** @brief Describes how the link is shared between flows */
   SharingPolicy get_sharing_policy();
@@ -101,19 +101,19 @@ public:
   static xbt::signal<void(Link&)> on_creation;
 
   /** @brief Callback signal fired when a Link is destroyed */
-  static xbt::signal<void(Link&)> on_destruction;
+  static xbt::signal<void(Link const&)> on_destruction;
 
   /** @brief Callback signal fired when the state of a Link changes (when it is turned on or off) */
-  static xbt::signal<void(Link&)> on_state_change;
+  static xbt::signal<void(Link const&)> on_state_change;
 
   /** @brief Callback signal fired when the bandwidth of a Link changes */
-  static xbt::signal<void(Link&)> on_bandwidth_change;
+  static xbt::signal<void(Link const&)> on_bandwidth_change;
 
   /** @brief Callback signal fired when a communication starts */
-  static xbt::signal<void(kernel::resource::NetworkAction*, Host* src, Host* dst)> on_communicate;
+  static xbt::signal<void(kernel::resource::NetworkAction&, Host* src, Host* dst)> on_communicate;
 
   /** @brief Callback signal fired when a communication changes it state (ready/done/cancel) */
-  static xbt::signal<void(kernel::resource::NetworkAction*, kernel::resource::Action::State)>
+  static xbt::signal<void(kernel::resource::NetworkAction&, kernel::resource::Action::State)>
       on_communication_state_change;
 
 #ifndef DOXYGEN
index 4b34063..2ce888a 100644 (file)
@@ -22,6 +22,7 @@ class XBT_PUBLIC Mailbox {
   kernel::activity::MailboxImpl* const pimpl_;
 
   explicit Mailbox(kernel::activity::MailboxImpl * mbox) : pimpl_(mbox) {}
+  ~Mailbox() = default;
 
 public:
   /** private function, do not use. FIXME: make me protected */
index 3855348..815b176 100644 (file)
@@ -69,10 +69,10 @@ public:
   /*** Called on each newly created regular route (not on bypass routes) */
   static xbt::signal<void(bool symmetrical, kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst,
                           kernel::routing::NetPoint* gw_src, kernel::routing::NetPoint* gw_dst,
-                          std::vector<kernel::resource::LinkImpl*>& link_list)>
+                          std::vector<kernel::resource::LinkImpl*> const& link_list)>
       on_route_creation;
-  static xbt::signal<void(NetZone&)> on_creation;
-  static xbt::signal<void(NetZone&)> on_seal;
+  static xbt::signal<void(NetZone const&)> on_creation;
+  static xbt::signal<void(NetZone const&)> on_seal;
 
 #ifndef DOXYGEN
   // Deprecation wrappers
index 569a93a..1b5107b 100644 (file)
@@ -39,9 +39,9 @@ public:
   /** @brief Callback signal fired when a new Storage is created */
   static xbt::signal<void(Storage&)> on_creation;
   /** @brief Callback signal fired when a Storage is destroyed */
-  static xbt::signal<void(Storage&)> on_destruction;
+  static xbt::signal<void(Storage const&)> on_destruction;
   /** @brief Callback signal fired when a Storage's state changes */
-  static xbt::signal<void(Storage&)> on_state_change;
+  static xbt::signal<void(Storage const&)> on_state_change;
 
   /** Retrieve a Storage by its name. It must exist in the platform file */
   static Storage* by_name(const std::string& name);
index b2bd8aa..4dd134d 100644 (file)
@@ -38,7 +38,7 @@ public:
     DESTROYED
   };
 
-  vm::VirtualMachineImpl* get_impl() { return pimpl_vm_; }
+  vm::VirtualMachineImpl* get_impl() const { return pimpl_vm_; }
   void start();
   void suspend();
   void resume();
@@ -52,13 +52,13 @@ public:
   void set_bound(double bound);
 
   VirtualMachine::state get_state();
-  static xbt::signal<void(VirtualMachine&)> on_start;
-  static xbt::signal<void(VirtualMachine&)> on_started;
-  static xbt::signal<void(VirtualMachine&)> on_shutdown;
-  static xbt::signal<void(VirtualMachine&)> on_suspend;
-  static xbt::signal<void(VirtualMachine&)> on_resume;
-  static xbt::signal<void(VirtualMachine&)> on_migration_start;
-  static xbt::signal<void(VirtualMachine&)> on_migration_end;
+  static xbt::signal<void(VirtualMachine const&)> on_start;
+  static xbt::signal<void(VirtualMachine const&)> on_started;
+  static xbt::signal<void(VirtualMachine const&)> on_shutdown;
+  static xbt::signal<void(VirtualMachine const&)> on_suspend;
+  static xbt::signal<void(VirtualMachine const&)> on_resume;
+  static xbt::signal<void(VirtualMachine const&)> on_migration_start;
+  static xbt::signal<void(VirtualMachine const&)> on_migration_end;
 
 #ifndef DOXYGEN
   // Deprecated methods
index 25a83c6..1a6bb09 100644 (file)
@@ -148,12 +148,14 @@ XBT_ATTRIB_DEPRECATED_v325("Please use ActorImpl::set_user_data()") XBT_PUBLIC
 XBT_ATTRIB_DEPRECATED_v325("Please use ActorImpl::get_user_data()") XBT_PUBLIC void* SIMIX_process_self_get_data();
 XBT_ATTRIB_DEPRECATED_v325("Please manifest if you actually need this function") XBT_PUBLIC
     int SIMIX_process_has_pending_comms(smx_actor_t process);
-XBT_PUBLIC void SIMIX_process_on_exit(smx_actor_t process, int_f_pvoid_pvoid_t fun, void* data);
+XBT_ATTRIB_DEPRECATED_v325("Please use SIMIX_process_on_exit(smx_actor_t, const std::function<void(bool)>&)") XBT_PUBLIC
+    void SIMIX_process_on_exit(smx_actor_t process, int_f_pvoid_pvoid_t fun, void* data);
 SG_END_DECL()
 
 #ifdef __cplusplus
-XBT_PUBLIC void SIMIX_process_on_exit(smx_actor_t process,
-                                      const std::function<void(bool /*failed*/, void* /*data*/)>& fun, void* data);
+XBT_ATTRIB_DEPRECATED_v325("Please use SIMIX_process_on_exit(smx_actor_t, const std::function<void(bool)>&)") XBT_PUBLIC
+    void SIMIX_process_on_exit(smx_actor_t process, const std::function<void(int, void*)>& fun, void* data);
+XBT_PUBLIC void SIMIX_process_on_exit(smx_actor_t process, const std::function<void(bool /*failed*/)>& fun);
 #endif
 
 /****************************** Communication *********************************/
index aa52f47..9b48080 100644 (file)
@@ -86,7 +86,7 @@ class Timer {
 public:
   decltype(simix_timers)::handle_type handle_;
 
-  Timer(double date, simgrid::xbt::Task<void()> callback) : date(date), callback(std::move(callback)) {}
+  Timer(double date, simgrid::xbt::Task<void()>&& callback) : date(date), callback(std::move(callback)) {}
 
   simgrid::xbt::Task<void()> callback;
   double get_date() { return date; }
@@ -97,13 +97,19 @@ public:
     return set(date, simgrid::xbt::Task<void()>(std::move(callback)));
   }
 
-  template <class R, class T> static inline Timer* set(double date, R (*callback)(T*), T* arg)
+  template <class R, class T>
+  XBT_ATTRIB_DEPRECATED_v325("Please use a lambda or std::bind") static inline Timer* set(double date,
+                                                                                          R (*callback)(T*), T* arg)
   {
-    return set(date, [callback, arg]() { callback(arg); });
+    return set(date, std::bind(callback, arg));
   }
 
-  static Timer* set(double date, void (*callback)(void*), void* arg);
-  static Timer* set(double date, simgrid::xbt::Task<void()> callback);
+  XBT_ATTRIB_DEPRECATED_v325("Please use a lambda or std::bind") static Timer* set(double date, void (*callback)(void*),
+                                                                                   void* arg)
+  {
+    return set(date, std::bind(callback, arg));
+  }
+  static Timer* set(double date, simgrid::xbt::Task<void()>&& callback);
   static double next() { return simix_timers.empty() ? -1.0 : simix_timers.top().first; }
 };
 
@@ -114,7 +120,7 @@ XBT_PUBLIC smx_actor_t simcall_process_create(const std::string& name, const sim
                                               void* data, sg_host_t host,
                                               std::unordered_map<std::string, std::string>* properties);
 
-XBT_PUBLIC smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task<void()> callback);
-
+XBT_ATTRIB_DEPRECATED_v325("Please use simgrid::xbt::Timer::set") XBT_PUBLIC smx_timer_t
+    SIMIX_timer_set(double date, simgrid::xbt::Task<void()>&& callback);
 
 #endif
index a0835da..ad51171 100644 (file)
@@ -569,6 +569,40 @@ MPI_CALL(XBT_PUBLIC MPI_Fint, MPI_Request_c2f, (MPI_Request request));
 
 MPI_CALL(XBT_PUBLIC int, MPI_Bcast, (void* buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm));
 MPI_CALL(XBT_PUBLIC int, MPI_Barrier, (MPI_Comm comm));
+MPI_CALL(XBT_PUBLIC int, MPI_Ibarrier, (MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Ibcast, (void* buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Igather, (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
+                                      MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Igatherv, (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                       int* recvcounts, int* displs, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Iallgather, (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                         int recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Iallgatherv, (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                          int* recvcounts, int* displs, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Iscatter, (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                       int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Iscatterv, (void* sendbuf, int* sendcounts, int* displs, MPI_Datatype sendtype,
+                                        void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Ireduce,
+         (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Iallreduce,
+         (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Iscan,
+         (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Iexscan,
+         (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Ireduce_scatter,
+         (void* sendbuf, void* recvbuf, int* recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Ireduce_scatter_block,
+         (void* sendbuf, void* recvbuf, int recvcount, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Ialltoall, (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                        int recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Ialltoallv,
+         (void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf, int* recvcounts,
+          int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request));
+MPI_CALL(XBT_PUBLIC int, MPI_Ialltoallw,
+         (void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype* sendtypes, void* recvbuf, int* recvcounts,
+          int* recvdisps, MPI_Datatype* recvtypes, MPI_Comm comm, MPI_Request *request));
 MPI_CALL(XBT_PUBLIC int, MPI_Gather, (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
                                       MPI_Datatype recvtype, int root, MPI_Comm comm));
 MPI_CALL(XBT_PUBLIC int, MPI_Gatherv, (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
index 690aea1..3dca953 100644 (file)
 #define MPI_Request_c2f(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Request_c2f(__VA_ARGS__); })
 #define MPI_Bcast(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Bcast(__VA_ARGS__); })
 #define MPI_Barrier(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Barrier(__VA_ARGS__); })
+#define MPI_Ibarrier(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ibarrier(__VA_ARGS__); })
+#define MPI_Ibcast(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ibcast(__VA_ARGS__); })
+#define MPI_Igather(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Igather(__VA_ARGS__); })
+#define MPI_Igatherv(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Igatherv(__VA_ARGS__); })
+#define MPI_Iallgather(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Iallgather(__VA_ARGS__); })
+#define MPI_Iallgatherv(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Iallgatherv(__VA_ARGS__); })
+#define MPI_Iscatter(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Iscatter(__VA_ARGS__); })
+#define MPI_Iscatterv(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Iscatterv(__VA_ARGS__); })
+#define MPI_Ireduce(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ireduce(__VA_ARGS__); })
+#define MPI_Iallreduce(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Iallreduce(__VA_ARGS__); })
+#define MPI_Iscan(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Iscan(__VA_ARGS__); })
+#define MPI_Iexscan(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Iexscan(__VA_ARGS__); })
+#define MPI_Ireduce_scatter(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ireduce_scatter(__VA_ARGS__); })
+#define MPI_Ireduce_scatter_block(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ireduce_scatter_block(__VA_ARGS__); })
+#define MPI_Ialltoall(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ialltoall(__VA_ARGS__); })
+#define MPI_Ialltoallv(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ialltoallv(__VA_ARGS__); })
+#define MPI_Ialltoallw(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Ialltoallw(__VA_ARGS__); })
 #define MPI_Gather(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Gather(__VA_ARGS__); })
 #define MPI_Gatherv(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Gatherv(__VA_ARGS__); })
 #define MPI_Allgather(...) ({ smpi_trace_set_call_location(__FILE__,__LINE__); MPI_Allgather(__VA_ARGS__); })
index a634e4b..ef443c0 100644 (file)
 #define MPI_BCAST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Bcast
 #define mpi_barrier smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Barrier
 #define MPI_BARRIER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Barrier
+#define mpi_ibarrier smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibarrier
+#define MPI_IBARRIER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibarrier
+#define mpi_ibcast smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibcast
+#define MPI_IBCAST smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ibcast
+#define mpi_igather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Igather
+#define MPI_IGATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Igather
+#define mpi_igatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Igatherv
+#define MPI_IGATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Igatherv
+#define mpi_iallgather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallgather
+#define MPI_IALLGATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallgather
+#define mpi_iallgatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallgatherv
+#define MPI_IALLGATHERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallgatherv
+#define mpi_iscatter smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscatter
+#define MPI_ISCATTER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscatter
+#define mpi_iscatterv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscatterv
+#define MPI_ISCATTERV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscatterv
+#define mpi_ireduce smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce
+#define MPI_IREDUCE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce
+#define mpi_iallreduce smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallreduce
+#define MPI_IALLREDUCE smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iallreduce
+#define mpi_iscan smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscan
+#define MPI_ISCAN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iscan
+#define mpi_iexscan smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iexscan
+#define MPI_IEXSCAN smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Iexscan
+#define mpi_ireduce_scatter smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce_scatter
+#define MPI_IREDUCE_SCATTER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce_scatter
+#define mpi_ireduce_scatter_block smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce_scatter_block
+#define MPI_IREDUCE_SCATTER_BLOCK smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ireduce_scatter_block
+#define mpi_ialltoall smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoall
+#define MPI_IALLTOALL smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoall
+#define mpi_ialltoallv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoallv
+#define MPI_IALLTOALLV smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoallv
+#define mpi_ialltoallw smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoallw
+#define MPI_IALLTOALLW smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Ialltoallw
 #define mpi_gather smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Gather
 #define MPI_GATHER smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Gather
 #define mpi_gatherv smpi_trace_set_call_location(__FILE__,__LINE__); call MPI_Gatherv
index 5acaebe..37a7d41 100644 (file)
@@ -26,7 +26,7 @@ class Extension {
 public:
   explicit constexpr Extension() : id_(INVALID_ID) {}
   std::size_t id() const { return id_; }
-  bool valid() { return id_ != INVALID_ID; }
+  bool valid() const { return id_ != INVALID_ID; }
 };
 
 /** An Extendable is an object that you can extend with external elements.
@@ -83,7 +83,7 @@ public:
   }
 
   // Type-unsafe versions of the facet access methods:
-  void* extension(std::size_t rank)
+  void* extension(std::size_t rank) const
   {
     if (rank >= extensions_.size())
       return nullptr;
@@ -101,11 +101,7 @@ public:
   }
 
   // Type safe versions of the facet access methods:
-  template<class U>
-  U* extension(Extension<T,U> rank)
-  {
-    return static_cast<U*>(extension(rank.id()));
-  }
+  template <class U> U* extension(Extension<T, U> rank) const { return static_cast<U*>(extension(rank.id())); }
   template<class U>
   void extension_set(Extension<T,U> rank, U* value, bool use_dtor = true)
   {
@@ -113,7 +109,7 @@ public:
   }
 
   // Convenience extension access when the type has a associated EXTENSION ID:
-  template<class U> U* extension()           { return extension<U>(U::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 3886b7f..d34b992 100644 (file)
@@ -77,6 +77,8 @@
   XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped in v3.24)") /* Will be dropped in v3.24 */
 #define XBT_ATTRIB_DEPRECATED_v325(mesg)                                                                               \
   XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped in v3.25)") /* Will be dropped in v3.25 */
+#define XBT_ATTRIB_DEPRECATED_v326(mesg)                                                                               \
+  XBT_ATTRIB_DEPRECATED(mesg " (this compatibility wrapper will be dropped in v3.26)") /* Will be dropped in v3.26 */
 
 #if !defined(__APPLE__)
 #  define XBT_ATTRIB_CONSTRUCTOR(prio) __attribute__((__constructor__(prio)))
index 4524106..c37ff47 100644 (file)
@@ -77,7 +77,7 @@ XBT_ATTRIB_NORETURN void xbt_throw_impossible(const char* file, int line, const
 /** Throw an exception because something unimplemented stuff has been attempted
  *  @ingroup XBT_ex_c
  */
-XBT_ATTRIB_NORETURN void xbt_throw_unimplemented(const char* file, int line, const char* func);
+XBT_ATTRIB_NORETURN XBT_PUBLIC void xbt_throw_unimplemented(const char* file, int line, const char* func);
 #define THROW_UNIMPLEMENTED xbt_throw_unimplemented(__FILE__, __LINE__, __func__)
 
 /** Die because something impossible happened
index 608d372..9ca66f8 100644 (file)
@@ -175,7 +175,8 @@ public:
     vtable_ = that.vtable_;
     that.vtable_ = nullptr;
   }
-  Task& operator=(Task that)
+  Task& operator=(Task const& that) = delete;
+  Task& operator=(Task&& that)
   {
     this->clear();
     if (that.vtable_ && that.vtable_->move)
index 4f0365d..a6df123 100644 (file)
@@ -297,10 +297,10 @@ XBT_PUBLIC void xbt_log_additivity_set(xbt_log_category_t cat, int additivity);
  *
  * This layout is not as flexible as the pattern one
  */
-XBT_PUBLIC xbt_log_layout_t xbt_log_layout_simple_new(char* arg);
-XBT_PUBLIC xbt_log_layout_t xbt_log_layout_format_new(char* arg);
-XBT_PUBLIC xbt_log_appender_t xbt_log_appender_file_new(char* arg);
-XBT_PUBLIC xbt_log_appender_t xbt_log_appender2_file_new(char* arg, int roll);
+XBT_PUBLIC xbt_log_layout_t xbt_log_layout_simple_new(const char* arg);
+XBT_PUBLIC xbt_log_layout_t xbt_log_layout_format_new(const char* arg);
+XBT_PUBLIC xbt_log_appender_t xbt_log_appender_file_new(const char* arg);
+XBT_PUBLIC xbt_log_appender_t xbt_log_appender2_file_new(const char* arg, int roll);
 
 /* ********************************** */
 /* Functions that you shouldn't call  */
index 7eb960f..b98b00e 100644 (file)
@@ -28,8 +28,6 @@ XBT_PUBLIC xbt_dynar_t xbt_str_split(const char* s, const char* sep);
 XBT_PUBLIC xbt_dynar_t xbt_str_split_quoted(const char* s);
 XBT_PUBLIC xbt_dynar_t xbt_str_split_quoted_in_place(char* s);
 
-XBT_PUBLIC char* xbt_str_join_array(const char* const* strs, const char* sep);
-
 XBT_PUBLIC long int xbt_str_parse_int(const char* str, const char* error_mesg);
 XBT_PUBLIC double xbt_str_parse_double(const char* str, const char* error_mesg);
 
index a082dd9..b6c12aa 100644 (file)
@@ -3,7 +3,7 @@
 
 sonar.projectKey=simgrid
 sonar.projectName=SimGrid
-sonar.projectVersion=3.21.90
+sonar.projectVersion=3.22.90
 
 sonar.links.homepage=https://simgrid.org
 sonar.links.issue=https://framagit.org/simgrid/simgrid/issues
diff --git a/src/bindings/lua/lua_debug.cpp b/src/bindings/lua/lua_debug.cpp
deleted file mode 100644 (file)
index 1d7ed69..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/* Copyright (c) 2010-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 file contains functions that aid users to debug their lua scripts; for instance,
- * tables can be easily output and values are represented in a human-readable way. (For instance,
- * a nullptr value becomes the string "nil").
- *
- */
- /* SimGrid Lua debug functions                                             */
-#include <lauxlib.h>
-#include "lua_utils.hpp"
-#include "xbt.h"
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(lua_debug, "Lua bindings (helper functions)");
-
-/**
- * @brief Returns a string representation of a value in the Lua stack.
- *
- * This function is for debugging purposes.
- * It always returns the same pointer.
- *
- * @param L the Lua state
- * @param index index in the stack
- * @return a string representation of the value at this index
- */
-const char* sglua_tostring(lua_State* L, int index) {
-
-  static char buff[64];
-
-  switch (lua_type(L, index)) {
-
-    case LUA_TNIL:
-      snprintf(buff, 4, "nil");
-      break;
-
-    case LUA_TNUMBER:
-      snprintf(buff, 64, "%.3f", lua_tonumber(L, index));
-      break;
-
-    case LUA_TBOOLEAN:
-      snprintf(buff, 64, "%s", lua_toboolean(L, index) ? "true" : "false");
-      break;
-
-    case LUA_TSTRING:
-      snprintf(buff, 63, "'%s'", lua_tostring(L, index));
-      break;
-
-    case LUA_TFUNCTION:
-      if (lua_iscfunction(L, index)) {
-        snprintf(buff, 11, "C-function");
-      }
-      else {
-        snprintf(buff, 9, "function");
-      }
-      break;
-
-    case LUA_TTABLE:
-      snprintf(buff, 64, "table(%p)", lua_topointer(L, index));
-      break;
-
-    case LUA_TLIGHTUSERDATA:
-    case LUA_TUSERDATA:
-      snprintf(buff, 64, "userdata(%p)", lua_touserdata(L, index));
-      break;
-
-    case LUA_TTHREAD:
-      snprintf(buff, 7, "thread");
-      break;
-
-    default:
-      snprintf(buff, 64, "unknown(%d)", lua_type(L, index));
-      break;
-  }
-  return buff;
-}
-
-static int sglua_dump_table(lua_State* L) {
-  int argc = lua_gettop(L);
-
-  for (int i = 1; i < argc; i++) {
-    if (lua_istable(L, i)) {
-      lua_pushnil(L); /* table nil */
-
-      //lua_next pops the topmost element from the stack and
-      //gets the next pair from the table
-      while (lua_next(L, -1)) { /* table key val  */
-        // we need to copy here, as a cast from "Number" to "String"
-        // could happen in Lua.
-        // see remark in the lua manual, function "lua_tolstring"
-        // http://www.lua.org/manual/5.3/manual.html#lua_tolstring
-
-        lua_pushvalue(L, -2); /* table key val key */
-
-        const char *key = lua_tostring(L, -1); /* table key val */
-        const char *val = lua_tostring(L, -1); /* table key     */
-
-        XBT_DEBUG("%s => %s", key, val);
-      }
-
-      lua_settop(L, argc); // Remove everything except the initial arguments
-    }
-  }
-
-  return 0;
-}
-
-/**
- * @brief Returns a string composed of the specified number of spaces.
- *
- * This function can be used to indent strings for debugging purposes.
- * It always returns the same pointer.
- *
- * @param length length of the string
- * @return a string of this length with only spaces
- */
-const char* sglua_get_spaces(int length) {
-
-  static char spaces[128];
-
-  xbt_assert(length >= 0 && length < 128,
-      "Invalid indentation length: %d", length);
-  if (length != 0) {
-    memset(spaces, ' ', length);
-  }
-  spaces[length] = '\0';
-  return spaces;
-}
-
-/**
- * @brief Returns a string representation of a key-value pair.
- *
- * It always returns the same pointer.
- *
- * @param L the Lua state
- * @param key_index index of the key (in the lua stack)
- * @param value_index index of the value (in the lua stack)
- * @return a string representation of the key-value pair
- */
-const char* sglua_keyvalue_tostring(lua_State* L, int key_index, int value_index) {
-
-  static char buff[64];
-  /* value_tostring also always returns the same pointer */
-  int len = snprintf(buff, 63, "[%s] -> ", sglua_tostring(L, key_index));
-  snprintf(buff + len, 63 - len, "%s", sglua_tostring(L, value_index));
-  return buff;
-}
-
-/**
- * @brief Dumps the Lua stack if debug logs are enabled.
- * @param msg a message to print
- * @param L a Lua state
- */
-void sglua_stack_dump(lua_State* L, const char* msg)
-{
-  if (XBT_LOG_ISENABLED(lua_debug, xbt_log_priority_debug)) {
-    char buff[2048];
-    char* p = buff;
-    int top = lua_gettop(L);
-
-    fflush(stdout);
-
-    p[0] = '\0';
-    for (int i = 1; i <= top; i++) {  /* repeat for each level */
-      p += snprintf(p, 2048-(p-buff), "%s ", sglua_tostring(L, i));
-    }
-
-    XBT_DEBUG("%s%s", msg, buff);
-  }
-}
-
-/**
- * @brief Like luaL_checkudata, with additional debug logs.
- *
- * This function is for debugging purposes only.
- *
- * @param L a lua state
- * @param ud index of the userdata to check in the stack
- * @param tname key of the metatable of this userdata in the registry
- */
-void* sglua_checkudata_debug(lua_State* L, int ud, const char* tname)
-{
-  XBT_DEBUG("Checking the userdata: ud = %d", ud);
-  sglua_stack_dump(L, "my_checkudata: ");
-  void* p = lua_touserdata(L, ud);
-  lua_getfield(L, LUA_REGISTRYINDEX, tname);
-  const void* correct_mt = lua_topointer(L, -1);
-
-  int has_mt = lua_getmetatable(L, ud);
-  XBT_DEBUG("Checking the userdata: has metatable ? %d", has_mt);
-  const void* actual_mt = nullptr;
-  if (has_mt) {
-    actual_mt = lua_topointer(L, -1);
-    lua_pop(L, 1);
-  }
-  XBT_DEBUG("Checking the task's metatable: expected %p, found %p", correct_mt, actual_mt);
-  sglua_stack_dump(L, "my_checkudata: ");
-
-  if (p == nullptr || not lua_getmetatable(L, ud) || not lua_rawequal(L, -1, -2))
-    XBT_ERROR("Error: Userdata is nullptr, couldn't find metatable or top of stack does not equal element below it.");
-  lua_pop(L, 2);
-  return p;
-}
-
-/**
- * @brief Writes the specified data into a memory buffer.
- *
- * This function is a valid lua_Writer that writes into a memory buffer passed
- * as userdata.
- *
- * @param L        a lua state
- * @param source   some data
- * @param size     number of bytes of data
- * @param userdata the memory buffer to write
- */
-int sglua_memory_writer(lua_State* /*L*/, const void* source, size_t size, void* userdata)
-{
-  sglua_buffer_t buffer = static_cast<sglua_buffer_t>(userdata);
-  while (buffer->capacity < buffer->size + size) {
-    buffer->capacity *= 2;
-    buffer->data = static_cast<char*>(xbt_realloc(buffer->data, buffer->capacity));
-  }
-  memcpy(buffer->data + buffer->size, source, size);
-  buffer->size += size;
-
-  return 0;
-}
diff --git a/src/bindings/lua/lua_utils.cpp b/src/bindings/lua/lua_utils.cpp
new file mode 100644 (file)
index 0000000..82a3689
--- /dev/null
@@ -0,0 +1,96 @@
+/* Copyright (c) 2010-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 file contains functions that aid users to debug their lua scripts; for instance,
+ * tables can be easily output and values are represented in a human-readable way. (For instance,
+ * a nullptr value becomes the string "nil").
+ *
+ */
+/* SimGrid Lua helper functions                                             */
+#include "lua_utils.hpp"
+#include <lauxlib.h>
+
+/**
+ * @brief Returns a string representation of a value in the Lua stack.
+ *
+ * This function is for debugging purposes.
+ * It always returns the same pointer.
+ *
+ * @param L the Lua state
+ * @param index index in the stack
+ * @return a string representation of the value at this index
+ */
+const char* sglua_tostring(lua_State* L, int index)
+{
+
+  static char buff[64];
+
+  switch (lua_type(L, index)) {
+
+    case LUA_TNIL:
+      snprintf(buff, 4, "nil");
+      break;
+
+    case LUA_TNUMBER:
+      snprintf(buff, 64, "%.3f", lua_tonumber(L, index));
+      break;
+
+    case LUA_TBOOLEAN:
+      snprintf(buff, 64, "%s", lua_toboolean(L, index) ? "true" : "false");
+      break;
+
+    case LUA_TSTRING:
+      snprintf(buff, 63, "'%s'", lua_tostring(L, index));
+      break;
+
+    case LUA_TFUNCTION:
+      if (lua_iscfunction(L, index)) {
+        snprintf(buff, 11, "C-function");
+      } else {
+        snprintf(buff, 9, "function");
+      }
+      break;
+
+    case LUA_TTABLE:
+      snprintf(buff, 64, "table(%p)", lua_topointer(L, index));
+      break;
+
+    case LUA_TLIGHTUSERDATA:
+    case LUA_TUSERDATA:
+      snprintf(buff, 64, "userdata(%p)", lua_touserdata(L, index));
+      break;
+
+    case LUA_TTHREAD:
+      snprintf(buff, 7, "thread");
+      break;
+
+    default:
+      snprintf(buff, 64, "unknown(%d)", lua_type(L, index));
+      break;
+  }
+  return buff;
+}
+
+/**
+ * @brief Returns a string representation of a key-value pair.
+ *
+ * It always returns the same pointer.
+ *
+ * @param L the Lua state
+ * @param key_index index of the key (in the lua stack)
+ * @param value_index index of the value (in the lua stack)
+ * @return a string representation of the key-value pair
+ */
+const char* sglua_keyvalue_tostring(lua_State* L, int key_index, int value_index)
+{
+
+  static char buff[64];
+  /* value_tostring also always returns the same pointer */
+  int len = snprintf(buff, 63, "[%s] -> ", sglua_tostring(L, key_index));
+  snprintf(buff + len, 63 - len, "%s", sglua_tostring(L, value_index));
+  return buff;
+}
index a7d63bc..678bdfa 100644 (file)
 
 #include <lua.h>
 
-/**
- * @brief A chunk of memory.
- *
- * This structure is used as the userdata parameter of lua_Writer.
- */
-struct s_sglua_buffer_t {
-  char* data;
-  size_t size;
-  size_t capacity;
-};
-typedef s_sglua_buffer_t* sglua_buffer_t;
-
 const char* sglua_tostring(lua_State* L, int index);
 const char* sglua_keyvalue_tostring(lua_State* L, int key_index, int value_index);
-void sglua_stack_dump(lua_State* L, const char* msg);
-static int sglua_dump_table(lua_State* L);
-void* sglua_checkudata_debug(lua_State* L, int ud, const char* tname);
-const char* sglua_get_spaces(int length);
-int sglua_memory_writer(lua_State* L, const void* source, size_t size, void* userdata);
 
 #endif
index ca67538..340c5d2 100644 (file)
@@ -15,6 +15,8 @@
 #include "src/kernel/context/Context.hpp"
 #include <simgrid/Exception.hpp>
 #include <simgrid/s4u/Actor.hpp>
+#include <simgrid/s4u/Comm.hpp>
+#include <simgrid/s4u/Exec.hpp>
 #include <simgrid/s4u/Engine.hpp>
 #include <simgrid/s4u/Host.hpp>
 #include <simgrid/s4u/Mailbox.hpp>
@@ -57,7 +59,7 @@ PYBIND11_MODULE(simgrid, m)
   m.attr("simgrid_version") = simgrid_version;
 
   // Internal exception used to kill actors and sweep the RAII chimney (free objects living on the stack)
-  py::object pyForcefulKillEx = py::register_exception<simgrid::ForcefulKillException>(m, "ActorKilled");
+  static py::object pyForcefulKillEx(py::register_exception<simgrid::ForcefulKillException>(m, "ActorKilled"));
 
   /* this_actor namespace */
   void (*sleep_for_fun)(double) = &simgrid::s4u::this_actor::sleep_for; // pick the right overload
@@ -70,6 +72,7 @@ PYBIND11_MODULE(simgrid, m)
          "Block the current actor, computing the given amount of flops at the given priority, see :cpp:func:`void "
          "simgrid::s4u::this_actor::execute(double, double)`",
          py::arg("flops"), py::arg("priority") = 1);
+  m2.def("exec_init", [](double flops){return simgrid::s4u::this_actor::exec_init(flops);});
   m2.def("get_host", &simgrid::s4u::this_actor::get_host, "Retrieves host on which the current actor is located");
   m2.def("migrate", &simgrid::s4u::this_actor::migrate, "Moves the current actor to another host, see :cpp:func:`void simgrid::s4u::this_actor::migrate()`",
       py::arg("dest"));
@@ -106,8 +109,8 @@ PYBIND11_MODULE(simgrid, m)
         // Currently this can be dangling, we should wrap this somehow.
         return new simgrid::s4u::Engine(&argc, argv.get());
       }))
+      .def_static("get_clock", &Engine::get_clock, "The simulation time, ie the amount of simulated seconds since the simulation start.")
       .def("get_all_hosts", &Engine::get_all_hosts, "Returns the list of all hosts found in the platform")
-      .def("get_clock", &Engine::get_clock, "Retrieve the simulation time (in seconds)")
       .def("load_platform", &Engine::load_platform,
            "Load a platform file describing the environment, see :cpp:func:`simgrid::s4u::Engine::load_platform()`")
       .def("load_deployment", &Engine::load_deployment,
@@ -115,69 +118,116 @@ PYBIND11_MODULE(simgrid, m)
            ":cpp:func:`simgrid::s4u::Engine::load_deployment()`")
       .def("run", &Engine::run, "Run the simulation")
       .def("register_actor",
-           [pyForcefulKillEx](Engine*, const std::string& name, py::object fun_or_class) {
-             simgrid::simix::register_function(
-                 name, [pyForcefulKillEx, fun_or_class](std::vector<std::string> args) -> simgrid::simix::ActorCode {
-                   return [pyForcefulKillEx, fun_or_class, args]() {
-                     try {
-                       /* Convert the std::vector into a py::tuple */
-                       py::tuple params(args.size() - 1);
-                       for (size_t i = 1; i < args.size(); i++)
-                         params[i - 1] = py::cast(args[i]);
-
-                       py::object res = fun_or_class(*params);
-
-                       /* If I was passed a class, I just built an instance, so I need to call it now */
-                       if (py::isinstance<py::function>(res))
-                         res();
-                     } catch (py::error_already_set& ex) {
-                       if (ex.matches(pyForcefulKillEx)) {
-                         XBT_VERB("Actor killed");
-                         /* Stop here that ForcefulKill exception which was meant to free the RAII stuff on the stack */
-                       } else {
-                         throw;
-                       }
-                     }
-                   };
-                 });
+           [](Engine* e, const std::string& name, py::object fun_or_class) {
+             e->register_actor(name, [fun_or_class](std::vector<std::string> args) {
+               try {
+                 /* Convert the std::vector into a py::tuple */
+                 py::tuple params(args.size() - 1);
+                 for (size_t i = 1; i < args.size(); i++)
+                   params[i - 1] = py::cast(args[i]);
+
+                 py::object res = fun_or_class(*params);
+
+                 /* If I was passed a class, I just built an instance, so I need to call it now */
+                 if (py::isinstance<py::function>(res))
+                   res();
+               } catch (py::error_already_set& ex) {
+                 if (ex.matches(pyForcefulKillEx)) {
+                   XBT_VERB("Actor killed");
+                   /* Stop here that ForcefulKill exception which was meant to free the RAII stuff on the stack */
+                 } else {
+                   throw;
+                 }
+               }
+             });
            },
-           "Registers the main function of an actor, see :cpp:func:`simgrid::s4u::Engine::register_function()`");
+           "Registers the main function of an actor, see :cpp:func:`simgrid::s4u::Engine::register_actor()`");
 
   /* Class Host */
   py::class_<simgrid::s4u::Host, std::unique_ptr<Host, py::nodelete>>(m, "Host", "Simulation Engine, see :ref:`class s4u::Host <API_s4u_Host>`")
       .def("by_name", &Host::by_name, "Retrieves a host from its name, or die")
+      .def("get_pstate_count", &Host::get_pstate_count, "Retrieve the cound of defined pstate levels, see :cpp:func:`simgrid::s4u::Host::get_pstate_count`")
+      .def("get_pstate_speed", &Host::get_pstate_speed, "Retrieve the maximal speed at the given pstate, see :cpp:func:`simgrid::s4u::Host::get_pstate_speed`")
+      .def_property("pstate", &Host::get_pstate, &Host::set_pstate, "The current pstate")
+
       .def("current", &Host::current, "Retrieves the host on which the running actor is located, see :cpp:func:`simgrid::s4u::Host::current()`")
       .def_property_readonly("name", [](Host* self) -> const std::string {
           return std::string(self->get_name().c_str()); // Convert from xbt::string because of MC
         }, "The name of this host")
+      .def_property_readonly("load", &Host::get_load,
+          "Returns the current computation load (in flops per second). This is the currently achieved speed. See :cpp:func:`simgrid::s4u::Host::get_load()`")
       .def_property_readonly("speed", &Host::get_speed,
-          "The peak computing speed in flops/s at the current pstate, taking the external load into account, see :cpp:func:`simgrid::s4u::Host::get_speed()`");
+          "The peak computing speed in flops/s at the current pstate, taking the external load into account. This is the max potential speed. See :cpp:func:`simgrid::s4u::Host::get_speed()`");
 
   /* Class Mailbox */
   py::class_<simgrid::s4u::Mailbox, std::unique_ptr<Mailbox, py::nodelete>>(m, "Mailbox", "Mailbox, see :ref:`class s4u::Mailbox <API_s4u_Mailbox>`")
+      .def("__str__", [](Mailbox* self) -> const std::string {
+         return std::string("Mailbox(") + self->get_cname() + ")";
+      }, "Textual representation of the Mailbox`")
       .def("by_name", &Mailbox::by_name, "Retrieve a Mailbox from its name, see :cpp:func:`simgrid::s4u::Mailbox::by_name()`")
       .def_property_readonly("name", [](Mailbox* self) -> const std::string {
          return std::string(self->get_name().c_str()); // Convert from xbt::string because of MC
       }, "The name of that mailbox, see :cpp:func:`simgrid::s4u::Mailbox::get_name()`")
-      .def("put", [](Mailbox self, py::object data, int size) {
+      .def("put", [](Mailbox* self, py::object data, int size) {
         data.inc_ref();
-        self.put(data.ptr(), size);
+        self->put(data.ptr(), size);
       }, "Blocking data transmission, see :cpp:func:`void simgrid::s4u::Mailbox::put(void*, uint64_t)`")
-      .def("get", [](Mailbox self) -> py::object {
-         py::object data = pybind11::reinterpret_steal<py::object>(pybind11::handle(static_cast<PyObject*>(self.get())));
+      .def("put_async", [](Mailbox* self, py::object data, int size) -> simgrid::s4u::CommPtr {
+        data.inc_ref();
+        return self->put_async(data.ptr(), size);
+      }, "Non-blocking data transmission, see :cpp:func:`void simgrid::s4u::Mailbox::put_async(void*, uint64_t)`")
+      .def("get", [](Mailbox* self) -> py::object {
+         py::object data = pybind11::reinterpret_steal<py::object>(static_cast<PyObject*>(self->get()));
          data.dec_ref();
          return data;
       }, "Blocking data reception, see :cpp:func:`void* simgrid::s4u::Mailbox::get()`");
 
+  /* Class Comm */
+  py::class_<simgrid::s4u::Comm, simgrid::s4u::CommPtr>(m, "Comm",
+                                                        "Communication, see :ref:`class s4u::Comm <API_s4u_Comm>`")
+      .def("test", [](simgrid::s4u::CommPtr self) { return self->test(); },
+           "Test whether the communication is terminated, see :cpp:func:`simgrid::s4u::Comm::test()`")
+      .def("wait", [](simgrid::s4u::CommPtr self) { self->wait(); },
+           "Block until the completion of that communication, see :cpp:func:`simgrid::s4u::Comm::wait()`")
+      .def("wait_all", [](std::vector<simgrid::s4u::CommPtr>* comms) { simgrid::s4u::Comm::wait_all(comms); },
+           "Block until the completion of all communications in the list, see "
+           ":cpp:func:`simgrid::s4u::Comm::wait_all()`")
+      .def(
+          "wait_any", [](std::vector<simgrid::s4u::CommPtr>* comms) { return simgrid::s4u::Comm::wait_any(comms); },
+          "Block until the completion of any communication in the list and return the index of the terminated one, see "
+          ":cpp:func:`simgrid::s4u::Comm::wait_any()`");
+  py::class_<simgrid::s4u::Exec, simgrid::s4u::ExecPtr>(m, "Exec", "Execution, see :ref:`class s4u::Exec <API_s4u_Exec>`")
+      .def_property_readonly("remaining", [](simgrid::s4u::ExecPtr self) { return self->get_remaining(); },
+          "Amount of flops that remain to be computed until completion, see :cpp:func:`simgrid::s4u::Exec::get_remaining()`")
+      .def_property_readonly("remaining_ratio", [](simgrid::s4u::ExecPtr self) { return self->get_remaining_ratio(); },
+          "Amount of work remaining until completion from 0 (completely done) to 1 (nothing done yet). See :cpp:func:`simgrid::s4u::Exec::get_remaining_ratio()`")
+      .def_property("host",
+                    [](simgrid::s4u::ExecPtr self) {
+                        simgrid::s4u::ExecSeqPtr seq = boost::dynamic_pointer_cast<simgrid::s4u::ExecSeq>(self);
+                        if (seq != nullptr)
+                            return seq->get_host();
+                        xbt_throw_unimplemented(__FILE__, __LINE__, "host of parallel executions is not implemented in python yet.");
+                    },
+                    [](simgrid::s4u::ExecPtr self, simgrid::s4u::Host* host) { self->set_host(host); },
+          "Host on which this execution runs. See :cpp:func:`simgrid::s4u::ExecSeq::get_host()`")
+      .def("test", [](simgrid::s4u::ExecPtr self) { return self->test(); },
+          "Test whether the execution is terminated, see :cpp:func:`simgrid::s4u::Exec::test()`")
+      .def("cancel", [](simgrid::s4u::ExecPtr self) { self->cancel(); },
+          "Cancel that execution, see :cpp:func:`simgrid::s4u::Exec::cancel()`")
+      .def("start", [](simgrid::s4u::ExecPtr self) { return self->start(); },
+          "Start that execution, see :cpp:func:`simgrid::s4u::Exec::start()`")
+      .def("wait", [](simgrid::s4u::ExecPtr self) { return self->wait(); },
+          "Block until the completion of that execution, see :cpp:func:`simgrid::s4u::Exec::wait()`");
+
   /* Class Actor */
   py::class_<simgrid::s4u::Actor, ActorPtr>(m, "Actor",
                                             "An actor is an independent stream of execution in your distributed "
                                             "application, see :ref:`class s4u::Actor <API_s4u_Actor>`")
 
       .def("create",
-           [pyForcefulKillEx](py::str name, py::object host, py::object fun, py::args args) {
+           [](py::str name, py::object host, py::object fun, py::args args) {
 
-             return simgrid::s4u::Actor::create(name, host.cast<Host*>(), [fun, args, pyForcefulKillEx]() {
+             return simgrid::s4u::Actor::create(name, host.cast<Host*>(), [fun, args]() {
 
                try {
                  fun(*args);
index 839d029..ec4fdc8 100644 (file)
@@ -294,7 +294,7 @@ template <typename T> void Parmap<T>::worker_main(ThreadData* data)
 {
   Parmap<T>& parmap     = data->parmap;
   unsigned round        = 0;
-  smx_context_t context = simix_global->context_factory->create_context(std::function<void()>(), nullptr);
+  kernel::context::Context* context = simix_global->context_factory->create_context(std::function<void()>(), nullptr);
   kernel::context::Context::set_current(context);
 
   XBT_CDEBUG(xbt_parmap, "New worker thread created");
index 49271aa..dedda24 100644 (file)
@@ -59,7 +59,7 @@ RouterContainer::RouterContainer(const std::string& name, Container* father)
   trivaNodeTypes.insert(type_->get_name());
 }
 
-HostContainer::HostContainer(simgrid::s4u::Host& host, NetZoneContainer* father)
+HostContainer::HostContainer(simgrid::s4u::Host const& host, NetZoneContainer* father)
     : Container::Container(host.get_name(), "HOST", father)
 {
   xbt_assert(father, "Only the Root container has no father");
index e4c33e6..17241ef 100644 (file)
@@ -58,7 +58,7 @@ public:
 
 class HostContainer : public Container {
 public:
-  HostContainer(simgrid::s4u::Host& host, NetZoneContainer* father);
+  HostContainer(simgrid::s4u::Host const& host, NetZoneContainer* father);
 };
 }
 }
index 0870bf0..ed016d8 100644 (file)
@@ -83,6 +83,10 @@ void VariableEvent::print()
   tracing_file << stream_.str() << std::endl;
 }
 
+StateEvent::~StateEvent(){
+  delete extra_;
+}
+
 void StateEvent::print()
 {
   if (trace_format == simgrid::instr::TraceFormat::Paje) {
@@ -119,7 +123,6 @@ void StateEvent::print()
     THROW_IMPOSSIBLE;
   }
 
-  delete extra_;
 }
 }
 }
index 71dd4c7..d57c644 100644 (file)
@@ -74,6 +74,7 @@ class StateEvent : public PajeEvent {
 
 public:
   StateEvent(Container* container, Type* type, e_event_type event_type, EntityValue* value, TIData* extra);
+  ~StateEvent();
   void print() override;
 };
 
index 2a440d1..f880887 100644 (file)
@@ -85,8 +85,6 @@ static void buffer_debug(std::vector<simgrid::instr::PajeEvent*>* buf)
 /* internal do the instrumentation module */
 void simgrid::instr::PajeEvent::insert_into_buffer()
 {
-  buffer_debug(&buffer);
-
   XBT_DEBUG("%s: insert event_type=%u, timestamp=%f, buffersize=%zu)", __func__, eventType_, timestamp_, buffer.size());
   std::vector<simgrid::instr::PajeEvent*>::reverse_iterator i;
   for (i = buffer.rbegin(); i != buffer.rend(); ++i) {
@@ -102,6 +100,4 @@ void simgrid::instr::PajeEvent::insert_into_buffer()
   else
     XBT_DEBUG("%s: inserted at pos= %zd from its end", __func__, std::distance(buffer.rbegin(), i));
   buffer.insert(i.base(), this);
-
-  buffer_debug(&buffer);
 }
index 4bc1e2c..e260779 100644 (file)
@@ -155,7 +155,7 @@ static void recursiveGraphExtraction(simgrid::s4u::NetZone* netzone, container_t
 /*
  * Callbacks
  */
-static void instr_netzone_on_creation(simgrid::s4u::NetZone& netzone)
+static void instr_netzone_on_creation(simgrid::s4u::NetZone const& netzone)
 {
   std::string id = netzone.get_name();
   if (simgrid::instr::Container::get_root() == nullptr) {
@@ -185,7 +185,7 @@ static void instr_netzone_on_creation(simgrid::s4u::NetZone& netzone)
   }
 }
 
-static void instr_link_on_creation(simgrid::s4u::Link& link)
+static void instr_link_on_creation(simgrid::s4u::Link const& link)
 {
   if (currentContainer.empty()) // No ongoing parsing. Are you creating the loopback?
     return;
@@ -205,7 +205,7 @@ static void instr_link_on_creation(simgrid::s4u::Link& link)
   }
 }
 
-static void instr_host_on_creation(simgrid::s4u::Host& host)
+static void instr_host_on_creation(simgrid::s4u::Host const& host)
 {
   container_t container = new simgrid::instr::HostContainer(host, currentContainer.back());
   container_t root      = simgrid::instr::Container::get_root();
@@ -232,48 +232,48 @@ static void instr_host_on_creation(simgrid::s4u::Host& host)
   }
 }
 
-static void instr_host_on_speed_change(simgrid::s4u::Host& host)
+static void instr_host_on_speed_change(simgrid::s4u::Host const& host)
 {
   simgrid::instr::Container::by_name(host.get_name())
       ->get_variable("speed")
       ->set_event(surf_get_clock(), host.get_core_count() * host.get_available_speed());
 }
 
-static void instr_action_on_state_change(simgrid::kernel::resource::Action* action,
+static void instr_action_on_state_change(simgrid::kernel::resource::Action const& action,
                                          simgrid::kernel::resource::Action::State /* previous */)
 {
-  int n = action->get_variable()->get_number_of_constraint();
+  int n = action.get_variable()->get_number_of_constraint();
 
   for (int i = 0; i < n; i++) {
-    double value = action->get_variable()->get_value() * action->get_variable()->get_constraint_weight(i);
+    double value = action.get_variable()->get_value() * action.get_variable()->get_constraint_weight(i);
     /* Beware of composite actions: ptasks put links and cpus together. Extra pb: we cannot dynamic_cast from void* */
     simgrid::kernel::resource::Resource* resource =
-        static_cast<simgrid::kernel::resource::Resource*>(action->get_variable()->get_constraint(i)->get_id());
+        static_cast<simgrid::kernel::resource::Resource*>(action.get_variable()->get_constraint(i)->get_id());
     simgrid::surf::Cpu* cpu = dynamic_cast<simgrid::surf::Cpu*>(resource);
 
     if (cpu != nullptr)
-      TRACE_surf_resource_set_utilization("HOST", "speed_used", cpu->get_cname(), action->get_category(), value,
-                                          action->get_last_update(), SIMIX_get_clock() - action->get_last_update());
+      TRACE_surf_resource_set_utilization("HOST", "speed_used", cpu->get_cname(), action.get_category(), value,
+                                          action.get_last_update(), SIMIX_get_clock() - action.get_last_update());
 
     simgrid::kernel::resource::LinkImpl* link = dynamic_cast<simgrid::kernel::resource::LinkImpl*>(resource);
 
     if (link != nullptr)
-      TRACE_surf_resource_set_utilization("LINK", "bandwidth_used", link->get_cname(), action->get_category(), value,
-                                          action->get_last_update(), SIMIX_get_clock() - action->get_last_update());
+      TRACE_surf_resource_set_utilization("LINK", "bandwidth_used", link->get_cname(), action.get_category(), value,
+                                          action.get_last_update(), SIMIX_get_clock() - action.get_last_update());
   }
 }
 
-static void instr_link_on_bandwidth_change(simgrid::s4u::Link& link)
+static void instr_link_on_bandwidth_change(simgrid::s4u::Link const& link)
 {
   simgrid::instr::Container::by_name(link.get_name())
       ->get_variable("bandwidth")
       ->set_event(surf_get_clock(), sg_bandwidth_factor * link.get_bandwidth());
 }
 
-static void instr_netpoint_on_creation(simgrid::kernel::routing::NetPoint* netpoint)
+static void instr_netpoint_on_creation(simgrid::kernel::routing::NetPoint const& netpoint)
 {
-  if (netpoint->is_router())
-    new simgrid::instr::RouterContainer(netpoint->get_name(), currentContainer.back());
+  if (netpoint.is_router())
+    new simgrid::instr::RouterContainer(netpoint.get_name(), currentContainer.back());
 }
 
 static void instr_on_platform_created()
@@ -288,12 +288,12 @@ static void instr_on_platform_created()
   TRACE_paje_dump_buffer(true);
 }
 
-static void instr_actor_on_creation(simgrid::s4u::ActorPtr actor)
+static void instr_actor_on_creation(simgrid::s4u::Actor const& actor)
 {
   container_t root      = simgrid::instr::Container::get_root();
-  container_t container = simgrid::instr::Container::by_name(actor->get_host()->get_name());
+  container_t container = simgrid::instr::Container::by_name(actor.get_host()->get_name());
 
-  container->create_child(instr_pid(actor.get()), "ACTOR");
+  container->create_child(instr_pid(actor), "ACTOR");
   simgrid::instr::ContainerType* actor_type =
       container->type_->by_name_or_create<simgrid::instr::ContainerType>("ACTOR");
   simgrid::instr::StateType* state = actor_type->by_name_or_create<simgrid::instr::StateType>("ACTOR_STATE");
@@ -305,8 +305,8 @@ static void instr_actor_on_creation(simgrid::s4u::ActorPtr actor)
   root->type_->by_name_or_create("ACTOR_LINK", actor_type, actor_type);
   root->type_->by_name_or_create("ACTOR_TASK_LINK", actor_type, actor_type);
 
-  std::string container_name = instr_pid(actor.get());
-  actor->on_exit([container_name](bool failed) {
+  std::string container_name = instr_pid(actor);
+  actor.on_exit([container_name](bool failed) {
     if (failed)
       // kill means that this actor no longer exists, let's destroy it
       simgrid::instr::Container::by_name(container_name)->remove_from_parent();
@@ -315,28 +315,28 @@ static void instr_actor_on_creation(simgrid::s4u::ActorPtr actor)
 
 static long long int counter = 0;
 
-static void instr_actor_on_migration_start(simgrid::s4u::ActorPtr actor)
+static void instr_actor_on_migration_start(simgrid::s4u::Actor const& actor)
 {
   // start link
-  container_t container = simgrid::instr::Container::by_name(instr_pid(actor.get()));
+  container_t container = simgrid::instr::Container::by_name(instr_pid(actor));
   simgrid::instr::Container::get_root()->get_link("ACTOR_LINK")->start_event(container, "M", std::to_string(counter));
 
   // destroy existing container of this process
   container->remove_from_parent();
 }
 
-static void instr_actor_on_migration_end(simgrid::s4u::ActorPtr actor)
+static void instr_actor_on_migration_end(simgrid::s4u::Actor const& actor)
 {
   // create new container on the new_host location
-  simgrid::instr::Container::by_name(actor->get_host()->get_name())->create_child(instr_pid(actor.get()), "ACTOR");
+  simgrid::instr::Container::by_name(actor.get_host()->get_name())->create_child(instr_pid(actor), "ACTOR");
   // end link
   simgrid::instr::Container::get_root()
       ->get_link("ACTOR_LINK")
-      ->end_event(simgrid::instr::Container::by_name(instr_pid(actor.get())), "M", std::to_string(counter));
+      ->end_event(simgrid::instr::Container::by_name(instr_pid(actor)), "M", std::to_string(counter));
   counter++;
 }
 
-static void instr_vm_on_creation(simgrid::s4u::Host& host)
+static void instr_vm_on_creation(simgrid::s4u::Host const& host)
 {
   container_t container             = new simgrid::instr::HostContainer(host, currentContainer.back());
   container_t root                  = simgrid::instr::Container::get_root();
@@ -361,7 +361,8 @@ void instr_define_callbacks()
     simgrid::s4u::Host::on_speed_change.connect(instr_host_on_speed_change);
     simgrid::s4u::Link::on_creation.connect(instr_link_on_creation);
     simgrid::s4u::Link::on_bandwidth_change.connect(instr_link_on_bandwidth_change);
-    simgrid::s4u::NetZone::on_seal.connect([](simgrid::s4u::NetZone& /*netzone*/) { currentContainer.pop_back(); });
+    simgrid::s4u::NetZone::on_seal.connect(
+        [](simgrid::s4u::NetZone const& /*netzone*/) { currentContainer.pop_back(); });
     simgrid::kernel::routing::NetPoint::on_creation.connect(instr_netpoint_on_creation);
   }
   simgrid::s4u::NetZone::on_creation.connect(instr_netzone_on_creation);
@@ -371,37 +372,37 @@ void instr_define_callbacks()
 
   if (TRACE_actor_is_enabled()) {
     simgrid::s4u::Actor::on_creation.connect(instr_actor_on_creation);
-    simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::ActorPtr actor) {
-      auto container = simgrid::instr::Container::by_name_or_null(instr_pid(actor.get()));
+    simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::Actor const& actor) {
+      auto container = simgrid::instr::Container::by_name_or_null(instr_pid(actor));
       if (container != nullptr)
         container->remove_from_parent();
     });
-    simgrid::s4u::Actor::on_suspend.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->push_event("suspend");
+    simgrid::s4u::Actor::on_suspend.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->push_event("suspend");
     });
-    simgrid::s4u::Actor::on_resume.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->pop_event();
+    simgrid::s4u::Actor::on_resume.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->pop_event();
     });
-    simgrid::s4u::Actor::on_sleep.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->push_event("sleep");
+    simgrid::s4u::Actor::on_sleep.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->push_event("sleep");
     });
-    simgrid::s4u::Actor::on_wake_up.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->pop_event();
+    simgrid::s4u::Actor::on_wake_up.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->pop_event();
     });
-    simgrid::s4u::Exec::on_start.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->push_event("execute");
+    simgrid::s4u::Exec::on_start.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->push_event("execute");
     });
-    simgrid::s4u::Exec::on_completion.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->pop_event();
+    simgrid::s4u::Exec::on_completion.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->pop_event();
     });
-    simgrid::s4u::Comm::on_sender_start.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->push_event("send");
+    simgrid::s4u::Comm::on_sender_start.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->push_event("send");
     });
-    simgrid::s4u::Comm::on_receiver_start.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->push_event("receive");
+    simgrid::s4u::Comm::on_receiver_start.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->push_event("receive");
     });
-    simgrid::s4u::Comm::on_completion.connect([](simgrid::s4u::ActorPtr actor) {
-      simgrid::instr::Container::by_name(instr_pid(actor.get()))->get_state("ACTOR_STATE")->pop_event();
+    simgrid::s4u::Comm::on_completion.connect([](simgrid::s4u::Actor const& actor) {
+      simgrid::instr::Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->pop_event();
     });
     simgrid::s4u::Actor::on_migration_start.connect(instr_actor_on_migration_start);
     simgrid::s4u::Actor::on_migration_end.connect(instr_actor_on_migration_end);
@@ -409,20 +410,21 @@ void instr_define_callbacks()
 
   if (TRACE_vm_is_enabled()) {
     simgrid::s4u::Host::on_creation.connect(instr_vm_on_creation);
-    simgrid::s4u::VirtualMachine::on_start.connect([](simgrid::s4u::VirtualMachine& vm) {
+    simgrid::s4u::VirtualMachine::on_start.connect([](simgrid::s4u::VirtualMachine const& vm) {
       simgrid::instr::Container::by_name(vm.get_name())->get_state("VM_STATE")->push_event("start");
     });
-    simgrid::s4u::VirtualMachine::on_started.connect([](simgrid::s4u::VirtualMachine& vm) {
+    simgrid::s4u::VirtualMachine::on_started.connect([](simgrid::s4u::VirtualMachine const& vm) {
       simgrid::instr::Container::by_name(vm.get_name())->get_state("VM_STATE")->pop_event();
     });
-    simgrid::s4u::VirtualMachine::on_suspend.connect([](simgrid::s4u::VirtualMachine& vm) {
+    simgrid::s4u::VirtualMachine::on_suspend.connect([](simgrid::s4u::VirtualMachine const& vm) {
       simgrid::instr::Container::by_name(vm.get_name())->get_state("VM_STATE")->push_event("suspend");
     });
-    simgrid::s4u::VirtualMachine::on_resume.connect([](simgrid::s4u::VirtualMachine& vm) {
+    simgrid::s4u::VirtualMachine::on_resume.connect([](simgrid::s4u::VirtualMachine const& vm) {
       simgrid::instr::Container::by_name(vm.get_name())->get_state("VM_STATE")->pop_event();
     });
-    simgrid::s4u::Host::on_destruction.connect(
-        [](simgrid::s4u::Host& host) { simgrid::instr::Container::by_name(host.get_name())->remove_from_parent(); });
+    simgrid::s4u::Host::on_destruction.connect([](simgrid::s4u::Host const& host) {
+      simgrid::instr::Container::by_name(host.get_name())->remove_from_parent();
+    });
   }
 }
 /*
index c5886f5..985d664 100644 (file)
@@ -235,7 +235,7 @@ public:
 }
 }
 
-XBT_PRIVATE std::string instr_pid(s4u_Actor* proc);
+XBT_PRIVATE std::string instr_pid(simgrid::s4u::Actor const& proc);
 
 extern XBT_PRIVATE std::set<std::string> created_categories;
 extern XBT_PRIVATE std::set<std::string> declared_marks;
index 0778432..f824149 100644 (file)
@@ -21,7 +21,7 @@ class EngineImpl {
 
 public:
   EngineImpl() = default;
-  ;
+
   EngineImpl(const EngineImpl&) = delete;
   EngineImpl& operator=(const EngineImpl&) = delete;
   virtual ~EngineImpl();
index 5b5c614..f7f719c 100644 (file)
@@ -11,13 +11,22 @@ namespace simgrid {
 namespace kernel {
 namespace activity {
 
+ActivityImpl::~ActivityImpl()
+{
+  if (surf_action_) {
+    surf_action_->unref();
+    XBT_DEBUG("Destroy activity %p", this);
+    surf_action_ = nullptr;
+  }
+}
+
 void ActivityImpl::suspend()
 {
   if (surf_action_ == nullptr)
     return;
   XBT_VERB("This activity is suspended (remain: %f)", surf_action_->get_remains());
   surf_action_->suspend();
-  on_suspended(this);
+  on_suspended(*this);
 }
 
 void ActivityImpl::resume()
@@ -26,7 +35,7 @@ void ActivityImpl::resume()
     return;
   XBT_VERB("This activity is resumed (remain: %f)", surf_action_->get_remains());
   surf_action_->resume();
-  on_resumed(this);
+  on_resumed(*this);
 }
 
 void ActivityImpl::set_category(const std::string& category)
@@ -48,8 +57,8 @@ void intrusive_ptr_release(simgrid::kernel::activity::ActivityImpl* activity)
     delete activity;
   }
 }
-xbt::signal<void(ActivityImplPtr)> ActivityImpl::on_resumed;
-xbt::signal<void(ActivityImplPtr)> ActivityImpl::on_suspended;
+xbt::signal<void(ActivityImpl const&)> ActivityImpl::on_resumed;
+xbt::signal<void(ActivityImpl const&)> ActivityImpl::on_suspended;
 }
 }
 } // namespace simgrid::kernel::activity::
index ed5dc6c..8fdd778 100644 (file)
@@ -21,34 +21,32 @@ namespace kernel {
 namespace activity {
 
 class XBT_PUBLIC ActivityImpl {
+  std::atomic_int_fast32_t refcount_{0};
+  std::string name_; /* Activity name if any */
 public:
+  virtual ~ActivityImpl();
   ActivityImpl() = default;
   explicit ActivityImpl(const std::string& name) : name_(name) {}
-  virtual ~ActivityImpl() = default;
   e_smx_state_t state_ = SIMIX_WAITING; /* State of the activity */
   std::list<smx_simcall_t> simcalls_;   /* List of simcalls waiting for this activity */
   resource::Action* surf_action_ = nullptr;
 
   const std::string& get_name() const { return name_; }
   const char* get_cname() const { return name_.c_str(); }
+  void set_name(const std::string& name) { name_ = name; }
+  void set_category(const std::string& category);
 
   virtual void suspend();
   virtual void resume();
   virtual void post()   = 0; // What to do when a simcall terminates
   virtual void finish() = 0;
-  void set_category(const std::string& category);
 
   // boost::intrusive_ptr<ActivityImpl> support:
   friend XBT_PUBLIC void intrusive_ptr_add_ref(ActivityImpl* activity);
   friend XBT_PUBLIC void intrusive_ptr_release(ActivityImpl* activity);
 
-private:
-  std::atomic_int_fast32_t refcount_{0};
-  std::string name_;                    /* Activity name if any */
-
-public:
-  static xbt::signal<void(ActivityImplPtr)> on_suspended;
-  static xbt::signal<void(ActivityImplPtr)> on_resumed;
+  static xbt::signal<void(ActivityImpl const&)> on_suspended;
+  static xbt::signal<void(ActivityImpl const&)> on_resumed;
 };
 } // namespace activity
 } // namespace kernel
index 5fbd6b3..a838619 100644 (file)
@@ -40,8 +40,9 @@ XBT_PRIVATE smx_activity_t simcall_HANDLER_comm_isend(
   XBT_DEBUG("send from mailbox %p", mbox);
 
   /* Prepare a synchro describing us, so that it gets passed to the user-provided filter of other side */
-  simgrid::kernel::activity::CommImplPtr this_comm = simgrid::kernel::activity::CommImplPtr(
-      new simgrid::kernel::activity::CommImpl(simgrid::kernel::activity::CommImpl::Type::SEND));
+  simgrid::kernel::activity::CommImplPtr this_comm =
+      simgrid::kernel::activity::CommImplPtr(new simgrid::kernel::activity::CommImpl());
+  this_comm->set_type(simgrid::kernel::activity::CommImpl::Type::SEND);
 
   /* Look for communication synchro matching our needs. We also provide a description of
    * ourself so that the other side also gets a chance of choosing if it wants to match with us.
@@ -68,34 +69,29 @@ XBT_PRIVATE smx_activity_t simcall_HANDLER_comm_isend(
     XBT_DEBUG("Receive already pushed");
 
     other_comm->state_ = SIMIX_READY;
-    other_comm->type   = simgrid::kernel::activity::CommImpl::Type::READY;
+    other_comm->set_type(simgrid::kernel::activity::CommImpl::Type::READY);
   }
-  src_proc->comms.push_back(other_comm);
 
   if (detached) {
     other_comm->detached  = true;
     other_comm->clean_fun = clean_fun;
   } else {
     other_comm->clean_fun = nullptr;
+    src_proc->comms.push_back(other_comm);
   }
 
   /* Setup the communication synchro */
   other_comm->src_actor_     = src_proc;
-  other_comm->task_size_     = task_size;
-  other_comm->rate_          = rate;
-  other_comm->src_buff_      = src_buff;
-  other_comm->src_buff_size_ = src_buff_size;
   other_comm->src_data_      = data;
+  (*other_comm).set_src_buff(src_buff, src_buff_size).set_size(task_size).set_rate(rate);
 
   other_comm->match_fun     = match_fun;
   other_comm->copy_data_fun = copy_data_fun;
 
-  if (MC_is_active() || MC_record_replay_is_active()) {
+  if (MC_is_active() || MC_record_replay_is_active())
     other_comm->state_ = SIMIX_RUNNING;
-    return (detached ? nullptr : other_comm);
-  }
-
-  other_comm->start();
+  else
+    other_comm->start();
 
   return (detached ? nullptr : other_comm);
 }
@@ -117,8 +113,9 @@ XBT_PRIVATE smx_activity_t simcall_HANDLER_comm_irecv(
     simix_match_func_t match_fun, void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t),
     void* data, double rate)
 {
-  simgrid::kernel::activity::CommImplPtr this_synchro = simgrid::kernel::activity::CommImplPtr(
-      new simgrid::kernel::activity::CommImpl(simgrid::kernel::activity::CommImpl::Type::RECEIVE));
+  simgrid::kernel::activity::CommImplPtr this_synchro =
+      simgrid::kernel::activity::CommImplPtr(new simgrid::kernel::activity::CommImpl());
+  this_synchro->set_type(simgrid::kernel::activity::CommImpl::Type::RECEIVE);
   XBT_DEBUG("recv from mbox %p. this_synchro=%p", mbox, this_synchro.get());
 
   simgrid::kernel::activity::CommImplPtr other_comm;
@@ -140,7 +137,7 @@ XBT_PRIVATE smx_activity_t simcall_HANDLER_comm_irecv(
       if (other_comm->surf_action_ && other_comm->remains() < 1e-12) {
         XBT_DEBUG("comm %p has been already sent, and is finished, destroy it", other_comm.get());
         other_comm->state_ = SIMIX_DONE;
-        other_comm->type   = simgrid::kernel::activity::CommImpl::Type::DONE;
+        other_comm->set_type(simgrid::kernel::activity::CommImpl::Type::DONE);
         other_comm->mbox   = nullptr;
       }
     }
@@ -163,19 +160,18 @@ XBT_PRIVATE smx_activity_t simcall_HANDLER_comm_irecv(
       XBT_DEBUG("Match my %p with the existing %p", this_synchro.get(), other_comm.get());
 
       other_comm->state_ = SIMIX_READY;
-      other_comm->type   = simgrid::kernel::activity::CommImpl::Type::READY;
+      other_comm->set_type(simgrid::kernel::activity::CommImpl::Type::READY);
     }
     receiver->comms.push_back(other_comm);
   }
 
   /* Setup communication synchro */
   other_comm->dst_actor_     = receiver;
-  other_comm->dst_buff_      = dst_buff;
-  other_comm->dst_buff_size_ = dst_buff_size;
   other_comm->dst_data_      = data;
+  other_comm->set_dst_buff(dst_buff, dst_buff_size);
 
-  if (rate > -1.0 && (other_comm->rate_ < 0.0 || rate < other_comm->rate_))
-    other_comm->rate_ = rate;
+  if (rate > -1.0 && (other_comm->get_rate() < 0.0 || rate < other_comm->get_rate()))
+    other_comm->set_rate(rate);
 
   other_comm->match_fun     = match_fun;
   other_comm->copy_data_fun = copy_data_fun;
@@ -367,12 +363,36 @@ namespace simgrid {
 namespace kernel {
 namespace activity {
 
-CommImpl::CommImpl(CommImpl::Type type) : type(type)
+CommImpl& CommImpl::set_type(CommImpl::Type type)
 {
-  state_   = SIMIX_WAITING;
-  src_data_ = nullptr;
-  dst_data_ = nullptr;
-  XBT_DEBUG("Create comm activity %p", this);
+  type_ = type;
+  return *this;
+}
+
+CommImpl& CommImpl::set_size(double size)
+{
+  size_ = size;
+  return *this;
+}
+
+CommImpl& CommImpl::set_rate(double rate)
+{
+  rate_ = rate;
+  return *this;
+}
+
+CommImpl& CommImpl::set_src_buff(void* buff, size_t size)
+{
+  src_buff_      = buff;
+  src_buff_size_ = size;
+  return *this;
+}
+
+CommImpl& CommImpl::set_dst_buff(void* buff, size_t* size)
+{
+  dst_buff_      = buff;
+  dst_buff_size_ = size;
+  return *this;
 }
 
 CommImpl::~CommImpl()
@@ -394,7 +414,7 @@ CommImpl::~CommImpl()
 }
 
 /**  @brief Starts the simulation of a communication synchro. */
-void CommImpl::start()
+CommImpl* CommImpl::start()
 {
   /* If both the sender and the receiver are already there, start the communication */
   if (state_ == SIMIX_READY) {
@@ -402,7 +422,7 @@ void CommImpl::start()
     s4u::Host* sender   = src_actor_->get_host();
     s4u::Host* receiver = dst_actor_->get_host();
 
-    surf_action_ = surf_network_model->communicate(sender, receiver, task_size_, rate_);
+    surf_action_ = surf_network_model->communicate(sender, receiver, size_, rate_);
     surf_action_->set_data(this);
     state_ = SIMIX_RUNNING;
 
@@ -431,6 +451,8 @@ void CommImpl::start()
       surf_action_->suspend();
     }
   }
+
+  return this;
 }
 
 /** @brief Copy the communication data from the sender's buffer to the receiver's one  */
@@ -585,8 +607,6 @@ void CommImpl::finish()
 
     if (not simcall->issuer->get_host()->is_on()) {
       simcall->issuer->context_->iwannadie = true;
-      simcall->issuer->exception_ =
-          std::make_exception_ptr(simgrid::HostFailureException(XBT_THROW_POINT, "Host failed"));
     } else {
       switch (state_) {
 
index f881e04..481b16b 100644 (file)
@@ -19,11 +19,20 @@ class XBT_PUBLIC CommImpl : public ActivityImpl {
   ~CommImpl() override;
   void cleanupSurf();
 
+  double rate_ = 0.0;
+  double size_ = 0.0;
+
 public:
   enum class Type { SEND = 0, RECEIVE, READY, DONE };
 
-  explicit CommImpl(Type type);
-  void start();
+  CommImpl& set_type(CommImpl::Type type);
+  CommImpl& set_size(double size);
+  double get_rate() { return rate_; }
+  CommImpl& set_rate(double rate);
+  CommImpl& set_src_buff(void* buff, size_t size);
+  CommImpl& set_dst_buff(void* buff, size_t* size);
+
+  CommImpl* start();
   void copy_data();
   void suspend() override;
   void resume() override;
@@ -32,7 +41,7 @@ public:
   void cancel();
   double remains();
 
-  CommImpl::Type type        /* Type of the communication (SIMIX_COMM_SEND or SIMIX_COMM_RECEIVE) */
+  CommImpl::Type type_;        /* Type of the communication (SIMIX_COMM_SEND or SIMIX_COMM_RECEIVE) */
   MailboxImpl* mbox = nullptr; /* Rendez-vous where the comm is queued */
 
 #if SIMGRID_HAVE_MC
@@ -49,13 +58,10 @@ expectations of the other side, too. See  */
   void (*copy_data_fun)(CommImpl*, void*, size_t) = nullptr;
 
   /* Surf action data */
-  resource::Action* surf_action_ = nullptr; /* The Surf communication action encapsulated */
   resource::Action* src_timeout_ = nullptr; /* Surf's actions to instrument the timeouts */
   resource::Action* dst_timeout_ = nullptr; /* Surf's actions to instrument the timeouts */
   actor::ActorImplPtr src_actor_ = nullptr;
   actor::ActorImplPtr dst_actor_ = nullptr;
-  double rate_                   = 0.0;
-  double task_size_              = 0.0;
 
   /* Data to be transfered */
   void* src_buff_        = nullptr;
index a46a904..18d1197 100644 (file)
@@ -101,7 +101,8 @@ void ConditionVariableImpl::wait(smx_mutex_t mutex, double timeout, actor::Actor
     mutex->unlock(issuer);
   }
 
-  synchro = RawImplPtr(new RawImpl())->start(issuer->get_host(), timeout);
+  synchro = RawImplPtr(new RawImpl());
+  (*synchro).set_host(issuer->get_host()).set_timeout(timeout).start();
   synchro->simcalls_.push_front(simcall);
   issuer->waiting_synchro = synchro;
   sleeping_.push_back(*simcall->issuer);
index 4b66dd2..07b3c4e 100644 (file)
@@ -51,67 +51,89 @@ namespace simgrid {
 namespace kernel {
 namespace activity {
 
-ExecImpl::ExecImpl(const std::string& name, const std::string& tracing_category) : ActivityImpl(name)
-{
-  this->state_ = SIMIX_RUNNING;
-  this->set_category(tracing_category);
-
-  XBT_DEBUG("Create exec %p", this);
-}
-
 ExecImpl::~ExecImpl()
 {
-  if (surf_action_)
-    surf_action_->unref();
   if (timeout_detector_)
     timeout_detector_->unref();
   XBT_DEBUG("Destroy exec %p", this);
 }
 
-ExecImpl* ExecImpl::set_host(s4u::Host* host)
+ExecImpl& ExecImpl::set_host(s4u::Host* host)
 {
-  host_ = host;
-  return this;
+  if (not hosts_.empty())
+    hosts_.clear();
+  hosts_.push_back(host);
+  return *this;
+}
+
+ExecImpl& ExecImpl::set_hosts(const std::vector<s4u::Host*>& hosts)
+{
+  hosts_ = hosts;
+  return *this;
 }
 
-ExecImpl* ExecImpl::set_timeout(double timeout)
+ExecImpl& ExecImpl::set_name(const std::string& name)
+{
+  ActivityImpl::set_name(name);
+  return *this;
+}
+
+ExecImpl& ExecImpl::set_tracing_category(const std::string& category)
+{
+  ActivityImpl::set_category(category);
+  return *this;
+}
+
+ExecImpl& ExecImpl::set_timeout(double timeout)
 {
   if (timeout > 0 && not MC_is_active() && not MC_record_replay_is_active()) {
-    timeout_detector_ = host_->pimpl_cpu->sleep(timeout);
+    timeout_detector_ = hosts_.front()->pimpl_cpu->sleep(timeout);
     timeout_detector_->set_data(this);
   }
-  return this;
+  return *this;
 }
 
-ExecImpl* ExecImpl::start(double flops_amount, double priority, double bound)
+ExecImpl& ExecImpl::set_flops_amount(double flops_amount)
 {
-  if (not MC_is_active() && not MC_record_replay_is_active()) {
-    surf_action_ = host_->pimpl_cpu->execution_start(flops_amount);
-    surf_action_->set_data(this);
-    surf_action_->set_priority(priority);
-    if (bound > 0)
-      surf_action_->set_bound(bound);
-  }
+  if (not flops_amounts_.empty())
+    flops_amounts_.clear();
+  flops_amounts_.push_back(flops_amount);
+  return *this;
+}
 
-  XBT_DEBUG("Create execute synchro %p: %s", this, get_cname());
-  ExecImpl::on_creation(this);
-  return this;
+ExecImpl& ExecImpl::set_flops_amounts(const std::vector<double>& flops_amounts)
+{
+  flops_amounts_ = flops_amounts;
+  return *this;
 }
 
-ExecImpl* ExecImpl::start(const std::vector<s4u::Host*>& hosts, const std::vector<double>& flops_amounts,
-                          const std::vector<double>& bytes_amounts)
+ExecImpl& ExecImpl::set_bytes_amounts(const std::vector<double>& bytes_amounts)
 {
-  /* set surf's synchro */
+  bytes_amounts_ = bytes_amounts;
+
+  return *this;
+}
+
+ExecImpl* ExecImpl::start()
+{
+  state_ = SIMIX_RUNNING;
   if (not MC_is_active() && not MC_record_replay_is_active()) {
-    surf_action_ = surf_host_model->execute_parallel(hosts, flops_amounts.data(), bytes_amounts.data(), -1);
-    if (surf_action_ != nullptr) {
-      surf_action_->set_data(this);
+    if (hosts_.size() == 1) {
+      surf_action_ = hosts_.front()->pimpl_cpu->execution_start(flops_amounts_.front());
+      surf_action_->set_priority(priority_);
+      if (bound_ > 0)
+        surf_action_->set_bound(bound_);
+    } else {
+      surf_action_ = surf_host_model->execute_parallel(hosts_, flops_amounts_.data(), bytes_amounts_.data(), -1);
     }
+    surf_action_->set_data(this);
   }
-  XBT_DEBUG("Create parallel execute synchro %p", this);
-  ExecImpl::on_creation(this);
+
+  XBT_DEBUG("Create execute synchro %p: %s", this, get_cname());
+  ExecImpl::on_creation(*this);
   return this;
 }
+
 void ExecImpl::cancel()
 {
   XBT_VERB("This exec %p is canceled", this);
@@ -119,7 +141,7 @@ void ExecImpl::cancel()
     surf_action_->cancel();
 }
 
-double ExecImpl::get_remaining()
+double ExecImpl::get_remaining() const
 {
   return surf_action_ ? surf_action_->get_remains() : 0;
 }
@@ -135,20 +157,21 @@ double ExecImpl::get_par_remaining_ratio()
   return (surf_action_ == nullptr) ? 0 : surf_action_->get_remains();
 }
 
-void ExecImpl::set_bound(double bound)
+ExecImpl& ExecImpl::set_bound(double bound)
 {
-  if (surf_action_)
-    surf_action_->set_bound(bound);
+  bound_ = bound;
+  return *this;
 }
-void ExecImpl::set_priority(double priority)
+
+ExecImpl& ExecImpl::set_priority(double priority)
 {
-  if (surf_action_)
-    surf_action_->set_priority(priority);
+  priority_ = priority;
+  return *this;
 }
 
 void ExecImpl::post()
 {
-  if (host_ && not host_->is_on()) { /* FIXME: handle resource failure for parallel tasks too */
+  if (hosts_.size() == 1 && not hosts_.front()->is_on()) { /* FIXME: handle resource failure for parallel tasks too */
     /* If the host running the synchro failed, notice it. This way, the asking
      * process can be killed if it runs on that host itself */
     state_ = SIMIX_FAILED;
@@ -161,7 +184,7 @@ void ExecImpl::post()
     state_ = SIMIX_DONE;
   }
 
-  on_completion(this);
+  on_completion(*this);
 
   if (surf_action_) {
     surf_action_->unref();
@@ -242,16 +265,16 @@ ActivityImpl* ExecImpl::migrate(s4u::Host* to)
     this->surf_action_ = new_action;
   }
 
-  on_migration(this, to);
+  on_migration(*this, to);
   return this;
 }
 
 /*************
  * Callbacks *
  *************/
-xbt::signal<void(ExecImplPtr)> ExecImpl::on_creation;
-xbt::signal<void(ExecImplPtr)> ExecImpl::on_completion;
-xbt::signal<void(ExecImplPtr, s4u::Host*)> ExecImpl::on_migration;
+xbt::signal<void(ExecImpl&)> ExecImpl::on_creation;
+xbt::signal<void(ExecImpl const&)> ExecImpl::on_completion;
+xbt::signal<void(ExecImpl const&, s4u::Host*)> ExecImpl::on_migration;
 
 } // namespace activity
 } // namespace kernel
index 74daa44..80d25bd 100644 (file)
@@ -16,32 +16,42 @@ namespace activity {
 
 class XBT_PUBLIC ExecImpl : public ActivityImpl {
   resource::Action* timeout_detector_ = nullptr;
-  ~ExecImpl() override;
+  double priority_                    = 1.0;
+  double bound_                       = 0.0;
+  std::vector<s4u::Host*> hosts_;
+  std::vector<double> flops_amounts_;
+  std::vector<double> bytes_amounts_;
+  ~ExecImpl();
 
 public:
-  explicit ExecImpl(const std::string& name, const std::string& tracing_category);
-  ExecImpl* start(double flops_amount, double priority, double bound);
-  ExecImpl* start(const std::vector<s4u::Host*>& hosts, const std::vector<double>& flops_amounts,
-                  const std::vector<double>& bytes_amounts);
-
-  ExecImpl* set_host(s4u::Host* host);
-  ExecImpl* set_timeout(double timeout);
-  void cancel();
-  void post() override;
-  void finish() override;
-  double get_remaining();
+  ExecImpl& set_name(const std::string& name);
+  ExecImpl& set_tracing_category(const std::string& category);
+  ExecImpl& set_timeout(double timeout);
+  ExecImpl& set_bound(double bound);
+  ExecImpl& set_priority(double priority);
+
+  ExecImpl& set_flops_amount(double flop_amount);
+  ExecImpl& set_host(s4u::Host* host);
+  s4u::Host* get_host() const { return hosts_.front(); }
+
+  ExecImpl& set_flops_amounts(const std::vector<double>& flops_amounts);
+  ExecImpl& set_bytes_amounts(const std::vector<double>& bytes_amounts);
+  ExecImpl& set_hosts(const std::vector<s4u::Host*>& hosts);
+
+  unsigned int get_host_number() const { return hosts_.size(); }
+  double get_remaining() const;
   double get_seq_remaining_ratio();
   double get_par_remaining_ratio();
-  void set_bound(double bound);       // deprecated. To be removed in v3.25
-  void set_priority(double priority); // deprecated. To be removed in v3.25
   virtual ActivityImpl* migrate(s4u::Host* to);
 
-  /* The host where the execution takes place. nullptr means this is a parallel exec (and only surf knows the hosts) */
-  s4u::Host* host_ = nullptr;
+  ExecImpl* start();
+  void cancel();
+  void post() override;
+  void finish() override;
 
-  static xbt::signal<void(ExecImplPtr)> on_creation;
-  static xbt::signal<void(ExecImplPtr)> on_completion;
-  static xbt::signal<void(ExecImplPtr, s4u::Host*)> on_migration;
+  static xbt::signal<void(ExecImpl&)> on_creation;
+  static xbt::signal<void(ExecImpl const&)> on_completion;
+  static xbt::signal<void(ExecImpl const&, s4u::Host*)> on_migration;
 };
 } // namespace activity
 } // namespace kernel
index 7647a18..e24fe23 100644 (file)
@@ -37,27 +37,38 @@ namespace simgrid {
 namespace kernel {
 namespace activity {
 
-IoImpl::IoImpl(const std::string& name, resource::StorageImpl* storage) : ActivityImpl(name), storage_(storage)
+IoImpl& IoImpl::set_name(const std::string& name)
 {
-  this->state_ = SIMIX_RUNNING;
+  ActivityImpl::set_name(name);
+  return *this;
+}
 
-  XBT_DEBUG("Create io impl %p", this);
+IoImpl& IoImpl::set_type(s4u::Io::OpType type)
+{
+  type_ = type;
+  return *this;
 }
 
-IoImpl::~IoImpl()
+IoImpl& IoImpl::set_size(sg_size_t size)
 {
-  if (surf_action_ != nullptr)
-    surf_action_->unref();
-  XBT_DEBUG("Destroy io %p", this);
+  size_ = size;
+  return *this;
+}
+
+IoImpl& IoImpl::set_storage(resource::StorageImpl* storage)
+{
+  storage_ = storage;
+  return *this;
 }
 
-IoImpl* IoImpl::start(sg_size_t size, s4u::Io::OpType type)
+IoImpl* IoImpl::start()
 {
-  surf_action_ = storage_->io_start(size, type);
+  state_       = SIMIX_RUNNING;
+  surf_action_ = storage_->io_start(size_, type_);
   surf_action_->set_data(this);
 
   XBT_DEBUG("Create IO synchro %p %s", this, get_cname());
-  IoImpl::on_start(this);
+  IoImpl::on_start(*this);
 
   return this;
 }
@@ -88,7 +99,7 @@ void IoImpl::post()
     default:
       THROW_IMPOSSIBLE;
   }
-  on_completion(this);
+  on_completion(*this);
 
   finish();
 }
@@ -123,8 +134,8 @@ void IoImpl::finish()
 /*************
  * Callbacks *
  *************/
-xbt::signal<void(IoImplPtr)> IoImpl::on_start;
-xbt::signal<void(IoImplPtr)> IoImpl::on_completion;
+xbt::signal<void(IoImpl const&)> IoImpl::on_start;
+xbt::signal<void(IoImpl const&)> IoImpl::on_completion;
 
 } // namespace activity
 } // namespace kernel
index 52d0aa7..102b691 100644 (file)
@@ -15,21 +15,27 @@ namespace kernel {
 namespace activity {
 
 class XBT_PUBLIC IoImpl : public ActivityImpl {
+  resource::StorageImpl* storage_ = nullptr;
+  sg_size_t size_                 = 0;
+  s4u::Io::OpType type_           = s4u::Io::OpType::READ;
+  sg_size_t performed_ioops_      = 0;
+
 public:
-  ~IoImpl() override;
-  explicit IoImpl(const std::string& name, resource::StorageImpl* storage);
+  IoImpl& set_name(const std::string& name);
+  IoImpl& set_size(sg_size_t size);
+  IoImpl& set_type(s4u::Io::OpType type);
+  IoImpl& set_storage(resource::StorageImpl* storage);
+
+  sg_size_t get_performed_ioops() { return performed_ioops_; }
 
-  IoImpl* start(sg_size_t size, s4u::Io::OpType type);
+  IoImpl* start();
   void post() override;
   void finish() override;
   void cancel();
   double get_remaining();
-  sg_size_t get_performed_ioops() { return performed_ioops_; }
 
-  resource::StorageImpl* storage_                 = nullptr;
-  sg_size_t performed_ioops_                      = 0;
-  static xbt::signal<void(IoImplPtr)> on_start;
-  static xbt::signal<void(IoImplPtr)> on_completion;
+  static xbt::signal<void(IoImpl const&)> on_start;
+  static xbt::signal<void(IoImpl const&)> on_completion;
 };
 } // namespace activity
 } // namespace kernel
index 218fce7..c7a8362 100644 (file)
@@ -91,10 +91,12 @@ CommImplPtr MailboxImpl::iprobe(int type, int (*match_fun)(void*, void*, CommImp
   CommImplPtr this_comm;
   CommImpl::Type smx_type;
   if (type == 1) {
-    this_comm = CommImplPtr(new CommImpl(CommImpl::Type::SEND));
+    this_comm = CommImplPtr(new CommImpl());
+    this_comm->set_type(CommImpl::Type::SEND);
     smx_type  = CommImpl::Type::RECEIVE;
   } else {
-    this_comm = CommImplPtr(new CommImpl(CommImpl::Type::RECEIVE));
+    this_comm = CommImplPtr(new CommImpl());
+    this_comm->set_type(CommImpl::Type::RECEIVE);
     smx_type  = CommImpl::Type::SEND;
   }
   CommImplPtr other_comm = nullptr;
@@ -129,12 +131,12 @@ CommImplPtr MailboxImpl::find_matching_comm(CommImpl::Type type, int (*match_fun
   for (auto it = comm_queue.begin(); it != comm_queue.end(); it++) {
     CommImplPtr& comm = *it;
 
-    if (comm->type == CommImpl::Type::SEND) {
+    if (comm->type_ == CommImpl::Type::SEND) {
       other_user_data = comm->src_data_;
-    } else if (comm->type == CommImpl::Type::RECEIVE) {
+    } else if (comm->type_ == CommImpl::Type::RECEIVE) {
       other_user_data = comm->dst_data_;
     }
-    if (comm->type == type && (match_fun == nullptr || match_fun(this_user_data, other_user_data, comm.get())) &&
+    if (comm->type_ == type && (match_fun == nullptr || match_fun(this_user_data, other_user_data, comm.get())) &&
         (not comm->match_fun || comm->match_fun(other_user_data, this_user_data, my_synchro.get()))) {
       XBT_DEBUG("Found a matching communication synchro %p", comm.get());
 #if SIMGRID_HAVE_MC
@@ -148,7 +150,7 @@ CommImplPtr MailboxImpl::find_matching_comm(CommImpl::Type type, int (*match_fun
     }
     XBT_DEBUG("Sorry, communication synchro %p does not match our needs:"
               " its type is %d but we are looking for a comm of type %d (or maybe the filtering didn't match)",
-              comm.get(), (int)comm->type, (int)type);
+              comm.get(), (int)comm->type_, (int)type);
   }
   XBT_DEBUG("No matching communication synchro found");
   return nullptr;
index 883f135..e8a2b1d 100644 (file)
@@ -33,7 +33,8 @@ void MutexImpl::lock(actor::ActorImpl* issuer)
   if (locked_) {
     /* FIXME: check if the host is active ? */
     /* Somebody using the mutex, use a synchronization to get host failures */
-    synchro = RawImplPtr(new RawImpl())->start(issuer->get_host(), -1);
+    synchro = RawImplPtr(new RawImpl());
+    (*synchro).set_host(issuer->get_host()).start();
     synchro->simcalls_.push_back(&issuer->simcall);
     issuer->waiting_synchro = synchro;
     sleeping_.push_back(*issuer);
index bf20f2b..66e9900 100644 (file)
@@ -18,7 +18,8 @@ void SemaphoreImpl::acquire(actor::ActorImpl* issuer, double timeout)
 
   XBT_DEBUG("Wait semaphore %p (timeout:%f)", this, timeout);
   if (value_ <= 0) {
-    synchro = RawImplPtr(new RawImpl())->start(issuer->get_host(), timeout);
+    synchro = RawImplPtr(new RawImpl());
+    (*synchro).set_host(issuer->get_host()).set_timeout(timeout).start();
     synchro->simcalls_.push_front(&issuer->simcall);
     issuer->waiting_synchro = synchro;
     sleeping_.push_back(*issuer);
index 8735baf..3072fb9 100644 (file)
@@ -18,16 +18,27 @@ namespace simgrid {
 namespace kernel {
 namespace activity {
 
-SleepImpl::~SleepImpl()
+SleepImpl& SleepImpl::set_name(const std::string& name)
 {
-  if (surf_action_)
-    surf_action_->unref();
-  XBT_DEBUG("Destroy activity %p", this);
+  ActivityImpl::set_name(name);
+  return *this;
 }
 
-SleepImpl* SleepImpl::start(double duration)
+SleepImpl& SleepImpl::set_host(s4u::Host* host)
 {
-  surf_action_ = host_->pimpl_cpu->sleep(duration);
+  host_ = host;
+  return *this;
+}
+
+SleepImpl& SleepImpl::set_duration(double duration)
+{
+  duration_ = duration;
+  return *this;
+}
+
+SleepImpl* SleepImpl::start()
+{
+  surf_action_ = host_->pimpl_cpu->sleep(duration_);
   surf_action_->set_data(this);
   XBT_DEBUG("Create sleep synchronization %p", this);
   return this;
@@ -73,7 +84,6 @@ void SleepImpl::post()
       SIMIX_simcall_answer(simcall);
     }
   }
-
   SIMIX_process_sleep_destroy(this);
 }
 void SleepImpl::finish()
index 2bf4657..a4d75b0 100644 (file)
@@ -14,15 +14,16 @@ namespace kernel {
 namespace activity {
 
 class XBT_PUBLIC SleepImpl : public ActivityImpl {
-  ~SleepImpl() override;
+  sg_host_t host_  = nullptr;
+  double duration_ = 0;
 
 public:
-  explicit SleepImpl(const std::string& name, s4u::Host* host) : ActivityImpl(name), host_(host) {}
+  SleepImpl& set_name(const std::string& name);
+  SleepImpl& set_host(s4u::Host* host);
+  SleepImpl& set_duration(double duration);
   void post() override;
   void finish() override;
-  SleepImpl* start(double duration);
-
-  sg_host_t host_ = nullptr;
+  SleepImpl* start();
 };
 } // namespace activity
 } // namespace kernel
index d58e1e4..9f55eba 100644 (file)
@@ -20,16 +20,22 @@ namespace simgrid {
 namespace kernel {
 namespace activity {
 
-RawImpl* RawImpl::start(s4u::Host* host, double timeout)
+RawImpl& RawImpl::set_host(s4u::Host* host)
 {
-  surf_action_ = host->pimpl_cpu->sleep(timeout);
-  surf_action_->set_data(this);
-  return this;
+  host_ = host;
+  return *this;
+}
+RawImpl& RawImpl::set_timeout(double timeout)
+{
+  timeout_ = timeout;
+  return *this;
 }
 
-RawImpl::~RawImpl()
+RawImpl* RawImpl::start()
 {
-  surf_action_->unref();
+  surf_action_ = host_->pimpl_cpu->sleep(timeout_);
+  surf_action_->set_data(this);
+  return this;
 }
 
 void RawImpl::suspend()
index da5766b..a1d4ca3 100644 (file)
@@ -15,9 +15,14 @@ namespace activity {
 
   /** Used to implement mutexes, semaphores and conditions */
 class XBT_PUBLIC RawImpl : public ActivityImpl {
+  sg_host_t host_ = nullptr;
+  double timeout_ = -1;
+
 public:
-  ~RawImpl() override;
-  RawImpl* start(s4u::Host* host, double timeout);
+  RawImpl& set_host(s4u::Host* host);
+  RawImpl& set_timeout(double timeout);
+
+  RawImpl* start();
   void suspend() override;
   void resume() override;
   void post() override;
index 1c2fcfb..b0d47c3 100644 (file)
@@ -33,7 +33,7 @@ static unsigned long simix_process_maxpid = 0;
  */
 smx_actor_t SIMIX_process_self()
 {
-  smx_context_t self_context = simgrid::kernel::context::Context::self();
+  simgrid::kernel::context::Context* self_context = simgrid::kernel::context::Context::self();
 
   return (self_context != nullptr) ? self_context->get_actor() : nullptr;
 }
@@ -110,8 +110,7 @@ ActorImplPtr ActorImpl::attach(const std::string& name, void* data, s4u::Host* h
   context->attach_start();
 
   /* The on_creation() signal must be delayed until there, where the pid and everything is set */
-  simgrid::s4u::ActorPtr tmp = actor->iface(); // Passing this directly to on_creation will lead to crashes
-  simgrid::s4u::Actor::on_creation(tmp);
+  simgrid::s4u::Actor::on_creation(*actor->ciface());
 
   return ActorImplPtr(actor);
 }
@@ -133,11 +132,40 @@ void ActorImpl::detach()
 
 void ActorImpl::cleanup()
 {
+  finished_ = true;
+
+  if (has_to_auto_restart() && not get_host()->is_on()) {
+    XBT_DEBUG("Insert host %s to watched_hosts because it's off and %s needs to restart", get_host()->get_cname(),
+              get_cname());
+    watched_hosts.insert(get_host()->get_name());
+  }
+
+  // Execute the termination callbacks
+  bool failed = context_->iwannadie;
+  while (not on_exit.empty()) {
+    auto exit_fun = on_exit.back();
+    on_exit.pop_back();
+    exit_fun(failed);
+  }
+
+  /* cancel non-blocking activities */
+  for (auto activity : comms)
+    boost::static_pointer_cast<activity::CommImpl>(activity)->cancel();
+  comms.clear();
+
+  XBT_DEBUG("%s@%s(%ld) should not run anymore", get_cname(), get_host()->get_cname(), get_pid());
+
   if (this == simix_global->maestro_process) /* Do not cleanup maestro */
     return;
 
   XBT_DEBUG("Cleanup actor %s (%p), waiting synchro %p", get_cname(), this, waiting_synchro.get());
 
+  /* Unregister from the kill timer if any */
+  if (kill_timer != nullptr) {
+    kill_timer->remove();
+    kill_timer = nullptr;
+  }
+
   simix_global->mutex.lock();
 
   simix_global->process_list.erase(pid_);
@@ -149,9 +177,12 @@ void ActorImpl::cleanup()
 #endif
     simix_global->actors_to_destroy.push_back(*this);
   }
-  context_->iwannadie = false;
 
   simix_global->mutex.unlock();
+
+  context_->iwannadie = false; // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops
+  simgrid::simix::simcall([this] { simgrid::s4u::Actor::on_destruction(*ciface()); });
+  context_->iwannadie = true;
 }
 
 void ActorImpl::exit()
@@ -247,18 +278,6 @@ double ActorImpl::get_kill_time()
   return kill_timer ? kill_timer->get_date() : 0;
 }
 
-static void dying_daemon(int /*exit_status*/, void* data)
-{
-  std::vector<ActorImpl*>* vect = &simix_global->daemons;
-
-  auto it = std::find(vect->begin(), vect->end(), static_cast<ActorImpl*>(data));
-  xbt_assert(it != vect->end(), "The dying daemon is not a daemon after all. Please report that bug.");
-
-  /* Don't move the whole content since we don't really care about the order */
-  std::swap(*it, vect->back());
-  vect->pop_back();
-}
-
 void ActorImpl::yield()
 {
   XBT_DEBUG("Yield actor '%s'", get_cname());
@@ -270,7 +289,6 @@ void ActorImpl::yield()
   XBT_DEBUG("Control returned to me: '%s'", get_cname());
 
   if (context_->iwannadie) {
-
     XBT_DEBUG("Actor %s@%s is dead", get_cname(), host_->get_cname());
     // throw simgrid::kernel::context::ForcefulKillException(); Does not seem to properly kill the actor
     context_->stop();
@@ -303,19 +321,29 @@ void ActorImpl::daemonize()
   if (not daemon_) {
     daemon_ = true;
     simix_global->daemons.push_back(this);
-    SIMIX_process_on_exit(this, dying_daemon, this);
+    SIMIX_process_on_exit(this, [this](bool) {
+      auto& vect = simix_global->daemons;
+      auto it    = std::find(vect.begin(), vect.end(), this);
+      xbt_assert(it != vect.end(), "The dying daemon is not a daemon after all. Please report that bug.");
+
+      /* Don't move the whole content since we don't really care about the order */
+      std::swap(*it, vect.back());
+      vect.pop_back();
+    });
   }
 }
 
 s4u::Actor* ActorImpl::restart()
 {
+  xbt_assert(this != simix_global->maestro_process, "Restarting maestro is not supported");
+
   XBT_DEBUG("Restarting actor %s on %s", get_cname(), host_->get_cname());
 
   // retrieve the arguments of the old actor
   ProcessArg arg = ProcessArg(host_, this);
 
   // kill the old actor
-  (this == simix_global->maestro_process) ? this->exit() : SIMIX_process_self()->kill(this);
+  context::Context::self()->get_actor()->kill(this);
 
   // start the new actor
   ActorImplPtr actor =
@@ -343,7 +371,9 @@ activity::ActivityImplPtr ActorImpl::suspend(ActorImpl* issuer)
 
     return nullptr;
   } else {
-    return activity::ExecImplPtr(new activity::ExecImpl("suspend", ""))->set_host(host_)->start(0.0, 1.0, 0.0);
+    activity::ExecImpl* exec = new activity::ExecImpl();
+    (*exec).set_name("suspend").set_host(host_).set_flops_amount(0.0).start();
+    return activity::ExecImplPtr(exec);
   }
 }
 
@@ -369,17 +399,12 @@ void ActorImpl::resume()
 
 activity::ActivityImplPtr ActorImpl::join(ActorImpl* actor, double timeout)
 {
-  activity::ActivityImplPtr res = this->sleep(timeout);
-  intrusive_ptr_add_ref(res.get());
-  SIMIX_process_on_exit(actor,
-                        [](int, void* arg) {
-                          auto sleep = static_cast<activity::SleepImpl*>(arg);
-                          if (sleep->surf_action_)
-                            sleep->surf_action_->finish(resource::Action::State::FINISHED);
-                          intrusive_ptr_release(sleep);
-                        },
-                        res.get());
-  return res;
+  activity::ActivityImplPtr sleep = this->sleep(timeout);
+  SIMIX_process_on_exit(actor, [sleep](bool) {
+    if (sleep->surf_action_)
+      sleep->surf_action_->finish(resource::Action::State::FINISHED);
+  });
+  return sleep;
 }
 
 activity::ActivityImplPtr ActorImpl::sleep(double duration)
@@ -388,7 +413,9 @@ activity::ActivityImplPtr ActorImpl::sleep(double duration)
     throw_exception(std::make_exception_ptr(simgrid::HostFailureException(
         XBT_THROW_POINT, std::string("Host ") + host_->get_cname() + " failed, you cannot sleep there.")));
 
-  return activity::SleepImplPtr(new activity::SleepImpl("sleep", host_))->start(duration);
+  activity::SleepImpl* sleep = new activity::SleepImpl();
+  (*sleep).set_name("sleep").set_host(host_).set_duration(duration).start();
+  return activity::SleepImplPtr(sleep);
 }
 
 void ActorImpl::throw_exception(std::exception_ptr e)
@@ -413,7 +440,7 @@ void ActorImpl::throw_exception(std::exception_ptr e)
 
     activity::SleepImplPtr sleep = boost::dynamic_pointer_cast<activity::SleepImpl>(waiting_synchro);
     if (sleep != nullptr) {
-      SIMIX_process_sleep_destroy(waiting_synchro);
+      SIMIX_process_sleep_destroy(sleep);
       if (std::find(begin(simix_global->actors_to_run), end(simix_global->actors_to_run), this) ==
               end(simix_global->actors_to_run) &&
           this != SIMIX_process_self()) {
@@ -449,7 +476,7 @@ ActorImplPtr ActorImpl::init(const std::string& name, s4u::Host* host)
 
   intrusive_ptr_add_ref(actor);
   /* The on_creation() signal must be delayed until there, where the pid and everything is set */
-  s4u::Actor::on_creation(actor->iface());
+  s4u::Actor::on_creation(*actor->ciface());
 
   return ActorImplPtr(actor);
 }
@@ -564,7 +591,7 @@ void SIMIX_process_throw(smx_actor_t actor, xbt_errcat_t cat, int value, const c
     simgrid::kernel::activity::SleepImplPtr sleep =
         boost::dynamic_pointer_cast<simgrid::kernel::activity::SleepImpl>(actor->waiting_synchro);
     if (sleep != nullptr) {
-      SIMIX_process_sleep_destroy(actor->waiting_synchro);
+      SIMIX_process_sleep_destroy(sleep);
       if (std::find(begin(simix_global->actors_to_run), end(simix_global->actors_to_run), actor) ==
               end(simix_global->actors_to_run) &&
           actor != SIMIX_process_self()) {
@@ -665,11 +692,9 @@ void simcall_HANDLER_process_sleep(smx_simcall_t simcall, double duration)
   simcall->issuer->waiting_synchro = sync;
 }
 
-void SIMIX_process_sleep_destroy(smx_activity_t synchro)
+void SIMIX_process_sleep_destroy(simgrid::kernel::activity::SleepImplPtr sleep)
 {
-  XBT_DEBUG("Destroy sleep synchro %p", synchro.get());
-  simgrid::kernel::activity::SleepImplPtr sleep =
-      boost::static_pointer_cast<simgrid::kernel::activity::SleepImpl>(synchro);
+  XBT_DEBUG("Destroy sleep synchro %p", sleep.get());
 
   if (sleep->surf_action_) {
     sleep->surf_action_->unref();
@@ -702,14 +727,21 @@ smx_actor_t SIMIX_process_from_PID(aid_t PID)
 
 void SIMIX_process_on_exit(smx_actor_t actor, int_f_pvoid_pvoid_t fun, void* data)
 {
-  SIMIX_process_on_exit(actor, [fun](int a, void* b) { fun((void*)(intptr_t)a, b); }, data);
+  SIMIX_process_on_exit(actor, [fun, data](bool failed) {
+    intptr_t status = failed ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS;
+    fun(reinterpret_cast<void*>(status), data);
+  });
 }
 
-void SIMIX_process_on_exit(smx_actor_t actor, const std::function<void(bool, void*)>& fun, void* data)
+void SIMIX_process_on_exit(smx_actor_t actor, const std::function<void(int, void*)>& fun, void* data)
 {
-  xbt_assert(actor, "current process not found: are you in maestro context ?");
+  SIMIX_process_on_exit(actor, [fun, data](bool failed) { fun(failed ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS, data); });
+}
 
-  actor->on_exit.emplace_back(s_smx_process_exit_fun_t{fun, data});
+void SIMIX_process_on_exit(smx_actor_t actor, const std::function<void(bool /*failed*/)>& fun)
+{
+  xbt_assert(actor, "current process not found: are you in maestro context ?");
+  actor->on_exit.emplace_back(fun);
 }
 
 /** @brief Restart a process, starting it again from the beginning. */
index 3dc9224..f4ee3a8 100644 (file)
 #include <map>
 #include <memory>
 
-struct s_smx_process_exit_fun_t {
-  std::function<void(bool, void*)> fun;
-  void* arg;
-};
-
 namespace simgrid {
 namespace kernel {
 namespace actor {
@@ -70,7 +65,7 @@ public:
   activity::ActivityImplPtr waiting_synchro = nullptr; /* the current blocking synchro if any */
   std::list<activity::ActivityImplPtr> comms;          /* the current non-blocking communication synchros */
   s_smx_simcall simcall;
-  std::vector<s_smx_process_exit_fun_t> on_exit; /* list of functions executed when the process dies */
+  std::vector<std::function<void(bool)>> on_exit; /* list of functions executed when the process dies */
 
   std::function<void()> code;
   simix::Timer* kill_timer = nullptr;
@@ -181,6 +176,6 @@ XBT_PUBLIC void create_maestro(const std::function<void()>& code);
 
 extern void (*SMPI_switch_data_segment)(simgrid::s4u::ActorPtr actor);
 
-XBT_PRIVATE void SIMIX_process_sleep_destroy(smx_activity_t synchro);
+XBT_PRIVATE void SIMIX_process_sleep_destroy(simgrid::kernel::activity::SleepImplPtr synchro);
 
 #endif
index dc182b9..145e1e1 100644 (file)
@@ -22,7 +22,7 @@ ContextFactoryInitializer factory_initializer = nullptr;
 
 ContextFactory::~ContextFactory() = default;
 
-static thread_local smx_context_t smx_current_context = nullptr;
+static thread_local Context* smx_current_context = nullptr;
 Context* Context::self()
 {
   return smx_current_context;
@@ -69,45 +69,7 @@ Context::~Context()
 
 void Context::stop()
 {
-  actor_->finished_ = true;
-
-  if (actor_->has_to_auto_restart() && not actor_->get_host()->is_on()) {
-    XBT_DEBUG("Insert host %s to watched_hosts because it's off and %s needs to restart",
-              actor_->get_host()->get_cname(), actor_->get_cname());
-    watched_hosts.insert(actor_->get_host()->get_name());
-  }
-
-  // Execute the termination callbacks
-  smx_process_exit_status_t exit_status = (actor_->context_->iwannadie) ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS;
-  while (not actor_->on_exit.empty()) {
-    s_smx_process_exit_fun_t exit_fun = actor_->on_exit.back();
-    actor_->on_exit.pop_back();
-    (exit_fun.fun)(exit_status, exit_fun.arg);
-  }
-
-  /* cancel non-blocking activities */
-  for (auto activity : actor_->comms)
-    boost::static_pointer_cast<activity::CommImpl>(activity)->cancel();
-  actor_->comms.clear();
-
-  XBT_DEBUG("%s@%s(%ld) should not run anymore", actor_->get_cname(), actor_->iface()->get_host()->get_cname(),
-            actor_->get_pid());
-
   this->actor_->cleanup();
-
-  this->iwannadie = false; // don't let the simcall's yield() do a Context::stop(), because that's me
-  simgrid::simix::simcall([this] {
-    simgrid::s4u::Actor::on_destruction(actor_->iface());
-
-    /* Unregister from the kill timer if any */
-    if (actor_->kill_timer != nullptr) {
-      actor_->kill_timer->remove();
-      actor_->kill_timer = nullptr;
-    }
-
-    actor_->cleanup();
-  });
-  this->iwannadie = true;
 }
 
 AttachContext::~AttachContext() = default;
index 1ba7c36..d4dc55d 100644 (file)
@@ -15,7 +15,7 @@ namespace kernel {
 namespace context {
 
 // BoostContextFactory
-smx_context_t BoostContextFactory::create_context(std::function<void()>&& code, actor::ActorImpl* actor)
+BoostContext* BoostContextFactory::create_context(std::function<void()>&& code, actor::ActorImpl* actor)
 {
   return this->new_context<BoostContext>(std::move(code), actor, this);
 }
index 082c6e8..c0adb53 100644 (file)
@@ -54,7 +54,7 @@ private:
 
 class BoostContextFactory : public SwappedContextFactory {
 public:
-  Context* create_context(std::function<void()>&& code, actor::ActorImpl* actor) override;
+  BoostContext* create_context(std::function<void()>&& code, actor::ActorImpl* actor) override;
 };
 } // namespace context
 } // namespace kernel
index 11a7888..5645aea 100644 (file)
@@ -188,7 +188,7 @@ namespace context {
 
 // RawContextFactory
 
-Context* RawContextFactory::create_context(std::function<void()>&& code, actor::ActorImpl* actor)
+RawContext* RawContextFactory::create_context(std::function<void()>&& code, actor::ActorImpl* actor)
 {
   return this->new_context<RawContext>(std::move(code), actor, this);
 }
index 84c9055..7d56296 100644 (file)
@@ -39,7 +39,7 @@ private:
 
 class RawContextFactory : public SwappedContextFactory {
 public:
-  Context* create_context(std::function<void()>&& code, actor::ActorImpl* actor) override;
+  RawContext* create_context(std::function<void()>&& code, actor::ActorImpl* actor) override;
 };
 } // namespace context
 } // namespace kernel
index 9bae6d2..2ebe3da 100644 (file)
@@ -56,7 +56,7 @@ namespace kernel {
 namespace context {
 
 // UContextFactory
-Context* UContextFactory::create_context(std::function<void()>&& code, actor::ActorImpl* actor)
+UContext* UContextFactory::create_context(std::function<void()>&& code, actor::ActorImpl* actor)
 {
   return new_context<UContext>(std::move(code), actor, this);
 }
index ac12cc8..cec22ac 100644 (file)
@@ -35,7 +35,7 @@ private:
 
 class UContextFactory : public SwappedContextFactory {
 public:
-  Context* create_context(std::function<void()>&& code, actor::ActorImpl* actor) override;
+  UContext* create_context(std::function<void()>&& code, actor::ActorImpl* actor) override;
 };
 } // namespace context
 } // namespace kernel
index 9df8fb4..fdab111 100644 (file)
@@ -207,7 +207,7 @@ void Lagrange::lagrange_solve()
     /* Improve the value of lambda_i */
     for (Constraint& cnst : active_constraint_set) {
       XBT_DEBUG("Working on cnst (%p)", &cnst);
-      cnst.new_lambda = dichotomy(cnst.lambda, partial_diff_lambda, cnst, dichotomy_min_error);
+      cnst.new_lambda = dichotomy(cnst.lambda, cnst, dichotomy_min_error);
       XBT_DEBUG("Updating lambda : cnst->lambda (%p) : %1.20f -> %1.20f", &cnst, cnst.lambda, cnst.new_lambda);
       cnst.lambda = cnst.new_lambda;
 
@@ -264,8 +264,7 @@ void Lagrange::lagrange_solve()
  *
  * @return a double corresponding to the result of the dichotomy process
  */
-double Lagrange::dichotomy(double init, double diff(double, const Constraint&), const Constraint& cnst,
-                           double min_error)
+double Lagrange::dichotomy(double init, const Constraint& cnst, double min_error)
 {
   double min = init;
   double max = init;
@@ -283,15 +282,15 @@ double Lagrange::dichotomy(double init, double diff(double, const Constraint&),
 
   overall_error = 1;
 
-  diff_0 = diff(1e-16, cnst);
+  diff_0 = partial_diff_lambda(1e-16, cnst);
   if (diff_0 >= 0) {
     XBT_CDEBUG(surf_lagrange_dichotomy, "returning 0.0 (diff = %e)", diff_0);
     XBT_OUT();
     return 0.0;
   }
 
-  double min_diff = diff(min, cnst);
-  double max_diff = diff(max, cnst);
+  double min_diff = partial_diff_lambda(min, cnst);
+  double max_diff = partial_diff_lambda(max, cnst);
 
   while (overall_error > min_error) {
     XBT_CDEBUG(surf_lagrange_dichotomy, "[min, max] = [%1.20f, %1.20f] || diffmin, diffmax = %1.20f, %1.20f", min, max,
@@ -301,7 +300,7 @@ double Lagrange::dichotomy(double init, double diff(double, const Constraint&),
       if (min == max) {
         XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing min");
         min      = min / 2.0;
-        min_diff = diff(min, cnst);
+        min_diff = partial_diff_lambda(min, cnst);
       } else {
         XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing max");
         max      = min;
@@ -311,7 +310,7 @@ double Lagrange::dichotomy(double init, double diff(double, const Constraint&),
       if (min == max) {
         XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing max");
         max      = max * 2.0;
-        max_diff = diff(max, cnst);
+        max_diff = partial_diff_lambda(max, cnst);
       } else {
         XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing min");
         min      = max;
@@ -328,7 +327,7 @@ double Lagrange::dichotomy(double init, double diff(double, const Constraint&),
                   min, max - min, min_diff, max_diff);
         break;
       }
-      middle_diff = diff(middle, cnst);
+      middle_diff = partial_diff_lambda(middle, cnst);
 
       if (middle_diff < 0) {
         XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing min");
index 1e3b0d3..123169d 100644 (file)
@@ -633,8 +633,7 @@ private:
    * Local prototypes to implement the Lagrangian optimization with optimal step, also called dichotomy.
    */
   // computes the value of the dichotomy using a initial values, init, with a specific variable or constraint
-  static double dichotomy(double init, double diff(double, const Constraint&), const Constraint& cnst,
-                          double min_error);
+  static double dichotomy(double init, const Constraint& cnst, double min_error);
   // computes the value of the differential of constraint cnst applied to lambda
   static double partial_diff_lambda(double lambda, const Constraint& cnst);
 
index 3ea572b..cf86b5c 100644 (file)
@@ -47,8 +47,8 @@ Action::~Action()
 void Action::finish(Action::State state)
 {
   finish_time_ = surf_get_clock();
-  set_state(state);
   set_remains(0);
+  set_state(state);
 }
 
 Action::State Action::get_state() const
index 28d84cf..16851b2 100644 (file)
@@ -12,69 +12,19 @@ namespace simgrid {
 namespace kernel {
 namespace resource {
 
-Resource::Resource(Model* model, const std::string& name, lmm::Constraint* constraint)
-    : name_(name), model_(model), constraint_(constraint)
-{
-}
-
 Resource::~Resource() = default;
 
-bool Resource::is_on() const
-{
-  return is_on_;
-}
-bool Resource::is_off() const // deprecated
-{
-  return not is_on_;
-}
-
-void Resource::turn_on()
-{
-  is_on_ = true;
-}
-
-void Resource::turn_off()
-{
-  is_on_ = false;
-}
-
-double Resource::get_load()
+double Resource::get_load() const
 {
   return constraint_->get_usage();
 }
 
-Model* Resource::get_model() const
-{
-  return model_;
-}
-
-const std::string& Resource::get_name() const
-{
-  return name_;
-}
-
-const char* Resource::get_cname() const
-{
-  return name_.c_str();
-}
-
-bool Resource::operator==(const Resource& other) const
-{
-  return name_ == other.name_;
-}
-
 void Resource::set_state_profile(profile::Profile* profile)
 {
   xbt_assert(state_event_ == nullptr, "Cannot set a second state profile to %s", get_cname());
-
   state_event_ = profile->schedule(&future_evt_set, this);
 }
 
-kernel::lmm::Constraint* Resource::get_constraint() const
-{
-  return constraint_;
-}
-
 } // namespace resource
 } // namespace kernel
 } // namespace simgrid
index f723a2e..434f943 100644 (file)
@@ -13,7 +13,7 @@ namespace simgrid {
 namespace kernel {
 namespace routing {
 
-simgrid::xbt::signal<void(NetPoint*)> NetPoint::on_creation;
+simgrid::xbt::signal<void(NetPoint&)> NetPoint::on_creation;
 
 NetPoint::NetPoint(const std::string& name, NetPoint::Type componentType, NetZoneImpl* netzone_p)
     : name_(name), component_type_(componentType), englobing_zone_(netzone_p)
@@ -23,7 +23,7 @@ NetPoint::NetPoint(const std::string& name, NetPoint::Type componentType, NetZon
   else
     id_ = static_cast<decltype(id_)>(-1);
   simgrid::s4u::Engine::get_instance()->netpoint_register(this);
-  simgrid::kernel::routing::NetPoint::on_creation(this);
+  simgrid::kernel::routing::NetPoint::on_creation(*this);
 }
 }
 }
index 2889810..b87a8dd 100644 (file)
@@ -92,8 +92,8 @@ int NetZoneImpl::get_host_count()
   return count;
 }
 
-simgrid::s4u::Host* NetZoneImpl::create_host(const char* name, std::vector<double>* speedPerPstate, int coreAmount,
-                                             std::map<std::string, std::string>* props)
+simgrid::s4u::Host* NetZoneImpl::create_host(const char* name, const std::vector<double>& speed_per_pstate,
+                                             int coreAmount, std::map<std::string, std::string>* props)
 {
   simgrid::s4u::Host* res = new simgrid::s4u::Host(name);
 
@@ -102,7 +102,7 @@ simgrid::s4u::Host* NetZoneImpl::create_host(const char* name, std::vector<doubl
 
   res->pimpl_netpoint = new NetPoint(name, NetPoint::Type::Host, this);
 
-  surf_cpu_model_pm->create_cpu(res, speedPerPstate, coreAmount);
+  surf_cpu_model_pm->create_cpu(res, speed_per_pstate, coreAmount);
 
   if (props != nullptr)
     for (auto const& kv : *props)
index a99957c..d441926 100644 (file)
@@ -98,7 +98,7 @@ bool actor_is_enabled(smx_actor_t actor)
       }
       /* On the other hand if it hasn't a timeout, check if the comm is ready.*/
       else if (act->detached && act->src_actor_ == nullptr &&
-               act->type == simgrid::kernel::activity::CommImpl::Type::READY)
+               act->type_ == simgrid::kernel::activity::CommImpl::Type::READY)
         return (act->dst_actor_ != nullptr);
       return (act->src_actor_ && act->dst_actor_);
     }
index 40d650a..ec22c9a 100644 (file)
@@ -447,7 +447,7 @@ static uint64_t MC_dwarf_array_element_count(Dwarf_Die * die, Dwarf_Die * unit)
 static bool MC_compare_variable(
   simgrid::mc::Variable const& a, simgrid::mc::Variable const& b)
 {
-  int cmp = strcmp(a.name.c_str(), b.name.c_str());
+  int cmp = a.name.compare(b.name);
   if (cmp < 0)
     return true;
   else if (cmp > 0)
index c1bd140..b531d8d 100644 (file)
@@ -74,11 +74,11 @@ bool request_depend_asymmetric(smx_simcall_t r1, smx_simcall_t r2)
         simcall_comm_wait__get__timeout(r2) <= 0)
       return false;
 
-    if ((r1->call == SIMCALL_COMM_ISEND) && (synchro2->type == kernel::activity::CommImpl::Type::SEND) &&
+    if ((r1->call == SIMCALL_COMM_ISEND) && (synchro2->type_ == kernel::activity::CommImpl::Type::SEND) &&
         (synchro2->src_buff_ != simcall_comm_isend__get__src_buff(r1)) && simcall_comm_wait__get__timeout(r2) <= 0)
       return false;
 
-    if ((r1->call == SIMCALL_COMM_IRECV) && (synchro2->type == kernel::activity::CommImpl::Type::RECEIVE) &&
+    if ((r1->call == SIMCALL_COMM_IRECV) && (synchro2->type_ == kernel::activity::CommImpl::Type::RECEIVE) &&
         (synchro2->dst_buff_ != simcall_comm_irecv__get__dst_buff(r1)) && simcall_comm_wait__get__timeout(r2) <= 0)
       return false;
   }
@@ -114,43 +114,39 @@ bool request_depend_asymmetric(smx_simcall_t r1, smx_simcall_t r2)
 }
 
 // Those are internal_req
-bool request_depend(smx_simcall_t r1, smx_simcall_t r2)
+bool request_depend(smx_simcall_t req1, smx_simcall_t req2)
 {
-  if (r1->issuer == r2->issuer)
+  if (req1->issuer == req2->issuer)
     return false;
 
   /* Wait with timeout transitions are not considered by the independence theorem, thus we consider them as dependent with all other transitions */
-  if ((r1->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(r1) > 0)
-      || (r2->call == SIMCALL_COMM_WAIT
-          && simcall_comm_wait__get__timeout(r2) > 0))
+  if ((req1->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(req1) > 0) ||
+      (req2->call == SIMCALL_COMM_WAIT && simcall_comm_wait__get__timeout(req2) > 0))
     return true;
 
-  if (r1->call != r2->call)
-    return request_depend_asymmetric(r1, r2)
-      && request_depend_asymmetric(r2, r1);
+  if (req1->call != req2->call)
+    return request_depend_asymmetric(req1, req2) && request_depend_asymmetric(req2, req1);
 
   // Those are internal requests, we do not need indirection
   // because those objects are copies:
-  simgrid::kernel::activity::CommImpl* synchro1 = MC_get_comm(r1);
-  simgrid::kernel::activity::CommImpl* synchro2 = MC_get_comm(r2);
-
-  switch(r1->call) {
-  case SIMCALL_COMM_ISEND:
-    return simcall_comm_isend__get__mbox(r1)
-      == simcall_comm_isend__get__mbox(r2);
-  case SIMCALL_COMM_IRECV:
-    return simcall_comm_irecv__get__mbox(r1)
-      == simcall_comm_irecv__get__mbox(r2);
-  case SIMCALL_COMM_WAIT:
-    if (synchro1->src_buff_ == synchro2->src_buff_ && synchro1->dst_buff_ == synchro2->dst_buff_)
-      return false;
-    if (synchro1->src_buff_ != nullptr && synchro1->dst_buff_ != nullptr && synchro2->src_buff_ != nullptr &&
-        synchro2->dst_buff_ != nullptr && synchro1->dst_buff_ != synchro2->src_buff_ &&
-        synchro1->dst_buff_ != synchro2->dst_buff_ && synchro2->dst_buff_ != synchro1->src_buff_)
-      return false;
-    return true;
-  default:
-    return true;
+  simgrid::kernel::activity::CommImpl* synchro1 = MC_get_comm(req1);
+  simgrid::kernel::activity::CommImpl* synchro2 = MC_get_comm(req2);
+
+  switch (req1->call) {
+    case SIMCALL_COMM_ISEND:
+      return simcall_comm_isend__get__mbox(req1) == simcall_comm_isend__get__mbox(req2);
+    case SIMCALL_COMM_IRECV:
+      return simcall_comm_irecv__get__mbox(req1) == simcall_comm_irecv__get__mbox(req2);
+    case SIMCALL_COMM_WAIT:
+      if (synchro1->src_buff_ == synchro2->src_buff_ && synchro1->dst_buff_ == synchro2->dst_buff_)
+        return false;
+      if (synchro1->src_buff_ != nullptr && synchro1->dst_buff_ != nullptr && synchro2->src_buff_ != nullptr &&
+          synchro2->dst_buff_ != nullptr && synchro1->dst_buff_ != synchro2->src_buff_ &&
+          synchro1->dst_buff_ != synchro2->dst_buff_ && synchro2->dst_buff_ != synchro1->src_buff_)
+        return false;
+      return true;
+    default:
+      return true;
   }
 }
 
index f5d1ce8..035c8d7 100644 (file)
@@ -113,7 +113,7 @@ static inline smx_simcall_t MC_state_get_request_for_process(simgrid::mc::State*
       simgrid::kernel::activity::CommImpl* act = temp_act.getBuffer();
       if (act->src_actor_.get() && act->dst_actor_.get())
         state->transition.argument = 0;
-      else if (act->src_actor_.get() == nullptr && act->type == simgrid::kernel::activity::CommImpl::Type::READY &&
+      else if (act->src_actor_.get() == nullptr && act->type_ == simgrid::kernel::activity::CommImpl::Type::READY &&
                act->detached == 1)
         state->transition.argument = 0;
       else
index 9c644ff..8c6365c 100644 (file)
@@ -14,7 +14,9 @@
 XBT_LOG_NEW_CATEGORY(msg, "All MSG categories");
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_kernel, msg, "Logging specific to MSG (kernel)");
 
-MSG_Global_t msg_global = nullptr;
+bool MSG_Global_t::debug_multiple_use = false;
+
+MSG_Global_t* msg_global = nullptr;
 simgrid::xbt::Extension<simgrid::s4u::Actor, simgrid::msg::ActorUserData> simgrid::msg::ActorUserData::EXTENSION_ID;
 
 static void MSG_exit();
@@ -31,33 +33,17 @@ void MSG_init_nocheck(int *argc, char **argv) {
   TRACE_global_init();
 
   if (not msg_global) {
-
-    msg_global = new s_MSG_Global_t();
-    if (not simgrid::msg::ActorUserData::EXTENSION_ID.valid())
-      simgrid::msg::ActorUserData::EXTENSION_ID = simgrid::s4u::Actor::extension_create<simgrid::msg::ActorUserData>();
-
-    msg_global->debug_multiple_use = false;
-    simgrid::config::bind_flag(msg_global->debug_multiple_use, "msg/debug-multiple-use",
+    simgrid::config::bind_flag(MSG_Global_t::debug_multiple_use, "msg/debug-multiple-use",
                                "Print backtraces of both processes when there is a conflict of multiple use of a task");
 
     SIMIX_global_init(argc, argv);
 
+    msg_global = new MSG_Global_t();
+
     msg_global->sent_msg = 0;
     msg_global->task_copy_callback = nullptr;
     msg_global->process_data_cleanup = nullptr;
-
-    simgrid::s4u::Actor::on_creation.connect([](simgrid::s4u::ActorPtr actor) {
-      XBT_DEBUG("creating the extension to store user data");
-      actor->extension_set(new simgrid::msg::ActorUserData());
-    });
-
-    simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::ActorPtr actor) {
-      // free the data if a function was provided
-      void* userdata = actor->extension<simgrid::msg::ActorUserData>()->get_user_data();
-      if (userdata && msg_global->process_data_cleanup) {
-        msg_global->process_data_cleanup(userdata);
-      }
-    });
+    MSG_process_userdata_init();
   }
 
   if(MC_is_active()){
index db817a6..13f17f4 100644 (file)
@@ -115,15 +115,14 @@ public:
 } // namespace simgrid
 
 /************************** Global variables ********************************/
-struct s_MSG_Global_t {
-  bool debug_multiple_use;           /* whether we want an error message when reusing the same Task for 2 things */
+struct MSG_Global_t {
+  static bool debug_multiple_use;    /* whether we want an error message when reusing the same Task for 2 things */
   std::atomic_int_fast32_t sent_msg; /* Total amount of messages sent during the simulation */
   void (*task_copy_callback)(msg_task_t task, msg_process_t src, msg_process_t dst);
   void_f_pvoid_t process_data_cleanup;
 };
-typedef s_MSG_Global_t* MSG_Global_t;
 
-XBT_PUBLIC_DATA MSG_Global_t msg_global;
+XBT_PUBLIC_DATA MSG_Global_t* msg_global;
 
 /*************************************************************/
 XBT_PRIVATE void MSG_comm_copy_data_from_SIMIX(simgrid::kernel::activity::CommImpl* comm, void* buff, size_t buff_size);
index 9cdb605..1d6bb19 100644 (file)
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_process, msg, "Logging specific to MSG (process)");
 
-std::string instr_pid(msg_process_t proc)
+std::string instr_pid(simgrid::s4u::Actor const& proc)
 {
-  return std::string(proc->get_name()) + "-" + std::to_string(proc->get_pid());
+  return std::string(proc.get_name()) + "-" + std::to_string(proc.get_pid());
+}
+
+void MSG_process_userdata_init()
+{
+  if (not msg_global)
+    msg_global = new MSG_Global_t();
+
+  if (not simgrid::msg::ActorUserData::EXTENSION_ID.valid())
+    simgrid::msg::ActorUserData::EXTENSION_ID = simgrid::s4u::Actor::extension_create<simgrid::msg::ActorUserData>();
+  simgrid::s4u::Actor::on_creation.connect([](simgrid::s4u::Actor& actor) {
+    XBT_DEBUG("creating the extension to store user data");
+    actor.extension_set(new simgrid::msg::ActorUserData());
+  });
+
+  simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::Actor const& actor) {
+    // free the data if a function was provided
+    void* userdata = actor.extension<simgrid::msg::ActorUserData>()->get_user_data();
+    if (userdata && msg_global->process_data_cleanup) {
+      msg_global->process_data_cleanup(userdata);
+    }
+  });
 }
 
 /******************************** Process ************************************/
index b0998af..786ebea 100644 (file)
@@ -100,7 +100,7 @@ msg_error_t Task::execute()
 s4u::CommPtr Task::send_async(const std::string& alias, void_f_pvoid_t cleanup, bool detached)
 {
   if (TRACE_actor_is_enabled()) {
-    container_t process_container = simgrid::instr::Container::by_name(instr_pid(MSG_process_self()));
+    container_t process_container = simgrid::instr::Container::by_name(instr_pid(*MSG_process_self()));
     std::string key               = std::string("p") + std::to_string(get_id());
     simgrid::instr::Container::get_root()->get_link("ACTOR_TASK_LINK")->start_event(process_container, "SR", key);
   }
@@ -184,7 +184,7 @@ void Task::set_used()
 
 void Task::report_multiple_use() const
 {
-  if (msg_global->debug_multiple_use){
+  if (MSG_Global_t::debug_multiple_use) {
     XBT_ERROR("This task is already used in there:");
     // TODO, backtrace
     XBT_ERROR("<missing backtrace>");
@@ -639,7 +639,7 @@ msg_error_t MSG_task_receive_ext_bounded(msg_task_t* task, const char* alias, do
   }
 
   if (TRACE_actor_is_enabled() && ret != MSG_HOST_FAILURE && ret != MSG_TRANSFER_FAILURE && ret != MSG_TIMEOUT) {
-    container_t process_container = simgrid::instr::Container::by_name(instr_pid(MSG_process_self()));
+    container_t process_container = simgrid::instr::Container::by_name(instr_pid(*MSG_process_self()));
 
     std::string key = std::string("p") + std::to_string((*task)->get_id());
     simgrid::instr::Container::get_root()->get_link("ACTOR_TASK_LINK")->end_event(process_container, "SR", key);
index 807dc1d..684c2ad 100644 (file)
@@ -11,7 +11,7 @@ namespace simgrid {
 namespace vm {
 class DirtyPageTrackingExt {
   bool dp_tracking_ = false;
-  std::map<kernel::activity::ExecImplPtr, double> dp_objs_;
+  std::map<kernel::activity::ExecImpl const*, double> dp_objs_;
   double dp_updated_by_deleted_tasks_ = 0.0;
   // Percentage of pages that get dirty compared to netspeed [0;1] bytes per 1 flop execution
   double dp_intensity_          = 0.0;
@@ -23,9 +23,9 @@ public:
   void start_tracking();
   void stop_tracking() { dp_tracking_ = false; }
   bool is_tracking() { return dp_tracking_; }
-  void track(kernel::activity::ExecImplPtr exec, double amount) { dp_objs_.insert({exec, amount}); }
-  void untrack(kernel::activity::ExecImplPtr exec) { dp_objs_.erase(exec); }
-  double get_stored_remains(kernel::activity::ExecImplPtr exec) { return dp_objs_.at(exec); }
+  void track(kernel::activity::ExecImpl const* exec, double amount) { dp_objs_.insert({exec, amount}); }
+  void untrack(kernel::activity::ExecImpl const* exec) { dp_objs_.erase(exec); }
+  double get_stored_remains(kernel::activity::ExecImpl const* exec) { return dp_objs_.at(exec); }
   void update_dirty_page_count(double delta) { dp_updated_by_deleted_tasks_ += delta; }
   double computed_flops_lookup();
   double get_intensity() { return dp_intensity_; }
@@ -67,37 +67,37 @@ double DirtyPageTrackingExt::computed_flops_lookup()
 } // namespace vm
 } // namespace simgrid
 
-static void on_virtual_machine_creation(simgrid::vm::VirtualMachineImpl* vm)
+static void on_virtual_machine_creation(simgrid::vm::VirtualMachineImpl& vm)
 {
-  vm->extension_set<simgrid::vm::DirtyPageTrackingExt>(new simgrid::vm::DirtyPageTrackingExt());
+  vm.extension_set<simgrid::vm::DirtyPageTrackingExt>(new simgrid::vm::DirtyPageTrackingExt());
 }
 
-static void on_exec_creation(simgrid::kernel::activity::ExecImplPtr exec)
+static void on_exec_creation(simgrid::kernel::activity::ExecImpl const& exec)
 {
-  simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(exec->host_);
+  simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(exec.get_host());
   if (vm == nullptr)
     return;
 
   if (vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->is_tracking()) {
-    vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->track(exec, exec->get_remaining());
+    vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->track(&exec, exec.get_remaining());
   } else {
-    vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->track(exec, 0.0);
+    vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->track(&exec, 0.0);
   }
 }
 
-static void on_exec_completion(simgrid::kernel::activity::ExecImplPtr exec)
+static void on_exec_completion(simgrid::kernel::activity::ExecImpl const& exec)
 {
-  simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(exec->host_);
+  simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(exec.get_host());
   if (vm == nullptr)
     return;
 
   /* If we are in the middle of dirty page tracking, we record how much computation has been done until now, and keep
    * the information for the lookup_() function that will called soon. */
   if (vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->is_tracking()) {
-    double delta = vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->get_stored_remains(exec);
+    double delta = vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->get_stored_remains(&exec);
     vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->update_dirty_page_count(delta);
   }
-  vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->untrack(exec);
+  vm->get_impl()->extension<simgrid::vm::DirtyPageTrackingExt>()->untrack(&exec);
 }
 
 void sg_vm_dirty_page_tracking_init()
index 74227e3..b28d3d8 100644 (file)
@@ -193,7 +193,7 @@ sg_size_t File::tell()
 void File::move(const std::string& fullpath)
 {
   /* Check if the new full path is on the same mount point */
-  if (not strncmp(mount_point_.c_str(), fullpath.c_str(), mount_point_.length())) {
+  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
index cda87c0..d94c836 100644 (file)
@@ -278,36 +278,38 @@ public:
   explicit Adagio(simgrid::s4u::Host* ptr)
       : Governor(ptr), rates(100, std::vector<double>(ptr->get_pstate_count(), 0.0))
   {
-    simgrid::smpi::plugin::ampi::on_iteration_in.connect([this](simgrid::s4u::ActorPtr actor) {
+    simgrid::smpi::plugin::ampi::on_iteration_in.connect([this](simgrid::s4u::Actor const& actor) {
       // Every instance of this class subscribes to this event, so one per host
       // This means that for any actor, all 'hosts' are normally notified of these
       // changes, even those who don't currently run the actor 'proc_id'.
       // -> Let's check if this signal call is for us!
-      if (get_host() == actor->get_host()) {
+      if (get_host() == actor.get_host()) {
         iteration_running = true;
       }
     });
-    simgrid::smpi::plugin::ampi::on_iteration_out.connect([this](simgrid::s4u::ActorPtr actor) {
-      if (get_host() == actor->get_host()) {
+    simgrid::smpi::plugin::ampi::on_iteration_out.connect([this](simgrid::s4u::Actor const& actor) {
+      if (get_host() == actor.get_host()) {
         iteration_running = false;
         task_id           = 0;
       }
     });
-    simgrid::kernel::activity::ExecImpl::on_creation.connect([this](simgrid::kernel::activity::ExecImplPtr activity) {
-      if (activity->host_ == get_host())
-        pre_task();
-    });
-    simgrid::kernel::activity::ExecImpl::on_completion.connect([this](simgrid::kernel::activity::ExecImplPtr activity) {
-      // For more than one host (not yet supported), we can access the host via
-      // simcalls_.front()->issuer->iface()->get_host()
-      if (activity->host_ == get_host() && iteration_running) {
-        comp_timer += activity->surf_action_->get_finish_time() - activity->surf_action_->get_start_time();
-      }
-    });
+    simgrid::kernel::activity::ExecImpl::on_creation.connect(
+        [this](simgrid::kernel::activity::ExecImpl const& activity) {
+          if (activity.get_host() == get_host())
+            pre_task();
+        });
+    simgrid::kernel::activity::ExecImpl::on_completion.connect(
+        [this](simgrid::kernel::activity::ExecImpl const& activity) {
+          // For more than one host (not yet supported), we can access the host via
+          // simcalls_.front()->issuer->iface()->get_host()
+          if (activity.get_host() == get_host() && iteration_running) {
+            comp_timer += activity.surf_action_->get_finish_time() - activity.surf_action_->get_start_time();
+          }
+        });
     // FIXME I think that this fires at the same time for all hosts, so when the src sends something,
     // the dst will be notified even though it didn't even arrive at the recv yet
     simgrid::s4u::Link::on_communicate.connect(
-        [this](kernel::resource::NetworkAction*, s4u::Host* src, s4u::Host* dst) {
+        [this](kernel::resource::NetworkAction const&, s4u::Host* src, s4u::Host* dst) {
           if ((get_host() == src || get_host() == dst) && iteration_running) {
             post_task();
           }
index f52746b..92a6b5c 100644 (file)
@@ -411,10 +411,10 @@ static void on_creation(simgrid::s4u::Host& host)
   host.extension_set(new HostEnergy(&host));
 }
 
-static void on_action_state_change(simgrid::surf::CpuAction* action,
+static void on_action_state_change(simgrid::surf::CpuAction const& action,
                                    simgrid::kernel::resource::Action::State /*previous*/)
 {
-  for (simgrid::surf::Cpu* const& cpu : action->cpus()) {
+  for (simgrid::surf::Cpu* const& cpu : action.cpus()) {
     simgrid::s4u::Host* host = cpu->get_host();
     if (host != nullptr) {
 
@@ -434,9 +434,9 @@ static void on_action_state_change(simgrid::surf::CpuAction* action,
 
 /* This callback is fired either when the host changes its state (on/off) ("onStateChange") or its speed
  * (because the user changed the pstate, or because of external trace events) ("onSpeedChange") */
-static void on_host_change(simgrid::s4u::Host& host)
+static void on_host_change(simgrid::s4u::Host const& host)
 {
-  if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
+  if (dynamic_cast<simgrid::s4u::VirtualMachine const*>(&host)) // Ignore virtual machines
     return;
 
   HostEnergy* host_energy = host.extension<HostEnergy>();
@@ -444,9 +444,9 @@ static void on_host_change(simgrid::s4u::Host& host)
   host_energy->update();
 }
 
-static void on_host_destruction(simgrid::s4u::Host& host)
+static void on_host_destruction(simgrid::s4u::Host const& host)
 {
-  if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
+  if (dynamic_cast<simgrid::s4u::VirtualMachine const*>(&host)) // Ignore virtual machines
     return;
 
   XBT_INFO("Energy consumption of host %s: %f Joules", host.get_cname(),
@@ -497,9 +497,9 @@ void sg_host_energy_plugin_init()
   // that the next trigger would be the 2nd compute, hence ignoring the idle time
   // during the recv call. By updating at the beginning of a compute, we can
   // fix that. (If the cpu is not idle, this is not required.)
-  simgrid::kernel::activity::ExecImpl::on_creation.connect([](simgrid::kernel::activity::ExecImplPtr activity){
-    if (activity->host_ != nullptr) { // We only run on one host
-      simgrid::s4u::Host* host = activity->host_;
+  simgrid::kernel::activity::ExecImpl::on_creation.connect([](simgrid::kernel::activity::ExecImpl const& activity) {
+    if (activity.get_host_number() == 1) { // We only run on one host
+      simgrid::s4u::Host* host         = activity.get_host();
       simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
       if (vm != nullptr)
         host = vm->get_pm();
index c529ac8..ea40824 100644 (file)
@@ -168,9 +168,9 @@ using simgrid::plugin::HostLoad;
 /* **************************** events  callback *************************** */
 /* This callback is fired either when the host changes its state (on/off) or its speed
  * (because the user changed the pstate, or because of external trace events) */
-static void on_host_change(simgrid::s4u::Host& host)
+static void on_host_change(simgrid::s4u::Host const& host)
 {
-  if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
+  if (dynamic_cast<simgrid::s4u::VirtualMachine const*>(&host)) // Ignore virtual machines
     return;
 
   host.extension<HostLoad>()->update();
@@ -204,14 +204,14 @@ void sg_host_load_plugin_init()
     host.extension_set(new HostLoad(&host));
   });
 
-  simgrid::kernel::activity::ExecImpl::on_creation.connect([](simgrid::kernel::activity::ExecImplPtr activity){
-    if (activity->host_ != nullptr) { // We only run on one host
-      simgrid::s4u::Host* host = activity->host_;
+  simgrid::kernel::activity::ExecImpl::on_creation.connect([](simgrid::kernel::activity::ExecImpl& activity) {
+    if (activity.get_host_number() == 1) { // We only run on one host
+      simgrid::s4u::Host* host         = activity.get_host();
       simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
       if (vm != nullptr)
         host = vm->get_pm();
 
-      host->extension<HostLoad>()->add_activity(activity);
+      host->extension<HostLoad>()->add_activity(&activity);
       host->extension<HostLoad>()->update(); // If the system was idle until now, we need to update *before*
                                              // this computation starts running so we can keep track of the
                                              // idle time. (Communication operations don't trigger this hook!)
@@ -220,9 +220,9 @@ void sg_host_load_plugin_init()
       XBT_DEBUG("HostLoad plugin currently does not support executions on several hosts");
     }
   });
-  simgrid::kernel::activity::ExecImpl::on_completion.connect([](simgrid::kernel::activity::ExecImplPtr activity){
-    if (activity->host_ != nullptr) { // We only run on one host
-      simgrid::s4u::Host* host = activity->host_;
+  simgrid::kernel::activity::ExecImpl::on_completion.connect([](simgrid::kernel::activity::ExecImpl const& activity) {
+    if (activity.get_host_number() == 1) { // We only run on one host
+      simgrid::s4u::Host* host         = activity.get_host();
       simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
       if (vm != nullptr)
         host = vm->get_pm();
index 5e27abd..ea5cf2d 100644 (file)
@@ -145,10 +145,11 @@ double LinkEnergy::get_consumed_energy()
 using simgrid::plugin::LinkEnergy;
 
 /* **************************** events  callback *************************** */
-static void on_communicate(simgrid::kernel::resource::NetworkAction* action, simgrid::s4u::Host*, simgrid::s4u::Host*)
+static void on_communicate(simgrid::kernel::resource::NetworkAction const& action, simgrid::s4u::Host*,
+                           simgrid::s4u::Host*)
 {
   XBT_DEBUG("onCommunicate is called");
-  for (simgrid::kernel::resource::LinkImpl* link : action->links()) {
+  for (simgrid::kernel::resource::LinkImpl* link : action.links()) {
 
     if (link == nullptr)
       continue;
@@ -194,21 +195,22 @@ void sg_link_energy_plugin_init()
 
   simgrid::s4u::Link::on_creation.connect([](simgrid::s4u::Link& link) { link.extension_set(new LinkEnergy(&link)); });
 
-  simgrid::s4u::Link::on_state_change.connect([](simgrid::s4u::Link& link) { link.extension<LinkEnergy>()->update(); });
+  simgrid::s4u::Link::on_state_change.connect(
+      [](simgrid::s4u::Link const& link) { link.extension<LinkEnergy>()->update(); });
 
-  simgrid::s4u::Link::on_destruction.connect([](simgrid::s4u::Link& link) {
+  simgrid::s4u::Link::on_destruction.connect([](simgrid::s4u::Link const& link) {
     if (link.get_name() != "__loopback__")
       XBT_INFO("Energy consumption of link '%s': %f Joules", link.get_cname(),
                link.extension<LinkEnergy>()->get_consumed_energy());
   });
 
-  simgrid::s4u::Link::on_communication_state_change.connect(
-      [](simgrid::kernel::resource::NetworkAction* action, simgrid::kernel::resource::Action::State /* previous */) {
-        for (simgrid::kernel::resource::LinkImpl* link : action->links()) {
-          if (link != nullptr)
-            link->piface_.extension<LinkEnergy>()->update();
-        }
-      });
+  simgrid::s4u::Link::on_communication_state_change.connect([](
+      simgrid::kernel::resource::NetworkAction const& action, simgrid::kernel::resource::Action::State /* previous */) {
+    for (simgrid::kernel::resource::LinkImpl* link : action.links()) {
+      if (link != nullptr)
+        link->piface_.extension<LinkEnergy>()->update();
+    }
+  });
 
   simgrid::s4u::Link::on_communicate.connect(&on_communicate);
   simgrid::s4u::on_simulation_end.connect(&on_simulation_end);
index 3098d59..a461371 100644 (file)
@@ -23,9 +23,9 @@ namespace vm {
 /*************
  * Callbacks *
  *************/
-simgrid::xbt::signal<void(VirtualMachineImpl*)> VirtualMachineImpl::on_creation;
-simgrid::xbt::signal<void(VirtualMachineImpl*)> VirtualMachineImpl::on_destruction;
-simgrid::xbt::signal<void(VirtualMachineImpl*)> VirtualMachineImpl::on_state_change;
+simgrid::xbt::signal<void(VirtualMachineImpl&)> VirtualMachineImpl::on_creation;
+simgrid::xbt::signal<void(VirtualMachineImpl const&)> VirtualMachineImpl::on_destruction;
+
 /*********
  * Model *
  *********/
@@ -38,7 +38,7 @@ std::deque<s4u::VirtualMachine*> VirtualMachineImpl::allVms_;
  */
 const double virt_overhead = 1; // 0.95
 
-static void host_state_change(s4u::Host& host)
+static void host_state_change(s4u::Host const& host)
 {
   if (not host.is_on()) { // just turned off.
     std::vector<s4u::VirtualMachine*> trash;
@@ -51,13 +51,13 @@ static void host_state_change(s4u::Host& host)
   }
 }
 
-static s4u::VirtualMachine* get_vm_from_task(kernel::activity::ActivityImplPtr task)
+static s4u::VirtualMachine* get_vm_from_task(kernel::activity::ActivityImpl const& task)
 {
-  kernel::activity::ExecImpl* exec = dynamic_cast<kernel::activity::ExecImpl*>(task.get());
-  return exec != nullptr ? dynamic_cast<s4u::VirtualMachine*>(exec->host_) : nullptr;
+  auto* exec = dynamic_cast<kernel::activity::ExecImpl const*>(&task);
+  return exec != nullptr ? dynamic_cast<s4u::VirtualMachine*>(exec->get_host()) : nullptr;
 }
 
-static void add_active_task(kernel::activity::ActivityImplPtr task)
+static void add_active_task(kernel::activity::ActivityImpl const& task)
 {
   s4u::VirtualMachine* vm = get_vm_from_task(task);
   if (vm != nullptr) {
@@ -67,7 +67,7 @@ static void add_active_task(kernel::activity::ActivityImplPtr task)
   }
 }
 
-static void remove_active_task(kernel::activity::ActivityImplPtr task)
+static void remove_active_task(kernel::activity::ActivityImpl const& task)
 {
   s4u::VirtualMachine* vm = get_vm_from_task(task);
   if (vm != nullptr) {
@@ -153,13 +153,13 @@ VirtualMachineImpl::VirtualMachineImpl(simgrid::s4u::VirtualMachine* piface, sim
   update_action_weight();
 
   XBT_VERB("Create VM(%s)@PM(%s)", piface->get_cname(), physical_host_->get_cname());
-  on_creation(this);
+  on_creation(*this);
 }
 
 /** @brief A physical host does not disappear in the current SimGrid code, but a VM may disappear during a simulation */
 VirtualMachineImpl::~VirtualMachineImpl()
 {
-  on_destruction(this);
+  on_destruction(*this);
   /* I was already removed from the allVms set if the VM was destroyed cleanly */
   auto iter = find(allVms_.begin(), allVms_.end(), piface_);
   if (iter != allVms_.end())
index 2e2bce5..6606520 100644 (file)
@@ -31,12 +31,10 @@ public:
   explicit VirtualMachineImpl(s4u::VirtualMachine* piface, s4u::Host* host, int core_amount, size_t ramsize);
   ~VirtualMachineImpl();
 
-  /** @brief Callbacks fired after VM creation. Signature: `void(VirtualMachineImpl*)` */
-  static xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> on_creation;
-  /** @brief Callbacks fired after VM destruction. Signature: `void(VirtualMachineImpl*)` */
-  static xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> on_destruction;
-  /** @brief Callbacks after VM State changes. Signature: `void(VirtualMachineImpl*)` */
-  static xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> on_state_change;
+  /** @brief Callbacks fired after VM creation. Signature: `void(VirtualMachineImpl&)` */
+  static xbt::signal<void(simgrid::vm::VirtualMachineImpl&)> on_creation;
+  /** @brief Callbacks fired after VM destruction. Signature: `void(VirtualMachineImpl const&)` */
+  static xbt::signal<void(simgrid::vm::VirtualMachineImpl const&)> on_destruction;
 
   virtual void suspend(kernel::actor::ActorImpl* issuer);
   virtual void resume();
index a489757..10a8a19 100644 (file)
@@ -287,7 +287,7 @@ void MigrationTx::operator()()
 }
 }
 
-static void onVirtualMachineShutdown(simgrid::s4u::VirtualMachine& vm)
+static void onVirtualMachineShutdown(simgrid::s4u::VirtualMachine const& vm)
 {
   if (vm.get_impl()->is_migrating_) {
     vm.extension<simgrid::vm::VmMigrationExt>()->rx_->kill();
index 9483c03..0a927af 100644 (file)
@@ -15,13 +15,13 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_vm, "S4U virtual machines");
 
 namespace simgrid {
 namespace s4u {
-simgrid::xbt::signal<void(VirtualMachine&)> VirtualMachine::on_start;
-simgrid::xbt::signal<void(VirtualMachine&)> VirtualMachine::on_started;
-simgrid::xbt::signal<void(VirtualMachine&)> VirtualMachine::on_shutdown;
-simgrid::xbt::signal<void(VirtualMachine&)> VirtualMachine::on_suspend;
-simgrid::xbt::signal<void(VirtualMachine&)> VirtualMachine::on_resume;
-simgrid::xbt::signal<void(VirtualMachine&)> VirtualMachine::on_migration_start;
-simgrid::xbt::signal<void(VirtualMachine&)> VirtualMachine::on_migration_end;
+simgrid::xbt::signal<void(VirtualMachine const&)> VirtualMachine::on_start;
+simgrid::xbt::signal<void(VirtualMachine const&)> VirtualMachine::on_started;
+simgrid::xbt::signal<void(VirtualMachine const&)> VirtualMachine::on_shutdown;
+simgrid::xbt::signal<void(VirtualMachine const&)> VirtualMachine::on_suspend;
+simgrid::xbt::signal<void(VirtualMachine const&)> VirtualMachine::on_resume;
+simgrid::xbt::signal<void(VirtualMachine const&)> VirtualMachine::on_migration_start;
+simgrid::xbt::signal<void(VirtualMachine const&)> VirtualMachine::on_migration_end;
 
 VirtualMachine::VirtualMachine(const std::string& name, s4u::Host* physical_host, int core_amount)
     : VirtualMachine(name, physical_host, core_amount, 1024)
@@ -44,7 +44,7 @@ VirtualMachine::VirtualMachine(const std::string& name, s4u::Host* physical_host
   for (int i = 0; i < physical_host->get_pstate_count(); i++)
     speeds.push_back(physical_host->get_pstate_speed(i));
 
-  surf_cpu_model_vm->create_cpu(this, &speeds, core_amount);
+  surf_cpu_model_vm->create_cpu(this, speeds, core_amount);
   if (physical_host->get_pstate() != 0)
     set_pstate(physical_host->get_pstate());
 }
index 1b45a6a..6e49f99 100644 (file)
@@ -21,19 +21,19 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor, "S4U actors");
 namespace simgrid {
 namespace s4u {
 
-xbt::signal<void(ActorPtr)> s4u::Actor::on_creation;
-xbt::signal<void(ActorPtr)> s4u::Actor::on_suspend;
-xbt::signal<void(ActorPtr)> s4u::Actor::on_resume;
-xbt::signal<void(ActorPtr)> s4u::Actor::on_sleep;
-xbt::signal<void(ActorPtr)> s4u::Actor::on_wake_up;
-xbt::signal<void(ActorPtr)> s4u::Actor::on_migration_start;
-xbt::signal<void(ActorPtr)> s4u::Actor::on_migration_end;
-xbt::signal<void(ActorPtr)> s4u::Actor::on_destruction;
+xbt::signal<void(Actor&)> s4u::Actor::on_creation;
+xbt::signal<void(Actor const&)> s4u::Actor::on_suspend;
+xbt::signal<void(Actor const&)> s4u::Actor::on_resume;
+xbt::signal<void(Actor const&)> s4u::Actor::on_sleep;
+xbt::signal<void(Actor const&)> s4u::Actor::on_wake_up;
+xbt::signal<void(Actor const&)> s4u::Actor::on_migration_start;
+xbt::signal<void(Actor const&)> s4u::Actor::on_migration_end;
+xbt::signal<void(Actor const&)> s4u::Actor::on_destruction;
 
 // ***** Actor creation *****
 ActorPtr Actor::self()
 {
-  smx_context_t self_context = kernel::context::Context::self();
+  kernel::context::Context* self_context = kernel::context::Context::self();
   if (self_context == nullptr)
     return ActorPtr();
 
@@ -101,27 +101,27 @@ void Actor::set_auto_restart(bool autorestart)
   });
 }
 
-void Actor::on_exit(int_f_pvoid_pvoid_t fun,
-                    void* data) /* deprecated: cleanup SIMIX_process_on_exit: change prototype of second parameter and
-                                   remove the last one */
+void Actor::on_exit(int_f_pvoid_pvoid_t fun, void* data) /* deprecated */
 {
-  simix::simcall([this, fun, data] { SIMIX_process_on_exit(pimpl_, fun, data); });
+  on_exit([fun, data](bool failed) {
+    intptr_t status = failed ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS;
+    fun(reinterpret_cast<void*>(status), data);
+  });
 }
 
 void Actor::on_exit(const std::function<void(int, void*)>& fun, void* data) /* deprecated */
 {
-  on_exit([fun, data](bool exit) { fun(exit, data); });
+  on_exit([fun, data](bool failed) { fun(failed ? SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS, data); });
 }
 
-void Actor::on_exit(const std::function<void(bool /*failed*/)>& fun)
+void Actor::on_exit(const std::function<void(bool /*failed*/)>& fun) const
 {
-  simix::simcall(
-      [this, fun] { SIMIX_process_on_exit(pimpl_, [fun](int a, void* /*data*/) { fun(a != 0); }, nullptr); });
+  simix::simcall([this, &fun] { SIMIX_process_on_exit(pimpl_, fun); });
 }
 
 void Actor::migrate(Host* new_host)
 {
-  s4u::Actor::on_migration_start(this);
+  s4u::Actor::on_migration_start(*this);
 
   simix::simcall([this, new_host]() {
     if (pimpl_->waiting_synchro != nullptr) {
@@ -135,10 +135,10 @@ void Actor::migrate(Host* new_host)
     this->pimpl_->set_host(new_host);
   });
 
-  s4u::Actor::on_migration_end(this);
+  s4u::Actor::on_migration_end(*this);
 }
 
-s4u::Host* Actor::get_host()
+s4u::Host* Actor::get_host() const
 {
   return this->pimpl_->get_host();
 }
@@ -175,14 +175,14 @@ aid_t Actor::get_ppid() const
 
 void Actor::suspend()
 {
-  s4u::Actor::on_suspend(this);
+  s4u::Actor::on_suspend(*this);
   simcall_process_suspend(pimpl_);
 }
 
 void Actor::resume()
 {
   simix::simcall([this] { pimpl_->resume(); });
-  s4u::Actor::on_resume(this);
+  s4u::Actor::on_resume(*this);
 }
 
 bool Actor::is_suspended()
@@ -218,18 +218,11 @@ void Actor::kill()
 {
   kernel::actor::ActorImpl* process = SIMIX_process_self();
   simix::simcall([this, process] {
-    if (pimpl_ == simix_global->maestro_process)
-      pimpl_->exit();
-    else
-      process->kill(pimpl_);
+    xbt_assert(pimpl_ != simix_global->maestro_process, "Killing maestro is a rather bad idea");
+    process->kill(pimpl_);
   });
 }
 
-kernel::actor::ActorImpl* Actor::get_impl()
-{
-  return pimpl_;
-}
-
 // ***** Static functions *****
 
 ActorPtr Actor::by_pid(aid_t pid)
@@ -291,11 +284,11 @@ void sleep_for(double duration)
 {
   if (duration > 0) {
     kernel::actor::ActorImpl* actor = SIMIX_process_self();
-    Actor::on_sleep(actor->iface());
+    Actor::on_sleep(*actor->ciface());
 
     simcall_process_sleep(duration);
 
-    Actor::on_wake_up(actor->iface());
+    Actor::on_wake_up(*actor->ciface());
   }
 }
 
@@ -420,7 +413,7 @@ Host* get_host()
 void suspend()
 {
   kernel::actor::ActorImpl* actor = SIMIX_process_self();
-  Actor::on_suspend(actor->iface());
+  Actor::on_suspend(*actor->ciface());
 
   simcall_process_suspend(actor);
 }
@@ -429,7 +422,7 @@ void resume()
 {
   kernel::actor::ActorImpl* self = SIMIX_process_self();
   simix::simcall([self] { self->resume(); });
-  Actor::on_resume(self->iface());
+  Actor::on_resume(*self->ciface());
 }
 
 void exit()
index 03d222a..188fda5 100644 (file)
@@ -14,9 +14,9 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_comm, s4u_activity, "S4U asynchronous commun
 
 namespace simgrid {
 namespace s4u {
-xbt::signal<void(ActorPtr)> Comm::on_sender_start;
-xbt::signal<void(ActorPtr)> Comm::on_receiver_start;
-xbt::signal<void(ActorPtr)> Comm::on_completion;
+xbt::signal<void(Actor const&)> Comm::on_sender_start;
+xbt::signal<void(Actor const&)> Comm::on_receiver_start;
+xbt::signal<void(Actor const&)> Comm::on_completion;
 
 Comm::~Comm()
 {
@@ -112,12 +112,12 @@ Comm* Comm::start()
              __FUNCTION__);
 
   if (src_buff_ != nullptr) { // Sender side
-    on_sender_start(Actor::self());
+    on_sender_start(*Actor::self());
     pimpl_ = simcall_comm_isend(sender_, mailbox_->get_impl(), remains_, rate_, src_buff_, src_buff_size_, match_fun_,
                                 clean_fun_, copy_data_function_, get_user_data(), detached_);
   } else if (dst_buff_ != nullptr) { // Receiver side
     xbt_assert(not detached_, "Receive cannot be detached");
-    on_receiver_start(Actor::self());
+    on_receiver_start(*Actor::self());
     pimpl_ = simcall_comm_irecv(receiver_, mailbox_->get_impl(), dst_buff_, &dst_buff_size_, match_fun_,
                                 copy_data_function_, get_user_data(), rate_);
 
@@ -136,7 +136,7 @@ Comm* Comm::wait()
 
 /** @brief Block the calling actor until the communication is finished, or until timeout
  *
- * On timeout, an exception is thrown.
+ * On timeout, an exception is thrown and the communication is invalidated.
  *
  * @param timeout the amount of seconds to wait for the comm termination.
  *                Negative values denote infinite wait times. 0 as a timeout returns immediately. */
@@ -148,12 +148,12 @@ Comm* Comm::wait_for(double timeout)
 
     case State::INITED: // It's not started yet. Do it in one simcall
       if (src_buff_ != nullptr) {
-        on_sender_start(Actor::self());
+        on_sender_start(*Actor::self());
         simcall_comm_send(sender_, mailbox_->get_impl(), remains_, rate_, src_buff_, src_buff_size_, match_fun_,
                           copy_data_function_, get_user_data(), timeout);
 
       } else { // Receiver
-        on_receiver_start(Actor::self());
+        on_receiver_start(*Actor::self());
         simcall_comm_recv(receiver_, mailbox_->get_impl(), dst_buff_, &dst_buff_size_, match_fun_, copy_data_function_,
                           get_user_data(), timeout, rate_);
       }
@@ -162,7 +162,7 @@ Comm* Comm::wait_for(double timeout)
 
     case State::STARTED:
       simcall_comm_wait(pimpl_, timeout);
-      on_completion(Actor::self());
+      on_completion(*Actor::self());
       state_ = State::FINISHED;
       break;
 
index 27ff9fd..e65f996 100644 (file)
@@ -12,12 +12,12 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_exec, s4u_activity, "S4U asynchronous execut
 
 namespace simgrid {
 namespace s4u {
-xbt::signal<void(ActorPtr)> Exec::on_start;
-xbt::signal<void(ActorPtr)> Exec::on_completion;
+xbt::signal<void(Actor const&)> Exec::on_start;
+xbt::signal<void(Actor const&)> Exec::on_completion;
 
 Exec::Exec()
 {
-  pimpl_ = kernel::activity::ExecImplPtr(new kernel::activity::ExecImpl(get_name(), get_tracing_category()));
+  pimpl_ = kernel::activity::ExecImplPtr(new kernel::activity::ExecImpl());
 }
 
 bool Exec::test()
@@ -44,7 +44,7 @@ Exec* Exec::wait()
     start();
   simcall_execution_wait(pimpl_);
   state_ = State::FINISHED;
-  on_completion(Actor::self());
+  on_completion(*Actor::self());
   return this;
 }
 
@@ -113,10 +113,16 @@ ExecSeq::ExecSeq(sg_host_t host, double flops_amount) : Exec(), flops_amount_(fl
 Exec* ExecSeq::start()
 {
   simix::simcall([this] {
-    boost::static_pointer_cast<kernel::activity::ExecImpl>(pimpl_)->start(flops_amount_, 1. / priority_, bound_);
+    (*boost::static_pointer_cast<kernel::activity::ExecImpl>(pimpl_))
+        .set_name(name_)
+        .set_tracing_category(tracing_category_)
+        .set_priority(1. / priority_)
+        .set_bound(bound_)
+        .set_flops_amount(flops_amount_)
+        .start();
   });
   state_ = State::STARTED;
-  on_start(Actor::self());
+  on_start(*Actor::self());
   return this;
 }
 
@@ -131,7 +137,7 @@ ExecPtr ExecSeq::set_host(Host* host)
   if (state_ == State::STARTED)
     boost::static_pointer_cast<simgrid::kernel::activity::ExecImpl>(pimpl_)->migrate(host);
   host_ = host;
-  boost::static_pointer_cast<simgrid::kernel::activity::ExecImpl>(pimpl_)->host_ = host;
+  boost::static_pointer_cast<simgrid::kernel::activity::ExecImpl>(pimpl_)->set_host(host);
   return this;
 }
 
@@ -165,21 +171,23 @@ ExecPar::ExecPar(const std::vector<s4u::Host*>& hosts, const std::vector<double>
                  const std::vector<double>& bytes_amounts)
     : Exec(), hosts_(hosts), flops_amounts_(flops_amounts), bytes_amounts_(bytes_amounts)
 {
-  // For parallel executions, we need a special host to run the timeout detector.
-  host_                                                                          = hosts.front();
-  boost::static_pointer_cast<simgrid::kernel::activity::ExecImpl>(pimpl_)->host_ = host_;
 }
 
 Exec* ExecPar::start()
 {
   simix::simcall([this] {
-    boost::static_pointer_cast<kernel::activity::ExecImpl>(pimpl_)->set_timeout(timeout_);
-    boost::static_pointer_cast<kernel::activity::ExecImpl>(pimpl_)->start(hosts_, flops_amounts_, bytes_amounts_);
+    (*boost::static_pointer_cast<kernel::activity::ExecImpl>(pimpl_))
+        .set_hosts(hosts_)
+        .set_timeout(timeout_)
+        .set_flops_amounts(flops_amounts_)
+        .set_bytes_amounts(bytes_amounts_)
+        .start();
   });
   state_ = State::STARTED;
-  on_start(Actor::self());
+  on_start(*Actor::self());
   return this;
 }
+
 double ExecPar::get_remaining_ratio()
 {
   return simix::simcall(
index 746d4d3..b2731c4 100644 (file)
@@ -10,6 +10,7 @@
 #include "src/simix/smx_private.hpp"
 #include "src/surf/HostImpl.hpp"
 
+#include <algorithm>
 #include <string>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_host, s4u, "Logging specific to the S4U hosts");
@@ -25,9 +26,9 @@ template class Extendable<s4u::Host>;
 namespace s4u {
 
 xbt::signal<void(Host&)> Host::on_creation;
-xbt::signal<void(Host&)> Host::on_destruction;
-xbt::signal<void(Host&)> Host::on_state_change;
-xbt::signal<void(Host&)> Host::on_speed_change;
+xbt::signal<void(Host const&)> Host::on_destruction;
+xbt::signal<void(Host const&)> Host::on_state_change;
+xbt::signal<void(Host const&)> Host::on_speed_change;
 
 Host::Host(const std::string& name) : name_(name)
 {
@@ -215,7 +216,7 @@ void Host::set_speed_profile(kernel::profile::Profile* p)
 /** @brief Get the peak processor speed (in flops/s), at the specified pstate  */
 double Host::get_pstate_speed(int pstate_index) const
 {
-  return simix::simcall([this, pstate_index] { return this->pimpl_cpu->get_pstate_peak_speed(pstate_index); });
+  return this->pimpl_cpu->get_pstate_peak_speed(pstate_index);
 }
 
 /** @brief Get the peak computing speed in flops/s at the current pstate, NOT taking the external load into account.
@@ -338,7 +339,7 @@ sg_host_t* sg_host_list()
   xbt_assert(sg_host_count() > 0, "There is no host!");
   std::vector<simgrid::s4u::Host*> hosts = simgrid::s4u::Engine::get_instance()->get_all_hosts();
 
-  sg_host_t* res = (sg_host_t*)malloc(sizeof(sg_host_t) * hosts.size());
+  sg_host_t* res = xbt_new(sg_host_t, hosts.size());
   memcpy(res, hosts.data(), sizeof(sg_host_t) * hosts.size());
 
   return res;
@@ -366,19 +367,16 @@ sg_host_t sg_host_by_name(const char* name)
 
 xbt_dynar_t sg_hosts_as_dynar()
 {
-  xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), nullptr);
-
   std::vector<simgrid::s4u::Host*> list = simgrid::s4u::Engine::get_instance()->get_all_hosts();
 
-  for (auto const& host : list) {
-    if (host && host->pimpl_netpoint && host->pimpl_netpoint->is_host())
-      xbt_dynar_push(res, &host);
-  }
-  xbt_dynar_sort(res, [](const void* pa, const void* pb) {
-    const std::string& na = (*static_cast<simgrid::s4u::Host* const*>(pa))->get_name();
-    const std::string& nb = (*static_cast<simgrid::s4u::Host* const*>(pb))->get_name();
-    return na.compare(nb);
+  auto last = std::remove_if(begin(list), end(list), [](const simgrid::s4u::Host* host) {
+    return not host || not host->pimpl_netpoint || not host->pimpl_netpoint->is_host();
   });
+  std::sort(begin(list), last,
+            [](const simgrid::s4u::Host* a, const simgrid::s4u::Host* b) { return a->get_name() < b->get_name(); });
+
+  xbt_dynar_t res = xbt_dynar_new(sizeof(sg_host_t), nullptr);
+  std::for_each(begin(list), last, [res](sg_host_t host) { xbt_dynar_push_as(res, sg_host_t, host); });
   return res;
 }
 
index eb450ed..7a89c7b 100644 (file)
@@ -16,12 +16,19 @@ namespace s4u {
 Io::Io(sg_storage_t storage, sg_size_t size, OpType type) : storage_(storage), size_(size), type_(type)
 {
   Activity::set_remaining(size_);
-  pimpl_ = kernel::activity::IoImplPtr(new kernel::activity::IoImpl(get_name(), storage_->get_impl()));
+  pimpl_ = kernel::activity::IoImplPtr(new kernel::activity::IoImpl());
 }
 
 Io* Io::start()
 {
-  simix::simcall([this] { boost::static_pointer_cast<kernel::activity::IoImpl>(pimpl_)->start(size_, type_); });
+  simix::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();
+  });
   state_ = State::STARTED;
   return this;
 }
index 86f5c31..456c57d 100644 (file)
@@ -19,11 +19,11 @@ namespace simgrid {
 namespace s4u {
 
 xbt::signal<void(Link&)> Link::on_creation;
-xbt::signal<void(Link&)> Link::on_destruction;
-xbt::signal<void(Link&)> Link::on_state_change;
-xbt::signal<void(Link&)> Link::on_bandwidth_change;
-xbt::signal<void(kernel::resource::NetworkAction*, Host* src, Host* dst)> Link::on_communicate;
-xbt::signal<void(kernel::resource::NetworkAction*, kernel::resource::Action::State)>
+xbt::signal<void(Link const&)> Link::on_destruction;
+xbt::signal<void(Link const&)> Link::on_state_change;
+xbt::signal<void(Link const&)> Link::on_bandwidth_change;
+xbt::signal<void(kernel::resource::NetworkAction&, Host* src, Host* dst)> Link::on_communicate;
+xbt::signal<void(kernel::resource::NetworkAction&, kernel::resource::Action::State)>
     Link::on_communication_state_change;
 
 Link* Link::by_name(const std::string& name)
@@ -49,12 +49,12 @@ bool Link::is_used()
   return this->pimpl_->is_used();
 }
 
-double Link::get_latency()
+double Link::get_latency() const
 {
   return this->pimpl_->get_latency();
 }
 
-double Link::get_bandwidth()
+double Link::get_bandwidth() const
 {
   return this->pimpl_->get_bandwidth();
 }
@@ -156,7 +156,7 @@ sg_link_t* sg_link_list()
 {
   std::vector<simgrid::s4u::Link*> links = simgrid::s4u::Engine::get_instance()->get_all_links();
 
-  sg_link_t* res = (sg_link_t*)malloc(sizeof(sg_link_t) * links.size());
+  sg_link_t* res = xbt_new(sg_link_t, links.size());
   memcpy(res, links.data(), sizeof(sg_link_t) * links.size());
 
   return res;
index da6c963..cb45e8e 100644 (file)
@@ -16,10 +16,10 @@ namespace s4u {
 
 xbt::signal<void(bool symmetrical, kernel::routing::NetPoint* src, kernel::routing::NetPoint* dst,
                  kernel::routing::NetPoint* gw_src, kernel::routing::NetPoint* gw_dst,
-                 std::vector<kernel::resource::LinkImpl*>& link_list)>
+                 std::vector<kernel::resource::LinkImpl*> const& link_list)>
     NetZone::on_route_creation;
-xbt::signal<void(NetZone&)> NetZone::on_creation;
-xbt::signal<void(NetZone&)> NetZone::on_seal;
+xbt::signal<void(NetZone const&)> NetZone::on_creation;
+xbt::signal<void(NetZone const&)> NetZone::on_seal;
 
 NetZone::NetZone(kernel::routing::NetZoneImpl* impl) : pimpl_(impl) {}
 
index cabbcb0..0be7985 100644 (file)
@@ -18,8 +18,8 @@ template class Extendable<s4u::Storage>;
 namespace s4u {
 
 xbt::signal<void(Storage&)> Storage::on_creation;
-xbt::signal<void(Storage&)> Storage::on_destruction;
-xbt::signal<void(Storage&)> Storage::on_state_change;
+xbt::signal<void(Storage const&)> Storage::on_destruction;
+xbt::signal<void(Storage const&)> Storage::on_state_change;
 
 Storage::Storage(const std::string& name, kernel::resource::StorageImpl* pimpl) : pimpl_(pimpl), name_(name)
 {
index 536d34b..9f999f7 100644 (file)
@@ -9,8 +9,10 @@
 #include "simgrid/simdag.h"
 #include "src/internal_config.h"
 #include "xbt/file.hpp"
+#include <algorithm>
 #include <cstring>
 #include <unordered_map>
+#include <vector>
 
 #if HAVE_GRAPHVIZ
 #include <graphviz/cgraph.h>
@@ -43,23 +45,12 @@ xbt_dynar_t SD_dotload_with_sched(const char *filename) {
   return SD_dotload_generic(filename, true, true);
 }
 
-static int edge_compare(const void *a, const void *b)
-{
-  unsigned va = AGSEQ(*(Agedge_t **)a);
-  unsigned vb = AGSEQ(*(Agedge_t **)b);
-  if (va == vb)
-    return 0;
-  else
-    return (va < vb ? -1 : 1);
-}
-
 xbt_dynar_t SD_dotload_generic(const char* filename, bool sequential, bool schedule)
 {
   xbt_assert(filename, "Unable to use a null file descriptor\n");
   FILE *in_file = fopen(filename, "r");
   xbt_assert(in_file != nullptr, "Failed to open file: %s", filename);
 
-  unsigned int i;
   SD_task_t root;
   SD_task_t end;
   SD_task_t task;
@@ -152,17 +143,16 @@ xbt_dynar_t SD_dotload_generic(const char* filename, bool sequential, bool sched
     end = jobs.at("end");
 
   /* Create edges */
-  xbt_dynar_t edges = xbt_dynar_new(sizeof(Agedge_t*), nullptr);
+  std::vector<Agedge_t*> edges;
   for (node = agfstnode(dag_dot); node; node = agnxtnode(dag_dot, node)) {
-    Agedge_t * edge;
-    xbt_dynar_reset(edges);
-    for (edge = agfstout(dag_dot, node); edge; edge = agnxtout(dag_dot, edge))
-      xbt_dynar_push_as(edges, Agedge_t *, edge);
+    edges.clear();
+    for (Agedge_t* edge = agfstout(dag_dot, node); edge; edge = agnxtout(dag_dot, edge))
+      edges.push_back(edge);
 
     /* Be sure edges are sorted */
-    xbt_dynar_sort(edges, edge_compare);
+    std::sort(edges.begin(), edges.end(), [](const Agedge_t* a, const Agedge_t* b) { return AGSEQ(a) < AGSEQ(b); });
 
-    xbt_dynar_foreach(edges, i, edge) {
+    for (Agedge_t* edge : edges) {
       char *src_name=agnameof(agtail(edge));
       char *dst_name=agnameof(aghead(edge));
       double size = atof(agget(edge, (char *) "size"));
@@ -190,12 +180,12 @@ xbt_dynar_t SD_dotload_generic(const char* filename, bool sequential, bool sched
       }
     }
   }
-  xbt_dynar_free(&edges);
 
   XBT_DEBUG("All tasks have been created, put %s at the end of the dynar", end->name);
   xbt_dynar_push(result, &end);
 
   /* Connect entry tasks to 'root', and exit tasks to 'end'*/
+  unsigned i;
   xbt_dynar_foreach (result, i, task){
     if (task->predecessors->empty() && task->inputs->empty() && task != root) {
       XBT_DEBUG("Task '%s' has no source. Add dependency from 'root'", task->name);
index aad9dd6..6358b59 100644 (file)
@@ -69,7 +69,7 @@ static void sg_config_cmd_line(int *argc, char **argv)
       simgrid::config::set_parse(opt);
       XBT_DEBUG("Did apply '%s' as config setting", opt);
     } else if (parse_args && not strcmp(argv[i], "--version")) {
-      printf("%s\n", SIMGRID_VERSION_STRING);
+      sg_version();
       shall_exit = true;
     } else if (parse_args && (not strcmp(argv[i], "--cfg-help") || not strcmp(argv[i], "--help"))) {
       printf("Description of the configuration accepted by this simulator:\n");
index 4909007..2840515 100644 (file)
@@ -384,10 +384,16 @@ smx_activity_t simcall_execution_start(const std::string& name, const std::strin
                                        double priority, double bound, sg_host_t host)
 {
   return simgrid::simix::simcall([name, category, flops_amount, priority, bound, host] {
-    return simgrid::kernel::activity::ExecImplPtr(
-               new simgrid::kernel::activity::ExecImpl(std::move(name), std::move(category)))
-        ->set_host(host)
-        ->start(flops_amount, priority, bound);
+    simgrid::kernel::activity::ExecImpl* exec = new simgrid::kernel::activity::ExecImpl();
+    (*exec)
+        .set_name(name)
+        .set_tracing_category(category)
+        .set_host(host)
+        .set_priority(priority)
+        .set_bound(bound)
+        .set_flops_amount(flops_amount)
+        .start();
+    return simgrid::kernel::activity::ExecImplPtr(exec);
   });
 }
 
@@ -424,9 +430,15 @@ smx_activity_t simcall_execution_parallel_start(const std::string& name, int hos
   if (bytes_amount != nullptr)
     bytes_parallel_amount = std::vector<double>(bytes_amount, bytes_amount + host_nb * host_nb);
   return simgrid::simix::simcall([name, hosts, flops_parallel_amount, bytes_parallel_amount, timeout] {
-    return simgrid::kernel::activity::ExecImplPtr(new simgrid::kernel::activity::ExecImpl(std::move(name), ""))
-        ->set_timeout(timeout)
-        ->start(hosts, flops_parallel_amount, bytes_parallel_amount);
+    simgrid::kernel::activity::ExecImpl* exec = new simgrid::kernel::activity::ExecImpl();
+    (*exec)
+        .set_name(name)
+        .set_hosts(hosts)
+        .set_timeout(timeout)
+        .set_flops_amounts(flops_parallel_amount)
+        .set_bytes_amounts(bytes_parallel_amount)
+        .start();
+    return simgrid::kernel::activity::ExecImplPtr(exec);
   });
 }
 
index 3d71623..c25d519 100755 (executable)
@@ -9,6 +9,7 @@
 import re
 import glob
 
+
 class Arg(object):
 
     def __init__(self, name, thetype):
@@ -21,6 +22,7 @@ class Arg(object):
     def rettype(self):
         return self.type
 
+
 class Simcall(object):
     simcalls_body = None
     simcalls_pre = None
@@ -42,7 +44,7 @@ class Simcall(object):
             print ('# ERROR: No function calling simcall_BODY_%s' % self.name)
             print ('# Add something like this to libsmx.c:')
             print ('%s simcall_%s(%s)' % (self.res.rettype(), self.name, ', '.
-                   join('%s %s' % (arg.rettype(), arg.name) for arg in self.args)))
+                                          join('%s %s' % (arg.rettype(), arg.name) for arg in self.args)))
             print ('{')
             print ('  return simcall_BODY_%s(%s);' % (self.name, "..."))
             print ('}')
@@ -52,7 +54,8 @@ class Simcall(object):
         # smx_host_t h)
         if self.simcalls_pre is None:
             self.simcalls_pre = set()
-            for fn in glob.glob('smx_*') + glob.glob('ActorImpl*') + glob.glob('../mc/*cpp') + glob.glob('../kernel/activity/*cpp'):
+            for fn in glob.glob('smx_*') + glob.glob('ActorImpl*') + \
+                    glob.glob('../mc/*cpp') + glob.glob('../kernel/activity/*cpp'):
                 f = open(fn)
                 self.simcalls_pre |= set(re.findall(r'simcall_HANDLER_(.*?)\(', f.read()))
                 f.close()
@@ -61,14 +64,16 @@ class Simcall(object):
                 print ('# ERROR: No function called simcall_HANDLER_%s' % self.name)
                 print ('# Add something like this to the relevant C file (like smx_io.c if it\'s an IO call):')
                 print ('%s simcall_HANDLER_%s(smx_simcall_t simcall%s)' % (self.res.rettype(), self.name, ''.
-                       join(', %s %s' % (arg.rettype(), arg.name)for arg in self.args)))
+                                                                           join(', %s %s' % (arg.rettype(), arg.name)for arg in self.args)))
                 print ('{')
                 print ('  // Your code handling the simcall')
                 print ('}')
                 return False
         else:
             if self.name in self.simcalls_pre:
-                print ('# ERROR: You have a function called simcall_HANDLER_%s, but that simcall is not using any handler' % self.name)
+                print (
+                    '# ERROR: You have a function called simcall_HANDLER_%s, but that simcall is not using any handler' %
+                    self.name)
                 print ('# Either change your simcall definition, or kill that function')
                 return False
         return True
@@ -82,7 +87,7 @@ class Simcall(object):
     def accessors(self):
         res = []
         res.append('')
-        regex = re.compile(r"^boost::intrusive_ptr<(.*?)>(.*)$") # to compute the raw type
+        regex = re.compile(r"^boost::intrusive_ptr<(.*?)>(.*)$")  # Â to compute the raw type
         # Arguments getter/setters
         for i in range(len(self.args)):
             arg = self.args[i]
@@ -124,19 +129,19 @@ class Simcall(object):
 
     def case(self):
         res = []
-        args = [ "simgrid::simix::unmarshal<%s>(simcall->args[%d])" % (arg.rettype(), i)
-            for i, arg in enumerate(self.args) ]
+        args = ["simgrid::simix::unmarshal<%s>(simcall->args[%d])" % (arg.rettype(), i)
+                for i, arg in enumerate(self.args)]
         res.append('case SIMCALL_%s:' % (self.name.upper()))
         if self.need_handler:
             call = "simcall_HANDLER_%s(simcall%s%s)" % (self.name,
-                ", " if len(args) > 0 else "",
-                ', '.join(args))
+                                                        ", " if len(args) > 0 else "",
+                                                        ', '.join(args))
         else:
             call = "SIMIX_%s(%s)" % (self.name, ', '.join(args))
         if self.call_kind == 'Func':
             res.append("  simgrid::simix::marshal<%s>(simcall->result, %s);" % (self.res.rettype(), call))
         else:
-            res.append("  " + call + ";");
+            res.append("  " + call + ";")
         if self.call_kind != 'Blck':
             res.append('  SIMIX_simcall_answer(simcall);')
         res.append('  break;')
@@ -147,8 +152,8 @@ class Simcall(object):
         res = ['']
         res.append(
             'inline static %s simcall_BODY_%s(%s)' % (self.res.rettype(),
-                                                        self.name,
-                                                        ', '.join('%s %s' % (arg.rettype(), arg.name) for arg in self.args)))
+                                                      self.name,
+                                                      ', '.join('%s %s' % (arg.rettype(), arg.name) for arg in self.args)))
         res.append('{')
         res.append('  if (0) /* Go to that function to follow the code flow through the simcall barrier */')
         if self.need_handler:
@@ -156,13 +161,13 @@ class Simcall(object):
                                                         ', '.join(["&SIMIX_process_self()->simcall"] + [arg.name for arg in self.args])))
         else:
             res.append('    SIMIX_%s(%s);' % (self.name,
-                                                     ', '.join(arg.name for arg in self.args)))
+                                              ', '.join(arg.name for arg in self.args)))
         res.append('  return simcall<%s%s>(SIMCALL_%s%s);' % (
             self.res.rettype(),
-            "".join([ ", " + arg.rettype() for i, arg in enumerate(self.args) ]),
+            "".join([", " + arg.rettype() for i, arg in enumerate(self.args)]),
             self.name.upper(),
-            "".join([ ", " + arg.name for i, arg in enumerate(self.args) ])
-            ));
+            "".join([", " + arg.name for i, arg in enumerate(self.args)])
+        ))
         res.append('}')
         return '\n'.join(res)
 
@@ -261,6 +266,7 @@ def handle(fd, func, simcalls, guarded_simcalls):
         fd.write('\n'.join(func(simcall) for simcall in ll))
         fd.write('\n#endif\n')
 
+
 if __name__ == '__main__':
     simcalls, simcalls_dict = parse('simcalls.in')
 
@@ -277,7 +283,7 @@ if __name__ == '__main__':
     # popping_accessors.hpp
     #
     fd = header('popping_accessors.hpp')
-    fd.write('#include "src/simix/popping_private.hpp"');
+    fd.write('#include "src/simix/popping_private.hpp"')
     handle(fd, Simcall.accessors, simcalls, simcalls_dict)
     fd.write(
         "\n\n/* The prototype of all simcall handlers, automatically generated for you */\n\n")
@@ -384,5 +390,5 @@ inline static R simcall(e_smx_simcall_t call, T const&... t)
 }
 ''')
     handle(fd, Simcall.body, simcalls, simcalls_dict)
-    fd.write(" /** @endcond */\n");
+    fd.write(" /** @endcond */\n")
     fd.close()
index 2485979..b44d2c8 100644 (file)
@@ -124,14 +124,7 @@ static void install_segvhandler()
 namespace simgrid {
 namespace simix {
 
-Timer* Timer::set(double date, void (*callback)(void*), void* arg)
-{
-  Timer* timer   = new Timer(date, simgrid::xbt::make_task([callback, arg]() { callback(arg); }));
-  timer->handle_ = simix_timers.emplace(std::make_pair(date, timer));
-  return timer;
-}
-
-Timer* Timer::set(double date, simgrid::xbt::Task<void()> callback)
+Timer* Timer::set(double date, simgrid::xbt::Task<void()>&& callback)
 {
   Timer* timer   = new Timer(date, std::move(callback));
   timer->handle_ = simix_timers.emplace(std::make_pair(date, timer));
@@ -219,7 +212,7 @@ void SIMIX_global_init(int *argc, char **argv)
     sg_platf_init();
     simgrid::s4u::on_platform_created.connect(surf_presolve);
 
-    simgrid::s4u::Storage::on_creation.connect([](simgrid::s4u::Storage& storage) {
+    simgrid::s4u::Storage::on_creation.connect([](simgrid::s4u::Storage const& storage) {
       sg_storage_t s = simgrid::s4u::Storage::by_name(storage.get_name());
       xbt_assert(s != nullptr, "Storage not found for name %s", storage.get_cname());
     });
@@ -545,14 +538,12 @@ double SIMIX_timer_next()
 
 smx_timer_t SIMIX_timer_set(double date, void (*callback)(void*), void *arg)
 {
-  return simgrid::simix::Timer::set(date, callback, arg);
+  return simgrid::simix::Timer::set(date, std::bind(callback, arg));
 }
 
-smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task<void()> callback)
+smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task<void()>&& callback) // deprecated
 {
-  smx_timer_t timer = new simgrid::simix::Timer(date, std::move(callback));
-  timer->handle_    = simgrid::simix::simix_timers.emplace(std::make_pair(date, timer));
-  return timer;
+  return simgrid::simix::Timer::set(date, std::move(callback));
 }
 
 /** @brief cancels a timer that was added earlier */
index ac866f1..96e2fd3 100644 (file)
@@ -80,6 +80,7 @@ WRAPPED_PMPI_CALL(int,MPI_Alloc_mem,(MPI_Aint size, MPI_Info info, void *baseptr
 WRAPPED_PMPI_CALL(int,MPI_Allreduce,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm),(sendbuf, recvbuf, count, datatype, op, comm))
 WRAPPED_PMPI_CALL(int,MPI_Alltoall,(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount,MPI_Datatype recvtype, MPI_Comm comm),(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm))
 WRAPPED_PMPI_CALL(int,MPI_Alltoallv,(void *sendbuf, int *sendcounts, int *senddisps, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm),(sendbuf, sendcounts, senddisps, sendtype, recvbuf, recvcounts, recvdisps, recvtype, comm))
+WRAPPED_PMPI_CALL(int,MPI_Alltoallw,( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype *sendtypes, void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype *recvtypes, MPI_Comm comm),( sendbuf, sendcnts, sdispls, sendtypes, recvbuf, recvcnts, rdispls, recvtypes, comm))
 WRAPPED_PMPI_CALL(int,MPI_Attr_delete,(MPI_Comm comm, int keyval) ,(comm, keyval))
 WRAPPED_PMPI_CALL(int,MPI_Attr_get,(MPI_Comm comm, int keyval, void* attr_value, int* flag) ,(comm, keyval, attr_value, flag))
 WRAPPED_PMPI_CALL(int,MPI_Attr_put,(MPI_Comm comm, int keyval, void* attr_value) ,(comm, keyval, attr_value))
@@ -140,6 +141,25 @@ WRAPPED_PMPI_CALL(int,MPI_Group_rank,(MPI_Group group, int *rank),(group, rank))
 WRAPPED_PMPI_CALL(int,MPI_Group_size,(MPI_Group group, int *size),(group, size))
 WRAPPED_PMPI_CALL(int,MPI_Group_translate_ranks,(MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2),(group1, n, ranks1, group2, ranks2))
 WRAPPED_PMPI_CALL(int,MPI_Group_union,(MPI_Group group1, MPI_Group group2, MPI_Group * newgroup),(group1, group2, newgroup))
+WRAPPED_PMPI_CALL(int,MPI_Ibarrier,(MPI_Comm comm, MPI_Request *request),(comm,request))
+WRAPPED_PMPI_CALL(int,MPI_Ibcast,(void* buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm, MPI_Request *request),(buf, count, datatype, root, comm, request))
+
+WRAPPED_PMPI_CALL(int,MPI_Iallgather,(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Iallgatherv,(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Iallreduce,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Ialltoall,(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount,MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Ialltoallv,(void *sendbuf, int *sendcounts, int *senddisps, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcounts, senddisps, sendtype, recvbuf, recvcounts, recvdisps, recvtype, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Ialltoallw,( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype *sendtypes, void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype *recvtypes, MPI_Comm comm, MPI_Request *request),( sendbuf, sendcnts, sdispls, sendtypes, recvbuf, recvcnts, rdispls, recvtypes, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Igather,(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Igatherv,(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Ireduce_scatter_block,(void *sendbuf, void *recvbuf, int recvcount, MPI_Datatype datatype, MPI_Op op,MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, recvcount, datatype, op, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Ireduce_scatter,(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, recvcounts, datatype, op, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Ireduce,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, root, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Iexscan,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Iscan,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request),(sendbuf, recvbuf, count, datatype, op, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Iscatter,(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,int root, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, request))
+WRAPPED_PMPI_CALL(int,MPI_Iscatterv,(void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcount,MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request),(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm, request))
+
 WRAPPED_PMPI_CALL(int,MPI_Info_create,( MPI_Info *info),( info))
 WRAPPED_PMPI_CALL(int,MPI_Info_delete,(MPI_Info info, char *key),(info, key))
 WRAPPED_PMPI_CALL(int,MPI_Info_dup,(MPI_Info info, MPI_Info *newinfo),(info, newinfo))
@@ -193,6 +213,9 @@ WRAPPED_PMPI_CALL(int,MPI_Testall,(int count, MPI_Request* requests, int* flag,
 WRAPPED_PMPI_CALL(int,MPI_Testany,(int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status),(count, requests, index, flag, status))
 WRAPPED_PMPI_CALL(int,MPI_Test,(MPI_Request * request, int *flag, MPI_Status * status),(request, flag, status))
 WRAPPED_PMPI_CALL(int,MPI_Testsome,(int incount, MPI_Request* requests, int* outcount, int* indices, MPI_Status* statuses) ,(incount, requests, outcount, indices, statuses))
+WRAPPED_PMPI_CALL(int,MPI_Request_get_status,( MPI_Request request, int *flag, MPI_Status *status),( request, flag, status))
+WRAPPED_PMPI_CALL(int,MPI_Grequest_complete,( MPI_Request request),( request))
+WRAPPED_PMPI_CALL(int,MPI_Grequest_start,(MPI_Grequest_query_function *query_fn, MPI_Grequest_free_function *free_fn,MPI_Grequest_cancel_function *cancel_fn, void *extra_state, MPI_Request *request),( query_fn, free_fn, cancel_fn, extra_state, request))
 WRAPPED_PMPI_CALL(int,MPI_Type_commit,(MPI_Datatype* datatype) ,(datatype))
 WRAPPED_PMPI_CALL(int,MPI_Type_contiguous,(int count, MPI_Datatype old_type, MPI_Datatype* newtype) ,(count, old_type, newtype))
 WRAPPED_PMPI_CALL(int,MPI_Type_create_hindexed_block,(int count, int blocklength, MPI_Aint* indices, MPI_Datatype old_type, MPI_Datatype* newtype) ,(count, blocklength, indices, old_type, newtype))
@@ -275,8 +298,10 @@ WRAPPED_PMPI_CALL_NORETURN(MPI_Info, MPI_Info_f2c,(MPI_Fint info),(info))
 WRAPPED_PMPI_CALL_NORETURN(MPI_Op, MPI_Op_f2c,(MPI_Fint op),(op))
 WRAPPED_PMPI_CALL_NORETURN(MPI_Request, MPI_Request_f2c,(MPI_Fint request),(request))
 WRAPPED_PMPI_CALL_NORETURN(MPI_Win, MPI_Win_f2c,(MPI_Fint win),(win))
-WRAPPED_PMPI_CALL(int,MPI_Cancel,(MPI_Request* request) ,(request))
+WRAPPED_PMPI_CALL(int, MPI_Cancel,(MPI_Request* request) ,(request))
 WRAPPED_PMPI_CALL(int, MPI_Test_cancelled,(MPI_Status* status, int* flag) ,(status, flag))
+WRAPPED_PMPI_CALL(int, MPI_Status_set_cancelled,(MPI_Status *status,int flag),(status,flag))
+WRAPPED_PMPI_CALL(int,MPI_Status_set_elements,( MPI_Status *status, MPI_Datatype datatype, int count),( status, datatype, count))
 /*
   Unimplemented Calls - both PMPI and MPI calls are generated.
   When implementing, please move ahead, swap UNIMPLEMENTED_WRAPPED_PMPI_CALL for WRAPPED_PMPI_CALL,
@@ -287,7 +312,6 @@ WRAPPED_PMPI_CALL(int, MPI_Test_cancelled,(MPI_Status* status, int* flag) ,(stat
 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_Alltoallw,( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype *sendtypes, void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype *recvtypes, MPI_Comm comm),( sendbuf, sendcnts, sdispls, sendtypes, recvbuf, recvcnts, rdispls, recvtypes, comm))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Bsend_init,(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,(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))
@@ -384,8 +408,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, int* index, 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_Grequest_complete,( MPI_Request request),( request))
-UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Grequest_start,(MPI_Grequest_query_function *query_fn, MPI_Grequest_free_function *free_fn,MPI_Grequest_cancel_function *cancel_fn, void *extra_state, MPI_Request *request),( query_fn, free_fn, cancel_fn, extra_state, request))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Ibsend,(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))
@@ -396,11 +418,8 @@ UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Pack_external,(char *datarep, void *inbu
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Pack_external_size,(char *datarep, int incount, MPI_Datatype datatype, MPI_Aint *size),(datarep, incount, datatype, size))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Pcontrol,(const int level, ... ),(level))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Publish_name,( char *service_name, MPI_Info info, char *port_name),( service_name, info, port_name))
-UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Request_get_status,( MPI_Request request, int *flag, MPI_Status *status),( request, flag, status))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Rsend_init,(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_Rsend,(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_Status_set_cancelled,(MPI_Status *status,int flag),(status,flag))
-UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Status_set_elements,( MPI_Status *status, MPI_Datatype datatype, int count),( status, datatype, count))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Topo_test,(MPI_Comm comm, int* top_type) ,(comm, top_type))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(int,MPI_Type_create_darray,(int size, int rank, int ndims, int* array_of_gsizes, int* array_of_distribs, int* array_of_dargs, int* array_of_psizes,int order, MPI_Datatype oldtype, MPI_Datatype *newtype) ,(size, rank, ndims, array_of_gsizes,array_of_distribs, array_of_dargs, array_of_psizes,order,oldtype, newtype))
 UNIMPLEMENTED_WRAPPED_PMPI_CALL(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),(datatype, max_integers, max_addresses,max_datatypes, array_of_integers, array_of_addresses, array_of_datatypes))
index 43cbdb8..6b831d5 100644 (file)
@@ -215,7 +215,7 @@ int PMPI_Error_class(int errorcode, int* errorclass) {
 }
 
 int PMPI_Error_string(int errorcode, char* string, int* resultlen){
-  if (errorcode<0 || string ==nullptr){
+  if (errorcode<0 || errorcode>= MPI_MAX_ERROR_STRING || string ==nullptr){
     return MPI_ERR_ARG;
   } else {
     static const char *smpi_error_string[] = {
index 93202eb..66df954 100644 (file)
@@ -6,6 +6,7 @@
 #include "private.hpp"
 #include "smpi_coll.hpp"
 #include "smpi_comm.hpp"
+#include "smpi_request.hpp"
 #include "smpi_datatype_derived.hpp"
 #include "smpi_op.hpp"
 #include "src/smpi/include/smpi_actor.hpp"
@@ -16,58 +17,78 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
 
 int PMPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
 {
-  int retval = 0;
+  return PMPI_Ibcast(buf, count, datatype, root, comm, MPI_REQUEST_IGNORED);
+}
 
-  smpi_bench_end();
+int PMPI_Barrier(MPI_Comm comm)
+{
+  return PMPI_Ibarrier(comm, MPI_REQUEST_IGNORED);
+}
 
+int PMPI_Ibarrier(MPI_Comm comm, MPI_Request *request)
+{
+  int retval = 0;
+  smpi_bench_end();
   if (comm == MPI_COMM_NULL) {
     retval = MPI_ERR_COMM;
-  } else if (not datatype->is_valid()) {
+  } else if(request == nullptr){
     retval = MPI_ERR_ARG;
-  } else {
+  }else{
     int rank = simgrid::s4u::this_actor::get_pid();
-    TRACE_smpi_comm_in(rank, __func__,
-                       new simgrid::instr::CollTIData("bcast", root, -1.0,
-                                                      datatype->is_replayable() ? count : count * datatype->size(), -1,
-                                                      simgrid::smpi::Datatype::encode(datatype), ""));
-    if (comm->size() > 1)
-      simgrid::smpi::Colls::bcast(buf, count, datatype, root, comm);
-    retval = MPI_SUCCESS;
-
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED? "PMPI_Barrier" : "PMPI_Ibarrier", new simgrid::instr::NoOpTIData(request==MPI_REQUEST_IGNORED? "barrier" : "ibarrier"));
+    if(request==MPI_REQUEST_IGNORED){
+      simgrid::smpi::Colls::barrier(comm);
+      //Barrier can be used to synchronize RMA calls. Finish all requests from comm before.
+      comm->finish_rma_calls();
+    } else
+      simgrid::smpi::Colls::ibarrier(comm, request);
     TRACE_smpi_comm_out(rank);
-  }
+  }    
   smpi_bench_begin();
   return retval;
 }
 
-int PMPI_Barrier(MPI_Comm comm)
+int PMPI_Ibcast(void *buf, int count, MPI_Datatype datatype, 
+                   int root, MPI_Comm comm, MPI_Request* request)
 {
   int retval = 0;
-
   smpi_bench_end();
-
   if (comm == MPI_COMM_NULL) {
     retval = MPI_ERR_COMM;
+  } else if (not datatype->is_valid()) {
+    retval = MPI_ERR_ARG;
+  } else if(request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank = simgrid::s4u::this_actor::get_pid();
-    TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::NoOpTIData("barrier"));
-
-    simgrid::smpi::Colls::barrier(comm);
-
-    //Barrier can be used to synchronize RMA calls. Finish all requests from comm before.
-    comm->finish_rma_calls();
-
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED?"PMPI_Bcast":"PMPI_Ibcast",
+                       new simgrid::instr::CollTIData(request==MPI_REQUEST_IGNORED?"bcast":"ibcast", root, -1.0,
+                                                      datatype->is_replayable() ? count : count * datatype->size(), -1,
+                                                      simgrid::smpi::Datatype::encode(datatype), ""));
+    if (comm->size() > 1){
+      if(request==MPI_REQUEST_IGNORED)
+        simgrid::smpi::Colls::bcast(buf, count, datatype, root, comm);
+      else
+        simgrid::smpi::Colls::ibcast(buf, count, datatype, root, comm, request);
+    } else {
+      if(request!=MPI_REQUEST_IGNORED)
+        *request = MPI_REQUEST_NULL;
+    }
     retval = MPI_SUCCESS;
 
     TRACE_smpi_comm_out(rank);
   }
-
   smpi_bench_begin();
   return retval;
 }
 
 int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,
-                int root, MPI_Comm comm)
+                int root, MPI_Comm comm){
+  return PMPI_Igather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Igather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbuf, int recvcount, MPI_Datatype recvtype,
+                int root, MPI_Comm comm, MPI_Request *request)
 {
   int retval = 0;
 
@@ -80,7 +101,9 @@ int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbu
     retval = MPI_ERR_TYPE;
   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) || ((comm->rank() == root) && (recvcount <0))){
     retval = MPI_ERR_COUNT;
-  } else {
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  }  else {
 
     char* sendtmpbuf = static_cast<char*>(sendbuf);
     int sendtmpcount = sendcount;
@@ -92,13 +115,15 @@ int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbu
     int rank = simgrid::s4u::this_actor::get_pid();
 
     TRACE_smpi_comm_in(
-        rank, __func__,
+        rank, request==MPI_REQUEST_IGNORED?"PMPI_Gather":"PMPI_Igather",
         new simgrid::instr::CollTIData(
-            "gather", root, -1.0, sendtmptype->is_replayable() ? sendtmpcount : sendtmpcount * sendtmptype->size(),
+            request==MPI_REQUEST_IGNORED ? "gather":"igather", root, -1.0, sendtmptype->is_replayable() ? sendtmpcount : sendtmpcount * sendtmptype->size(),
             (comm->rank() != root || recvtype->is_replayable()) ? recvcount : recvcount * recvtype->size(),
             simgrid::smpi::Datatype::encode(sendtmptype), simgrid::smpi::Datatype::encode(recvtype)));
-
-    simgrid::smpi::Colls::gather(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      simgrid::smpi::Colls::gather(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm);
+    else
+      simgrid::smpi::Colls::igather(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, root, comm, request);
 
     retval = MPI_SUCCESS;
     TRACE_smpi_comm_out(rank);
@@ -109,7 +134,12 @@ int PMPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,void *recvbu
 }
 
 int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
-                MPI_Datatype recvtype, int root, MPI_Comm comm)
+                MPI_Datatype recvtype, int root, MPI_Comm comm){
+  return PMPI_Igatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Igatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
+                MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request)
 {
   int retval = 0;
 
@@ -124,7 +154,9 @@ int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recv
     retval = MPI_ERR_COUNT;
   } else if ((comm->rank() == root) && (recvcounts == nullptr || displs == nullptr)) {
     retval = MPI_ERR_ARG;
-  } else {
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  }  else {
     char* sendtmpbuf = static_cast<char*>(sendbuf);
     int sendtmpcount = sendcount;
     MPI_Datatype sendtmptype = sendtype;
@@ -142,14 +174,16 @@ int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recv
         trace_recvcounts->push_back(recvcounts[i] * dt_size_recv);
     }
 
-    TRACE_smpi_comm_in(rank, __func__,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED?"PMPI_Gatherv":"PMPI_Igatherv",
                        new simgrid::instr::VarCollTIData(
-                           "gatherv", root,
+                           request==MPI_REQUEST_IGNORED ? "gatherv":"igatherv", root,
                            sendtmptype->is_replayable() ? sendtmpcount : sendtmpcount * sendtmptype->size(), nullptr,
                            dt_size_recv, trace_recvcounts, simgrid::smpi::Datatype::encode(sendtmptype),
                            simgrid::smpi::Datatype::encode(recvtype)));
-
-    retval = simgrid::smpi::Colls::gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::gatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm);
+    else
+      retval = simgrid::smpi::Colls::igatherv(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcounts, displs, recvtype, root, comm, request);
     TRACE_smpi_comm_out(rank);
   }
 
@@ -158,7 +192,12 @@ int PMPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recv
 }
 
 int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
-                   void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
+                   void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm){
+  return PMPI_Iallgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, MPI_REQUEST_IGNORED);
+}
+              
+int PMPI_Iallgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                   void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request* request)
 {
   int retval = MPI_SUCCESS;
 
@@ -172,7 +211,9 @@ int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   } else if ((( sendbuf != MPI_IN_PLACE) && (sendcount <0)) ||
             (recvcount <0)){
     retval = MPI_ERR_COUNT;
-  } else {
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  }  else {
     if(sendbuf == MPI_IN_PLACE) {
       sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*recvcount*comm->rank();
       sendcount=recvcount;
@@ -180,13 +221,15 @@ int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
     }
     int rank = simgrid::s4u::this_actor::get_pid();
 
-    TRACE_smpi_comm_in(rank, __func__,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED?"PMPI_Allgather":"PMPI_Iallggather",
                        new simgrid::instr::CollTIData(
-                           "allgather", -1, -1.0, sendtype->is_replayable() ? sendcount : sendcount * sendtype->size(),
+                           request==MPI_REQUEST_IGNORED ? "allgather" : "iallgather", -1, -1.0, sendtype->is_replayable() ? sendcount : sendcount * sendtype->size(),
                            recvtype->is_replayable() ? recvcount : recvcount * recvtype->size(),
                            simgrid::smpi::Datatype::encode(sendtype), simgrid::smpi::Datatype::encode(recvtype)));
-
-    simgrid::smpi::Colls::allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      simgrid::smpi::Colls::allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm);
+    else
+      simgrid::smpi::Colls::iallgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, request);
     TRACE_smpi_comm_out(rank);
   }
   smpi_bench_begin();
@@ -194,7 +237,12 @@ int PMPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 }
 
 int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
-                   void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
+                   void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm){
+  return PMPI_Iallgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Iallgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                   void *recvbuf, int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request* request)
 {
   int retval = 0;
 
@@ -208,7 +256,9 @@ int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
     retval = MPI_ERR_COUNT;
   } else if (recvcounts == nullptr || displs == nullptr) {
     retval = MPI_ERR_ARG;
-  } else {
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  }  else {
 
     if(sendbuf == MPI_IN_PLACE) {
       sendbuf=static_cast<char*>(recvbuf)+recvtype->get_extent()*displs[comm->rank()];
@@ -222,13 +272,15 @@ int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
     for (int i = 0; i < comm->size(); i++) // copy data to avoid bad free
       trace_recvcounts->push_back(recvcounts[i] * dt_size_recv);
 
-    TRACE_smpi_comm_in(rank, __func__,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED?"PMPI_Allgatherv":"PMPI_Iallgatherv",
                        new simgrid::instr::VarCollTIData(
-                           "allgatherv", -1, sendtype->is_replayable() ? sendcount : sendcount * sendtype->size(),
+                           request==MPI_REQUEST_IGNORED ? "allgatherv" : "iallgatherv", -1, sendtype->is_replayable() ? sendcount : sendcount * sendtype->size(),
                            nullptr, dt_size_recv, trace_recvcounts, simgrid::smpi::Datatype::encode(sendtype),
                            simgrid::smpi::Datatype::encode(recvtype)));
-
-    simgrid::smpi::Colls::allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      simgrid::smpi::Colls::allgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm);
+    else
+      simgrid::smpi::Colls::iallgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm, request);
     retval = MPI_SUCCESS;
     TRACE_smpi_comm_out(rank);
   }
@@ -238,7 +290,12 @@ int PMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 }
 
 int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
-                void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
+                void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm){
+  return PMPI_Iscatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Iscatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request* request)
 {
   int retval = 0;
 
@@ -252,7 +309,9 @@ int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   } else if ((sendbuf == recvbuf) ||
       ((comm->rank()==root) && sendcount>0 && (sendbuf == nullptr))){
     retval = MPI_ERR_BUFFER;
-  }else {
+  }else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  } else {
 
     if (recvbuf == MPI_IN_PLACE) {
       recvtype  = sendtype;
@@ -261,14 +320,16 @@ int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
     int rank = simgrid::s4u::this_actor::get_pid();
 
     TRACE_smpi_comm_in(
-        rank, __func__,
+        rank, request==MPI_REQUEST_IGNORED?"PMPI_Scatter":"PMPI_Iscatter",
         new simgrid::instr::CollTIData(
-            "scatter", root, -1.0,
+            request==MPI_REQUEST_IGNORED ? "scatter" : "iscatter", root, -1.0,
             (comm->rank() != root || sendtype->is_replayable()) ? sendcount : sendcount * sendtype->size(),
             recvtype->is_replayable() ? recvcount : recvcount * recvtype->size(),
             simgrid::smpi::Datatype::encode(sendtype), simgrid::smpi::Datatype::encode(recvtype)));
-
-    simgrid::smpi::Colls::scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      simgrid::smpi::Colls::scatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm);
+    else
+      simgrid::smpi::Colls::iscatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, request);
     retval = MPI_SUCCESS;
     TRACE_smpi_comm_out(rank);
   }
@@ -278,7 +339,12 @@ int PMPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 }
 
 int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
-                 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
+                 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm){
+  return PMPI_Iscatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Iscatterv(void *sendbuf, int *sendcounts, int *displs,
+                 MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request)
 {
   int retval = 0;
 
@@ -291,6 +357,8 @@ int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
   } else if (((comm->rank() == root) && (sendtype == MPI_DATATYPE_NULL)) ||
              ((recvbuf != MPI_IN_PLACE) && (recvtype == MPI_DATATYPE_NULL))) {
     retval = MPI_ERR_TYPE;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     if (recvbuf == MPI_IN_PLACE) {
       recvtype  = sendtype;
@@ -305,13 +373,15 @@ int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
         trace_sendcounts->push_back(sendcounts[i] * dt_size_send);
     }
 
-    TRACE_smpi_comm_in(rank, __func__,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED?"PMPI_Scatterv":"PMPI_Iscatterv",
                        new simgrid::instr::VarCollTIData(
-                           "scatterv", root, dt_size_send, trace_sendcounts,
+                           request==MPI_REQUEST_IGNORED ? "scatterv":"iscatterv", root, dt_size_send, trace_sendcounts,
                            recvtype->is_replayable() ? recvcount : recvcount * recvtype->size(), nullptr,
                            simgrid::smpi::Datatype::encode(sendtype), simgrid::smpi::Datatype::encode(recvtype)));
-
-    retval = simgrid::smpi::Colls::scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::scatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm);
+    else
+     retval = simgrid::smpi::Colls::iscatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm, request);
 
     TRACE_smpi_comm_out(rank);
   }
@@ -321,6 +391,11 @@ int PMPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
 }
 
 int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)
+{
+  return PMPI_Ireduce(sendbuf, recvbuf, count, datatype, op, root, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Ireduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, MPI_Request* request)
 {
   int retval = 0;
 
@@ -330,15 +405,20 @@ int PMPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
     retval = MPI_ERR_COMM;
   } else if (not datatype->is_valid() || op == MPI_OP_NULL) {
     retval = MPI_ERR_ARG;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank = simgrid::s4u::this_actor::get_pid();
 
-    TRACE_smpi_comm_in(rank, __func__,
-                       new simgrid::instr::CollTIData("reduce", root, 0,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED ? "PMPI_Reduce":"PMPI_Ireduce",
+                       new simgrid::instr::CollTIData(request==MPI_REQUEST_IGNORED ? "reduce":"ireduce", root, 0,
                                                       datatype->is_replayable() ? count : count * datatype->size(), -1,
                                                       simgrid::smpi::Datatype::encode(datatype), ""));
+    if(request == MPI_REQUEST_IGNORED)
+      simgrid::smpi::Colls::reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
+    else
+      simgrid::smpi::Colls::ireduce(sendbuf, recvbuf, count, datatype, op, root, comm, request);
 
-    simgrid::smpi::Colls::reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
 
     retval = MPI_SUCCESS;
     TRACE_smpi_comm_out(rank);
@@ -363,6 +443,11 @@ int PMPI_Reduce_local(void *inbuf, void *inoutbuf, int count, MPI_Datatype datat
 }
 
 int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+{
+  return PMPI_Iallreduce(sendbuf, recvbuf, count, datatype, op, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Iallreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request)
 {
   int retval = 0;
 
@@ -374,8 +459,9 @@ int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatyp
     retval = MPI_ERR_TYPE;
   } else if (op == MPI_OP_NULL) {
     retval = MPI_ERR_OP;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
-
     char* sendtmpbuf = static_cast<char*>(sendbuf);
     if( sendbuf == MPI_IN_PLACE ) {
       sendtmpbuf = static_cast<char*>(xbt_malloc(count*datatype->get_extent()));
@@ -383,12 +469,15 @@ int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatyp
     }
     int rank = simgrid::s4u::this_actor::get_pid();
 
-    TRACE_smpi_comm_in(rank, __func__,
-                       new simgrid::instr::CollTIData("allreduce", -1, 0,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED ?"PMPI_Allreduce":"PMPI_Iallreduce",
+                       new simgrid::instr::CollTIData(request==MPI_REQUEST_IGNORED ? "allreduce":"iallreduce", -1, 0,
                                                       datatype->is_replayable() ? count : count * datatype->size(), -1,
                                                       simgrid::smpi::Datatype::encode(datatype), ""));
 
-    simgrid::smpi::Colls::allreduce(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      simgrid::smpi::Colls::allreduce(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    else
+      simgrid::smpi::Colls::iallreduce(sendtmpbuf, recvbuf, count, datatype, op, comm, request);
 
     if( sendbuf == MPI_IN_PLACE )
       xbt_free(sendtmpbuf);
@@ -402,6 +491,11 @@ int PMPI_Allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatyp
 }
 
 int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+{
+  return PMPI_Iscan(sendbuf, recvbuf, count, datatype, op, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Iscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request* request)
 {
   int retval = 0;
 
@@ -413,6 +507,8 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MP
     retval = MPI_ERR_TYPE;
   } else if (op == MPI_OP_NULL) {
     retval = MPI_ERR_OP;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank = simgrid::s4u::this_actor::get_pid();
     void* sendtmpbuf = sendbuf;
@@ -420,11 +516,15 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MP
       sendtmpbuf = static_cast<void*>(xbt_malloc(count * datatype->size()));
       memcpy(sendtmpbuf, recvbuf, count * datatype->size());
     }
-    TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::Pt2PtTIData(
-                                           "scan", -1, datatype->is_replayable() ? count : count * datatype->size(),
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED ? "PMPI_Scan" : "PMPI_Iscan", new simgrid::instr::Pt2PtTIData(
+                                           request==MPI_REQUEST_IGNORED ? "scan":"iscan", -1, 
+                                           datatype->is_replayable() ? count : count * datatype->size(),
                                            simgrid::smpi::Datatype::encode(datatype)));
 
-    retval = simgrid::smpi::Colls::scan(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::scan(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    else
+      retval = simgrid::smpi::Colls::iscan(sendtmpbuf, recvbuf, count, datatype, op, comm, request);
 
     TRACE_smpi_comm_out(rank);
     if (sendbuf == MPI_IN_PLACE)
@@ -435,7 +535,12 @@ int PMPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MP
   return retval;
 }
 
-int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm){
+int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+{
+  return PMPI_Iexscan(sendbuf, recvbuf, count, datatype, op, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Iexscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request* request){
   int retval = 0;
 
   smpi_bench_end();
@@ -446,6 +551,8 @@ int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
     retval = MPI_ERR_TYPE;
   } else if (op == MPI_OP_NULL) {
     retval = MPI_ERR_OP;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank         = simgrid::s4u::this_actor::get_pid();
     void* sendtmpbuf = sendbuf;
@@ -454,11 +561,14 @@ int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
       memcpy(sendtmpbuf, recvbuf, count * datatype->size());
     }
 
-    TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::Pt2PtTIData(
-                                           "exscan", -1, datatype->is_replayable() ? count : count * datatype->size(),
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED ? "PMPI_Exscan" : "PMPI_Iexscan", new simgrid::instr::Pt2PtTIData(
+                                           request==MPI_REQUEST_IGNORED ? "exscan":"iexscan", -1, datatype->is_replayable() ? count : count * datatype->size(),
                                            simgrid::smpi::Datatype::encode(datatype)));
 
-    retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::exscan(sendtmpbuf, recvbuf, count, datatype, op, comm);
+    else
+      retval = simgrid::smpi::Colls::iexscan(sendtmpbuf, recvbuf, count, datatype, op, comm, request);
 
     TRACE_smpi_comm_out(rank);
     if (sendbuf == MPI_IN_PLACE)
@@ -470,6 +580,11 @@ int PMPI_Exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
 }
 
 int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+{
+  return PMPI_Ireduce_scatter(sendbuf, recvbuf, recvcounts, datatype, op, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Ireduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request)
 {
   int retval = 0;
   smpi_bench_end();
@@ -482,6 +597,8 @@ int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datat
     retval = MPI_ERR_OP;
   } else if (recvcounts == nullptr) {
     retval = MPI_ERR_ARG;
+  }  else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank                           = simgrid::s4u::this_actor::get_pid();
     std::vector<int>* trace_recvcounts = new std::vector<int>;
@@ -499,11 +616,15 @@ int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datat
       memcpy(sendtmpbuf, recvbuf, totalcount * datatype->size());
     }
 
-    TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::VarCollTIData(
-                                           "reducescatter", -1, dt_send_size, nullptr, -1, trace_recvcounts,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED ? "PMPI_Reduce_scatter": "PMPI_Ireduce_scatter", new simgrid::instr::VarCollTIData(
+                                           request==MPI_REQUEST_IGNORED ? "reducescatter":"ireducescatter", -1, dt_send_size, nullptr, -1, trace_recvcounts,
                                            simgrid::smpi::Datatype::encode(datatype), ""));
 
-    simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
+    else
+      simgrid::smpi::Colls::ireduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm, request);
+
     retval = MPI_SUCCESS;
     TRACE_smpi_comm_out(rank);
 
@@ -517,6 +638,12 @@ int PMPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datat
 
 int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
                               MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
+{
+  return PMPI_Ireduce_scatter_block(sendbuf, recvbuf, recvcount, datatype, op, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Ireduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
+                              MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request)
 {
   int retval;
   smpi_bench_end();
@@ -529,7 +656,9 @@ int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
     retval = MPI_ERR_OP;
   } else if (recvcount < 0) {
     retval = MPI_ERR_ARG;
-  } else {
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  }  else {
     int count = comm->size();
 
     int rank                           = simgrid::s4u::this_actor::get_pid();
@@ -542,14 +671,17 @@ int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
       memcpy(sendtmpbuf, recvbuf, recvcount * count * datatype->size());
     }
 
-    TRACE_smpi_comm_in(rank, __func__,
-                       new simgrid::instr::VarCollTIData("reducescatter", -1, 0, nullptr, -1, trace_recvcounts,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED ? "PMPI_Reduce_scatter_block":"PMPI_Ireduce_scatter_block",
+                       new simgrid::instr::VarCollTIData(request==MPI_REQUEST_IGNORED ? "reducescatter":"ireducescatter", -1, 0, nullptr, -1, trace_recvcounts,
                                                          simgrid::smpi::Datatype::encode(datatype), ""));
 
     int* recvcounts = new int[count];
     for (int i      = 0; i < count; i++)
       recvcounts[i] = recvcount;
-    simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      simgrid::smpi::Colls::reduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm);
+    else
+      simgrid::smpi::Colls::ireduce_scatter(sendtmpbuf, recvbuf, recvcounts, datatype, op, comm, request);
     delete[] recvcounts;
     retval = MPI_SUCCESS;
 
@@ -562,9 +694,13 @@ int PMPI_Reduce_scatter_block(void *sendbuf, void *recvbuf, int recvcount,
   smpi_bench_begin();
   return retval;
 }
-
 int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
-                  MPI_Datatype recvtype, MPI_Comm comm)
+                  MPI_Datatype recvtype, MPI_Comm comm){
+  return PMPI_Ialltoall(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, MPI_REQUEST_IGNORED);
+}
+                  
+int PMPI_Ialltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
+                  MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request)
 {
   int retval = 0;
   smpi_bench_end();
@@ -573,6 +709,8 @@ int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* rec
     retval = MPI_ERR_COMM;
   } else if ((sendbuf != MPI_IN_PLACE && sendtype == MPI_DATATYPE_NULL) || recvtype == MPI_DATATYPE_NULL) {
     retval = MPI_ERR_TYPE;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
   } else {
     int rank                 = simgrid::s4u::this_actor::get_pid();
     void* sendtmpbuf         = static_cast<char*>(sendbuf);
@@ -585,14 +723,16 @@ int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* rec
       sendtmptype  = recvtype;
     }
 
-    TRACE_smpi_comm_in(rank, __func__,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED?"PMPI_Alltoall":"PMPI_Ialltoall",
                        new simgrid::instr::CollTIData(
-                           "alltoall", -1, -1.0,
+                           request==MPI_REQUEST_IGNORED ? "alltoall" : "ialltoall", -1, -1.0,
                            sendtmptype->is_replayable() ? sendtmpcount : sendtmpcount * sendtmptype->size(),
                            recvtype->is_replayable() ? recvcount : recvcount * recvtype->size(),
                            simgrid::smpi::Datatype::encode(sendtmptype), simgrid::smpi::Datatype::encode(recvtype)));
-
-    retval = simgrid::smpi::Colls::alltoall(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm);
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::alltoall(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm);
+    else
+      retval = simgrid::smpi::Colls::ialltoall(sendtmpbuf, sendtmpcount, sendtmptype, recvbuf, recvcount, recvtype, comm, request);
 
     TRACE_smpi_comm_out(rank);
 
@@ -606,6 +746,12 @@ int PMPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* rec
 
 int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf,
                    int* recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
+{
+  return PMPI_Ialltoallv(sendbuf, sendcounts, senddisps, sendtype, recvbuf, recvcounts, recvdisps, recvtype, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Ialltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf,
+                   int* recvcounts, int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request)
 {
   int retval = 0;
 
@@ -613,12 +759,14 @@ int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype
 
   if (comm == MPI_COMM_NULL) {
     retval = MPI_ERR_COMM;
-  } else if (sendtype == MPI_DATATYPE_NULL || recvtype == MPI_DATATYPE_NULL) {
+  } else if ((sendbuf != MPI_IN_PLACE && sendtype == MPI_DATATYPE_NULL)  || recvtype == MPI_DATATYPE_NULL) {
     retval = MPI_ERR_TYPE;
   } else if ((sendbuf != MPI_IN_PLACE && (sendcounts == nullptr || senddisps == nullptr)) || recvcounts == nullptr ||
              recvdisps == nullptr) {
     retval = MPI_ERR_ARG;
-  } else {
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  }  else {
     int rank                           = simgrid::s4u::this_actor::get_pid();
     int size               = comm->size();
     int send_size                      = 0;
@@ -656,19 +804,111 @@ int PMPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype
       trace_sendcounts->push_back(sendtmpcounts[i] * dt_size_send);
     }
 
-    TRACE_smpi_comm_in(rank, __func__,
-                       new simgrid::instr::VarCollTIData("alltoallv", -1, send_size, trace_sendcounts, recv_size,
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED?"PMPI_Alltoallv":"PMPI_Ialltoallv",
+                       new simgrid::instr::VarCollTIData(request==MPI_REQUEST_IGNORED ? "alltoallv":"ialltoallv", -1, send_size, trace_sendcounts, recv_size,
                                                          trace_recvcounts, simgrid::smpi::Datatype::encode(sendtype),
                                                          simgrid::smpi::Datatype::encode(recvtype)));
 
-    retval = simgrid::smpi::Colls::alltoallv(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::alltoallv(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
                                     recvdisps, recvtype, comm);
+    else
+      retval = simgrid::smpi::Colls::ialltoallv(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptype, recvbuf, recvcounts,
+                                    recvdisps, recvtype, comm, request);
+    TRACE_smpi_comm_out(rank);
+
+    if (sendbuf == MPI_IN_PLACE) {
+      xbt_free(sendtmpbuf);
+      xbt_free(sendtmpcounts);
+      xbt_free(sendtmpdisps);
+    }
+  }
+
+  smpi_bench_begin();
+  return retval;
+}
+
+int PMPI_Alltoallw(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype* sendtypes, void* recvbuf,
+                   int* recvcounts, int* recvdisps, MPI_Datatype* recvtypes, MPI_Comm comm)
+{
+  return PMPI_Ialltoallw(sendbuf, sendcounts, senddisps, sendtypes, recvbuf, recvcounts, recvdisps, recvtypes, comm, MPI_REQUEST_IGNORED);
+}
+
+int PMPI_Ialltoallw(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype* sendtypes, void* recvbuf,
+                   int* recvcounts, int* recvdisps, MPI_Datatype* recvtypes, MPI_Comm comm, MPI_Request *request)
+{
+  int retval = 0;
+
+  smpi_bench_end();
+
+  if (comm == MPI_COMM_NULL) {
+    retval = MPI_ERR_COMM;
+  } else if ((sendbuf != MPI_IN_PLACE && sendtypes == nullptr)  || recvtypes == nullptr) {
+    retval = MPI_ERR_TYPE;
+  } else if ((sendbuf != MPI_IN_PLACE && (sendcounts == nullptr || senddisps == nullptr)) || recvcounts == nullptr ||
+             recvdisps == nullptr) {
+    retval = MPI_ERR_ARG;
+  } else if (request == nullptr){
+    retval = MPI_ERR_ARG;
+  }  else {
+    int rank                           = simgrid::s4u::this_actor::get_pid();
+    int size                           = comm->size();
+    int send_size                      = 0;
+    int recv_size                      = 0;
+    std::vector<int>* trace_sendcounts = new std::vector<int>;
+    std::vector<int>* trace_recvcounts = new std::vector<int>;
+
+    void* sendtmpbuf           = static_cast<char*>(sendbuf);
+    int* sendtmpcounts         = sendcounts;
+    int* sendtmpdisps          = senddisps;
+    MPI_Datatype* sendtmptypes = sendtypes;
+    unsigned long maxsize                = 0;
+    for (int i = 0; i < size; i++) { // copy data to avoid bad free
+      if(recvtypes[i]==MPI_DATATYPE_NULL){
+        delete trace_recvcounts;
+        delete trace_sendcounts;
+        return MPI_ERR_TYPE;
+      }
+      recv_size += recvcounts[i] * recvtypes[i]->size();
+      trace_recvcounts->push_back(recvcounts[i] * recvtypes[i]->size());
+      if ((recvdisps[i] + (recvcounts[i] * recvtypes[i]->size())) > maxsize)
+        maxsize = recvdisps[i] + (recvcounts[i] * recvtypes[i]->size());
+    }
+
+    if (sendbuf == MPI_IN_PLACE) {
+      sendtmpbuf = static_cast<void*>(xbt_malloc(maxsize));
+      memcpy(sendtmpbuf, recvbuf, maxsize);
+      sendtmpcounts = static_cast<int*>(xbt_malloc(size * sizeof(int)));
+      memcpy(sendtmpcounts, recvcounts, size * sizeof(int));
+      sendtmpdisps = static_cast<int*>(xbt_malloc(size * sizeof(int)));
+      memcpy(sendtmpdisps, recvdisps, size * sizeof(int));
+      sendtmptypes = static_cast<MPI_Datatype*>(xbt_malloc(size * sizeof(MPI_Datatype)));
+      memcpy(sendtmptypes, recvtypes, size * sizeof(MPI_Datatype));
+    }
+
+    for (int i = 0; i < size; i++) { // copy data to avoid bad free
+      send_size += sendtmpcounts[i] * sendtmptypes[i]->size();
+      trace_sendcounts->push_back(sendtmpcounts[i] * sendtmptypes[i]->size());
+    }
+
+    TRACE_smpi_comm_in(rank, request==MPI_REQUEST_IGNORED?"PMPI_Alltoallw":"PMPI_Ialltoallw",
+                       new simgrid::instr::VarCollTIData(request==MPI_REQUEST_IGNORED ? "alltoallv":"ialltoallv", -1, send_size, trace_sendcounts, recv_size,
+                                                         trace_recvcounts, simgrid::smpi::Datatype::encode(sendtmptypes[0]),
+                                                         simgrid::smpi::Datatype::encode(recvtypes[0])));
+
+    if(request == MPI_REQUEST_IGNORED)
+      retval = simgrid::smpi::Colls::alltoallw(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptypes, recvbuf, recvcounts,
+                                    recvdisps, recvtypes, comm);
+    else
+      retval = simgrid::smpi::Colls::ialltoallw(sendtmpbuf, sendtmpcounts, sendtmpdisps, sendtmptypes, recvbuf, recvcounts,
+                                    recvdisps, recvtypes, comm, request);
     TRACE_smpi_comm_out(rank);
 
     if (sendbuf == MPI_IN_PLACE) {
       xbt_free(sendtmpbuf);
       xbt_free(sendtmpcounts);
       xbt_free(sendtmpdisps);
+      xbt_free(sendtmptypes);
     }
   }
 
index 6b3bd32..505914e 100644 (file)
@@ -27,7 +27,7 @@ int PMPI_Op_free(MPI_Op * op)
   } else if (*op == MPI_OP_NULL) {
     return MPI_ERR_OP;
   } else {
-    delete (*op);
+    simgrid::smpi::Op::unref(op);
     *op = MPI_OP_NULL;
     return MPI_SUCCESS;
   }
index 2153455..790d371 100644 (file)
@@ -524,10 +524,9 @@ int PMPI_Test(MPI_Request * request, int *flag, MPI_Status * status)
 
     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("test"));
     
-    *flag = simgrid::smpi::Request::test(request,status);
+    retval = simgrid::smpi::Request::test(request,status, flag);
 
     TRACE_smpi_comm_out(my_proc_id);
-    retval = MPI_SUCCESS;
   }
   smpi_bench_begin();
   return retval;
@@ -543,9 +542,8 @@ int PMPI_Testany(int count, MPI_Request requests[], int *index, int *flag, MPI_S
   } else {
     int my_proc_id = simgrid::s4u::this_actor::get_pid();
     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("testany"));
-    *flag = simgrid::smpi::Request::testany(count, requests, index, status);
+    retval = simgrid::smpi::Request::testany(count, requests, index, flag, status);
     TRACE_smpi_comm_out(my_proc_id);
-    retval = MPI_SUCCESS;
   }
   smpi_bench_begin();
   return retval;
@@ -561,9 +559,8 @@ int PMPI_Testall(int count, MPI_Request* requests, int* flag, MPI_Status* status
   } else {
     int my_proc_id = simgrid::s4u::this_actor::get_pid();
     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("testall"));
-    *flag = simgrid::smpi::Request::testall(count, requests, statuses);
+    retval = simgrid::smpi::Request::testall(count, requests, flag, statuses);
     TRACE_smpi_comm_out(my_proc_id);
-    retval = MPI_SUCCESS;
   }
   smpi_bench_begin();
   return retval;
@@ -579,9 +576,8 @@ int PMPI_Testsome(int incount, MPI_Request requests[], int* outcount, int* indic
   } else {
     int my_proc_id = simgrid::s4u::this_actor::get_pid();
     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("testsome"));
-    *outcount = simgrid::smpi::Request::testsome(incount, requests, indices, status);
+    retval = simgrid::smpi::Request::testsome(incount, requests, outcount, indices, status);
     TRACE_smpi_comm_out(my_proc_id);
-    retval    = MPI_SUCCESS;
   }
   smpi_bench_begin();
   return retval;
@@ -662,7 +658,8 @@ int PMPI_Wait(MPI_Request * request, MPI_Status * status)
   } else {
     //for tracing, save the handle which might get overriden before we can use the helper on it
     MPI_Request savedreq = *request;
-    if (savedreq != MPI_REQUEST_NULL && not(savedreq->flags() & MPI_REQ_FINISHED))
+    if (savedreq != MPI_REQUEST_NULL && not(savedreq->flags() & MPI_REQ_FINISHED)
+    && not(savedreq->flags() & MPI_REQ_GENERALIZED))
       savedreq->ref();//don't erase te handle in Request::wait, we'll need it later
     else
       savedreq = MPI_REQUEST_NULL;
@@ -673,8 +670,7 @@ int PMPI_Wait(MPI_Request * request, MPI_Status * status)
     TRACE_smpi_comm_in(my_proc_id, __func__,
                        new simgrid::instr::WaitTIData((*request)->src(), (*request)->dst(), (*request)->tag()));
 
-    simgrid::smpi::Request::wait(request, status);
-    retval = MPI_SUCCESS;
+    retval = simgrid::smpi::Request::wait(request, status);
 
     //the src may not have been known at the beginning of the recv (MPI_ANY_SOURCE)
     TRACE_smpi_comm_out(my_proc_id);
@@ -793,6 +789,42 @@ int PMPI_Test_cancelled(MPI_Status* status, int* flag){
   return MPI_SUCCESS;  
 }
 
+int PMPI_Status_set_cancelled(MPI_Status* status, int flag){
+  if(status==MPI_STATUS_IGNORE){
+    return MPI_ERR_ARG;
+  }
+  simgrid::smpi::Status::set_cancelled(status,flag);
+  return MPI_SUCCESS;  
+}
+
+int PMPI_Status_set_elements(MPI_Status* status, MPI_Datatype datatype, int count){
+  if(status==MPI_STATUS_IGNORE){
+    return MPI_ERR_ARG;
+  }
+  simgrid::smpi::Status::set_elements(status,datatype, count);
+  return MPI_SUCCESS;  
+}
+
+int PMPI_Grequest_start( MPI_Grequest_query_function *query_fn, MPI_Grequest_free_function *free_fn, MPI_Grequest_cancel_function *cancel_fn, void *extra_state, MPI_Request *request){
+  return simgrid::smpi::Request::grequest_start(query_fn, free_fn,cancel_fn, extra_state, request);
+}
+
+int PMPI_Grequest_complete( MPI_Request request){
+  return simgrid::smpi::Request::grequest_complete(request);
+}
+
+
+int PMPI_Request_get_status( MPI_Request request, int *flag, MPI_Status *status){
+  if(request==MPI_REQUEST_NULL){
+    *flag=1;
+    simgrid::smpi::Status::empty(status);
+    return MPI_ERR_REQUEST;
+  } else if (flag==NULL || status ==NULL){
+    return MPI_ERR_ARG;
+  }
+  return simgrid::smpi::Request::get_status(request,flag,status);
+}
+
 MPI_Request PMPI_Request_f2c(MPI_Fint request){
   return static_cast<MPI_Request>(simgrid::smpi::Request::f2c(request));
 }
index 746991a..39c764e 100644 (file)
@@ -16,7 +16,7 @@ namespace smpi{
 int Coll_alltoall_basic_linear::alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                                           void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
 {
-  int system_tag = 888;
+  int system_tag = COLL_TAG_ALLTOALL;
   int i;
   int count;
   MPI_Aint lb = 0, sendext = 0, recvext = 0;
index a665472..501d15e 100644 (file)
@@ -56,7 +56,7 @@ Coll_alltoallv_ompi_basic_linear::alltoallv(void *sbuf, int *scounts, int *sdisp
 
     /* Post all receives first */
     for (i = 0; i < size; ++i) {
-        if (i == rank || 0 == rcounts[i]) {
+        if (i == rank) {
             continue;
         }
 
@@ -72,7 +72,7 @@ Coll_alltoallv_ompi_basic_linear::alltoallv(void *sbuf, int *scounts, int *sdisp
 
     /* Now post all sends */
     for (i = 0; i < size; ++i) {
-        if (i == rank || 0 == scounts[i]) {
+        if (i == rank) {
             continue;
         }
 
index f50418b..4f16a56 100644 (file)
@@ -115,86 +115,23 @@ void Colls::set_collectives(){
   }
 }
 
-
 //Implementations of the single algorith collectives
 
 int Colls::gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
                       MPI_Datatype recvtype, int root, MPI_Comm comm)
 {
-  int system_tag = COLL_TAG_GATHERV;
-  MPI_Aint lb = 0;
-  MPI_Aint recvext = 0;
-
-  int rank = comm->rank();
-  int size = comm->size();
-  if (rank != root) {
-    // Send buffer to root
-    Request::send(sendbuf, sendcount, sendtype, root, system_tag, comm);
-  } else {
-    recvtype->extent(&lb, &recvext);
-    // Local copy from root
-    Datatype::copy(sendbuf, sendcount, sendtype, static_cast<char*>(recvbuf) + displs[root] * recvext,
-                       recvcounts[root], recvtype);
-    // Receive buffers from senders
-    MPI_Request *requests = xbt_new(MPI_Request, size - 1);
-    int index = 0;
-    for (int src = 0; src < size; src++) {
-      if(src != root) {
-        requests[index] = Request::irecv_init(static_cast<char*>(recvbuf) + displs[src] * recvext,
-                          recvcounts[src], recvtype, src, system_tag, comm);
-        index++;
-      }
-    }
-    // Wait for completion of irecv's.
-    Request::startall(size - 1, requests);
-    Request::waitall(size - 1, requests, MPI_STATUS_IGNORE);
-    for (int src = 0; src < size-1; src++) {
-      Request::unref(&requests[src]);
-    }
-    xbt_free(requests);
-  }
-  return MPI_SUCCESS;
+  MPI_Request request;
+  Colls::igatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm, &request);
+  return Request::wait(&request, MPI_STATUS_IGNORE);
 }
 
 
 int Colls::scatterv(void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcount,
                        MPI_Datatype recvtype, int root, MPI_Comm comm)
 {
-  int system_tag = COLL_TAG_SCATTERV;
-  MPI_Aint lb = 0;
-  MPI_Aint sendext = 0;
-
-  int rank = comm->rank();
-  int size = comm->size();
-  if(rank != root) {
-    // Recv buffer from root
-    Request::recv(recvbuf, recvcount, recvtype, root, system_tag, comm, MPI_STATUS_IGNORE);
-  } else {
-    sendtype->extent(&lb, &sendext);
-    // Local copy from root
-    if(recvbuf!=MPI_IN_PLACE){
-      Datatype::copy(static_cast<char *>(sendbuf) + displs[root] * sendext, sendcounts[root],
-                       sendtype, recvbuf, recvcount, recvtype);
-    }
-    // Send buffers to receivers
-    MPI_Request *requests = xbt_new(MPI_Request, size - 1);
-    int index = 0;
-    for (int dst = 0; dst < size; dst++) {
-      if (dst != root) {
-        requests[index] = Request::isend_init(static_cast<char *>(sendbuf) + displs[dst] * sendext, sendcounts[dst],
-                            sendtype, dst, system_tag, comm);
-        index++;
-      }
-    }
-    // Wait for completion of isend's.
-    Request::startall(size - 1, requests);
-    Request::waitall(size - 1, requests, MPI_STATUS_IGNORE);
-    for (int dst = 0; dst < size-1; dst++) {
-      Request::unref(&requests[dst]);
-    }
-    xbt_free(requests);
-  }
-  return MPI_SUCCESS;
+  MPI_Request request;
+  Colls::iscatterv(sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm, &request);
+  return Request::wait(&request, MPI_STATUS_IGNORE);
 }
 
 
@@ -326,5 +263,13 @@ int Colls::exscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype
   return MPI_SUCCESS;
 }
 
+int Colls::alltoallw(void *sendbuf, int *sendcounts, int *senddisps, MPI_Datatype* sendtypes,
+                              void *recvbuf, int *recvcounts, int *recvdisps, MPI_Datatype* recvtypes, MPI_Comm comm)
+{
+  MPI_Request request;
+  Colls::ialltoallw(sendbuf, sendcounts, senddisps, sendtypes, recvbuf, recvcounts, recvdisps, recvtypes, comm, &request);  
+  return Request::wait(&request, MPI_STATUS_IGNORE);
+}
+
 }
 }
index d6126c7..1aebcf6 100644 (file)
@@ -25,39 +25,9 @@ int Coll_barrier_default::barrier(MPI_Comm comm)
 int Coll_gather_default::gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                      void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
 {
-  const int system_tag = COLL_TAG_GATHER;
-  MPI_Aint lb = 0;
-  MPI_Aint recvext = 0;
-
-  int rank = comm->rank();
-  int size = comm->size();
-  if(rank != root) {
-    // Send buffer to root
-    Request::send(sendbuf, sendcount, sendtype, root, system_tag, comm);
-  } else {
-    recvtype->extent(&lb, &recvext);
-    // Local copy from root
-    Datatype::copy(sendbuf, sendcount, sendtype, static_cast<char*>(recvbuf) + root * recvcount * recvext,
-                       recvcount, recvtype);
-    // Receive buffers from senders
-    MPI_Request *requests = xbt_new(MPI_Request, size - 1);
-    int index = 0;
-    for (int src = 0; src < size; src++) {
-      if(src != root) {
-        requests[index] = Request::irecv_init(static_cast<char*>(recvbuf) + src * recvcount * recvext, recvcount, recvtype,
-                                          src, system_tag, comm);
-        index++;
-      }
-    }
-    // Wait for completion of irecv's.
-    Request::startall(size - 1, requests);
-    Request::waitall(size - 1, requests, MPI_STATUS_IGNORE);
-    for (int src = 0; src < size-1; src++) {
-      Request::unref(&requests[src]);
-    }
-    xbt_free(requests);
-  }
-  return MPI_SUCCESS;
+  MPI_Request request;
+  Colls::igather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, &request);
+  return Request::wait(&request, MPI_STATUS_IGNORE);
 }
 
 int Coll_reduce_scatter_default::reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op,
@@ -87,186 +57,45 @@ int Coll_reduce_scatter_default::reduce_scatter(void *sendbuf, void *recvbuf, in
 int Coll_allgather_default::allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                         void *recvbuf,int recvcount, MPI_Datatype recvtype, MPI_Comm comm)
 {
-  const int system_tag = COLL_TAG_ALLGATHER;
-  MPI_Aint lb = 0;
-  MPI_Aint recvext = 0;
-  MPI_Request *requests;
-
-  int rank = comm->rank();
-  int size = comm->size();
-  // FIXME: check for errors
-  recvtype->extent(&lb, &recvext);
-  // Local copy from self
-  Datatype::copy(sendbuf, sendcount, sendtype, static_cast<char *>(recvbuf) + rank * recvcount * recvext, recvcount,
-                     recvtype);
-  // Send/Recv buffers to/from others;
-  requests = xbt_new(MPI_Request, 2 * (size - 1));
-  int index = 0;
-  for (int other = 0; other < size; other++) {
-    if(other != rank) {
-      requests[index] = Request::isend_init(sendbuf, sendcount, sendtype, other, system_tag,comm);
-      index++;
-      requests[index] = Request::irecv_init(static_cast<char *>(recvbuf) + other * recvcount * recvext, recvcount, recvtype,
-                                        other, system_tag, comm);
-      index++;
-    }
-  }
-  // Wait for completion of all comms.
-  Request::startall(2 * (size - 1), requests);
-  Request::waitall(2 * (size - 1), requests, MPI_STATUS_IGNORE);
-  for (int other = 0; other < 2*(size-1); other++) {
-    Request::unref(&requests[other]);
-  }
-  xbt_free(requests);
-  return MPI_SUCCESS;
+  MPI_Request request;
+  Colls::iallgather(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, &request);
+  return Request::wait(&request, MPI_STATUS_IGNORE);
 }
 
 int Coll_allgatherv_default::allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf,
                          int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
 {
-  const int system_tag = COLL_TAG_ALLGATHERV;
-  MPI_Aint lb = 0;
-  MPI_Aint recvext = 0;
-
-  int rank = comm->rank();
-  int size = comm->size();
-  recvtype->extent(&lb, &recvext);
-  // Local copy from self
-  Datatype::copy(sendbuf, sendcount, sendtype,
-                     static_cast<char *>(recvbuf) + displs[rank] * recvext,recvcounts[rank], recvtype);
-  // Send buffers to others;
-  MPI_Request *requests = xbt_new(MPI_Request, 2 * (size - 1));
-  int index = 0;
-  for (int other = 0; other < size; other++) {
-    if(other != rank) {
-      requests[index] =
-        Request::isend_init(sendbuf, sendcount, sendtype, other, system_tag, comm);
-      index++;
-      requests[index] = Request::irecv_init(static_cast<char *>(recvbuf) + displs[other] * recvext, recvcounts[other],
-                          recvtype, other, system_tag, comm);
-      index++;
-    }
-  }
-  // Wait for completion of all comms.
-  Request::startall(2 * (size - 1), requests);
-  Request::waitall(2 * (size - 1), requests, MPI_STATUS_IGNORE);
-  for (int other = 0; other < 2*(size-1); other++) {
+  MPI_Request request;
+  Colls::iallgatherv(sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm, &request);
+  MPI_Request* requests = request->get_nbc_requests();
+  int count = request->get_nbc_requests_size();
+  Request::waitall(count, requests, MPI_STATUS_IGNORE);
+  for (int other = 0; other < count; other++) {
     Request::unref(&requests[other]);
   }
-  xbt_free(requests);
+  delete[] requests;
+  Request::unref(&request);
   return MPI_SUCCESS;
 }
 
 int Coll_scatter_default::scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                       void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
 {
-  const int system_tag = COLL_TAG_SCATTER;
-  MPI_Aint lb = 0;
-  MPI_Aint sendext = 0;
-  MPI_Request *requests;
-
-  int rank = comm->rank();
-  int size = comm->size();
-  if(rank != root) {
-    // Recv buffer from root
-    Request::recv(recvbuf, recvcount, recvtype, root, system_tag, comm, MPI_STATUS_IGNORE);
-  } else {
-    sendtype->extent(&lb, &sendext);
-    // Local copy from root
-    if(recvbuf!=MPI_IN_PLACE){
-        Datatype::copy(static_cast<char *>(sendbuf) + root * sendcount * sendext,
-                           sendcount, sendtype, recvbuf, recvcount, recvtype);
-    }
-    // Send buffers to receivers
-    requests = xbt_new(MPI_Request, size - 1);
-    int index = 0;
-    for(int dst = 0; dst < size; dst++) {
-      if(dst != root) {
-        requests[index] = Request::isend_init(static_cast<char *>(sendbuf) + dst * sendcount * sendext, sendcount, sendtype,
-                                          dst, system_tag, comm);
-        index++;
-      }
-    }
-    // Wait for completion of isend's.
-    Request::startall(size - 1, requests);
-    Request::waitall(size - 1, requests, MPI_STATUS_IGNORE);
-    for (int dst = 0; dst < size-1; dst++) {
-      Request::unref(&requests[dst]);
-    }
-    xbt_free(requests);
-  }
-  return MPI_SUCCESS;
+  MPI_Request request;
+  Colls::iscatter(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm, &request);
+  return Request::wait(&request, MPI_STATUS_IGNORE);
 }
 
-
-
 int Coll_reduce_default::reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root,
                      MPI_Comm comm)
 {
-  const int system_tag = COLL_TAG_REDUCE;
-  MPI_Aint lb = 0;
-  MPI_Aint dataext = 0;
-
-  char* sendtmpbuf = static_cast<char *>(sendbuf);
-
-  int rank = comm->rank();
-  int size = comm->size();
-  if (size <= 0)
-    return MPI_ERR_COMM;
   //non commutative case, use a working algo from openmpi
   if (op != MPI_OP_NULL && not op->is_commutative()) {
-    return Coll_reduce_ompi_basic_linear::reduce(sendtmpbuf, recvbuf, count, datatype, op, root, comm);
-  }
-
-  if( sendbuf == MPI_IN_PLACE ) {
-    sendtmpbuf = static_cast<char *>(smpi_get_tmp_sendbuffer(count*datatype->get_extent()));
-    Datatype::copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
-  }
-
-  if(rank != root) {
-    // Send buffer to root
-    Request::send(sendtmpbuf, count, datatype, root, system_tag, comm);
-  } else {
-    datatype->extent(&lb, &dataext);
-    // Local copy from root
-    if (sendtmpbuf != nullptr && recvbuf != nullptr)
-      Datatype::copy(sendtmpbuf, count, datatype, recvbuf, count, datatype);
-    // Receive buffers from senders
-    MPI_Request *requests = xbt_new(MPI_Request, size - 1);
-    void **tmpbufs = xbt_new(void *, size - 1);
-    int index = 0;
-    for (int src = 0; src < size; src++) {
-      if (src != root) {
-        tmpbufs[index] = smpi_get_tmp_sendbuffer(count * dataext);
-        requests[index] =
-          Request::irecv_init(tmpbufs[index], count, datatype, src, system_tag, comm);
-        index++;
-      }
-    }
-    // Wait for completion of irecv's.
-    Request::startall(size - 1, requests);
-    for (int src = 0; src < size - 1; src++) {
-      index = Request::waitany(size - 1, requests, MPI_STATUS_IGNORE);
-      XBT_DEBUG("finished waiting any request with index %d", index);
-      if(index == MPI_UNDEFINED) {
-        break;
-      }else{
-        Request::unref(&requests[index]);
-      }
-      if(op) /* op can be MPI_OP_NULL that does nothing */
-        if(op!=MPI_OP_NULL) op->apply( tmpbufs[index], recvbuf, &count, datatype);
-    }
-      for(index = 0; index < size - 1; index++) {
-        smpi_free_tmp_buffer(tmpbufs[index]);
-      }
-    xbt_free(tmpbufs);
-    xbt_free(requests);
-
-  }
-  if( sendbuf == MPI_IN_PLACE ) {
-    smpi_free_tmp_buffer(sendtmpbuf);
+    return Coll_reduce_ompi_basic_linear::reduce(sendbuf, recvbuf, count, datatype, op, root, comm);
   }
-  return MPI_SUCCESS;
+  MPI_Request request;
+  Colls::ireduce(sendbuf, recvbuf, count, datatype, op, root, comm, &request);
+  return Request::wait(&request, MPI_STATUS_IGNORE);
 }
 
 int Coll_allreduce_default::allreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
@@ -283,61 +112,12 @@ int Coll_alltoall_default::alltoall( void *sbuf, int scount, MPI_Datatype sdtype
   return Coll_alltoall_ompi::alltoall(sbuf, scount, sdtype, rbuf, rcount, rdtype, comm);
 }
 
-
-
 int Coll_alltoallv_default::alltoallv(void *sendbuf, int *sendcounts, int *senddisps, MPI_Datatype sendtype,
                               void *recvbuf, int *recvcounts, int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm)
 {
-  const int system_tag = 889;
-  MPI_Aint lb = 0;
-  MPI_Aint sendext = 0;
-  MPI_Aint recvext = 0;
-  MPI_Request *requests;
-
-  /* Initialize. */
-  int rank = comm->rank();
-  int size = comm->size();
-  XBT_DEBUG("<%d> algorithm basic_alltoallv() called.", rank);
-  sendtype->extent(&lb, &sendext);
-  recvtype->extent(&lb, &recvext);
-  /* Local copy from self */
-  int err = Datatype::copy(static_cast<char *>(sendbuf) + senddisps[rank] * sendext, sendcounts[rank], sendtype,
-                               static_cast<char *>(recvbuf) + recvdisps[rank] * recvext, recvcounts[rank], recvtype);
-  if (err == MPI_SUCCESS && size > 1) {
-    /* Initiate all send/recv to/from others. */
-    requests = xbt_new(MPI_Request, 2 * (size - 1));
-    int count = 0;
-    /* Create all receives that will be posted first */
-    for (int i = 0; i < size; ++i) {
-      if (i != rank && recvcounts[i] != 0) {
-        requests[count] = Request::irecv_init(static_cast<char *>(recvbuf) + recvdisps[i] * recvext,
-                                          recvcounts[i], recvtype, i, system_tag, comm);
-        count++;
-      }else{
-        XBT_DEBUG("<%d> skip request creation [src = %d, recvcounts[src] = %d]", rank, i, recvcounts[i]);
-      }
-    }
-    /* Now create all sends  */
-    for (int i = 0; i < size; ++i) {
-      if (i != rank && sendcounts[i] != 0) {
-      requests[count] = Request::isend_init(static_cast<char *>(sendbuf) + senddisps[i] * sendext,
-                                        sendcounts[i], sendtype, i, system_tag, comm);
-      count++;
-      }else{
-        XBT_DEBUG("<%d> skip request creation [dst = %d, sendcounts[dst] = %d]", rank, i, sendcounts[i]);
-      }
-    }
-    /* Wait for them all. */
-    Request::startall(count, requests);
-    XBT_DEBUG("<%d> wait for %d requests", rank, count);
-    Request::waitall(count, requests, MPI_STATUS_IGNORE);
-    for (int i = 0; i < count; i++) {
-      if(requests[i]!=MPI_REQUEST_NULL)
-        Request::unref(&requests[i]);
-    }
-    xbt_free(requests);
-  }
-  return err;
+  MPI_Request request;
+  Colls::ialltoallv(sendbuf, sendcounts, senddisps, sendtype, recvbuf, recvcounts, recvdisps, recvtype, comm, &request);
+  return Request::wait(&request, MPI_STATUS_IGNORE);
 }
 
 }
diff --git a/src/smpi/colls/smpi_nbc_impl.cpp b/src/smpi/colls/smpi_nbc_impl.cpp
new file mode 100644 (file)
index 0000000..6c234e6
--- /dev/null
@@ -0,0 +1,643 @@
+/* Asynchronous parts of the basic collective algorithms, meant to be used both for the naive default implementation, but also for non blocking collectives */
+
+/* Copyright (c) 2009-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 "colls_private.hpp"
+#include "src/smpi/include/smpi_actor.hpp"
+
+namespace simgrid{
+namespace smpi{
+
+
+int Colls::ibarrier(MPI_Comm comm, MPI_Request* request)
+{
+  int i;
+  int size = comm->size();
+  int rank = comm->rank();
+  MPI_Request* requests;
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, COLL_TAG_BARRIER, comm, MPI_REQ_PERSISTENT);
+  if (rank > 0) {
+    requests = new MPI_Request[2];
+    requests[0] = Request::isend (nullptr, 0, MPI_BYTE, 0,
+                             COLL_TAG_BARRIER,
+                             comm);
+    requests[1] = Request::irecv (nullptr, 0, MPI_BYTE, 0,
+                             COLL_TAG_BARRIER,
+                             comm);
+    (*request)->set_nbc_requests(requests, 2);
+  }
+  else {
+    requests = new MPI_Request[(size-1)*2];
+    for (i = 1; i < 2*size-1; i+=2) {
+        requests[i-1] = Request::irecv(nullptr, 0, MPI_BYTE, MPI_ANY_SOURCE,
+                                 COLL_TAG_BARRIER, comm
+                                 );
+        requests[i] = Request::isend(nullptr, 0, MPI_BYTE, (i+1)/2,
+                                 COLL_TAG_BARRIER,
+                                 comm
+                                 );
+    }
+    (*request)->set_nbc_requests(requests, 2*(size-1));
+  }
+  return MPI_SUCCESS;
+}
+
+int Colls::ibcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm, MPI_Request* request)
+{
+  int i;
+  int size = comm->size();
+  int rank = comm->rank();
+  MPI_Request* requests;
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, COLL_TAG_BCAST, comm, MPI_REQ_PERSISTENT);
+  if (rank != root) {
+    requests = new MPI_Request[1];
+    requests[0] = Request::irecv (buf, count, datatype, root,
+                             COLL_TAG_BCAST,
+                             comm);
+    (*request)->set_nbc_requests(requests, 1);
+  }
+  else {
+    requests = new MPI_Request[size-1];
+    int n = 0;
+    for (i = 0; i < size; i++) {
+      if(i!=root){
+        requests[n] = Request::isend(buf, count, datatype, i,
+                                 COLL_TAG_BCAST,
+                                 comm
+                                 );
+        n++;
+      }
+    }
+    (*request)->set_nbc_requests(requests, size-1);
+  }
+  return MPI_SUCCESS;
+}
+
+int Colls::iallgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                        void *recvbuf,int recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request* request)
+{
+
+  const int system_tag = COLL_TAG_ALLGATHER;
+  MPI_Aint lb = 0;
+  MPI_Aint recvext = 0;
+  MPI_Request *requests;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  // FIXME: check for errors
+  recvtype->extent(&lb, &recvext);
+  // Local copy from self
+  Datatype::copy(sendbuf, sendcount, sendtype, static_cast<char *>(recvbuf) + rank * recvcount * recvext, recvcount,
+                     recvtype);
+  // Send/Recv buffers to/from others;
+  requests = new MPI_Request[2 * (size - 1)];
+  int index = 0;
+  for (int other = 0; other < size; other++) {
+    if(other != rank) {
+      requests[index] = Request::isend_init(sendbuf, sendcount, sendtype, other, system_tag,comm);
+      index++;
+      requests[index] = Request::irecv_init(static_cast<char *>(recvbuf) + other * recvcount * recvext, recvcount, recvtype,
+                                        other, system_tag, comm);
+      index++;
+    }
+  }
+  Request::startall(2 * (size - 1), requests);
+  (*request)->set_nbc_requests(requests, 2 * (size - 1));
+  return MPI_SUCCESS;
+}
+
+int Colls::iscatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                      void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request* request)
+{
+  const int system_tag = COLL_TAG_SCATTER;
+  MPI_Aint lb = 0;
+  MPI_Aint sendext = 0;
+  MPI_Request *requests;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  if(rank != root) {
+    requests = new MPI_Request[1];
+    // Recv buffer from root
+    requests[0] = Request::irecv(recvbuf, recvcount, recvtype, root, system_tag, comm);
+    (*request)->set_nbc_requests(requests, 1);
+  } else {
+    sendtype->extent(&lb, &sendext);
+    // Local copy from root
+    if(recvbuf!=MPI_IN_PLACE){
+        Datatype::copy(static_cast<char *>(sendbuf) + root * sendcount * sendext,
+                           sendcount, sendtype, recvbuf, recvcount, recvtype);
+    }
+    // Send buffers to receivers
+    requests = new MPI_Request[size - 1];
+    int index = 0;
+    for(int dst = 0; dst < size; dst++) {
+      if(dst != root) {
+        requests[index] = Request::isend_init(static_cast<char *>(sendbuf) + dst * sendcount * sendext, sendcount, sendtype,
+                                          dst, system_tag, comm);
+        index++;
+      }
+    }
+    // Wait for completion of isend's.
+    Request::startall(size - 1, requests);
+    (*request)->set_nbc_requests(requests, size - 1);
+  }
+  return MPI_SUCCESS;
+}
+
+int Colls::iallgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf,
+                         int *recvcounts, int *displs, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request* request)
+{
+  const int system_tag = COLL_TAG_ALLGATHERV;
+  MPI_Aint lb = 0;
+  MPI_Aint recvext = 0;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  recvtype->extent(&lb, &recvext);
+  // Local copy from self
+  Datatype::copy(sendbuf, sendcount, sendtype,
+                     static_cast<char *>(recvbuf) + displs[rank] * recvext,recvcounts[rank], recvtype);
+  // Send buffers to others;
+  MPI_Request *requests = new MPI_Request[2 * (size - 1)];
+  int index = 0;
+  for (int other = 0; other < size; other++) {
+    if(other != rank) {
+      requests[index] =
+        Request::isend_init(sendbuf, sendcount, sendtype, other, system_tag, comm);
+      index++;
+      requests[index] = Request::irecv_init(static_cast<char *>(recvbuf) + displs[other] * recvext, recvcounts[other],
+                          recvtype, other, system_tag, comm);
+      index++;
+    }
+  }
+  // Wait for completion of all comms.
+  Request::startall(2 * (size - 1), requests);
+  (*request)->set_nbc_requests(requests, 2 * (size - 1));
+  return MPI_SUCCESS;
+}
+
+int Colls::ialltoall( void *sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request* request){
+int system_tag = COLL_TAG_ALLTOALL;
+  int i;
+  int count;
+  MPI_Aint lb = 0, sendext = 0, recvext = 0;
+  MPI_Request *requests;
+
+  /* Initialize. */
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  sendtype->extent(&lb, &sendext);
+  recvtype->extent(&lb, &recvext);
+  /* simple optimization */
+  int err = Datatype::copy(static_cast<char *>(sendbuf) + rank * sendcount * sendext, sendcount, sendtype,
+                               static_cast<char *>(recvbuf) + rank * recvcount * recvext, recvcount, recvtype);
+  if (err == MPI_SUCCESS && size > 1) {
+    /* Initiate all send/recv to/from others. */
+    requests = new MPI_Request[2 * (size - 1)];
+    /* Post all receives first -- a simple optimization */
+    count = 0;
+    for (i = (rank + 1) % size; i != rank; i = (i + 1) % size) {
+      requests[count] = Request::irecv_init(static_cast<char *>(recvbuf) + i * recvcount * recvext, recvcount,
+                                        recvtype, i, system_tag, comm);
+      count++;
+    }
+    /* Now post all sends in reverse order
+     *   - We would like to minimize the search time through message queue
+     *     when messages actually arrive in the order in which they were posted.
+     * TODO: check the previous assertion
+     */
+    for (i = (rank + size - 1) % size; i != rank; i = (i + size - 1) % size) {
+      requests[count] = Request::isend_init(static_cast<char *>(sendbuf) + i * sendcount * sendext, sendcount,
+                                        sendtype, i, system_tag, comm);
+      count++;
+    }
+    /* Wait for them all. */
+    Request::startall(count, requests);
+    (*request)->set_nbc_requests(requests, count);
+  }
+  return MPI_SUCCESS;
+}
+
+int Colls::ialltoallv(void *sendbuf, int *sendcounts, int *senddisps, MPI_Datatype sendtype,
+                              void *recvbuf, int *recvcounts, int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request){
+  const int system_tag = COLL_TAG_ALLTOALLV;
+  MPI_Aint lb = 0;
+  MPI_Aint sendext = 0;
+  MPI_Aint recvext = 0;
+  MPI_Request *requests;
+
+  /* Initialize. */
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  sendtype->extent(&lb, &sendext);
+  recvtype->extent(&lb, &recvext);
+  /* Local copy from self */
+  int err = Datatype::copy(static_cast<char *>(sendbuf) + senddisps[rank] * sendext, sendcounts[rank], sendtype,
+                               static_cast<char *>(recvbuf) + recvdisps[rank] * recvext, recvcounts[rank], recvtype);
+  if (err == MPI_SUCCESS && size > 1) {
+    /* Initiate all send/recv to/from others. */
+    requests = new MPI_Request[2 * (size - 1)];
+    int count = 0;
+    /* Create all receives that will be posted first */
+    for (int i = 0; i < size; ++i) {
+      if (i != rank) {
+        requests[count] = Request::irecv_init(static_cast<char *>(recvbuf) + recvdisps[i] * recvext,
+                                          recvcounts[i], recvtype, i, system_tag, comm);
+        count++;
+      }else{
+        XBT_DEBUG("<%d> skip request creation [src = %d, recvcounts[src] = %d]", rank, i, recvcounts[i]);
+      }
+    }
+    /* Now create all sends  */
+    for (int i = 0; i < size; ++i) {
+      if (i != rank) {
+      requests[count] = Request::isend_init(static_cast<char *>(sendbuf) + senddisps[i] * sendext,
+                                        sendcounts[i], sendtype, i, system_tag, comm);
+      count++;
+      }else{
+        XBT_DEBUG("<%d> skip request creation [dst = %d, sendcounts[dst] = %d]", rank, i, sendcounts[i]);
+      }
+    }
+    /* Wait for them all. */
+    Request::startall(count, requests);
+    (*request)->set_nbc_requests(requests, count);
+  }
+  return err;
+}
+
+int Colls::ialltoallw(void *sendbuf, int *sendcounts, int *senddisps, MPI_Datatype* sendtypes,
+                              void *recvbuf, int *recvcounts, int *recvdisps, MPI_Datatype* recvtypes, MPI_Comm comm, MPI_Request *request){
+  const int system_tag = COLL_TAG_ALLTOALLV;
+  MPI_Request *requests;
+
+  /* Initialize. */
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  /* Local copy from self */
+  int err = (sendcounts[rank]>0 && recvcounts[rank]) ? Datatype::copy(static_cast<char *>(sendbuf) + senddisps[rank], sendcounts[rank], sendtypes[rank],
+                               static_cast<char *>(recvbuf) + recvdisps[rank], recvcounts[rank], recvtypes[rank]): MPI_SUCCESS;
+  if (err == MPI_SUCCESS && size > 1) {
+    /* Initiate all send/recv to/from others. */
+    requests = new MPI_Request[2 * (size - 1)];
+    int count = 0;
+    /* Create all receives that will be posted first */
+    for (int i = 0; i < size; ++i) {
+      if (i != rank) {
+        requests[count] = Request::irecv_init(static_cast<char *>(recvbuf) + recvdisps[i],
+                                          recvcounts[i], recvtypes[i], i, system_tag, comm);
+        count++;
+      }else{
+        XBT_DEBUG("<%d> skip request creation [src = %d, recvcounts[src] = %d]", rank, i, recvcounts[i]);
+      }
+    }
+    /* Now create all sends  */
+    for (int i = 0; i < size; ++i) {
+      if (i != rank) {
+      requests[count] = Request::isend_init(static_cast<char *>(sendbuf) + senddisps[i] ,
+                                        sendcounts[i], sendtypes[i], i, system_tag, comm);
+      count++;
+      }else{
+        XBT_DEBUG("<%d> skip request creation [dst = %d, sendcounts[dst] = %d]", rank, i, sendcounts[i]);
+      }
+    }
+    /* Wait for them all. */
+    Request::startall(count, requests);
+    (*request)->set_nbc_requests(requests, count);
+  }
+  return err;
+}
+
+int Colls::igather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                     void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request)
+{
+  const int system_tag = COLL_TAG_GATHER;
+  MPI_Aint lb = 0;
+  MPI_Aint recvext = 0;
+  MPI_Request *requests;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  if(rank != root) {
+    // Send buffer to root
+    requests = new MPI_Request[1];
+    requests[0]=Request::isend(sendbuf, sendcount, sendtype, root, system_tag, comm);
+    (*request)->set_nbc_requests(requests, 1);
+  } else {
+    recvtype->extent(&lb, &recvext);
+    // Local copy from root
+    Datatype::copy(sendbuf, sendcount, sendtype, static_cast<char*>(recvbuf) + root * recvcount * recvext,
+                       recvcount, recvtype);
+    // Receive buffers from senders
+    requests = new MPI_Request[size - 1];
+    int index = 0;
+    for (int src = 0; src < size; src++) {
+      if(src != root) {
+        requests[index] = Request::irecv_init(static_cast<char*>(recvbuf) + src * recvcount * recvext, recvcount, recvtype,
+                                          src, system_tag, comm);
+        index++;
+      }
+    }
+    // Wait for completion of irecv's.
+    Request::startall(size - 1, requests);
+    (*request)->set_nbc_requests(requests, size - 1);
+  }
+  return MPI_SUCCESS;
+}
+
+int Colls::igatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcounts, int *displs,
+                      MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request)
+{
+  int system_tag = COLL_TAG_GATHERV;
+  MPI_Aint lb = 0;
+  MPI_Aint recvext = 0;
+  MPI_Request *requests;
+  
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  if (rank != root) {
+    // Send buffer to root
+    requests = new MPI_Request[1];
+    requests[0]=Request::isend(sendbuf, sendcount, sendtype, root, system_tag, comm);
+    (*request)->set_nbc_requests(requests, 1);
+  } else {
+    recvtype->extent(&lb, &recvext);
+    // Local copy from root
+    Datatype::copy(sendbuf, sendcount, sendtype, static_cast<char*>(recvbuf) + displs[root] * recvext,
+                       recvcounts[root], recvtype);
+    // Receive buffers from senders
+    requests = new MPI_Request[size - 1];
+    int index = 0;
+    for (int src = 0; src < size; src++) {
+      if(src != root) {
+        requests[index] = Request::irecv_init(static_cast<char*>(recvbuf) + displs[src] * recvext,
+                          recvcounts[src], recvtype, src, system_tag, comm);
+        index++;
+      }
+    }
+    // Wait for completion of irecv's.
+    Request::startall(size - 1, requests);
+    (*request)->set_nbc_requests(requests, size - 1);
+  }
+  return MPI_SUCCESS;
+}
+int Colls::iscatterv(void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcount,
+                       MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request)
+{
+  int system_tag = COLL_TAG_SCATTERV;
+  MPI_Aint lb = 0;
+  MPI_Aint sendext = 0;
+  MPI_Request* requests;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( nullptr, 0, MPI_BYTE,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+  if(rank != root) {
+    // Recv buffer from root
+    requests = new MPI_Request[1];
+    requests[0]=Request::irecv(recvbuf, recvcount, recvtype, root, system_tag, comm);
+    (*request)->set_nbc_requests(requests, 1);
+  } else {
+    sendtype->extent(&lb, &sendext);
+    // Local copy from root
+    if(recvbuf!=MPI_IN_PLACE){
+      Datatype::copy(static_cast<char *>(sendbuf) + displs[root] * sendext, sendcounts[root],
+                       sendtype, recvbuf, recvcount, recvtype);
+    }
+    // Send buffers to receivers
+    MPI_Request *requests = new MPI_Request[size - 1];
+    int index = 0;
+    for (int dst = 0; dst < size; dst++) {
+      if (dst != root) {
+        requests[index] = Request::isend_init(static_cast<char *>(sendbuf) + displs[dst] * sendext, sendcounts[dst],
+                            sendtype, dst, system_tag, comm);
+        index++;
+      }
+    }
+    // Wait for completion of isend's.
+    Request::startall(size - 1, requests);
+    (*request)->set_nbc_requests(requests, size - 1);
+  }
+  return MPI_SUCCESS;
+}
+
+int Colls::ireduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root,
+                     MPI_Comm comm, MPI_Request* request)
+{
+  const int system_tag = COLL_TAG_REDUCE;
+  MPI_Aint lb = 0;
+  MPI_Aint dataext = 0;
+  MPI_Request* requests;
+
+  char* sendtmpbuf = static_cast<char *>(sendbuf);
+
+  int rank = comm->rank();
+  int size = comm->size();
+
+  if (size <= 0)
+    return MPI_ERR_COMM;
+
+  if( sendbuf == MPI_IN_PLACE ) {
+    sendtmpbuf = static_cast<char *>(smpi_get_tmp_sendbuffer(count*datatype->get_extent()));
+    Datatype::copy(recvbuf, count, datatype,sendtmpbuf, count, datatype);
+  }
+
+  if(rank == root){
+    (*request) =  new Request( recvbuf, count, datatype,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
+  }
+  else
+    (*request) = new Request( nullptr, count, datatype,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT);
+
+  if(rank != root) {
+    // Send buffer to root
+    requests = new MPI_Request[1];
+    requests[0]=Request::isend(sendtmpbuf, count, datatype, root, system_tag, comm);
+    (*request)->set_nbc_requests(requests, 1);
+  } else {
+    datatype->extent(&lb, &dataext);
+    // Local copy from root
+    if (sendtmpbuf != nullptr && recvbuf != nullptr)
+      Datatype::copy(sendtmpbuf, count, datatype, recvbuf, count, datatype);
+    // Receive buffers from senders
+    MPI_Request *requests = new MPI_Request[size - 1];
+    int index = 0;
+    for (int src = 0; src < size; src++) {
+      if (src != root) {
+        requests[index] =
+          Request::irecv_init(smpi_get_tmp_sendbuffer(count * dataext), count, datatype, src, system_tag, comm);
+        index++;
+      }
+    }
+    // Wait for completion of irecv's.
+    Request::startall(size - 1, requests);
+    (*request)->set_nbc_requests(requests, size - 1);
+  }    
+  if( sendbuf == MPI_IN_PLACE ) {
+    smpi_free_tmp_buffer(sendtmpbuf);
+  }
+  return MPI_SUCCESS;
+}
+
+int Colls::iallreduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
+                      MPI_Op op, MPI_Comm comm, MPI_Request* request)
+{
+
+  const int system_tag = COLL_TAG_ALLREDUCE;
+  MPI_Aint lb = 0;
+  MPI_Aint dataext = 0;
+  MPI_Request *requests;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( recvbuf, count, datatype,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
+  // FIXME: check for errors
+  datatype->extent(&lb, &dataext);
+  // Local copy from self
+  Datatype::copy(sendbuf, count, datatype, recvbuf, count, datatype);
+  // Send/Recv buffers to/from others;
+  requests = new MPI_Request[2 * (size - 1)];
+  int index = 0;
+  for (int other = 0; other < size; other++) {
+    if(other != rank) {
+      requests[index] = Request::isend_init(sendbuf, count, datatype, other, system_tag,comm);
+      index++;
+      requests[index] = Request::irecv_init(smpi_get_tmp_sendbuffer(count * dataext), count, datatype,
+                                        other, system_tag, comm);
+      index++;
+    }
+  }
+  Request::startall(2 * (size - 1), requests);
+  (*request)->set_nbc_requests(requests, 2 * (size - 1));
+  return MPI_SUCCESS;
+}
+
+int Colls::iscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request* request)
+{
+  int system_tag = -888;
+  MPI_Aint lb      = 0;
+  MPI_Aint dataext = 0;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( recvbuf, count, datatype,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
+  datatype->extent(&lb, &dataext);
+
+  // Local copy from self
+  Datatype::copy(sendbuf, count, datatype, recvbuf, count, datatype);
+
+  // Send/Recv buffers to/from others
+  MPI_Request *requests = new MPI_Request[size - 1];
+  void **tmpbufs = xbt_new(void *, rank);
+  int index = 0;
+  for (int other = 0; other < rank; other++) {
+    tmpbufs[index] = smpi_get_tmp_sendbuffer(count * dataext);
+    requests[index] = Request::irecv_init(tmpbufs[index], count, datatype, other, system_tag, comm);
+    index++;
+  }
+  for (int other = rank + 1; other < size; other++) {
+    requests[index] = Request::isend_init(sendbuf, count, datatype, other, system_tag, comm);
+    index++;
+  }
+  // Wait for completion of all comms.
+  Request::startall(size - 1, requests);
+  (*request)->set_nbc_requests(requests, size - 1);
+  return MPI_SUCCESS;
+}
+
+int Colls::iexscan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request* request)
+{
+  int system_tag = -888;
+  MPI_Aint lb         = 0;
+  MPI_Aint dataext    = 0;
+  int rank = comm->rank();
+  int size = comm->size();
+  (*request) = new Request( recvbuf, count, datatype,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
+  datatype->extent(&lb, &dataext);
+  if(rank != 0)
+    memset(recvbuf, 0, count*dataext);
+
+  // Send/Recv buffers to/from others
+  MPI_Request *requests = new MPI_Request[size - 1];
+  void **tmpbufs = xbt_new(void *, rank);
+  int index = 0;
+  for (int other = 0; other < rank; other++) {
+    tmpbufs[index] = smpi_get_tmp_sendbuffer(count * dataext);
+    requests[index] = Request::irecv_init(tmpbufs[index], count, datatype, other, system_tag, comm);
+    index++;
+  }
+  for (int other = rank + 1; other < size; other++) {
+    requests[index] = Request::isend_init(sendbuf, count, datatype, other, system_tag, comm);
+    index++;
+  }
+  // Wait for completion of all comms.
+  Request::startall(size - 1, requests);
+  (*request)->set_nbc_requests(requests, size - 1);
+  return MPI_SUCCESS;
+}
+
+int Colls::ireduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op,
+                             MPI_Comm comm, MPI_Request* request){
+//Version where each process performs the reduce for its own part. Alltoall pattern for comms.
+  const int system_tag = COLL_TAG_REDUCE_SCATTER;
+  MPI_Aint lb = 0;
+  MPI_Aint dataext = 0;
+  MPI_Request *requests;
+
+  int rank = comm->rank();
+  int size = comm->size();
+  int count=recvcounts[rank];
+  (*request) = new Request( recvbuf, count, datatype,
+                         rank,rank, system_tag, comm, MPI_REQ_PERSISTENT, op);
+  datatype->extent(&lb, &dataext);
+
+  // Send/Recv buffers to/from others;
+  requests = new MPI_Request[2 * (size - 1)];
+  int index = 0;
+  int recvdisp=0;
+  for (int other = 0; other < size; other++) {
+    if(other != rank) {
+      requests[index] = Request::isend_init(static_cast<char *>(sendbuf) + recvdisp * dataext, recvcounts[other], datatype, other, system_tag,comm);
+      XBT_VERB("sending with recvdisp %d", recvdisp);
+      index++;
+      requests[index] = Request::irecv_init(smpi_get_tmp_sendbuffer(count * dataext), count, datatype,
+                                        other, system_tag, comm);
+      index++;
+    }else{
+      Datatype::copy(static_cast<char *>(sendbuf) + recvdisp * dataext, count, datatype, recvbuf, count, datatype);
+    }
+    recvdisp+=recvcounts[other];
+  }
+  Request::startall(2 * (size - 1), requests);
+  (*request)->set_nbc_requests(requests, 2 * (size - 1));
+  return MPI_SUCCESS;
+}
+
+}
+}
index c588ce0..fbf827a 100644 (file)
@@ -17,13 +17,15 @@ constexpr unsigned MPI_REQ_PERSISTENT     = 0x1;
 constexpr unsigned MPI_REQ_NON_PERSISTENT = 0x2;
 constexpr unsigned MPI_REQ_SEND           = 0x4;
 constexpr unsigned MPI_REQ_RECV           = 0x8;
-// constexpr unsigned MPI_REQ_RECV_DELETE    = 0x10;
+constexpr unsigned MPI_REQ_RECV_DELETE    = 0x10;
 constexpr unsigned MPI_REQ_ISEND          = 0x20;
 constexpr unsigned MPI_REQ_SSEND          = 0x40;
 constexpr unsigned MPI_REQ_PREPARED       = 0x80;
 constexpr unsigned MPI_REQ_FINISHED       = 0x100;
 constexpr unsigned MPI_REQ_RMA            = 0x200;
 constexpr unsigned MPI_REQ_ACCUMULATE     = 0x400;
+constexpr unsigned MPI_REQ_GENERALIZED    = 0x800;
+constexpr unsigned MPI_REQ_COMPLETE       = 0x1000;
 
 enum class SmpiProcessState { UNINITIALIZED, INITIALIZING, INITIALIZED, FINALIZED };
 
@@ -43,6 +45,8 @@ constexpr int COLL_TAG_ALLREDUCE      = -4445;
 // SMPI_RMA_TAG has to be the smallest one, as it will be decremented for accumulate ordering.
 constexpr int SMPI_RMA_TAG            = -6666;
 
+#define MPI_REQUEST_IGNORED ((MPI_Request*)-100)
+
 /* Convert between Fortran and C */
 
 #define FORT_BOTTOM(addr) ((*(int*)addr) == -200 ? MPI_BOTTOM : (void*)addr)
index 0299f6c..e4c5df3 100644 (file)
@@ -115,6 +115,47 @@ public:
                       MPI_Datatype recvtype, int root, MPI_Comm comm);
   static int scan(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
   static int exscan(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm);
+  static int alltoallw
+         (void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype* sendtypes, void* recvbuf, int* recvcounts,
+          int* recvdisps, MPI_Datatype* recvtypes, MPI_Comm comm);
+
+  //async collectives
+  static int ibarrier(MPI_Comm comm, MPI_Request* request);
+  static int ibcast(void *buf, int count, MPI_Datatype datatype, 
+                   int root, MPI_Comm comm, MPI_Request* request);
+  static int igather (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount,
+                                      MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request);
+  static int igatherv (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                       int* recvcounts, int* displs, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request);
+  static int iallgather (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                         int recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request);
+  static int iallgatherv (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                          int* recvcounts, int* displs, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request);
+  static int iscatter (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                       int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request);
+  static int iscatterv (void* sendbuf, int* sendcounts, int* displs, MPI_Datatype sendtype,
+                                        void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, MPI_Request *request);
+  static int ireduce
+         (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, MPI_Request *request);
+  static int iallreduce
+         (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request);
+  static int iscan
+         (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request);
+  static int iexscan
+         (void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request);
+  static int ireduce_scatter
+         (void* sendbuf, void* recvbuf, int* recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request);
+  static int ireduce_scatter_block
+         (void* sendbuf, void* recvbuf, int recvcount, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request);
+  static int ialltoall (void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf,
+                                        int recvcount, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request);
+  static int ialltoallv
+         (void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype sendtype, void* recvbuf, int* recvcounts,
+          int* recvdisps, MPI_Datatype recvtype, MPI_Comm comm, MPI_Request *request);
+  static int ialltoallw
+         (void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype* sendtypes, void* recvbuf, int* recvcounts,
+          int* recvdisps, MPI_Datatype* recvtypes, MPI_Comm comm, MPI_Request *request);
+
 
   static void (*smpi_coll_cleanup_callback)();
 };
index 5354177..c0eb212 100644 (file)
@@ -16,6 +16,7 @@ class Op : public F2C{
   MPI_User_function* func_;
   bool is_commutative_;
   bool is_fortran_op_ = false;
+  int refcount_ = 1;
 
 public:
   Op(MPI_User_function* function, bool commutative) : func_(function), is_commutative_(commutative) {}
@@ -25,6 +26,8 @@ public:
   void set_fortran_op() { is_fortran_op_ = true; }
   void apply(void* invec, void* inoutvec, int* len, MPI_Datatype datatype);
   static Op* f2c(int id);
+  void ref();
+  static void unref(MPI_Op* op);
 };
 
 }
index 4876237..a4fa0d5 100644 (file)
 namespace simgrid{
 namespace smpi{
 
+typedef struct s_smpi_mpi_generalized_request_funcs {
+  MPI_Grequest_query_function *query_fn;
+  MPI_Grequest_free_function *free_fn;
+  MPI_Grequest_cancel_function *cancel_fn;
+  void* extra_state;
+  s4u::ConditionVariablePtr cond;
+  s4u::MutexPtr mutex;
+} s_smpi_mpi_generalized_request_funcs_t; 
+typedef struct s_smpi_mpi_generalized_request_funcs *smpi_mpi_generalized_request_funcs;
+
 class Request : public F2C {
   void* buf_;
   /* in the case of non-contiguous memory the user address should be keep
@@ -38,10 +48,13 @@ class Request : public F2C {
   int refcount_;
   MPI_Op op_;
   int cancelled_;
+  smpi_mpi_generalized_request_funcs generalized_funcs;
+  MPI_Request* nbc_requests_;
+  int nbc_requests_size_;
 
 public:
   Request() = default;
-  Request(void* buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags);
+  Request(void* buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags, MPI_Op op = MPI_REPLACE);
   MPI_Comm comm() { return comm_; }
   size_t size() { return size_; }
   size_t real_size() { return real_size_; }
@@ -55,9 +68,12 @@ public:
   void start();
   void cancel();
   void ref();
+  void set_nbc_requests(MPI_Request* reqs, int size);
+  int get_nbc_requests_size();
+  MPI_Request* get_nbc_requests();
   static void finish_wait(MPI_Request* request, MPI_Status* status);
   static void unref(MPI_Request* request);
-  static void wait(MPI_Request* req, MPI_Status* status);
+  static int wait(MPI_Request* req, MPI_Status* status);
   static MPI_Request send_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static MPI_Request isend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
   static MPI_Request ssend_init(void* buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm);
@@ -80,10 +96,10 @@ public:
 
   static void startall(int count, MPI_Request* requests);
 
-  static int test(MPI_Request* request, MPI_Status* status);
-  static int testsome(int incount, MPI_Request requests[], int* indices, MPI_Status status[]);
-  static int testany(int count, MPI_Request requests[], int* index, MPI_Status* status);
-  static int testall(int count, MPI_Request requests[], MPI_Status status[]);
+  static int test(MPI_Request* request, MPI_Status* status, int* flag);
+  static int testsome(int incount, MPI_Request requests[], int* outcounts, int* indices, MPI_Status status[]);
+  static int testany(int count, MPI_Request requests[], int* index, int* flag, MPI_Status* status);
+  static int testall(int count, MPI_Request requests[], int* flag, MPI_Status status[]);
 
   static void probe(int source, int tag, MPI_Comm comm, MPI_Status* status);
   static void iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status);
@@ -95,6 +111,10 @@ public:
   static int match_send(void* a, void* b, kernel::activity::CommImpl* ignored);
   static int match_recv(void* a, void* b, kernel::activity::CommImpl* ignored);
 
+  static int grequest_start( MPI_Grequest_query_function *query_fn, MPI_Grequest_free_function *free_fn, MPI_Grequest_cancel_function *cancel_fn, void *extra_state, MPI_Request *request);
+  static int grequest_complete( MPI_Request request);
+  static int get_status(MPI_Request req, int* flag, MPI_Status * status);
+
   int add_f() override;
   static void free_f(int id);
   static Request* f2c(int);
index 4a9ddd4..4018f9e 100644 (file)
@@ -18,6 +18,8 @@ class Status{
 public:
 static void empty(MPI_Status * status);
 static int cancelled (MPI_Status * status);
+static void set_cancelled (MPI_Status * status, int flag);
+static void set_elements (MPI_Status * status, MPI_Datatype , int count);
 static int get_count(MPI_Status * status, MPI_Datatype datatype);
 };
 
index e0aef7d..e657ab9 100644 (file)
@@ -19,10 +19,7 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_process, smpi, "Logging specific to SMPI (k
 namespace simgrid {
 namespace smpi {
 
-using simgrid::s4u::Actor;
-using simgrid::s4u::ActorPtr;
-
-ActorExt::ActorExt(ActorPtr actor, simgrid::s4u::Barrier* finalization_barrier)
+ActorExt::ActorExt(s4u::ActorPtr actor, s4u::Barrier* finalization_barrier)
     : finalization_barrier_(finalization_barrier), actor_(actor)
 {
   mailbox_         = s4u::Mailbox::by_name("SMPI-" + std::to_string(actor_->get_pid()));
@@ -124,7 +121,7 @@ bool ActorExt::replaying()
   return replaying_;
 }
 
-ActorPtr ActorExt::get_actor()
+s4u::ActorPtr ActorExt::get_actor()
 {
   return actor_;
 }
index 70def16..26aafa4 100644 (file)
@@ -71,11 +71,9 @@ std::string papi_default_config_name = "default";
 std::map</* computation unit name */ std::string, papi_process_data> units2papi_setup;
 #endif
 
-using simgrid::s4u::Actor;
-using simgrid::s4u::ActorPtr;
 std::unordered_map<std::string, double> location2speedup;
 
-static std::map</*process_id*/ ActorPtr, simgrid::smpi::ActorExt*> process_data;
+static std::map</*process_id*/ simgrid::s4u::Actor const*, simgrid::smpi::ActorExt*> process_data;
 int process_count = 0;
 static int smpi_exit_status = 0;
 int smpi_universe_size = 0;
@@ -112,17 +110,17 @@ int smpi_process_count()
 
 simgrid::smpi::ActorExt* smpi_process()
 {
-  ActorPtr me = Actor::self();
+  simgrid::s4u::ActorPtr me = simgrid::s4u::Actor::self();
 
   if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...)
     return nullptr;
 
-  return process_data.at(me);
+  return process_data.at(me.get());
 }
 
-simgrid::smpi::ActorExt* smpi_process_remote(ActorPtr actor)
+simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor)
 {
-  return process_data.at(actor);
+  return process_data.at(actor.get());
 }
 
 MPI_Comm smpi_process_comm_self(){
@@ -134,11 +132,11 @@ void smpi_process_init(int *argc, char ***argv){
 }
 
 void * smpi_process_get_user_data(){
-  return Actor::self()->get_impl()->get_user_data();
+  return simgrid::s4u::Actor::self()->get_impl()->get_user_data();
 }
 
 void smpi_process_set_user_data(void *data){
-  Actor::self()->get_impl()->set_user_data(data);
+  simgrid::s4u::Actor::self()->get_impl()->set_user_data(data);
 }
 
 
@@ -720,13 +718,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::ActorPtr actor) {
-    if (not actor->is_daemon()) {
-      process_data.insert({actor, new simgrid::smpi::ActorExt(actor, nullptr)});
+  simgrid::s4u::Actor::on_creation.connect([](simgrid::s4u::Actor& actor) {
+    if (not actor.is_daemon()) {
+      process_data.insert({&actor, new simgrid::smpi::ActorExt(&actor, nullptr)});
     }
   });
-  simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::ActorPtr actor) {
-    auto it = process_data.find(actor);
+  simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::Actor const& actor) {
+    auto it = process_data.find(&actor);
     if (it != process_data.end()) {
       delete it->second;
       process_data.erase(it);
index 878b3b1..9d3aae3 100644 (file)
@@ -493,7 +493,8 @@ void TestAction::kernel(simgrid::xbt::ReplayAction&)
     TRACE_smpi_comm_in(my_proc_id, __func__, new simgrid::instr::NoOpTIData("test"));
 
     MPI_Status status;
-    int flag = Request::test(&request, &status);
+    int flag = 0;
+    Request::test(&request, &status, &flag);
 
     XBT_DEBUG("MPI_Test result: %d", flag);
     /* push back request in vector to be caught by a subsequent wait. if the test did succeed, the request is now
index c9ddb5a..b2ca92d 100644 (file)
@@ -18,8 +18,6 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_comm, smpi, "Logging specific to SMPI (comm
 simgrid::smpi::Comm mpi_MPI_COMM_UNINITIALIZED;
 MPI_Comm MPI_COMM_UNINITIALIZED=&mpi_MPI_COMM_UNINITIALIZED;
 
-using simgrid::s4u::ActorPtr;
-
 /* Support for cartesian topology was added, but there are 2 other types of topology, graph et dist graph. In order to
  * support them, we have to add a field SMPI_Topo_type, and replace the MPI_Topology field by an union. */
 
@@ -54,7 +52,7 @@ void Comm::destroy(Comm* comm)
 int Comm::dup(MPI_Comm* newcomm){
   if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
-    smpi_switch_data_segment(simgrid::s4u::Actor::self());
+    smpi_switch_data_segment(s4u::Actor::self());
   }
   MPI_Group cp = new  Group(this->group());
   (*newcomm)   = new  Comm(cp, this->topo());
@@ -111,7 +109,7 @@ int Comm::rank()
 {
   if (this == MPI_COMM_UNINITIALIZED)
     return smpi_process()->comm_world()->rank();
-  return group_->rank(simgrid::s4u::Actor::self());
+  return group_->rank(s4u::Actor::self());
 }
 
 void Comm::get_name (char* name, int* len)
@@ -224,7 +222,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++) {
-          ActorPtr actor = group->actor(rankmap[j].second);
+          s4u::ActorPtr actor = group->actor(rankmap[j].second);
           group_out->set_mapping(actor, j);
         }
         MPI_Request* requests = xbt_new(MPI_Request, rankmap.size());
@@ -305,7 +303,7 @@ void Comm::init_smp(){
 
   if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
-    smpi_switch_data_segment(simgrid::s4u::Actor::self());
+    smpi_switch_data_segment(s4u::Actor::self());
   }
   //identify neighbours in comm
   //get the indices of all processes sharing the same simix host
@@ -342,7 +340,7 @@ void Comm::init_smp(){
 
   if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
-    smpi_switch_data_segment(simgrid::s4u::Actor::self());
+    smpi_switch_data_segment(s4u::Actor::self());
   }
 
   if(leaders_map_==nullptr){
@@ -371,7 +369,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(simgrid::s4u::Actor::by_pid(leader_list[i]), i);
+      leaders_group->set_mapping(s4u::Actor::by_pid(leader_list[i]), i);
     leader_comm = new  Comm(leaders_group, nullptr,1);
     this->set_leaders_comm(leader_comm);
     this->set_intra_comm(comm_intra);
@@ -379,7 +377,7 @@ void Comm::init_smp(){
     // create intracommunicator
   }else{
     for (i=0; i< leader_group_size;i++)
-      leaders_group->set_mapping(simgrid::s4u::Actor::by_pid(leader_list[i]), i);
+      leaders_group->set_mapping(s4u::Actor::by_pid(leader_list[i]), i);
 
     if(this->get_leaders_comm()==MPI_COMM_NULL){
       leader_comm = new  Comm(leaders_group, nullptr,1);
@@ -415,7 +413,7 @@ void Comm::init_smp(){
 
   if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) {
     // we need to switch as the called function may silently touch global variables
-    smpi_switch_data_segment(simgrid::s4u::Actor::self());
+    smpi_switch_data_segment(s4u::Actor::self());
   }
   // Are the ranks blocked ? = allocated contiguously on the SMP nodes
   int is_blocked=1;
index 9cce9ba..8d7a457 100644 (file)
@@ -123,7 +123,7 @@ Datatype::Datatype(char* name, int ident, int size, MPI_Aint lb, MPI_Aint ub, in
 #endif
 }
 
-Datatype::Datatype(Datatype *datatype, int* ret) : name_(nullptr), lb_(datatype->lb_), ub_(datatype->ub_), flags_(datatype->flags_), refcount_(1)
+Datatype::Datatype(Datatype *datatype, int* ret) : name_(nullptr), size_(datatype->size_), lb_(datatype->lb_), ub_(datatype->ub_), flags_(datatype->flags_), refcount_(1)
 {
   flags_ &= ~DT_FLAG_PREDEFINED;
   *ret = MPI_SUCCESS;
index a6e92a9..f8eb81c 100644 (file)
@@ -17,8 +17,6 @@ MPI_Group MPI_GROUP_EMPTY=&mpi_MPI_GROUP_EMPTY;
 namespace simgrid{
 namespace smpi{
 
-using simgrid::s4u::ActorPtr;
-
 Group::Group(Group* origin)
 {
   if (origin != MPI_GROUP_NULL && origin != MPI_GROUP_EMPTY) {
@@ -30,7 +28,7 @@ Group::Group(Group* origin)
   }
 }
 
-void Group::set_mapping(simgrid::s4u::ActorPtr actor, int rank)
+void Group::set_mapping(s4u::ActorPtr actor, int rank)
 {
   if (0 <= rank && rank < size_) {
     int index                = actor->get_pid();
@@ -58,14 +56,16 @@ int Group::rank(int index)
   return rank;
 }
 
-simgrid::s4u::ActorPtr Group::actor(int rank) {
+s4u::ActorPtr Group::actor(int rank)
+{
   if (0 <= rank && rank < size_)
     return rank_to_actor_map_[rank];
   else
     return nullptr;
 }
 
-int Group::rank(const simgrid::s4u::ActorPtr actor) {
+int Group::rank(const s4u::ActorPtr actor)
+{
   auto iterator = actor_to_rank_map_.find(actor);
   return (iterator == actor_to_rank_map_.end()) ? MPI_UNDEFINED : (*iterator).second;
 }
@@ -92,7 +92,7 @@ int Group::compare(MPI_Group group2)
     result = MPI_UNEQUAL;
   } else {
     for (int i = 0; i < size_; i++) {
-      ActorPtr actor = this->actor(i);
+      s4u::ActorPtr actor = this->actor(i);
       int rank = group2->rank(actor);
       if (rank == MPI_UNDEFINED) {
         result = MPI_UNEQUAL;
@@ -118,7 +118,7 @@ int Group::incl(int n, int* ranks, MPI_Group* newgroup)
   } else {
     *newgroup = new Group(n);
     for (i = 0; i < n; i++) {
-      ActorPtr actor = this->actor(ranks[i]); // ranks[] was passed as a param!
+      s4u::ActorPtr actor = this->actor(ranks[i]); // ranks[] was passed as a param!
       (*newgroup)->set_mapping(actor, i);
     }
   }
@@ -130,7 +130,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++) {
-    ActorPtr actor = group2->actor(i);
+    s4u::ActorPtr actor = group2->actor(i);
     int proc1 = this->rank(actor);
     if (proc1 == MPI_UNDEFINED) {
       size1++;
@@ -142,11 +142,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++) {
-      ActorPtr actor1 = this->actor(i);
+      s4u::ActorPtr actor1 = this->actor(i);
       (*newgroup)->set_mapping(actor1, i);
     }
     for (int i = size2; i < size1; i++) {
-      ActorPtr actor = group2->actor(i - size2);
+      s4u::ActorPtr actor = group2->actor(i - size2);
       (*newgroup)->set_mapping(actor, i);
     }
   }
@@ -157,7 +157,7 @@ int Group::intersection(MPI_Group group2, MPI_Group* newgroup)
 {
   int size2 = group2->size();
   for (int i = 0; i < size2; i++) {
-    ActorPtr actor = group2->actor(i);
+    s4u::ActorPtr actor = group2->actor(i);
     int proc1 = this->rank(actor);
     if (proc1 == MPI_UNDEFINED) {
       size2--;
@@ -169,7 +169,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++) {
-      ActorPtr actor = group2->actor(i);
+      s4u::ActorPtr actor = group2->actor(i);
       int proc1 = this->rank(actor);
       if (proc1 != MPI_UNDEFINED) {
         (*newgroup)->set_mapping(actor, j);
@@ -185,7 +185,7 @@ int Group::difference(MPI_Group group2, MPI_Group* newgroup)
   int newsize = size_;
   int size2 = size_;
   for (int i = 0; i < size2; i++) {
-    ActorPtr actor = this->actor(i);
+    s4u::ActorPtr actor = this->actor(i);
     int proc2 = group2->rank(actor);
     if (proc2 != MPI_UNDEFINED) {
       newsize--;
@@ -196,7 +196,7 @@ int Group::difference(MPI_Group group2, MPI_Group* newgroup)
   } else {
     *newgroup = new  Group(newsize);
     for (int i = 0; i < size2; i++) {
-      ActorPtr actor = this->actor(i);
+      s4u::ActorPtr actor = this->actor(i);
       int proc2 = group2->rank(actor);
       if (proc2 == MPI_UNDEFINED) {
         (*newgroup)->set_mapping(actor, i);
@@ -218,7 +218,7 @@ int Group::excl(int n, int *ranks, MPI_Group * newgroup){
   int j = 0;
   for (int i = 0; i < oldsize; i++) {
     if(to_exclude[i]==0){
-      ActorPtr actor = this->actor(i);
+      s4u::ActorPtr actor = this->actor(i);
       (*newgroup)->set_mapping(actor, j);
       j++;
     }
@@ -257,7 +257,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 */
          ) {
-      ActorPtr actor = this->actor(rank);
+      s4u::ActorPtr actor = this->actor(rank);
       (*newgroup)->set_mapping(actor, j);
       j++;
       if(rank == ranges[i][1]){/*already last ?*/
@@ -309,7 +309,7 @@ int Group::range_excl(int n, int ranges[][3], MPI_Group * newgroup){
         }
       }
       if(add==1){
-        ActorPtr actor = this->actor(oldrank);
+        s4u::ActorPtr actor = this->actor(oldrank);
         (*newgroup)->set_mapping(actor, newrank);
         newrank++;
       }
index e81b93f..bb52d0e 100644 (file)
@@ -242,5 +242,17 @@ Op* Op::f2c(int id){
   return static_cast<Op*>(F2C::f2c(id));
 }
 
+void Op::ref(){
+  refcount_++;
+}
+
+void Op::unref(MPI_Op* op){
+  if((*op)!=MPI_OP_NULL){
+    (*op)->refcount_--;
+    if((*op)->refcount_==0)
+      delete(*op);
+  }
+}
+
 }
 }
index 759f0f5..47b37fe 100644 (file)
@@ -2,7 +2,8 @@
 
 /* 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/Mutex.hpp"
+#include "simgrid/s4u/ConditionVariable.hpp"
 #include "smpi_request.hpp"
 
 #include "mc/mc.h"
@@ -18,6 +19,7 @@
 #include "src/smpi/include/smpi_actor.hpp"
 #include "xbt/config.hpp"
 
+
 #include <algorithm>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_request, smpi, "Logging specific to SMPI (request)");
@@ -34,8 +36,8 @@ extern void (*smpi_comm_copy_data_callback)(simgrid::kernel::activity::CommImpl*
 namespace simgrid{
 namespace smpi{
 
-Request::Request(void* buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags)
-    : buf_(buf), old_type_(datatype), src_(src), dst_(dst), tag_(tag), comm_(comm), flags_(flags)
+Request::Request(void* buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags, MPI_Op op)
+    : buf_(buf), old_type_(datatype), src_(src), dst_(dst), tag_(tag), comm_(comm), flags_(flags), op_(op)
 {
   void *old_buf = nullptr;
 // FIXME Handle the case of a partial shared malloc.
@@ -56,6 +58,8 @@ Request::Request(void* buf, int count, MPI_Datatype datatype, int src, int dst,
   size_ = datatype->size() * count;
   datatype->ref();
   comm_->ref();
+  if(op != MPI_REPLACE && op != MPI_OP_NULL)
+    op_->ref();
   action_          = nullptr;
   detached_        = 0;
   detached_sender_ = nullptr;
@@ -67,8 +71,10 @@ Request::Request(void* buf, int count, MPI_Datatype datatype, int src, int dst,
     refcount_ = 1;
   else
     refcount_ = 0;
-  op_   = MPI_REPLACE;
   cancelled_ = 0;
+  generalized_funcs=nullptr;
+  nbc_requests_=nullptr;
+  nbc_requests_size_=0;
 }
 
 void Request::ref(){
@@ -84,11 +90,18 @@ void Request::unref(MPI_Request* request)
       xbt_die("Whoops, wrong refcount");
     }
     if((*request)->refcount_==0){
-        Datatype::unref((*request)->old_type_);
+      if ((*request)->flags_ & MPI_REQ_GENERALIZED){
+        ((*request)->generalized_funcs)->free_fn(((*request)->generalized_funcs)->extra_state);
+      }else{
         Comm::unref((*request)->comm_);
-        (*request)->print_request("Destroying");
-        delete *request;
-        *request = MPI_REQUEST_NULL;
+        Datatype::unref((*request)->old_type_);
+      }
+      if ((*request)->op_!=MPI_REPLACE && (*request)->op_!=MPI_OP_NULL)
+        Op::unref(&(*request)->op_);
+
+      (*request)->print_request("Destroying");
+      delete *request;
+      *request = MPI_REQUEST_NULL;
     }else{
       (*request)->print_request("Decrementing");
     }
@@ -192,8 +205,7 @@ MPI_Request Request::rma_send_init(void *buf, int count, MPI_Datatype datatype,
     request      = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, comm->group()->actor(src)->get_pid(),
                           comm->group()->actor(dst)->get_pid(), tag, comm,
                           MPI_REQ_RMA | MPI_REQ_NON_PERSISTENT | MPI_REQ_ISEND | MPI_REQ_SEND | MPI_REQ_PREPARED |
-                              MPI_REQ_ACCUMULATE);
-    request->op_ = op;
+                              MPI_REQ_ACCUMULATE, op);
   }
   return request;
 }
@@ -217,8 +229,7 @@ MPI_Request Request::rma_recv_init(void *buf, int count, MPI_Datatype datatype,
   }else{
     request      = new Request(buf == MPI_BOTTOM ? nullptr : buf, count, datatype, comm->group()->actor(src)->get_pid(),
                           comm->group()->actor(dst)->get_pid(), tag, comm,
-                          MPI_REQ_RMA | MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PREPARED | MPI_REQ_ACCUMULATE);
-    request->op_ = op;
+                          MPI_REQ_RMA | MPI_REQ_NON_PERSISTENT | MPI_REQ_RECV | MPI_REQ_PREPARED | MPI_REQ_ACCUMULATE, op);
   }
   return request;
 }
@@ -506,28 +517,59 @@ void Request::cancel()
     (boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(this->action_))->cancel();
 }
 
-int Request::test(MPI_Request * request, MPI_Status * status) {
+int Request::test(MPI_Request * request, MPI_Status * status, int* flag) {
   //assume that request is not MPI_REQUEST_NULL (filtered in PMPI_Test or testall before)
   // to avoid deadlocks if used as a break condition, such as
   //     while (MPI_Test(request, flag, status) && flag) dostuff...
   // because the time will not normally advance when only calls to MPI_Test are made -> deadlock
   // multiplier to the sleeptime, to increase speed of execution, each failed test will increase it
   static int nsleeps = 1;
+  int ret = MPI_SUCCESS;
+  
+  // Are we testing a request meant for non blocking collectives ?
+  // If so, test all the subrequests.
+  if ((*request)->nbc_requests_size_>0){
+    ret = testall((*request)->nbc_requests_size_, (*request)->nbc_requests_, flag, MPI_STATUSES_IGNORE);
+    if(*flag){
+      delete[] (*request)->nbc_requests_;
+      (*request)->nbc_requests_size_=0;
+      unref(request);
+    }
+    return ret;
+  }
+  
   if(smpi_test_sleep > 0)
     simcall_process_sleep(nsleeps*smpi_test_sleep);
 
+  MPI_Status* mystatus;
   Status::empty(status);
-  int flag = 1;
+  *flag = 1;
   if (((*request)->flags_ & MPI_REQ_PREPARED) == 0) {
     if ((*request)->action_ != nullptr){
       try{
-        flag = simcall_comm_test((*request)->action_);
+        *flag = simcall_comm_test((*request)->action_);
       }catch (xbt_ex& e) {
-        return 0;
+        *flag = 0;
+        return ret;
       }
     }
-    if (flag) {
+    if (*request != MPI_REQUEST_NULL && 
+        ((*request)->flags_ & MPI_REQ_GENERALIZED)
+        && !((*request)->flags_ & MPI_REQ_COMPLETE)) 
+      *flag=0;
+    if (*flag) {
       finish_wait(request,status);
+      if (*request != MPI_REQUEST_NULL && ((*request)->flags_ & MPI_REQ_GENERALIZED)){
+        if(status==MPI_STATUS_IGNORE){
+          mystatus=new MPI_Status();
+          Status::empty(mystatus);
+        }else{
+          mystatus=status;
+        }
+        ret = ((*request)->generalized_funcs)->query_fn(((*request)->generalized_funcs)->extra_state, mystatus);
+        if(status==MPI_STATUS_IGNORE) 
+          delete mystatus;
+      }
       nsleeps=1;//reset the number of sleeps we will do next time
       if (*request != MPI_REQUEST_NULL && ((*request)->flags_ & MPI_REQ_PERSISTENT) == 0)
         *request = MPI_REQUEST_NULL;
@@ -535,21 +577,27 @@ int Request::test(MPI_Request * request, MPI_Status * status) {
       nsleeps++;
     }
   }
-  return flag;
+  return ret;
 }
 
-int Request::testsome(int incount, MPI_Request requests[], int *indices, MPI_Status status[])
+int Request::testsome(int incount, MPI_Request requests[], int *count, int *indices, MPI_Status status[])
 {
-  int count = 0;
+  int ret = MPI_SUCCESS;
+  int error=0;
   int count_dead = 0;
+  int flag = 0;
   MPI_Status stat;
   MPI_Status *pstat = status == MPI_STATUSES_IGNORE ? MPI_STATUS_IGNORE : &stat;
 
+  *count = 0;
   for (int i = 0; i < incount; i++) {
     if (requests[i] != MPI_REQUEST_NULL) {
-      if (test(&requests[i], pstat)) {
+      ret = test(&requests[i], pstat, &flag);
+      if(ret!=MPI_SUCCESS)
+        error = 1;
+      if(flag) {
         indices[i] = 1;
-        count++;
+        (*count)++;
         if (status != MPI_STATUSES_IGNORE)
           status[i] = *pstat;
         if ((requests[i] != MPI_REQUEST_NULL) && (requests[i]->flags_ & MPI_REQ_NON_PERSISTENT))
@@ -559,19 +607,22 @@ int Request::testsome(int incount, MPI_Request requests[], int *indices, MPI_Sta
       count_dead++;
     }
   }
-  if(count_dead==incount)
-    return MPI_UNDEFINED;
-  else return count;
+  if(count_dead==incount)*count=MPI_UNDEFINED;
+  if(error!=0)
+    return MPI_ERR_IN_STATUS;
+  else
+    return MPI_SUCCESS;
 }
 
-int Request::testany(int count, MPI_Request requests[], int *index, MPI_Status * status)
+int Request::testany(int count, MPI_Request requests[], int *index, int* flag, MPI_Status * status)
 {
   std::vector<simgrid::kernel::activity::CommImpl*> comms;
   comms.reserve(count);
 
   int i;
-  int flag = 0;
-
+  *flag = 0;
+  int ret = MPI_SUCCESS;
+  MPI_Status* mystatus;
   *index = MPI_UNDEFINED;
 
   std::vector<int> map; /** Maps all matching comms back to their location in requests **/
@@ -594,36 +645,59 @@ int Request::testany(int count, MPI_Request requests[], int *index, MPI_Status *
     
     if (i != -1) { // -1 is not MPI_UNDEFINED but a SIMIX return code. (nothing matches)
       *index = map[i];
-      finish_wait(&requests[*index],status);
-      flag             = 1;
-      nsleeps          = 1;
-      if (requests[*index] != MPI_REQUEST_NULL && (requests[*index]->flags_ & MPI_REQ_NON_PERSISTENT)) {
-        requests[*index] = MPI_REQUEST_NULL;
+      if (requests[*index] != MPI_REQUEST_NULL && 
+          (requests[*index]->flags_ & MPI_REQ_GENERALIZED)
+          && !(requests[*index]->flags_ & MPI_REQ_COMPLETE)) {
+        *flag=0;
+      } else {
+        finish_wait(&requests[*index],status);
+      if (requests[*index] != MPI_REQUEST_NULL && (requests[*index]->flags_ & MPI_REQ_GENERALIZED)){
+        if(status==MPI_STATUS_IGNORE){
+          mystatus=new MPI_Status();
+          Status::empty(mystatus);
+        }else{
+          mystatus=status;
+        }
+        ret=(requests[*index]->generalized_funcs)->query_fn((requests[*index]->generalized_funcs)->extra_state, mystatus);
+        if(status==MPI_STATUS_IGNORE) 
+          delete mystatus;
+      }
+
+        if (requests[*index] != MPI_REQUEST_NULL && (requests[*index]->flags_ & MPI_REQ_NON_PERSISTENT)) 
+          requests[*index] = MPI_REQUEST_NULL;
+        *flag=1;
       }
+      nsleeps = 1;
     } else {
       nsleeps++;
     }
   } else {
       //all requests are null or inactive, return true
-      flag = 1;
+      *flag = 1;
       Status::empty(status);
   }
 
-  return flag;
+  return ret;
 }
 
-int Request::testall(int count, MPI_Request requests[], MPI_Status status[])
+int Request::testall(int count, MPI_Request requests[], int* outflag, MPI_Status status[])
 {
   MPI_Status stat;
   MPI_Status *pstat = status == MPI_STATUSES_IGNORE ? MPI_STATUS_IGNORE : &stat;
-  int flag=1;
+  int flag, error=0;
+  int ret=MPI_SUCCESS;
+  *outflag = 1;
   for(int i=0; i<count; i++){
     if (requests[i] != MPI_REQUEST_NULL && not(requests[i]->flags_ & MPI_REQ_PREPARED)) {
-      if (test(&requests[i], pstat)!=1){
+      ret = test(&requests[i], pstat, &flag);
+      if (flag){
         flag=0;
+        requests[i]=MPI_REQUEST_NULL;
       }else{
-          requests[i]=MPI_REQUEST_NULL;
+        *outflag=0;
       }
+      if (ret != MPI_SUCCESS) 
+        error = 1;
     }else{
       Status::empty(pstat);
     }
@@ -631,7 +705,10 @@ int Request::testall(int count, MPI_Request requests[], MPI_Status status[])
       status[i] = *pstat;
     }
   }
-  return flag;
+  if(error==1) 
+    return MPI_ERR_IN_STATUS;
+  else 
+    return MPI_SUCCESS;
 }
 
 void Request::probe(int source, int tag, MPI_Comm comm, MPI_Status* status){
@@ -720,7 +797,9 @@ void Request::finish_wait(MPI_Request* request, MPI_Status * status)
     return;
   }
 
-  if (not((req->detached_ != 0) && ((req->flags_ & MPI_REQ_SEND) != 0)) && ((req->flags_ & MPI_REQ_PREPARED) == 0)) {
+  if (not((req->detached_ != 0) && ((req->flags_ & MPI_REQ_SEND) != 0)) 
+  && ((req->flags_ & MPI_REQ_PREPARED) == 0)
+  && ((req->flags_ & MPI_REQ_GENERALIZED) == 0)) {
     if(status != MPI_STATUS_IGNORE) {
       int src = req->src_ == MPI_ANY_SOURCE ? req->real_src_ : req->src_;
       status->MPI_SOURCE = req->comm_->group()->rank(src);
@@ -780,12 +859,39 @@ void Request::finish_wait(MPI_Request* request, MPI_Status * status)
   unref(request);
 }
 
-void Request::wait(MPI_Request * request, MPI_Status * status)
+int Request::wait(MPI_Request * request, MPI_Status * status)
 {
+  int ret=MPI_SUCCESS;
+  // Are we waiting on a request meant for non blocking collectives ?
+  // If so, wait for all the subrequests.
+  if ((*request)->nbc_requests_size_>0){
+    ret = waitall((*request)->nbc_requests_size_, (*request)->nbc_requests_, MPI_STATUSES_IGNORE);
+    for (int i = 0; i < (*request)->nbc_requests_size_; i++) {
+      if((*request)->buf_!=nullptr && (*request)->nbc_requests_[i]!=MPI_REQUEST_NULL){//reduce case
+        void * buf=(*request)->nbc_requests_[i]->buf_;
+        if((*request)->old_type_->flags() & DT_FLAG_DERIVED)
+          buf=(*request)->nbc_requests_[i]->old_buf_;
+        if((*request)->nbc_requests_[i]->flags_ & MPI_REQ_RECV ){
+          if((*request)->op_!=MPI_OP_NULL){
+            int count=(*request)->size_/ (*request)->old_type_->size();
+            (*request)->op_->apply(buf, (*request)->buf_, &count, (*request)->old_type_);
+          }
+          smpi_free_tmp_buffer(buf);
+        }
+      }
+      if((*request)->nbc_requests_[i]!=MPI_REQUEST_NULL)
+        Request::unref(&((*request)->nbc_requests_[i]));
+    }
+    delete[] (*request)->nbc_requests_;
+    (*request)->nbc_requests_size_=0;
+    unref(request);
+    return ret;
+  }
+
   (*request)->print_request("Waiting");
   if ((*request)->flags_ & MPI_REQ_PREPARED) {
     Status::empty(status);
-    return;
+    return ret;
   }
 
   if ((*request)->action_ != nullptr){
@@ -797,10 +903,28 @@ void Request::wait(MPI_Request * request, MPI_Status * status)
       }
   }
 
+  if (*request != MPI_REQUEST_NULL && ((*request)->flags_ & MPI_REQ_GENERALIZED)){
+    MPI_Status* mystatus;
+    if(!((*request)->flags_ & MPI_REQ_COMPLETE)){
+      ((*request)->generalized_funcs)->mutex->lock();
+      ((*request)->generalized_funcs)->cond->wait(((*request)->generalized_funcs)->mutex);
+      ((*request)->generalized_funcs)->mutex->unlock();
+      }
+    if(status==MPI_STATUS_IGNORE){
+      mystatus=new MPI_Status();
+      Status::empty(mystatus);
+    }else{
+      mystatus=status;
+    }
+    ret = ((*request)->generalized_funcs)->query_fn(((*request)->generalized_funcs)->extra_state, mystatus);
+    if(status==MPI_STATUS_IGNORE) 
+      delete mystatus;
+  }
 
   finish_wait(request,status);
   if (*request != MPI_REQUEST_NULL && (((*request)->flags_ & MPI_REQ_NON_PERSISTENT) != 0))
     *request = MPI_REQUEST_NULL;
+  return ret;
 }
 
 int Request::waitany(int count, MPI_Request requests[], MPI_Status * status)
@@ -922,21 +1046,30 @@ int Request::waitall(int count, MPI_Request requests[], MPI_Status status[])
 int Request::waitsome(int incount, MPI_Request requests[], int *indices, MPI_Status status[])
 {
   int count = 0;
+  int flag = 0;
+  int index = 0;
   MPI_Status stat;
   MPI_Status *pstat = status == MPI_STATUSES_IGNORE ? MPI_STATUS_IGNORE : &stat;
 
+  index = waitany(incount, (MPI_Request*)requests, pstat);
+  if(index==MPI_UNDEFINED) return MPI_UNDEFINED;
+  if(status != MPI_STATUSES_IGNORE) {
+    status[count] = *pstat;
+  }
+  indices[count] = index;
+  count++;
   for (int i = 0; i < incount; i++) {
-    int index = waitany(incount, requests, pstat);
-    if(index!=MPI_UNDEFINED){
-      indices[count] = index;
-      count++;
-      if(status != MPI_STATUSES_IGNORE) {
-        status[index] = *pstat;
+    if((requests[i] != MPI_REQUEST_NULL)) {
+      test(&requests[i], pstat,&flag);
+      if (flag==1){
+        indices[count] = i;
+        if(status != MPI_STATUSES_IGNORE) {
+          status[count] = *pstat;
+        }
+        if (requests[i] != MPI_REQUEST_NULL && (requests[i]->flags_ & MPI_REQ_NON_PERSISTENT))
+          requests[i]=MPI_REQUEST_NULL;
+        count++;
       }
-      if (requests[index] != MPI_REQUEST_NULL && (requests[index]->flags_ & MPI_REQ_NON_PERSISTENT))
-        requests[index] = MPI_REQUEST_NULL;
-    }else{
-      return MPI_UNDEFINED;
     }
   }
   return count;
@@ -968,5 +1101,72 @@ void Request::free_f(int id)
   }
 }
 
+
+int Request::get_status(MPI_Request req, int* flag, MPI_Status * status){
+  *flag=0;
+
+  if(req != MPI_REQUEST_NULL && req->action_ != nullptr) {
+    req->iprobe(req->src_, req->tag_, req->comm_, flag, status);
+    if(*flag)
+      return MPI_SUCCESS;
+  }
+  if (req != MPI_REQUEST_NULL && 
+     (req->flags_ & MPI_REQ_GENERALIZED)
+     && !(req->flags_ & MPI_REQ_COMPLETE)) {
+     *flag=0;
+    return MPI_SUCCESS;
+  }
+
+  *flag=1;
+  if(req != MPI_REQUEST_NULL &&
+     status != MPI_STATUS_IGNORE) {
+    int src = req->src_ == MPI_ANY_SOURCE ? req->real_src_ : req->src_;
+    status->MPI_SOURCE = req->comm_->group()->rank(src);
+    status->MPI_TAG = req->tag_ == MPI_ANY_TAG ? req->real_tag_ : req->tag_;
+    status->MPI_ERROR = req->truncated_ ? MPI_ERR_TRUNCATE : MPI_SUCCESS;
+    status->count = req->real_size_;
+  }
+  return MPI_SUCCESS;
+}
+
+int Request::grequest_start( MPI_Grequest_query_function *query_fn, MPI_Grequest_free_function *free_fn, MPI_Grequest_cancel_function *cancel_fn, void *extra_state, MPI_Request *request){
+
+  *request = new Request();
+  (*request)->flags_ |= MPI_REQ_GENERALIZED;
+  (*request)->flags_ |= MPI_REQ_PERSISTENT;
+  (*request)->refcount_ = 1;
+  ((*request)->generalized_funcs)=xbt_new0(s_smpi_mpi_generalized_request_funcs_t ,1);
+  ((*request)->generalized_funcs)->query_fn=query_fn;
+  ((*request)->generalized_funcs)->free_fn=free_fn;
+  ((*request)->generalized_funcs)->cancel_fn=cancel_fn;
+  ((*request)->generalized_funcs)->extra_state=extra_state;
+  ((*request)->generalized_funcs)->cond = simgrid::s4u::ConditionVariable::create();
+  ((*request)->generalized_funcs)->mutex = simgrid::s4u::Mutex::create();
+  return MPI_SUCCESS;
+}
+
+int Request::grequest_complete( MPI_Request request){
+  if ((!(request->flags_ & MPI_REQ_GENERALIZED)) || request->generalized_funcs->mutex==NULL) 
+    return MPI_ERR_REQUEST;
+  request->generalized_funcs->mutex->lock();
+  request->flags_ |= MPI_REQ_COMPLETE; // in case wait would be called after complete
+  request->generalized_funcs->cond->notify_one();
+  request->generalized_funcs->mutex->unlock();
+  return MPI_SUCCESS;
+}
+
+void Request::set_nbc_requests(MPI_Request* reqs, int size){
+  nbc_requests_=reqs;
+  nbc_requests_size_=size;
+}
+
+int Request::get_nbc_requests_size(){
+  return nbc_requests_size_;
+}
+
+MPI_Request* Request::get_nbc_requests(){
+  return nbc_requests_;
+}
+
 }
 }
index 0af84e2..22690e2 100644 (file)
@@ -27,6 +27,15 @@ int Status::cancelled(MPI_Status * status)
   return status->cancelled!=0;
 }
 
+void Status::set_cancelled(MPI_Status * status, int flag)
+{
+  status->cancelled=flag;
+}
+
+void Status::set_elements (MPI_Status * status, MPI_Datatype , int count){
+  status->count=count;
+}
+
 int Status::get_count(MPI_Status * status, MPI_Datatype datatype)
 {
   return status->count / datatype->size();
index 86059ca..84d748a 100644 (file)
@@ -16,7 +16,6 @@
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_rma, smpi, "Logging specific to SMPI (RMA operations)");
 
-using simgrid::s4u::Actor;
 
 namespace simgrid{
 namespace smpi{
@@ -40,7 +39,7 @@ Win::Win(void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm,
   connected_wins_[rank_] = this;
   count_                 = 0;
   if(rank_==0){
-    bar_ = new simgrid::s4u::Barrier(comm_size);
+    bar_ = new s4u::Barrier(comm_size);
   }
   mode_=0;
 
@@ -50,7 +49,7 @@ Win::Win(void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm,
   Colls::allgather(&(connected_wins_[rank_]), sizeof(MPI_Win), MPI_BYTE, connected_wins_, sizeof(MPI_Win),
                          MPI_BYTE, comm);
 
-  Colls::bcast(&(bar_), sizeof(simgrid::s4u::Barrier*), MPI_BYTE, 0, comm);
+  Colls::bcast(&(bar_), sizeof(s4u::Barrier*), MPI_BYTE, 0, comm);
 
   Colls::barrier(comm);
 }
index f18a911..e0e44e0 100644 (file)
@@ -5,11 +5,12 @@
 
 #include <simgrid/plugins/load_balancer.h>
 #include <simgrid/s4u/Actor.hpp>
-#include <src/smpi/include/smpi_comm.hpp>
+#include <src/instr/instr_smpi.hpp>
 #include <src/smpi/include/smpi_actor.hpp>
+#include <src/smpi/include/smpi_comm.hpp>
 #include <src/smpi/plugins/ampi/instr_ampi.hpp>
-#include <src/instr/instr_smpi.hpp>
 #include <xbt/replay.hpp>
+#include <xbt/sysdep.h>
 
 #include "ampi.hpp"
 #include <smpi/sampi.h>
@@ -24,7 +25,7 @@ extern "C" XBT_PUBLIC void* _sampi_calloc(size_t num_elm, size_t elem_size);
 extern "C" XBT_PUBLIC void* _sampi_realloc(void* ptr, size_t size);
 extern "C" void* _sampi_malloc(size_t size)
 {
-  void* result = malloc (size); // We need the space here to prevent recursive substitution
+  void* result = xbt_malloc(size);
   alloc_table.insert({result, size});
   if (not simgrid::s4u::this_actor::is_maestro()) {
     memory_size[simgrid::s4u::this_actor::get_pid()] += size;
@@ -37,12 +38,12 @@ extern "C" void _sampi_free(void* ptr)
   size_t alloc_size = alloc_table.at(ptr);
   int my_proc_id    = simgrid::s4u::this_actor::get_pid();
   memory_size[my_proc_id] -= alloc_size;
-  free(ptr);
+  xbt_free(ptr);
 }
 
 extern "C" void* _sampi_calloc(size_t num_elm, size_t elem_size)
 {
-  void* result = calloc (num_elm, elem_size); // We need the space here to prevent recursive substitution
+  void* result = xbt_malloc0(num_elm * elem_size);
   alloc_table.insert({result, num_elm * elem_size});
   if (not simgrid::s4u::this_actor::is_maestro()) {
     memory_size[simgrid::s4u::this_actor::get_pid()] += num_elm * elem_size;
@@ -51,7 +52,7 @@ extern "C" void* _sampi_calloc(size_t num_elm, size_t elem_size)
 }
 extern "C" void* _sampi_realloc(void* ptr, size_t size)
 {
-  void* result = realloc (ptr, size); // We need the space here to prevent recursive substitution
+  void* result = xbt_realloc(ptr, size);
   int old_size = alloc_table.at(ptr);
   alloc_table.erase(ptr);
   alloc_table.insert({result, size});
@@ -65,8 +66,8 @@ namespace simgrid {
 namespace smpi {
 namespace plugin {
 namespace ampi {
-  simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_iteration_in;
-  simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_iteration_out;
+simgrid::xbt::signal<void(simgrid::s4u::Actor const&)> on_iteration_in;
+simgrid::xbt::signal<void(simgrid::s4u::Actor const&)> on_iteration_out;
 }
 }
 }
index eef8a5a..b31fb73 100644 (file)
@@ -12,8 +12,8 @@ namespace simgrid {
 namespace smpi {
 namespace plugin {
 namespace ampi {
-  extern simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_iteration_out;
-  extern simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_iteration_in;
+extern simgrid::xbt::signal<void(simgrid::s4u::Actor const&)> on_iteration_out;
+extern simgrid::xbt::signal<void(simgrid::s4u::Actor const&)> on_iteration_in;
 }
 }
 }
index 3880e19..72a68ca 100644 (file)
@@ -112,7 +112,7 @@ void action_iteration_in(simgrid::xbt::ReplayAction& action)
 {
   CHECK_ACTION_PARAMS(action, 0, 0)
   TRACE_Iteration_in(simgrid::s4u::this_actor::get_pid(), nullptr);
-  simgrid::smpi::plugin::ampi::on_iteration_in(MPI_COMM_WORLD->group()->actor(std::stol(action[0])));
+  simgrid::smpi::plugin::ampi::on_iteration_in(*MPI_COMM_WORLD->group()->actor(std::stol(action[0])));
 }
 
 XBT_PRIVATE void action_iteration_out(simgrid::xbt::ReplayAction& action);
@@ -120,7 +120,7 @@ void action_iteration_out(simgrid::xbt::ReplayAction& action)
 {
   CHECK_ACTION_PARAMS(action, 0, 0)
   TRACE_Iteration_out(simgrid::s4u::this_actor::get_pid(), nullptr);
-  simgrid::smpi::plugin::ampi::on_iteration_out(MPI_COMM_WORLD->group()->actor(std::stol(action[0])));
+  simgrid::smpi::plugin::ampi::on_iteration_out(*MPI_COMM_WORLD->group()->actor(std::stol(action[0])));
 }
 }
 }
@@ -136,8 +136,9 @@ void sg_load_balancer_plugin_init()
   static bool done = false;
   if (!done) {
     done = true;
-    simgrid::kernel::activity::ExecImpl::on_completion.connect([](simgrid::kernel::activity::ExecImplPtr activity){
-        simgrid::smpi::plugin::lb.record_actor_computation(activity->simcalls_.front()->issuer->iface(), activity->surf_action_->get_cost());
+    simgrid::kernel::activity::ExecImpl::on_completion.connect([](simgrid::kernel::activity::ExecImpl const& activity) {
+      simgrid::smpi::plugin::lb.record_actor_computation(activity.simcalls_.front()->issuer->iface(),
+                                                         activity.surf_action_->get_cost());
     });
 
     xbt_replay_action_register(
index 8d28059..03c6264 100755 (executable)
@@ -35,6 +35,9 @@ Usage: $0 [OPTIONS] -platform <xmldesc> -hostfile <hostfile> program [program-op
 Options:
   -keep-temps                # don't remove the generated files after execution
   -wrapper <command>         # use command to run the program (e.g. "valgrind" or "gdb --args")
+  -gdb                       # run within GDB (-wrapper "gdb --args" -keep-temps)
+  -lldb                      # run within LLDB (-wrapper "lldb --" -keep-temps)
+  -vgdb                      # run within Valgrind+GDB (-wrapper "valgrind --vgdb=yes --vgdb-error=0" -keep-temps)
   -map                       # display the machine on which each process rank is mapped
   -np <numprocs>             # use that amount of processes from the hostfile.
                              # By default, all processes of the hostfile are used.
@@ -195,14 +198,32 @@ while true; do
             shift 1
             ;;
         "-keep-temps")
-           KEEP="true"
-           SIMOPTS="$SIMOPTS --cfg=smpi/keep-temps:yes"
+            KEEP="true"
+            SIMOPTS="$SIMOPTS --cfg=smpi/keep-temps:yes"
             shift 1
             ;;
         "-wrapper")
             WRAPPER="$2"
             shift 2
             ;;
+        "-gdb")
+            WRAPPER="gdb --args"
+            KEEP="true"
+            SIMOPTS="$SIMOPTS --cfg=smpi/keep-temps:yes"
+            shift 1
+            ;;
+        "-vgdb")
+            WRAPPER="valgrind --vgdb=yes --vgdb-error=0"
+            KEEP="true"
+            SIMOPTS="$SIMOPTS --cfg=smpi/keep-temps:yes"
+            shift 1
+            ;;
+        "-lldb")
+            WRAPPER="lldb --"
+            KEEP="true"
+            SIMOPTS="$SIMOPTS --cfg=smpi/keep-temps:yes"
+            shift 1
+            ;;
         "-help" | "--help" | "-h")
             usage
             exit 0
index 18c9ac6..9cdc554 100644 (file)
@@ -93,7 +93,7 @@ void StorageImpl::turn_off()
     s4u::Storage::on_state_change(this->piface_);
   }
 }
-xbt::signal<void(StorageAction*, kernel::resource::Action::State, kernel::resource::Action::State)>
+xbt::signal<void(StorageAction const&, kernel::resource::Action::State, kernel::resource::Action::State)>
     StorageAction::on_state_change;
 
 /**********
@@ -103,7 +103,7 @@ void StorageAction::set_state(Action::State state)
 {
   Action::State old = get_state();
   Action::set_state(state);
-  on_state_change(this, old, state);
+  on_state_change(*this, old, state);
 }
 } // namespace resource
 } // namespace kernel
index 70d8e4b..ff68774 100644 (file)
@@ -34,18 +34,6 @@ class StorageAction;
 /** @ingroup SURF_storage_interface
  * @brief The possible type of action for the storage component
  */
-/*************
- * Callbacks *
- *************/
-
-/** @ingroup SURF_callbacks
- * @brief Callbacks handler which emit the callbacks after StorageAction State changed *
- * @details Callback functions have the following signature: `void(StorageAction *action,
- * simgrid::kernel::resource::Action::State old, simgrid::kernel::resource::Action::State current)`
- */
-XBT_PUBLIC_DATA
-simgrid::xbt::signal<void(StorageAction*, kernel::resource::Action::State, kernel::resource::Action::State)>
-    on_state_change;
 
 /*********
  * Model *
@@ -135,7 +123,12 @@ private:
  */
 class StorageAction : public Action {
 public:
-  static xbt::signal<void(StorageAction*, Action::State, Action::State)> on_state_change;
+  /**
+   * @brief Callbacks handler which emit the callbacks after StorageAction State changed *
+   * @details Callback functions have the following signature: `void(StorageAction& action,
+   * simgrid::kernel::resource::Action::State old, simgrid::kernel::resource::Action::State current)`
+   */
+  static xbt::signal<void(StorageAction const&, Action::State, Action::State)> on_state_change;
 
   /**
    * @brief StorageAction constructor
index a82c956..114e9e1 100644 (file)
@@ -76,7 +76,7 @@ CpuCas01Model::~CpuCas01Model()
   surf_cpu_model_pm = nullptr;
 }
 
-Cpu* CpuCas01Model::create_cpu(simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core)
+Cpu* CpuCas01Model::create_cpu(simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core)
 {
   return new CpuCas01(this, host, speed_per_pstate, core);
 }
@@ -84,9 +84,10 @@ Cpu* CpuCas01Model::create_cpu(simgrid::s4u::Host* host, std::vector<double>* sp
 /************
  * Resource *
  ************/
-CpuCas01::CpuCas01(CpuCas01Model* model, simgrid::s4u::Host* host, std::vector<double>* speedPerPstate, int core)
-    : Cpu(model, host, model->get_maxmin_system()->constraint_new(this, core * speedPerPstate->front()), speedPerPstate,
-          core)
+CpuCas01::CpuCas01(CpuCas01Model* model, simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate,
+                   int core)
+    : Cpu(model, host, model->get_maxmin_system()->constraint_new(this, core * speed_per_pstate.front()),
+          speed_per_pstate, core)
 {
 }
 
index 23aa4aa..67ed574 100644 (file)
@@ -28,7 +28,7 @@ public:
   CpuCas01Model& operator=(const CpuCas01Model&) = delete;
   ~CpuCas01Model() override;
 
-  Cpu* create_cpu(simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core) override;
+  Cpu* create_cpu(simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core) override;
 };
 
 /************
@@ -37,7 +37,7 @@ public:
 
 class CpuCas01 : public Cpu {
 public:
-  CpuCas01(CpuCas01Model* model, simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core);
+  CpuCas01(CpuCas01Model* model, simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core);
   CpuCas01(const CpuCas01&) = delete;
   CpuCas01& operator=(const CpuCas01&) = delete;
   ~CpuCas01() override;
index c507a90..4452435 100644 (file)
@@ -51,35 +51,28 @@ void CpuModel::update_actions_state_full(double /*now*/, double delta)
 /************
  * Resource *
  ************/
-Cpu::Cpu(kernel::resource::Model* model, simgrid::s4u::Host* host, std::vector<double>* speedPerPstate, int core)
-    : Cpu(model, host, nullptr /*constraint*/, speedPerPstate, core)
+Cpu::Cpu(kernel::resource::Model* model, simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate,
+         int core)
+    : Cpu(model, host, nullptr /*constraint*/, speed_per_pstate, core)
 {
 }
 
 Cpu::Cpu(kernel::resource::Model* model, simgrid::s4u::Host* host, kernel::lmm::Constraint* constraint,
-         std::vector<double>* speedPerPstate, int core)
-    : Resource(model, host->get_cname(), constraint), core_count_(core), host_(host)
+         const std::vector<double>& speed_per_pstate, int core)
+    : Resource(model, host->get_cname(), constraint)
+    , core_count_(core)
+    , host_(host)
+    , speed_per_pstate_(speed_per_pstate)
 {
   xbt_assert(core > 0, "Host %s must have at least one core, not 0.", host->get_cname());
 
-  speed_.peak = speedPerPstate->front();
+  speed_.peak     = speed_per_pstate_.front();
   speed_.scale = 1;
   host->pimpl_cpu = this;
   xbt_assert(speed_.scale > 0, "Speed of host %s must be >0", host->get_cname());
-
-  // Copy the power peak array:
-  for (double const& value : *speedPerPstate) {
-    speed_per_pstate_.push_back(value);
-  }
-}
-
-Cpu::~Cpu()
-{
-  if (get_model() == surf_cpu_model_pm)
-    speed_per_pstate_.clear();
 }
 
-int Cpu::get_pstate_count()
+int Cpu::get_pstate_count() const
 {
   return speed_per_pstate_.size();
 }
@@ -98,12 +91,12 @@ void Cpu::set_pstate(int pstate_index)
   on_speed_change();
 }
 
-int Cpu::get_pstate()
+int Cpu::get_pstate() const
 {
   return pstate_;
 }
 
-double Cpu::get_pstate_peak_speed(int pstate_index)
+double Cpu::get_pstate_peak_speed(int pstate_index) const
 {
   xbt_assert((pstate_index <= static_cast<int>(speed_per_pstate_.size())),
              "Invalid parameters (pstate index out of bounds)");
@@ -111,7 +104,7 @@ double Cpu::get_pstate_peak_speed(int pstate_index)
   return speed_per_pstate_[pstate_index];
 }
 
-double Cpu::get_speed(double load)
+double Cpu::get_speed(double load) const
 {
   return load * speed_.peak;
 }
@@ -164,17 +157,17 @@ void CpuAction::update_remains_lazy(double now)
   set_last_value(get_variable()->get_value());
 }
 
-simgrid::xbt::signal<void(simgrid::surf::CpuAction*, kernel::resource::Action::State)> CpuAction::on_state_change;
+simgrid::xbt::signal<void(simgrid::surf::CpuAction const&, kernel::resource::Action::State)> CpuAction::on_state_change;
 
 void CpuAction::suspend(){
   Action::State previous = get_state();
-  on_state_change(this, previous);
+  on_state_change(*this, previous);
   Action::suspend();
 }
 
 void CpuAction::resume(){
   Action::State previous = get_state();
-  on_state_change(this, previous);
+  on_state_change(*this, previous);
   Action::resume();
 }
 
@@ -182,11 +175,12 @@ void CpuAction::set_state(Action::State state)
 {
   Action::State previous = get_state();
   Action::set_state(state);
-  on_state_change(this, previous);
+  on_state_change(*this, previous);
 }
 
 /** @brief returns a list of all CPUs that this action is using */
-std::list<Cpu*> CpuAction::cpus() {
+std::list<Cpu*> CpuAction::cpus() const
+{
   std::list<Cpu*> retlist;
   int llen = get_variable()->get_number_of_constraint();
 
index 93bc683..7ae6e58 100644 (file)
@@ -37,7 +37,7 @@ public:
    *                         This ignores any potential external load coming from a trace.
    * @param core The number of core of this Cpu
    */
-  virtual Cpu* create_cpu(simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core) = 0;
+  virtual Cpu* create_cpu(simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core) = 0;
 
   void update_actions_state_lazy(double now, double delta) override;
   void update_actions_state_full(double now, double delta) override;
@@ -62,8 +62,8 @@ public:
    * @param speedPerPstate Processor speed (in flop per second) for each pstate
    * @param core The number of core of this Cpu
    */
-  Cpu(simgrid::kernel::resource::Model * model, simgrid::s4u::Host * host, kernel::lmm::Constraint * constraint,
-      std::vector<double> * speedPerPstate, int core);
+  Cpu(simgrid::kernel::resource::Model* model, simgrid::s4u::Host* host, kernel::lmm::Constraint* constraint,
+      const std::vector<double>& speed_per_pstate, int core);
 
   /**
    * @brief Cpu constructor
@@ -73,12 +73,11 @@ public:
    * @param speedPerPstate Processor speed (in flop per second) for each pstate
    * @param core The number of core of this Cpu
    */
-  Cpu(simgrid::kernel::resource::Model * model, simgrid::s4u::Host * host, std::vector<double> * speedPerPstate,
+  Cpu(simgrid::kernel::resource::Model* model, simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate,
       int core);
 
   Cpu(const Cpu&) = delete;
   Cpu& operator=(const Cpu&) = delete;
-  ~Cpu();
 
   /**
    * @brief Execute some quantity of computation
@@ -117,7 +116,7 @@ public:
    *
    * If you want to know the amount of flops currently delivered, use  load = get_load()*get_speed_ratio()
    */
-  virtual double get_speed(double load);
+  virtual double get_speed(double load) const;
 
 protected:
   /** @brief Take speed changes (either load or max) into account */
@@ -131,11 +130,11 @@ public:
   virtual double get_speed_ratio();
 
   /** @brief Get the peak processor speed (in flops/s), at the specified pstate */
-  virtual double get_pstate_peak_speed(int pstate_index);
+  virtual double get_pstate_peak_speed(int pstate_index) const;
 
-  virtual int get_pstate_count();
+  virtual int get_pstate_count() const;
   virtual void set_pstate(int pstate_index);
-  virtual int get_pstate();
+  virtual int get_pstate() const;
 
   simgrid::s4u::Host* get_host() { return host_; }
 
@@ -144,7 +143,7 @@ private:
   simgrid::s4u::Host* host_;
 
   int pstate_ = 0;                       /*< Current pstate (index in the speed_per_pstate_)*/
-  std::vector<double> speed_per_pstate_; /*< List of supported CPU capacities (pstate related) */
+  const std::vector<double> speed_per_pstate_; /*< List of supported CPU capacities (pstate related) */
 
 public:
   /*< @brief Setup the trace file with availability events (peak speed changes due to external load).
@@ -166,13 +165,10 @@ protected:
 class XBT_PUBLIC CpuAction : public simgrid::kernel::resource::Action {
 public:
   /** @brief Signal emitted when the action state changes (ready/running/done, etc)
-   *  Signature: `void(CpuAction *action, simgrid::kernel::resource::Action::State previous)`
+   *  Signature: `void(CpuAction const& action, simgrid::kernel::resource::Action::State previous)`
    */
-  static simgrid::xbt::signal<void(simgrid::surf::CpuAction*, simgrid::kernel::resource::Action::State)> on_state_change;
-  /** @brief Signal emitted when the action share changes (amount of flops it gets)
-   *  Signature: `void(CpuAction *action)`
-   */
-  static simgrid::xbt::signal<void(simgrid::surf::CpuAction*)> on_share_change;
+  static simgrid::xbt::signal<void(simgrid::surf::CpuAction const&, simgrid::kernel::resource::Action::State)>
+      on_state_change;
 
   CpuAction(simgrid::kernel::resource::Model * model, double cost, bool failed) : Action(model, cost, failed) {}
   CpuAction(simgrid::kernel::resource::Model * model, double cost, bool failed, kernel::lmm::Variable* var)
@@ -183,7 +179,7 @@ public:
   void set_state(simgrid::kernel::resource::Action::State state) override;
 
   void update_remains_lazy(double now) override;
-  std::list<Cpu*> cpus();
+  std::list<Cpu*> cpus() const;
 
   void suspend() override;
   void resume() override;
index c29102b..2ef2169 100644 (file)
@@ -312,7 +312,7 @@ CpuTiModel::~CpuTiModel()
   surf_cpu_model_pm = nullptr;
 }
 
-Cpu* CpuTiModel::create_cpu(simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core)
+Cpu* CpuTiModel::create_cpu(simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core)
 {
   return new CpuTi(this, host, speed_per_pstate, core);
 }
@@ -351,12 +351,12 @@ void CpuTiModel::update_actions_state(double now, double /*delta*/)
 /************
  * Resource *
  ************/
-CpuTi::CpuTi(CpuTiModel *model, simgrid::s4u::Host *host, std::vector<double> *speedPerPstate, int core)
-  : Cpu(model, host, speedPerPstate, core)
+CpuTi::CpuTi(CpuTiModel* model, simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core)
+    : Cpu(model, host, speed_per_pstate, core)
 {
   xbt_assert(core == 1, "Multi-core not handled by this model yet");
 
-  speed_.peak = speedPerPstate->front();
+  speed_.peak = speed_per_pstate.front();
   XBT_DEBUG("CPU create: peak=%f", speed_.peak);
 
   speed_integrated_trace_ = new CpuTiTmgr(nullptr, 1 /*scale*/);
index 2b3dff1..f3cafa7 100644 (file)
@@ -102,7 +102,7 @@ typedef boost::intrusive::list<CpuTiAction, ActionTiListOptions > ActionTiList;
  ************/
 class CpuTi : public Cpu {
 public:
-  CpuTi(CpuTiModel* model, simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core);
+  CpuTi(CpuTiModel* model, simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core);
   CpuTi(const CpuTi&)            = delete;
   CpuTi& operator&(const CpuTi&) = delete;
   ~CpuTi() override;
@@ -147,7 +147,7 @@ public:
   CpuTiModel(const CpuTiModel&) = delete;
   CpuTiModel& operator=(const CpuTiModel&) = delete;
   ~CpuTiModel() override;
-  Cpu* create_cpu(simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core) override;
+  Cpu* create_cpu(simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core) override;
   double next_occuring_event(double now) override;
   void update_actions_state(double now, double delta) override;
 
index 2f78a0d..5bc6070 100644 (file)
@@ -296,7 +296,7 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz
   }
   XBT_OUT();
 
-  simgrid::s4u::Link::on_communicate(action, src, dst);
+  simgrid::s4u::Link::on_communicate(*action, src, dst);
   return action;
 }
 
index c8a5bcb..26ae955 100644 (file)
@@ -72,7 +72,7 @@ kernel::resource::Action* NetworkConstantModel::communicate(s4u::Host* src, s4u:
 {
   NetworkConstantAction* action = new NetworkConstantAction(this, size, sg_latency_factor);
 
-  simgrid::s4u::Link::on_communicate(action, src, dst);
+  simgrid::s4u::Link::on_communicate(*action, src, dst);
   return action;
 }
 
index 344cf11..afdd570 100644 (file)
@@ -14,7 +14,8 @@
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
 
-static void IB_create_host_callback(simgrid::s4u::Host& host){
+static void IB_create_host_callback(simgrid::s4u::Host const& host)
+{
   using simgrid::kernel::resource::IBNode;
   using simgrid::kernel::resource::NetworkIBModel;
 
@@ -27,24 +28,23 @@ static void IB_create_host_callback(simgrid::s4u::Host& host){
   ((NetworkIBModel*)surf_network_model)->active_nodes.insert({host.get_name(), act});
 }
 
-static void IB_action_state_changed_callback(simgrid::kernel::resource::NetworkAction* action,
+static void IB_action_state_changed_callback(simgrid::kernel::resource::NetworkAction& action,
                                              simgrid::kernel::resource::Action::State /*previous*/)
 {
   using simgrid::kernel::resource::IBNode;
   using simgrid::kernel::resource::NetworkIBModel;
 
-  if (action->get_state() != simgrid::kernel::resource::Action::State::FINISHED)
+  if (action.get_state() != simgrid::kernel::resource::Action::State::FINISHED)
     return;
-  std::pair<IBNode*,IBNode*> pair = ((NetworkIBModel*)surf_network_model)->active_comms[action];
-  XBT_DEBUG("IB callback - action %p finished", action);
-
-  ((NetworkIBModel*)surf_network_model)->updateIBfactors(action, pair.first, pair.second, 1);
+  std::pair<IBNode*, IBNode*> pair = ((NetworkIBModel*)surf_network_model)->active_comms[&action];
+  XBT_DEBUG("IB callback - action %p finished", &action);
 
-  ((NetworkIBModel*)surf_network_model)->active_comms.erase(action);
+  ((NetworkIBModel*)surf_network_model)->updateIBfactors(&action, pair.first, pair.second, 1);
 
+  ((NetworkIBModel*)surf_network_model)->active_comms.erase(&action);
 }
 
-static void IB_action_init_callback(simgrid::kernel::resource::NetworkAction* action, simgrid::s4u::Host* src,
+static void IB_action_init_callback(simgrid::kernel::resource::NetworkAction& action, simgrid::s4u::Host* src,
                                     simgrid::s4u::Host* dst)
 {
   simgrid::kernel::resource::NetworkIBModel* ibModel = (simgrid::kernel::resource::NetworkIBModel*)surf_network_model;
@@ -65,9 +65,9 @@ static void IB_action_init_callback(simgrid::kernel::resource::NetworkAction* ac
     throw std::out_of_range(std::string("Could not find '") + dst->get_cname() + "' active comms !");
   }
 
-  ibModel->active_comms[action]=std::make_pair(act_src, act_dst);
+  ibModel->active_comms[&action] = std::make_pair(act_src, act_dst);
 
-  ibModel->updateIBfactors(action, act_src, act_dst, 0);
+  ibModel->updateIBfactors(&action, act_src, act_dst, 0);
 }
 
 /*********
index 9bdcd82..530b483 100644 (file)
@@ -166,11 +166,11 @@ void NetworkAction::set_state(Action::State state)
   Action::State previous = get_state();
   Action::set_state(state);
   if (previous != state) // Trigger only if the state changed
-    s4u::Link::on_communication_state_change(this, previous);
+    s4u::Link::on_communication_state_change(*this, previous);
 }
 
 /** @brief returns a list of all Links that this action is using */
-std::list<LinkImpl*> NetworkAction::links()
+std::list<LinkImpl*> NetworkAction::links() const
 {
   std::list<LinkImpl*> retlist;
   int llen = get_variable()->get_number_of_constraint();
index de80df1..c3dbfc0 100644 (file)
@@ -198,7 +198,7 @@ public:
   NetworkAction(Model* model, double cost, bool failed, lmm::Variable* var) : Action(model, cost, failed, var){};
 
   void set_state(Action::State state) override;
-  virtual std::list<LinkImpl*> links();
+  virtual std::list<LinkImpl*> links() const;
 
   double latency_    = {};
   double lat_current_ = {};
index 0a71792..63c4a27 100644 (file)
@@ -64,32 +64,32 @@ NetPointNs3::NetPointNs3()
  * Callbacks *
  *************/
 
-static void clusterCreation_cb(simgrid::kernel::routing::ClusterCreationArgs* cluster)
+static void clusterCreation_cb(simgrid::kernel::routing::ClusterCreationArgs const& cluster)
 {
-  for (int const& i : *cluster->radicals) {
+  for (int const& i : *cluster.radicals) {
     // Routers don't create a router on the other end of the private link by themselves.
     // We just need this router to be given an ID so we create a temporary NetPointNS3 so that it gets one
     NetPointNs3* host_dst = new NetPointNs3();
 
     // Create private link
-    std::string host_id   = cluster->prefix + std::to_string(i) + cluster->suffix;
+    std::string host_id   = cluster.prefix + std::to_string(i) + cluster.suffix;
     NetPointNs3* host_src = simgrid::s4u::Host::by_name(host_id)->pimpl_netpoint->extension<NetPointNs3>();
     xbt_assert(host_src, "Cannot find a NS3 host of name %s", host_id.c_str());
 
     // Any NS3 route is symmetrical
-    ns3_add_link(host_src, host_dst, cluster->bw, cluster->lat);
+    ns3_add_link(host_src, host_dst, cluster.bw, cluster.lat);
 
     delete host_dst;
   }
 
   //Create link backbone
-  ns3_add_cluster(cluster->id.c_str(), cluster->bb_bw, cluster->bb_lat);
+  ns3_add_cluster(cluster.id.c_str(), cluster.bb_bw, cluster.bb_lat);
 }
 
 static void routeCreation_cb(bool symmetrical, simgrid::kernel::routing::NetPoint* src,
                              simgrid::kernel::routing::NetPoint* dst, simgrid::kernel::routing::NetPoint* gw_src,
                              simgrid::kernel::routing::NetPoint* gw_dst,
-                             std::vector<simgrid::kernel::resource::LinkImpl*>& link_list)
+                             std::vector<simgrid::kernel::resource::LinkImpl*> const& link_list)
 {
   if (link_list.size() == 1) {
     simgrid::kernel::resource::LinkNS3* link = static_cast<simgrid::kernel::resource::LinkNS3*>(link_list[0]);
@@ -159,9 +159,9 @@ NetworkNS3Model::NetworkNS3Model() : NetworkModel(Model::UpdateAlgo::FULL)
 
   ns3_initialize(ns3_tcp_model.get().c_str());
 
-  simgrid::kernel::routing::NetPoint::on_creation.connect([](simgrid::kernel::routing::NetPoint* pt) {
-    pt->extension_set<NetPointNs3>(new NetPointNs3());
-    XBT_VERB("SimGrid's %s is known as node %d within NS3", pt->get_cname(), pt->extension<NetPointNs3>()->node_num);
+  simgrid::kernel::routing::NetPoint::on_creation.connect([](simgrid::kernel::routing::NetPoint& pt) {
+    pt.extension_set<NetPointNs3>(new NetPointNs3());
+    XBT_VERB("SimGrid's %s is known as node %d within NS3", pt.get_cname(), pt.extension<NetPointNs3>()->node_num);
   });
   simgrid::surf::on_cluster.connect(&clusterCreation_cb);
 
@@ -328,7 +328,7 @@ NetworkNS3Action::NetworkNS3Action(kernel::resource::Model* model, double totalB
   port_number++;
   xbt_assert(port_number <= 65000, "Too many connections! Port number is saturated.");
 
-  s4u::Link::on_communicate(this, src, dst);
+  s4u::Link::on_communicate(*this, src, dst);
 }
 
 void NetworkNS3Action::suspend() {
@@ -339,7 +339,7 @@ void NetworkNS3Action::resume() {
   THROW_UNIMPLEMENTED;
 }
 
-std::list<LinkImpl*> NetworkNS3Action::links()
+std::list<LinkImpl*> NetworkNS3Action::links() const
 {
   THROW_UNIMPLEMENTED;
 }
index 632fe81..af200b8 100644 (file)
@@ -50,7 +50,7 @@ public:
 
   void suspend() override;
   void resume() override;
-  std::list<LinkImpl*> links() override;
+  std::list<LinkImpl*> links() const override;
   void update_remains_lazy(double now) override;
 
   // private:
index 9a4715d..e296241 100644 (file)
@@ -218,7 +218,7 @@ kernel::resource::Action* NetworkL07Model::communicate(s4u::Host* src, s4u::Host
   return res;
 }
 
-Cpu* CpuL07Model::create_cpu(simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core)
+Cpu* CpuL07Model::create_cpu(simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core)
 {
   return new CpuL07(this, host, speed_per_pstate, core);
 }
@@ -233,8 +233,8 @@ kernel::resource::LinkImpl* NetworkL07Model::create_link(const std::string& name
  * Resource *
  ************/
 
-CpuL07::CpuL07(CpuL07Model* model, simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core)
-    : Cpu(model, host, model->get_maxmin_system()->constraint_new(this, speed_per_pstate->front()), speed_per_pstate,
+CpuL07::CpuL07(CpuL07Model* model, simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core)
+    : Cpu(model, host, model->get_maxmin_system()->constraint_new(this, speed_per_pstate.front()), speed_per_pstate,
           core)
 {
 }
index 76bb0bb..edc2fb2 100644 (file)
@@ -53,7 +53,7 @@ public:
   CpuL07Model& operator=(const CpuL07Model&) = delete;
   ~CpuL07Model();
 
-  Cpu* create_cpu(simgrid::s4u::Host* host, std::vector<double>* speed_per_pstate, int core) override;
+  Cpu* create_cpu(simgrid::s4u::Host* host, const std::vector<double>& speed_per_pstate, int core) override;
   HostL07Model *hostModel_;
 };
 
@@ -77,7 +77,7 @@ public:
 
 class CpuL07 : public Cpu {
 public:
-  CpuL07(CpuL07Model* model, s4u::Host* host, std::vector<double>* speed_per_pstate, int core);
+  CpuL07(CpuL07Model* model, s4u::Host* host, const std::vector<double>& speed_per_pstate, int core);
   CpuL07(const CpuL07&) = delete;
   CpuL07& operator=(const CpuL07&) = delete;
   ~CpuL07() override;
index 5eac4b4..bbea348 100644 (file)
@@ -33,7 +33,7 @@ XBT_PRIVATE std::vector<std::string> known_storages;
 namespace simgrid {
 namespace surf {
 
-simgrid::xbt::signal<void(kernel::routing::ClusterCreationArgs*)> on_cluster;
+simgrid::xbt::signal<void(kernel::routing::ClusterCreationArgs const&)> on_cluster;
 }
 }
 
@@ -74,7 +74,7 @@ void sg_platf_new_host(simgrid::kernel::routing::HostCreationArgs* args)
   }
 
   simgrid::s4u::Host* host =
-      routing_get_current()->create_host(args->id, &args->speed_per_pstate, args->core_amount, &props);
+      routing_get_current()->create_host(args->id, args->speed_per_pstate, args->core_amount, &props);
 
   host->pimpl_->storage_ = mount_list;
   mount_list.clear();
@@ -285,7 +285,7 @@ void sg_platf_new_cluster(simgrid::kernel::routing::ClusterCreationArgs* cluster
   XBT_DEBUG("</AS>");
   sg_platf_new_Zone_seal();
 
-  simgrid::surf::on_cluster(cluster);
+  simgrid::surf::on_cluster(*cluster);
   delete cluster->radicals;
 }
 
@@ -481,9 +481,9 @@ void sg_platf_new_peer(simgrid::kernel::routing::PeerCreationArgs* peer)
   simgrid::kernel::routing::VivaldiZone* as = dynamic_cast<simgrid::kernel::routing::VivaldiZone*>(current_routing);
   xbt_assert(as, "<peer> tag can only be used in Vivaldi netzones.");
 
-  std::vector<double> speedPerPstate;
-  speedPerPstate.push_back(peer->speed);
-  simgrid::s4u::Host* host = as->create_host(peer->id.c_str(), &speedPerPstate, 1, nullptr);
+  std::vector<double> speed_per_pstate;
+  speed_per_pstate.push_back(peer->speed);
+  simgrid::s4u::Host* host = as->create_host(peer->id.c_str(), speed_per_pstate, 1, nullptr);
 
   as->set_peer_link(host->pimpl_netpoint, peer->bw_in, peer->bw_out, peer->coord);
 
index 713cbee..0ab1fa2 100644 (file)
@@ -227,7 +227,7 @@ XBT_PUBLIC int surf_parse_lex_destroy();
 namespace simgrid {
 namespace surf {
 
-extern XBT_PRIVATE simgrid::xbt::signal<void(kernel::routing::ClusterCreationArgs*)> on_cluster;
+extern XBT_PRIVATE simgrid::xbt::signal<void(kernel::routing::ClusterCreationArgs const&)> on_cluster;
 }
 }
 
index 891f370..71ffabb 100644 (file)
 #include "xbt/dynar.h"
 #include "xbt/str.h"
 
+#include <algorithm>
 #include <mutex>
 #include <string>
+#include <vector>
 
 int xbt_log_no_loc = 0; /* if set to true (with --log=no_loc), file localization will be omitted (for tesh tests) */
 static std::recursive_mutex* log_cat_init_mutex = nullptr;
@@ -25,29 +27,15 @@ static std::recursive_mutex* log_cat_init_mutex = nullptr;
 xbt_log_appender_t xbt_log_default_appender = nullptr; /* set in log_init */
 xbt_log_layout_t xbt_log_default_layout     = nullptr; /* set in log_init */
 
-typedef struct {
-  char *catname;
-  char *fmt;
-  e_xbt_log_priority_t thresh;
-  int additivity;
-  xbt_log_appender_t appender;
-} s_xbt_log_setting_t;
-
-typedef s_xbt_log_setting_t* xbt_log_setting_t;
-
-static xbt_dynar_t xbt_log_settings = nullptr;
-
-static void _free_setting(void *s)
-{
-  xbt_log_setting_t set = *(xbt_log_setting_t *) s;
-  if (set) {
-    xbt_free(set->catname);
-    xbt_free(set->fmt);
-    xbt_free(set);
-  }
-}
+struct xbt_log_setting_t {
+  std::string catname;
+  std::string fmt;
+  e_xbt_log_priority_t thresh = xbt_log_priority_uninitialized;
+  int additivity              = -1;
+  xbt_log_appender_t appender = nullptr;
+};
 
-static void _xbt_log_cat_apply_set(xbt_log_category_t category, xbt_log_setting_t setting);
+static std::vector<xbt_log_setting_t> xbt_log_settings;
 
 const char *xbt_log_priority_names[8] = {
   "NONE",
@@ -102,17 +90,17 @@ void xbt_log_init(int *argc, char **argv)
 
   /* Set logs and init log submodule */
   for (int i = 1; i < *argc; i++) {
-    if (!strcmp("--", argv[i])) {
+    if (strcmp("--", argv[i]) == 0) {
       parse_args = 0;
       argv[j++]  = argv[i]; // Keep the '--' for sg_config
-    } else if (parse_args && !strncmp(argv[i], "--log=", strlen("--log="))) {
+    } else if (parse_args && strncmp(argv[i], "--log=", strlen("--log=")) == 0) {
       char* opt = strchr(argv[i], '=');
       opt++;
       xbt_log_control_set(opt);
       XBT_DEBUG("Did apply '%s' as log setting", opt);
-    } else if (parse_args && !strcmp(argv[i], "--help-logs")) {
+    } else if (parse_args && strcmp(argv[i], "--help-logs") == 0) {
       help_requested |= 1U;
-    } else if (parse_args && !strcmp(argv[i], "--help-log-categories")) {
+    } else if (parse_args && strcmp(argv[i], "--help-log-categories") == 0) {
       help_requested |= 2U;
     } else {
       argv[j++] = argv[i];
@@ -155,7 +143,6 @@ void xbt_log_postexit(void)
 {
   XBT_VERB("Exiting log");
   delete log_cat_init_mutex;
-  xbt_dynar_free(&xbt_log_settings);
   log_cat_exit(&_XBT_LOGV(XBT_LOG_ROOT_CAT));
 }
 
@@ -230,34 +217,34 @@ static int fake_xbt_log_cat_init(xbt_log_category_t, e_xbt_log_priority_t)
 #define DISABLE_XBT_LOG_CAT_INIT()                                                                                     \
   int (*_xbt_log_cat_init)(xbt_log_category_t, e_xbt_log_priority_t) XBT_ATTRIB_UNUSED = fake_xbt_log_cat_init;
 
-static void _xbt_log_cat_apply_set(xbt_log_category_t category, xbt_log_setting_t setting)
+static void _xbt_log_cat_apply_set(xbt_log_category_t category, const xbt_log_setting_t& setting)
 {
   DISABLE_XBT_LOG_CAT_INIT();
-  if (setting->thresh != xbt_log_priority_uninitialized) {
-    xbt_log_threshold_set(category, setting->thresh);
+  if (setting.thresh != xbt_log_priority_uninitialized) {
+    xbt_log_threshold_set(category, setting.thresh);
 
     XBT_DEBUG("Apply settings for category '%s': set threshold to %s (=%d)",
            category->name, xbt_log_priority_names[category->threshold], category->threshold);
   }
 
-  if (setting->fmt) {
-    xbt_log_layout_set(category, xbt_log_layout_format_new(setting->fmt));
+  if (not setting.fmt.empty()) {
+    xbt_log_layout_set(category, xbt_log_layout_format_new(setting.fmt.c_str()));
 
-    XBT_DEBUG("Apply settings for category '%s': set format to %s", category->name, setting->fmt);
+    XBT_DEBUG("Apply settings for category '%s': set format to %s", category->name, setting.fmt.c_str());
   }
 
-  if (setting->additivity != -1) {
-    xbt_log_additivity_set(category, setting->additivity);
+  if (setting.additivity != -1) {
+    xbt_log_additivity_set(category, setting.additivity);
 
-    XBT_DEBUG("Apply settings for category '%s': set additivity to %s",
-           category->name, (setting->additivity ? "on" : "off"));
+    XBT_DEBUG("Apply settings for category '%s': set additivity to %s", category->name,
+              (setting.additivity ? "on" : "off"));
   }
-  if (setting->appender) {
-    xbt_log_appender_set(category, setting->appender);
+  if (setting.appender) {
+    xbt_log_appender_set(category, setting.appender);
     if (!category->layout)
       xbt_log_layout_set(category, xbt_log_layout_simple_new(nullptr));
     category->additivity = 0;
-    XBT_DEBUG("Set %p as appender of category '%s'", setting->appender, category->name);
+    XBT_DEBUG("Set %p as appender of category '%s'", setting.appender, category->name);
   }
 }
 
@@ -274,9 +261,6 @@ int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority
   if (log_cat_init_mutex != nullptr)
     log_cat_init_mutex->lock();
 
-  unsigned int cursor;
-  xbt_log_setting_t setting = nullptr;
-
   XBT_DEBUG("Initializing category '%s' (firstChild=%s, nextSibling=%s)", category->name,
          (category->firstChild ? category->firstChild->name : "none"),
          (category->nextSibling ? category->nextSibling->name : "none"));
@@ -308,25 +292,14 @@ int _xbt_log_cat_init(xbt_log_category_t category, e_xbt_log_priority_t priority
   }
 
   /* Apply the control */
-  if (xbt_log_settings) {
-    xbt_assert(category, "NULL category");
-    xbt_assert(category->name);
-    int found = 0;
-
-    xbt_dynar_foreach(xbt_log_settings, cursor, setting) {
-      xbt_assert(setting, "Damnit, NULL cat in the list");
-      xbt_assert(setting->catname, "NULL setting(=%p)->catname", (void *) setting);
-
-      if (!strcmp(setting->catname, category->name)) {
-        found = 1;
-        _xbt_log_cat_apply_set(category, setting);
-        xbt_dynar_cursor_rm(xbt_log_settings, &cursor);
-      }
-    }
-
-    if (!found)
-      XBT_DEBUG("Category '%s': inherited threshold = %s (=%d)",
-                category->name, xbt_log_priority_names[category->threshold], category->threshold);
+  auto iset = std::find_if(begin(xbt_log_settings), end(xbt_log_settings),
+                           [category](const xbt_log_setting_t& s) { return s.catname == category->name; });
+  if (iset != xbt_log_settings.end()) {
+    _xbt_log_cat_apply_set(category, *iset);
+    xbt_log_settings.erase(iset);
+  } else {
+    XBT_DEBUG("Category '%s': inherited threshold = %s (=%d)", category->name,
+              xbt_log_priority_names[category->threshold], category->threshold);
   }
 
   category->initialized = 1;
@@ -391,107 +364,77 @@ void xbt_log_threshold_set(xbt_log_category_t cat, e_xbt_log_priority_t threshol
 static xbt_log_setting_t _xbt_log_parse_setting(const char *control_string)
 {
   const char *orig_control_string = control_string;
-  xbt_log_setting_t set = xbt_new(s_xbt_log_setting_t, 1);
-
-  set->catname    = nullptr;
-  set->thresh = xbt_log_priority_uninitialized;
-  set->fmt        = nullptr;
-  set->additivity = -1;
-  set->appender   = nullptr;
+  xbt_log_setting_t set;
 
   if (!*control_string)
     return set;
   XBT_DEBUG("Parse log setting '%s'", control_string);
 
   control_string += strspn(control_string, " ");
-  const char *name = control_string;
+  const charname = control_string;
   control_string += strcspn(control_string, ".:= ");
-  const char *dot = control_string;
+  const char* option = control_string;
   control_string += strcspn(control_string, ":= ");
-  const char *eq = control_string;
-
-  xbt_assert(*dot == '.' || (*eq != '=' && *eq != ':'), "Invalid control string '%s'", orig_control_string);
+  const char* value = control_string;
 
-  if (!strncmp(dot + 1, "threshold", (size_t) (eq - dot - 1))) {
-    int i;
-    char *neweq = xbt_strdup(eq + 1);
-    char *p = neweq - 1;
+  xbt_assert(*option == '.' && (*value == '=' || *value == ':'), "Invalid control string '%s'", orig_control_string);
 
-    while (*(++p) != '\0') {
-      if (*p >= 'a' && *p <= 'z') {
-        *p -= 'a' - 'A';
-      }
-    }
+  size_t name_len = option - name;
+  ++option;
+  size_t option_len = value - option;
+  ++value;
 
-    XBT_DEBUG("New priority name = %s", neweq);
+  if (strncmp(option, "threshold", option_len) == 0) {
+    XBT_DEBUG("New priority name = %s", value);
+    int i;
     for (i = 0; i < xbt_log_priority_infinite; i++) {
-      if (!strncmp(xbt_log_priority_names[i], neweq, p - eq)) {
+      if (strcasecmp(value, xbt_log_priority_names[i]) == 0) {
         XBT_DEBUG("This is priority %d", i);
         break;
       }
     }
 
     if(i<XBT_LOG_STATIC_THRESHOLD){
-     fprintf(stderr,
-         "Priority '%s' (in setting '%s') is above allowed priority '%s'.\n\n"
-         "Compiling SimGrid with -DNDEBUG forbids the levels 'trace' and 'debug'\n"
-         "while -DNLOG forbids any logging, at any level.",
-             eq + 1, name, xbt_log_priority_names[XBT_LOG_STATIC_THRESHOLD]);
-     exit(1);
+      fprintf(stderr, "Priority '%s' (in setting '%s') is above allowed priority '%s'.\n\n"
+                      "Compiling SimGrid with -DNDEBUG forbids the levels 'trace' and 'debug'\n"
+                      "while -DNLOG forbids any logging, at any level.",
+              value, name, xbt_log_priority_names[XBT_LOG_STATIC_THRESHOLD]);
+      exit(1);
     }else if (i < xbt_log_priority_infinite) {
-      set->thresh = (e_xbt_log_priority_t) i;
+      set.thresh = (e_xbt_log_priority_t)i;
     } else {
       THROWF(arg_error, 0,
-             "Unknown priority name: %s (must be one of: trace,debug,verbose,info,warning,error,critical)", eq + 1);
+             "Unknown priority name: %s (must be one of: trace,debug,verbose,info,warning,error,critical)", value);
     }
-    xbt_free(neweq);
-  } else if (!strncmp(dot + 1, "add", (size_t) (eq - dot - 1)) ||
-             !strncmp(dot + 1, "additivity", (size_t) (eq - dot - 1))) {
-    char *neweq = xbt_strdup(eq + 1);
-    char *p = neweq - 1;
-
-    while (*(++p) != '\0') {
-      if (*p >= 'a' && *p <= 'z') {
-        *p -= 'a' - 'A';
-      }
-    }
-    if (!strcmp(neweq, "ON") || !strcmp(neweq, "YES") || !strcmp(neweq, "1")) {
-      set->additivity = 1;
+  } else if (strncmp(option, "additivity", option_len) == 0) {
+    if (strcasecmp(value, "ON") == 0 || strcasecmp(value, "YES") == 0 || strcmp(value, "1") == 0) {
+      set.additivity = 1;
     } else {
-      set->additivity = 0;
+      set.additivity = 0;
     }
-    xbt_free(neweq);
-  } else if (!strncmp(dot + 1, "app", (size_t) (eq - dot - 1)) ||
-             !strncmp(dot + 1, "appender", (size_t) (eq - dot - 1))) {
-    char *neweq = xbt_strdup(eq + 1);
-
-    if (!strncmp(neweq, "file:", 5)) {
-      set->appender = xbt_log_appender_file_new(neweq + 5);
-    }else if (!strncmp(neweq, "rollfile:", 9)) {
-      set->appender = xbt_log_appender2_file_new(neweq + 9,1);
-    }else if (!strncmp(neweq, "splitfile:", 10)) {
-      set->appender = xbt_log_appender2_file_new(neweq + 10,0);
+  } else if (strncmp(option, "appender", option_len) == 0) {
+    if (strncmp(value, "file:", 5) == 0) {
+      set.appender = xbt_log_appender_file_new(value + 5);
+    } else if (strncmp(value, "rollfile:", 9) == 0) {
+      set.appender = xbt_log_appender2_file_new(value + 9, 1);
+    } else if (strncmp(value, "splitfile:", 10) == 0) {
+      set.appender = xbt_log_appender2_file_new(value + 10, 0);
     } else {
-      THROWF(arg_error, 0, "Unknown appender log type: '%s'", neweq);
+      THROWF(arg_error, 0, "Unknown appender log type: '%s'", value);
     }
-    xbt_free(neweq);
-  } else if (!strncmp(dot + 1, "fmt", (size_t) (eq - dot - 1))) {
-    set->fmt = xbt_strdup(eq + 1);
+  } else if (strncmp(option, "fmt", option_len) == 0) {
+    set.fmt = std::string(value);
   } else {
-    char buff[512];
-    snprintf(buff, std::min<int>(512, eq - dot), "%s", dot + 1);
-    xbt_die("Unknown setting of the log category: '%s'", buff);
+    xbt_die("Unknown setting of the log category: '%.*s'", static_cast<int>(option_len), option);
   }
-  set->catname = (char *) xbt_malloc(dot - name + 1);
+  set.catname = std::string(name, name_len);
 
-  memcpy(set->catname, name, dot - name);
-  set->catname[dot - name] = '\0';      /* Just in case */
-  XBT_DEBUG("This is for cat '%s'", set->catname);
+  XBT_DEBUG("This is for cat '%s'", set.catname.c_str());
 
   return set;
 }
 
-static xbt_log_category_t _xbt_log_cat_searchsub(xbt_log_category_t cat, char *name)
+static xbt_log_category_t _xbt_log_cat_searchsub(xbt_log_category_t cat, const char* name)
 {
   xbt_log_category_t child;
   xbt_log_category_t res;
@@ -499,7 +442,7 @@ static xbt_log_category_t _xbt_log_cat_searchsub(xbt_log_category_t cat, char *n
   XBT_DEBUG("Search '%s' into '%s' (firstChild='%s'; nextSibling='%s')", name,
          cat->name, (cat->firstChild ? cat->firstChild->name : "none"),
          (cat->nextSibling ? cat->nextSibling->name : "none"));
-  if (!strcmp(cat->name, name))
+  if (strcmp(cat->name, name) == 0)
     return cat;
 
   for (child = cat->firstChild; child != nullptr; child = child->nextSibling) {
@@ -533,8 +476,6 @@ static xbt_log_category_t _xbt_log_cat_searchsub(xbt_log_category_t cat, char *n
  */
 void xbt_log_control_set(const char *control_string)
 {
-  xbt_log_setting_t set;
-
   /* To split the string in commands, and the cursors */
   xbt_dynar_t set_strings;
   char *str;
@@ -545,14 +486,10 @@ void xbt_log_control_set(const char *control_string)
   XBT_DEBUG("Parse log settings '%s'", control_string);
 
   /* Special handling of no_loc request, which asks for any file localization to be omitted (for tesh runs) */
-  if (!strcmp(control_string, "no_loc")) {
+  if (strcmp(control_string, "no_loc") == 0) {
     xbt_log_no_loc = 1;
     return;
   }
-  /* some initialization if this is the first time that this get called */
-  if (xbt_log_settings == nullptr)
-    xbt_log_settings = xbt_dynar_new(sizeof(xbt_log_setting_t), _free_setting);
-
   /* split the string, and remove empty entries */
   set_strings = xbt_str_split_quoted(control_string);
 
@@ -563,17 +500,16 @@ void xbt_log_control_set(const char *control_string)
 
   /* Parse each entry and either use it right now (if the category was already created), or store it for further use */
   xbt_dynar_foreach(set_strings, cpt, str) {
-    set = _xbt_log_parse_setting(str);
-    xbt_log_category_t cat = _xbt_log_cat_searchsub(&_XBT_LOGV(XBT_LOG_ROOT_CAT), set->catname);
+    xbt_log_setting_t set  = _xbt_log_parse_setting(str);
+    xbt_log_category_t cat = _xbt_log_cat_searchsub(&_XBT_LOGV(XBT_LOG_ROOT_CAT), set.catname.c_str());
 
     if (cat) {
       XBT_DEBUG("Apply directly");
       _xbt_log_cat_apply_set(cat, set);
-      _free_setting((void *) &set);
     } else {
       XBT_DEBUG("Store for further application");
-      XBT_DEBUG("push %p to the settings", (void *) set);
-      xbt_dynar_push(xbt_log_settings, &set);
+      XBT_DEBUG("push %p to the settings", &set);
+      xbt_log_settings.emplace_back(std::move(set));
     }
   }
   xbt_dynar_free(&set_strings);
@@ -648,7 +584,6 @@ static void xbt_log_help(void)
          "in 'l'etter)\n"
          "         -> %%L: line number where the log event was raised (LOG4J compatible)\n"
          "         -> %%M: function name (LOG4J compatible -- called method name here of course).\n"
-         "                 Defined only when using gcc because there is no __func__ elsewhere.\n"
          "\n"
          "         -> %%b: full backtrace (Called %%throwable in LOG4J). Defined only under windows or when using the "
          "GNU libc because\n"
@@ -666,47 +601,31 @@ static void xbt_log_help(void)
          "\n");
 }
 
-static int xbt_log_cat_cmp(const void *pa, const void *pb)
-{
-  xbt_log_category_t a = *(xbt_log_category_t *)pa;
-  xbt_log_category_t b = *(xbt_log_category_t *)pb;
-  return strcmp(a->name, b->name);
-}
-
-static void xbt_log_help_categories_rec(xbt_log_category_t category, const char *prefix)
+static void xbt_log_help_categories_rec(xbt_log_category_t category, const std::string& prefix)
 {
-  char *this_prefix;
-  char *child_prefix;
-  unsigned i;
-  xbt_log_category_t cat;
-
   if (!category)
     return;
 
+  std::string this_prefix(prefix);
+  std::string child_prefix(prefix);
   if (category->parent) {
-    this_prefix = bprintf("%s \\_ ", prefix);
-    child_prefix = bprintf("%s |  ", prefix);
-  } else {
-    this_prefix = xbt_strdup(prefix);
-    child_prefix = xbt_strdup(prefix);
+    this_prefix  += " \\_ ";
+    child_prefix += " |  ";
   }
 
-  xbt_dynar_t dynar = xbt_dynar_new(sizeof(xbt_log_category_t), nullptr);
-  for (cat = category; cat != nullptr; cat = cat->nextSibling)
-    xbt_dynar_push_as(dynar, xbt_log_category_t, cat);
+  std::vector<xbt_log_category_t> cats;
+  for (xbt_log_category_t cat = category; cat != nullptr; cat = cat->nextSibling)
+    cats.push_back(cat);
 
-  xbt_dynar_sort(dynar, xbt_log_cat_cmp);
+  std::sort(begin(cats), end(cats),
+            [](xbt_log_category_t a, xbt_log_category_t b) { return strcmp(a->name, b->name) < 0; });
 
-  xbt_dynar_foreach(dynar, i, cat){
-    if (i == xbt_dynar_length(dynar) - 1 && category->parent)
-      *strrchr(child_prefix, '|') = ' ';
-    printf("%s%s: %s\n", this_prefix, cat->name, cat->description);
+  for (auto const& cat : cats) {
+    printf("%s%s: %s\n", this_prefix.c_str(), cat->name, cat->description);
+    if (cat == cats.back() && category->parent)
+      child_prefix[child_prefix.rfind('|')] = ' ';
     xbt_log_help_categories_rec(cat->firstChild, child_prefix);
   }
-
-  xbt_dynar_free(&dynar);
-  xbt_free(this_prefix);
-  xbt_free(child_prefix);
 }
 
 static void xbt_log_help_categories(void)
index c082050..7d9a216 100644 (file)
@@ -22,8 +22,8 @@ static void free_(xbt_log_appender_t this_) {
     fclose(static_cast<FILE*>(this_->data));
 }
 
-xbt_log_appender_t xbt_log_appender_file_new(char *arg) {
-
+xbt_log_appender_t xbt_log_appender_file_new(const char* arg)
+{
   xbt_log_appender_t res = xbt_new0(s_xbt_log_appender_t, 1);
   res->do_append         = &append_file;
   res->free_             = &free_;
@@ -105,8 +105,8 @@ static void free_append2_(xbt_log_appender_t this_)
 //syntax is  <maxsize>:<filename>
 //If roll is 0, use split files, otherwise, use roll file
 //For split, replace %  in the file by the current count
-xbt_log_appender_t xbt_log_appender2_file_new(char *arg,int roll) {
-
+xbt_log_appender_t xbt_log_appender2_file_new(const char* arg, int roll)
+{
   xbt_log_appender_t res      = xbt_new0(s_xbt_log_appender_t, 1);
   res->do_append              = &append2_file;
   res->free_                  = &free_append2_;
index 854968e..06c9a73 100644 (file)
@@ -179,7 +179,7 @@ static void xbt_log_layout_format_free(xbt_log_layout_t lay)
   xbt_free(lay->data);
 }
 
-xbt_log_layout_t xbt_log_layout_format_new(char *arg)
+xbt_log_layout_t xbt_log_layout_format_new(const char* arg)
 {
   xbt_log_layout_t res = xbt_new0(s_xbt_log_layout_t, 1);
   res->do_layout       = &xbt_log_layout_format_doit;
index aa4a1c9..6e4b400 100644 (file)
@@ -70,7 +70,7 @@ static int xbt_log_layout_simple_doit(xbt_log_layout_t, xbt_log_event_t ev, cons
   return 1;
 }
 
-xbt_log_layout_t xbt_log_layout_simple_new(char*)
+xbt_log_layout_t xbt_log_layout_simple_new(const char*)
 {
   xbt_log_layout_t res = xbt_new0(s_xbt_log_layout_t, 1);
   res->do_layout       = &xbt_log_layout_simple_doit;
index 0d784a1..bfaeff9 100644 (file)
@@ -192,39 +192,6 @@ xbt_dynar_t xbt_str_split_quoted(const char *s)
   return res;
 }
 
-/** @brief Join a set of strings as a single string
- *
- * The parameter must be a nullptr-terminated array of chars,
- * just like xbt_dynar_to_array() produces
- */
-char *xbt_str_join_array(const char *const *strs, const char *sep)
-{
-  int amount_strings=0;
-  int len=0;
-
-  if ((not strs) || (not strs[0]))
-    return xbt_strdup("");
-
-  /* compute the length before malloc */
-  for (int i = 0; strs[i]; i++) {
-    len += strlen(strs[i]);
-    amount_strings++;
-  }
-  len += strlen(sep) * amount_strings;
-
-  /* Do the job */
-  char* res = (char*)xbt_malloc(len);
-  char* q   = res;
-  for (int i = 0; strs[i]; i++) {
-    if (i != 0) { // not first loop
-      q += snprintf(q,len, "%s%s", sep, strs[i]);
-    } else {
-      q += snprintf(q,len, "%s",strs[i]);
-    }
-  }
-  return res;
-}
-
 /** @brief Parse an integer out of a string, or raise an error
  *
  * The @a str is passed as argument to your @a error_msg, as follows:
index d6eee1e..48fe51b 100644 (file)
 #include "simgrid/Exception.hpp"
 
 #include "catch.hpp"
+#include <string>
+#include <vector>
 
-#define mytest(name, input, expected)                                                                                  \
-  INFO(name);                                                                                                          \
-  a = static_cast<char**>(xbt_dynar_to_array(xbt_str_split_quoted(input)));                                            \
-  s = xbt_str_join_array(a, "XXX");                                                                                    \
-  REQUIRE(not strcmp(s, expected));                                                                                    \
-  xbt_free(s);                                                                                                         \
-  for (int i = 0; a[i] != nullptr; i++)                                                                                \
-    xbt_free(a[i]);                                                                                                    \
-  xbt_free(a);
+namespace {
+void test_split_quoted(const std::string& name, const char* input, const std::vector<std::string>& expected)
+{
+  INFO(name);
+  xbt_dynar_t a = xbt_str_split_quoted(input);
+  REQUIRE(xbt_dynar_length(a) == expected.size());
+  unsigned i;
+  char* token;
+  xbt_dynar_foreach (a, i, token)
+    REQUIRE(token == expected[i]);
+  xbt_dynar_free(&a);
+}
 
-#define test_parse_error(function, name, variable, str)                                                                \
-  do {                                                                                                                 \
-    INFO(name);                                                                                                        \
-    REQUIRE_THROWS_MATCHES(variable = function(str, "Parse error"), xbt_ex,                                            \
-                           Catch::Matchers::Predicate<xbt_ex>([](xbt_ex const& e) { return e.category == arg_error; }, \
-                                                              "category arg_error"));                                  \
-  } while (0)
+template <typename F> void test_parse_error(F function, const std::string& name, const char* str)
+{
+  INFO(name);
+  REQUIRE_THROWS_MATCHES(function(str, "Parse error"), xbt_ex,
+                         Catch::Matchers::Predicate<xbt_ex>([](xbt_ex const& e) { return e.category == arg_error; },
+                                                            "category arg_error"));
+}
 
-#define test_parse_ok(function, name, variable, str, value)                                                            \
-  do {                                                                                                                 \
-    INFO(name);                                                                                                        \
-    REQUIRE_NOTHROW(variable = function(str, "Parse error"));                                                          \
-    REQUIRE(variable == value); /* Fail to parse str */                                                                \
-  } while (0)
+template <typename F, typename T> void test_parse_ok(F function, const std::string& name, const char* str, T value)
+{
+  INFO(name);
+  T variable = static_cast<T>(-9999);
+  REQUIRE_NOTHROW(variable = function(str, "Parse error"));
+  REQUIRE(variable == value); /* Fail to parse str */
+}
+}
 
 TEST_CASE("xbt::str: String Handling", "xbt_str")
 {
 
   SECTION("Test the function xbt_str_split_quoted")
   {
-    char** a;
-    char* s;
-
-    mytest("Empty", "", "");
-    mytest("Basic test", "toto tutu", "totoXXXtutu");
-    mytest("Useless backslashes", "\\t\\o\\t\\o \\t\\u\\t\\u", "totoXXXtutu");
-    mytest("Protected space", "toto\\ tutu", "toto tutu");
-    mytest("Several spaces", "toto   tutu", "totoXXXtutu");
-    mytest("LTriming", "  toto tatu", "totoXXXtatu");
-    mytest("Triming", "  toto   tutu  ", "totoXXXtutu");
-    mytest("Single quotes", "'toto tutu' tata", "toto tutuXXXtata");
-    mytest("Double quotes", "\"toto tutu\" tata", "toto tutuXXXtata");
-    mytest("Mixed quotes", "\"toto' 'tutu\" tata", "toto' 'tutuXXXtata");
-    mytest("Backslashed quotes", "\\'toto tutu\\' tata", "'totoXXXtutu'XXXtata");
-    mytest("Backslashed quotes + quotes", "'toto \\'tutu' tata", "toto 'tutuXXXtata");
+    test_split_quoted("Empty", "", {});
+    test_split_quoted("Basic test", "toto tutu", {"toto", "tutu"});
+    test_split_quoted("Useless backslashes", "\\t\\o\\t\\o \\t\\u\\t\\u", {"toto", "tutu"});
+    test_split_quoted("Protected space", "toto\\ tutu", {"toto tutu"});
+    test_split_quoted("Several spaces", "toto   tutu", {"toto", "tutu"});
+    test_split_quoted("LTriming", "  toto tatu", {"toto", "tatu"});
+    test_split_quoted("Triming", "  toto   tutu  ", {"toto", "tutu"});
+    test_split_quoted("Single quotes", "'toto tutu' tata", {"toto tutu", "tata"});
+    test_split_quoted("Double quotes", "\"toto tutu\" tata", {"toto tutu", "tata"});
+    test_split_quoted("Mixed quotes", "\"toto' 'tutu\" tata", {"toto' 'tutu", "tata"});
+    test_split_quoted("Backslashed quotes", "\\'toto tutu\\' tata", {"'toto", "tutu'", "tata"});
+    test_split_quoted("Backslashed quotes + quotes", "'toto \\'tutu' tata", {"toto 'tutu", "tata"});
   }
 
   SECTION("Test the parsing functions")
   {
-    int rint = -9999;
-    test_parse_ok(xbt_str_parse_int, "Parse int", rint, "42", 42);
-    test_parse_ok(xbt_str_parse_int, "Parse 0 as an int", rint, "0", 0);
-    test_parse_ok(xbt_str_parse_int, "Parse -1 as an int", rint, "-1", -1);
+    test_parse_ok(xbt_str_parse_int, "Parse int", "42", 42);
+    test_parse_ok(xbt_str_parse_int, "Parse 0 as an int", "0", 0);
+    test_parse_ok(xbt_str_parse_int, "Parse -1 as an int", "-1", -1);
 
-    test_parse_error(xbt_str_parse_int, "Parse int + noise", rint, "342 cruft");
-    test_parse_error(xbt_str_parse_int, "Parse nullptr as an int", rint, nullptr);
-    test_parse_error(xbt_str_parse_int, "Parse '' as an int", rint, "");
-    test_parse_error(xbt_str_parse_int, "Parse cruft as an int", rint, "cruft");
+    test_parse_error(xbt_str_parse_int, "Parse int + noise", "342 cruft");
+    test_parse_error(xbt_str_parse_int, "Parse nullptr as an int", nullptr);
+    test_parse_error(xbt_str_parse_int, "Parse '' as an int", "");
+    test_parse_error(xbt_str_parse_int, "Parse cruft as an int", "cruft");
 
-    double rdouble = -9999;
-    test_parse_ok(xbt_str_parse_double, "Parse 42 as a double", rdouble, "42", 42);
-    test_parse_ok(xbt_str_parse_double, "Parse 42.5 as a double", rdouble, "42.5", 42.5);
-    test_parse_ok(xbt_str_parse_double, "Parse 0 as a double", rdouble, "0", 0);
-    test_parse_ok(xbt_str_parse_double, "Parse -1 as a double", rdouble, "-1", -1);
+    test_parse_ok(xbt_str_parse_double, "Parse 42 as a double", "42", 42);
+    test_parse_ok(xbt_str_parse_double, "Parse 42.5 as a double", "42.5", 42.5);
+    test_parse_ok(xbt_str_parse_double, "Parse 0 as a double", "0", 0);
+    test_parse_ok(xbt_str_parse_double, "Parse -1 as a double", "-1", -1);
 
-    test_parse_error(xbt_str_parse_double, "Parse double + noise", rdouble, "342 cruft");
-    test_parse_error(xbt_str_parse_double, "Parse nullptr as a double", rdouble, nullptr);
-    test_parse_error(xbt_str_parse_double, "Parse '' as a double", rdouble, "");
-    test_parse_error(xbt_str_parse_double, "Parse cruft as a double", rdouble, "cruft");
+    test_parse_error(xbt_str_parse_double, "Parse double + noise", "342 cruft");
+    test_parse_error(xbt_str_parse_double, "Parse nullptr as a double", nullptr);
+    test_parse_error(xbt_str_parse_double, "Parse '' as a double", "");
+    test_parse_error(xbt_str_parse_double, "Parse cruft as a double", "cruft");
   }
 }
diff --git a/teshsuite/lua/CMakeLists.txt b/teshsuite/lua/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a213e80
--- /dev/null
@@ -0,0 +1,6 @@
+IF(SIMGRID_HAVE_LUA)
+  # Tests testing simulation from C but using lua for platform files. Executed like this
+  # ~$ ./masterslave platform.lua deploy.lua
+  ADD_TESH(lua-platform-masterslave                --setenv srcdir=${CMAKE_HOME_DIRECTORY} --setenv bindir=${CMAKE_BINARY_DIR} --cd ${CMAKE_BINARY_DIR} ${CMAKE_HOME_DIRECTORY}/teshsuite/lua/lua_platforms.tesh)
+  SET_TESTS_PROPERTIES(lua-platform-masterslave    PROPERTIES ENVIRONMENT "LUA_CPATH=${CMAKE_BINARY_DIR}/lib/lib?.${LIB_EXE}")
+ENDIF()
index 6dddbd6..7d47505 100644 (file)
@@ -8,8 +8,8 @@ $ ${bindir:=.}/energy-pstate$EXEEXT ${platfdir}/energy_platform.xml "--log=root.
 > [  0.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
 > [  0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000
 > [  1.000000] (1:dvfs_test@MyHost1) Task1 simulation time: 1.000000e+00
-> [  1.000000] (2:dvfs_test@MyHost2) Task1 simulation time: 1.000000e+00
 > [  1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2)
+> [  1.000000] (2:dvfs_test@MyHost2) Task1 simulation time: 1.000000e+00
 > [  1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2)
 > [  1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
 > [  1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
@@ -29,8 +29,8 @@ $ ${bindir:=.}/energy-pstate$EXEEXT ${platfdir}/energy_cluster.xml "--log=root.f
 > [  0.000000] (2:dvfs_test@MyHost2) Count of Processor states=3
 > [  0.000000] (2:dvfs_test@MyHost2) Current power peak=100000000.000000
 > [  1.000000] (1:dvfs_test@MyHost1) Task1 simulation time: 1.000000e+00
-> [  1.000000] (2:dvfs_test@MyHost2) Task1 simulation time: 1.000000e+00
 > [  1.000000] (1:dvfs_test@MyHost1) Changing power peak value to 20000000.000000 (at index 2)
+> [  1.000000] (2:dvfs_test@MyHost2) Task1 simulation time: 1.000000e+00
 > [  1.000000] (2:dvfs_test@MyHost2) Changing power peak value to 20000000.000000 (at index 2)
 > [  1.000000] (1:dvfs_test@MyHost1) Current power peak=20000000.000000
 > [  1.000000] (2:dvfs_test@MyHost2) Current power peak=20000000.000000
index f4857f0..309dbd4 100644 (file)
@@ -27,9 +27,9 @@ $ ${bindir}/host_on_off_processes ${platfdir}/small_platform.xml 4 --log=no_loc
 > [Tremblay:test_launcher:(1) 20.000000] [msg_test/INFO]   Turn Jupiter off
 > [Tremblay:test_launcher:(1) 20.000000] [msg_test/INFO] Test 4 is ok.  (number of Process : 2, it should be 1 or 2 if RX has not been satisfied). An exception is raised when we turn off a node that has a process sleeping
 > [Tremblay:test_launcher:(1) 20.000000] [msg_test/INFO]   Test done. See you!
-> [Tremblay:commRX:(2) 20.000000] [msg_test/INFO]   Receive message: TRANSFER_FAILURE
-> [Tremblay:commRX:(2) 20.000000] [msg_test/INFO]   RX Done
-> [20.000000] [msg_test/INFO] Simulation time 20
+> [Tremblay:commRX:(2) 25.033047] [msg_test/INFO]   Receive message: COMM
+> [Tremblay:commRX:(2) 25.033047] [msg_test/INFO]   RX Done
+> [25.033047] [msg_test/INFO] Simulation time 25.033
 
 $ ${bindir}/host_on_off_processes ${platfdir}/small_platform.xml 5 --log=no_loc
 > [Tremblay:test_launcher:(1) 0.000000] [msg_test/INFO] Test 5 (turn off dest during a communication : Create a Process/task to make a communication between Tremblay and Jupiter and turn off Jupiter during the communication
@@ -39,8 +39,6 @@ $ ${bindir}/host_on_off_processes ${platfdir}/small_platform.xml 5 --log=no_loc
 > [Tremblay:test_launcher:(1) 20.000000] [msg_test/INFO]   Turn Jupiter off
 > [Tremblay:test_launcher:(1) 20.000000] [msg_test/INFO] Test 5 seems ok (number of Process: 2, it should be 2)
 > [Tremblay:test_launcher:(1) 20.000000] [msg_test/INFO]   Test done. See you!
-> [Jupiter:commRX:(2) 20.000000] [msg_test/INFO]   Receive message: HOST_FAILURE
-> [Jupiter:commRX:(2) 20.000000] [msg_test/INFO]   RX Done
 > [Tremblay:commTX:(3) 40.000000] [msg_test/INFO]   TX done
 > [40.000000] [msg_test/INFO] Simulation time 40
 
index f3737bc..be1e495 100644 (file)
@@ -255,7 +255,7 @@ static void test_comm()
   xbt_assert(recv_done, "Receiver killed somehow. It shouldn't");
 }
 
-static void test_comm_dsend_and_quit()
+static void test_comm_dsend_and_quit_put_before_get()
 {
   XBT_INFO("%s: Launch a detached communication and end right after", __func__);
   bool dsend_done = false;
@@ -271,16 +271,10 @@ static void test_comm_dsend_and_quit()
 
   simgrid::s4u::Actor::create("receiver", all_hosts[2], [&recv_done]() {
     assert_exit(false, 3);
-    bool got_exception = false;
     simgrid::s4u::this_actor::sleep_for(2);
-    try {
-      void* payload = simgrid::s4u::Mailbox::by_name("mb")->get();
-      xbt_free(payload);
-    } catch (xbt_ex const& e) {
-      got_exception = true;
-    }
+    void* payload = simgrid::s4u::Mailbox::by_name("mb")->get();
+    xbt_free(payload);
     recv_done = true;
-    xbt_assert(not got_exception);
     return;
   });
 
@@ -290,6 +284,36 @@ static void test_comm_dsend_and_quit()
   xbt_assert(recv_done, "Receiver killed somehow. It shouldn't");
 }
 
+static void test_comm_dsend_and_quit_get_before_put()
+{
+  XBT_INFO("%s: Launch a detached communication and end right after", __func__);
+  bool dsend_done = false;
+  bool recv_done  = false;
+
+  simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create("sender", all_hosts[1], [&dsend_done]() {
+    assert_exit(false, 2);
+    char* payload = xbt_strdup("toto");
+    simgrid::s4u::this_actor::sleep_for(2);
+    simgrid::s4u::Mailbox::by_name("mb")->put_init(payload, 1000)->detach();
+    dsend_done = true;
+    return;
+  });
+
+  simgrid::s4u::Actor::create("receiver", all_hosts[2], [&recv_done]() {
+    assert_exit(false, 3);
+    void* payload = simgrid::s4u::Mailbox::by_name("mb")->get();
+    xbt_free(payload);
+    recv_done = true;
+    return;
+  });
+
+  // Sleep long enough to let the test ends by itself. 3 + surf_precision should be enough.
+  simgrid::s4u::this_actor::sleep_for(4);
+  xbt_assert(dsend_done, "Sender killed somehow. It shouldn't");
+  xbt_assert(recv_done, "Receiver killed somehow. It shouldn't");
+}
+
+
 static void test_comm_killsend()
 {
   XBT_INFO("%s: Launch a communication and kill the sender", __func__);
@@ -327,6 +351,55 @@ static void test_comm_killsend()
   xbt_assert(recv_done, "Receiver killed somehow. It shouldn't");
 }
 
+static void test_host_off_while_receive()
+{
+  XBT_INFO("%s: Launch an actor that waits on a recv, kill its host", __func__);
+  bool in_on_exit = false;
+  bool returned_from_main = false;
+  bool in_catch_before_on_exit = false;
+  bool in_catch_after_on_exit = false;
+
+  simgrid::s4u::ActorPtr receiver = simgrid::s4u::Actor::create(
+    "receiver", all_hosts[1], 
+    [&in_on_exit, &returned_from_main, &in_catch_before_on_exit, &in_catch_after_on_exit]() {
+       assert_exit(true, 1);
+       try {
+         simgrid::s4u::Mailbox::by_name("mb")->get();
+       } catch (simgrid::HostFailureException const&) {
+         in_catch_before_on_exit = not in_on_exit;
+         in_catch_after_on_exit = in_on_exit;
+       } catch (simgrid::NetworkFailureException const&) {
+         in_catch_before_on_exit = not in_on_exit;
+         in_catch_after_on_exit = in_on_exit;
+       }
+       returned_from_main = true;
+     });
+
+  receiver->on_exit([&in_on_exit](bool) { in_on_exit = true; });
+
+  simgrid::s4u::ActorPtr sender = simgrid::s4u::Actor::create(
+    "sender", all_hosts[2], 
+    []() {
+      int data;
+      simgrid::s4u::Mailbox::by_name("mb")->put(&data, 100000);
+    });
+
+  simgrid::s4u::this_actor::sleep_for(1);
+  receiver->get_host()->turn_off();
+  
+  // Note: If we don't sleep here, we don't "see" the bug
+  simgrid::s4u::this_actor::sleep_for(1);
+
+  xbt_assert(in_on_exit, 
+    "Receiver's on_exit function was never called");
+  xbt_assert(not in_catch_before_on_exit, 
+    "Receiver mistakenly went to catch clause (before the on_exit function was called)");
+  xbt_assert(not in_catch_after_on_exit, 
+    "Receiver mistakenly went to catch clause (after the on_exit function was called)");
+  xbt_assert(not returned_from_main, 
+    "Receiver returned from main normally even though its host was killed");
+}
+
 /* We need an extra actor here, so that it can sleep until the end of each test */
 static void main_dispatcher()
 {
@@ -336,19 +409,22 @@ static void main_dispatcher()
   /* We cannot kill right at the end of the action because killer actors are always rescheduled to the end of the round
    * to avoid that they exit before their victim dereferences their name */
   run_test("sleep restarted at start", test_sleep_restart_begin);
-  run_test("sleep restarted at middle", test_sleep_restart_middle);
+  run_test("sleep restarted in middle", test_sleep_restart_middle);
   // run_test("sleep restarted at end", test_sleep_restart_end);
 
   run_test("exec", static_cast<std::function<void()>>(test_exec));
   run_test("exec killed at start", test_exec_kill_begin);
   run_test("exec killed in middle", test_exec_kill_middle);
   run_test("exec restarted at start", test_exec_restart_begin);
-  run_test("exec restarted at middle", test_exec_restart_middle);
+  run_test("exec restarted in middle", test_exec_restart_middle);
   run_test("exec restarted at end", test_exec_restart_end);
 
   run_test("comm", test_comm);
-  run_test("comm dsend and quit", test_comm_dsend_and_quit);
+  run_test("comm dsend and quit (put before get)", test_comm_dsend_and_quit_put_before_get);
+  run_test("comm dsend and quit (get before put)", test_comm_dsend_and_quit_get_before_put);
   run_test("comm kill sender", test_comm_killsend);
+
+  //run_test("comm recv and kill", test_host_off_while_receive);
 }
 
 int main(int argc, char* argv[])
index 42ac105..e13e3e2 100644 (file)
@@ -78,9 +78,9 @@ foreach(x availability basic0 basic1 basic3 basic4 basic5 basic6 basic-link-test
 endforeach()
 
 # test for code coverage
-ADD_TEST(test-help            ${CMAKE_BINARY_DIR}/teshsuite/simdag/basic-parsing-test/basic-parsing-test --help)
-ADD_TEST(test-help-models     ${CMAKE_BINARY_DIR}/teshsuite/simdag/basic-parsing-test/basic-parsing-test --help-models)
-ADD_TEST(test-tracing-help    ${CMAKE_BINARY_DIR}/teshsuite/simdag/basic-parsing-test/basic-parsing-test --help-tracing)
+foreach(x version help help-logs help-log-categories help-aliases help-models help-tracing)
+  ADD_TEST(test-${x} ${CMAKE_BINARY_DIR}/teshsuite/simdag/basic-parsing-test/basic-parsing-test --${x})
+endforeach()
 
 ADD_TESH(tesh-simdag-parser-bypass   --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/simdag/basic-parsing-test --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/basic-parsing-test --setenv srcdir=${CMAKE_HOME_DIRECTORY} basic-parsing-test-bypass.tesh)
 ADD_TESH(tesh-simdag-parser-sym-full --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/simdag/basic-parsing-test --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/simdag/basic-parsing-test basic-parsing-test-sym-full.tesh)
index e8a01ba..140fedb 100644 (file)
@@ -54,3 +54,10 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
     add_library(mtest_c STATIC util/mtest_manual.c util/dtypes_manual.c util/mtestcheck.c util/mtest_datatype.c util/mtest_datatype_gen_manual.c)
   endif()
 endif()
+
+IF(enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
+  ADD_TEST(test-smpi-mpich3-thread-f77     ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f77/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${TESH_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f77/ -tests=testlist -privatization=${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/stack-size:8000 -execarg=--cfg=contexts/factory:thread -execarg=--cfg=smpi/privatization:${HAVE_PRIVATIZATION})
+  SET_TESTS_PROPERTIES(test-smpi-mpich3-thread-f77 PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
+  ADD_TEST(test-smpi-mpich3-thread-f90     ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f90/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${TESH_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f90/ -tests=testlist -privatization=${HAVE_PRIVATIZATION} -execarg=--cfg=smpi/privatization:${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/factory:thread)
+  SET_TESTS_PROPERTIES(test-smpi-mpich3-thread-f90 PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
+ENDIF()
index 1c28008..2b6a852 100644 (file)
@@ -9,30 +9,24 @@ if(enable_smpi AND enable_smpi_MPICH3_testsuite)
   include_directories(BEFORE "${CMAKE_HOME_DIRECTORY}/include/smpi")
   include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../include/")
  
-  foreach(test allgather2 allgather3 allgather_struct 
-               allgatherv2 allgatherv3
-              allred2 allred3 allred4 allred5 allred6 allredmany
-              alltoall1 alltoallv0 alltoallv
-            # alltoallw1 alltoallw2 alltoallw_zeros
-              bcasttest bcastzerotype 
-              coll2 coll3 coll4 coll5 coll6 coll7 coll8 coll9 coll10 coll11 coll12 coll13
-              exscan exscan2 
-              gather gather2 gather_big
-            # iallred ibarrier icallgather icallgatherv icallreduce
-             # icalltoall icalltoallv icalltoallw icbarrier icbcast
-            # icgather icgatherv icreduce icscatter icscatterv
-              longuser
-            # nonblocking2 nonblocking3 nonblocking
-            # opband opbor opbxor opland oplor oplxor opmax opmaxloc
-             # opmin opminloc opprod opsum
-              op_commutative
-              red3 red4 redscat2 redscat3 redscatbkinter redscatblk3
-               redscat red_scat_block red_scat_block2
-            # redscatinter
-              reduce_local
-              scantst scatter2 scatter3 scattern scatterv
-            # uoplong
-              )
+  foreach(test allgather2 allgather3 allgather_struct allgatherv2 allgatherv3
+          allred2 allred3 allred4 allred5 allred6 allredmany alltoall1 
+          alltoallv0 alltoallv alltoallw1 alltoallw2 alltoallw_zeros
+          bcasttest bcastzerotype coll2 coll3 coll4 coll5 coll6 coll7 coll8
+          coll9 coll10 coll11 coll12 coll13 exscan exscan2 gather gather2 
+          gather_big ibarrier longuser nonblocking nonblocking2
+        # iallred icallgather icallgatherv icallreduce
+        # icalltoall icalltoallv icalltoallw icbarrier icbcast
+        # icgather icgatherv icreduce icscatter icscatterv
+        # nonblocking3 
+        # opband opbor opbxor opland oplor oplxor opmax opmaxloc
+        # opmin opminloc opprod opsum
+          op_commutative red3 red4 redscat2 redscat3 redscatbkinter redscatblk3
+          redscat red_scat_block red_scat_block2
+        # redscatinter
+          reduce_local scantst scatter2 scatter3 scattern scatterv
+        # uoplong
+         )
     add_executable(${test} EXCLUDE_FROM_ALL ${test}.c)
     add_dependencies(tests ${test})
     target_link_libraries(${test} simgrid mtest_c)
index fe5fd00..cac4c5d 100644 (file)
@@ -163,10 +163,10 @@ MPI_Datatype transpose_type(int N, int m, int n, MPI_Datatype type)
         MPI_Type_size(type, &tsize);
         MPI_Type_get_true_extent(submatrix, &llb, &textent);
 
-        if (textent != tsize * (N * (m - 1) + n)) {
-            fprintf(stderr, "Transpose Submatrix extent is %ld, expected %ld (%d,%d,%d)\n",
-                    (long) textent, (long) (tsize * (N * (m - 1) + n)), N, n, m);
-        }
+/*        if (textent != tsize * (N * (m - 1) + n)) {*/
+/*            fprintf(stderr, "Transpose Submatrix extent is %ld, expected %ld (%d,%d,%d)\n",*/
+/*                    (long) textent, (long) (tsize * (N * (m - 1) + n)), N, n, m);*/
+/*        }*/
     }
 
     return (submatrix);
index 634077b..187b288 100644 (file)
@@ -47,8 +47,8 @@ int main(int argc, char **argv)
     int *recvcounts = NULL;
     int *sdispls = NULL;
     int *rdispls = NULL;
-    int *sendtypes = NULL;
-    int *recvtypes = NULL;
+    MPI_Datatype *sendtypes = NULL;
+    MPI_Datatype *recvtypes = NULL;
     signed char *buf_alias = NULL;
     MPI_Request req;
 
@@ -126,8 +126,7 @@ int main(int argc, char **argv)
     /* same again, use a user op and free it before the wait */
     {
         MPI_Op op = MPI_OP_NULL;
-        MPI_Op_create(sum_fn, /*commute= */ 1, &op);
-
+        MPI_Op_create(sum_fn, 1, &op);
         for (i = 0; i < COUNT; ++i) {
             buf[i] = rank + i;
             recvbuf[i] = 0xdeadbeef;
@@ -296,7 +295,7 @@ int main(int argc, char **argv)
     }
     for (i = 1; i < size; ++i) {
         for (j = 0; j < COUNT; ++j) {
-            /* check we didn't corrupt the rest of the recvbuf */
+/*             check we didn't corrupt the rest of the recvbuf */
             my_assert(recvbuf[i * COUNT + j] == 0xdeadbeef);
         }
     }
@@ -439,7 +438,7 @@ int main(int argc, char **argv)
     MPI_Wait(&req, MPI_STATUS_IGNORE);
     for (i = 0; i < size; ++i) {
         for (j = 0; j < COUNT; ++j) {
-            /*printf("recvbuf[%d*COUNT+%d]=%d, expecting %d\n", i, j, recvbuf[i*COUNT+j], (i + (rank * j))); */
+/*            printf("recvbuf[%d*COUNT+%d]=%d, expecting %d\n", i, j, recvbuf[i*COUNT+j], (i + (rank * j))); */
             my_assert(recvbuf[i * COUNT + j] == (i + (rank * j)));
         }
     }
index 6158b7a..5cf9414 100644 (file)
@@ -18,12 +18,12 @@ red4 10
 alltoall1 8
 alltoallv 10
 alltoallv0 10
-#alltoallw1 10
-#alltoallw2 10
-#alltoallw_zeros 1
-#alltoallw_zeros 2
-#alltoallw_zeros 5
-#alltoallw_zeros 8
+alltoallw1 10
+alltoallw2 10
+alltoallw_zeros 1
+alltoallw_zeros 2
+alltoallw_zeros 5
+alltoallw_zeros 8
 allgather2 10
 allgather3 10
 allgatherv2 10
@@ -130,13 +130,13 @@ scatterv 4
 #uoplong 4
 #uoplong 11
 #uoplong 16
-nonblocking 4 mpiversion=3.0
-nonblocking 5 mpiversion=3.0
-nonblocking 10 mpiversion=3.0
-nonblocking2 1 mpiversion=3.0
-nonblocking2 4 mpiversion=3.0
-nonblocking2 5 mpiversion=3.0
-nonblocking2 10 timeLimit=420 mpiversion=3.0
+nonblocking 4
+nonblocking 5
+nonblocking 10
+nonblocking2 1
+nonblocking2 4
+nonblocking2 5
+nonblocking2 10
 nonblocking3 1 mpiversion=3.0
 nonblocking3 4 mpiversion=3.0
 nonblocking3 5 mpiversion=3.0
@@ -144,7 +144,7 @@ nonblocking3 10 timeLimit=600 mpiversion=3.0
 iallred 2 mpiversion=3.0
 # ibarrier will hang forever if it fails, but will complete quickly if it
 # succeeds
-ibarrier 2 mpiversion=3.0 timeLimit=30
+ibarrier 2 timeLimit=30
 
 # run some of the tests, relinked with the nbc_pmpi_adaptor.o file
 nballtoall1 8 mpiversion=3.0
index 7c537a4..50ad8f5 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 probe-unexp sendall sendflood sendrecv1 sendrecv2 sendrecv3 waitany-null waittestnull many_isend manylmt recv_any scancel scancel2 rcancel)
+          dtype_send greq1 probe-unexp rqstatus sendall sendflood sendrecv1 sendrecv2 sendrecv3 waitany-null waittestnull many_isend manylmt recv_any scancel scancel2 rcancel)
     # not compiled files: big_count_status bsend1 bsend2 bsend3 bsend4 bsend5 bsendalign bsendfrag bsendpending mprobe
-    # cancelrecv greq1 icsend large_message pscancel  rqfreeb rqstatus  sendself scancel_unmatch
+    # cancelrecv  icsend large_message pscancel  rqfreeb   sendself scancel_unmatch
     add_executable(${file} EXCLUDE_FROM_ALL ${file}.c)
     add_dependencies(tests ${file})
     target_link_libraries(${file} simgrid mtest_c)
index 80e84cd..7f151b5 100644 (file)
@@ -24,12 +24,11 @@ isendirecv 10
 #bsendfrag 2
 #needs MPI_Intercomm_create
 #icsend 4
-#needs MPI_Request_get_status
-#rqstatus 2
+rqstatus 2
 #needs MPI_Pack, MPI_Buffer_attach, MPI_Buffer_detach, MPI_Irsend, MPI_Ibsend
 #rqfreeb 4
 #needs MPI_Grequest_start MPI_Grequest_complete
-#greq1 1
+greq1 1
 probe-unexp 4
 probenull 1
 # For testing, scancel will run with 1 process as well
index ff7a329..7c7c8c6 100644 (file)
@@ -41,12 +41,20 @@ static lmm::System* new_system(method_t method)
   }
 }
 
-static double dichotomy(double func(double), double min, double max, double min_error)
+double a_test_1 = 0;
+double b_test_1 = 0;
+static double diff_lagrange_test_1(double x)
+{
+  return -(3 / (1 + 3 * x * x / 2) - 3 / (2 * (3 * (a_test_1 - x) * (a_test_1 - x) / 2 + 1)) +
+           3 / (2 * (3 * (b_test_1 - a_test_1 + x) * (b_test_1 - a_test_1 + x) / 2 + 1)));
+}
+
+static double dichotomy(double min, double max, double min_error)
 {
   double overall_error = 2 * min_error;
 
-  double min_func = func(min);
-  double max_func = func(max);
+  double min_func = diff_lagrange_test_1(min);
+  double max_func = diff_lagrange_test_1(max);
 
   if (min_func > 0 && max_func > 0)
     return min - 1.0;
@@ -72,7 +80,7 @@ static double dichotomy(double func(double), double min, double max, double min_
     if (fabs(min - middle) < 1e-12 || fabs(max - middle) < 1e-12) {
       break;
     }
-    double middle_func = func(middle);
+    double middle_func = diff_lagrange_test_1(middle);
     SHOW_EXPR(middle);
     SHOW_EXPR(middle_func);
 
@@ -91,14 +99,6 @@ static double dichotomy(double func(double), double min, double max, double min_
   return ((min + max) / 2.0);
 }
 
-double a_test_1 = 0;
-double b_test_1 = 0;
-static double diff_lagrange_test_1(double x)
-{
-  return -(3 / (1 + 3 * x * x / 2) - 3 / (2 * (3 * (a_test_1 - x) * (a_test_1 - x) / 2 + 1)) +
-           3 / (2 * (3 * (b_test_1 - a_test_1 + x) * (b_test_1 - a_test_1 + x) / 2 + 1)));
-}
-
 static void test1(method_t method)
 {
   double a = 1.0;
@@ -148,7 +148,7 @@ static void test1(method_t method)
     } else if (method == LAGRANGE_RENO) {
       a_test_1 = a;
       b_test_1 = b;
-      x = dichotomy(diff_lagrange_test_1, 0, a, 1e-13);
+      x        = dichotomy(0, a, 1e-13);
 
       if (x < 0)
         x = 0;
index 6e56862..2a23033 100644 (file)
@@ -90,4 +90,4 @@ $ rm -f ${bindir:=.}/log_usage.log ${bindir:=.}/log_usage_0.log ${bindir:=.}/log
 
 # Would be nice for code coverage, but the early exit leads to lots of memory leaks
 #! output ignore
-#$ $SG_TEST_EXENV ${bindir:=.}/log_usage --help --help-log-categories
+#$ $SG_TEST_EXENV ${bindir:=.}/log_usage --help-logs --help-log-categories
index 84b70b7..463104f 100644 (file)
@@ -62,7 +62,11 @@ in Appveyor's YAML:
 
 """
 
-import random, socket, ssl, sys, time
+import random
+import socket
+import ssl
+import sys
+import time
 
 
 def appveyor_vars():
@@ -170,7 +174,7 @@ if __name__ == '__main__':
                 # leave the channel
                 irc_sock.send('PART #{}\r\n'.format(channel).encode('utf_8'))
                 sys.exit()
-    except:
+    except BaseException:
         e = sys.exc_info()[0]
         print(e)
         sys.exit()
index 92ef0dd..9fb63c2 100644 (file)
@@ -203,6 +203,7 @@ set(SMPI_SRC
   src/smpi/colls/reduce/reduce-rab.cpp
   src/smpi/colls/scatter/scatter-ompi.cpp
   src/smpi/colls/scatter/scatter-mvapich-two-level.cpp
+  src/smpi/colls/smpi_nbc_impl.cpp
   src/smpi/colls/smpi_automatic_selector.cpp
   src/smpi/colls/smpi_default_selector.cpp
   src/smpi/colls/smpi_mpich_selector.cpp
@@ -536,7 +537,7 @@ list(APPEND JMSG_JAVA_SRC ${JTRACE_JAVA_SRC})
 set(LUA_SRC
   src/bindings/lua/lua_host.cpp
   src/bindings/lua/lua_platf.cpp
-  src/bindings/lua/lua_debug.cpp
+  src/bindings/lua/lua_utils.cpp
   src/bindings/lua/simgrid_lua.cpp
   )
 
@@ -887,7 +888,6 @@ set(DOC_SOURCES
   docs/source/Start_Your_Own_Project.rst
   docs/source/models.rst
   docs/source/platform.rst
-  docs/source/platform_examples.rst
   docs/source/platform_howtos.rst
   docs/source/platform_reference.rst
   docs/source/Configuring_SimGrid.rst
@@ -973,19 +973,20 @@ set(txt_files
 set(CMAKEFILES_TXT
   examples/s4u/CMakeLists.txt
   examples/smpi/CMakeLists.txt
-    examples/smpi/NAS/CMakeLists.txt
-    examples/smpi/smpi_msg_masterslave/CMakeLists.txt
-    examples/smpi/replay_multiple/CMakeLists.txt
-    examples/smpi/replay_multiple_manual_deploy/CMakeLists.txt
-    examples/smpi/energy/f77/CMakeLists.txt
-    examples/smpi/energy/f90/CMakeLists.txt
+  examples/smpi/NAS/CMakeLists.txt
+  examples/smpi/smpi_msg_masterslave/CMakeLists.txt
+  examples/smpi/replay_multiple/CMakeLists.txt
+  examples/smpi/replay_multiple_manual_deploy/CMakeLists.txt
+  examples/smpi/energy/f77/CMakeLists.txt
+  examples/smpi/energy/f90/CMakeLists.txt
   examples/python/CMakeLists.txt
   examples/deprecated/java/CMakeLists.txt
   examples/deprecated/msg/CMakeLists.txt
-    examples/deprecated/msg/mc/CMakeLists.txt
+  examples/deprecated/msg/mc/CMakeLists.txt
   examples/deprecated/simdag/CMakeLists.txt
 
   teshsuite/java/CMakeLists.txt
+  teshsuite/lua/CMakeLists.txt
   teshsuite/mc/CMakeLists.txt
   teshsuite/msg/CMakeLists.txt
   teshsuite/s4u/CMakeLists.txt
index ead60a7..4765bd4 100644 (file)
@@ -232,7 +232,7 @@ if(enable_maintainer_mode AND NOT WIN32)
       message(STATUS "Error : Install sed before use maintainer mode.")
     endif()
 
-    message(FATAL_ERROR STATUS "Error : Need to install all tools for maintainer mode !!!")
+    message(FATAL_ERROR STATUS "Error : Need to install all (flexml, flex, sed) tools for maintainer mode !!!")
   endif()
 
 endif()
index 107579e..c175f19 100644 (file)
@@ -91,35 +91,6 @@ IF(enable_java)
   ENDIF()
 ENDIF()
 
-IF(SIMGRID_HAVE_MC)
-  ADD_TESH_FACTORIES(mc-bugged1                "ucontext;raw" --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1.tesh)
-  ADD_TESH_FACTORIES(mc-bugged2                "ucontext;raw" --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged2.tesh)
-  IF(HAVE_UCONTEXT_CONTEXTS AND SIMGRID_PROCESSOR_x86_64) # liveness model-checking works only on 64bits (for now ...)
-    ADD_TESH(mc-bugged1-liveness-ucontext         --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1_liveness.tesh)
-    ADD_TESH(mc-bugged1-liveness-ucontext-sparse  --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1_liveness_sparse.tesh)
-    ADD_TESH(mc-bugged1-liveness-visited-ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1_liveness_visited.tesh)
-    ADD_TESH(mc-bugged1-liveness-visited-ucontext-sparse --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc bugged1_liveness_visited_sparse.tesh)
-    IF(HAVE_C_STACK_CLEANER)
-      # This test checks if the stack cleaner is making a difference:
-      ADD_TEST(mc-bugged1-liveness-stack-cleaner ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc/bugged1_liveness_stack_cleaner ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/mc/ ${CMAKE_BINARY_DIR}/examples/deprecated/msg/mc/)
-    ENDIF()
-  ENDIF()
-ENDIF()
-
-IF(enable_smpi_MPICH3_testsuite AND SMPI_FORTRAN)
-  ADD_TEST(test-smpi-mpich3-thread-f77     ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f77/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${TESH_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f77/ -tests=testlist -privatization=${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/stack-size:8000 -execarg=--cfg=contexts/factory:thread -execarg=--cfg=smpi/privatization:${HAVE_PRIVATIZATION})
-  SET_TESTS_PROPERTIES(test-smpi-mpich3-thread-f77 PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
-  ADD_TEST(test-smpi-mpich3-thread-f90     ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/f90/ ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests "-wrapper=${TESH_WRAPPER}" -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/f90/ -tests=testlist -privatization=${HAVE_PRIVATIZATION} -execarg=--cfg=smpi/privatization:${HAVE_PRIVATIZATION} -execarg=--cfg=contexts/factory:thread)
-  SET_TESTS_PROPERTIES(test-smpi-mpich3-thread-f90 PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
-ENDIF()
-
-IF(SIMGRID_HAVE_LUA)
-  # Tests testing simulation from C but using lua for platform files. Executed like this
-  # ~$ ./masterslave platform.lua deploy.lua
-  ADD_TESH(lua-platform-masterslave                --setenv srcdir=${CMAKE_HOME_DIRECTORY} --setenv bindir=${CMAKE_BINARY_DIR} --cd ${CMAKE_BINARY_DIR} ${CMAKE_HOME_DIRECTORY}/teshsuite/lua/lua_platforms.tesh)
-  SET_TESTS_PROPERTIES(lua-platform-masterslave    PROPERTIES ENVIRONMENT "LUA_CPATH=${CMAKE_BINARY_DIR}/lib/lib?.${LIB_EXE}")
-ENDIF()
-
 # New tests should use the Catch Framework
 set(UNIT_TESTS  src/xbt/unit-tests_main.cpp
                 src/kernel/resource/profile/trace_mgr_test.cpp
index b68e431..f7cc5c4 100644 (file)
@@ -49,6 +49,7 @@ def convert(xml, formats, attrib):
 def formats(ll):
     return sorted(((Decimal(i), j) for i, j in ll), key=lambda x: x[0], reverse=True)
 
+
 for root, dirnames, filenames in os.walk(sys.argv[1]):
     for filename in fnmatch.filter(filenames, '*.xml'):
         print root, dirnames, filename
index f1a5ed7..995d328 100755 (executable)
@@ -35,7 +35,7 @@ def convert_trace(trace_path, base_path, output_path, trace_version="1.0"):
 
         new_file_path = os.path.join(output_path, trace_path)
         pathlib.Path(os.path.dirname(new_file_path)).mkdir(
-                parents=True, exist_ok=True)
+            parents=True, exist_ok=True)
 
         with open(new_file_path, "w") as new_trace:
             # Write header
@@ -44,7 +44,7 @@ def convert_trace(trace_path, base_path, output_path, trace_version="1.0"):
             last_async_call_src = None
             last_async_call_dst = None
             for line_num, line in enumerate(trace_file.readlines()):
-                #print(line)
+                # print(line)
                 new_line = None
                 split_line = line.lower().strip().split(" ")
                 mpi_call = split_line[1]
@@ -63,8 +63,8 @@ def convert_trace(trace_path, base_path, output_path, trace_version="1.0"):
                     if (last_async_call_src is None
                             or last_async_call_dst is None):
                         raise Exception("Invalid traces: No Isend or Irecv "
-                                "found before the wait in line " +
-                                str(line_num) + " in file " + old_file_path )
+                                        "found before the wait in line " +
+                                        str(line_num) + " in file " + old_file_path)
                     new_line = insert_elem(split_line, 2, last_async_call_src)
                     new_line = insert_elem(split_line, 3, last_async_call_dst)
                     new_line = insert_elem(split_line, 4, "0")
@@ -81,14 +81,13 @@ if __name__ == "__main__":
     import argparse
     import sys
 
-
     parser = argparse.ArgumentParser(description=sys.modules[__name__].__doc__)
 
     parser.add_argument('trace_list_file', type=argparse.FileType('r'),
-            default=sys.stdin, help="The trace list file (e.g. smpi_simgrid.txt)")
+                        default=sys.stdin, help="The trace list file (e.g. smpi_simgrid.txt)")
 
     parser.add_argument('--output_path', '-o', default="converted_traces",
-            help="The path where converted traces will be put")
+                        help="The path where converted traces will be put")
 
     args = parser.parse_args()
 
@@ -96,7 +95,7 @@ if __name__ == "__main__":
 
     # creates results dir
     pathlib.Path(args.output_path).mkdir(
-            parents=True, exist_ok=True)
+        parents=True, exist_ok=True)
 
     # copy trace list file
     try:
@@ -106,7 +105,6 @@ if __name__ == "__main__":
               "Please, select another output path")
         sys.exit(-1)
 
-
     with open(trace_list_file_path) as tracelist_file:
         trace_list = tracelist_file.readlines()
 
index 16116ee..dc7b629 100755 (executable)
@@ -26,7 +26,8 @@ under the terms of the license (GNU LGPL) which comes with this package.
 """
 
 
-import sys, os
+import sys
+import os
 import shlex
 import re
 import difflib
@@ -45,57 +46,65 @@ else:
 #
 #
 
+
 def isWindows():
     return sys.platform.startswith('win')
 
 # Singleton metaclass that works in Python 2 & 3
 # http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python
+
+
 class _Singleton(type):
     """ A metaclass that creates a Singleton base class when called. """
     _instances = {}
+
     def __call__(cls, *args, **kwargs):
         if cls not in cls._instances:
             cls._instances[cls] = super(_Singleton, cls).__call__(*args, **kwargs)
         return cls._instances[cls]
-class Singleton(_Singleton('SingletonMeta', (object,), {})): pass
 
-SIGNALS_TO_NAMES_DICT = dict((getattr(signal, n), n) \
-    for n in dir(signal) if n.startswith('SIG') and '_' not in n )
 
+class Singleton(_Singleton('SingletonMeta', (object,), {})):
+    pass
+
+
+SIGNALS_TO_NAMES_DICT = dict((getattr(signal, n), n)
+                             for n in dir(signal) if n.startswith('SIG') and '_' not in n)
 
 
-#exit correctly
+# exit correctly
 def tesh_exit(errcode):
-    #If you do not flush some prints are skipped
+    # If you do not flush some prints are skipped
     sys.stdout.flush()
-    #os._exit exit even when executed within a thread
+    # os._exit exit even when executed within a thread
     os._exit(errcode)
 
 
 def fatal_error(msg):
-    print("[Tesh/CRITICAL] "+str(msg))
+    print("[Tesh/CRITICAL] " + str(msg))
     tesh_exit(1)
 
 
-#Set an environment variable.
+# Set an environment variable.
 # arg must be a string with the format "variable=value"
 def setenv(arg):
-    print("[Tesh/INFO] setenv "+arg)
+    print("[Tesh/INFO] setenv " + arg)
     t = arg.split("=", 1)
     os.environ[t[0]] = t[1]
-    #os.putenv(t[0], t[1]) does not work
-    #see http://stackoverflow.com/questions/17705419/python-os-environ-os-putenv-usr-bin-env
+    # os.putenv(t[0], t[1]) does not work
+    # see http://stackoverflow.com/questions/17705419/python-os-environ-os-putenv-usr-bin-env
 
 
-#http://stackoverflow.com/questions/30734967/how-to-expand-environment-variables-in-python-as-bash-does
+# http://stackoverflow.com/questions/30734967/how-to-expand-environment-variables-in-python-as-bash-does
 def expandvars2(path):
     return re.sub(r'(?<!\\)\$[A-Za-z_][A-Za-z0-9_]*', '', os.path.expandvars(path))
 
+
 # https://github.com/Cadair/jupyter_environment_kernels/issues/10
 try:
     FileNotFoundError
 except NameError:
-    #py2
+    # py2
     FileNotFoundError = OSError
 
 ##############
@@ -107,8 +116,9 @@ except NameError:
 # Global variable. Stores which process group should be killed (or None otherwise)
 pgtokill = None
 
+
 def kill_process_group(pgid):
-    if pgid is None: # Nobody to kill. We don't know who to kill on windows, or we don't have anyone to kill on signal handler
+    if pgid is None:  # Nobody to kill. We don't know who to kill on windows, or we don't have anyone to kill on signal handler
         return
 
     # print("Kill process group {}".format(pgid))
@@ -118,6 +128,7 @@ def kill_process_group(pgid):
         # os.killpg failed. OK. Some subprocesses may still be running.
         pass
 
+
 def signal_handler(signal, frame):
     print("Caught signal {}".format(SIGNALS_TO_NAMES_DICT[signal]))
     if pgtokill is not None:
@@ -125,7 +136,6 @@ def signal_handler(signal, frame):
     tesh_exit(5)
 
 
-
 ##############
 #
 # Classes
@@ -133,7 +143,6 @@ def signal_handler(signal, frame):
 #
 
 
-
 # read file line per line (and concat line that ends with "\")
 class FileReader(Singleton):
     def __init__(self, filename=None):
@@ -149,7 +158,7 @@ class FileReader(Singleton):
         self.linenumber = 0
 
     def __repr__(self):
-        return self.filename+":"+str(self.linenumber)
+        return self.filename + ":" + str(self.linenumber)
 
     def readfullline(self):
         try:
@@ -169,14 +178,14 @@ class FileReader(Singleton):
         return txt
 
 
-#keep the state of tesh (mostly configuration values)
+# keep the state of tesh (mostly configuration values)
 class TeshState(Singleton):
     def __init__(self):
         self.threads = []
         self.args_suffix = ""
         self.ignore_regexps_common = []
-        self.jenkins = False # not a Jenkins run by default
-        self.timeout = 10 # default value: 10 sec
+        self.jenkins = False  # not a Jenkins run by default
+        self.timeout = 10  # default value: 10 sec
         self.wrapper = None
         self.keep = False
 
@@ -189,6 +198,8 @@ class TeshState(Singleton):
             t.release()
 
 # Command line object
+
+
 class Cmd(object):
     def __init__(self):
         self.input_pipe = []
@@ -229,15 +240,14 @@ class Cmd(object):
 
     def remove_ignored_lines(self, lines):
         for ign in self.ignore_regexps:
-                lines = [l for l in lines if not ign.match(l)]
+            lines = [l for l in lines if not ign.match(l)]
         return lines
 
-
     def _cmd_mkfile(self, argline):
         filename = argline[len("mkfile "):]
         file = open(filename, "w")
         if file is None:
-            fatal_error("Unable to create file "+filename)
+            fatal_error("Unable to create file " + filename)
         file.write("\n".join(self.input_pipe))
         file.write("\n")
         file.close()
@@ -248,54 +258,55 @@ class Cmd(object):
             fatal_error("Too many arguments to cd")
         try:
             os.chdir(args[1])
-            print("[Tesh/INFO] change directory to "+args[1])
+            print("[Tesh/INFO] change directory to " + args[1])
         except FileNotFoundError:
-            print("Chdir to "+args[1]+" failed: No such file or directory")
-            print("Test suite `"+FileReader().filename+"': NOK (system error)")
+            print("Chdir to " + args[1] + " failed: No such file or directory")
+            print("Test suite `" + FileReader().filename + "': NOK (system error)")
             tesh_exit(4)
 
-
-    #Run the Cmd if possible.
+    # Run the Cmd if possible.
     # Return False if nothing has been ran.
+
     def run_if_possible(self):
         if self.can_run():
             if self.background:
                 lock = _thread.allocate_lock()
                 lock.acquire()
                 TeshState().add_thread(lock)
-                _thread.start_new_thread( Cmd._run, (self, lock) )
+                _thread.start_new_thread(Cmd._run, (self, lock))
             else:
                 self._run()
             return True
         else:
             return False
 
-
     def _run(self, lock=None):
         # Python threads loose the cwd
         os.chdir(self.cwd)
 
-        #retrocompatibility: support ${aaa:=.} variable format
+        # retrocompatibility: support ${aaa:=.} variable format
         def replace_perl_variables(m):
             vname = m.group(1)
             vdefault = m.group(2)
             if vname in os.environ:
-                return "$"+vname
+                return "$" + vname
             else:
                 return vdefault
         self.args = re.sub(r"\${(\w+):=([^}]*)}", replace_perl_variables, self.args)
 
-        #replace bash environment variables ($THINGS) to their values
+        # replace bash environment variables ($THINGS) to their values
         self.args = expandvars2(self.args)
 
         if re.match("^mkfile ", self.args) is not None:
             self._cmd_mkfile(self.args)
-            if lock is not None: lock.release()
+            if lock is not None:
+                lock.release()
             return
 
         if re.match("^cd ", self.args) is not None:
             self._cmd_cd(self.args)
-            if lock is not None: lock.release()
+            if lock is not None:
+                lock.release()
             return
 
         if TeshState().wrapper is not None:
@@ -303,12 +314,12 @@ class Cmd(object):
             self.args = TeshState().wrapper + self.args
         elif re.match(".*smpirun.*", self.args) is not None:
             self.args = "sh " + self.args
-        if TeshState().jenkins and self.timeout != None:
+        if TeshState().jenkins and self.timeout is not None:
             self.timeout *= 10
 
         self.args += TeshState().args_suffix
 
-        print("["+FileReader().filename+":"+str(self.linenumber)+"] "+self.args)
+        print("[" + FileReader().filename + ":" + str(self.linenumber) + "] " + self.args)
 
         args = shlex.split(self.args)
         #print (args)
@@ -316,7 +327,14 @@ class Cmd(object):
         global pgtokill
 
         try:
-            proc = subprocess.Popen(args, bufsize=1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, start_new_session=True)
+            proc = subprocess.Popen(
+                args,
+                bufsize=1,
+                stdin=subprocess.PIPE,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.STDOUT,
+                universal_newlines=True,
+                start_new_session=True)
             try:
                 if not isWindows():
                     pgtokill = os.getpgid(proc.pid)
@@ -324,41 +342,45 @@ class Cmd(object):
                 # os.getpgid failed. OK. No cleanup.
                 pass
         except PermissionError:
-            print("["+FileReader().filename+":"+str(self.linenumber)+"] Cannot start '"+args[0]+"': The binary is not executable.")
-            print("["+FileReader().filename+":"+str(self.linenumber)+"] Current dir: "+os.getcwd())
+            print("[" + FileReader().filename + ":" + str(self.linenumber) +
+                  "] Cannot start '" + args[0] + "': The binary is not executable.")
+            print("[" + FileReader().filename + ":" + str(self.linenumber) + "] Current dir: " + os.getcwd())
             tesh_exit(3)
         except NotADirectoryError:
-            print("["+FileReader().filename+":"+str(self.linenumber)+"] Cannot start '"+args[0]+"': The path to binary does not exist.")
-            print("["+FileReader().filename+":"+str(self.linenumber)+"] Current dir: "+os.getcwd())
+            print("[" + FileReader().filename + ":" + str(self.linenumber) + "] Cannot start '" +
+                  args[0] + "': The path to binary does not exist.")
+            print("[" + FileReader().filename + ":" + str(self.linenumber) + "] Current dir: " + os.getcwd())
             tesh_exit(3)
         except FileNotFoundError:
-            print("["+FileReader().filename+":"+str(self.linenumber)+"] Cannot start '"+args[0]+"': File not found")
+            print("[" + FileReader().filename + ":" + str(self.linenumber) +
+                  "] Cannot start '" + args[0] + "': File not found")
             tesh_exit(3)
         except OSError as osE:
             if osE.errno == 8:
                 osE.strerror += "\nOSError: [Errno 8] Executed scripts should start with shebang line (like #!/usr/bin/env sh)"
             raise osE
 
-        cmdName = FileReader().filename+":"+str(self.linenumber)
+        cmdName = FileReader().filename + ":" + str(self.linenumber)
         try:
             (stdout_data, stderr_data) = proc.communicate("\n".join(self.input_pipe), self.timeout)
             pgtokill = None
         except subprocess.TimeoutExpired:
-            print("Test suite `"+FileReader().filename+"': NOK (<"+cmdName+"> timeout after "+str(self.timeout)+" sec)")
+            print("Test suite `" + FileReader().filename + "': NOK (<" +
+                  cmdName + "> timeout after " + str(self.timeout) + " sec)")
             kill_process_group(pgtokill)
             tesh_exit(3)
 
         if self.output_display:
             print(stdout_data)
 
-        #remove text colors
+        # remove text colors
         ansi_escape = re.compile(r'\x1b[^m]*m')
         stdout_data = ansi_escape.sub('', stdout_data)
 
         #print ((stdout_data, stderr_data))
 
         if self.ignore_output:
-            print("(ignoring the output of <"+cmdName+"> as requested)")
+            print("(ignoring the output of <" + cmdName + "> as requested)")
         else:
             stdouta = stdout_data.split("\n")
             while len(stdouta) > 0 and stdouta[-1] == "":
@@ -374,13 +396,19 @@ class Cmd(object):
                 stdouta.sort(key=lambda x: x[:self.sort].lower())
                 self.output_pipe_stdout.sort(key=lambda x: x[:self.sort].lower())
 
-            diff = list(difflib.unified_diff(self.output_pipe_stdout, stdouta,lineterm="",fromfile='expected', tofile='obtained'))
+            diff = list(
+                difflib.unified_diff(
+                    self.output_pipe_stdout,
+                    stdouta,
+                    lineterm="",
+                    fromfile='expected',
+                    tofile='obtained'))
             if len(diff) > 0:
-                print("Output of <"+cmdName+"> mismatch:")
-                if self.sort >= 0: # If sorted, truncate the diff output and show the unsorted version
-                    difflen = 0;
+                print("Output of <" + cmdName + "> mismatch:")
+                if self.sort >= 0:  # If sorted, truncate the diff output and show the unsorted version
+                    difflen = 0
                     for line in diff:
-                        if difflen<50:
+                        if difflen < 50:
                             print(line)
                         difflen += 1
                     if difflen > 50:
@@ -388,46 +416,48 @@ class Cmd(object):
                     print("Unsorted observed output:\n")
                     for line in stdcpy:
                         print(line)
-                else: # If not sorted, just display the diff
+                else:  # If not sorted, just display the diff
                     for line in diff:
                         print(line)
 
-                print("Test suite `"+FileReader().filename+"': NOK (<"+cmdName+"> output mismatch)")
-                if lock is not None: lock.release()
+                print("Test suite `" + FileReader().filename + "': NOK (<" + cmdName + "> output mismatch)")
+                if lock is not None:
+                    lock.release()
                 if TeshState().keep:
-                    f = open('obtained','w')
+                    f = open('obtained', 'w')
                     obtained = stdout_data.split("\n")
                     while len(obtained) > 0 and obtained[-1] == "":
                         del obtained[-1]
                     obtained = self.remove_ignored_lines(obtained)
                     for line in obtained:
-                        f.write("> "+line+"\n")
+                        f.write("> " + line + "\n")
                     f.close()
-                    print("Obtained output kept as requested: "+os.path.abspath("obtained"))
+                    print("Obtained output kept as requested: " + os.path.abspath("obtained"))
                 tesh_exit(2)
 
         #print ((proc.returncode, self.expect_return))
 
         if proc.returncode != self.expect_return:
             if proc.returncode >= 0:
-                print("Test suite `"+FileReader().filename+"': NOK (<"+cmdName+"> returned code "+str(proc.returncode)+")")
-                if lock is not None: lock.release()
+                print("Test suite `" + FileReader().filename + "': NOK (<" +
+                      cmdName + "> returned code " + str(proc.returncode) + ")")
+                if lock is not None:
+                    lock.release()
                 tesh_exit(2)
             else:
-                print("Test suite `"+FileReader().filename+"': NOK (<"+cmdName+"> got signal "+SIGNALS_TO_NAMES_DICT[-proc.returncode]+")")
-                if lock is not None: lock.release()
+                print("Test suite `" + FileReader().filename + "': NOK (<" + cmdName +
+                      "> got signal " + SIGNALS_TO_NAMES_DICT[-proc.returncode] + ")")
+                if lock is not None:
+                    lock.release()
                 tesh_exit(-proc.returncode)
 
-        if lock is not None: lock.release()
-
-
+        if lock is not None:
+            lock.release()
 
     def can_run(self):
         return self.args is not None
 
 
-
-
 ##############
 #
 # Main
@@ -435,7 +465,6 @@ class Cmd(object):
 #
 
 
-
 if __name__ == '__main__':
     signal.signal(signal.SIGINT, signal_handler)
     signal.signal(signal.SIGTERM, signal_handler)
@@ -443,13 +472,22 @@ if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='tesh -- testing shell', add_help=True)
     group1 = parser.add_argument_group('Options')
     group1.add_argument('teshfile', nargs='?', help='Name of teshfile, stdin if omitted')
-    group1.add_argument('--cd', metavar='some/directory', help='ask tesh to switch the working directory before launching the tests')
+    group1.add_argument(
+        '--cd',
+        metavar='some/directory',
+        help='ask tesh to switch the working directory before launching the tests')
     group1.add_argument('--setenv', metavar='var=value', action='append', help='set a specific environment variable')
     group1.add_argument('--cfg', metavar='arg', action='append', help='add parameter --cfg=arg to each command line')
     group1.add_argument('--log', metavar='arg', action='append', help='add parameter --log=arg to each command line')
-    group1.add_argument('--ignore-jenkins', action='store_true', help='ignore all cruft generated on SimGrid continous integration servers')
+    group1.add_argument(
+        '--ignore-jenkins',
+        action='store_true',
+        help='ignore all cruft generated on SimGrid continous integration servers')
     group1.add_argument('--wrapper', metavar='arg', help='Run each command in the provided wrapper (eg valgrind)')
-    group1.add_argument('--keep', action='store_true', help='Keep the obtained output when it does not match the expected one')
+    group1.add_argument(
+        '--keep',
+        action='store_true',
+        help='Keep the obtained output when it does not match the expected one')
 
     try:
         options = parser.parse_args()
@@ -464,32 +502,33 @@ if __name__ == '__main__':
         print("Ignore all cruft seen on SimGrid's continous integration servers")
         # Note: regexps should match at the beginning of lines
         TeshState().ignore_regexps_common = [
-           re.compile(r"profiling:"),
-           re.compile(r"Unable to clean temporary file C:"),
-           re.compile(r".*Configuration change: Set 'contexts/"),
-           re.compile(r"Picked up JAVA_TOOL_OPTIONS: "),
-           re.compile(r"Picked up _JAVA_OPTIONS: "),
-           re.compile(r"==[0-9]+== ?WARNING: ASan doesn't fully support"),
-           re.compile(r"==[0-9]+== ?WARNING: ASan is ignoring requested __asan_handle_no_return: stack top:"),
-           re.compile(r"False positive error reports may follow"),
-           re.compile(r"For details see http://code.google.com/p/address-sanitizer/issues/detail\?id=189"),
-           re.compile(r"For details see https://github.com/google/sanitizers/issues/189"),
-           re.compile(r"Python runtime initialized with LC_CTYPE=C .*"),
-           re.compile(r"cmake: /usr/local/lib/libcurl\.so\.4: no version information available \(required by cmake\)"), # Seen on CircleCI
-           re.compile(r".*mmap broken on FreeBSD, but dlopen\+thread broken too. Switching to dlopen\+raw contexts\."),
-           re.compile(r".*dlopen\+thread broken on Apple and BSD\. Switching to raw contexts\."),
-           ]
-        TeshState().jenkins = True # This is a Jenkins build
+            re.compile(r"profiling:"),
+            re.compile(r"Unable to clean temporary file C:"),
+            re.compile(r".*Configuration change: Set 'contexts/"),
+            re.compile(r"Picked up JAVA_TOOL_OPTIONS: "),
+            re.compile(r"Picked up _JAVA_OPTIONS: "),
+            re.compile(r"==[0-9]+== ?WARNING: ASan doesn't fully support"),
+            re.compile(r"==[0-9]+== ?WARNING: ASan is ignoring requested __asan_handle_no_return: stack top:"),
+            re.compile(r"False positive error reports may follow"),
+            re.compile(r"For details see http://code.google.com/p/address-sanitizer/issues/detail\?id=189"),
+            re.compile(r"For details see https://github.com/google/sanitizers/issues/189"),
+            re.compile(r"Python runtime initialized with LC_CTYPE=C .*"),
+            # Seen on CircleCI
+            re.compile(r"cmake: /usr/local/lib/libcurl\.so\.4: no version information available \(required by cmake\)"),
+            re.compile(r".*mmap broken on FreeBSD, but dlopen\+thread broken too. Switching to dlopen\+raw contexts\."),
+            re.compile(r".*dlopen\+thread broken on Apple and BSD\. Switching to raw contexts\."),
+        ]
+        TeshState().jenkins = True  # This is a Jenkins build
 
     if options.teshfile is None:
         f = FileReader(None)
         print("Test suite from stdin")
     else:
         if not os.path.isfile(options.teshfile):
-            print("Cannot open teshfile '"+options.teshfile+"': File not found")
+            print("Cannot open teshfile '" + options.teshfile + "': File not found")
             tesh_exit(3)
         f = FileReader(options.teshfile)
-        print("Test suite '"+f.abspath+"'")
+        print("Test suite '" + f.abspath + "'")
 
     if options.setenv is not None:
         for e in options.setenv:
@@ -508,14 +547,14 @@ if __name__ == '__main__':
     if options.keep:
         TeshState().keep = True
 
-    #cmd holds the current command line
+    # cmd holds the current command line
     # tech commands will add some parameters to it
     # when ready, we execute it.
     cmd = Cmd()
 
     line = f.readfullline()
     while line is not None:
-        #print(">>============="+line+"==<<")
+        # print(">>============="+line+"==<<")
         if len(line) == 0:
             #print ("END CMD block")
             if cmd.run_if_possible():
@@ -525,7 +564,7 @@ if __name__ == '__main__':
             pass
 
         elif line[0:2] == "p ":
-            print("["+str(FileReader())+"] "+line[2:])
+            print("[" + str(FileReader()) + "] " + line[2:])
 
         elif line[0:2] == "< ":
             cmd.add_input_pipe(line[2:])
@@ -559,11 +598,11 @@ if __name__ == '__main__':
             #print("expect return "+str(int(line[16:])))
         elif line[0:15] == "! expect signal":
             sig = line[16:]
-            #get the signal integer value from the signal module
+            # get the signal integer value from the signal module
             if sig not in signal.__dict__:
-                fatal_error("unrecognized signal '"+sig+"'")
+                fatal_error("unrecognized signal '" + sig + "'")
             sig = int(signal.__dict__[sig])
-            #popen return -signal when a process ends with a signal
+            # popen return -signal when a process ends with a signal
             cmd.expect_return = -sig
         elif line[0:len("! timeout ")] == "! timeout ":
             if "no" in line[len("! timeout "):]:
@@ -586,7 +625,6 @@ if __name__ == '__main__':
         else:
             fatal_error("UNRECOGNIZED OPTION")
 
-
         line = f.readfullline()
 
     cmd.run_if_possible()
@@ -596,4 +634,4 @@ if __name__ == '__main__':
     if f.filename == "(stdin)":
         print("Test suite from stdin OK")
     else:
-        print("Test suite `"+f.filename+"' OK")
+        print("Test suite `" + f.filename + "' OK")