#- choco install lua53
# We need python v3
- cmd: SET PATH=C:\Python37-x64;%PATH% # We need python v3
+# Ugly hack to ignore versions 3.8 and later of Python
+- rename "C:\Python38-x64\python.exe" "python-ignored.exe"
+- rename "C:\Python39-x64\python.exe" "python-ignored.exe"
# Use the mingw-w64 provided by Appveyor (must be placed before Perl in the path)
- cmd: SET PATH=C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\;%PATH%
# Work around a bug on appveyor where the default sh is not the one I expect
examples/c/platform-properties/c-platform-properties
examples/c/plugin-hostload/c-plugin-hostload
examples/c/synchro-semaphore/c-synchro-semaphore
-examples/deprecated/msg/app-masterworker/app-masterworker
-examples/deprecated/msg/cloud-masterworker/cloud-masterworker
-examples/deprecated/msg/dht-kademlia/dht-kademlia
-examples/deprecated/msg/dht-pastry/dht-pastry
examples/deprecated/msg/mc/bugged2_liveness
-examples/deprecated/msg/mc/bugged3
examples/deprecated/msg/mc/centralized_mutex
-examples/deprecated/msg/mc/electric_fence
-examples/deprecated/msg/synchro-semaphore/synchro-semaphore
-examples/deprecated/msg/trace-categories/trace-categories
-examples/deprecated/msg/trace-host-user-variables/trace-host-user-variables
-examples/deprecated/msg/trace-link-user-variables/trace-link-user-variables
-examples/deprecated/msg/trace-masterworker/trace-masterworker
-examples/deprecated/msg/trace-process-migration/trace-process-migration
-examples/deprecated/msg/trace-route-user-variables/trace-route-user-variables
-examples/deprecated/msg/*.pcap
-examples/deprecated/msg/*.tr
examples/s4u/actor-create/s4u-actor-create
examples/s4u/actor-daemon/s4u-actor-daemon
examples/s4u/actor-exiting/s4u-actor-exiting
examples/s4u/synchro-condition-variable/s4u-synchro-condition-variable
examples/s4u/synchro-mutex/s4u-synchro-mutex
examples/s4u/synchro-semaphore/s4u-synchro-semaphore
+examples/s4u/trace-categories/s4u-trace-categories
+examples/s4u/trace-host-user-variables/s4u-trace-host-user-variables
+examples/s4u/trace-link-user-variables/s4u-trace-link-user-variables
+examples/s4u/trace-masterworkers/s4u-trace-masterworkers
examples/s4u/trace-platform/s4u-trace-platform
+examples/s4u/trace-process-migration/s4u-trace-process-migration
+examples/s4u/trace-route-user-variables/s4u-trace-route-user-variables
examples/deprecated/simdag/dag-dotload/sd_dag-dotload
examples/deprecated/simdag/daxload/sd_daxload
examples/deprecated/simdag/fail/sd_fail
# .mailmap file, used by git shortlog
#
+Ehsan Azimi <eazimi@ehsan.irisa.fr> <azimi.ehsan@outlook.com>
Khaled Baati <kbaati@realopt-Latitude-E6530>
Benoît Bimal <bimal@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Laurent Bobelin <lbobelin@mintcar.lip.ens-lyon.fr> <lbobelin@mintcar.imag.fr>
endif()
# tesh.py needs python 3 (or the module python-subprocess32 on python2.8+)
-set(PythonInterp_FIND_VERSION 3)
-set(PythonInterp_FIND_VERSION_COUNT 1)
-set(PythonInterp_FIND_VERSION_MAJOR 3)
-include(FindPythonInterp)
-if(NOT PYTHONINTERP_FOUND)
- message(FATAL_ERROR "Please install Python (version 3 or higher) to compile SimGrid.")
+if(CMAKE_VERSION VERSION_LESS "3.12")
+ set(PythonInterp_FIND_VERSION 3)
+ set(PythonInterp_FIND_VERSION_COUNT 1)
+ set(PythonInterp_FIND_VERSION_MAJOR 3)
+ include(FindPythonInterp)
+ if(NOT PYTHONINTERP_FOUND)
+ message(FATAL_ERROR "Please install Python (version 3 or higher) to compile SimGrid.")
+ endif()
+else()
+ find_package(Python3 COMPONENTS Interpreter Development)
+ if(NOT Python3_Interpreter_FOUND)
+ message(FATAL_ERROR "Please install Python (version 3 or higher) to compile SimGrid.")
+ endif()
+ set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
endif()
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
set(pybind11_FOUND ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_HOME_DIRECTORY}/pybind11/tools/)
- set(Python_ADDITIONAL_VERSIONS 3.7 3.6 3.5 3.4)
+ set(Python_ADDITIONAL_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4)
find_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} REQUIRED)
else()
endif()
endif()
- if(NOT PYTHONLIBS_FOUND)
+ if(NOT PYTHONLIBS_FOUND AND NOT Python3_Development_FOUND)
message(STATUS "Python libs not found. Turn pybind11 off.")
set(pybind11_FOUND OFF)
- LTO behavior on GCC can be parameterized using LTO_EXTRA_FLAG in cmake.
Setting it to "auto" will use all available cores, while setting it to n will
use n cores to speedup link step (usage: cmake -DLTO_EXTRA_FLAG=4).
- - Remove obsolete option --cfg=contexts/parallel-threshold.
+ - Remove obsolete runtime option 'contexts/parallel-threshold'.
+ - Runtime option 'tracing/msg/process' renamed to 'tracing/actor'. The old name
+ has been kept for compatibility.
+ - Finally remove obsolete snake_case() aliases for runtime options.
- Further improve the documentation.
S4U:
- smpicc/cxx/ff/f90 now will actually perform definition checks at link time. When
building shared libraries, this may cause issues, so environment variable
SMPI_NO_UNDEFINED_CHECK can be added to disable this.
+ - most temporary files should now be created in /tmp dir (or equivalent).
+ If this one does not allow execution of code (noexec flag), this may cause issues.
+ Please use another tmp directory (using TMPDIR or equivalent system variable)
+ in this case
+
+XBT:
+ - Drop xbt_str_split().
C binding and interface:
- The return type of the sg_actor_on_exit() callbacks is now 'void'
(int value was previously ignored)
+ - Many C functions were renamed to follow a common naming style
+ (sg_object_get_something and sg_object_set_something). As usual, the deprecated
+ names are kept until version 3.30.
- Many MSG tests were converted to the new S4U's interface in C, that
was extended for that.
- FG#48: The Impossible Did Happen (yet again)
- FG#50: Suspending an actor executed at the current timestamp fails
- FG#52: Zero-seconds timeout : "That's in the past already"
+ - FG#53: Crash while using ns-3 network model
- FG#54: How to suspend a comm?
+ - FG!22: Stochastic Profiles
- FG!24: Documentation and fix for xbt/random
- FG!35: Add a modeling hint for parallel links in doc
- FG!36: [xbt/random] Read/Write the state of the RNG
- GH#128: Parallelization of simulation with --cfg=contexts/nthreads
- GH#139: Allow pthread creation in SMPI
- GH#336: Packet-level simulation using SMPI?
+ - GH#345: Error in the LMM while migrating a VM
- GH#346: [SMPI] error while loading shared libraries: libsimgrid.so
+ - GH#352: pip install / python setup.py install fail to find pybind11
- GH!337: Fix link_energy plugin for wifi platforms
- GH!339: Add Mailbox set_receiver method to python binding
- GH!344: Cast hugepages macros parameters to int64
include examples/deprecated/java/trace/pingpong/Receiver.java
include examples/deprecated/java/trace/pingpong/Sender.java
include examples/deprecated/java/trace/pingpong/trace-pingpong.tesh
-include examples/deprecated/msg/README.doc
include examples/deprecated/msg/mc/bugged2-liveness.tesh
include examples/deprecated/msg/mc/bugged2_liveness.c
include examples/deprecated/msg/mc/centralized_mutex.c
include examples/deprecated/msg/mc/deploy_bugged2_liveness.xml
include examples/deprecated/msg/mc/deploy_centralized_mutex.xml
include examples/deprecated/msg/mc/promela_bugged2_liveness
-include examples/deprecated/msg/trace-categories/trace-categories.c
-include examples/deprecated/msg/trace-categories/trace-categories.tesh
-include examples/deprecated/msg/trace-host-user-variables/trace-host-user-variables.c
-include examples/deprecated/msg/trace-host-user-variables/trace-host-user-variables.tesh
-include examples/deprecated/msg/trace-link-user-variables/trace-link-user-variables.c
-include examples/deprecated/msg/trace-link-user-variables/trace-link-user-variables.tesh
-include examples/deprecated/msg/trace-masterworker/trace-masterworker.c
-include examples/deprecated/msg/trace-masterworker/trace-masterworker.tesh
-include examples/deprecated/msg/trace-process-migration/trace-process-migration.c
-include examples/deprecated/msg/trace-process-migration/trace-process-migration.tesh
-include examples/deprecated/msg/trace-route-user-variables/trace-route-user-variables.c
-include examples/deprecated/msg/trace-route-user-variables/trace-route-user-variables.tesh
include examples/deprecated/simdag/dag-dotload/dag.dot
include examples/deprecated/simdag/dag-dotload/dag_with_cycle.dot
include examples/deprecated/simdag/dag-dotload/sd_dag-dotload.c
include examples/s4u/synchro-mutex/s4u-synchro-mutex.tesh
include examples/s4u/synchro-semaphore/s4u-synchro-semaphore.cpp
include examples/s4u/synchro-semaphore/s4u-synchro-semaphore.tesh
+include examples/s4u/trace-categories/s4u-trace-categories.cpp
+include examples/s4u/trace-categories/s4u-trace-categories.tesh
+include examples/s4u/trace-host-user-variables/s4u-trace-host-user-variables.cpp
+include examples/s4u/trace-host-user-variables/s4u-trace-host-user-variables.tesh
+include examples/s4u/trace-link-user-variables/s4u-trace-link-user-variables.cpp
+include examples/s4u/trace-link-user-variables/s4u-trace-link-user-variables.tesh
+include examples/s4u/trace-masterworkers/s4u-trace-masterworkers.cpp
+include examples/s4u/trace-masterworkers/s4u-trace-masterworkers.tesh
include examples/s4u/trace-platform/s4u-trace-platform.cpp
include examples/s4u/trace-platform/s4u-trace-platform.tesh
+include examples/s4u/trace-process-migration/s4u-trace-process-migration.cpp
+include examples/s4u/trace-process-migration/s4u-trace-process-migration.tesh
+include examples/s4u/trace-route-user-variables/s4u-trace-route-user-variables.cpp
+include examples/s4u/trace-route-user-variables/s4u-trace-route-user-variables.tesh
include examples/smpi/NAS/DGraph.c
include examples/smpi/NAS/DGraph.h
include examples/smpi/NAS/README.install
include teshsuite/s4u/trace-integration/test-hbp2.5-hbp1.5.xml
include teshsuite/s4u/trace-integration/trace-integration.cpp
include teshsuite/s4u/trace-integration/trace-integration.tesh
+include teshsuite/s4u/vm-live-migration/platform.xml
+include teshsuite/s4u/vm-live-migration/vm-live-migration.cpp
+include teshsuite/s4u/vm-live-migration/vm-live-migration.tesh
include teshsuite/s4u/wait-any-for/wait-any-for.cpp
include teshsuite/s4u/wait-any-for/wait-any-for.tesh
include teshsuite/simdag/availability/availability.c
include examples/deprecated/java/.classpath
include examples/deprecated/java/.project
include examples/deprecated/java/CMakeLists.txt
-include examples/deprecated/msg/CMakeLists.txt
include examples/deprecated/msg/mc/CMakeLists.txt
include examples/deprecated/simdag/CMakeLists.txt
include examples/platforms/bypassRoute.xml
include include/simgrid/plugins/file_system.h
include include/simgrid/plugins/live_migration.h
include include/simgrid/plugins/load.h
-include include/simgrid/plugins/load_balancer.h
include include/simgrid/s4u.hpp
include include/simgrid/s4u/Activity.hpp
include include/simgrid/s4u/Actor.hpp
include src/kernel/resource/profile/Profile.cpp
include src/kernel/resource/profile/Profile.hpp
include src/kernel/resource/profile/Profile_test.cpp
+include src/kernel/resource/profile/StochasticDatedValue.cpp
+include src/kernel/resource/profile/StochasticDatedValue.hpp
include src/kernel/routing/ClusterZone.cpp
include src/kernel/routing/DijkstraZone.cpp
include src/kernel/routing/DragonflyZone.cpp
include src/mc/Transition.hpp
include src/mc/VisitedState.cpp
include src/mc/VisitedState.hpp
-include src/mc/checker/Checker.cpp
include src/mc/checker/Checker.hpp
include src/mc/checker/CommunicationDeterminismChecker.cpp
include src/mc/checker/CommunicationDeterminismChecker.hpp
include src/mc/inspect/mc_unw.cpp
include src/mc/inspect/mc_unw.hpp
include src/mc/inspect/mc_unw_vmread.cpp
+include src/mc/mc_api.cpp
+include src/mc/mc_api.hpp
include src/mc/mc_base.cpp
include src/mc/mc_base.h
include src/mc/mc_client_api.cpp
-include src/mc/mc_comm_pattern.cpp
include src/mc/mc_comm_pattern.hpp
include src/mc/mc_config.cpp
include src/mc/mc_config.hpp
include src/mc/mc_hash.hpp
include src/mc/mc_ignore.hpp
include src/mc/mc_mmu.hpp
+include src/mc/mc_pattern.hpp
include src/mc/mc_private.hpp
include src/mc/mc_record.cpp
include src/mc/mc_record.hpp
include src/smpi/plugins/ampi/ampi.hpp
include src/smpi/plugins/ampi/instr_ampi.cpp
include src/smpi/plugins/ampi/instr_ampi.hpp
-include src/smpi/plugins/load_balancer/LoadBalancer.cpp
-include src/smpi/plugins/load_balancer/load_balancer.hpp
-include src/smpi/plugins/sampi_loadbalancer.cpp
include src/smpi/smpi_main.c
include src/smpi/smpi_replay_main.cpp
include src/smpi/smpicc.in
- Example: src/kernel/activity/Activity.cpp
include/simgrid/activity/Activity.hpp
C
- - Field getters are named sg_object_field() eg sg_link_name()
- Field setters are named sg_object_field_set() eg sg_link_data_set()
+ - Field getters are named sg_object_get_field() e.g. sg_link_get_name()
+ Field setters are named sg_object_set_field() e.g. sg_link_set_data()
- variables and functions are in snake_case()
- - typedefs do not hide the pointers, ie * must be explicit
- char * sg_host_get_name(sg_host_t * host);
+ - typedefs do not hide the pointers, i.e. * must be explicit
+ char* sg_host_get_name(sg_host_t* host);
This is different from the old convention (described below), that
@CMAKE_HOME_DIRECTORY@/doc/doxygen/module-trace.doc \
@CMAKE_BINARY_DIR@/doc/doxygen/logcategories.doc \
@CMAKE_HOME_DIRECTORY@/include/ \
- @CMAKE_HOME_DIRECTORY@/src/plugins/ \
- @CMAKE_HOME_DIRECTORY@/examples/deprecated/msg/README.doc \
- @CMAKE_HOME_DIRECTORY@/examples/s4u/README.doc
+ @CMAKE_HOME_DIRECTORY@/src/plugins/
# This tag can be used to specify the character encoding of the source files
- popping_bodies.cpp:
The BODY function of each simcall
- popping_enum.hpp:
- Definition of type `enum e_smx_simcall_t` (one value per existing simcall)
+ Definition of type `enum class Simcall` (one value per existing simcall)
- popping_generated.cpp:
Definitions of `simcall_names[]` (debug name of each simcall), and
- SIMIX_simcall_enter() that deals with the simcall from within the kernel
+ ActorImpl::simcall_handle() that deals with the simcall from within the kernel
The simcall.in file list all the simcalls in sections. A line starting by "##"
define a new section which will be replace by a "ifdef" in the generated code.
@endverbatim
@li <b>@c
-tracing/msg/process
+tracing/actor
</b>:
- This option only has effect if this simulator is MSG-based. It traces the
- behavior of all categorized MSG processes, grouping them by hosts. This option
- can be used to track process location if this simulator has process migration.
+ This option traces the behavior of all categorized actors, grouping them by hosts. This option
+ can be used to track actor location if this simulator has actor migration.
@verbatim
---cfg=tracing/msg/process:yes
+--cfg=tracing/actor:yes
@endverbatim
@li <b>@c
@code{cpp}
struct s_smx_simcall {
// Simcall number:
- e_smx_simcall_t call;
+ Simcall call;
// Issuing actor:
smx_actor_t issuer;
// Arguments of the simcall:
.. code-block:: shell
- ./master-workers small_platform.xml master-workers_d.xml --cfg=tracing:yes --cfg=tracing/msg/process:yes
+ ./master-workers small_platform.xml master-workers_d.xml --cfg=tracing:yes --cfg=tracing/actor:yes
vite simgrid.trace
.. image:: /tuto_s4u/img/vite-screenshot.png
.. code-block:: shell
- ./master-workers small_platform.xml master-workers_d.xml --cfg=tracing:yes --cfg=tracing/msg/process:yes
+ ./master-workers small_platform.xml master-workers_d.xml --cfg=tracing:yes --cfg=tracing/actor:yes
Rscript draw_gantt.R simgrid.trace
It produces a ``Rplots.pdf`` with the following content:
.. code-block:: shell
- ./master-workers-lab3 small_platform.xml deployment3.xml --log=msg_test.thres:debug
+ ./master-workers-lab3 small_platform.xml deployment3.xml --log=s4u_app_masterworker.thres:debug
Lab 4: Competing Applications
xpath_query_noparam = ('{:s}/memberdef[@kind="function"]/name[text()="{:s}"]/..').format(prefix, meth)
xpath_query = ""
- if self.argsstring != None:
+ if self.argsstring is not None:
xpath_query = ('{:s}/memberdef[@kind="function" and argsstring/text()="{:s}"]/name[text()="{:s}"]/..').format(prefix,self.argsstring,meth)
else:
xpath_query = xpath_query_noparam
if not match:
logger = logging.getLogger(__name__)
- if self.argsstring != None:
+ if self.argsstring is not None:
candidates = get_doxygen_root().xpath(xpath_query_noparam)
if len(candidates) == 1:
logger.warning("[autodoxy] Using method '{}{}{}' instead of '{}{}{}'. You may want to drop your specification of the signature, or to fix it."
'.. toggle-header::',
' :header: View {}'.format(filename),
'',
- ' `Download {} <https://framagit.org/simgrid/simgrid/tree/{}>`_'.format(os.path.basename(filename), filename),
+ ' `Download {} <https://framagit.org/simgrid/simgrid/tree/master/{}>`_'.format(os.path.basename(filename), filename),
'',
' .. literalinclude:: ../../{}'.format(filename),
' :language: {}'.format(language),
.. autodoxymethod:: sg_actor_get_host(const_sg_actor_t actor)
.. autodoxymethod:: sg_actor_set_host(sg_actor_t actor, sg_host_t host)
- .. autodoxymethod:: sg_actor_data(const_sg_actor_t actor)
- .. autodoxymethod:: sg_actor_data_set(sg_actor_t actor, void *userdata)
+ .. autodoxymethod:: sg_actor_get_data(const_sg_actor_t actor)
+ .. autodoxymethod:: sg_actor_set_data(sg_actor_t actor, void *userdata)
Suspending and resuming actors
------------------------------
.. group-tab:: C++
.. autodoxymethod:: simgrid::s4u::Actor::on_exit
- .. autodoxymethod:: simgrid::s4u::Actor::join()
- .. autodoxymethod:: simgrid::s4u::Actor::join(double timeout)
+ .. autodoxymethod:: simgrid::s4u::Actor::join() const
+ .. autodoxymethod:: simgrid::s4u::Actor::join(double timeout) const
.. autodoxymethod:: simgrid::s4u::Actor::set_auto_restart(bool autorestart)
.. group-tab:: Python
.. group-tab:: C
- .. autodoxymethod:: sg_actor_join(sg_actor_t actor, double timeout)
+ .. autodoxymethod:: sg_actor_join(const_sg_actor_t actor, double timeout)
.. autodoxymethod:: sg_actor_set_auto_restart(sg_actor_t actor, int auto_restart)
Signals
.. group-tab:: C
- .. autodoxymethod:: sg_actor_self_data()
- .. autodoxymethod:: sg_actor_self_data_set(void *data)
+ .. autodoxymethod:: sg_actor_self_get_data()
+ .. autodoxymethod:: sg_actor_self_set_data(void *data)
.. autodoxymethod:: sg_actor_self_get_name()
.. autodoxymethod:: sg_actor_self_get_pid()
.. autodoxymethod:: sg_actor_self_get_ppid()
.. autodoxymethod:: sg_host_core_count(const_sg_host_t host)
.. autodoxymethod:: sg_host_dump(const_sg_host_t ws)
.. autodoxymethod:: sg_host_get_name(const_sg_host_t host)
- .. autodoxymethod:: sg_host_load(const_sg_host_t host)
- .. autodoxymethod:: sg_host_speed(const_sg_host_t host)
+ .. autodoxymethod:: sg_host_get_load(const_sg_host_t host)
+ .. autodoxymethod:: sg_host_get_speed(const_sg_host_t host)
User data and properties
------------------------
.. group-tab:: C++
- .. autodoxymethod:: simgrid::s4u::Host::add_disk(Disk *disk)
+ .. autodoxymethod:: simgrid::s4u::Host::add_disk(const Disk* disk)
.. autodoxymethod:: simgrid::s4u::Host::get_actor_count() const
.. autodoxymethod:: simgrid::s4u::Host::get_all_actors() const
.. autodoxymethod:: simgrid::s4u::Host::get_disks() const
.. group-tab:: C
- .. autodoxymethod:: sg_host_route(const_sg_host_t from, const_sg_host_t to, xbt_dynar_t links)
- .. autodoxymethod:: sg_host_route_bandwidth(const_sg_host_t from, const_sg_host_t to)
- .. autodoxymethod:: sg_host_route_latency(const_sg_host_t from, const_sg_host_t to)
+ .. autodoxymethod:: sg_host_get_route(const_sg_host_t from, const_sg_host_t to, xbt_dynar_t links)
+ .. autodoxymethod:: sg_host_get_route_bandwidth(const_sg_host_t from, const_sg_host_t to)
+ .. autodoxymethod:: sg_host_get_route_latency(const_sg_host_t from, const_sg_host_t to)
.. autodoxymethod:: sg_host_sendto(sg_host_t from, sg_host_t to, double byte_amount)
Signals
.. group-tab:: C
- .. autodoxymethod:: sg_link_bandwidth(const_sg_link_t link)
+ .. autodoxymethod:: sg_link_get_bandwidth(const_sg_link_t link)
+ .. autodoxymethod:: sg_link_get_latency(const_sg_link_t link)
+ .. autodoxymethod:: sg_link_get_name(const_sg_link_t link)
.. autodoxymethod:: sg_link_is_shared(const_sg_link_t link)
- .. autodoxymethod:: sg_link_latency(const_sg_link_t link)
- .. autodoxymethod:: sg_link_name(const_sg_link_t link)
Modifying characteristics
-------------------------
.. autodoxymethod:: simgrid::s4u::Link::set_bandwidth(double value)
.. autodoxymethod:: simgrid::s4u::Link::set_latency(double value)
+ .. group-tab:: C
+
+ .. autodoxymethod:: sg_link_set_bandwidth(const_sg_link_t link, double value)
+ .. autodoxymethod:: sg_link_set_latency(const_sg_link_t link, double value)
+
User data and properties
------------------------
.. group-tab:: C
- .. autodoxymethod:: sg_link_data(const_sg_link_t link)
- .. autodoxymethod:: sg_link_data_set(sg_link_t link, void *data)
+ .. autodoxymethod:: sg_link_get_data(const_sg_link_t link)
+ .. autodoxymethod:: sg_link_set_data(sg_link_t link, void *data)
On/Off
------
.. autodoxymethod:: simgrid::s4u::VirtualMachine::get_pm() const
.. autodoxymethod:: simgrid::s4u::VirtualMachine::get_ramsize() const
- .. autodoxymethod:: simgrid::s4u::VirtualMachine::get_state()
+ .. autodoxymethod:: simgrid::s4u::VirtualMachine::get_state() const
.. autodoxymethod:: simgrid::s4u::VirtualMachine::set_bound(double bound)
.. autodoxymethod:: simgrid::s4u::VirtualMachine::set_pm(Host *pm)
.. autodoxymethod:: simgrid::s4u::Semaphore::acquire()
.. autodoxymethod:: simgrid::s4u::Semaphore::acquire_timeout(double timeout)
- .. autodoxymethod:: simgrid::s4u::Semaphore::get_capacity()
+ .. autodoxymethod:: simgrid::s4u::Semaphore::get_capacity() const
.. autodoxymethod:: simgrid::s4u::Semaphore::release()
- .. autodoxymethod:: simgrid::s4u::Semaphore::would_block()
+ .. autodoxymethod:: simgrid::s4u::Semaphore::would_block() const
.. group-tab:: C
.. autodoxymethod:: sg_sem_acquire(sg_sem_t sem)
.. autodoxymethod:: sg_sem_acquire_timeout(sg_sem_t sem, double timeout)
- .. autodoxymethod:: sg_sem_get_capacity(sg_sem_t sem)
+ .. autodoxymethod:: sg_sem_get_capacity(const_sg_sem_t sem)
.. autodoxymethod:: sg_sem_release(sg_sem_t sem)
- .. autodoxymethod:: sg_sem_would_block(sg_sem_t sem)
+ .. autodoxymethod:: sg_sem_would_block(const_sg_sem_t sem)
.. |hr| raw:: html
framework, and you never know who have the time and knowledge to
answer your question, so please keep messages on the public mailing
list.
- - Join us on IRC and ask your question directly on the channel \#simgrid at
- ``irc.debian.org``
- (or use the ugly `web interface <https://webchat.oftc.net/?channels=%23simgrid>`__
- if you don't have a
- `real client <https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients>`_
- installed). When no non-french speaker are connected, we usually
- chat in french on this channel, but we do switch back to english
- when we have a guest.
- Be warned that even if many people are connected to
- the channel, they may not be staring at their IRC windows.
- So don't be surprised if you don't get an answer in the
- second, and turn to the mailing lists if nobody seems to be there.
- The logs of this channel are publicly
- `available online <http://colabti.org/irclogger/irclogger_logs/simgrid>`_,
- so may also want to check in a few hours if someone answered after
- you left.
+ - If you want to chat with the community, join us on `Mattermost
+ <https://framateam.org/simgrid/channels/town-square>`_. Be warned
+ that even if many people are connected to the channel, they may not
+ be staring at their chat windows. So don't be surprised if you
+ don't get an answer in the second, and please be patient.
+
+ If you prefer, you can reach us on IRC on \#simgrid at
+ ``irc.debian.org`` (the `logs are available
+ <http://colabti.org/irclogger/irclogger_logs/simgrid>`_). When no
+ non-french speaker are connected, we usually chat in french on
+ these channel, but we do switch back to english when we have a
+ guest.
- Asking your question on
`StackOverflow <http://stackoverflow.com/questions/tagged/simgrid>`_
.. example-tab:: examples/s4u/trace-platform/s4u-trace-platform.cpp
+ - **Setting Categories**
+ This example declares several tracing categories to that are used to
+ classify its tasks. When the program is executed, the tracing mechanism
+ registers the resource utilization of hosts and links according to these
+ categories. Recommended options:
+ ``--cfg=tracing:yes --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes``
+
+ .. tabs::
+
+ .. example-tab:: examples/s4u/trace-categories/s4u-trace-categories.cpp
+
+ - **Master Workers tracing**
+ This is an augmented version of our basic master/worker example using
+ several tracing features. It traces resource usage, sorted out in several
+ categories; Trace marks and user variables are also used. Recommended
+ options: ``--cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes``
+
+ .. tabs::
+
+ .. example-tab:: examples/s4u/trace-masterworkers/s4u-trace-masterworkers.cpp
+
+ - **Process migration tracing**
+ This version is enhanced so that the process migrations can be displayed
+ as arrows in a Gantt-chart visualization. Recommended options to that
+ extend: ``--cfg=tracing:yes --cfg=tracing/actor:yes``
+
+ .. tabs::
+
+ .. example-tab:: examples/s4u/trace-process-migration/s4u-trace-process-migration.cpp
+
+..
+ TODO: These tracing examples should be integrated in the examples to not
+ duplicate the C++ files. A full command line to see the result in the right
+ tool (vite/FrameSoc) should be given along with some screenshots.
+
+Tracing user variables
+----------------------
+
+You can also attach your own variables to any resource described in the platform
+file. The following examples illustrate this feature. They have to be run with
+the following options: ``--cfg=tracing:yes --cfg=tracing/platform:yes``
+
+ - **Attaching variables to Hosts**
+
+ .. tabs::
+
+ .. example-tab:: examples/s4u/trace-host-user-variables/s4u-trace-host-user-variables.cpp
+
+ - **Attaching variables to Links**
+ The tricky part is that you have to know the name of the link you want to
+ enhance with a variable.
+
+ .. tabs::
+
+ .. example-tab:: examples/s4u/trace-link-user-variables/s4u-trace-link-user-variables.cpp
+
+ - **Attaching variables to network Routes**
+ It is often easier to update a given variable for all links of a given
+ network path (identified by its source and destination hosts) instead of
+ knowing the name of each specific link.
+
+ .. tabs::
+
+ .. example-tab:: examples/s4u/trace-route-user-variables/s4u-trace-route-user-variables.cpp
+
========================
Larger SimGrid Examplars
========================
static void master(int argc, char* argv[])
{
- sg_actor_t actor;
+ const_sg_actor_t actor;
XBT_INFO("Start sleeper");
actor = sg_actor_create("sleeper from master", sg_host_self(), sleeper, 0, NULL);
sg_host_t first = sg_host_by_name(argv[1]);
const_sg_host_t second = sg_host_by_name(argv[2]);
- double flopAmount = sg_host_speed(first) * 5 + sg_host_speed(second) * 5;
+ double flopAmount = sg_host_get_speed(first) * 5 + sg_host_get_speed(second) * 5;
XBT_INFO("Let's move to %s to execute %.2f Mflops (5sec on %s and 5sec on %s)", argv[1], flopAmount / 1e6, argv[1],
argv[2]);
const char* w0_argv[] = {"worker0", "Task0", "-1.0", NULL};
sg_actor_create("worker0", (sg_host_t)vm0, worker_busy_loop, 3, w0_argv);
- char* speed = bprintf("%f", sg_host_speed(pm0));
+ char* speed = bprintf("%f", sg_host_get_speed(pm0));
const char* w1_argv[] = {"worker1", "Task1", speed, NULL};
sg_actor_create("worker1", (sg_host_t)vm1, worker_busy_loop, 3, w1_argv);
static void test_one_task(sg_host_t hostA)
{
- const double cpu_speed = sg_host_speed(hostA);
+ const double cpu_speed = sg_host_get_speed(hostA);
const double computation_amount = cpu_speed * 10;
const char* hostA_name = sg_host_get_name(hostA);
static void test_two_tasks(sg_host_t hostA, sg_host_t hostB)
{
- const double cpu_speed = sg_host_speed(hostA);
- xbt_assert(cpu_speed == sg_host_speed(hostB));
+ const double cpu_speed = sg_host_get_speed(hostA);
+ xbt_assert(cpu_speed == sg_host_get_speed(hostB));
const double computation_amount = cpu_speed * 10;
const char* hostA_name = sg_host_get_name(hostA);
const char* hostB_name = sg_host_get_name(hostB);
sg_vm_destroy(vm0);
vm0 = sg_vm_create_core(pm0, "VM0");
- double cpu_speed = sg_host_speed(pm0);
+ double cpu_speed = sg_host_get_speed(pm0);
sg_vm_set_bound(vm0, cpu_speed / 10);
sg_vm_start(vm0);
sg_vm_set_ramsize(vm0, 1e9); // 1GB
sg_vm_start(vm0);
- cpu_speed = sg_host_speed(pm0);
+ cpu_speed = sg_host_get_speed(pm0);
sg_vm_start(vm0);
XBT_INFO("# 10. Test migration");
static void master_fun(int argc, char* argv[])
{
- sg_host_t* worker_pms = sg_actor_self_data();
+ sg_host_t* worker_pms = sg_actor_self_get_data();
sg_vm_t* vms = xbt_malloc(2 * sizeof(sg_vm_t));
free(pms);
sg_actor_t actor = sg_actor_init("master", master_pm);
- sg_actor_data_set(actor, worker_pms);
+ sg_actor_set_data(actor, worker_pms);
sg_actor_start(actor, master_fun, 0, NULL);
simgrid_run();
XBT_INFO("First, build a classical parallel task, with 1 Gflop to execute on each node, "
"and 10MB to exchange between each pair");
- double* computation_amounts = (double*)calloc(host_count, sizeof(double));
- double* communication_amounts = (double*)calloc(host_count * host_count, sizeof(double));
+ double* computation_amounts = xbt_new0(double, host_count);
+ double* communication_amounts = xbt_new0(double, host_count * host_count);
for (int i = 0; i < host_count; i++)
computation_amounts[i] = 1e9; // 1 Gflop
sg_actor_parallel_execute(host_count, hosts, computation_amounts, communication_amounts);
- free(communication_amounts);
- free(computation_amounts);
+ xbt_free(communication_amounts);
+ xbt_free(computation_amounts);
XBT_INFO("We can do the same with a timeout of one second enabled.");
- computation_amounts = (double*)calloc(host_count, sizeof(double));
- communication_amounts = (double*)calloc(host_count * host_count, sizeof(double));
+ computation_amounts = xbt_new0(double, host_count);
+ communication_amounts = xbt_new0(double, host_count * host_count);
for (int i = 0; i < host_count; i++)
computation_amounts[i] = 1e9; // 1 Gflop
for (int i = 0; i < host_count; i++)
sg_exec_t exec = sg_actor_parallel_exec_init(host_count, hosts, computation_amounts, communication_amounts);
sg_exec_wait_for(exec, 1 /* timeout (in seconds)*/);
- free(communication_amounts);
- free(computation_amounts);
+ xbt_free(communication_amounts);
+ xbt_free(computation_amounts);
XBT_INFO("Then, build a parallel task involving only computations and no communication (1 Gflop per node)");
- computation_amounts = (double*)calloc(host_count, sizeof(double));
+ computation_amounts = xbt_new0(double, host_count);
for (int i = 0; i < host_count; i++)
computation_amounts[i] = 1e9; // 1 Gflop
sg_actor_parallel_execute(host_count, hosts, computation_amounts, NULL);
- free(computation_amounts);
+ xbt_free(computation_amounts);
XBT_INFO("Then, build a parallel task with no computation nor communication (synchro only)");
- computation_amounts = (double*)calloc(host_count, sizeof(double));
- communication_amounts = (double*)calloc(host_count * host_count, sizeof(double));
+ computation_amounts = xbt_new0(double, host_count);
+ communication_amounts = xbt_new0(double, host_count * host_count);
sg_actor_parallel_execute(host_count, hosts, computation_amounts, communication_amounts);
- free(communication_amounts);
- free(computation_amounts);
+ xbt_free(communication_amounts);
+ xbt_free(computation_amounts);
XBT_INFO("Finally, trick the ptask to do a 'remote execution', on host %s", sg_host_get_name(hosts[1]));
- computation_amounts = (double*)calloc(1, sizeof(double));
+ computation_amounts = xbt_new0(double, 1);
computation_amounts[0] = 1e9; // 1 Gflop
sg_host_t remote[1];
remote[0] = hosts[1];
sg_actor_parallel_execute(1, remote, computation_amounts, NULL /* no comm */);
- free(computation_amounts);
+ xbt_free(computation_amounts);
XBT_INFO("Goodbye now!");
- free(hosts);
+ xbt_free(hosts);
}
int main(int argc, char* argv[])
/* Pick the first host from the platform file */
sg_host_t* all_hosts = sg_host_list();
sg_host_t first_host = all_hosts[0];
- free(all_hosts);
+ xbt_free(all_hosts);
sg_actor_create("test", first_host, runner, 0, NULL);
sg_host_t host = sg_host_by_name("MyHost1");
XBT_INFO("Energetic profile: %s", sg_host_get_property_value(host, "wattage_per_state"));
- XBT_INFO("Initial peak speed=%.0E flop/s; Energy dissipated =%.0E J", sg_host_speed(host),
+ XBT_INFO("Initial peak speed=%.0E flop/s; Energy dissipated =%.0E J", sg_host_get_speed(host),
sg_host_get_consumed_energy(host));
double start = simgrid_get_clock();
XBT_INFO("Sleep for 10 seconds");
sg_actor_sleep_for(10);
XBT_INFO("Done sleeping (duration: %.2f s). Current peak speed=%.0E; Energy dissipated=%.2f J",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_consumed_energy(host));
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_consumed_energy(host));
// Run a task
start = simgrid_get_clock();
sg_actor_execute(100E6);
XBT_INFO("Task done (duration: %.2f s). Current peak speed=%.0E flop/s; Current consumption: from %.0fW to %.0fW"
" depending on load; Energy dissipated=%.0f J",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_wattmin_at(host, sg_host_get_pstate(host)),
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_wattmin_at(host, sg_host_get_pstate(host)),
sg_host_get_wattmax_at(host, sg_host_get_pstate(host)), sg_host_get_consumed_energy(host));
// ========= Change power peak =========
int pstate = 2;
sg_host_set_pstate(host, pstate);
XBT_INFO("========= Requesting pstate %d (speed should be of %.0E flop/s and is of %.0E flop/s)", pstate,
- sg_host_get_pstate_speed(host, pstate), sg_host_speed(host));
+ sg_host_get_pstate_speed(host, pstate), sg_host_get_speed(host));
// Run a second task
start = simgrid_get_clock();
XBT_INFO("Run a task of %.0E flops", 100E6);
sg_actor_execute(100E6);
XBT_INFO("Task done (duration: %.2f s). Current peak speed=%.0E flop/s; Energy dissipated=%.0f J",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_consumed_energy(host));
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_consumed_energy(host));
start = simgrid_get_clock();
XBT_INFO("Sleep for 4 seconds");
sg_actor_sleep_for(4);
XBT_INFO("Done sleeping (duration: %.2f s). Current peak speed=%.0E flop/s; Energy dissipated=%.0f J",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_consumed_energy(host));
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_consumed_energy(host));
// =========== Turn the other host off ==========
XBT_INFO("Turning MyHost2 off, and sleeping another 10 seconds. MyHost2 dissipated %.0f J so far.",
start = simgrid_get_clock();
sg_actor_sleep_for(10);
XBT_INFO("Done sleeping (duration: %.2f s). Current peak speed=%.0E flop/s; Energy dissipated=%.0f J",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_consumed_energy(host));
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_consumed_energy(host));
}
int main(int argc, char* argv[])
* That's exactly equivalent to synchronous execution. */
static void waiter(int argc, char* argv[])
{
- double computation_amount = sg_host_speed(sg_host_self());
+ double computation_amount = sg_host_get_speed(sg_host_self());
XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
sg_exec_t activity = sg_actor_exec_init(computation_amount);
sg_exec_start(activity);
/* This actor tests the ongoing execution until its completion, and don't wait before it's terminated. */
static void monitor(int argc, char* argv[])
{
- double computation_amount = sg_host_speed(sg_host_self());
+ double computation_amount = sg_host_get_speed(sg_host_self());
XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
sg_exec_t activity = sg_actor_exec_init(computation_amount);
sg_exec_start(activity);
/* This actor cancels the ongoing execution after a while. */
static void canceller(int argc, char* argv[])
{
- double computation_amount = sg_host_speed(sg_host_self());
+ double computation_amount = sg_host_get_speed(sg_host_self());
XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
sg_exec_t activity = sg_actor_exec_init(computation_amount);
int nb = sg_host_get_nb_pstates(host);
XBT_INFO("Count of Processor states=%d", nb);
- double current_peak = sg_host_speed(host);
+ double current_peak = sg_host_get_speed(host);
XBT_INFO("Current power peak=%f", current_peak);
sg_actor_execute(100E6);
sg_host_set_pstate(host, new_pstate);
- current_peak = sg_host_speed(host);
+ current_peak = sg_host_get_speed(host);
XBT_INFO("Current power peak=%f", current_peak);
sg_actor_execute(100E6);
int nb2 = sg_host_get_nb_pstates(host);
XBT_INFO("Count of Processor states=%d", nb2);
- double current_peak2 = sg_host_speed(host);
+ double current_peak2 = sg_host_get_speed(host);
XBT_INFO("Current power peak=%f", current_peak2);
}
XBT_INFO("It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).");
sg_actor_sleep_for(0.1);
- XBT_INFO("Loads in flops/s: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", sg_host_load(boivin), sg_host_load(fafard),
- sg_host_load(ginette));
+ XBT_INFO("Loads in flops/s: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", sg_host_get_load(boivin),
+ sg_host_get_load(fafard), sg_host_get_load(ginette));
sg_exec_wait(exec);
sg_exec_start(exec);
sg_actor_sleep_for(0.5);
- XBT_INFO("Loads before the move: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", sg_host_load(boivin), sg_host_load(fafard),
- sg_host_load(ginette));
+ XBT_INFO("Loads before the move: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", sg_host_get_load(boivin),
+ sg_host_get_load(fafard), sg_host_get_load(ginette));
sg_exec_set_host(exec, boivin);
sg_actor_sleep_for(0.1);
- XBT_INFO("Loads after the move: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", sg_host_load(boivin), sg_host_load(fafard),
- sg_host_load(ginette));
+ XBT_INFO("Loads after the move: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", sg_host_get_load(boivin),
+ sg_host_get_load(fafard), sg_host_get_load(ginette));
sg_exec_wait(exec);
XBT_INFO("Done!");
for (int i = 0; i < 3; i++) {
char* name = bprintf("Exec-%d", i);
- double amount = (6 * (i % 2) + i + 1) * sg_host_speed(sg_host_self());
+ double amount = (6 * (i % 2) + i + 1) * sg_host_get_speed(sg_host_self());
sg_exec_t exec = sg_actor_exec_init(amount);
sg_exec_set_name(exec, name);
pending_execs[pending_execs_count++] = exec;
sg_exec_start(exec);
- XBT_INFO("Activity %s has started for %.0f seconds", name, amount / sg_host_speed(sg_host_self()));
+ XBT_INFO("Activity %s has started for %.0f seconds", name, amount / sg_host_get_speed(sg_host_self()));
free(name);
}
/* - Retrieve all disks from current host */
unsigned int disk_count;
sg_disk_t* disk_list;
- sg_host_disks(sg_host_self(), &disk_count, &disk_list);
+ sg_host_get_disks(sg_host_self(), &disk_count, &disk_list);
for (unsigned int i = 0; i < disk_count; i++)
- XBT_INFO("Disk name: %s (read: %.0f B/s -- write: %.0f B/s ", sg_disk_name(disk_list[i]),
+ XBT_INFO("Disk name: %s (read: %.0f B/s -- write: %.0f B/s ", sg_disk_get_name(disk_list[i]),
sg_disk_read_bandwidth(disk_list[i]), sg_disk_write_bandwidth(disk_list[i]));
/* - Write 400,000 bytes on Disk1 */
sg_disk_t disk = disk_list[0];
sg_size_t write = sg_disk_write(disk, 400000);
- XBT_INFO("Wrote %llu bytes on '%s'", write, sg_disk_name(disk));
+ XBT_INFO("Wrote %llu bytes on '%s'", write, sg_disk_get_name(disk));
/* - Now read 200,000 bytes */
sg_size_t read = sg_disk_read(disk, 200000);
- XBT_INFO("Read %llu bytes on '%s'", read, sg_disk_name(disk));
+ XBT_INFO("Read %llu bytes on '%s'", read, sg_disk_get_name(disk));
/* - Attach some user data to disk1 */
XBT_INFO("*** Get/set data for storage element: Disk1 ***");
- char* data = (char*)sg_disk_data(disk);
+ char* data = (char*)sg_disk_get_data(disk);
XBT_INFO("Get storage data: '%s'", data ? data : "No user data");
- sg_disk_data_set(disk, xbt_strdup("Some user data"));
- data = (char*)sg_disk_data(disk);
+ sg_disk_set_data(disk, xbt_strdup("Some user data"));
+ data = (char*)sg_disk_get_data(disk);
XBT_INFO("Set and get data: '%s'", data);
free(data);
free(disk_list);
for (long i = 0; i < host_count; i++) {
unsigned int disk_count;
sg_disk_t* disks;
- sg_host_disks(hosts[i], &disk_count, &disks);
+ sg_host_get_disks(hosts[i], &disk_count, &disks);
for (unsigned int j = 0; j < disk_count; j++)
XBT_INFO("Init: %s: %llu/%llu MiB used/free on '%s@%s'", sg_host_get_name(hosts[i]),
sg_disk_get_size_used(disks[j]) / INMEGA, sg_disk_get_size_free(disks[j]) / INMEGA,
- sg_disk_name(disks[j]), sg_host_get_name(sg_disk_get_host(disks[j])));
+ sg_disk_get_name(disks[j]), sg_host_get_name(sg_disk_get_host(disks[j])));
free(disks);
}
for (long i = 0; i < host_count; i++) {
unsigned int disk_count;
sg_disk_t* disks;
- sg_host_disks(hosts[i], &disk_count, &disks);
+ sg_host_get_disks(hosts[i], &disk_count, &disks);
for (unsigned int j = 0; j < disk_count; j++)
XBT_INFO("End: %llu/%llu MiB used/free on '%s@%s'", sg_disk_get_size_used(disks[j]) / INMEGA,
- sg_disk_get_size_free(disks[j]) / INMEGA, sg_disk_name(disks[j]), sg_host_get_name(hosts[i]));
+ sg_disk_get_size_free(disks[j]) / INMEGA, sg_disk_get_name(disks[j]), sg_host_get_name(hosts[i]));
free(disks);
}
for (unsigned int i = 0; i < disk_count; i++) {
const_sg_disk_t d = disks[i];
// Retrieve disk's information
- XBT_INFO(" %s (%s) Used: %llu; Free: %llu; Total: %llu.", sg_disk_name(d), sg_disk_get_mount_point(d),
+ XBT_INFO(" %s (%s) Used: %llu; Free: %llu; Total: %llu.", sg_disk_get_name(d), sg_disk_get_mount_point(d),
sg_disk_get_size_used(d), sg_disk_get_size_free(d), sg_disk_get_size(d));
}
}
{
unsigned int disk_count;
sg_disk_t* disks;
- sg_host_disks(sg_host_self(), &disk_count, &disks);
+ sg_host_get_disks(sg_host_self(), &disk_count, &disks);
show_info(disk_count, disks);
sg_host_t* hosts = sg_host_list();
for (size_t i = 0; i < host_count; i++)
- XBT_INFO("Host '%s' runs at %.0f flops/s", sg_host_get_name(hosts[i]), sg_host_speed(hosts[i]));
+ XBT_INFO("Host '%s' runs at %.0f flops/s", sg_host_get_name(hosts[i]), sg_host_get_speed(hosts[i]));
free(hosts);
XBT_INFO("Initial peak speed: %.0E flop/s; number of flops computed so far: %.0E (should be 0) and current average "
"load: %.5f (should be 0)",
- sg_host_speed(host), sg_host_get_computed_flops(host), sg_host_get_avg_load(host));
+ sg_host_get_speed(host), sg_host_get_computed_flops(host), sg_host_get_avg_load(host));
double start = simgrid_get_clock();
XBT_INFO("Sleep for 10 seconds");
sg_actor_sleep_for(10);
- double speed = sg_host_speed(host);
+ double speed = sg_host_get_speed(host);
XBT_INFO("Done sleeping %.2fs; peak speed: %.0E flop/s; number of flops computed so far: %.0E (nothing should have "
"changed)",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_computed_flops(host));
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_computed_flops(host));
// Run a task
start = simgrid_get_clock();
- XBT_INFO("Run a task of %.0E flops at current speed of %.0E flop/s", 200e6, sg_host_speed(host));
+ XBT_INFO("Run a task of %.0E flops at current speed of %.0E flop/s", 200e6, sg_host_get_speed(host));
sg_actor_execute(200e6);
XBT_INFO("Done working on my task; this took %.2fs; current peak speed: %.0E flop/s (when I started the computation, "
"the speed was set to %.0E flop/s); number of flops computed so "
"far: %.2E, average load as reported by the HostLoad plugin: %.5f (should be %.5f)",
- simgrid_get_clock() - start, sg_host_speed(host), speed, sg_host_get_computed_flops(host),
+ simgrid_get_clock() - start, sg_host_get_speed(host), speed, sg_host_get_computed_flops(host),
sg_host_get_avg_load(host),
200E6 / (10.5 * speed * sg_host_core_count(host) +
- (simgrid_get_clock() - start - 0.5) * sg_host_speed(host) * sg_host_core_count(host)));
+ (simgrid_get_clock() - start - 0.5) * sg_host_get_speed(host) * sg_host_core_count(host)));
// ========= Change power peak =========
int pstate = 1;
sg_host_set_pstate(host, pstate);
XBT_INFO(
"========= Requesting pstate %d (speed should be of %.0E flop/s and is of %.0E flop/s, average load is %.5f)",
- pstate, sg_host_get_pstate_speed(host, pstate), sg_host_speed(host), sg_host_get_avg_load(host));
+ pstate, sg_host_get_pstate_speed(host, pstate), sg_host_get_speed(host), sg_host_get_avg_load(host));
// Run a second task
start = simgrid_get_clock();
sg_actor_execute(100e6);
XBT_INFO("Done working on my task; this took %.2fs; current peak speed: %.0E flop/s; number of flops computed so "
"far: %.2E",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_computed_flops(host));
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_computed_flops(host));
start = simgrid_get_clock();
XBT_INFO("========= Requesting a reset of the computation and load counters");
XBT_INFO("Sleep for 4 seconds");
sg_actor_sleep_for(4);
XBT_INFO("Done sleeping %.2f s; peak speed: %.0E flop/s; number of flops computed so far: %.0E",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_computed_flops(host));
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_computed_flops(host));
// =========== Turn the other host off ==========
XBT_INFO("Turning MyHost2 off, and sleeping another 10 seconds. MyHost2 computed %.0f flops so far and has an "
start = simgrid_get_clock();
sg_actor_sleep_for(10);
XBT_INFO("Done sleeping %.2f s; peak speed: %.0E flop/s; number of flops computed so far: %.0E",
- simgrid_get_clock() - start, sg_host_speed(host), sg_host_get_computed_flops(host));
+ simgrid_get_clock() - start, sg_host_get_speed(host), sg_host_get_computed_flops(host));
}
static void change_speed(int argc, char* argv[])
+++ /dev/null
-foreach(x trace-categories trace-route-user-variables trace-link-user-variables
- trace-masterworker trace-process-migration trace-host-user-variables)
- if(enable_msg)
- add_executable (${x} EXCLUDE_FROM_ALL ${x}/${x}.c)
- target_link_libraries(${x} simgrid)
- set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x})
- add_dependencies(tests ${x})
- endif()
- set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.c)
- set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.tesh)
-endforeach()
-
-set(examples_src ${examples_src} PARENT_SCOPE)
-set(txt_files ${txt_files} ${CMAKE_CURRENT_SOURCE_DIR}/README.doc PARENT_SCOPE)
-set(tesh_files ${tesh_files} PARENT_SCOPE)
-
-if(enable_msg)
- foreach (x trace-categories trace-route-user-variables trace-link-user-variables trace-masterworker
- trace-process-migration trace-host-user-variables)
- ADD_TESH(msg-${x} --setenv bindir=${CMAKE_BINARY_DIR}/examples/deprecated/msg/${x}
- --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/${x}
- --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
- --cd ${CMAKE_BINARY_DIR}/examples/deprecated/msg/${x}
- ${CMAKE_HOME_DIRECTORY}/examples/deprecated/msg/${x}/${x}.tesh)
- endforeach()
-endif(enable_msg)
\ No newline at end of file
+++ /dev/null
-// This file follows the Doxygen syntax to be included in the
-// documentation, but it should remain readable directly.
-
-/**
- @defgroup msg_examples MSG examples
- @ingroup MSG_API
- @brief Find the MSG example fitting your needs from the extensive set provided in the archive.
-
- - @ref msg_ex_tracing
- - @ref msg_ex_tracing_user_variables
-
-@warning MSG was deprecated in SimGrid v3.18. These examples should be
- converted to S4U in the next releases. You really should
- consider using S4U in your next project.
-
-@section msg_ex_tracing Tracing and visualization features
-
-Tracing can be activated by various configuration options which
-are illustrated in these example. See also the
-@ref tracing_tracing_options "full list of options related to tracing".
-
-It is interesting to run the process-create example with the following
-options to see the task executions:
-
- - <b>Setting Categories</b>.
- @ref examples/deprecated/msg/trace-categories/trace-categories.c \n
- This example declares several tracing categories
- to that are used to classify its tasks. When the program is executed,
- the tracing mechanism registers the resource utilization of hosts
- and links according to these categories. Recommended options:
- @verbatim --cfg=tracing:yes --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes
- @endverbatim
-
- - <b>Master Workers tracing</b>.
- @ref examples/deprecated/msg/trace-masterworker/trace-masterworker.c \n
- This is an augmented version of our basic master/worker example
- using several tracing features. It traces resource usage, sorted
- out in several categories; Trace marks and user variables are also
- used. Recommended options:
- @verbatim --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes
- @endverbatim
-
- - <b>Process migration tracing</b>.
- @ref examples/deprecated/msg/trace-process-migration/trace-process-migration.c \n
- This version is enhanced so that the process migrations can be
- displayed as arrows in a Gantt-chart visualization. Recommended
- options to that extend:
- @verbatim -cfg=tracing:yes --cfg=tracing/msg/process:yes
- @endverbatim
-
-TODO: These tracing examples should be integrated in the examples to
-not duplicate the C files. A full command line to see the result in
-the right tool (vite/FrameSoc) should be given along with some
-screenshots.
-
-@subsection msg_ex_tracing_user_variables Tracing user variables
-
-You can also attach your own variables to any resource described in
-the platform file. The following examples illustrate this feature.
-They have to be run with the following options:
-@verbatim --cfg=tracing:yes --cfg=tracing/platform:yes
-@endverbatim
-
- - <b>Attaching variables to Hosts</b>.
- @ref examples/deprecated/msg/trace-host-user-variables/trace-host-user-variables.c
-
- - <b>Attaching variables to Links</b>.
- @ref examples/deprecated/msg/trace-link-user-variables/trace-link-user-variables.c \n
- The tricky part is that you have to know the name of the link you
- want to enhance with a variable.
-
- - <b>Attaching variables to network Routes</b>
- @ref examples/deprecated/msg/trace-route-user-variables/trace-route-user-variables.c \n
- It is often easier to update a given variable for all links of a
- given network path (identified by its source and destination
- hosts) instead of knowing the name of each specific link.
-
-// As a human, you can stop reading at this point. The rest is garbage:
-//
-// Every example must be listed in the following, but it's not possible
-// to move this content upper as each @example directive seems to eat
-// everything until the next */ marker (and the content is placed at the
-// top of the example file).
-
-
-/**
-
-@example examples/deprecated/msg/trace-categories/trace-categories.c
-@example examples/deprecated/msg/trace-masterworker/trace-masterworker.c
-@example examples/deprecated/msg/trace-process-migration/trace-process-migration.c
-@example examples/deprecated/msg/trace-host-user-variables/trace-host-user-variables.c
-@example examples/deprecated/msg/trace-link-user-variables/trace-link-user-variables.c
-@example examples/deprecated/msg/trace-route-user-variables/trace-route-user-variables.c
-
-*/
-
+++ /dev/null
-/* Copyright (c) 2010-2020. 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/msg.h"
-
-static int master(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
-{
- long number_of_tasks = 10;
- long workers_count = 1;
-
- for (int i = 0; i < number_of_tasks; i++) {
- msg_task_t task = NULL;
-
- /* creating task and setting its category */
- if (i % 2) {
- task = MSG_task_create("task_compute", 10000000, 0, NULL);
- MSG_task_set_category(task, "compute");
- } else if (i % 3) {
- task = MSG_task_create("task_request", 10, 10, NULL);
- MSG_task_set_category(task, "request");
- } else {
- task = MSG_task_create("task_data", 10, 10000000, NULL);
- MSG_task_set_category(task, "data");
- }
- MSG_task_send(task, "master_mailbox");
- }
-
- for (int i = 0; i < workers_count; i++) {
- msg_task_t finalize = MSG_task_create("finalize", 0, 1000, 0);
- MSG_task_set_category(finalize, "finalize");
- MSG_task_send(finalize, "master_mailbox");
- }
-
- return 0;
-}
-
-static int worker(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
-{
- msg_task_t task = NULL;
-
- while (1) {
- MSG_task_receive(&(task), "master_mailbox");
-
- if (strcmp(MSG_task_get_name(task), "finalize") == 0) {
- MSG_task_destroy(task);
- break;
- }
-
- MSG_task_execute(task);
- MSG_task_destroy(task);
- task = NULL;
- }
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- MSG_init(&argc, argv);
- xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s msg_platform.xml\n", argv[0], argv[0]);
-
- MSG_create_environment(argv[1]);
-
- /* declaring user categories with RGB colors */
- TRACE_category_with_color ("compute", "1 0 0"); //red
- TRACE_category_with_color ("request", "0 1 0"); //green
- TRACE_category_with_color ("data", "0 0 1"); //blue
- TRACE_category_with_color ("finalize", "0 0 0");//black
-
- MSG_process_create("master", master, NULL, MSG_host_by_name("Tremblay"));
- MSG_process_create("worker", worker, NULL, MSG_host_by_name("Fafard"));
-
- MSG_main();
- return 0;
-}
+++ /dev/null
-/* Copyright (c) 2010-2020. The SimGrid Team. All rights reserved. */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#include <stdio.h>
-#include "simgrid/msg.h"
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
-
-static int trace_fun(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
-{
- const char *hostname = MSG_host_get_name(MSG_host_self());
-
- //the hostname has an empty HDD with a capacity of 100000 (bytes)
- TRACE_host_variable_set(hostname, "HDD_capacity", 100000);
- TRACE_host_variable_set(hostname, "HDD_utilization", 0);
-
- for (int i = 0; i < 10; i++) {
- //create and execute a task just to make the simulated time advance
- msg_task_t task = MSG_task_create("task", 10000, 0, NULL);
- MSG_task_execute (task);
- MSG_task_destroy (task);
-
- //ADD: after the execution of this task, the HDD utilization increases by 100 (bytes)
- TRACE_host_variable_add(hostname, "HDD_utilization", 100);
- }
-
- for (int i = 0; i < 10; i++) {
- //create and execute a task just to make the simulated time advance
- msg_task_t task = MSG_task_create("task", 10000, 0, NULL);
- MSG_task_execute (task);
- MSG_task_destroy (task);
-
- //SUB: after the execution of this task, the HDD utilization decreases by 100 (bytes)
- TRACE_host_variable_sub(hostname, "HDD_utilization", 100);
- }
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- MSG_init(&argc, argv);
- xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s msg_platform.xml\n", argv[0], argv[0]);
-
- MSG_create_environment(argv[1]);
-
- //declaring user variables
- TRACE_host_variable_declare("HDD_capacity");
- TRACE_host_variable_declare("HDD_utilization");
-
- MSG_process_create("master", trace_fun, NULL, MSG_host_by_name("Tremblay"));
-
- MSG_main();
-
- //get user declared variables
- unsigned int cursor;
- char *variable;
- xbt_dynar_t host_variables = TRACE_get_host_variables ();
- if (host_variables){
- XBT_INFO ("Declared host variables:");
- xbt_dynar_foreach (host_variables, cursor, variable){
- XBT_INFO ("%s", variable);
- }
- xbt_dynar_free (&host_variables);
- }
- xbt_dynar_t link_variables = TRACE_get_link_variables ();
- if (link_variables){
- XBT_INFO ("Declared link variables:");
- xbt_dynar_foreach (link_variables, cursor, variable){
- XBT_INFO ("%s", variable);
- }
- xbt_dynar_free (&link_variables);
- }
- return 0;
-}
+++ /dev/null
-#!/usr/bin/env tesh
-
-p Tracing user variables for hosts
-$ ${bindir:=.}/trace-host-user-variables --cfg=tracing:yes --cfg=tracing/platform:yes ${platfdir}/small_platform.xml
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/platform' to 'yes'
-> [0.002039] [msg_test/INFO] Declared host variables:
-> [0.002039] [msg_test/INFO] HDD_capacity
-> [0.002039] [msg_test/INFO] HDD_utilization
-> [0.002039] [msg_test/INFO] Declared link variables:
-
-$ rm -f simgrid.trace
-
-p Not tracing user variables
-$ ${bindir:=.}/trace-host-user-variables ${platfdir}/small_platform.xml
+++ /dev/null
-/* Copyright (c) 2012-2020. 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/msg.h>
-
-//dump function to create and execute a task
-static void create_and_execute_task (void)
-{
- msg_task_t task = MSG_task_create("task", 1000000, 0, NULL);
- MSG_task_execute (task);
- MSG_task_destroy (task);
-}
-
-static int trace_fun(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
-{
- //set initial values for the link user variables this example only shows for links identified by "6" and "3" in the
- //platform file
-
- //Set the Link_Capacity variable
- TRACE_link_variable_set("6", "Link_Capacity", 12.34);
- TRACE_link_variable_set("3", "Link_Capacity", 56.78);
-
- //Set the Link_Utilization variable
- TRACE_link_variable_set("3", "Link_Utilization", 1.2);
- TRACE_link_variable_set("6", "Link_Utilization", 3.4);
-
- //run the simulation, update my variables accordingly
- for (int i = 0; i < 10; i++) {
- create_and_execute_task ();
-
- //Add to link user variables
- TRACE_link_variable_add ("3", "Link_Utilization", 5.6);
- TRACE_link_variable_add ("6", "Link_Utilization", 7.8);
- }
-
- for (int i = 0; i < 10; i++) {
- create_and_execute_task ();
-
- //Subtract from link user variables
- TRACE_link_variable_sub ("3", "Link_Utilization", 3.4);
- TRACE_link_variable_sub ("6", "Link_Utilization", 5.6);
- }
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- MSG_init(&argc, argv);
- xbt_assert(argc > 2, "Usage: %s platform_file deployment_file\n"
- "\tExample: %s msg_platform.xml msg_deployment.xml\n", argv[0], argv[0]);
-
- MSG_create_environment(argv[1]);
-
- // declaring link user variables (one without, another with an RGB color)
- TRACE_link_variable_declare("Link_Capacity");
- TRACE_link_variable_declare_with_color ("Link_Utilization", "0.9 0.1 0.1");
-
- //register functions and launch deployment
- MSG_function_register("master", trace_fun);
- MSG_function_register("worker", trace_fun);
- MSG_launch_application(argv[2]);
-
- MSG_main();
- return 0;
-}
+++ /dev/null
-/* Copyright (c) 2010-2020. 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/msg.h"
-
-XBT_LOG_NEW_DEFAULT_CATEGORY(msg_trace_masterworker, "Messages specific for this msg example");
-
-static int master(int argc, char *argv[])
-{
- xbt_assert(argc == 5);
- long number_of_tasks = xbt_str_parse_int(argv[1], "Invalid amount of tasks: %s");
- double task_comp_size = xbt_str_parse_double(argv[2], "Invalid computational size: %s");
- double task_comm_size = xbt_str_parse_double(argv[3], "Invalid communication size: %s");
- long workers_count = xbt_str_parse_int(argv[4], "Invalid amount of workers: %s");
-
- //setting the variable "is_master" (previously declared) to value 1
- TRACE_host_variable_set(MSG_host_get_name(MSG_host_self()), "is_master", 1);
-
- TRACE_mark("msmark", "start_send_tasks");
- for (int i = 0; i < number_of_tasks; i++) {
- msg_task_t task = MSG_task_create("task", task_comp_size, task_comm_size, NULL);
-
- //setting the variable "task_creation" to value i
- TRACE_host_variable_set(MSG_host_get_name(MSG_host_self()), "task_creation", i);
-
- //setting the category of task to "compute"
- //the category of a task must be defined before it is sent or executed
- MSG_task_set_category(task, "compute");
- MSG_task_send(task, "master_mailbox");
- }
- TRACE_mark("msmark", "finish_send_tasks");
-
- for (int i = 0; i < workers_count; i++) {
- msg_task_t finalize = MSG_task_create("finalize", 0, 0, 0);
- MSG_task_set_category(finalize, "finalize");
- MSG_task_send(finalize, "master_mailbox");
- }
-
- return 0;
-}
-
-static int worker(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
-{
- msg_task_t task = NULL;
-
- TRACE_host_variable_set(MSG_host_get_name(MSG_host_self()), "is_worker", 1);
- TRACE_host_variable_set(MSG_host_get_name(MSG_host_self()), "task_computation", 0);
- while (1) {
- MSG_task_receive(&(task), "master_mailbox");
-
- if (strcmp(MSG_task_get_name(task), "finalize") == 0) {
- MSG_task_destroy(task);
- break;
- }
- // adding the value returned by MSG_task_get_compute_duration(task) to the variable "task_computation"
- TRACE_host_variable_add(MSG_host_get_name(MSG_host_self()), "task_computation", MSG_task_get_flops_amount(task));
- MSG_task_execute(task);
- MSG_task_destroy(task);
- task = NULL;
- }
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- MSG_init(&argc, argv);
- xbt_assert(argc > 2, "Usage: %s platform_file deployment_file\n"
- "\tExample: %s msg_platform.xml msg_deployment.xml\n", argv[0], argv[0]);
-
- MSG_create_environment(argv[1]);
-
- //declaring user variables
- TRACE_host_variable_declare("is_worker");
- TRACE_host_variable_declare("is_master");
- TRACE_host_variable_declare("task_creation");
- TRACE_host_variable_declare("task_computation");
-
- //declaring user markers and values
- TRACE_declare_mark("msmark");
- TRACE_declare_mark_value ("msmark", "start_send_tasks");
- TRACE_declare_mark_value ("msmark", "finish_send_tasks");
-
- //declaring user categories with RGB colors (values from 0 to 1)
- TRACE_category_with_color ("compute", "1 0 0"); //compute is red
- TRACE_category_with_color ("finalize", "0 1 0"); //finalize is green
- //categories without user-defined colors receive random colors generated by the tracing system
- TRACE_category ("request");
- TRACE_category_with_color ("report", NULL);
-
- MSG_function_register("master", master);
- MSG_function_register("worker", worker);
- MSG_launch_application(argv[2]);
-
- MSG_main();
-
- unsigned int cursor;
- xbt_dynar_t categories = TRACE_get_categories ();
- if (categories){
- XBT_INFO ("Declared tracing categories:");
- char *category;
- xbt_dynar_foreach (categories, cursor, category){
- XBT_INFO ("%s", category);
- }
- xbt_dynar_free (&categories);
- }
-
- xbt_dynar_t marks = TRACE_get_marks ();
- if (marks){
- XBT_INFO ("Declared marks:");
- char *mark;
- xbt_dynar_foreach (marks, cursor, mark){
- XBT_INFO ("%s", mark);
- }
- xbt_dynar_free (&marks);
- }
-
- return 0;
-}
+++ /dev/null
-#!/usr/bin/env tesh
-
-p Tracing master/worker application
-$ ${bindir:=.}/trace-masterworker --cfg=tracing:yes --cfg=tracing/filename:trace-masterworker.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${platfdir}/small_platform.xml ${srcdir:=.}/../../../c/app-masterworker/app-masterworker_d.xml
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
-> [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
-> [4.214821] [msg_trace_masterworker/INFO] compute
-> [4.214821] [msg_trace_masterworker/INFO] finalize
-> [4.214821] [msg_trace_masterworker/INFO] report
-> [4.214821] [msg_trace_masterworker/INFO] request
-> [4.214821] [msg_trace_masterworker/INFO] Declared marks:
-> [4.214821] [msg_trace_masterworker/INFO] msmark
-
-p Tracing master/worker application with xml config
-$ ${bindir:=.}/trace-masterworker ${platfdir}/config_tracing.xml ${srcdir:=.}/../../../c/app-masterworker/app-masterworker_d.xml
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
-> [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
-> [4.214821] [msg_trace_masterworker/INFO] compute
-> [4.214821] [msg_trace_masterworker/INFO] finalize
-> [4.214821] [msg_trace_masterworker/INFO] report
-> [4.214821] [msg_trace_masterworker/INFO] request
-> [4.214821] [msg_trace_masterworker/INFO] Declared marks:
-> [4.214821] [msg_trace_masterworker/INFO] msmark
-
-p Not tracing master/worker application
-$ ${bindir:=.}/trace-masterworker ${platfdir}/small_platform.xml ${srcdir:=.}/../../../c/app-masterworker/app-masterworker_d.xml
-
-p Testing tracing by process
-$ ${bindir:=.}/trace-masterworker --cfg=tracing:yes --cfg=tracing/msg/process:yes --cfg=tracing/filename:trace-masterworker.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${platfdir}/small_platform.xml ${srcdir:=.}/../../../c/app-masterworker/app-masterworker_d.xml
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/msg/process' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
-> [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
-> [4.214821] [msg_trace_masterworker/INFO] compute
-> [4.214821] [msg_trace_masterworker/INFO] finalize
-> [4.214821] [msg_trace_masterworker/INFO] report
-> [4.214821] [msg_trace_masterworker/INFO] request
-> [4.214821] [msg_trace_masterworker/INFO] Declared marks:
-> [4.214821] [msg_trace_masterworker/INFO] msmark
-
-$ rm -rf trace-masterworker.trace
+++ /dev/null
-/* Copyright (c) 2010-2020. 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/msg.h"
-
-/* The guy we will move from host to host. It move alone and then is moved by policeman back */
-static int emigrant(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
-{
- msg_task_t task = NULL;
- char *destination = NULL;
-
- MSG_process_sleep(2);
-
- while (1){ // I am an eternal emigrant
- MSG_task_receive(&(task), "master_mailbox");
- destination = (char*)MSG_task_get_data (task);
- MSG_task_destroy (task);
- if (destination == NULL)
- break; //there is no destination, die
- MSG_process_migrate(MSG_process_self(), MSG_host_by_name(destination));
- MSG_process_sleep(2); // I am tired, have to sleep for 2 seconds
- free (destination);
- task = NULL;
- }
- return 0;
-}
-
-static int policeman(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
-{
- // I am the master of emigrant process,
- // I tell it where it must emigrate to.
- xbt_dynar_t destinations = xbt_dynar_new (sizeof(char*), &xbt_free_ref);
- xbt_dynar_push_as (destinations, char*, xbt_strdup ("Tremblay"));
- xbt_dynar_push_as (destinations, char*, xbt_strdup ("Jupiter"));
- xbt_dynar_push_as (destinations, char*, xbt_strdup ("Fafard"));
- xbt_dynar_push_as (destinations, char*, xbt_strdup ("Ginette"));
- xbt_dynar_push_as (destinations, char*, xbt_strdup ("Bourassa"));
- xbt_dynar_push_as (destinations, char*, xbt_strdup ("Fafard"));
- xbt_dynar_push_as (destinations, char*, xbt_strdup ("Tremblay"));
- xbt_dynar_push_as (destinations, char*, xbt_strdup ("Ginette"));
- xbt_dynar_push_as (destinations, char*, NULL);
-
- char *destination;
- unsigned int i;
- xbt_dynar_foreach(destinations, i, destination){
- msg_task_t task = MSG_task_create("task", 0, 0, NULL);
- if (destination != NULL){
- MSG_task_set_data(task, xbt_strdup (destination));
- }
- MSG_task_set_category(task, "migration_order");
- MSG_task_send (task, "master_mailbox");
- }
- xbt_dynar_free (&destinations);
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- MSG_init(&argc, argv);
- xbt_assert(argc > 1, "Usage: %s platform_file\n\tExample: %s msg_platform.xml\n", argv[0], argv[0]);
-
- MSG_create_environment(argv[1]);
-
- TRACE_category ("migration_order");
-
- MSG_process_create("emigrant", emigrant, NULL, MSG_get_host_by_name("Fafard"));
- MSG_process_create("policeman", policeman, NULL, MSG_get_host_by_name("Tremblay"));
-
- MSG_main();
- return 0;
-}
+++ /dev/null
-/* Copyright (c) 2012-2020. 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/msg.h>
-
-//dump function to create and execute a task
-static void create_and_execute_task (void)
-{
- msg_task_t task = MSG_task_create("task", 1000000, 0, NULL);
- MSG_task_execute (task);
- MSG_task_destroy (task);
-}
-
-static int trace_fun(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
-{
- //Set initial values for the link user variables
- //This example uses source and destination where source and destination are the name of hosts in the platform file.
- //The functions will set/change the value of the variable for all links in the route between source and destination.
-
- //Set the Link_Capacity variable
- TRACE_link_srcdst_variable_set("Tremblay", "Bourassa", "Link_Capacity", 12.34);
- TRACE_link_srcdst_variable_set("Fafard", "Ginette", "Link_Capacity", 56.78);
-
- //Set the Link_Utilization variable
- TRACE_link_srcdst_variable_set("Tremblay", "Bourassa", "Link_Utilization", 1.2);
- TRACE_link_srcdst_variable_set("Fafard", "Ginette", "Link_Utilization", 3.4);
-
- //run the simulation, update my variables accordingly
- for (int i = 0; i < 10; i++) {
- create_and_execute_task ();
-
- //Add to link user variables
- TRACE_link_srcdst_variable_add ("Tremblay", "Bourassa", "Link_Utilization", 5.6);
- TRACE_link_srcdst_variable_add ("Fafard", "Ginette", "Link_Utilization", 7.8);
- }
-
- for (int i = 0; i < 10; i++) {
- create_and_execute_task ();
-
- //Subtract from link user variables
- TRACE_link_srcdst_variable_sub ("Tremblay", "Bourassa", "Link_Utilization", 3.4);
- TRACE_link_srcdst_variable_sub ("Fafard", "Ginette", "Link_Utilization", 5.6);
- }
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- MSG_init(&argc, argv);
- xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s msg_platform.xml\n", argv[0], argv[0]);
-
- MSG_create_environment(argv[1]);
-
- // declaring link user variables (one without, another with an RGB color)
- TRACE_link_variable_declare("Link_Capacity");
- TRACE_link_variable_declare_with_color ("Link_Utilization", "0.9 0.1 0.1");
-
- MSG_process_create("master", trace_fun, NULL, MSG_host_by_name("Tremblay"));
- MSG_process_create("worker", trace_fun, NULL, MSG_host_by_name("Tremblay"));
- MSG_process_create("worker", trace_fun, NULL, MSG_host_by_name("Jupiter"));
- MSG_process_create("worker", trace_fun, NULL, MSG_host_by_name("Fafard"));
- MSG_process_create("worker", trace_fun, NULL, MSG_host_by_name("Ginette"));
- MSG_process_create("worker", trace_fun, NULL, MSG_host_by_name("Bourassa"));
-
- MSG_main();
- return 0;
-}
static double sg_host_get_available_at(const_sg_host_t host)
{
- const struct _HostAttribute* attr = (HostAttribute)sg_host_data(host);
+ const struct _HostAttribute* attr = (HostAttribute)sg_host_get_data(host);
return attr->available_at;
}
static void sg_host_set_available_at(sg_host_t host, double time)
{
- HostAttribute attr = (HostAttribute)sg_host_data(host);
+ HostAttribute attr = (HostAttribute)sg_host_get_data(host);
attr->available_at = time;
- sg_host_data_set(host, attr);
+ sg_host_set_data(host, attr);
}
static SD_task_t sg_host_get_last_scheduled_task(const_sg_host_t host)
{
- const struct _HostAttribute* attr = (HostAttribute)sg_host_data(host);
+ const struct _HostAttribute* attr = (HostAttribute)sg_host_get_data(host);
return attr->last_scheduled_task;
}
static void sg_host_set_last_scheduled_task(sg_host_t host, SD_task_t task){
- HostAttribute attr = (HostAttribute)sg_host_data(host);
+ HostAttribute attr = (HostAttribute)sg_host_get_data(host);
attr->last_scheduled_task=task;
- sg_host_data_set(host, attr);
+ sg_host_set_data(host, attr);
}
static xbt_dynar_t get_ready_tasks(const_xbt_dynar_t dax)
if (SD_task_get_amount(parent) <= 1e-6){
redist_time= 0;
} else {
- redist_time = sg_host_route_latency(parent_host[0], host) +
- SD_task_get_amount(parent) / sg_host_route_bandwidth(parent_host[0], host);
+ redist_time = sg_host_get_route_latency(parent_host[0], host) +
+ SD_task_get_amount(parent) / sg_host_get_route_bandwidth(parent_host[0], host);
}
data_available = SD_task_get_start_time(parent) + redist_time;
}
xbt_dynar_free_container(&parents);
- result = fmax(sg_host_get_available_at(host), last_data_available) + SD_task_get_amount(task) / sg_host_speed(host);
+ result =
+ fmax(sg_host_get_available_at(host), last_data_available) + SD_task_get_amount(task) / sg_host_get_speed(host);
} else {
xbt_dynar_free_container(&parents);
- result = sg_host_get_available_at(host) + SD_task_get_amount(task)/sg_host_speed(host);
+ result = sg_host_get_available_at(host) + SD_task_get_amount(task) / sg_host_get_speed(host);
}
return result;
}
sg_host_t *hosts = sg_host_list();
for (cursor = 0; cursor < total_nhosts; cursor++)
- sg_host_data_set(hosts[cursor], xbt_new0(struct _HostAttribute, 1));
+ sg_host_set_data(hosts[cursor], xbt_new0(struct _HostAttribute, 1));
/* load the DAX file */
xbt_dynar_t dax = SD_daxload(argv[2]);
xbt_dynar_free_container(&dax);
for (cursor = 0; cursor < total_nhosts; cursor++) {
- free(sg_host_data(hosts[cursor]));
- sg_host_data_set(hosts[cursor], NULL);
+ free(sg_host_get_data(hosts[cursor]));
+ sg_host_set_data(hosts[cursor], NULL);
}
xbt_free(hosts);
h1->route_to(h2, route, &latency);
for (auto const& link : route)
- XBT_INFO(" Link %s: latency = %f, bandwidth = %f", sg_link_name(link), sg_link_latency(link),
- sg_link_bandwidth(link));
+ XBT_INFO(" Link %s: latency = %f, bandwidth = %f", sg_link_get_name(link), sg_link_get_latency(link),
+ sg_link_get_bandwidth(link));
- XBT_INFO("Route latency = %f, route bandwidth = %f", latency, sg_host_route_bandwidth(h1, h2));
+ XBT_INFO("Route latency = %f, route bandwidth = %f", latency, sg_host_get_route_bandwidth(h1, h2));
XBT_INFO("Communication time for %f bytes between %s and %s: %f", comm_amount12, h1->get_cname(), h2->get_cname(),
- sg_host_route_latency(h1, h2) + comm_amount12 / sg_host_route_bandwidth(h1, h2));
+ sg_host_get_route_latency(h1, h2) + comm_amount12 / sg_host_get_route_bandwidth(h1, h2));
XBT_INFO("Communication time for %f bytes between %s and %s: %f", comm_amount21, h2->get_cname(), h1->get_cname(),
- sg_host_route_latency(h2, h1) + comm_amount21 / sg_host_route_bandwidth(h2, h1));
+ sg_host_get_route_latency(h2, h1) + comm_amount21 / sg_host_get_route_bandwidth(h2, h1));
/* creation of the tasks and their dependencies */
SD_task_t taskA = SD_task_create("Task A", nullptr, 10.0);
set(_${example}_factories "ucontext;raw;boost")
endforeach()
-set(_mc-bugged1-liveness_disable 1)
if(SIMGRID_HAVE_MC)
add_executable (s4u-mc-bugged1-liveness EXCLUDE_FROM_ALL mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp)
target_link_libraries(s4u-mc-bugged1-liveness simgrid)
set_target_properties(s4u-mc-bugged1-liveness PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/mc-bugged1-liveness)
add_dependencies(tests s4u-mc-bugged1-liveness)
- set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp)
- set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh)
if(HAVE_C_STACK_CLEANER)
add_executable (s4u-mc-bugged1-liveness-cleaner-on EXCLUDE_FROM_ALL s4u-mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp)
set_target_properties(s4u-mc-bugged1-liveness-cleaner-off PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fno-stack-cleaner")
add_dependencies(tests s4u-mc-bugged1-liveness-cleaner-off)
endif()
-
endif()
if(SIMGRID_HAVE_NS3)
engine-filtering
exec-async exec-basic exec-dvfs exec-ptask exec-remote exec-waitany exec-waitfor exec-dependent
maestro-set
- mc-bugged1 mc-bugged1-liveness mc-bugged2 mc-electric-fence mc-failing-assert
+ mc-bugged1 mc-bugged2 mc-electric-fence mc-failing-assert
network-wifi
io-async io-file-system io-file-remote io-disk-raw io-dependent
platform-failures platform-profile platform-properties
${CMAKE_HOME_DIRECTORY}/examples/s4u/${example}/s4u-${example}.tesh)
else()
message(STATUS "Example ${example} disabled, thus not compiled.")
- unset(_${example}_disabled)
+ unset(_${example}_disable)
endif()
set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/s4u-${example}.tesh)
# Examples not accepting factories
##################################
-foreach (example trace-platform)
+foreach (example trace-categories trace-masterworkers trace-platform trace-process-migration
+ trace-host-user-variables trace-link-user-variables trace-route-user-variables)
add_executable (s4u-${example} EXCLUDE_FROM_ALL ${example}/s4u-${example}.cpp)
target_link_libraries(s4u-${example} simgrid)
set_target_properties(s4u-${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${example})
set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/s4u-${example}.cpp)
ADD_TESH(s4u-${example} --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example}
+ --setenv srcdir=${CMAKE_CURRENT_SOURCE_DIR}/${example}
--setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
+ --cd ${CMAKE_CURRENT_BINARY_DIR}/${example}
${CMAKE_HOME_DIRECTORY}/examples/s4u/${example}/s4u-${example}.tesh)
endforeach()
${CMAKE_CURRENT_SOURCE_DIR}/app-pingpong/simix-breakpoint.tesh)
endif()
+if(enable_coverage AND SIMGRID_HAVE_MC)
+ foreach (example mc-bugged1 mc-bugged2 mc-electric-fence mc-failing-assert)
+ ADD_TEST(cover-${example} ${CMAKE_CURRENT_BINARY_DIR}/${example}/s4u-${example} ${CMAKE_HOME_DIRECTORY}/examples/platforms/model_checker_platform.xml)
+ endforeach()
+ ADD_TEST(cover-mc-bugged1-liveness ${CMAKE_CURRENT_BINARY_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness ${CMAKE_HOME_DIRECTORY}/examples/platforms/small_platform.xml 1 1001)
+endif()
+
# Add all extra files to the archive
####################################
-
-set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/s4u-network-ns3.cpp
+set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/s4u-network-ns3.cpp
${CMAKE_CURRENT_SOURCE_DIR}/network-ns3-wifi/s4u-network-ns3-wifi.cpp PARENT_SCOPE)
set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/app-pingpong/simix-breakpoint.tesh
+ ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh
${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh
${CMAKE_CURRENT_SOURCE_DIR}/network-ns3/s4u-network-ns3.tesh
${CMAKE_CURRENT_SOURCE_DIR}/network-ns3-wifi/s4u-network-ns3-wifi.tesh PARENT_SCOPE)
/** Interval between each update of the choked peers */
constexpr int UPDATE_CHOKED_INTERVAL = 30;
-/** Message sizes
- * Sizes based on report by A. Legout et al, Understanding BitTorrent: An Experimental Perspective
- * http://hal.inria.fr/inria-00000156/en
- */
-constexpr unsigned MESSAGE_HANDSHAKE_SIZE = 68;
-constexpr unsigned MESSAGE_CHOKE_SIZE = 5;
-constexpr unsigned MESSAGE_UNCHOKE_SIZE = 5;
-constexpr unsigned MESSAGE_INTERESTED_SIZE = 5;
-constexpr unsigned MESSAGE_NOTINTERESTED_SIZE = 5;
-constexpr unsigned MESSAGE_HAVE_SIZE = 9;
-constexpr unsigned MESSAGE_BITFIELD_SIZE = 5;
-constexpr unsigned MESSAGE_REQUEST_SIZE = 17;
-constexpr unsigned MESSAGE_PIECE_SIZE = 13;
-constexpr unsigned MESSAGE_CANCEL_SIZE = 17;
-
/** Types of messages exchanged between two peers. */
-enum e_message_type {
- MESSAGE_HANDSHAKE,
- MESSAGE_CHOKE,
- MESSAGE_UNCHOKE,
- MESSAGE_INTERESTED,
- MESSAGE_NOTINTERESTED,
- MESSAGE_HAVE,
- MESSAGE_BITFIELD,
- MESSAGE_REQUEST,
- MESSAGE_PIECE,
- MESSAGE_CANCEL
-};
+enum class MessageType { HANDSHAKE, CHOKE, UNCHOKE, INTERESTED, NOTINTERESTED, HAVE, BITFIELD, REQUEST, PIECE, CANCEL };
class Message {
public:
- e_message_type type;
+ MessageType type;
int peer_id;
simgrid::s4u::Mailbox* return_mailbox;
unsigned int bitfield = 0U;
int piece = 0;
int block_index = 0;
int block_length = 0;
- Message(e_message_type type, int peer_id, simgrid::s4u::Mailbox* return_mailbox)
+ Message(MessageType type, int peer_id, simgrid::s4u::Mailbox* return_mailbox)
: type(type), peer_id(peer_id), return_mailbox(return_mailbox){};
- Message(e_message_type type, int peer_id, unsigned int bitfield, simgrid::s4u::Mailbox* return_mailbox)
+ Message(MessageType type, int peer_id, unsigned int bitfield, simgrid::s4u::Mailbox* return_mailbox)
: type(type), peer_id(peer_id), return_mailbox(return_mailbox), bitfield(bitfield){};
- Message(e_message_type type, int peer_id, simgrid::s4u::Mailbox* return_mailbox, int piece, int block_index,
+ Message(MessageType type, int peer_id, simgrid::s4u::Mailbox* return_mailbox, int piece, int block_index,
int block_length)
: type(type)
, peer_id(peer_id)
, piece(piece)
, block_index(block_index)
, block_length(block_length){};
- Message(e_message_type type, int peer_id, simgrid::s4u::Mailbox* return_mailbox, int piece)
+ Message(MessageType type, int peer_id, simgrid::s4u::Mailbox* return_mailbox, int piece)
: type(type), peer_id(peer_id), return_mailbox(return_mailbox), piece(piece){};
};
constexpr double SLEEP_DURATION = 1.0;
#define BITS_TO_BYTES(x) (((x) / 8 + (x) % 8) ? 1 : 0)
-constexpr std::array<const char*, 10> message_type_names{
- {"HANDSHAKE", "CHOKE", "UNCHOKE", "INTERESTED", "NOTINTERESTED", "HAVE", "BITFIELD", "REQUEST", "PIECE", "CANCEL"}};
+/** Message sizes
+ * Sizes based on report by A. Legout et al, Understanding BitTorrent: An Experimental Perspective
+ * http://hal.inria.fr/inria-00000156/en
+ */
+constexpr unsigned message_size(MessageType type)
+{
+ constexpr std::array<unsigned, 10> sizes{{/* HANDSHAKE */ 68,
+ /* CHOKE */ 5,
+ /* UNCHOKE */ 5,
+ /* INTERESTED */ 5,
+ /* NOTINTERESTED */ 5,
+ /* HAVE */ 9,
+ /* BITFIELD */ 5,
+ /* REQUEST */ 17,
+ /* PIECE */ 13,
+ /* CANCEL */ 17}};
+ return sizes[static_cast<int>(type)];
+}
+
+constexpr const char* message_name(MessageType type)
+{
+ constexpr std::array<const char*, 10> names{{"HANDSHAKE", "CHOKE", "UNCHOKE", "INTERESTED", "NOTINTERESTED", "HAVE",
+ "BITFIELD", "REQUEST", "PIECE", "CANCEL"}};
+ return names[static_cast<int>(type)];
+}
Peer::Peer(std::vector<std::string> args)
{
{
for (auto const& kv : connected_peers) {
const Connection& remote_peer = kv.second;
- auto* handshake = new Message(MESSAGE_HANDSHAKE, id, mailbox_);
- remote_peer.mailbox_->put_init(handshake, MESSAGE_HANDSHAKE_SIZE)->detach();
+ auto* handshake = new Message(MessageType::HANDSHAKE, id, mailbox_);
+ remote_peer.mailbox_->put_init(handshake, message_size(MessageType::HANDSHAKE))->detach();
XBT_DEBUG("Sending a HANDSHAKE to %d", remote_peer.id);
}
}
-void Peer::sendMessage(simgrid::s4u::Mailbox* mailbox, e_message_type type, uint64_t size)
+void Peer::sendMessage(simgrid::s4u::Mailbox* mailbox, MessageType type, uint64_t size)
{
- XBT_DEBUG("Sending %s to %s", message_type_names.at(type), mailbox->get_cname());
+ XBT_DEBUG("Sending %s to %s", message_name(type), mailbox->get_cname());
mailbox->put_init(new Message(type, id, bitfield_, mailbox_), size)->detach();
}
{
XBT_DEBUG("Sending a BITFIELD to %s", mailbox->get_cname());
mailbox
- ->put_init(new Message(MESSAGE_BITFIELD, id, bitfield_, mailbox_),
- MESSAGE_BITFIELD_SIZE + BITS_TO_BYTES(FILE_PIECES))
+ ->put_init(new Message(MessageType::BITFIELD, id, bitfield_, mailbox_),
+ message_size(MessageType::BITFIELD) + BITS_TO_BYTES(FILE_PIECES))
->detach();
}
{
xbt_assert(not hasNotPiece(piece), "Tried to send a unavailable piece.");
XBT_DEBUG("Sending the PIECE %u (%d,%d) to %s", piece, block_index, block_length, mailbox->get_cname());
- mailbox->put_init(new Message(MESSAGE_PIECE, id, mailbox_, piece, block_index, block_length), BLOCK_SIZE)->detach();
+ mailbox->put_init(new Message(MessageType::PIECE, id, mailbox_, piece, block_index, block_length), BLOCK_SIZE)
+ ->detach();
}
void Peer::sendHaveToAllPeers(unsigned int piece)
XBT_DEBUG("Sending HAVE message to all my peers");
for (auto const& kv : connected_peers) {
const Connection& remote_peer = kv.second;
- remote_peer.mailbox_->put_init(new Message(MESSAGE_HAVE, id, mailbox_, piece), MESSAGE_HAVE_SIZE)->detach();
+ remote_peer.mailbox_->put_init(new Message(MessageType::HAVE, id, mailbox_, piece), message_size(MessageType::HAVE))
+ ->detach();
}
}
XBT_DEBUG("Sending a REQUEST to %s for piece %u (%d,%d)", remote_peer->mailbox_->get_cname(), piece, block_index,
block_length);
remote_peer->mailbox_
- ->put_init(new Message(MESSAGE_REQUEST, id, mailbox_, piece, block_index, block_length), MESSAGE_REQUEST_SIZE)
+ ->put_init(new Message(MessageType::REQUEST, id, mailbox_, piece, block_index, block_length),
+ message_size(MessageType::REQUEST))
->detach();
}
}
void Peer::handleMessage()
{
- XBT_DEBUG("Received a %s message from %s", message_type_names.at(message->type),
- message->return_mailbox->get_cname());
+ XBT_DEBUG("Received a %s message from %s", message_name(message->type), message->return_mailbox->get_cname());
auto known_peer = connected_peers.find(message->peer_id);
Connection* remote_peer = (known_peer == connected_peers.end()) ? nullptr : &known_peer->second;
- xbt_assert(remote_peer != nullptr || message->type == MESSAGE_HANDSHAKE,
+ xbt_assert(remote_peer != nullptr || message->type == MessageType::HANDSHAKE,
"The impossible did happened: A not-in-our-list peer sent us a message.");
switch (message->type) {
- case MESSAGE_HANDSHAKE:
+ case MessageType::HANDSHAKE:
// Check if the peer is in our connection list.
if (remote_peer == nullptr) {
XBT_DEBUG("This peer %d was unknown, answer to its handshake", message->peer_id);
connected_peers.emplace(message->peer_id, Connection(message->peer_id));
- sendMessage(message->return_mailbox, MESSAGE_HANDSHAKE, MESSAGE_HANDSHAKE_SIZE);
+ sendMessage(message->return_mailbox, MessageType::HANDSHAKE, message_size(MessageType::HANDSHAKE));
}
// Send our bitfield to the peer
sendBitfield(message->return_mailbox);
break;
- case MESSAGE_BITFIELD:
+ case MessageType::BITFIELD:
// Update the pieces list
updatePiecesCountFromBitfield(message->bitfield);
// Store the bitfield
xbt_assert(not remote_peer->am_interested, "Should not be interested at first");
if (isInterestedBy(remote_peer)) {
remote_peer->am_interested = true;
- sendMessage(message->return_mailbox, MESSAGE_INTERESTED, MESSAGE_INTERESTED_SIZE);
+ sendMessage(message->return_mailbox, MessageType::INTERESTED, message_size(MessageType::INTERESTED));
}
break;
- case MESSAGE_INTERESTED:
+ case MessageType::INTERESTED:
// Update the interested state of the peer.
remote_peer->interested = true;
updateActivePeersSet(remote_peer);
break;
- case MESSAGE_NOTINTERESTED:
+ case MessageType::NOTINTERESTED:
remote_peer->interested = false;
updateActivePeersSet(remote_peer);
break;
- case MESSAGE_UNCHOKE:
+ case MessageType::UNCHOKE:
xbt_assert(remote_peer->choked_download);
remote_peer->choked_download = false;
// Send requests to the peer, since it has unchoked us
if (remote_peer->am_interested)
requestNewPieceTo(remote_peer);
break;
- case MESSAGE_CHOKE:
+ case MessageType::CHOKE:
xbt_assert(not remote_peer->choked_download);
remote_peer->choked_download = true;
if (remote_peer->current_piece != -1)
removeCurrentPiece(remote_peer, remote_peer->current_piece);
break;
- case MESSAGE_HAVE:
+ case MessageType::HAVE:
XBT_DEBUG("\t for piece %d", message->piece);
xbt_assert((message->piece >= 0 && static_cast<unsigned int>(message->piece) < FILE_PIECES),
"Wrong HAVE message received");
// If the piece is in our pieces, we tell the peer that we are interested.
if (not remote_peer->am_interested && hasNotPiece(message->piece)) {
remote_peer->am_interested = true;
- sendMessage(message->return_mailbox, MESSAGE_INTERESTED, MESSAGE_INTERESTED_SIZE);
+ sendMessage(message->return_mailbox, MessageType::INTERESTED, message_size(MessageType::INTERESTED));
if (not remote_peer->choked_download)
requestNewPieceTo(remote_peer);
}
break;
- case MESSAGE_REQUEST:
+ case MessageType::REQUEST:
xbt_assert(remote_peer->interested);
xbt_assert((message->piece >= 0 && static_cast<unsigned int>(message->piece) < FILE_PIECES),
"Wrong HAVE message received");
XBT_DEBUG("\t for piece %d but he is choked.", message->peer_id);
}
break;
- case MESSAGE_PIECE:
+ case MessageType::PIECE:
XBT_DEBUG(" \t for piece %d (%d,%d)", message->piece, message->block_index,
message->block_index + message->block_length);
xbt_assert(not remote_peer->choked_download);
requestNewPieceTo(remote_peer);
}
break;
- case MESSAGE_CANCEL:
+ case MessageType::CANCEL:
break;
default:
THROW_IMPOSSIBLE;
choked_peer->choked_upload = true;
updateActivePeersSet(choked_peer);
XBT_DEBUG("(%d) Sending a CHOKE to %d", id, choked_peer->id);
- sendMessage(choked_peer->mailbox_, MESSAGE_CHOKE, MESSAGE_CHOKE_SIZE);
+ sendMessage(choked_peer->mailbox_, MessageType::CHOKE, message_size(MessageType::CHOKE));
}
if (chosen_peer != nullptr) {
xbt_assert((chosen_peer->choked_upload), "Tries to unchoked an unchoked peer");
chosen_peer->last_unchoke = simgrid::s4u::Engine::get_clock();
XBT_DEBUG("(%d) Sending a UNCHOKE to %d", id, chosen_peer->id);
updateActivePeersSet(chosen_peer);
- sendMessage(chosen_peer->mailbox_, MESSAGE_UNCHOKE, MESSAGE_UNCHOKE_SIZE);
+ sendMessage(chosen_peer->mailbox_, MessageType::UNCHOKE, message_size(MessageType::UNCHOKE));
}
}
}
if (not interested) { // no more piece to download from connection
remote_peer.am_interested = false;
- sendMessage(remote_peer.mailbox_, MESSAGE_NOTINTERESTED, MESSAGE_NOTINTERESTED_SIZE);
+ sendMessage(remote_peer.mailbox_, MessageType::NOTINTERESTED, message_size(MessageType::NOTINTERESTED));
}
}
}
void requestNewPieceTo(Connection* remote_peer);
bool getPeersFromTracker();
- void sendMessage(simgrid::s4u::Mailbox* mailbox, e_message_type type, uint64_t size);
+ void sendMessage(simgrid::s4u::Mailbox* mailbox, MessageType type, uint64_t size);
void sendBitfield(simgrid::s4u::Mailbox* mailbox);
void sendPiece(simgrid::s4u::Mailbox* mailbox, unsigned int piece, int block_index, int block_length);
void sendHandshakeToAllPeers();
{
XBT_DEBUG("peer");
- auto* p = new Peer();
+ Peer p;
double start_time = simgrid::s4u::Engine::get_clock();
- p->joinChain();
- p->forwardFile();
+ p.joinChain();
+ p.forwardFile();
- simgrid::s4u::Comm::wait_all(&p->pending_sends);
+ simgrid::s4u::Comm::wait_all(&p.pending_sends);
double end_time = simgrid::s4u::Engine::get_clock();
- XBT_INFO("### %f %llu bytes (Avg %f MB/s); copy finished (simulated).", end_time - start_time, p->received_bytes,
- p->received_bytes / 1024.0 / 1024.0 / (end_time - start_time));
-
- delete p;
+ XBT_INFO("### %f %llu bytes (Avg %f MB/s); copy finished (simulated).", end_time - start_time, p.received_bytes,
+ p.received_bytes / 1024.0 / 1024.0 / (end_time - start_time));
}
static void broadcaster(int hostcount, unsigned int piece_count)
{
XBT_DEBUG("broadcaster");
- auto* bc = new Broadcaster(hostcount, piece_count);
- bc->buildChain();
- bc->sendFile();
-
- delete bc;
+ Broadcaster bc(hostcount, piece_count);
+ bc.buildChain();
+ bc.sendFile();
}
int main(int argc, char* argv[])
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_token_ring, "Messages specific for this s4u example");
class RelayRunner {
- size_t token_size = 1000000; /* The token is 1MB long*/
- simgrid::s4u::Mailbox* my_mailbox;
- simgrid::s4u::Mailbox* neighbor_mailbox;
- unsigned int rank = 0;
-
public:
explicit RelayRunner() = default;
- void operator()()
+ void operator()() const
{
+ size_t token_size = 1000000; /* The token is 1MB long*/
+ simgrid::s4u::Mailbox* my_mailbox;
+ simgrid::s4u::Mailbox* neighbor_mailbox;
+ unsigned int rank = 0;
+
try {
rank = std::stoi(simgrid::s4u::this_actor::get_name());
} catch (const std::invalid_argument& ia) {
XBT_INFO("# 10. (c) migrate");
simgrid::s4u::Host* pm1 = simgrid::s4u::Host::by_name("Fafard");
- MSG_vm_migrate(vm0, pm1);
+ sg_vm_migrate(vm0, pm1);
XBT_INFO(" ");
XBT_INFO("# 10. (d) Put an activity again on the VM.");
void Node::notifyAndQuit()
{
// send the PREDECESSOR_LEAVING to our successor
- auto* pred_msg = new ChordMessage(PREDECESSOR_LEAVING);
+ auto* pred_msg = new ChordMessage(MessageType::PREDECESSOR_LEAVING);
pred_msg->request_id = pred_id_;
pred_msg->answer_to = mailbox_;
if (pred_id_ != -1 && pred_id_ != id_) {
// send the SUCCESSOR_LEAVING to our predecessor (only if I have one that is not me)
- auto* succ_msg = new ChordMessage(SUCCESSOR_LEAVING);
+ auto* succ_msg = new ChordMessage(MessageType::SUCCESSOR_LEAVING);
succ_msg->request_id = fingers_[0];
succ_msg->answer_to = mailbox_;
XBT_DEBUG("Sending a 'SUCCESSOR_LEAVING' to my predecessor %d", pred_id_);
simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(pred_id_));
simgrid::s4u::Mailbox* return_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_) + "_is_alive");
- auto* message = new ChordMessage(PREDECESSOR_ALIVE);
+ auto* message = new ChordMessage(MessageType::PREDECESSOR_ALIVE);
message->request_id = pred_id_;
message->answer_to = return_mailbox;
simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(ask_to));
simgrid::s4u::Mailbox* return_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_) + "_pred");
- auto* message = new ChordMessage(GET_PREDECESSOR);
+ auto* message = new ChordMessage(MessageType::GET_PREDECESSOR);
message->request_id = id_;
message->answer_to = return_mailbox;
simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(ask_to));
simgrid::s4u::Mailbox* return_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_) + "_succ");
- auto* message = new ChordMessage(FIND_SUCCESSOR);
+ auto* message = new ChordMessage(MessageType::FIND_SUCCESSOR);
message->request_id = id_;
message->answer_to = return_mailbox;
/* Notifies a remote node that its predecessor may have changed. */
void Node::remoteNotify(int notify_id, int predecessor_candidate_id) const
{
- auto* message = new ChordMessage(NOTIFY);
+ auto* message = new ChordMessage(MessageType::NOTIFY);
message->request_id = predecessor_candidate_id;
message->answer_to = nullptr;
void Node::handleMessage(ChordMessage* message)
{
switch (message->type) {
- case FIND_SUCCESSOR:
- XBT_DEBUG("Received a 'Find Successor' request from %s for id %d", message->issuer_host_name.c_str(),
- message->request_id);
- // is my successor the successor?
- if (is_in_interval(message->request_id, id_ + 1, fingers_[0])) {
- message->type = FIND_SUCCESSOR_ANSWER;
- message->answer_id = fingers_[0];
- XBT_DEBUG("Sending back a 'Find Successor Answer' to %s (mailbox %s): the successor of %d is %d",
- message->issuer_host_name.c_str(), message->answer_to->get_cname(), message->request_id,
- message->answer_id);
+ case MessageType::FIND_SUCCESSOR:
+ XBT_DEBUG("Received a 'Find Successor' request from %s for id %d", message->issuer_host_name.c_str(),
+ message->request_id);
+ // is my successor the successor?
+ if (is_in_interval(message->request_id, id_ + 1, fingers_[0])) {
+ message->type = MessageType::FIND_SUCCESSOR_ANSWER;
+ message->answer_id = fingers_[0];
+ XBT_DEBUG("Sending back a 'Find Successor Answer' to %s (mailbox %s): the successor of %d is %d",
+ message->issuer_host_name.c_str(), message->answer_to->get_cname(), message->request_id,
+ message->answer_id);
+ message->answer_to->put_init(message, 10)->detach(ChordMessage::destroy);
+ } else {
+ // otherwise, forward the request to the closest preceding finger in my table
+ int closest = closestPrecedingFinger(message->request_id);
+ XBT_DEBUG("Forwarding the 'Find Successor' request for id %d to my closest preceding finger %d",
+ message->request_id, closest);
+ simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(closest));
+ mailbox->put_init(message, 10)->detach(ChordMessage::destroy);
+ }
+ break;
+
+ case MessageType::GET_PREDECESSOR:
+ XBT_DEBUG("Receiving a 'Get Predecessor' request from %s", message->issuer_host_name.c_str());
+ message->type = MessageType::GET_PREDECESSOR_ANSWER;
+ message->answer_id = pred_id_;
+ XBT_DEBUG("Sending back a 'Get Predecessor Answer' to %s via mailbox '%s': my predecessor is %d",
+ message->issuer_host_name.c_str(), message->answer_to->get_cname(), message->answer_id);
message->answer_to->put_init(message, 10)->detach(ChordMessage::destroy);
- } else {
- // otherwise, forward the request to the closest preceding finger in my table
- int closest = closestPrecedingFinger(message->request_id);
- XBT_DEBUG("Forwarding the 'Find Successor' request for id %d to my closest preceding finger %d",
- message->request_id, closest);
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(closest));
- mailbox->put_init(message, 10)->detach(ChordMessage::destroy);
- }
- break;
-
- case GET_PREDECESSOR:
- XBT_DEBUG("Receiving a 'Get Predecessor' request from %s", message->issuer_host_name.c_str());
- message->type = GET_PREDECESSOR_ANSWER;
- message->answer_id = pred_id_;
- XBT_DEBUG("Sending back a 'Get Predecessor Answer' to %s via mailbox '%s': my predecessor is %d",
- message->issuer_host_name.c_str(), message->answer_to->get_cname(), message->answer_id);
- message->answer_to->put_init(message, 10)->detach(ChordMessage::destroy);
- break;
-
- case NOTIFY:
- // someone is telling me that he may be my new predecessor
- XBT_DEBUG("Receiving a 'Notify' request from %s", message->issuer_host_name.c_str());
- notify(message->request_id);
- delete message;
- break;
+ break;
+
+ case MessageType::NOTIFY:
+ // someone is telling me that he may be my new predecessor
+ XBT_DEBUG("Receiving a 'Notify' request from %s", message->issuer_host_name.c_str());
+ notify(message->request_id);
+ delete message;
+ break;
+
+ case MessageType::PREDECESSOR_LEAVING:
+ // my predecessor is about to quit
+ XBT_DEBUG("Receiving a 'Predecessor Leaving' message from %s", message->issuer_host_name.c_str());
+ // modify my predecessor
+ setPredecessor(message->request_id);
+ delete message;
+ /*TODO :
+ >> notify my new predecessor
+ >> send a notify_predecessors !!
+ */
+ break;
+
+ case MessageType::SUCCESSOR_LEAVING:
+ // my successor is about to quit
+ XBT_DEBUG("Receiving a 'Successor Leaving' message from %s", message->issuer_host_name.c_str());
+ // modify my successor FIXME : this should be implicit ?
+ setFinger(0, message->request_id);
+ delete message;
+ /* TODO
+ >> notify my new successor
+ >> update my table & predecessors table */
+ break;
+
+ case MessageType::PREDECESSOR_ALIVE:
+ XBT_DEBUG("Receiving a 'Predecessor Alive' request from %s", message->issuer_host_name.c_str());
+ message->type = MessageType::PREDECESSOR_ALIVE_ANSWER;
+ XBT_DEBUG("Sending back a 'Predecessor Alive Answer' to %s (mailbox %s)", message->issuer_host_name.c_str(),
+ message->answer_to->get_cname());
+ message->answer_to->put_init(message, 10)->detach(ChordMessage::destroy);
+ break;
- case PREDECESSOR_LEAVING:
- // my predecessor is about to quit
- XBT_DEBUG("Receiving a 'Predecessor Leaving' message from %s", message->issuer_host_name.c_str());
- // modify my predecessor
- setPredecessor(message->request_id);
- delete message;
- /*TODO :
- >> notify my new predecessor
- >> send a notify_predecessors !!
- */
- break;
-
- case SUCCESSOR_LEAVING:
- // my successor is about to quit
- XBT_DEBUG("Receiving a 'Successor Leaving' message from %s", message->issuer_host_name.c_str());
- // modify my successor FIXME : this should be implicit ?
- setFinger(0, message->request_id);
- delete message;
- /* TODO
- >> notify my new successor
- >> update my table & predecessors table */
- break;
-
- case PREDECESSOR_ALIVE:
- XBT_DEBUG("Receiving a 'Predecessor Alive' request from %s", message->issuer_host_name.c_str());
- message->type = PREDECESSOR_ALIVE_ANSWER;
- XBT_DEBUG("Sending back a 'Predecessor Alive Answer' to %s (mailbox %s)", message->issuer_host_name.c_str(),
- message->answer_to->get_cname());
- message->answer_to->put_init(message, 10)->detach(ChordMessage::destroy);
- break;
-
- default:
- XBT_DEBUG("Ignoring unexpected message: %d from %s", message->type, message->issuer_host_name.c_str());
- delete message;
+ default:
+ XBT_DEBUG("Ignoring unexpected message: %d from %s", static_cast<int>(message->type),
+ message->issuer_host_name.c_str());
+ delete message;
}
}
extern int timeout;
/* Types of tasks exchanged between nodes. */
-enum e_message_type_t {
+enum class MessageType {
FIND_SUCCESSOR,
FIND_SUCCESSOR_ANSWER,
GET_PREDECESSOR,
class ChordMessage {
public:
- e_message_type_t type; // type of message
+ MessageType type; // type of message
std::string issuer_host_name = simgrid::s4u::this_actor::get_host()->get_name(); // used for logging
int request_id = -1; // id (used by some types of messages)
int request_finger = 1; // finger parameter (used by some types of messages)
int answer_id = -1; // answer (used by some types of messages)
simgrid::s4u::Mailbox* answer_to = nullptr; // mailbox to send an answer to (if any)
- explicit ChordMessage(e_message_type_t type) : type(type) {}
+ explicit ChordMessage(MessageType type) : type(type) {}
static void destroy(void* message);
};
#include "s4u-dht-kademlia.hpp"
#include "simgrid/s4u.hpp"
+#include <memory>
#include <string>
namespace kademlia {
public:
unsigned int sender_id_ = 0; // Id of the guy who sent the task
unsigned int destination_id_ = 0; // Id we are trying to find, if needed.
- Answer* answer_ = nullptr; // Answer to the request made, if needed.
+ std::unique_ptr<Answer> answer_ = nullptr; // Answer to the request made, if needed.
simgrid::s4u::Mailbox* answer_to_ = nullptr; // mailbox to send the answer to (if not an answer).
std::string issuer_host_name_; // used for logging
- explicit Message(unsigned int sender_id, unsigned int destination_id, Answer* answer, simgrid::s4u::Mailbox* mailbox,
- const char* hostname)
+ explicit Message(unsigned int sender_id, unsigned int destination_id, std::unique_ptr<Answer> answer,
+ simgrid::s4u::Mailbox* mailbox, const char* hostname)
: sender_id_(sender_id)
, destination_id_(destination_id)
- , answer_(answer)
+ , answer_(std::move(answer))
, answer_to_(mailbox)
, issuer_host_name_(hostname)
{
static void destroy(void* message)
{
const auto* msg = static_cast<Message*>(message);
- delete msg->answer_;
delete msg;
}
*/
bool Node::join(unsigned int known_id)
{
- const Answer* node_list;
bool got_answer = false;
/* Add the guy we know to our routing table and ourselves. */
got_answer = true;
// retrieve the node list and ping them.
const auto* msg = static_cast<Message*>(received_msg);
- node_list = msg->answer_;
+ const Answer* node_list = msg->answer_.get();
if (node_list) {
for (auto const& contact : node_list->getNodes())
routingTableUpdate(contact.first);
} else {
handleFindNode(msg);
}
- delete msg->answer_;
delete msg;
receive_comm = nullptr;
} else
* @param node : our node
* @param destination_id : the id of the guy we are trying to find
*/
-Answer* Node::findClosest(unsigned int destination_id)
+std::unique_ptr<Answer> Node::findClosest(unsigned int destination_id)
{
- auto* answer = new Answer(destination_id);
+ auto answer = std::make_unique<Answer>(destination_id);
/* We find the corresponding bucket for the id */
const Bucket* bucket = table.findBucket(destination_id);
int bucket_id = bucket->getId();
unsigned int steps = 0;
/* First we build a list of who we already know */
- Answer* node_list = findClosest(id_to_find);
+ std::unique_ptr<Answer> node_list = findClosest(id_to_find);
xbt_assert((node_list != nullptr), "node_list incorrect");
XBT_DEBUG("Doing a FIND_NODE on %08x", id_to_find);
/* Ask the nodes on our list if they have information about the node we are trying to find */
do {
answers = 0;
- queries = sendFindNodeToBest(node_list);
+ queries = sendFindNodeToBest(node_list.get());
nodes_added = 0;
double timeout = simgrid::s4u::Engine::get_clock() + FIND_NODE_TIMEOUT;
steps++;
routingTableUpdate(contact.first);
answers++;
- nodes_added = node_list->merge(msg->answer_);
+ nodes_added = node_list->merge(msg->answer_.get());
XBT_DEBUG("Received an answer from %s (%s) with %zu nodes on it", msg->answer_to_->get_cname(),
msg->issuer_host_name_.c_str(), msg->answer_->getSize());
} else {
timeout += simgrid::s4u::Engine::get_clock() - time_beginreceive;
time_beginreceive = simgrid::s4u::Engine::get_clock();
}
- delete msg->answer_;
delete msg;
receive_comm = nullptr;
} else {
XBT_VERB("%08x not found in %u steps", id_to_find, steps);
}
}
- delete node_list;
return destination_found;
}
#include "routing_table.hpp"
#include "s4u-dht-kademlia.hpp"
+#include <memory>
+
namespace kademlia {
class Node {
void sendFindNode(unsigned int id, unsigned int destination) const;
unsigned int sendFindNodeToBest(const Answer* node_list) const;
void routingTableUpdate(unsigned int id);
- Answer* findClosest(unsigned int destination_id);
+ std::unique_ptr<Answer> findClosest(unsigned int destination_id);
bool findNode(unsigned int id_to_find, bool count_in_stats);
void randomLookup();
void handleFindNode(const Message* msg);
const auto* msg = static_cast<kademlia::Message*>(node.received_msg);
if (msg) {
node.handleFindNode(msg);
- delete msg->answer_;
delete msg;
node.receive_comm = nullptr;
} else
void* res = mailbox->get();
xbt_free(res);
} else {
- auto* data = new void*[flow_amount];
+ std::vector<void*> data(flow_amount);
// Start all comms in parallel, and wait for their completion in one shot
std::vector<simgrid::s4u::CommPtr> comms;
simgrid::s4u::Comm::wait_all(&comms);
for (int i = 0; i < flow_amount; i++)
xbt_free(data[i]);
- delete[] data;
}
XBT_INFO("receiver done.");
}
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("coordinator", simgrid::s4u::Host::by_name("Tremblay"), coordinator);
+ simgrid::s4u::Actor::create("coordinator", simgrid::s4u::Host::by_name("Tremblay"), coordinator)
+ ->set_kill_time(argc > 3 ? std::stod(argv[3]) : -1.0);
if (std::stod(argv[2]) == 0) {
simgrid::s4u::Actor::create("client", simgrid::s4u::Host::by_name("Boivin"), raw_client, 1);
simgrid::s4u::Actor::create("client", simgrid::s4u::Host::by_name("Fafard"), raw_client, 2);
xbt_replay_action_register("send", Replayer::send);
xbt_replay_action_register("recv", Replayer::recv);
+ std::ifstream ifs;
if (argv[3]) {
- simgrid::xbt::action_fs = new std::ifstream(argv[3], std::ifstream::in);
+ ifs.open(argv[3], std::ifstream::in);
+ simgrid::xbt::action_fs = &ifs;
}
e.run();
- if (argv[3]) {
- delete simgrid::xbt::action_fs;
- simgrid::xbt::action_fs = nullptr;
- }
+ simgrid::xbt::action_fs = nullptr;
XBT_INFO("Simulation time %g", e.get_clock());
((void)0)
class Replayer {
- static std::unordered_map<std::string, simgrid::s4u::File*> opened_files;
+ static std::unordered_map<std::string, simgrid::s4u::File> opened_files;
static void log_action(const simgrid::xbt::ReplayAction& action, double date)
{
static simgrid::s4u::File* get_file_descriptor(const std::string& file_name)
{
std::string full_name = simgrid::s4u::this_actor::get_name() + ":" + file_name;
- return opened_files.at(full_name);
+ return &opened_files.at(full_name);
}
public:
std::string full_name = simgrid::s4u::this_actor::get_name() + ":" + file_name;
ACT_DEBUG("Entering Open: %s (filename: %s)", NAME.c_str(), file_name.c_str());
- auto* file = new simgrid::s4u::File(file_name, nullptr);
-
- opened_files.insert({full_name, file});
+ opened_files.emplace(std::piecewise_construct, std::forward_as_tuple(full_name),
+ std::forward_as_tuple(file_name, nullptr));
log_action(action, simgrid::s4u::Engine::get_clock() - clock);
}
static void close(simgrid::xbt::ReplayAction& action)
{
std::string file_name = action[2];
+ std::string full_name = simgrid::s4u::this_actor::get_name() + ":" + file_name;
double clock = simgrid::s4u::Engine::get_clock();
- const simgrid::s4u::File* file = get_file_descriptor(file_name);
-
ACT_DEBUG("Entering Close: %s (filename: %s)", NAME.c_str(), file_name.c_str());
- delete file;
+ XBT_ATTRIB_UNUSED auto count = opened_files.erase(full_name);
+ xbt_assert(count == 1, "File not found in opened files: %s", full_name.c_str());
log_action(action, simgrid::s4u::Engine::get_clock() - clock);
}
};
-std::unordered_map<std::string, simgrid::s4u::File*> Replayer::opened_files;
+std::unordered_map<std::string, simgrid::s4u::File> Replayer::opened_files;
int main(int argc, char* argv[])
{
xbt_replay_action_register("read", Replayer::read);
xbt_replay_action_register("close", Replayer::close);
+ std::ifstream ifs;
if (argv[3]) {
- simgrid::xbt::action_fs = new std::ifstream(argv[3], std::ifstream::in);
+ ifs.open(argv[3], std::ifstream::in);
+ simgrid::xbt::action_fs = &ifs;
}
e.run();
- if (argv[3]) {
- delete simgrid::xbt::action_fs;
- simgrid::xbt::action_fs = nullptr;
- }
+ simgrid::xbt::action_fs = nullptr;
XBT_INFO("Simulation time %g", e.get_clock());
--- /dev/null
+/* Copyright (c) 2010-2020. 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 source code simply loads the platform. This is only useful to play
+ * with the tracing module. See the tesh file to see how to generate the
+ * traces.
+ */
+
+#include "simgrid/instr.h"
+#include "simgrid/s4u.hpp"
+
+struct Task {
+ std::string name;
+ std::string category;
+ double flops;
+ uint64_t bytes;
+};
+
+static void master()
+{
+ auto mbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+ for (int i = 0; i < 10; i++) {
+ Task task;
+ if (i % 2)
+ task = {"task_compute", "compute", 10000000, 0};
+ else if (i % 3)
+ task = {"task_request", "request", 10, 10};
+ else
+ task = {"task_data", "data", 10, 10000000};
+ mbox->put(new Task(task), task.bytes);
+ }
+ Task finalize = {"finalize", "finalize", 0, 1000};
+ mbox->put(new Task(finalize), finalize.bytes);
+}
+
+static void worker()
+{
+ auto mbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+ while (true) {
+ const auto* task = static_cast<Task*>(mbox->get());
+ if (task->name == "finalize") {
+ delete task;
+ break;
+ }
+ // creating task and setting its category
+ simgrid::s4u::this_actor::exec_init(task->flops)
+ ->set_name(task->name)
+ ->set_tracing_category(task->category)
+ ->wait();
+ delete task;
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
+
+ e.load_platform(argv[1]);
+
+ // declaring user categories with RGB colors
+ TRACE_category_with_color("compute", "1 0 0"); // red
+ TRACE_category_with_color("request", "0 1 0"); // green
+ TRACE_category_with_color("data", "0 0 1"); // blue
+ TRACE_category_with_color("finalize", "0 0 0"); // black
+
+ simgrid::s4u::Actor::create("master", simgrid::s4u::Host::by_name("Tremblay"), master);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Fafard"), worker);
+
+ e.run();
+ return 0;
+}
p Tracing multiple categories master/worker application
-$ ${bindir:=.}/trace-categories --cfg=tracing:yes --cfg=tracing/filename:categories.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${platfdir}/small_platform.xml
+$ ${bindir:=.}/s4u-trace-categories --cfg=tracing:yes --cfg=tracing/filename:categories.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${platfdir}/small_platform.xml
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'categories.trace'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
+
+$ rm -f categories.trace
--- /dev/null
+/* Copyright (c) 2010-2020. 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 source code simply loads the platform. This is only useful to play
+ * with the tracing module. See the tesh file to see how to generate the
+ * traces.
+ */
+
+#include "simgrid/instr.h"
+#include "simgrid/s4u.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+
+static void trace_fun()
+{
+ const char* hostname = simgrid::s4u::this_actor::get_host()->get_cname();
+
+ // the hostname has an empty HDD with a capacity of 100000 (bytes)
+ TRACE_host_variable_set(hostname, "HDD_capacity", 100000);
+ TRACE_host_variable_set(hostname, "HDD_utilization", 0);
+
+ for (int i = 0; i < 10; i++) {
+ // create and execute a task just to make the simulated time advance
+ simgrid::s4u::this_actor::execute(1e4);
+
+ // ADD: after the execution of this task, the HDD utilization increases by 100 (bytes)
+ TRACE_host_variable_add(hostname, "HDD_utilization", 100);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ // create and execute a task just to make the simulated time advance
+ simgrid::s4u::this_actor::execute(1e4);
+
+ // SUB: after the execution of this task, the HDD utilization decreases by 100 (bytes)
+ TRACE_host_variable_sub(hostname, "HDD_utilization", 100);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
+
+ e.load_platform(argv[1]);
+
+ // declaring user variables
+ TRACE_host_variable_declare("HDD_capacity");
+ TRACE_host_variable_declare("HDD_utilization");
+
+ simgrid::s4u::Actor::create("master", simgrid::s4u::Host::by_name("Tremblay"), trace_fun);
+
+ e.run();
+
+ // get user declared variables
+ xbt_dynar_t host_variables = TRACE_get_host_variables();
+ if (host_variables) {
+ XBT_INFO("Declared host variables:");
+ unsigned int cursor;
+ char* variable;
+ xbt_dynar_foreach (host_variables, cursor, variable) {
+ XBT_INFO("%s", variable);
+ }
+ xbt_dynar_free(&host_variables);
+ }
+ xbt_dynar_t link_variables = TRACE_get_link_variables();
+ if (link_variables) {
+ xbt_assert(xbt_dynar_is_empty(link_variables), "Should not have any declared link variable!");
+ xbt_dynar_free(&link_variables);
+ }
+
+ return 0;
+}
--- /dev/null
+#!/usr/bin/env tesh
+
+p Tracing user variables for hosts
+$ ${bindir:=.}/s4u-trace-host-user-variables --cfg=tracing:yes --cfg=tracing/platform:yes ${platfdir}/small_platform.xml
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/platform' to 'yes'
+> [0.002039] [s4u_test/INFO] Declared host variables:
+> [0.002039] [s4u_test/INFO] HDD_capacity
+> [0.002039] [s4u_test/INFO] HDD_utilization
+
+$ rm -f simgrid.trace
+
+p Not tracing user variables
+$ ${bindir:=.}/s4u-trace-host-user-variables ${platfdir}/small_platform.xml
--- /dev/null
+/* Copyright (c) 2010-2020. 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 source code simply loads the platform. This is only useful to play
+ * with the tracing module. See the tesh file to see how to generate the
+ * traces.
+ */
+
+#include "simgrid/instr.h"
+#include "simgrid/s4u.hpp"
+
+static void trace_fun()
+{
+ // set initial values for the link user variables this example only shows for links identified by "6" and "3" in the
+ // platform file
+
+ // Set the Link_Capacity variable
+ TRACE_link_variable_set("6", "Link_Capacity", 12.34);
+ TRACE_link_variable_set("3", "Link_Capacity", 56.78);
+
+ // Set the Link_Utilization variable
+ TRACE_link_variable_set("3", "Link_Utilization", 1.2);
+ TRACE_link_variable_set("6", "Link_Utilization", 3.4);
+
+ // run the simulation, update my variables accordingly
+ for (int i = 0; i < 10; i++) {
+ simgrid::s4u::this_actor::execute(1e6);
+
+ // Add to link user variables
+ TRACE_link_variable_add("3", "Link_Utilization", 5.6);
+ TRACE_link_variable_add("6", "Link_Utilization", 7.8);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ simgrid::s4u::this_actor::execute(1e6);
+
+ // Subtract from link user variables
+ TRACE_link_variable_sub("3", "Link_Utilization", 3.4);
+ TRACE_link_variable_sub("6", "Link_Utilization", 5.6);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
+
+ e.load_platform(argv[1]);
+
+ // declaring link user variables (one without, another with an RGB color)
+ TRACE_link_variable_declare("Link_Capacity");
+ TRACE_link_variable_declare_with_color("Link_Utilization", "0.9 0.1 0.1");
+
+ simgrid::s4u::Actor::create("master", simgrid::s4u::Host::by_name("Tremblay"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Tremblay"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Jupiter"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Fafard"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Ginette"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Bourassa"), trace_fun);
+
+ e.run();
+ return 0;
+}
#!/usr/bin/env tesh
p Trace user variables associated to links of the platform file
-$ ${bindir:=.}/trace-link-user-variables --cfg=tracing:yes --cfg=tracing/platform:yes ${platfdir}/small_platform.xml ${srcdir:=.}/../../../c/app-masterworker/app-masterworker_d.xml
+$ ${bindir:=.}/s4u-trace-link-user-variables --cfg=tracing:yes --cfg=tracing/platform:yes ${platfdir}/small_platform.xml
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/platform' to 'yes'
--- /dev/null
+/* Copyright (c) 2010-2020. 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/instr.h>
+#include <simgrid/s4u.hpp>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_trace_masterworker, "Messages specific for this example");
+
+struct Task {
+ std::string name;
+ std::string category;
+ double flops;
+};
+
+static void master(std::vector<std::string> args)
+{
+ xbt_assert(args.size() > 4, "The master function expects at least 3 arguments");
+
+ long tasks_count = std::stol(args[1]);
+ double compute_cost = std::stod(args[2]);
+ long communication_cost = std::stol(args[3]);
+ size_t workers_count = args.size() - 4;
+ const char* my_hostname = simgrid::s4u::this_actor::get_host()->get_cname();
+ auto mailbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+
+ XBT_DEBUG("Got %zu workers and %ld tasks to process", workers_count, tasks_count);
+
+ // setting the variable "is_master" (previously declared) to value 1
+ TRACE_host_variable_set(my_hostname, "is_master", 1);
+
+ TRACE_mark("msmark", "start_send_tasks");
+ for (int i = 0; i < tasks_count; i++) {
+ // setting the variable "task_creation" to value i
+ TRACE_host_variable_set(my_hostname, "task_creation", i);
+
+ // setting the category of task to "compute"
+ Task task = {"task", "compute", compute_cost};
+ mailbox->put(new Task(task), communication_cost);
+ }
+ TRACE_mark("msmark", "finish_send_tasks");
+
+ XBT_DEBUG("All tasks have been dispatched. Request all workers to stop.");
+ for (unsigned int i = 0; i < workers_count; i++) {
+ Task finalize = {"finalize", "finalize", 0};
+ mailbox->put(new Task(finalize), 0);
+ }
+}
+
+static void worker(std::vector<std::string> args)
+{
+ xbt_assert(args.size() == 1, "The worker expects no argument");
+
+ const char* my_hostname = simgrid::s4u::this_actor::get_host()->get_cname();
+ auto mailbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+
+ TRACE_host_variable_set(my_hostname, "is_worker", 1);
+ TRACE_host_variable_set(my_hostname, "task_computation", 0);
+
+ while (true) {
+ const auto* task = static_cast<Task*>(mailbox->get());
+ if (task->name == "finalize") {
+ delete task;
+ break;
+ }
+ // adding the task's cost to the variable "task_computation"
+ TRACE_host_variable_add(my_hostname, "task_computation", task->flops);
+ simgrid::s4u::this_actor::exec_init(task->flops)
+ ->set_name(task->name)
+ ->set_tracing_category(task->category)
+ ->wait();
+ delete task;
+ }
+
+ XBT_DEBUG("Exiting now.");
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ xbt_assert(argc > 2, "Usage: %s platform_file deployment_file\n", argv[0]);
+
+ e.load_platform(argv[1]);
+
+ // declaring user variables
+ TRACE_host_variable_declare("is_worker");
+ TRACE_host_variable_declare("is_master");
+ TRACE_host_variable_declare("task_creation");
+ TRACE_host_variable_declare("task_computation");
+
+ // declaring user markers and values
+ TRACE_declare_mark("msmark");
+ TRACE_declare_mark_value("msmark", "start_send_tasks");
+ TRACE_declare_mark_value("msmark", "finish_send_tasks");
+
+ // declaring user categories with RGB colors (values from 0 to 1)
+ TRACE_category_with_color("compute", "1 0 0"); // compute is red
+ TRACE_category_with_color("finalize", "0 1 0"); // finalize is green
+ // categories without user-defined colors receive random colors generated by the tracing system
+ TRACE_category("request");
+ TRACE_category_with_color("report", nullptr);
+
+ e.register_function("master", &master);
+ e.register_function("worker", &worker);
+ e.load_deployment(argv[2]);
+
+ e.run();
+
+ XBT_DEBUG("Simulation is over");
+
+ unsigned int cursor;
+ xbt_dynar_t categories = TRACE_get_categories();
+ if (categories) {
+ XBT_INFO("Declared tracing categories:");
+ char* category;
+ xbt_dynar_foreach (categories, cursor, category) {
+ XBT_INFO("%s", category);
+ }
+ xbt_dynar_free(&categories);
+ }
+
+ xbt_dynar_t marks = TRACE_get_marks();
+ if (marks) {
+ XBT_INFO("Declared marks:");
+ char* mark;
+ xbt_dynar_foreach (marks, cursor, mark) {
+ XBT_INFO("%s", mark);
+ }
+ xbt_dynar_free(&marks);
+ }
+
+ return 0;
+}
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-trace-masterworkers --cfg=tracing:yes --cfg=tracing/filename:trace-masterworker.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${platfdir}/small_platform.xml ${srcdir:=.}/../app-masterworkers/s4u-app-masterworkers_d.xml
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
+> [4.214821] [s4u_trace_masterworker/INFO] Declared tracing categories:
+> [4.214821] [s4u_trace_masterworker/INFO] compute
+> [4.214821] [s4u_trace_masterworker/INFO] finalize
+> [4.214821] [s4u_trace_masterworker/INFO] report
+> [4.214821] [s4u_trace_masterworker/INFO] request
+> [4.214821] [s4u_trace_masterworker/INFO] Declared marks:
+> [4.214821] [s4u_trace_masterworker/INFO] msmark
+
+p Tracing master/worker application with xml config
+$ ${bindir:=.}/s4u-trace-masterworkers ${platfdir}/config_tracing.xml ${srcdir:=.}/../app-masterworkers/s4u-app-masterworkers_d.xml
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
+> [4.214821] [s4u_trace_masterworker/INFO] Declared tracing categories:
+> [4.214821] [s4u_trace_masterworker/INFO] compute
+> [4.214821] [s4u_trace_masterworker/INFO] finalize
+> [4.214821] [s4u_trace_masterworker/INFO] report
+> [4.214821] [s4u_trace_masterworker/INFO] request
+> [4.214821] [s4u_trace_masterworker/INFO] Declared marks:
+> [4.214821] [s4u_trace_masterworker/INFO] msmark
+
+p Not tracing master/worker application
+$ ${bindir:=.}/s4u-trace-masterworkers ${platfdir}/small_platform.xml ${srcdir:=.}/../app-masterworkers/s4u-app-masterworkers_d.xml
+
+p Testing tracing by process
+$ ${bindir:=.}/s4u-trace-masterworkers --cfg=tracing:yes --cfg=tracing/actor:yes --cfg=tracing/filename:trace-masterworker.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${platfdir}/small_platform.xml ${srcdir:=.}/../app-masterworkers/s4u-app-masterworkers_d.xml
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/actor' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
+> [4.214821] [s4u_trace_masterworker/INFO] Declared tracing categories:
+> [4.214821] [s4u_trace_masterworker/INFO] compute
+> [4.214821] [s4u_trace_masterworker/INFO] finalize
+> [4.214821] [s4u_trace_masterworker/INFO] report
+> [4.214821] [s4u_trace_masterworker/INFO] request
+> [4.214821] [s4u_trace_masterworker/INFO] Declared marks:
+> [4.214821] [s4u_trace_masterworker/INFO] msmark
+
+$ rm -f trace-masterworker.trace
--- /dev/null
+/* Copyright (c) 2010-2020. 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 source code simply loads the platform. This is only useful to play
+ * with the tracing module. See the tesh file to see how to generate the
+ * traces.
+ */
+
+#include "simgrid/instr.h"
+#include "simgrid/s4u.hpp"
+#include <memory>
+
+/* The guy we will move from host to host. It move alone and then is moved by policeman back */
+static void emigrant()
+{
+ auto mailbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+
+ simgrid::s4u::this_actor::sleep_for(2);
+
+ while (true) { // I am an eternal emigrant
+ auto destination = std::unique_ptr<std::string>(static_cast<std::string*>(mailbox->get()));
+ if (destination->empty())
+ break; // there is no destination, die
+ simgrid::s4u::this_actor::set_host(simgrid::s4u::Host::by_name(*destination));
+ simgrid::s4u::this_actor::sleep_for(2); // I am tired, have to sleep for 2 seconds
+ }
+}
+
+static void policeman()
+{
+ // I am the master of emigrant process,
+ // I tell it where it must emigrate to.
+ auto destinations = {"Tremblay", "Jupiter", "Fafard", "Ginette", "Bourassa", "Fafard", "Tremblay", "Ginette", ""};
+ auto mailbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+
+ for (auto const& destination : destinations) {
+ mailbox->put_init(new std::string(destination), 0)->set_tracing_category("migration_order")->wait();
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
+
+ e.load_platform(argv[1]);
+
+ TRACE_category("migration_order");
+
+ simgrid::s4u::Actor::create("emigrant", simgrid::s4u::Host::by_name("Fafard"), emigrant);
+ simgrid::s4u::Actor::create("policeman", simgrid::s4u::Host::by_name("Tremblay"), policeman);
+
+ e.run();
+ return 0;
+}
#!/usr/bin/env tesh
p Tracing processes
-$ ${bindir:=.}/trace-process-migration --cfg=tracing:yes --cfg=tracing/filename:procmig.trace --cfg=tracing/msg/process:yes ${platfdir}/small_platform.xml
+$ ${bindir:=.}/s4u-trace-process-migration --cfg=tracing:yes --cfg=tracing/filename:procmig.trace --cfg=tracing/actor:yes ${platfdir}/small_platform.xml
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'procmig.trace'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/msg/process' to 'yes'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/actor' to 'yes'
$ tail -n +3 procmig.trace
> %EventDef PajeDefineContainerType 0
> 4 13 0 6 6 ACTOR_LINK
> 6 0.000000 33 6 1 "policeman-2"
> 12 0.000000 7 32 9
-> 15 0.000000 13 0 SR 33 p0
> 12 0.000000 7 33 11
> 13 2.000000 7 32
> 12 2.000000 7 32 10
> 13 2.025708 7 33
-> 15 2.025708 13 0 SR 33 p1
> 12 2.025708 7 33 11
-> 16 2.025708 13 0 SR 32 p0
+> 13 2.025708 7 32
> 15 2.025708 13 0 M 32 0
> 7 2.025708 6 32
> 6 2.025708 34 6 1 "emigrant-1"
> 13 4.025708 7 34
> 12 4.025708 7 34 10
> 13 4.025903 7 33
-> 15 4.025903 13 0 SR 33 p2
> 12 4.025903 7 33 11
-> 16 4.025903 13 0 SR 34 p1
+> 13 4.025903 7 34
> 15 4.025903 13 0 M 34 1
> 7 4.025903 6 34
> 6 4.025903 35 6 2 "emigrant-1"
> 13 6.025903 7 35
> 12 6.025903 7 35 10
> 13 6.044918 7 33
-> 15 6.044918 13 0 SR 33 p3
> 12 6.044918 7 33 11
-> 16 6.044918 13 0 SR 35 p2
+> 13 6.044918 7 35
> 15 6.044918 13 0 M 35 2
> 7 6.044918 6 35
> 6 6.044918 36 6 3 "emigrant-1"
> 13 8.044918 7 36
> 12 8.044918 7 36 10
> 13 8.070626 7 33
-> 15 8.070626 13 0 SR 33 p4
> 12 8.070626 7 33 11
-> 16 8.070626 13 0 SR 36 p3
+> 13 8.070626 7 36
> 15 8.070626 13 0 M 36 3
> 7 8.070626 6 36
> 6 8.070626 37 6 4 "emigrant-1"
> 13 10.070626 7 37
> 12 10.070626 7 37 10
> 13 10.087178 7 33
-> 15 10.087178 13 0 SR 33 p5
> 12 10.087178 7 33 11
-> 16 10.087178 13 0 SR 37 p4
+> 13 10.087178 7 37
> 15 10.087178 13 0 M 37 4
> 7 10.087178 6 37
> 6 10.087178 38 6 5 "emigrant-1"
> 13 12.087178 7 38
> 12 12.087178 7 38 10
> 13 12.112617 7 33
-> 15 12.112617 13 0 SR 33 p6
> 12 12.112617 7 33 11
-> 16 12.112617 13 0 SR 38 p5
+> 13 12.112617 7 38
> 15 12.112617 13 0 M 38 5
> 7 12.112617 6 38
> 6 12.112617 39 6 3 "emigrant-1"
> 13 14.112617 7 39
> 12 14.112617 7 39 10
> 13 14.138325 7 33
-> 15 14.138325 13 0 SR 33 p7
> 12 14.138325 7 33 11
-> 16 14.138325 13 0 SR 39 p6
+> 13 14.138325 7 39
> 15 14.138325 13 0 M 39 6
> 7 14.138325 6 39
> 6 14.138325 40 6 1 "emigrant-1"
> 13 16.138325 7 40
> 12 16.138325 7 40 10
> 13 16.138521 7 33
-> 15 16.138521 13 0 SR 33 p8
> 12 16.138521 7 33 11
-> 16 16.138521 13 0 SR 40 p7
+> 13 16.138521 7 40
> 15 16.138521 13 0 M 40 7
> 7 16.138521 6 40
> 6 16.138521 41 6 4 "emigrant-1"
> 13 18.138521 7 41
> 12 18.138521 7 41 10
> 13 18.155073 7 33
-> 16 18.155073 13 0 SR 41 p8
+> 13 18.155073 7 41
> 7 18.155073 6 33
> 7 18.155073 6 41
> 7 18.155073 2 16
> 7 18.155073 1 1
> 7 18.155073 2 31
-$ rm -rf procmig.trace
+$ rm -f procmig.trace
--- /dev/null
+/* Copyright (c) 2010-2020. 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 source code simply loads the platform. This is only useful to play
+ * with the tracing module. See the tesh file to see how to generate the
+ * traces.
+ */
+
+#include "simgrid/instr.h"
+#include "simgrid/s4u.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+
+static void trace_fun()
+{
+ // Set initial values for the link user variables
+ // This example uses source and destination where source and destination are the name of hosts in the platform file.
+ // The functions will set/change the value of the variable for all links in the route between source and destination.
+
+ // Set the Link_Capacity variable
+ TRACE_link_srcdst_variable_set("Tremblay", "Bourassa", "Link_Capacity", 12.34);
+ TRACE_link_srcdst_variable_set("Fafard", "Ginette", "Link_Capacity", 56.78);
+
+ // Set the Link_Utilization variable
+ TRACE_link_srcdst_variable_set("Tremblay", "Bourassa", "Link_Utilization", 1.2);
+ TRACE_link_srcdst_variable_set("Fafard", "Ginette", "Link_Utilization", 3.4);
+
+ // run the simulation, update my variables accordingly
+ for (int i = 0; i < 10; i++) {
+ simgrid::s4u::this_actor::execute(1e6);
+
+ // Add to link user variables
+ TRACE_link_srcdst_variable_add("Tremblay", "Bourassa", "Link_Utilization", 5.6);
+ TRACE_link_srcdst_variable_add("Fafard", "Ginette", "Link_Utilization", 7.8);
+ }
+
+ for (int i = 0; i < 10; i++) {
+ simgrid::s4u::this_actor::execute(1e6);
+
+ // Subtract from link user variables
+ TRACE_link_srcdst_variable_sub("Tremblay", "Bourassa", "Link_Utilization", 3.4);
+ TRACE_link_srcdst_variable_sub("Fafard", "Ginette", "Link_Utilization", 5.6);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
+
+ e.load_platform(argv[1]);
+
+ // declaring link user variables (one without, another with an RGB color)
+ TRACE_link_variable_declare("Link_Capacity");
+ TRACE_link_variable_declare_with_color("Link_Utilization", "0.9 0.1 0.1");
+
+ simgrid::s4u::Actor::create("master", simgrid::s4u::Host::by_name("Tremblay"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Tremblay"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Jupiter"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Fafard"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Ginette"), trace_fun);
+ simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Bourassa"), trace_fun);
+
+ e.run();
+ return 0;
+}
#!/usr/bin/env tesh
p Trace user variables associated to links of the platform file
-$ ${bindir:=.}/trace-route-user-variables --cfg=tracing:yes --cfg=tracing/platform:yes ${platfdir}/small_platform.xml
+$ ${bindir:=.}/s4u-trace-route-user-variables --cfg=tracing:yes --cfg=tracing/platform:yes ${platfdir}/small_platform.xml
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/platform' to 'yes'
int main(int argc, char* argv[])
{
MPI_Init(&argc, &argv);
+ // useless alocations for testing and coverage
void* pointer = malloc(100 * sizeof(int));
+ void* ptmp;
+ if ((ptmp = realloc(pointer, 50 * sizeof(int))) != nullptr)
+ pointer = ptmp;
+ if ((ptmp = realloc(pointer, 200 * sizeof(int))) != nullptr)
+ pointer = ptmp;
free(pointer);
- pointer = malloc(100 * sizeof(int));
+ pointer = calloc(100, sizeof(int));
int rank;
int err = MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* Get id of this process */
if (err != MPI_SUCCESS) {
-p Test if the load balancing code gets traced correctly
+p Test if the AMPI code gets traced correctly
$ rm -rf ${bindir:=.}/smpi_trace.trace ${bindir:=.}/smpi_trace.trace_files
for (i = 0; i < pstates; i++) {
sg_host_set_pstate(sg_host_self(), i);
- fprintf(stderr, "[%.6f] [rank %d] Current pstate: %d; Current power: %.0f\n",
- MPI_Wtime(), rank, i, sg_host_speed(sg_host_self()));
+ fprintf(stderr, "[%.6f] [rank %d] Current pstate: %d; Current power: %.0f\n", MPI_Wtime(), rank, i,
+ sg_host_get_speed(sg_host_self()));
SMPI_SAMPLE_FLOPS(1e9) {
/* imagine here some code running for 1e9 flops... */
#include <algorithm>
#include <fstream>
+#include <memory>
#include <sstream>
#include <stdexcept>
#include <vector>
static std::vector<simgrid::s4u::Host*> hosts;
static int noise_between_jobs;
-static bool job_comparator(const Job* j1, const Job* j2)
-{
- if (j1->starting_time == j2->starting_time)
- return j1->smpi_app_name < j2->smpi_app_name;
- return j1->starting_time < j2->starting_time;
-}
-
static void smpi_replay_process(Job* job, simgrid::s4u::BarrierPtr barrier, int rank)
{
XBT_INFO("Replaying rank %d of job %d (smpi_app '%s')", rank, job->unique_job_number, job->smpi_app_name.c_str());
}
// Sleeps for a given amount of time
-static int sleeper_process(const int* param)
+static int sleeper_process(int param)
{
- XBT_DEBUG("Sleeping for %d seconds", *param);
- simgrid::s4u::this_actor::sleep_for(*param);
-
- delete param;
-
+ XBT_DEBUG("Sleeping for %d seconds", param);
+ simgrid::s4u::this_actor::sleep_for(param);
return 0;
}
static void pop_some_processes(int nb_processes, simgrid::s4u::Host* host)
{
for (int i = 0; i < nb_processes; ++i) {
- auto* param = new int(i + 1);
+ int param = i + 1;
simgrid::s4u::Actor::create("meh", host, sleeper_process, param);
}
}
}
// Executes a workload of SMPI processes
-static int workload_executor_process(const std::vector<Job*>* workload)
+static int workload_executor_process(const std::vector<std::unique_ptr<Job>>* workload)
{
- for (Job* job : *workload) {
+ for (auto const& job : *workload) {
// Let's wait until the job's waiting time if needed
double curr_time = simgrid::s4u::Engine::get_clock();
if (job->starting_time > curr_time) {
// Let's finally run the job executor
char* str_pname = bprintf("job_%04d", job->unique_job_number);
XBT_INFO("Launching the job executor of job %d (app '%s')", job->unique_job_number, job->smpi_app_name.c_str());
- simgrid::s4u::Actor::create(str_pname, hosts[job->allocation[0]], job_executor_process, job);
+ simgrid::s4u::Actor::create(str_pname, hosts[job->allocation[0]], job_executor_process, job.get());
xbt_free(str_pname);
}
}
// Reads jobs from a workload file and returns them
-static std::vector<Job*> all_jobs(const std::string& workload_file)
+static std::vector<std::unique_ptr<Job>> all_jobs(const std::string& workload_file)
{
std::ifstream f(workload_file);
xbt_assert(f.is_open(), "Cannot open file '%s'.", workload_file.c_str());
- std::vector<Job*> jobs;
+ std::vector<std::unique_ptr<Job>> jobs;
simgrid::xbt::Path path(workload_file);
std::string dir = path.get_dir_name();
std::istringstream is(line);
if (is >> app_name >> filename_unprefixed >> app_size >> starting_time >> alloc) {
try {
- Job job;
- job.smpi_app_name = app_name;
- job.filename = dir + "/" + filename_unprefixed;
- job.app_size = app_size;
- job.starting_time = starting_time;
+ auto job = std::make_unique<Job>();
+ job->smpi_app_name = app_name;
+ job->filename = dir + "/" + filename_unprefixed;
+ job->app_size = app_size;
+ job->starting_time = starting_time;
std::vector<std::string> subparts;
boost::split(subparts, alloc, boost::is_any_of(","), boost::token_compress_on);
- if ((int)subparts.size() != job.app_size)
+ if ((int)subparts.size() != job->app_size)
throw std::invalid_argument("size/alloc inconsistency");
- job.allocation.resize(subparts.size());
+ job->allocation.resize(subparts.size());
for (unsigned int i = 0; i < subparts.size(); ++i)
- job.allocation[i] = stoi(subparts[i]);
+ job->allocation[i] = stoi(subparts[i]);
// Let's read the filename
- std::ifstream traces_file(job.filename);
+ std::ifstream traces_file(job->filename);
if (!traces_file.is_open())
- throw std::invalid_argument("Cannot open file " + job.filename);
+ throw std::invalid_argument("Cannot open file " + job->filename);
std::string traces_line;
while (std::getline(traces_file, traces_line)) {
boost::trim_right(traces_line);
- job.traces_filenames.push_back(dir + "/" + traces_line);
+ job->traces_filenames.push_back(dir + "/" + traces_line);
}
- if (static_cast<int>(job.traces_filenames.size()) < job.app_size)
+ if (static_cast<int>(job->traces_filenames.size()) < job->app_size)
throw std::invalid_argument("size/tracefiles inconsistency");
- job.traces_filenames.resize(job.app_size);
+ job->traces_filenames.resize(job->app_size);
XBT_INFO("Job read: app='%s', file='%s', size=%d, start=%d, "
"alloc='%s'",
- job.smpi_app_name.c_str(), filename_unprefixed.c_str(), job.app_size, job.starting_time,
+ job->smpi_app_name.c_str(), filename_unprefixed.c_str(), job->app_size, job->starting_time,
alloc.c_str());
- jobs.push_back(new Job(std::move(job)));
+ jobs.emplace_back(std::move(job));
} catch (const std::invalid_argument& e) {
xbt_die("Bad line '%s' of file '%s': %s.\n", line.c_str(), workload_file.c_str(), e.what());
}
// Jobs are sorted by ascending date, then by lexicographical order of their
// application names
- sort(jobs.begin(), jobs.end(), job_comparator);
-
+ sort(jobs.begin(), jobs.end(), [](auto const& j1, auto const& j2) {
+ if (j1->starting_time == j2->starting_time)
+ return j1->smpi_app_name < j2->smpi_app_name;
+ return j1->starting_time < j2->starting_time;
+ });
for (unsigned int i = 0; i < jobs.size(); ++i)
jobs[i]->unique_job_number = i;
xbt_assert(hosts.size() >= 4, "The given platform should contain at least 4 hosts (found %zu).", hosts.size());
// Let's retrieve all SMPI jobs
- std::vector<Job*> jobs = all_jobs(argv[2]);
+ std::vector<std::unique_ptr<Job>> jobs = all_jobs(argv[2]);
// Let's register them
- for (const Job* job : jobs)
+ for (auto const& job : jobs)
SMPI_app_instance_register(job->smpi_app_name.c_str(), nullptr, job->app_size);
SMPI_init();
SMPI_finalize();
- for (const Job* job : jobs)
- delete job;
-
return 0;
}
class XBT_PUBLIC ImpossibleError : public std::logic_error {
public:
- explicit ImpossibleError(const std::string& arg) : std::logic_error(arg) {}
+ using std::logic_error::logic_error;
~ImpossibleError() override;
};
class XBT_PUBLIC InitializationError : public std::logic_error {
public:
- explicit InitializationError(const std::string& arg) : std::logic_error(arg) {}
+ using std::logic_error::logic_error;
~InitializationError() override;
};
class XBT_PUBLIC UnimplementedError : public std::logic_error {
public:
- explicit UnimplementedError(const std::string& arg) : std::logic_error(arg) {}
+ using std::logic_error::logic_error;
~UnimplementedError() override;
};
/** Ancestor class of all SimGrid exception */
class Exception : public std::runtime_error {
public:
- Exception(simgrid::xbt::ThrowPoint&& throwpoint, std::string&& message)
- : std::runtime_error(std::move(message)), throwpoint_(std::move(throwpoint))
+ Exception(const simgrid::xbt::ThrowPoint& throwpoint, const std::string& message)
+ : std::runtime_error(message), throwpoint_(throwpoint)
{
}
Exception(const Exception&) = default;
/** Exception raised when a timeout elapsed */
class TimeoutException : public Exception {
public:
- TimeoutException(simgrid::xbt::ThrowPoint&& throwpoint, std::string&& message)
- : Exception(std::move(throwpoint), std::move(message))
- {
- }
- TimeoutException(const TimeoutException&) = default;
- TimeoutException(TimeoutException&&) noexcept = default;
+ using Exception::Exception;
~TimeoutException() override;
};
-XBT_ATTRIB_DEPRECATED_v328("Please use simgrid::TimeoutException") typedef TimeoutException TimeoutError;
+using TimeoutError XBT_ATTRIB_DEPRECATED_v328("Please use simgrid::TimeoutException") = TimeoutException;
/** Exception raised when a host fails */
class HostFailureException : public Exception {
public:
- HostFailureException(simgrid::xbt::ThrowPoint&& throwpoint, std::string&& message)
- : Exception(std::move(throwpoint), std::move(message))
- {
- }
- HostFailureException(const HostFailureException&) = default;
- HostFailureException(HostFailureException&&) noexcept = default;
+ using Exception::Exception;
~HostFailureException() override;
};
/** Exception raised when a communication fails because of the network or because of the remote host */
class NetworkFailureException : public Exception {
public:
- NetworkFailureException(simgrid::xbt::ThrowPoint&& throwpoint, std::string&& message)
- : Exception(std::move(throwpoint), std::move(message))
- {
- }
- NetworkFailureException(const NetworkFailureException&) = default;
- NetworkFailureException(NetworkFailureException&&) noexcept = default;
+ using Exception::Exception;
~NetworkFailureException() override;
};
/** Exception raised when a storage fails */
class StorageFailureException : public Exception {
public:
- StorageFailureException(simgrid::xbt::ThrowPoint&& throwpoint, std::string&& message)
- : Exception(std::move(throwpoint), std::move(message))
- {
- }
- StorageFailureException(const StorageFailureException&) = default;
- StorageFailureException(StorageFailureException&&) noexcept = default;
+ using Exception::Exception;
~StorageFailureException() override;
};
/** Exception raised when a VM fails */
class VmFailureException : public Exception {
public:
- VmFailureException(simgrid::xbt::ThrowPoint&& throwpoint, std::string&& message)
- : Exception(std::move(throwpoint), std::move(message))
- {
- }
- VmFailureException(const VmFailureException&) = default;
- VmFailureException(VmFailureException&&) noexcept = default;
+ using Exception::Exception;
~VmFailureException() override;
};
/** Exception raised when something got canceled before completion */
class CancelException : public Exception {
public:
- CancelException(simgrid::xbt::ThrowPoint&& throwpoint, std::string&& message)
- : Exception(std::move(throwpoint), std::move(message))
- {
- }
- CancelException(const CancelException&) = default;
- CancelException(CancelException&&) noexcept = default;
+ using Exception::Exception;
~CancelException() override;
};
/** Exception raised when something is going wrong during the simulation tracing */
class TracingError : public Exception {
public:
- TracingError(simgrid::xbt::ThrowPoint&& throwpoint, std::string&& message)
- : Exception(std::move(throwpoint), std::move(message))
- {
- }
- TracingError(const TracingError&) = default;
- TracingError(TracingError&&) noexcept = default;
+ using Exception::Exception;
~TracingError() override;
};
} // namespace simgrid
-XBT_ATTRIB_DEPRECATED_v328("Please use simgrid::Exception") typedef simgrid::Exception xbt_ex;
+using xbt_ex XBT_ATTRIB_DEPRECATED_v328("Please use simgrid::Exception") = simgrid::Exception;
#endif
#endif
XBT_PUBLIC void sg_actor_set_host(sg_actor_t actor, sg_host_t host);
-XBT_PUBLIC void sg_actor_join(sg_actor_t actor, double timeout);
+XBT_PUBLIC void sg_actor_join(const_sg_actor_t actor, double timeout);
XBT_PUBLIC void sg_actor_kill(sg_actor_t actor);
XBT_PUBLIC void sg_actor_kill_all();
XBT_PUBLIC void sg_actor_set_kill_time(sg_actor_t actor, double kill_time);
XBT_PUBLIC aid_t sg_actor_self_get_pid();
XBT_PUBLIC aid_t sg_actor_self_get_ppid();
XBT_PUBLIC const char* sg_actor_self_get_name();
-XBT_PUBLIC void* sg_actor_self_data();
-XBT_PUBLIC void sg_actor_self_data_set(void* data);
+XBT_PUBLIC void* sg_actor_self_get_data();
+XBT_PUBLIC void sg_actor_self_set_data(void* data);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_actor_self_get_data() instead") XBT_PUBLIC void* sg_actor_self_data();
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_actor_self_set_data() instead") XBT_PUBLIC
+ void sg_actor_self_data_set(void* data);
XBT_ATTRIB_DEPRECATED_v330("Please use sg_actor_execute() instead") XBT_PUBLIC void sg_actor_self_execute(double flops);
XBT_PUBLIC void sg_actor_execute(double flops);
XBT_PUBLIC void sg_actor_execute_with_priority(double flops, double priority);
void sg_actor_parallel_execute(int host_nb, sg_host_t* host_list, double* flops_amount, double* bytes_amount);
XBT_PUBLIC void sg_actor_ref(const_sg_actor_t actor);
XBT_PUBLIC void sg_actor_unref(const_sg_actor_t actor);
-XBT_PUBLIC void* sg_actor_data(const_sg_actor_t actor);
-XBT_PUBLIC void sg_actor_data_set(sg_actor_t actor, void* userdata);
+XBT_PUBLIC void* sg_actor_get_data(const_sg_actor_t actor);
+XBT_PUBLIC void sg_actor_set_data(sg_actor_t actor, void* userdata);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_actor_get_data() instead") XBT_PUBLIC
+ void* sg_actor_data(const_sg_actor_t actor);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_actor_set_data() instead") XBT_PUBLIC
+ void sg_actor_data_set(sg_actor_t actor, void* userdata);
XBT_PUBLIC sg_exec_t sg_actor_exec_init(double computation_amount);
XBT_PUBLIC sg_exec_t sg_actor_parallel_exec_init(int host_nb, const sg_host_t* host_list, double* flops_amount,
/* C interface */
SG_BEGIN_DECL
-XBT_PUBLIC const char* sg_disk_name(const_sg_disk_t disk);
+XBT_PUBLIC const char* sg_disk_get_name(const_sg_disk_t disk);
XBT_PUBLIC sg_host_t sg_disk_get_host(const_sg_disk_t disk);
XBT_PUBLIC double sg_disk_read_bandwidth(const_sg_disk_t disk);
XBT_PUBLIC double sg_disk_write_bandwidth(const_sg_disk_t disk);
XBT_PUBLIC sg_size_t sg_disk_write(sg_disk_t disk, sg_size_t size);
XBT_PUBLIC sg_size_t sg_disk_read(sg_disk_t disk, sg_size_t size);
-XBT_PUBLIC void* sg_disk_data(const_sg_disk_t disk);
-XBT_PUBLIC void sg_disk_data_set(sg_disk_t disk, void* data);
+XBT_PUBLIC void* sg_disk_get_data(const_sg_disk_t disk);
+XBT_PUBLIC void sg_disk_set_data(sg_disk_t disk, void* data);
SG_END_DECL
#endif /* INCLUDE_SIMGRID_DISK_H_ */
class EngineImpl;
namespace actor {
class ActorImpl;
-typedef boost::intrusive_ptr<ActorImpl> ActorImplPtr;
+using ActorImplPtr = boost::intrusive_ptr<ActorImpl>;
// What's executed as an actor code:
-typedef std::function<void()> ActorCode;
+using ActorCode = std::function<void()>;
// Create an ActorCode from the parameters parsed in the XML file (or elsewhere)
-typedef std::function<ActorCode(std::vector<std::string> args)> ActorCodeFactory;
+using ActorCodeFactory = std::function<ActorCode(std::vector<std::string> args)>;
} // namespace actor
namespace activity {
class ActivityImpl;
enum class State;
- typedef boost::intrusive_ptr<ActivityImpl> ActivityImplPtr;
+ using ActivityImplPtr = boost::intrusive_ptr<ActivityImpl>;
XBT_PUBLIC void intrusive_ptr_add_ref(ActivityImpl* activity);
XBT_PUBLIC void intrusive_ptr_release(ActivityImpl* activity);
class ConditionVariableImpl;
class CommImpl;
- typedef boost::intrusive_ptr<CommImpl> CommImplPtr;
+ using CommImplPtr = boost::intrusive_ptr<CommImpl>;
class ExecImpl;
- typedef boost::intrusive_ptr<ExecImpl> ExecImplPtr;
+ using ExecImplPtr = boost::intrusive_ptr<ExecImpl>;
class IoImpl;
- typedef boost::intrusive_ptr<IoImpl> IoImplPtr;
+ using IoImplPtr = boost::intrusive_ptr<IoImpl>;
class MutexImpl;
- typedef boost::intrusive_ptr<MutexImpl> MutexImplPtr;
+ using MutexImplPtr = boost::intrusive_ptr<MutexImpl>;
class RawImpl;
- typedef boost::intrusive_ptr<RawImpl> RawImplPtr;
+ using RawImplPtr = boost::intrusive_ptr<RawImpl>;
class SemaphoreImpl;
- typedef boost::intrusive_ptr<SemaphoreImpl> SemaphoreImplPtr;
+ using SemaphoreImplPtr = boost::intrusive_ptr<SemaphoreImpl>;
class SleepImpl;
- typedef boost::intrusive_ptr<SleepImpl> SleepImplPtr;
+ using SleepImplPtr = boost::intrusive_ptr<SleepImpl>;
class MailboxImpl;
}
} // namespace vm
} // namespace simgrid
-typedef simgrid::s4u::Actor s4u_Actor;
-typedef simgrid::s4u::Barrier s4u_Barrier;
-typedef simgrid::s4u::Comm s4u_Comm;
-typedef simgrid::s4u::Exec s4u_Exec;
-typedef simgrid::s4u::Host s4u_Host;
-typedef simgrid::s4u::Link s4u_Link;
-typedef simgrid::s4u::File s4u_File;
-typedef simgrid::s4u::ConditionVariable s4u_ConditionVariable;
-typedef simgrid::s4u::Mailbox s4u_Mailbox;
-typedef simgrid::s4u::Mutex s4u_Mutex;
-typedef simgrid::s4u::Semaphore s4u_Semaphore;
-typedef simgrid::s4u::Disk s4u_Disk;
-typedef simgrid::s4u::Storage s4u_Storage;
-typedef simgrid::s4u::NetZone s4u_NetZone;
-typedef simgrid::s4u::VirtualMachine s4u_VM;
-
-typedef simgrid::simix::Timer* smx_timer_t;
-typedef simgrid::kernel::actor::ActorImpl* smx_actor_t;
-typedef simgrid::kernel::activity::ActivityImpl* smx_activity_t;
-typedef simgrid::kernel::activity::ConditionVariableImpl* smx_cond_t;
-typedef simgrid::kernel::activity::MailboxImpl* smx_mailbox_t;
-typedef simgrid::kernel::activity::MutexImpl* smx_mutex_t;
-typedef simgrid::kernel::activity::SemaphoreImpl* smx_sem_t;
-XBT_ATTRIB_DEPRECATED_v330("Please use kernel::activity::State") typedef simgrid::kernel::activity::State e_smx_state_t;
+using s4u_Actor = simgrid::s4u::Actor;
+using s4u_Barrier = simgrid::s4u::Barrier;
+using s4u_Comm = simgrid::s4u::Comm;
+using s4u_Exec = simgrid::s4u::Exec;
+using s4u_Host = simgrid::s4u::Host;
+using s4u_Link = simgrid::s4u::Link;
+using s4u_File = simgrid::s4u::File;
+using s4u_ConditionVariable = simgrid::s4u::ConditionVariable;
+using s4u_Mailbox = simgrid::s4u::Mailbox;
+using s4u_Mutex = simgrid::s4u::Mutex;
+using s4u_Semaphore = simgrid::s4u::Semaphore;
+using s4u_Disk = simgrid::s4u::Disk;
+using s4u_Storage = simgrid::s4u::Storage;
+using s4u_NetZone = simgrid::s4u::NetZone;
+using s4u_VM = simgrid::s4u::VirtualMachine;
+
+using smx_timer_t = simgrid::simix::Timer*;
+using smx_actor_t = simgrid::kernel::actor::ActorImpl*;
+using smx_activity_t = simgrid::kernel::activity::ActivityImpl*;
+using smx_cond_t = simgrid::kernel::activity::ConditionVariableImpl*;
+using smx_mailbox_t = simgrid::kernel::activity::MailboxImpl*;
+using smx_mutex_t = simgrid::kernel::activity::MutexImpl*;
+using smx_sem_t = simgrid::kernel::activity::SemaphoreImpl*;
+using e_smx_state_t XBT_ATTRIB_DEPRECATED_v330("Please use kernel::activity::State") = simgrid::kernel::activity::State;
#else
typedef struct s4u_Actor s4u_Actor;
*
* This functions returns the user data associated to @a host if any.
*/
-XBT_PUBLIC void* sg_host_data(const_sg_host_t host);
-XBT_ATTRIB_DEPRECATED_v328("Please use sg_host_data()") XBT_PUBLIC void* sg_host_user(sg_host_t host);
+XBT_PUBLIC void* sg_host_get_data(const_sg_host_t host);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_host_get_data()") XBT_PUBLIC void* sg_host_data(const_sg_host_t host);
+XBT_ATTRIB_DEPRECATED_v328("Please use sg_host_get_data()") XBT_PUBLIC void* sg_host_user(sg_host_t host);
/** @brief Set the user data of a #sg_host_t.
*
* This functions attach @a data to @a host.
*/
-XBT_PUBLIC void sg_host_data_set(sg_host_t host, void* userdata);
-XBT_ATTRIB_DEPRECATED_v328("Please use sg_host_data_set()") XBT_PUBLIC
+XBT_PUBLIC void sg_host_set_data(sg_host_t host, void* userdata);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_host_set_data()") XBT_PUBLIC
+ void sg_host_data_set(sg_host_t host, void* userdata);
+XBT_ATTRIB_DEPRECATED_v328("Please use sg_host_set_data()") XBT_PUBLIC
void sg_host_user_set(sg_host_t host, void* userdata);
-XBT_ATTRIB_DEPRECATED_v328("Please use sg_host_data_set(h, NULL)") XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
+XBT_ATTRIB_DEPRECATED_v328("Please use sg_host_set_data(h, NULL)") XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
#endif
// ========= storage related functions ============
* @return a dynar containing all storages (name) attached to the host
*/
XBT_PUBLIC xbt_dynar_t sg_host_get_attached_storage_list(const_sg_host_t host);
-XBT_PUBLIC void sg_host_disks(const_sg_host_t host, unsigned int* disk_count, sg_disk_t** disks);
+XBT_PUBLIC void sg_host_get_disks(const_sg_host_t host, unsigned int* disk_count, sg_disk_t** disks);
// =========== user-level functions ===============
/** @brief Return the speed of the processor (in flop/s), regardless of the current load on the machine. */
-XBT_PUBLIC double sg_host_speed(const_sg_host_t host);
+XBT_PUBLIC double sg_host_get_speed(const_sg_host_t host);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_host_get_speed()") XBT_PUBLIC double sg_host_speed(const_sg_host_t host);
XBT_PUBLIC double sg_host_get_pstate_speed(const_sg_host_t host, int pstate_index);
XBT_PUBLIC double sg_host_get_available_speed(const_sg_host_t host);
/** @brief Returns the current computation load (in flops per second).
* @param host a host
*/
-XBT_PUBLIC double sg_host_load(const_sg_host_t host);
+XBT_PUBLIC double sg_host_get_load(const_sg_host_t host);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_host_get_load()") XBT_PUBLIC double sg_host_load(const_sg_host_t host);
/** @brief Return the location on which the current process is running. */
XBT_PUBLIC sg_host_t sg_host_self();
*/
XBT_PUBLIC void sg_host_set_property_value(sg_host_t host, const char* name, const char* value);
-XBT_PUBLIC void sg_host_route(const_sg_host_t from, const_sg_host_t to, xbt_dynar_t links);
-XBT_PUBLIC double sg_host_route_latency(const_sg_host_t from, const_sg_host_t to);
-XBT_PUBLIC double sg_host_route_bandwidth(const_sg_host_t from, const_sg_host_t to);
+XBT_PUBLIC void sg_host_get_route(const_sg_host_t from, const_sg_host_t to, xbt_dynar_t links);
+XBT_PUBLIC double sg_host_get_route_latency(const_sg_host_t from, const_sg_host_t to);
+XBT_PUBLIC double sg_host_get_route_bandwidth(const_sg_host_t from, const_sg_host_t to);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_host_get_route()") XBT_PUBLIC
+ void sg_host_route(const_sg_host_t from, const_sg_host_t to, xbt_dynar_t links);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_host_get_route_latency()") XBT_PUBLIC
+ double sg_host_route_latency(const_sg_host_t from, const_sg_host_t to);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_host_get_route_bandwidth()") XBT_PUBLIC
+ double sg_host_route_bandwidth(const_sg_host_t from, const_sg_host_t to);
XBT_PUBLIC void sg_host_sendto(sg_host_t from, sg_host_t to, double byte_amount);
#ifndef DOXYGEN
} // namespace jedule
} // namespace simgrid
-typedef simgrid::jedule::Jedule *jedule_t;
+using jedule_t = simgrid::jedule::Jedule*;
#endif /* JEDULE_HPP_ */
}
}
-typedef simgrid::jedule::Event* jed_event_t;
+using jed_event_t = simgrid::jedule::Event*;
#endif /* JEDULE_EVENTS_H_ */
} // namespace jedule
} // namespace simgrid
-typedef simgrid::jedule::Container * jed_container_t;
+using jed_container_t = simgrid::jedule::Container*;
void get_resource_selection_by_hosts(std::vector<simgrid::jedule::Subset>& subset_list,
const std::vector<sg_host_t>& host_list);
*/
template <class F> auto then_no_unwrap(F continuation) -> Future<decltype(continuation(std::move(*this)))>
{
- typedef decltype(continuation(std::move(*this))) R;
+ using R = decltype(continuation(std::move(*this)));
if (state_ == nullptr)
throw std::future_error(std::future_errc::no_state);
auto state = std::move(state_);
namespace kernel {
namespace resource {
-typedef std::pair<double, Action*> heap_element_type;
-typedef boost::heap::pairing_heap<heap_element_type, boost::heap::constant_time_size<false>, boost::heap::stable<true>,
- boost::heap::compare<simgrid::xbt::HeapComparator<heap_element_type>>>
- heap_type;
+using heap_element_type = std::pair<double, Action*>;
+using heap_type =
+ boost::heap::pairing_heap<heap_element_type, boost::heap::constant_time_size<false>, boost::heap::stable<true>,
+ boost::heap::compare<simgrid::xbt::HeapComparator<heap_element_type>>>;
-typedef std::pair<double, Action*> heap_element_type;
class XBT_PUBLIC ActionHeap : public heap_type {
friend Action;
/* Lazy update needs this Set hook to maintain a list of the tracked actions */
boost::intrusive::list_member_hook<> modified_set_hook_;
bool is_within_modified_set() const { return modified_set_hook_.is_linked(); }
- typedef boost::intrusive::list<
- Action, boost::intrusive::member_hook<Action, boost::intrusive::list_member_hook<>, &Action::modified_set_hook_>>
- ModifiedSet;
+ using ModifiedSet = boost::intrusive::list<
+ Action, boost::intrusive::member_hook<Action, boost::intrusive::list_member_hook<>, &Action::modified_set_hook_>>;
boost::intrusive::list_member_hook<> state_set_hook_;
- typedef boost::intrusive::list<
- Action, boost::intrusive::member_hook<Action, boost::intrusive::list_member_hook<>, &Action::state_set_hook_>>
- StateSet;
+ using StateSet = boost::intrusive::list<
+ Action, boost::intrusive::member_hook<Action, boost::intrusive::list_member_hook<>, &Action::state_set_hook_>>;
enum class State {
INITED, /**< Created, but not started yet */
return node_pos_with_loopback(id) + (has_limiter_ ? 1 : 0);
}
- void* loopback_ = nullptr;
kernel::resource::LinkImpl* backbone_ = nullptr;
NetPoint* router_ = nullptr;
bool has_limiter_ = false;
void generate_link(const std::string& id, int numlinks, resource::LinkImpl** linkup,
resource::LinkImpl** linkdown) const;
- simgrid::s4u::Link::SharingPolicy sharing_policy_;
+ simgrid::s4u::Link::SharingPolicy sharing_policy_ = simgrid::s4u::Link::SharingPolicy::SHARED;
double bw_ = 0;
double lat_ = 0;
private:
/* vars to compute the Floyd algorithm. */
- int* predecessor_table_ = nullptr;
- double* cost_table_ = nullptr;
- RouteCreationArgs** link_table_ = nullptr;
+ std::vector<int> predecessor_table_;
+ std::vector<double> cost_table_;
+ std::vector<RouteCreationArgs*> link_table_;
+
+ void init_tables(unsigned int table_size);
};
} // namespace routing
} // namespace kernel
std::vector<resource::LinkImpl*>& link_list, bool symmetrical) override;
private:
- RouteCreationArgs** routing_table_ = nullptr;
+ std::vector<RouteCreationArgs*> routing_table_;
};
} // namespace routing
} // namespace kernel
/* C interface */
SG_BEGIN_DECL
-XBT_PUBLIC const char* sg_link_name(const_sg_link_t link);
+XBT_PUBLIC const char* sg_link_get_name(const_sg_link_t link);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_link_get_name()") XBT_PUBLIC const char* sg_link_name(const_sg_link_t link);
XBT_PUBLIC sg_link_t sg_link_by_name(const char* name);
XBT_PUBLIC int sg_link_is_shared(const_sg_link_t link);
-XBT_PUBLIC double sg_link_bandwidth(const_sg_link_t link);
-XBT_PUBLIC void sg_link_bandwidth_set(sg_link_t link, double value);
-XBT_PUBLIC double sg_link_latency(const_sg_link_t link);
-XBT_PUBLIC void sg_link_latency_set(sg_link_t link, double value);
-XBT_PUBLIC void* sg_link_data(const_sg_link_t link);
-XBT_PUBLIC void sg_link_data_set(sg_link_t link, void* data);
+XBT_PUBLIC double sg_link_get_bandwidth(const_sg_link_t link);
+XBT_PUBLIC void sg_link_set_bandwidth(sg_link_t link, double value);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_link_get_bandwidth()") XBT_PUBLIC
+ double sg_link_bandwidth(const_sg_link_t link);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_link_set_bandwidth()") XBT_PUBLIC
+ void sg_link_bandwidth_set(sg_link_t link, double value);
+XBT_PUBLIC double sg_link_get_latency(const_sg_link_t link);
+XBT_PUBLIC void sg_link_set_latency(sg_link_t link, double value);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_link_get_latency()") XBT_PUBLIC double sg_link_latency(const_sg_link_t link);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_link_set_latency()") XBT_PUBLIC
+ void sg_link_latency_set(sg_link_t link, double value);
+XBT_PUBLIC void* sg_link_get_data(const_sg_link_t link);
+XBT_PUBLIC void sg_link_set_data(sg_link_t link, void* data);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_link_get_data()") XBT_PUBLIC void* sg_link_data(const_sg_link_t link);
+XBT_ATTRIB_DEPRECATED_v330("Please use sg_link_set_data()") XBT_PUBLIC
+ void sg_link_data_set(sg_link_t link, void* data);
XBT_PUBLIC int sg_link_count();
XBT_PUBLIC sg_link_t* sg_link_list();
SG_END_DECL
class Task;
}
}
-typedef simgrid::msg::Comm sg_msg_Comm;
-typedef simgrid::msg::Task sg_msg_Task;
+using sg_msg_Comm = simgrid::msg::Comm;
+using sg_msg_Task = simgrid::msg::Task;
#else
typedef struct msg_Comm sg_msg_Comm;
typedef struct msg_Task sg_msg_Task;
XBT_PUBLIC msg_vm_t MSG_vm_create_core(msg_host_t pm, const char* name);
XBT_PUBLIC msg_vm_t MSG_vm_create_multicore(msg_host_t pm, const char* name, int coreAmount);
-XBT_PUBLIC int MSG_vm_is_created(msg_vm_t vm);
-XBT_PUBLIC int MSG_vm_is_running(msg_vm_t vm);
-XBT_PUBLIC int MSG_vm_is_suspended(msg_vm_t vm);
+XBT_PUBLIC int MSG_vm_is_created(const_sg_vm_t vm);
+XBT_PUBLIC int MSG_vm_is_running(const_sg_vm_t vm);
+XBT_PUBLIC int MSG_vm_is_suspended(const_sg_vm_t vm);
XBT_PUBLIC const char* MSG_vm_get_name(const_sg_vm_t vm);
XBT_PUBLIC void MSG_vm_set_ramsize(msg_vm_t vm, size_t size);
* @param process the process to wait for
* @param timeout wait until the process is over, or the timeout occurs
*/
-XBT_PUBLIC void MSG_process_join(msg_process_t process, double timeout);
+XBT_PUBLIC void MSG_process_join(const_sg_actor_t process, double timeout);
/** @brief Kills a process */
XBT_PUBLIC void MSG_process_kill(msg_process_t process);
/** @brief Kill all running process */
XBT_PUBLIC void MSG_sem_acquire(msg_sem_t sem);
XBT_PUBLIC int MSG_sem_acquire_timeout(msg_sem_t sem, double timeout);
XBT_PUBLIC void MSG_sem_release(msg_sem_t sem);
-XBT_PUBLIC int MSG_sem_get_capacity(msg_sem_t sem);
+XBT_PUBLIC int MSG_sem_get_capacity(const_sg_sem_t sem);
XBT_PUBLIC void MSG_sem_destroy(const_sg_sem_t sem);
-XBT_PUBLIC int MSG_sem_would_block(msg_sem_t sem);
+XBT_PUBLIC int MSG_sem_would_block(const_sg_sem_t sem);
/** @brief Opaque type representing a barrier identifier */
typedef sg_bar_t msg_bar_t;
#ifndef SIMGRID_PLUGINS_DVFS_H_
#define SIMGRID_PLUGINS_DVFS_H_
+#include <simgrid/config.h>
#include <simgrid/forward.h>
#include <xbt/base.h>
XBT_PUBLIC void sg_host_dvfs_plugin_init();
+#if SIMGRID_HAVE_MSG
#define MSG_host_dvfs_plugin_init() sg_host_dvfs_plugin_init()
+#endif // SIMGRID_HAVE_MSG
SG_END_DECL
#ifndef SIMGRID_PLUGINS_ENERGY_H_
#define SIMGRID_PLUGINS_ENERGY_H_
-#include <xbt/base.h>
+#include <simgrid/config.h>
#include <simgrid/forward.h>
+#include <xbt/base.h>
SG_BEGIN_DECL
XBT_PUBLIC void sg_wifi_energy_plugin_init();
+#if SIMGRID_HAVE_MSG
+
#define MSG_host_energy_plugin_init() sg_host_energy_plugin_init()
#define MSG_host_get_consumed_energy(host) sg_host_get_consumed_energy(host)
#define MSG_host_get_idle_consumption_at(host,pstate) sg_host_get_idle_consumption_at((host), (pstate))
#define MSG_host_get_power_range_slope_at(host,pstate) sg_host_get_power_range_slope_at((host), (pstate))
#define MSG_host_get_current_consumption(host) sg_host_get_current_consumption(host)
+#endif // SIMGRID_HAVE_MSG
+
SG_END_DECL
#endif
#ifndef SIMGRID_PLUGINS_FILE_SYSTEM_H_
#define SIMGRID_PLUGINS_FILE_SYSTEM_H_
+#include <simgrid/config.h>
#include <simgrid/forward.h>
#include <xbt/base.h>
#include <xbt/dict.h>
// C interface
////////////////
-typedef sg_file_t msg_file_t; // MSG backwards compatibility
SG_BEGIN_DECL
XBT_PUBLIC void sg_storage_file_system_init();
XBT_PUBLIC xbt_dict_t sg_host_get_storage_content(sg_host_t host);
+#if SIMGRID_HAVE_MSG
+
+typedef sg_file_t msg_file_t; // MSG backwards compatibility
+
#define MSG_file_open(fullpath, data) sg_file_open((fullpath), (data))
#define MSG_file_read(fd, size) sg_file_read((fd), (size))
#define MSG_file_write(fd, size) sg_file_write((fd), (size))
#define MSG_host_get_storage_content(st) sg_host_get_storage_content(st)
+#endif // SIMGRID_HAVE_MSG
+
SG_END_DECL
// C++ interface
* For now, you cannot change the mountpoints programmatically, and must declare them from your platform file.
*/
class XBT_PUBLIC File : public xbt::Extendable<File> {
- sg_size_t size_;
+ sg_size_t size_ = 0;
std::string path_;
std::string fullpath_;
sg_size_t current_position_ = SEEK_SET;
#ifndef SIMGRID_PLUGINS_LIVE_MIGRATION_H_
#define SIMGRID_PLUGINS_LIVE_MIGRATION_H_
+#include <simgrid/config.h>
#include <simgrid/forward.h>
#include <xbt/base.h>
XBT_PUBLIC sg_vm_t sg_vm_create_migratable(sg_host_t pm, const char* name, int coreAmount, int ramsize,
int mig_netspeed, int dp_intensity);
+#if SIMGRID_HAVE_MSG
+
#define MSG_vm_live_migration_plugin_init() sg_vm_live_migration_plugin_init()
#define MSG_vm_create_migratable(pm, name, coreAmount, ramsize, mig_netspeed, dp_intensity) \
#define MSG_vm_is_migrating(vm) sg_vm_is_migrating(vm)
#define MSG_vm_migrate(vm, dst_pm) sg_vm_migrate((vm), (dst_pm))
+#endif // SIMGRID_HAVE_MSG
+
SG_END_DECL
#endif
#ifndef SIMGRID_PLUGINS_LOAD_H_
#define SIMGRID_PLUGINS_LOAD_H_
+#include <simgrid/config.h>
#include <simgrid/forward.h>
#include <xbt/base.h>
XBT_PUBLIC double sg_link_get_min_instantaneous_load(const_sg_link_t link);
XBT_PUBLIC double sg_link_get_max_instantaneous_load(const_sg_link_t link);
+#if SIMGRID_HAVE_MSG
+
#define MSG_host_load_plugin_init() sg_host_load_plugin_init()
/** @brief Returns the current load of that host, as a ratio = achieved_flops / (core_current_speed * core_amount)
*
#define MSG_host_get_computed_flops(host) sg_host_get_computed_flops(host)
#define MSG_host_get_avg_load(host) sg_host_get_avg_load(host)
+#endif // SIMGRID_HAVE_MSG
+
SG_END_DECL
#endif
+++ /dev/null
-/* Copyright (c) 2009-2020. The SimGrid Team. All rights reserved. */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-#ifndef SIMGRID_PLUGINS_LOAD_BALANCER_H_
-#define SIMGRID_PLUGINS_LOAD_BALANCER_H_
-
-#include <simgrid/forward.h>
-#include <xbt/base.h>
-
-SG_BEGIN_DECL
-
-XBT_PUBLIC void sg_load_balancer_plugin_init();
-
-SG_END_DECL
-
-#endif
#include <xbt/string.hpp>
#include <functional>
-#include <map> // deprecated wrappers
#include <unordered_map>
namespace simgrid {
* Blocks the calling actor until the joined actor is terminated. If actor alice executes bob.join(), then alice is
* blocked until bob terminates.
*/
- void join();
+ void join() const;
/** Wait for the actor to finish, or for the timeout to elapse.
*
* Blocks the calling actor until the joined actor is terminated. If actor alice executes bob.join(), then alice is
* blocked until bob terminates.
*/
- void join(double timeout);
+ void join(double timeout) const;
/** Kill that actor and restart it from start. */
Actor* restart();
size_t dst_buff_size_ = 0;
void* src_buff_ = nullptr;
size_t src_buff_size_ = sizeof(void*);
- std::string tracing_category_ = "";
/* FIXME: expose these elements in the API */
bool detached_ = false;
bool (*match_fun_)(void*, void*, kernel::activity::CommImpl*) = nullptr;
/*! take a vector s4u::CommPtr and return when one of them is finished.
* The return value is the rank of the first finished CommPtr. */
static int wait_any(const std::vector<CommPtr>* comms) { return wait_any_for(comms, -1); }
- /*! Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/
+ /*! Same as wait_any, but with a timeout. Return -1 if the timeout occurs.*/
static int wait_any_for(const std::vector<CommPtr>* comms_in, double timeout);
/*! take a vector s4u::CommPtr and return when all of them is finished. */
* That's a buffer where the sent data will be copied */
CommPtr set_dst_data(void** buff, size_t size);
- CommPtr set_tracing_category(const std::string& category);
-
/** Retrieve the mailbox on which this comm acts */
Mailbox* get_mailbox() const;
/** Retrieve the size of the received data. Not to be mixed with @ref Activity::set_remaining() */
template <class F> void register_actor(const std::string& name)
{
kernel::actor::ActorCodeFactory code_factory = [](std::vector<std::string> args) {
- return kernel::actor::ActorCode([args] {
+ return kernel::actor::ActorCode([args = std::move(args)]() mutable {
F code(std::move(args));
code();
});
};
- register_function(name, std::move(code_factory));
+ register_function(name, code_factory);
}
template <class F> void register_actor(const std::string& name, F code)
{
kernel::actor::ActorCodeFactory code_factory = [code](std::vector<std::string> args) {
- return kernel::actor::ActorCode([code, args] { code(std::move(args)); });
+ return kernel::actor::ActorCode([code, args = std::move(args)]() mutable { code(std::move(args)); });
};
- register_function(name, std::move(code_factory));
+ register_function(name, code_factory);
}
void load_deployment(const std::string& deploy) const;
int get_pstate() const;
std::vector<Disk*> get_disks() const;
- void add_disk(Disk* disk);
+ void add_disk(const Disk* disk);
void remove_disk(const std::string& disk_name);
std::vector<const char*> get_attached_storages() const;
void acquire();
int acquire_timeout(double timeout);
void release();
- int get_capacity();
- int would_block();
+ int get_capacity() const;
+ int would_block() const;
};
} // namespace s4u
VirtualMachine* set_ramsize(size_t ramsize);
VirtualMachine* set_bound(double bound);
- VirtualMachine::state get_state();
+ VirtualMachine::state get_state() const;
static xbt::signal<void(VirtualMachine const&)> on_start;
static xbt::signal<void(VirtualMachine const&)> on_started;
static xbt::signal<void(VirtualMachine const&)> on_shutdown;
XBT_PUBLIC void sg_sem_acquire(sg_sem_t sem);
XBT_PUBLIC int sg_sem_acquire_timeout(sg_sem_t sem, double timeout);
XBT_PUBLIC void sg_sem_release(sg_sem_t sem);
-XBT_PUBLIC int sg_sem_get_capacity(sg_sem_t sem);
+XBT_PUBLIC int sg_sem_get_capacity(const_sg_sem_t sem);
XBT_PUBLIC void sg_sem_destroy(const_sg_sem_t sem);
-XBT_PUBLIC int sg_sem_would_block(sg_sem_t sem);
+XBT_PUBLIC int sg_sem_would_block(const_sg_sem_t sem);
SG_END_DECL
/* Support some backward compatibility */
#define SD_workstation_t sg_host_t
-#define SD_link_get_name sg_link_name
-#define SD_link_get_current_latency sg_link_latency
-#define SD_link_get_current_bandwidth sg_link_bandwidth
+#define SD_link_get_name sg_link_get_name
+#define SD_link_get_current_latency sg_link_get_latency
+#define SD_link_get_current_bandwidth sg_link_get_bandwidth
#define SD_route_get_current_latency SD_route_get_latency
#define SD_route_get_current_bandwidth SD_route_get_bandwidth
#define SD_workstation_get_name sg_host_get_name
#define SD_workstation_get_by_name sg_host_by_name
#define SD_workstation_dump sg_host_dump
-#define SD_workstation_get_data sg_host_user
-#define SD_workstation_set_data sg_host_user_set
+#define SD_workstation_get_data sg_host_get_data
+#define SD_workstation_set_data sg_host_set_data
#define SD_workstation_get_properties sg_host_get_properties
#define SD_workstation_get_property_value sg_host_get_property_value
-#define SD_workstation_get_power sg_host_speed
+#define SD_workstation_get_power sg_host_get_speed
#define SD_workstation_get_available_power sg_host_get_available_speed
-#define SD_route_get_latency sg_host_route_latency
-#define SD_route_get_bandwidth sg_host_route_bandwidth
+#define SD_route_get_latency sg_host_get_route_latency
+#define SD_route_get_bandwidth sg_host_get_route_bandwidth
#define SD_workstation_get_mounted_storage_list sg_host_get_mounted_storage_list // XBT_ATTRIB_DEPRECATED_v330
// Lost functions
//SD_workstation_get_access_mode
//SD_workstation_set_access_mode
//SD_workstation_get_current_task
-//SD_route_get_communication_time => SG_route_get_latency() + amount / SD_route_get_bandwidth()
-//SD_workstation_get_computation_time => amount / sg_host_speed()
+//SD_route_get_communication_time => SD_route_get_latency() + amount / SD_route_get_bandwidth()
+//SD_workstation_get_computation_time => amount / sg_host_get_speed()
//SD_route_get_size
//SD_route_get_list
//TRACE_sd_set_task_category
/********************************* Process ************************************/
SG_BEGIN_DECL
-XBT_ATTRIB_DEPRECATED_v329("Please use simgrid_get_actor_count()") XBT_PUBLIC int SIMIX_process_count();
+XBT_ATTRIB_DEPRECATED_v329("Please use sg_actor_count()") XBT_PUBLIC int SIMIX_process_count();
XBT_PUBLIC smx_actor_t SIMIX_process_self();
XBT_PUBLIC const char* SIMIX_process_self_get_name();
XBT_ATTRIB_DEPRECATED_v329("This function will be removed in 3.29") XBT_PUBLIC
// If we are in the application, pass the code to the maestro which
// executes it for us and reports the result. We use a std::future which
// conveniently handles the success/failure value for us.
- typedef typename std::result_of<F()>::type R;
+ using R = typename std::result_of<F()>::type;
simgrid::xbt::Result<R> result;
simcall_run_kernel([&result, &code] { simgrid::xbt::fulfill_promise(result, std::forward<F>(code)); }, t);
return result.get();
namespace simgrid {
namespace simix {
-
-typedef std::pair<double, Timer*> TimerQelt;
+using TimerQelt = std::pair<double, Timer*>;
static boost::heap::fibonacci_heap<TimerQelt, boost::heap::compare<xbt::HeapComparator<TimerQelt>>> simix_timers;
/** @brief Timer datatype */
*/
template <class F> auto kernel_sync(F code) -> decltype(code().get())
{
- typedef decltype(code().get()) T;
+ using T = decltype(code().get());
if (SIMIX_is_maestro())
xbt_die("Can't execute blocking call in kernel mode");
template <class T>
class Future {
public:
- Future() { /* Nothing to do*/}
+ Future() = default;
explicit Future(simgrid::kernel::Future<T> future) : future_(std::move(future)) {}
Future(Future&&) noexcept = default;
Future& operator=(Future&&) noexcept = default;
*/
template <class F> auto kernel_async(F code) -> Future<decltype(code().get())>
{
- typedef decltype(code().get()) T;
+ using T = decltype(code().get());
// Execute the code in the kernel and get the kernel future:
simgrid::kernel::Future<T> future = simgrid::kernel::actor::simcall(std::move(code));
class GatherAction : public ReplayAction<GatherArgParser> {
public:
- explicit GatherAction(const std::string& name) : ReplayAction(name) {}
+ using ReplayAction::ReplayAction;
void kernel(xbt::ReplayAction& action) override;
};
class GatherVAction : public ReplayAction<GatherVArgParser> {
public:
- explicit GatherVAction(const std::string& name) : ReplayAction(name) {}
+ using ReplayAction::ReplayAction;
void kernel(xbt::ReplayAction& action) override;
};
XBT_PUBLIC sg_vm_t sg_vm_create_core(sg_host_t pm, const char* name);
XBT_PUBLIC sg_vm_t sg_vm_create_multicore(sg_host_t pm, const char* name, int core_amount);
-XBT_PUBLIC int sg_vm_is_created(sg_vm_t vm);
-XBT_PUBLIC int sg_vm_is_running(sg_vm_t vm);
-XBT_PUBLIC int sg_vm_is_suspended(sg_vm_t vm);
+XBT_PUBLIC int sg_vm_is_created(const_sg_vm_t vm);
+XBT_PUBLIC int sg_vm_is_running(const_sg_vm_t vm);
+XBT_PUBLIC int sg_vm_is_suspended(const_sg_vm_t vm);
XBT_PUBLIC const char* sg_vm_get_name(const_sg_vm_t vm);
XBT_PUBLIC void sg_vm_set_ramsize(sg_vm_t vm, size_t size);
}
}
-typedef simgrid::smpi::Comm SMPI_Comm;
-typedef simgrid::smpi::Datatype SMPI_Datatype;
-typedef simgrid::smpi::Errhandler SMPI_Errhandler;
-typedef simgrid::smpi::File SMPI_File;
-typedef simgrid::smpi::Group SMPI_Group;
-typedef simgrid::smpi::Info SMPI_Info;
-typedef simgrid::smpi::Op SMPI_Op;
-typedef simgrid::smpi::Request SMPI_Request;
-typedef simgrid::smpi::Topo SMPI_Topology;
-typedef simgrid::smpi::Topo_Cart SMPI_Cart_topology;
-typedef simgrid::smpi::Topo_Dist_Graph SMPI_Dist_Graph_topology;
-typedef simgrid::smpi::Topo_Graph SMPI_Graph_topology;
-typedef simgrid::smpi::Win SMPI_Win;
+using SMPI_Comm = simgrid::smpi::Comm;
+using SMPI_Datatype = simgrid::smpi::Datatype;
+using SMPI_Errhandler = simgrid::smpi::Errhandler;
+using SMPI_File = simgrid::smpi::File;
+using SMPI_Group = simgrid::smpi::Group;
+using SMPI_Info = simgrid::smpi::Info;
+using SMPI_Op = simgrid::smpi::Op;
+using SMPI_Request = simgrid::smpi::Request;
+using SMPI_Topology = simgrid::smpi::Topo;
+using SMPI_Cart_topology = simgrid::smpi::Topo_Cart;
+using SMPI_Dist_Graph_topology = simgrid::smpi::Topo_Dist_Graph;
+using SMPI_Graph_topology = simgrid::smpi::Topo_Graph;
+using SMPI_Win = simgrid::smpi::Win;
#else
#define SMPI_SAMPLE_FLOPS(flops) for(smpi_execute_flops(flops); 0; )
XBT_PUBLIC void* smpi_shared_malloc(size_t size, const char* file, int line);
#define SMPI_SHARED_MALLOC(size) smpi_shared_malloc((size), __FILE__, __LINE__)
-XBT_PUBLIC void* smpi_shared_malloc_partial(size_t size, size_t* shared_block_offsets, int nb_shared_blocks);
+XBT_PUBLIC void* smpi_shared_malloc_partial(size_t size, const size_t* shared_block_offsets, int nb_shared_blocks);
#define SMPI_PARTIAL_SHARED_MALLOC(size, shared_block_offsets, nb_shared_blocks) \
smpi_shared_malloc_partial((size), (shared_block_offsets), (nb_shared_blocks))
/** @brief Configuration set's data type is opaque. */
#ifdef __cplusplus
#include <xbt/config.hpp>
-typedef simgrid::config::Config* xbt_cfg_t;
+using xbt_cfg_t = simgrid::config::Config*;
#else
typedef void* xbt_cfg_t;
#endif
void bind_flag(T& value, const char* name, std::initializer_list<const char*> aliases, const char* description)
{
bind_flag(value, name, description);
- alias(name, std::move(aliases));
+ alias(name, aliases);
}
/** Bind a variable to configuration flag
bind_flag(T& value, const char* name, std::initializer_list<const char*> aliases, const char* description, F callback)
{
bind_flag(value, name, description, std::move(callback));
- alias(name, std::move(aliases));
+ alias(name, aliases);
}
template <class T, class F>
typename std::enable_if<std::is_same<void, decltype(std::declval<F>()(std::declval<const T&>()))>::value, void>::type
-bind_flag(T& value, const char* name, const char* description, std::map<T, std::string> valid_values, F callback)
+bind_flag(T& value, const char* name, const char* description, const std::map<T, std::string>& valid_values, F callback)
{
declare_flag(name, description, value,
std::function<void(const T&)>([&value, name, valid_values, callback](const T& val) {
callback(val);
- bool found = false;
- for (auto kv : valid_values) {
- if (kv.first == val)
- found = true;
+ if (valid_values.find(val) != valid_values.end()) {
+ value = std::move(val);
+ return;
}
- if (not found || std::string(val) == "help") {
- std::string mesg = "\n";
- if (std::string(val) == "help")
- mesg += std::string("Possible values for option ") + name + ":\n";
- else
- mesg += std::string("Invalid value '") + val + "' for option " + name + ". Possible values:\n";
- for (auto kv : valid_values)
- mesg += " - '" + std::string(kv.first) + "': " + kv.second +
- (kv.first == value ? " <=== DEFAULT" : "") + "\n";
- xbt_die("%s", mesg.c_str());
- }
- value = std::move(val);
+ std::string mesg = "\n";
+ if (std::string(val) == "help")
+ mesg += std::string("Possible values for option ") + name + ":\n";
+ else
+ mesg += std::string("Invalid value '") + val + "' for option " + name + ". Possible values:\n";
+ for (auto const& kv : valid_values)
+ mesg += " - '" + std::string(kv.first) + "': " + kv.second +
+ (kv.first == value ? " <=== DEFAULT" : "") + "\n";
+ xbt_die("%s", mesg.c_str());
}));
}
template <class T, class F>
typename std::enable_if<std::is_same<void, decltype(std::declval<F>()(std::declval<const T&>()))>::value, void>::type
bind_flag(T& value, const char* name, std::initializer_list<const char*> aliases, const char* description,
- std::map<T, std::string> valid_values, F callback)
+ const std::map<T, std::string>& valid_values, F callback)
{
- bind_flag(value, name, description, std::move(valid_values), std::move(callback));
- alias(name, std::move(aliases));
+ bind_flag(value, name, description, valid_values, std::move(callback));
+ alias(name, aliases);
}
/** Bind a variable to configuration flag
Flag(const char* name, std::initializer_list<const char*> aliases, const char* desc, T value)
: value_(value), name_(name)
{
- simgrid::config::bind_flag(value_, name, std::move(aliases), desc);
+ simgrid::config::bind_flag(value_, name, aliases, desc);
}
/* A constructor accepting a callback that will be passed the parameter.
Flag(const char* name, std::initializer_list<const char*> aliases, const char* desc, T value, F callback)
: value_(value), name_(name)
{
- simgrid::config::bind_flag(value_, name, std::move(aliases), desc, std::move(callback));
+ simgrid::config::bind_flag(value_, name, aliases, desc, std::move(callback));
}
/* A constructor accepting a map of valid values -> their description,
* and producing an informative error message when an invalid value is passed, or when help is passed as a value.
*/
template <class F>
- Flag(const char* name, const char* desc, T value, std::map<T, std::string> valid_values, F callback)
+ Flag(const char* name, const char* desc, T value, const std::map<T, std::string>& valid_values, F callback)
: value_(value), name_(name)
{
simgrid::config::bind_flag(value_, name, desc, std::move(valid_values), std::move(callback));
/* A constructor with everything */
template <class F>
Flag(const char* name, std::initializer_list<const char*> aliases, const char* desc, T value,
- std::map<T, std::string> valid_values, F callback)
+ const std::map<T, std::string>& valid_values, F callback)
: value_(value), name_(name)
{
- simgrid::config::bind_flag(value_, name, std::move(aliases), desc, std::move(valid_values), std::move(callback));
+ simgrid::config::bind_flag(value_, name, aliases, desc, valid_values, std::move(callback));
}
// No copy:
struct whatever {};
// Union used for storage:
- typedef typename std::aligned_union<0,
- void*,
- std::pair<void(*)(),void*>,
- std::pair<void(whatever::*)(), whatever*>
- >::type TaskUnion;
+ using TaskUnion = typename std::aligned_union<0, void*, std::pair<void (*)(), void*>,
+ std::pair<void (whatever::*)(), whatever*>>::type;
// Is F suitable for small buffer optimization?
template<class F>
"SBO not working for reference_wrapper");
// Call (and possibly destroy) the function:
- typedef R (*call_function)(TaskUnion&, Args...);
+ using call_function = R (*)(TaskUnion&, Args...);
// Destroy the function (of needed):
- typedef void (*destroy_function)(TaskUnion&);
+ using destroy_function = void (*)(TaskUnion&);
// Move the function (otherwise memcpy):
- typedef void (*move_function)(TaskUnion& dest, TaskUnion& src);
+ using move_function = void (*)(TaskUnion& dest, TaskUnion& src);
// Vtable of functions for manipulating whatever is in the TaskUnion:
struct TaskVtable {
class TaskImpl {
F code_;
std::tuple<Args...> args_;
- typedef decltype(simgrid::xbt::apply(std::move(code_), std::move(args_))) result_type;
+ using result_type = decltype(simgrid::xbt::apply(std::move(code_), std::move(args_)));
+
public:
TaskImpl(F code, std::tuple<Args...> args) :
code_(std::move(code)),
*/
class XBT_PUBLIC StdRandom : public Random {
public:
- StdRandom() = default;
- explicit StdRandom(int seed) : Random(seed) {}
+ using Random::Random;
int uniform_int(int min, int max) override;
double uniform_real(double min, double max) override;
*/
class XBT_PUBLIC XbtRandom : public Random {
public:
- XbtRandom() = default;
- explicit XbtRandom(int seed) : Random(seed) {}
+ using Random::Random;
int uniform_int(int min, int max) override;
double uniform_real(double min, double max) override;
namespace simgrid {
namespace xbt {
/* To split the file if a unique one is given (specific variable for the other case live in runner()) */
-typedef std::vector<std::string> ReplayAction;
+using ReplayAction = std::vector<std::string>;
XBT_PUBLIC_DATA std::ifstream* action_fs;
XBT_PUBLIC int replay_runner(const char* actor_name, const char* trace_filename);
}
}
-typedef std::function<void(simgrid::xbt::ReplayAction&)> action_fun;
+using action_fun = std::function<void(simgrid::xbt::ReplayAction&)>;
XBT_PUBLIC void xbt_replay_action_register(const char* action_name, const action_fun& function);
XBT_PUBLIC action_fun xbt_replay_action_get(const char* action_name);
*/
template<class R, class... P>
class signal<R(P...)> {
- typedef std::function<R(P...)> callback_type;
+ using callback_type = std::function<R(P...)>;
std::map<unsigned int, callback_type> handlers_;
unsigned int callback_sequence_id = 0;
* @{
*/
-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);
namespace simgrid {
namespace xbt {
+/** Create a C++ string from a C-style format
+ *
+ * @ingroup XBT_str
+ */
+XBT_PUBLIC std::string string_printf(const char* fmt, ...);
+
+/** Create a C++ string from a C-style format
+ *
+ * @ingroup XBT_str
+ */
+XBT_PUBLIC std::string string_vprintf(const char* fmt, va_list ap);
+
#if SIMGRID_HAVE_MC
/** POD structure representation of a string
public:
// Types
- typedef std::size_t size_type;
- typedef char& reference;
- typedef const char& const_reference;
- typedef char* iterator;
- typedef const char* const_iterator;
+ using size_type = std::size_t;
+ using reference = char&;
+ using const_reference = const char&;
+ using iterator = char*;
+ using const_iterator = const char*;
// Dtor
~string()
string() : string(&NUL, 0) {}
explicit string(const char* s) : string(s, strlen(s)) {}
string(string const& s) : string(s.c_str(), s.size()) {}
- string(string&& s) noexcept : str(std::move(s.str))
+ string(string&& s) noexcept : str(s.str)
{
s.str.len = 0;
s.str.data = &NUL;
str.data = &NUL;
}
+ size_t copy(char* s, size_t len, size_t pos = 0) const
+ {
+ if (pos > str.len)
+ throw std::out_of_range(string_printf("xbt::string::copy with pos > size() (%zu > %zu)", pos, str.len));
+ size_t count = std::min(len, str.len - pos);
+ std::copy_n(str.data + pos, count, s);
+ return count;
+ }
+
bool equals(const char* data, std::size_t len) const
{
return this->size() == len
typedef std::string string;
#endif
-
-/** Create a C++ string from a C-style format
- *
- * @ingroup XBT_str
-*/
-XBT_PUBLIC std::string string_printf(const char* fmt, ...);
-
-/** Create a C++ string from a C-style format
- *
- * @ingroup XBT_str
-*/
-XBT_PUBLIC std::string string_vprintf(const char* fmt, va_list ap);
}
}
self.build_extension(ext)
def build_extension(self, ext):
+ from pybind11 import get_cmake_dir
extdir = os.path.abspath(os.path.dirname(
self.get_ext_fullpath(ext.name)))
cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir,
'-Denable_smpi=OFF',
'-Denable_java=OFF',
'-Denable_python=ON',
- '-Dminimal-bindings=ON']
+ '-Dminimal-bindings=ON',
+ '-Dpybind11_DIR=' + get_cmake_dir()
+ ]
cfg = 'Debug' if self.debug else 'Release'
build_args = ['--config', cfg]
sonar.cfamily.gcov.reportsPath=Testing/CoverageInfo
# Files to ignore from coverage analysis:
# - foreign test suites
+# - examples in smpi/mc (coverage doesn't work with model checker)
# - XML files
# - Python files used to generate either simcalls or deployment files
# - Any java source code (it's deprecated now)
# - MSG (deprecated too)
-sonar.coverage.exclusions=teshsuite/smpi/isp/**,teshsuite/smpi/mpich3-test/**,**/*.xml,src/simix/simcalls.py,**/generate.py,**/*.java,src/bindings/java/**,src/msg/**,include/msg/**,examples/deprecated/**,teshsuite/msg/**
+sonar.coverage.exclusions=teshsuite/smpi/isp/**,teshsuite/smpi/mpich3-test/**,examples/smpi/mc/**,**/*.xml,src/simix/simcalls.py,**/generate.py,**/*.java,src/bindings/java/**,src/msg/**,include/msg/**,examples/deprecated/**,teshsuite/msg/**
+
# Encoding of the source files
sonar.sourceEncoding=UTF-8
return -1;
}
- return (jdouble)sg_host_speed(host);
+ return (jdouble)sg_host_get_speed(host);
}
JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCoreNumber(JNIEnv * env, jobject jhost) {
JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentPowerPeak(JNIEnv* env, jobject jhost)
{
const_sg_host_t host = jhost_get_native(env, jhost);
- return sg_host_speed(host);
+ return sg_host_get_speed(host);
}
JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getPowerPeakAt(JNIEnv* env, jobject jhost, jint pstate)
{
JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getLoad(JNIEnv* env, jobject jhost)
{
const_sg_host_t host = jhost_get_native(env, jhost);
- return sg_host_load(host);
+ return sg_host_get_load(host);
}
JNIEXPORT jdouble JNICALL Java_org_simgrid_msg_Host_getCurrentLoad (JNIEnv *env, jobject jhost)
JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isCreated(JNIEnv* env, jobject jvm)
{
- sg_vm_t vm = jvm_get_native(env, jvm);
+ const_sg_vm_t vm = jvm_get_native(env, jvm);
return sg_vm_is_created(vm);
}
JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isRunning(JNIEnv* env, jobject jvm)
{
- sg_vm_t vm = jvm_get_native(env, jvm);
+ const_sg_vm_t vm = jvm_get_native(env, jvm);
return sg_vm_is_running(vm);
}
JNIEXPORT jboolean JNICALL Java_org_simgrid_msg_VM_isSuspended(JNIEnv* env, jobject jvm)
{
- sg_vm_t vm = jvm_get_native(env, jvm);
+ const_sg_vm_t vm = jvm_get_native(env, jvm);
return sg_vm_is_suspended(vm);
}
std::vector<jobject> vms;
for (size_t i = 0; i < host_count; i++) {
- auto* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(hosts[i]);
+ const auto* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(hosts[i]);
if (vm != nullptr && vm->get_state() != simgrid::s4u::VirtualMachine::state::DESTROYED) {
auto jvm = static_cast<jobject>(vm->extension(JAVA_HOST_LEVEL));
vms.push_back(jvm);
lua_getstack(L, 1, &ar);
lua_getinfo(L, "Sl", &ar);
- link.properties = nullptr;
-
lua_ensure(lua_istable(L, -1),"Bad Arguments to create backbone in Lua. Should be a table with named arguments.");
lua_pushstring(L, "id");
*/
lua_pushstring(L,"symmetrical");
lua_gettable(L,-2);
- if (lua_isstring(L, -1)) {
- const char* value = lua_tostring(L, -1);
- if (strcmp("YES", value) == 0)
- route.symmetrical = true;
- else
- route.symmetrical = false;
- }
- else {
- route.symmetrical = true;
- }
+ route.symmetrical = (not lua_isstring(L, -1) || strcasecmp("YES", lua_tostring(L, -1)) == 0);
lua_pop(L,1);
- route.gw_src = nullptr;
- route.gw_dst = nullptr;
-
sg_platf_new_route(&route);
return 0;
lua_pushstring(L,"symmetrical");
lua_gettable(L,-2);
- if (lua_isstring(L, -1)) {
- const char* value = lua_tostring(L, -1);
- if (strcmp("YES", value) == 0)
- ASroute.symmetrical = true;
- else
- ASroute.symmetrical = false;
- }
- else {
- ASroute.symmetrical = true;
- }
+ ASroute.symmetrical = (not lua_isstring(L, -1) || strcasecmp("YES", lua_tostring(L, -1)) == 0);
lua_pop(L,1);
sg_platf_new_route(&ASroute);
namespace {
-static std::string get_simgrid_version()
+std::string get_simgrid_version()
{
int major;
int minor;
.def("is_daemon", &Actor::is_daemon,
"Returns True if that actor is a daemon and will be terminated automatically when the last non-daemon actor "
"terminates.")
- .def("join", py::overload_cast<double>(&Actor::join), py::call_guard<GilScopedRelease>(),
+ .def("join", py::overload_cast<double>(&Actor::join, py::const_), py::call_guard<GilScopedRelease>(),
"Wait for the actor to finish (more info in the C++ documentation).", py::arg("timeout"))
.def("kill", &Actor::kill, py::call_guard<GilScopedRelease>(), "Kill that actor")
.def("kill_all", &Actor::kill_all, py::call_guard<GilScopedRelease>(), "Kill all actors but the caller.")
template <typename T> void Parmap<T>::PosixSynchro::master_wait()
{
std::unique_lock<std::mutex> lk(done_mutex);
- while (this->parmap.thread_counter < this->parmap.num_workers) {
- /* wait for all workers to be ready */
- done_cond.wait(lk);
- }
+ /* wait for all workers to be ready */
+ done_cond.wait(lk, [this]() { return this->parmap.thread_counter >= this->parmap.num_workers; });
}
template <typename T> void Parmap<T>::PosixSynchro::worker_signal()
{
std::unique_lock<std::mutex> lk(ready_mutex);
/* wait for more work */
- while (this->parmap.work_round != round) {
- ready_cond.wait(lk);
- }
+ ready_cond.wait(lk, [this, round]() { return this->parmap.work_round == round; });
}
#if HAVE_FUTEX_H
"tracing", "Enable the tracing system. You have to enable this option to use other tracing options.", false};
static simgrid::config::Flag<bool> trace_actor_enabled{
- "tracing/msg/process", // FIXME rename this flag
+ "tracing/actor",
+ {"tracing/msg/process"}, // XBT_ATTRIB_DEPRECATED_v330(option alias)
"Trace the behavior of all categorized actors, grouping them by host. "
"Can be used to track actor location if the simulator does actor migration.",
false};
"To use if the simulator does not use tracing categories but resource utilization have to be traced.",
false};
-static simgrid::config::Flag<bool> trace_disable_destroy{
- OPT_TRACING_DISABLE_DESTROY, {"tracing/disable_destroy"}, "Disable platform containers destruction.", false};
+static simgrid::config::Flag<bool> trace_disable_destroy{OPT_TRACING_DISABLE_DESTROY,
+ "Disable platform containers destruction.", false};
static simgrid::config::Flag<bool> trace_basic{OPT_TRACING_BASIC, "Avoid extended events (impoverished trace file).",
false};
*************/
xbt::signal<void(Container const&)> Container::on_creation;
xbt::signal<void(Container const&)> Container::on_destruction;
-xbt::signal<void(Type const&, e_event_type)> Type::on_creation;
+xbt::signal<void(Type const&, PajeEventType)> Type::on_creation;
xbt::signal<void(LinkType const&, Type const&, Type const&)> LinkType::on_creation;
xbt::signal<void(PajeEvent&)> PajeEvent::on_creation;
xbt::signal<void(PajeEvent const&)> PajeEvent::on_destruction;
double timestamp = SIMIX_get_clock();
std::stringstream stream;
- XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_CreateContainer, timestamp);
+ XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, static_cast<unsigned>(PajeEventType::CreateContainer),
+ timestamp);
- stream << std::fixed << std::setprecision(trace_precision) << PAJE_CreateContainer << " ";
+ stream << std::fixed << std::setprecision(trace_precision) << PajeEventType::CreateContainer << " ";
stream << timestamp << " " << c.get_id() << " " << c.type_->get_id() << " " << c.father_->get_id() << " \"";
if (c.get_name().find("rank-") != 0)
stream << c.get_name() << "\"";
std::stringstream stream;
double timestamp = SIMIX_get_clock();
- XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_DestroyContainer, timestamp);
+ XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, static_cast<unsigned>(PajeEventType::DestroyContainer),
+ timestamp);
- stream << std::fixed << std::setprecision(trace_precision) << PAJE_DestroyContainer << " ";
+ stream << std::fixed << std::setprecision(trace_precision) << PajeEventType::DestroyContainer << " ";
stream << timestamp << " " << c.type_->get_id() << " " << c.get_id();
XBT_DEBUG("Dump %s", stream.str().c_str());
tracing_file << stream.str() << std::endl;
static void on_container_creation_ti(const Container& c)
{
- XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, PAJE_CreateContainer, SIMIX_get_clock());
+ XBT_DEBUG("%s: event_type=%u, timestamp=%f", __func__, static_cast<unsigned>(PajeEventType::CreateContainer),
+ SIMIX_get_clock());
// if we are in the mode with only one file
static std::ofstream* ti_unique_file = nullptr;
static void on_entity_value_creation(const EntityValue& value)
{
std::stringstream stream;
- XBT_DEBUG("%s: event_type=%u", __func__, PAJE_DefineEntityValue);
- stream << std::fixed << std::setprecision(trace_precision) << PAJE_DefineEntityValue;
+ XBT_DEBUG("%s: event_type=%u", __func__, static_cast<unsigned>(PajeEventType::DefineEntityValue));
+ stream << std::fixed << std::setprecision(trace_precision) << PajeEventType::DefineEntityValue;
stream << " " << value.get_id() << " " << value.get_father()->get_id() << " " << value.get_name();
if (not value.get_color().empty())
stream << " \"" << value.get_color() << "\"";
static void on_event_creation(PajeEvent& event)
{
- XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, event.eventType_, trace_precision, event.timestamp_);
+ XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, static_cast<unsigned>(event.eventType_), trace_precision,
+ event.timestamp_);
event.stream_ << std::fixed << std::setprecision(trace_precision);
event.stream_ << event.eventType_ << " " << event.timestamp_ << " ";
event.stream_ << event.get_type()->get_id() << " " << event.get_container()->get_id();
*tracing_files.at(event.get_container()) << event.stream_.str() << std::endl;
}
-static void on_type_creation(const Type& type, e_event_type event_type)
+static void on_type_creation(const Type& type, PajeEventType event_type)
{
- if (event_type == PAJE_DefineLinkType)
+ if (event_type == PajeEventType::DefineLinkType)
return; // this kind of type has to be handled differently
std::stringstream stream;
stream << std::fixed << std::setprecision(trace_precision);
- XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, event_type, trace_precision, 0.);
+ XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, static_cast<unsigned>(event_type), trace_precision, 0.);
stream << event_type << " " << type.get_id() << " " << type.get_father()->get_id() << " " << type.get_name();
if (type.is_colored())
stream << " \"" << type.get_color() << "\"";
static void on_link_type_creation(const Type& type, const Type& source, const Type& dest)
{
std::stringstream stream;
- XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, PAJE_DefineLinkType, trace_precision, 0.);
- stream << PAJE_DefineLinkType << " " << type.get_id() << " " << type.get_father()->get_id();
+ XBT_DEBUG("%s: event_type=%u, timestamp=%.*f", __func__, static_cast<unsigned>(PajeEventType::DefineLinkType),
+ trace_precision, 0.);
+ stream << PajeEventType::DefineLinkType << " " << type.get_id() << " " << type.get_father()->get_id();
stream << " " << source.get_id() << " " << dest.get_id() << " " << type.get_name();
XBT_DEBUG("Dump %s", stream.str().c_str());
tracing_file << stream.str() << std::endl;
config::declare_flag<bool>(OPT_TRACING_FORMAT_TI_ONEFILE,
"(smpi only) For replay format only : output to one file only", false);
- config::alias(OPT_TRACING_FORMAT_TI_ONEFILE, {"tracing/smpi/format/ti_one_file"});
config::declare_flag<std::string>("tracing/comment", "Add a comment line to the top of the trace file.", "");
config::declare_flag<std::string>(OPT_TRACING_COMMENT_FILE,
"Add the contents of a file as comments to the top of the trace.", "");
- config::alias(OPT_TRACING_COMMENT_FILE, {"tracing/comment_file"});
config::declare_flag<int>("tracing/precision",
"Numerical precision used when timestamping events "
"(expressed in number of digits after decimal point)",
Container* Container::root_container_ = nullptr; /* the root container */
std::map<std::string, Container*> Container::all_containers_; /* all created containers indexed by name */
-long long int new_paje_id()
-{
- static long long int type_id = 0;
- return type_id++;
-}
-
NetZoneContainer::NetZoneContainer(const std::string& name, unsigned int level, NetZoneContainer* father)
: Container::Container(name, "", father)
{
EntityValue::EntityValue(const std::string& name, const std::string& color, Type* father)
: name_(name), color_(color), father_(father)
{
- id_ = simgrid::instr::new_paje_id();
on_creation(*this);
}
namespace simgrid {
namespace instr {
-PajeEvent::PajeEvent(Container* container, Type* type, double timestamp, e_event_type eventType)
+PajeEvent::PajeEvent(Container* container, Type* type, double timestamp, PajeEventType eventType)
: container_(container), type_(type), timestamp_(timestamp), eventType_(eventType)
{
on_creation(*this);
on_destruction(*this);
}
-StateEvent::StateEvent(Container* container, Type* type, e_event_type event_type, EntityValue* value, TIData* extra)
+StateEvent::StateEvent(Container* container, Type* type, PajeEventType event_type, EntityValue* value, TIData* extra)
: PajeEvent::PajeEvent(container, type, SIMIX_get_clock(), event_type), value(value), extra_(extra)
{
#if HAVE_SMPI
- if (simgrid::config::get_value<bool>("smpi/trace-call-location")) {
+ if (smpi_cfg_trace_call_location()) {
const smpi_trace_call_location_t* loc = smpi_trace_get_call_location();
filename = loc->filename;
linenumber = loc->linenumber;
void StateEvent::print()
{
if (trace_format == TraceFormat::Paje) {
- if (value != nullptr) // PAJE_PopState Event does not need to have a value
+ if (value != nullptr) // PajeEventType::PopState Event does not need to have a value
stream_ << " " << value->get_id();
if (TRACE_display_sizes())
stream_ << " " << ((extra_ != nullptr) ? extra_->display_size() : "");
#if HAVE_SMPI
- if (simgrid::config::get_value<bool>("smpi/trace-call-location"))
+ if (smpi_cfg_trace_call_location())
stream_ << " \"" << filename << "\" " << linenumber;
#endif
} else if (trace_format == TraceFormat::Ti) {
container_name=std::to_string(stoi(container_name.erase(0, 5)) - 1);
}
#if HAVE_SMPI
- if (config::get_value<bool>("smpi/trace-call-location"))
+ if (smpi_cfg_trace_call_location())
stream_ << container_name << " location " << filename << " " << linenumber << std::endl ;
#endif
stream_ << container_name << " " << extra_->print();
class EntityValue;
class TIData;
-enum e_event_type : unsigned int {
- PAJE_DefineContainerType,
- PAJE_DefineVariableType,
- PAJE_DefineStateType,
- PAJE_DefineEventType,
- PAJE_DefineLinkType,
- PAJE_DefineEntityValue,
- PAJE_CreateContainer,
- PAJE_DestroyContainer,
- PAJE_SetVariable,
- PAJE_AddVariable,
- PAJE_SubVariable,
- PAJE_SetState,
- PAJE_PushState,
- PAJE_PopState,
- PAJE_ResetState,
- PAJE_StartLink,
- PAJE_EndLink,
- PAJE_NewEvent
+enum class PajeEventType : unsigned int {
+ DefineContainerType,
+ DefineVariableType,
+ DefineStateType,
+ DefineEventType,
+ DefineLinkType,
+ DefineEntityValue,
+ CreateContainer,
+ DestroyContainer,
+ SetVariable,
+ AddVariable,
+ SubVariable,
+ SetState,
+ PushState,
+ PopState,
+ ResetState,
+ StartLink,
+ EndLink,
+ NewEvent
};
+inline std::ostream& operator<<(std::ostream& os, PajeEventType event)
+{
+ return os << static_cast<std::underlying_type<PajeEventType>::type>(event);
+}
+
class PajeEvent {
Container* container_;
Type* type_;
static xbt::signal<void(PajeEvent const&)> on_destruction;
double timestamp_;
- e_event_type eventType_;
+ PajeEventType eventType_;
std::stringstream stream_;
- PajeEvent(Container* container, Type* type, double timestamp, e_event_type eventType);
+ PajeEvent(Container* container, Type* type, double timestamp, PajeEventType eventType);
virtual ~PajeEvent();
Container* get_container() const { return container_; }
double value_;
public:
- VariableEvent(double timestamp, Container* container, Type* type, e_event_type event_type, double value)
+ VariableEvent(double timestamp, Container* container, Type* type, PajeEventType event_type, double value)
: PajeEvent::PajeEvent(container, type, timestamp, event_type), value_(value)
{
}
public:
static xbt::signal<void(StateEvent const&)> on_destruction;
- StateEvent(Container* container, Type* type, e_event_type event_type, EntityValue* value, TIData* extra);
+ StateEvent(Container* container, Type* type, PajeEventType event_type, EntityValue* value, TIData* extra);
~StateEvent() override { on_destruction(*this); }
bool has_extra() const { return extra_ != nullptr; }
void print() override;
int size_ = -1;
public:
- LinkEvent(Container* container, Type* type, e_event_type event_type, Container* sourceContainer,
+ LinkEvent(Container* container, Type* type, PajeEventType event_type, Container* sourceContainer,
const std::string& value, const std::string& key, int size)
: PajeEvent(container, type, SIMIX_get_clock(), event_type)
, endpoint_(sourceContainer)
public:
NewEvent(double timestamp, Container* container, Type* type, EntityValue* value)
- : PajeEvent::PajeEvent(container, type, timestamp, PAJE_NewEvent), value(value)
+ : PajeEvent::PajeEvent(container, type, timestamp, PajeEventType::NewEvent), value(value)
{
}
void print() override;
#include "simgrid/Exception.hpp"
#include "src/instr/instr_private.hpp"
+#include "src/smpi/include/private.hpp"
#include "xbt/virtu.h" /* xbt::cmdline */
extern std::ofstream tracing_file;
void dump_header(bool basic, bool display_sizes)
{
// Types
- tracing_file << "%EventDef PajeDefineContainerType " << PAJE_DefineContainerType << std::endl;
+ tracing_file << "%EventDef PajeDefineContainerType " << PajeEventType::DefineContainerType << std::endl;
tracing_file << "% Alias string" << std::endl;
if (basic)
tracing_file << "% ContainerType string" << std::endl;
tracing_file << "% Name string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajeDefineVariableType " << PAJE_DefineVariableType << std::endl;
+ tracing_file << "%EventDef PajeDefineVariableType " << PajeEventType::DefineVariableType << std::endl;
tracing_file << "% Alias string" << std::endl;
tracing_file << "% " << (basic ? "Container" : "") << "Type string" << std::endl;
tracing_file << "% Name string" << std::endl;
tracing_file << "% Color color" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajeDefineStateType " << PAJE_DefineStateType << std::endl;
+ tracing_file << "%EventDef PajeDefineStateType " << PajeEventType::DefineStateType << std::endl;
tracing_file << "% Alias string" << std::endl;
tracing_file << "% " << (basic ? "Container" : "") << "Type string" << std::endl;
tracing_file << "% Name string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajeDefineEventType " << PAJE_DefineEventType << std::endl;
+ tracing_file << "%EventDef PajeDefineEventType " << PajeEventType::DefineEventType << std::endl;
tracing_file << "% Alias string" << std::endl;
tracing_file << "% " << (basic ? "Container" : "") << "Type string" << std::endl;
tracing_file << "% Name string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajeDefineLinkType " << PAJE_DefineLinkType << std::endl;
+ tracing_file << "%EventDef PajeDefineLinkType " << PajeEventType::DefineLinkType << std::endl;
tracing_file << "% Alias string" << std::endl;
tracing_file << "% " << (basic ? "Container" : "") << "Type string" << std::endl;
tracing_file << "% " << (basic ? "Source" : "Start") << "ContainerType string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
// EntityValue
- tracing_file << "%EventDef PajeDefineEntityValue " << PAJE_DefineEntityValue << std::endl;
+ tracing_file << "%EventDef PajeDefineEntityValue " << PajeEventType::DefineEntityValue << std::endl;
tracing_file << "% Alias string" << std::endl;
tracing_file << "% " << (basic ? "Entity" : "") << "Type string" << std::endl;
tracing_file << "% Name string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
// Container
- tracing_file << "%EventDef PajeCreateContainer " << PAJE_CreateContainer << std::endl;
+ tracing_file << "%EventDef PajeCreateContainer " << PajeEventType::CreateContainer << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Alias string" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Name string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajeDestroyContainer " << PAJE_DestroyContainer << std::endl;
+ tracing_file << "%EventDef PajeDestroyContainer " << PajeEventType::DestroyContainer << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Name string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
// Variable
- tracing_file << "%EventDef PajeSetVariable " << PAJE_SetVariable << std::endl;
+ tracing_file << "%EventDef PajeSetVariable " << PajeEventType::SetVariable << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
tracing_file << "% Value double" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajeAddVariable " << PAJE_AddVariable << std::endl;
+ tracing_file << "%EventDef PajeAddVariable " << PajeEventType::AddVariable << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
tracing_file << "% Value double" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajeSubVariable " << PAJE_SubVariable << std::endl;
+ tracing_file << "%EventDef PajeSubVariable " << PajeEventType::SubVariable << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
// State
- tracing_file << "%EventDef PajeSetState " << PAJE_SetState << std::endl;
+ tracing_file << "%EventDef PajeSetState " << PajeEventType::SetState << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
tracing_file << "% Value string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajePushState " << PAJE_PushState << std::endl;
+ tracing_file << "%EventDef PajePushState " << PajeEventType::PushState << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
if (display_sizes)
tracing_file << "% Size int" << std::endl;
#if HAVE_SMPI
- if (simgrid::config::get_value<bool>("smpi/trace-call-location")) {
+ if (smpi_cfg_trace_call_location()) {
/* paje currently (May 2016) uses "Filename" and "Linenumber" as reserved words. We cannot use them... */
tracing_file << "% Fname string" << std::endl;
tracing_file << "% Lnumber int" << std::endl;
#endif
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajePopState " << PAJE_PopState << std::endl;
+ tracing_file << "%EventDef PajePopState " << PajeEventType::PopState << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
if (not basic) {
- tracing_file << "%EventDef PajeResetState " << PAJE_ResetState << std::endl;
+ tracing_file << "%EventDef PajeResetState " << PajeEventType::ResetState << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
}
// Link
- tracing_file << "%EventDef PajeStartLink " << PAJE_StartLink << std::endl;
+ tracing_file << "%EventDef PajeStartLink " << PajeEventType::StartLink << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
tracing_file << "% Size int" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
- tracing_file << "%EventDef PajeEndLink " << PAJE_EndLink << std::endl;
+ tracing_file << "%EventDef PajeEndLink " << PajeEventType::EndLink << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
tracing_file << "%EndEventDef" << std::endl;
// Event
- tracing_file << "%EventDef PajeNewEvent " << PAJE_NewEvent << std::endl;
+ tracing_file << "%EventDef PajeNewEvent " << PajeEventType::NewEvent << std::endl;
tracing_file << "% Time date" << std::endl;
tracing_file << "% Type string" << std::endl;
tracing_file << "% Container string" << std::endl;
/* internal do the instrumentation module */
void PajeEvent::insert_into_buffer()
{
- XBT_DEBUG("%s: insert event_type=%u, timestamp=%f, buffersize=%zu)", __func__, eventType_, timestamp_, buffer.size());
+ XBT_DEBUG("%s: insert event_type=%u, timestamp=%f, buffersize=%zu)", __func__, static_cast<unsigned>(eventType_),
+ timestamp_, buffer.size());
std::vector<PajeEvent*>::reverse_iterator i;
for (i = buffer.rbegin(); i != buffer.rend(); ++i) {
PajeEvent* e1 = *i;
- XBT_DEBUG("compare to %p is of type %u; timestamp:%f", e1, e1->eventType_, e1->timestamp_);
+ XBT_DEBUG("compare to %p is of type %u; timestamp:%f", e1, static_cast<unsigned>(e1->eventType_), e1->timestamp_);
if (e1->timestamp_ <= timestamp_)
break;
}
namespace simgrid {
namespace instr {
-Type::Type(e_event_type event_type, const std::string& name, const std::string& alias, const std::string& color,
+long long int new_paje_id()
+{
+ static long long int type_id = 0;
+ return type_id++;
+}
+
+Type::Type(PajeEventType event_type, const std::string& name, const std::string& alias, const std::string& color,
Type* father)
- : id_(new_paje_id()), name_(name), color_(color), father_(father)
+ : name_(name), color_(color), father_(father)
{
if (name_.empty() || alias.empty())
throw TracingError(XBT_THROW_POINT, "can't create a new type with no name or alias");
void StateType::set_event(const std::string& value_name)
{
- events_.push_back(new StateEvent(get_issuer(), this, PAJE_SetState, get_entity_value(value_name), nullptr));
+ events_.push_back(new StateEvent(get_issuer(), this, PajeEventType::SetState, get_entity_value(value_name), nullptr));
}
void StateType::push_event(const std::string& value_name, TIData* extra)
{
- events_.push_back(new StateEvent(get_issuer(), this, PAJE_PushState, get_entity_value(value_name), extra));
+ events_.push_back(new StateEvent(get_issuer(), this, PajeEventType::PushState, get_entity_value(value_name), extra));
}
void StateType::push_event(const std::string& value_name)
{
- events_.push_back(new StateEvent(get_issuer(), this, PAJE_PushState, get_entity_value(value_name), nullptr));
+ events_.push_back(
+ new StateEvent(get_issuer(), this, PajeEventType::PushState, get_entity_value(value_name), nullptr));
}
void StateType::pop_event()
void StateType::pop_event(TIData* extra)
{
- events_.push_back(new StateEvent(get_issuer(), this, PAJE_PopState, nullptr, extra));
+ events_.push_back(new StateEvent(get_issuer(), this, PajeEventType::PopState, nullptr, extra));
}
void VariableType::instr_event(double now, double delta, const char* resource, double value)
void VariableType::set_event(double timestamp, double value)
{
- events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_SetVariable, value));
+ events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PajeEventType::SetVariable, value));
}
void VariableType::add_event(double timestamp, double value)
{
- events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_AddVariable, value));
+ events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PajeEventType::AddVariable, value));
}
void VariableType::sub_event(double timestamp, double value)
{
- events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_SubVariable, value));
+ events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PajeEventType::SubVariable, value));
}
void LinkType::start_event(Container* startContainer, const std::string& value, const std::string& key)
void LinkType::start_event(Container* startContainer, const std::string& value, const std::string& key, int size)
{
- new LinkEvent(get_issuer(), this, PAJE_StartLink, startContainer, value, key, size);
+ new LinkEvent(get_issuer(), this, PajeEventType::StartLink, startContainer, value, key, size);
}
void LinkType::end_event(Container* endContainer, const std::string& value, const std::string& key)
{
- new LinkEvent(get_issuer(), this, PAJE_EndLink, endContainer, value, key, -1);
+ new LinkEvent(get_issuer(), this, PajeEventType::EndLink, endContainer, value, key, -1);
}
Type* Type::by_name(const std::string& name)
class ContainerType;
class EventType;
+long long int new_paje_id();
+
class Type {
- long long int id_;
+ long long int id_ = new_paje_id();
std::string name_;
std::string color_;
Type* father_;
Container* get_issuer() const { return issuer_; }
public:
- static xbt::signal<void(Type const&, e_event_type event_type)> on_creation;
+ static xbt::signal<void(Type const&, PajeEventType event_type)> on_creation;
- Type(e_event_type event_type, const std::string& name, const std::string& alias, const std::string& color,
+ Type(PajeEventType event_type, const std::string& name, const std::string& alias, const std::string& color,
Type* father);
virtual ~Type() = default;
class ContainerType : public Type {
public:
- explicit ContainerType(const std::string& name) : Type(PAJE_DefineContainerType, name, name, "", nullptr){};
- ContainerType(const std::string& name, Type* father) : Type(PAJE_DefineContainerType, name, name, "", father){};
+ explicit ContainerType(const std::string& name) : Type(PajeEventType::DefineContainerType, name, name, "", nullptr){};
+ ContainerType(const std::string& name, Type* father)
+ : Type(PajeEventType::DefineContainerType, name, name, "", father){};
};
class VariableType : public Type {
std::vector<VariableEvent*> events_;
public:
VariableType(const std::string& name, const std::string& color, Type* father)
- : Type(PAJE_DefineVariableType, name, name, color, father)
+ : Type(PajeEventType::DefineVariableType, name, name, color, father)
{
}
void instr_event(double now, double delta, const char* resource, double value);
class ValueType : public Type {
public:
std::map<std::string, EntityValue> values_;
- ValueType(e_event_type event_type, const std::string& name, const std::string& alias, Type* father)
+ ValueType(PajeEventType event_type, const std::string& name, const std::string& alias, Type* father)
: Type(event_type, name, alias, "", father){};
- ValueType(e_event_type event_type, const std::string& name, Type* father)
+ ValueType(PajeEventType event_type, const std::string& name, Type* father)
: Type(event_type, name, name, "", father){};
~ValueType() override = default;
void add_entity_value(const std::string& name, const std::string& color);
public:
static xbt::signal<void(LinkType const&, Type const&, Type const&)> on_creation;
LinkType(const std::string& name, const Type* source, const Type* dest, const std::string& alias, Type* father)
- : ValueType(PAJE_DefineLinkType, name, alias, father)
+ : ValueType(PajeEventType::DefineLinkType, name, alias, father)
{
on_creation(*this, *source, *dest);
}
class EventType : public ValueType {
public:
- EventType(const std::string& name, Type* father) : ValueType(PAJE_DefineEventType, name, father) {}
+ EventType(const std::string& name, Type* father) : ValueType(PajeEventType::DefineEventType, name, father) {}
};
class StateType : public ValueType {
std::vector<StateEvent*> events_;
public:
- StateType(const std::string& name, Type* father) : ValueType(PAJE_DefineStateType, name, father) {}
+ StateType(const std::string& name, Type* father) : ValueType(PajeEventType::DefineStateType, name, father) {}
void set_event(const std::string& value_name);
void push_event(const std::string& value_name);
void push_event(const std::string& value_name, TIData* extra);
namespace instr {
class EntityValue {
- long long int id_;
+ long long int id_ = new_paje_id();
std::string name_;
std::string color_;
Type* father_;
// create an array with all ancestors of a1
std::vector<simgrid::instr::Container*> ancestors_a1;
- simgrid::instr::Container* p = a1->father_;
- while (p) {
+ for (auto* p = a1->father_; p != nullptr; p = p->father_)
ancestors_a1.push_back(p);
- p = p->father_;
- }
// create an array with all ancestors of a2
std::vector<simgrid::instr::Container*> ancestors_a2;
- p = a2->father_;
- while (p) {
+ for (auto* p = a2->father_; p != nullptr; p = p->father_)
ancestors_a2.push_back(p);
- p = p->father_;
- }
// find the lowest ancestor
- p = nullptr;
+ simgrid::instr::Container* p = nullptr;
int i = static_cast<int>(ancestors_a1.size()) - 1;
int j = static_cast<int>(ancestors_a2.size()) - 1;
while (i >= 0 && j >= 0) {
}
auto* graph = xbt_graph_new_graph(0, nullptr);
- auto* nodes = new std::map<std::string, xbt_node_t>();
- auto* edges = new std::map<std::string, xbt_edge_t>();
+ std::map<std::string, xbt_node_t> nodes;
+ std::map<std::string, xbt_edge_t> edges;
- netzone->get_impl()->get_graph(graph, nodes, edges);
- for (auto elm : *edges) {
+ netzone->get_impl()->get_graph(graph, &nodes, &edges);
+ for (auto elm : edges) {
const xbt_edge* edge = elm.second;
linkContainers(simgrid::instr::Container::by_name(static_cast<const char*>(edge->src->data)),
simgrid::instr::Container::by_name(static_cast<const char*>(edge->dst->data)), filter);
}
- delete nodes;
- delete edges;
xbt_graph_free_graph(graph, xbt_free_f, xbt_free_f, nullptr);
}
void platform_graph_export_graphviz(const std::string& output_filename)
{
auto* g = xbt_graph_new_graph(0, nullptr);
- auto* nodes = new std::map<std::string, xbt_node_t>();
- auto* edges = new std::map<std::string, xbt_edge_t>();
- s4u::Engine::get_instance()->get_netzone_root()->extract_xbt_graph(g, nodes, edges);
+ std::map<std::string, xbt_node_t> nodes;
+ std::map<std::string, xbt_edge_t> edges;
+ s4u::Engine::get_instance()->get_netzone_root()->extract_xbt_graph(g, &nodes, &edges);
std::ofstream fs;
fs.open(output_filename, std::ofstream::out);
fs << " node [shape=box, style=filled]" << std::endl;
fs << " node [width=.3, height=.3, style=filled, color=skyblue]" << std::endl << std::endl;
- for (auto const& elm : *nodes)
+ for (auto const& elm : nodes)
fs << " \"" << elm.first << "\";" << std::endl;
- for (auto const& elm : *edges) {
+ for (auto const& elm : edges) {
const char* src_s = static_cast<char*>(elm.second->src->data);
const char* dst_s = static_cast<char*>(elm.second->dst->data);
if (g->directed)
fs.close();
xbt_graph_free_graph(g, xbt_free_f, xbt_free_f, nullptr);
- delete nodes;
- delete edges;
}
/* Callbacks */
if (not TRACE_smpi_is_grouped())
mpi->by_name_or_create<StateType>("MPI_STATE");
root->type_->by_name_or_create("MPI_LINK", mpi, mpi);
- // TODO See if we can move this to the LoadBalancer plugin
root->type_->by_name_or_create("MIGRATE_LINK", mpi, mpi);
mpi->by_name_or_create<StateType>("MIGRATE_STATE");
}
if (TRACE_smpi_is_enabled() && TRACE_smpi_is_grouped()) {
auto* mpi = container->type_->by_name_or_create<ContainerType>("MPI");
mpi->by_name_or_create<StateType>("MPI_STATE");
- // TODO See if we can move this to the LoadBalancer plugin
root->type_->by_name_or_create("MIGRATE_LINK", mpi, mpi);
mpi->by_name_or_create<StateType>("MIGRATE_STATE");
}
static void on_platform_created()
{
currentContainer.clear();
- auto* filter = new std::set<std::string>();
+ std::set<std::string> filter;
XBT_DEBUG("Starting graph extraction.");
- recursiveGraphExtraction(s4u::Engine::get_instance()->get_netzone_root(), Container::get_root(), filter);
+ recursiveGraphExtraction(s4u::Engine::get_instance()->get_netzone_root(), Container::get_root(), &filter);
XBT_DEBUG("Graph extraction finished.");
- delete filter;
dump_buffer(true);
}
#include "src/instr/instr_paje_events.hpp"
#include "src/instr/instr_paje_types.hpp"
#include "src/instr/instr_paje_values.hpp"
-#include "xbt/graph.h"
#include <fstream>
#include <iomanip> /** std::setprecision **/
extern int trace_precision;
extern double last_timestamp_to_dump;
-long long int new_paje_id();
-
void init();
void define_callbacks();
XBT_PRIVATE void TRACE_smpi_recv(int src, int dst, int tag);
XBT_PRIVATE void TRACE_smpi_init(int rank, const std::string& calling_func);
-/* SMPI + LB (load balancer) */
-XBT_PRIVATE void TRACE_smpi_process_change_host(int rank, const_sg_host_t new_host);
-
class smpi_trace_call_location_t {
public:
std::string filename;
simgrid::jedule::Event event(std::string(SD_task_get_name(task)), SD_task_get_start_time(task),
SD_task_get_finish_time(task), "SD");
event.add_resources(*task->allocation);
- my_jedule->add_event(std::move(event));
+ my_jedule->add_event(event);
}
void jedule_sd_init()
dst_actor_ ? dst_actor_->get_host()->get_cname() : "a finished process", dst_buff_, buff_size);
/* Copy at most dst_buff_size bytes of the message to receiver's buffer */
- if (dst_buff_size_)
+ if (dst_buff_size_) {
buff_size = std::min(buff_size, *(dst_buff_size_));
- /* Update the receiver's buffer size to the copied amount */
- if (dst_buff_size_)
+ /* Update the receiver's buffer size to the copied amount */
*dst_buff_size_ = buff_size;
+ }
if (buff_size > 0) {
if (copy_data_fun)
* list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
* simcall */
- if (simcall->call_ == SIMCALL_NONE) // FIXME: maybe a better way to handle this case
- continue; // if actor handling comm is killed
- if (simcall->call_ == SIMCALL_COMM_WAITANY) {
+ if (simcall->call_ == simix::Simcall::NONE) // FIXME: maybe a better way to handle this case
+ continue; // if actor handling comm is killed
+ if (simcall->call_ == simix::Simcall::COMM_WAITANY) {
SIMIX_waitany_remove_simcall_from_actions(simcall);
if (simcall->timeout_cb_) {
simcall->timeout_cb_->remove();
}
/* if there is an exception during a waitany or a testany, indicate the position of the failed communication */
if (simcall->issuer_->exception_ &&
- (simcall->call_ == SIMCALL_COMM_WAITANY || simcall->call_ == SIMCALL_COMM_TESTANY)) {
+ (simcall->call_ == simix::Simcall::COMM_WAITANY || simcall->call_ == simix::Simcall::COMM_TESTANY)) {
// First retrieve the rank of our failing synchro
CommImpl** comms;
size_t count;
- if (simcall->call_ == SIMCALL_COMM_WAITANY) {
+ if (simcall->call_ == simix::Simcall::COMM_WAITANY) {
comms = simcall_comm_waitany__get__comms(simcall);
count = simcall_comm_waitany__get__count(simcall);
} else {
- /* simcall->call_ == SIMCALL_COMM_TESTANY */
+ /* simcall->call_ == simix::Simcall::COMM_TESTANY */
comms = simcall_comm_testany__get__comms(simcall);
count = simcall_comm_testany__get__count(simcall);
}
/** @brief Handle a condition waiting simcall with timeouts */
void simcall_HANDLER_cond_wait_timeout(smx_simcall_t simcall, smx_cond_t cond, smx_mutex_t mutex, double timeout)
{
+ simcall_cond_wait_timeout__set__result(simcall, 0); // default result, will be set to 1 on timeout
cond->wait(mutex, timeout, simcall->issuer_);
}
/* Now transform the cond wait simcall into a mutex lock one */
smx_simcall_t simcall = &proc.simcall_;
MutexImpl* simcall_mutex;
- if (simcall->call_ == SIMCALL_COND_WAIT)
+ if (simcall->call_ == simix::Simcall::COND_WAIT)
simcall_mutex = simcall_cond_wait__get__mutex(simcall);
else
simcall_mutex = simcall_cond_wait_timeout__get__mutex(simcall);
- simcall->call_ = SIMCALL_MUTEX_LOCK;
+ simcall->call_ = simix::Simcall::MUTEX_LOCK;
simcall_mutex->lock(simcall->issuer_);
}
* list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
* simcall */
- if (simcall->call_ == SIMCALL_NONE) // FIXME: maybe a better way to handle this case
+ if (simcall->call_ == simix::Simcall::NONE) // FIXME: maybe a better way to handle this case
continue; // if process handling comm is killed
- if (simcall->call_ == SIMCALL_EXECUTION_WAITANY_FOR) {
+ if (simcall->call_ == simix::Simcall::EXECUTION_WAITANY_FOR) {
simgrid::kernel::activity::ExecImpl** execs = simcall_execution_waitany_for__get__execs(simcall);
size_t count = simcall_execution_waitany_for__get__count(simcall);
}
switch (simcall->call_) {
- case SIMCALL_MUTEX_LOCK:
+ case simix::Simcall::MUTEX_LOCK:
simcall_mutex_lock__get__mutex(simcall)->remove_sleeping_actor(*simcall->issuer_);
break;
- case SIMCALL_COND_WAIT:
+ case simix::Simcall::COND_WAIT:
simcall_cond_wait_timeout__get__cond(simcall)->remove_sleeping_actor(*simcall->issuer_);
break;
- case SIMCALL_COND_WAIT_TIMEOUT:
+ case simix::Simcall::COND_WAIT_TIMEOUT:
simcall_cond_wait_timeout__get__cond(simcall)->remove_sleeping_actor(*simcall->issuer_);
simcall_cond_wait_timeout__set__result(simcall, 1); // signal a timeout
break;
- case SIMCALL_SEM_ACQUIRE:
+ case simix::Simcall::SEM_ACQUIRE:
simcall_sem_acquire_timeout__get__sem(simcall)->remove_sleeping_actor(*simcall->issuer_);
break;
- case SIMCALL_SEM_ACQUIRE_TIMEOUT:
+ case simix::Simcall::SEM_ACQUIRE_TIMEOUT:
simcall_sem_acquire_timeout__get__sem(simcall)->remove_sleeping_actor(*simcall->issuer_);
simcall_sem_acquire_timeout__set__result(simcall, 1); // signal a timeout
break;
namespace actor {
static unsigned long maxpid = 0;
-int get_maxpid()
+unsigned long get_maxpid()
{
return maxpid;
}
context::Context::self()->get_actor()->kill(this);
// start the new actor
- ActorImplPtr actor =
- ActorImpl::create(arg.name, std::move(arg.code), arg.data, arg.host, arg.properties.get(), nullptr);
+ ActorImplPtr actor = ActorImpl::create(arg.name, arg.code, arg.data, arg.host, arg.properties.get(), nullptr);
*actor->on_exit = std::move(*arg.on_exit);
actor->set_kill_time(arg.kill_time);
actor->set_auto_restart(arg.auto_restart);
if (this != simix_global->maestro_) {
XBT_DEBUG("Answer simcall %s (%d) issued by %s (%p)", SIMIX_simcall_name(simcall_.call_), (int)simcall_.call_,
get_cname(), this);
- xbt_assert(simcall_.call_ != SIMCALL_NONE);
- simcall_.call_ = SIMCALL_NONE;
+ xbt_assert(simcall_.call_ != simix::Simcall::NONE);
+ simcall_.call_ = simix::Simcall::NONE;
xbt_assert(not XBT_LOG_ISENABLED(simix_process, xbt_log_priority_debug) ||
std::find(begin(simix_global->actors_to_run), end(simix_global->actors_to_run), this) ==
end(simix_global->actors_to_run),
return simix_global->process_list.size();
}
-// XBT_DEPRECATED_v329
-void* SIMIX_process_self_get_data()
+void* SIMIX_process_self_get_data() // XBT_ATTRIB_DEPRECATED_v329
{
smx_actor_t self = simgrid::kernel::actor::ActorImpl::self();
return self->get_user_data();
}
-// XBT_DEPRECATED_v329
-void SIMIX_process_self_set_data(void* data)
+void SIMIX_process_self_set_data(void* data) // XBT_ATTRIB_DEPRECATED_v329
{
simgrid::kernel::actor::ActorImpl::self()->set_user_data(data);
}
actor->on_exit->emplace_back(fun);
}
-/** @brief Restart a process, starting it again from the beginning. */
-/**
- * @ingroup simix_process_management
- * @brief Creates and runs a new SIMIX process.
- *
- * The structure and the corresponding thread are created and put in the list of ready processes.
- *
- * @param name a name for the process. It is for user-level information and can be nullptr.
- * @param code the main function of the process
- * @param data a pointer to any data one may want to attach to the new object. It is for user-level information and can
- * be nullptr.
- * It can be retrieved with the method ActorImpl::getUserData().
- * @param host where the new agent is executed.
- * @param properties the properties of the process
- */
-smx_actor_t simcall_process_create(const std::string& name, const simgrid::kernel::actor::ActorCode& code, void* data,
- sg_host_t host, std::unordered_map<std::string, std::string>* properties)
-{
- smx_actor_t self = simgrid::kernel::actor::ActorImpl::self();
- return simgrid::kernel::actor::simcall([&name, &code, data, host, properties, self] {
- return simgrid::kernel::actor::ActorImpl::create(name, code, data, host, properties, self).get();
- });
-}
-
void simcall_process_set_data(smx_actor_t process, void* data) // XBT_ATTRIB_DEPRECATED_v329
{
simgrid::kernel::actor::simcall([process, data] { process->set_user_data(data); });
class XBT_PUBLIC ActorImpl : public xbt::PropertyHolder {
s4u::Host* host_ = nullptr; /* the host on which the actor is running */
- // XBT_DEPRECATED_v329
- void* userdata_ = nullptr; /* kept for compatibility, it should be replaced with moddata */
+ void* userdata_ = nullptr; /* XBT_ATTRIB_DEPRECATED_v329 kept for compatibility, should be replaced with moddata */
aid_t pid_ = 0;
aid_t ppid_ = -1;
bool daemon_ = false; /* Daemon actors are automatically killed when the last non-daemon leaves */
// Accessors to private fields
s4u::Host* get_host() { return host_; }
void set_host(s4u::Host* dest);
- // XBT_DEPRECATED_v329
- void* get_user_data() { return userdata_; }
- // XBT_DEPRECATED_v329
- void set_user_data(void* data) { userdata_ = data; }
+ void* get_user_data() { return userdata_; } // XBT_ATTRIB_DEPRECATED_v329
+ void set_user_data(void* data) { userdata_ = data; } // XBT_ATTRIB_DEPRECATED_v329
aid_t get_pid() const { return pid_; }
aid_t get_ppid() const { return ppid_; }
void set_ppid(aid_t ppid) { ppid_ = ppid; }
};
/* Used to keep the list of actors blocked on a synchro */
-typedef boost::intrusive::list<ActorImpl, boost::intrusive::member_hook<ActorImpl, boost::intrusive::list_member_hook<>,
- &ActorImpl::smx_synchro_hook>>
- SynchroList;
+using SynchroList =
+ boost::intrusive::list<ActorImpl, boost::intrusive::member_hook<ActorImpl, boost::intrusive::list_member_hook<>,
+ &ActorImpl::smx_synchro_hook>>;
XBT_PUBLIC void create_maestro(const std::function<void()>& code);
-XBT_PUBLIC int get_maxpid();
+XBT_PUBLIC unsigned long get_maxpid();
} // namespace actor
} // namespace kernel
} // namespace simgrid
extern void (*SMPI_switch_data_segment)(simgrid::s4u::ActorPtr actor);
-XBT_PUBLIC smx_actor_t simcall_process_create(const std::string& name, const simgrid::kernel::actor::ActorCode& code,
- void* data, sg_host_t host,
- std::unordered_map<std::string, std::string>* properties);
-
#endif
/* This allows Java to hijack the context factory (Java induces factories of factory :) */
-typedef ContextFactory* (*ContextFactoryInitializer)();
+using ContextFactoryInitializer = ContextFactory* (*)();
XBT_PUBLIC_DATA ContextFactoryInitializer factory_initializer;
XBT_PRIVATE ContextFactory* thread_factory();
private:
#if BOOST_VERSION < 106100
boost::context::fcontext_t fc_;
- typedef intptr_t arg_type;
+ using arg_type = intptr_t;
#else
boost::context::detail::fcontext_t fc_;
- typedef boost::context::detail::transfer_t arg_type;
+ using arg_type = boost::context::detail::transfer_t;
#endif
XBT_ATTRIB_NORETURN static void wrapper(arg_type arg);
// Raw context routines
-typedef void (*rawctx_entry_point_t)(simgrid::kernel::context::SwappedContext*);
+using rawctx_entry_point_t = void (*)(simgrid::kernel::context::SwappedContext*);
-typedef void* raw_stack_t;
+using raw_stack_t = void*;
extern "C" raw_stack_t raw_makecontext(void* malloced_stack, int stack_size, rawctx_entry_point_t entry_point,
simgrid::kernel::context::SwappedContext* arg);
extern "C" void raw_swapcontext(raw_stack_t* old, raw_stack_t new_context);
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_maxmin);
-simgrid::kernel::lmm::System* simgrid::kernel::lmm::make_new_fair_bottleneck_system(bool selective_update)
-{
- return new simgrid::kernel::lmm::FairBottleneck(selective_update);
-}
-
void simgrid::kernel::lmm::FairBottleneck::bottleneck_solve()
{
if (not modified_)
namespace kernel {
namespace lmm {
-typedef std::vector<int> dyn_light_t;
+using dyn_light_t = std::vector<int>;
int Variable::next_rank_ = 1;
int Constraint::next_rank_ = 1;
-System* make_new_maxmin_system(bool selective_update)
-{
- return new System(selective_update);
-}
-
int Element::get_concurrency() const
{
// Ignore element with weight less than one (e.g. cross-traffic)
XBT_DEBUG("Setting selective_update_active flag to %d", selective_update_active);
if (selective_update)
- modified_set_ = new kernel::resource::Action::ModifiedSet();
+ modified_set_ = std::make_unique<kernel::resource::Action::ModifiedSet>();
}
System::~System()
cnst_free(cnst);
xbt_mallocator_free(variable_mallocator_);
- delete modified_set_;
}
void System::cnst_free(Constraint* cnst)
#include <boost/intrusive/list.hpp>
#include <cmath>
#include <limits>
+#include <memory>
#include <vector>
namespace simgrid {
&Constraint::saturated_constraint_set_hook_>>
saturated_constraint_set;
- resource::Action::ModifiedSet* modified_set_ = nullptr;
+ std::unique_ptr<resource::Action::ModifiedSet> modified_set_ = nullptr;
private:
- typedef std::vector<int> dyn_light_t;
-
+ using dyn_light_t = std::vector<int>;
+
//Data used in lmm::solve
std::vector<ConstraintLight> cnst_light_vec;
dyn_light_t saturated_constraints;
class XBT_PUBLIC FairBottleneck : public System {
public:
- explicit FairBottleneck(bool selective_update) : System(selective_update) {}
+ using System::System;
void solve() final { bottleneck_solve(); }
private:
void bottleneck_solve();
};
-XBT_PUBLIC System* make_new_maxmin_system(bool selective_update);
-XBT_PUBLIC System* make_new_fair_bottleneck_system(bool selective_update);
-
/** @} */
} // namespace lmm
} // namespace kernel
TEST_CASE("kernel::lmm Single constraint shared systems", "[kernel-lmm-shared-single-sys]")
{
- lmm::System* Sys = lmm::make_new_maxmin_system(false);
+ lmm::System Sys(false);
SECTION("Variable penalty")
{
* o rho1 + rho2 = C (because all weights are 1)
*/
- lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 3);
- lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
- lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2);
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 3);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 2);
- Sys->expand(sys_cnst, rho_1, 1);
- Sys->expand(sys_cnst, rho_2, 1);
- Sys->solve();
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.solve();
REQUIRE(double_equals(rho_1->get_value(), 2, sg_maxmin_precision));
REQUIRE(double_equals(rho_2->get_value(), 1, sg_maxmin_precision));
* o so, rho1 = rho2 = 1 (because C is 3)
*/
- lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 3);
- lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
- lmm::Variable* rho_2 = Sys->variable_new(nullptr, 1);
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 3);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
- Sys->expand(sys_cnst, rho_1, 1);
- Sys->expand(sys_cnst, rho_2, 2);
- Sys->solve();
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 2);
+ Sys.solve();
REQUIRE(double_equals(rho_1->get_value(), 1, sg_maxmin_precision));
REQUIRE(double_equals(rho_2->get_value(), 1, sg_maxmin_precision));
* o rho1 + 2*rho2 = C (because consumption weight of rho2 is 2)
*/
- lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 20);
- lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
- lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2);
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 20);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 2);
- Sys->expand(sys_cnst, rho_1, 1);
- Sys->expand(sys_cnst, rho_2, 2);
- Sys->solve();
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 2);
+ Sys.solve();
double rho_1_share = 10;
REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision));
* o 2*rho1 + rho3 = C2 (because consumption weight of rho1 is 2)
*/
- lmm::Constraint* sys_cnst_1 = Sys->constraint_new(nullptr, 20);
- lmm::Constraint* sys_cnst_2 = Sys->constraint_new(nullptr, 60);
+ lmm::Constraint* sys_cnst_1 = Sys.constraint_new(nullptr, 20);
+ lmm::Constraint* sys_cnst_2 = Sys.constraint_new(nullptr, 60);
- lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1, -1, 2);
- lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2, -1, 1);
- lmm::Variable* rho_3 = Sys->variable_new(nullptr, 1, -1, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, -1, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 2, -1, 1);
+ lmm::Variable* rho_3 = Sys.variable_new(nullptr, 1, -1, 1);
// Constraint 1
- Sys->expand(sys_cnst_1, rho_1, 1);
- Sys->expand(sys_cnst_1, rho_2, 2);
+ Sys.expand(sys_cnst_1, rho_1, 1);
+ Sys.expand(sys_cnst_1, rho_2, 2);
// Constraint 2
- Sys->expand(sys_cnst_2, rho_1, 2);
- Sys->expand(sys_cnst_2, rho_3, 1);
- Sys->solve();
+ Sys.expand(sys_cnst_2, rho_1, 2);
+ Sys.expand(sys_cnst_2, rho_3, 1);
+ Sys.solve();
double rho_1_share = 10; // Start by solving the first constraint (results is the same as previous tests)
REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision));
REQUIRE(double_equals(rho_3->get_value(), 60 - 2 * rho_1_share, sg_maxmin_precision));
}
- Sys->variable_free_all();
- delete Sys;
+ Sys.variable_free_all();
}
TEST_CASE("kernel::lmm Single constraint unshared systems", "[kernel-lmm-unshared-single-sys]")
{
- lmm::System* Sys = lmm::make_new_maxmin_system(false);
+ lmm::System Sys(false);
SECTION("Variable penalty")
{
* o rho2 = max_share/2 (because penalty of rho2 is 2)
*/
- lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 10);
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 10);
sys_cnst->unshare(); // FATPIPE
- lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
- lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 2);
- Sys->expand(sys_cnst, rho_1, 1);
- Sys->expand(sys_cnst, rho_2, 1);
- Sys->solve();
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.solve();
REQUIRE(double_equals(rho_1->get_value(), 10, sg_maxmin_precision));
REQUIRE(double_equals(rho_2->get_value(), 10 / 2, sg_maxmin_precision));
* o rho2 = max_share/2 (because penalty of rho2 is 1)
*/
- lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 10);
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 10);
sys_cnst->unshare(); // FATPIPE
- lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
- lmm::Variable* rho_2 = Sys->variable_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
- Sys->expand(sys_cnst, rho_1, 1);
- Sys->expand(sys_cnst, rho_2, 2);
- Sys->solve();
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 2);
+ Sys.solve();
REQUIRE(double_equals(rho_1->get_value(), 5, sg_maxmin_precision));
REQUIRE(double_equals(rho_2->get_value(), 5, sg_maxmin_precision));
* o rho1 <= C and 2*rho2 <= C
*/
- lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 10);
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 10);
sys_cnst->unshare();
- lmm::Variable* sys_var_1 = Sys->variable_new(nullptr, 1);
- lmm::Variable* sys_var_2 = Sys->variable_new(nullptr, 2);
+ lmm::Variable* sys_var_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* sys_var_2 = Sys.variable_new(nullptr, 2);
- Sys->expand(sys_cnst, sys_var_1, 1);
- Sys->expand(sys_cnst, sys_var_2, 2);
- Sys->solve();
+ Sys.expand(sys_cnst, sys_var_1, 1);
+ Sys.expand(sys_cnst, sys_var_2, 2);
+ Sys.solve();
REQUIRE(double_equals(sys_var_1->get_value(), 10, sg_maxmin_precision));
REQUIRE(double_equals(sys_var_2->get_value(), 5, sg_maxmin_precision));
* o Each constraint should satisfy max(a_i * rho_i) <= C_r
*/
- lmm::Constraint* sys_cnst_1 = Sys->constraint_new(nullptr, 10);
- lmm::Constraint* sys_cnst_2 = Sys->constraint_new(nullptr, 60);
+ lmm::Constraint* sys_cnst_1 = Sys.constraint_new(nullptr, 10);
+ lmm::Constraint* sys_cnst_2 = Sys.constraint_new(nullptr, 60);
sys_cnst_1->unshare(); // FATPIPE
sys_cnst_2->unshare();
- lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1, -1, 2);
- lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2, -1, 1);
- lmm::Variable* rho_3 = Sys->variable_new(nullptr, 1, -1, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, -1, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 2, -1, 1);
+ lmm::Variable* rho_3 = Sys.variable_new(nullptr, 1, -1, 1);
// Constraint 1
- Sys->expand(sys_cnst_1, rho_1, 1);
- Sys->expand(sys_cnst_1, rho_2, 2);
+ Sys.expand(sys_cnst_1, rho_1, 1);
+ Sys.expand(sys_cnst_1, rho_2, 2);
// Constraint 2
- Sys->expand(sys_cnst_2, rho_1, 2);
- Sys->expand(sys_cnst_2, rho_3, 1);
- Sys->solve();
+ Sys.expand(sys_cnst_2, rho_1, 2);
+ Sys.expand(sys_cnst_2, rho_3, 1);
+ Sys.solve();
double rho_1_share = 10; // Start by solving the first constraint (results is the same as previous tests)
REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision));
REQUIRE(double_equals(rho_3->get_value(), 60, sg_maxmin_precision));
}
- Sys->variable_free_all();
- delete Sys;
+ Sys.variable_free_all();
}
double read_bw_;
double write_bw_;
lmm::Constraint* constraint_write_; /* Constraint for maximum write bandwidth*/
- lmm::Constraint* constraint_read_; /* Constraint for maximum write bandwidth*/
+ lmm::Constraint* constraint_read_; /* Constraint for maximum read bandwidth*/
public:
DiskImpl(Model* model, const std::string& name, kernel::lmm::System* maxmin_system, double read_bw, double bwrite_bw);
Action::ModifiedSet* Model::get_modified_set() const
{
- return maxmin_system_->modified_set_;
+ return maxmin_system_->modified_set_.get();
}
void Model::set_maxmin_system(lmm::System* system)
{
return (fabs(date_ - e2.date_) < 0.0001) && (fabs(value_ - e2.value_) < 0.0001);
}
-std::ostream& operator<<(std::ostream& out, const DatedValue& e)
-{
- out << e.date_ << " " << e.value_;
- return out;
-}
} // namespace profile
} // namespace kernel
bool operator==(DatedValue const& e2) const;
bool operator!=(DatedValue const& e2) const { return not(*this == e2); }
};
-std::ostream& operator<<(std::ostream& out, const DatedValue& e);
} // namespace profile
} // namespace kernel
void add_event(double date, Event* evt);
private:
- typedef std::pair<double, Event*> Qelt;
+ using Qelt = std::pair<double, Event*>;
std::priority_queue<Qelt, std::vector<Qelt>, std::greater<>> heap_;
};
#include "src/kernel/resource/profile/DatedValue.hpp"
#include "src/kernel/resource/profile/Event.hpp"
#include "src/kernel/resource/profile/FutureEvtSet.hpp"
+#include "src/kernel/resource/profile/StochasticDatedValue.hpp"
#include "src/surf/surf_interface.hpp"
#include <boost/algorithm/string.hpp>
#include <fstream>
+#include <memory>
#include <ostream>
#include <sstream>
#include <unordered_map>
{
/* Add the first fake event storing the time at which the trace begins */
DatedValue val(0, -1);
- event_list.push_back(val);
+ StochasticDatedValue stoval(0, -1);
+ event_list.emplace_back(val);
+ stochastic_event_list.emplace_back(stoval);
}
Profile::~Profile() = default;
fes_ = fes;
fes_->add_event(0.0 /* start time */, event);
+ if (stochastic) {
+ xbt_assert(event->idx < stochastic_event_list.size(), "Your profile should have at least one stochastic event!");
+ futureDV = stochastic_event_list.at(event->idx).get_datedvalue();
+ }
return event;
}
DatedValue Profile::next(Event* event)
{
double event_date = fes_->next_date();
- DatedValue dateVal = event_list.at(event->idx);
-
- if (event->idx < event_list.size() - 1) {
- fes_->add_event(event_date + dateVal.date_, event);
- event->idx++;
- } else if (dateVal.date_ > 0) { /* Last element. Shall we loop? */
- fes_->add_event(event_date + dateVal.date_, event);
- event->idx = 1; /* idx=0 is a placeholder to store when events really start */
- } else { /* If we don't loop, we don't need this event anymore */
- event->free_me = true;
- }
- return dateVal;
+ if (not stochastic) {
+ DatedValue dateVal = event_list.at(event->idx);
+
+ if (event->idx < event_list.size() - 1) {
+ fes_->add_event(event_date + dateVal.date_, event);
+ event->idx++;
+ } else if (dateVal.date_ > 0) { /* Last element. Shall we loop? */
+ fes_->add_event(event_date + dateVal.date_, event);
+ event->idx = 1; /* idx=0 is a placeholder to store when events really start */
+ } else { /* If we don't loop, we don't need this event anymore */
+ event->free_me = true;
+ }
+ return dateVal;
+ } else {
+ DatedValue dateVal = futureDV;
+ if (event->idx < stochastic_event_list.size() - 1) {
+ event->idx++;
+ } else if (stochasticloop) { /* We have reached the last element and we have to loop. */
+ event->idx = 1;
+ } else {
+ event->free_me = true; /* We have reached the last element, but we don't need to loop. */
+ }
+
+ if (not event->free_me) { // In the case there is an element, we draw the next event
+ futureDV = stochastic_event_list.at(event->idx).get_datedvalue();
+ fes_->add_event(event_date + futureDV.date_, event);
+ }
+ return dateVal;
+ }
}
Profile* Profile::from_string(const std::string& name, const std::string& input, double periodicity)
boost::split(list, input, boost::is_any_of("\n\r"));
for (auto val : list) {
simgrid::kernel::profile::DatedValue event;
+ simgrid::kernel::profile::StochasticDatedValue stochevent;
linecount++;
boost::trim(val);
if (val[0] == '#' || val[0] == '\0' || val[0] == '%') // pass comments
continue;
if (sscanf(val.c_str(), "LOOPAFTER %lg\n", &periodicity) == 1)
continue;
+ if (val == "STOCHASTIC LOOP") {
+ profile->stochastic = true;
+ profile->stochasticloop = true;
+ continue;
+ }
+ if (val == "STOCHASTIC") {
+ profile->stochastic = true;
+ continue;
+ }
- XBT_ATTRIB_UNUSED int res = sscanf(val.c_str(), "%lg %lg\n", &event.date_, &event.value_);
- xbt_assert(res == 2, "%s:%d: Syntax error in trace\n%s", name.c_str(), linecount, input.c_str());
+ if (profile->stochastic) {
+ unsigned int i;
+ unsigned int j;
+ std::istringstream iss(val);
+ std::vector<std::string> splittedval((std::istream_iterator<std::string>(iss)),
+ std::istream_iterator<std::string>());
+
+ xbt_assert(splittedval.size() > 0, "Invalid profile line");
+
+ if (splittedval[0] == "DET") {
+ stochevent.date_law = Distribution::DET;
+ i = 2;
+ } else if (splittedval[0] == "NORM" || splittedval[0] == "NORMAL" || splittedval[0] == "GAUSS" ||
+ splittedval[0] == "GAUSSIAN") {
+ stochevent.date_law = Distribution::NORM;
+ i = 3;
+ } else if (splittedval[0] == "EXP" || splittedval[0] == "EXPONENTIAL") {
+ stochevent.date_law = Distribution::EXP;
+ i = 2;
+ } else if (splittedval[0] == "UNIF" || splittedval[0] == "UNIFORM") {
+ stochevent.date_law = Distribution::UNIF;
+ i = 3;
+ } else {
+ xbt_die("Unknown law %s", splittedval[0].c_str());
+ }
+
+ xbt_assert(splittedval.size() > i, "Invalid profile line");
+ if (i == 2) {
+ stochevent.date_params = {std::stod(splittedval[1])};
+ } else if (i == 3) {
+ stochevent.date_params = {std::stod(splittedval[1]), std::stod(splittedval[2])};
+ }
+
+ if (splittedval[i] == "DET") {
+ stochevent.value_law = Distribution::DET;
+ j = 1;
+ } else if (splittedval[i] == "NORM" || splittedval[i] == "NORMAL" || splittedval[i] == "GAUSS" ||
+ splittedval[i] == "GAUSSIAN") {
+ stochevent.value_law = Distribution::NORM;
+ j = 2;
+ } else if (splittedval[i] == "EXP" || splittedval[i] == "EXPONENTIAL") {
+ stochevent.value_law = Distribution::EXP;
+ j = 1;
+ } else if (splittedval[i] == "UNIF" || splittedval[i] == "UNIFORM") {
+ stochevent.value_law = Distribution::UNIF;
+ j = 2;
+ } else {
+ xbt_die("Unknown law %s", splittedval[i].c_str());
+ }
+
+ xbt_assert(splittedval.size() > i + j, "Invalid profile line");
+ if (j == 1) {
+ stochevent.value_params = {std::stod(splittedval[i + 1])};
+ } else if (j == 2) {
+ stochevent.value_params = {std::stod(splittedval[i + 1]), std::stod(splittedval[i + 2])};
+ }
+
+ profile->stochastic_event_list.emplace_back(stochevent);
+ } else {
+ XBT_ATTRIB_UNUSED int res = sscanf(val.c_str(), "%lg %lg\n", &event.date_, &event.value_);
+ xbt_assert(res == 2, "%s:%d: Syntax error in trace\n%s", name.c_str(), linecount, input.c_str());
- xbt_assert(last_event->date_ <= event.date_,
- "%s:%d: Invalid trace: Events must be sorted, but time %g > time %g.\n%s", name.c_str(), linecount,
- last_event->date_, event.date_, input.c_str());
- last_event->date_ = event.date_ - last_event->date_;
+ xbt_assert(last_event->date_ <= event.date_,
+ "%s:%d: Invalid trace: Events must be sorted, but time %g > time %g.\n%s", name.c_str(), linecount,
+ last_event->date_, event.date_, input.c_str());
+ last_event->date_ = event.date_ - last_event->date_;
- profile->event_list.push_back(event);
- last_event = &(profile->event_list.back());
+ profile->event_list.emplace_back(event);
+ last_event = &(profile->event_list.back());
+ }
}
if (last_event) {
if (periodicity > 0) {
xbt_assert(not path.empty(), "Cannot parse a trace from an empty filename");
xbt_assert(trace_list.find(path) == trace_list.end(), "Refusing to define trace %s twice", path.c_str());
- const std::ifstream* f = surf_ifsopen(path);
+ auto f = std::unique_ptr<std::ifstream>(surf_ifsopen(path));
xbt_assert(not f->fail(), "Cannot open file '%s' (path=%s)", path.c_str(), (boost::join(surf_path, ":")).c_str());
std::stringstream buffer;
buffer << f->rdbuf();
- delete f;
return Profile::from_string(path, buffer.str(), -1);
}
#include "simgrid/forward.h"
#include "src/kernel/resource/profile/DatedValue.hpp"
#include "src/kernel/resource/profile/FutureEvtSet.hpp"
+#include "src/kernel/resource/profile/StochasticDatedValue.hpp"
#include <queue>
#include <vector>
static Profile* from_string(const std::string& name, const std::string& input, double periodicity);
// private:
std::vector<DatedValue> event_list;
+ std::vector<StochasticDatedValue> stochastic_event_list;
private:
- FutureEvtSet* fes_ = nullptr;
+ FutureEvtSet* fes_ = nullptr;
+ bool stochastic = false;
+ bool stochasticloop = false;
+ DatedValue futureDV;
};
} // namespace profile
#include "src/kernel/resource/profile/DatedValue.hpp"
#include "src/kernel/resource/profile/Event.hpp"
#include "src/kernel/resource/profile/Profile.hpp"
+#include "src/kernel/resource/profile/StochasticDatedValue.hpp"
#include "src/surf/surf_interface.hpp"
#include "xbt/log.h"
#include "xbt/misc.h"
+#include "xbt/random.hpp"
#include <cmath>
XBT_LOG_NEW_DEFAULT_CATEGORY(unit, "Unit tests of the Trace Manager");
-double thedate;
class MockedResource : public simgrid::kernel::resource::Resource {
public:
+ static double the_date;
+
explicit MockedResource() : simgrid::kernel::resource::Resource(nullptr, "fake", nullptr) {}
void apply_event(simgrid::kernel::profile::Event* event, double value) override
{
- XBT_VERB("t=%.1f: Change value to %lg (idx: %u)", thedate, value, event->idx);
+ XBT_VERB("t=%.1f: Change value to %lg (idx: %u)", the_date, value, event->idx);
tmgr_trace_event_unref(&event);
}
bool is_used() const override { return true; }
};
+double MockedResource::the_date;
+
static std::vector<simgrid::kernel::profile::DatedValue> trace2vector(const char* str)
{
std::vector<simgrid::kernel::profile::DatedValue> res;
simgrid::kernel::profile::Event* insertedIt = trace->schedule(&fes, &daResource);
while (fes.next_date() <= 20.0 && fes.next_date() >= 0) {
- thedate = fes.next_date();
+ MockedResource::the_date = fes.next_date();
double value;
simgrid::kernel::resource::Resource* resource;
- simgrid::kernel::profile::Event* it = fes.pop_leq(thedate, &value, &resource);
+ simgrid::kernel::profile::Event* it = fes.pop_leq(MockedResource::the_date, &value, &resource);
if (it == nullptr)
continue;
REQUIRE(it == insertedIt); // Check that we find what we've put
if (value >= 0) {
- res.emplace_back(thedate, value);
+ res.emplace_back(MockedResource::the_date, value);
} else {
- XBT_DEBUG("%.1f: ignore an event (idx: %u)\n", thedate, it->idx);
+ XBT_DEBUG("%.1f: ignore an event (idx: %u)\n", MockedResource::the_date, it->idx);
}
resource->apply_event(it, value);
}
return res;
}
+static std::vector<simgrid::kernel::profile::StochasticDatedValue> trace2selist(const char* str)
+{
+ const simgrid::kernel::profile::Profile* trace = simgrid::kernel::profile::Profile::from_string("TheName", str, 0);
+ std::vector<simgrid::kernel::profile::StochasticDatedValue> stocevlist = trace->stochastic_event_list;
+ tmgr_finalize();
+ return stocevlist;
+}
+
TEST_CASE("kernel::profile: Resource profiles, defining the external load", "kernel::profile")
{
SECTION("No event, no loop")
REQUIRE(want == got);
}
+
+ SECTION("One stochastic event (parsing)")
+ {
+ using simgrid::kernel::profile::Distribution;
+ std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
+ "DET 0 UNIF 10 20");
+
+ std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
+ want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(0, -1)); // The initial fake event
+ want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::DET, {0},
+ Distribution::UNIF, {10, 20}));
+
+ REQUIRE(want == got);
+ }
+
+ SECTION("Several stochastic events (all possible parsing forms)")
+ {
+ using simgrid::kernel::profile::Distribution;
+ std::vector<simgrid::kernel::profile::StochasticDatedValue> got = trace2selist("STOCHASTIC\n"
+ "DET 0 DET 4\n"
+ "NORMAL 25 10 DET 3\n"
+ "UNIF 10 20 NORMAL 25 10\n"
+ "DET 5 UNIF 5 25");
+
+ std::vector<simgrid::kernel::profile::StochasticDatedValue> want;
+ want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(0, -1));
+ want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::DET, {0},
+ Distribution::DET, {4}));
+ want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::NORM, {25, 10},
+ Distribution::DET, {3}));
+ want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::UNIF, {10, 20},
+ Distribution::NORM, {25, 10}));
+ want.emplace_back(simgrid::kernel::profile::StochasticDatedValue(Distribution::DET, {5},
+ Distribution::UNIF, {5, 25}));
+
+ REQUIRE(want == got);
+ }
+
+ SECTION("Two stochastic events (drawing each distribution)")
+ {
+ simgrid::xbt::random::set_implem_xbt();
+ simgrid::xbt::random::set_mersenne_seed(12345);
+ std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC\n"
+ "DET 0 UNIF 10 20\n"
+ "EXP 0.05 NORMAL 15 5");
+
+ std::vector<simgrid::kernel::profile::DatedValue> want;
+ // The following values were drawn using the XBT_RNG_xbt method /outside/ the testcase.
+ want.emplace_back(simgrid::kernel::profile::DatedValue(0, 19.29616086867082813683));
+ want.emplace_back(simgrid::kernel::profile::DatedValue(2.32719992449416279712, 20.16807234800742065772));
+
+ REQUIRE(want == got);
+ }
+
+ SECTION("Two stochastic events, with a loop")
+ {
+ simgrid::xbt::random::set_implem_xbt();
+ simgrid::xbt::random::set_mersenne_seed(12345);
+ std::vector<simgrid::kernel::profile::DatedValue> got = trace2vector("STOCHASTIC LOOP\n"
+ "DET 0 UNIF 10 20\n"
+ "EXP 0.05 NORMAL 15 5\n"
+ "UNIF 1 2 DET 0");
+
+ // In this case, the main use of the last stochastic event is to set when the first event takes place.
+
+ std::vector<simgrid::kernel::profile::DatedValue> want;
+ want.emplace_back(simgrid::kernel::profile::DatedValue(0, 19.29616086867082813683));
+ want.emplace_back(simgrid::kernel::profile::DatedValue(2.32719992449416279712, 20.16807234800742065772));
+ want.emplace_back(simgrid::kernel::profile::DatedValue(3.51111873684917075167, 0));
+ want.emplace_back(simgrid::kernel::profile::DatedValue(3.51111873684917075167, 10.39759496468994726115));
+
+ REQUIRE(want == got);
+ }
}
--- /dev/null
+/* Copyright (c) 2004-2020. 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 "src/kernel/resource/profile/StochasticDatedValue.hpp"
+#include "xbt.h"
+#include "xbt/random.hpp"
+#include <math.h>
+
+namespace simgrid {
+namespace kernel {
+namespace profile {
+
+double StochasticDatedValue::draw(Distribution law, std::vector<double> params)
+{
+ switch (law) {
+ case Distribution::DET:
+ return params[0];
+ case Distribution::EXP:
+ return simgrid::xbt::random::exponential(params[0]);
+ case Distribution::UNIF:
+ return simgrid::xbt::random::uniform_real(params[0], params[1]);
+ case Distribution::NORM:
+ return simgrid::xbt::random::normal(params[0], params[1]);
+ default:
+ xbt_die("Unimplemented distribution");
+ }
+}
+
+double StochasticDatedValue::get_value() const
+{
+ return draw(value_law, value_params);
+}
+
+double StochasticDatedValue::get_date() const
+{
+ return draw(date_law, date_params);
+}
+
+DatedValue StochasticDatedValue::get_datedvalue() const
+{
+ DatedValue event;
+ event.date_ = get_date();
+ event.value_ = get_value();
+ return event;
+}
+
+bool StochasticDatedValue::operator==(StochasticDatedValue const& e2) const
+{
+ return (e2.date_law == date_law) && (e2.value_law == value_law) && (e2.value_params == value_params) &&
+ (e2.date_params == date_params);
+}
+
+} // namespace profile
+} // namespace kernel
+} // namespace simgrid
--- /dev/null
+/* Copyright (c) 2004-2020. The SimGrid Team. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef SIMGRID_KERNEL_PROFILE_STOCHASTICDATEDVALUE
+#define SIMGRID_KERNEL_PROFILE_STOCHASTICDATEDVALUE
+
+#include "simgrid/forward.h"
+#include "src/kernel/resource/profile/DatedValue.hpp"
+#include <vector>
+
+namespace simgrid {
+namespace kernel {
+namespace profile {
+
+enum class Distribution { EXP, NORM, UNIF, DET };
+
+class XBT_PUBLIC StochasticDatedValue {
+public:
+ Distribution date_law = Distribution::DET;
+ std::vector<double> date_params;
+ Distribution value_law = Distribution::DET;
+ std::vector<double> value_params;
+ DatedValue get_datedvalue() const;
+ double get_date() const;
+ double get_value() const;
+ explicit StochasticDatedValue() = default;
+ explicit StochasticDatedValue(double d, double v) : date_params({d}), value_params({v}) {}
+ explicit StochasticDatedValue(Distribution dl, const std::vector<double>& dp, Distribution vl,
+ const std::vector<double>& vp)
+ : date_law(dl), date_params(dp), value_law(vl), value_params(vp)
+ {
+ }
+ bool operator==(StochasticDatedValue const& e2) const;
+
+private:
+ static double draw(Distribution law, std::vector<double> params);
+};
+
+} // namespace profile
+} // namespace kernel
+} // namespace simgrid
+
+#endif
int nr_nodes = xbt_dynar_length(nodes);
std::vector<double> cost_arr(nr_nodes); /* link cost from src to other hosts */
pred_arr.resize(nr_nodes); /* predecessors in path from src */
- typedef std::pair<double, int> Qelt;
+ using Qelt = std::pair<double, int>;
std::priority_queue<Qelt, std::vector<Qelt>, std::greater<>> pqueue;
/* initialize */
std::vector<std::string> tmp;
boost::split(parameters, cluster->topo_parameters, boost::is_any_of(";"));
- if (parameters.size() != 4 || parameters.empty()) {
+ if (parameters.size() != 4) {
surf_parse_error(
"Dragonfly are defined by the number of groups, chassis per groups, blades per chassis, nodes per blade");
}
linkTemplate.bandwidths.push_back(this->bw_ * numlinks);
linkTemplate.latency = this->lat_;
linkTemplate.policy = this->sharing_policy_;
- linkTemplate.id = std::move(id);
+ linkTemplate.id = id;
sg_platf_new_link(&linkTemplate);
XBT_DEBUG("Generating link %s", linkTemplate.id.c_str());
resource::LinkImpl* link;
FloydZone::~FloydZone()
{
- if (link_table_ == nullptr) // Dealing with a parse error in the file?
- return;
- unsigned int table_size = get_table_size();
/* Delete link_table */
- for (unsigned int i = 0; i < table_size; i++)
- for (unsigned int j = 0; j < table_size; j++)
- delete TO_FLOYD_LINK(i, j);
- delete[] link_table_;
+ for (auto const* link : link_table_)
+ delete link;
+}
- delete[] predecessor_table_;
- delete[] cost_table_;
+void FloydZone::init_tables(unsigned int table_size)
+{
+ if (link_table_.empty()) {
+ /* Create and initialize Cost, Predecessor and Link tables */
+ cost_table_.resize(table_size * table_size, DBL_MAX); /* link cost from host to host */
+ predecessor_table_.resize(table_size * table_size, -1); /* predecessor host numbers */
+ link_table_.resize(table_size * table_size, nullptr); /* actual link between src and dst */
+ }
}
void FloydZone::get_local_route(NetPoint* src, NetPoint* dst, RouteCreationArgs* route, double* lat)
{
/* set the size of table routing */
unsigned int table_size = get_table_size();
+ init_tables(table_size);
add_route_check_params(src, dst, gw_src, gw_dst, link_list, symmetrical);
- if (not link_table_) {
- /* Create Cost, Predecessor and Link tables */
- cost_table_ = new double[table_size * table_size]; /* link cost from host to host */
- predecessor_table_ = new int[table_size * table_size]; /* predecessor host numbers */
- link_table_ = new RouteCreationArgs*[table_size * table_size]; /* actual link between src and dst */
-
- /* Initialize costs and predecessors */
- for (unsigned int i = 0; i < table_size; i++)
- for (unsigned int j = 0; j < table_size; j++) {
- TO_FLOYD_COST(i, j) = DBL_MAX;
- TO_FLOYD_PRED(i, j) = -1;
- TO_FLOYD_LINK(i, j) = nullptr;
- }
- }
-
/* Check that the route does not already exist */
- if (gw_dst) // netzone route (to adapt the error message, if any)
+ if (gw_dst && gw_src) // netzone route (to adapt the error message, if any)
xbt_assert(nullptr == TO_FLOYD_LINK(src->id(), dst->id()),
"The route between %s@%s and %s@%s already exists (Rq: routes are symmetrical by default).",
src->get_cname(), gw_src->get_cname(), dst->get_cname(), gw_dst->get_cname());
TO_FLOYD_COST(src->id(), dst->id()) = (TO_FLOYD_LINK(src->id(), dst->id()))->link_list.size();
if (symmetrical) {
- if (gw_dst) // netzone route (to adapt the error message, if any)
+ if (gw_dst && gw_src) // netzone route (to adapt the error message, if any)
xbt_assert(
nullptr == TO_FLOYD_LINK(dst->id(), src->id()),
"The route between %s@%s and %s@%s already exists. You should not declare the reverse path as symmetrical.",
{
/* set the size of table routing */
unsigned int table_size = get_table_size();
-
- if (not link_table_) {
- /* Create Cost, Predecessor and Link tables */
- cost_table_ = new double[table_size * table_size]; /* link cost from host to host */
- predecessor_table_ = new int[table_size * table_size]; /* predecessor host numbers */
- link_table_ = new RouteCreationArgs*[table_size * table_size]; /* actual link between src and dst */
-
- /* Initialize costs and predecessors */
- for (unsigned int i = 0; i < table_size; i++)
- for (unsigned int j = 0; j < table_size; j++) {
- TO_FLOYD_COST(i, j) = DBL_MAX;
- TO_FLOYD_PRED(i, j) = -1;
- TO_FLOYD_LINK(i, j) = nullptr;
- }
- }
+ init_tables(table_size);
/* Add the loopback if needed */
if (network_model_->loopback_ && hierarchy_ == RoutingMode::base) {
unsigned int table_size = get_table_size();
/* Create table if needed */
- if (not routing_table_)
- routing_table_ = new RouteCreationArgs*[table_size * table_size]();
+ if (routing_table_.empty())
+ routing_table_.resize(table_size * table_size, nullptr);
/* Add the loopback if needed */
if (network_model_->loopback_ && hierarchy_ == RoutingMode::base) {
FullZone::~FullZone()
{
- if (routing_table_) {
- unsigned int table_size = get_table_size();
- /* Delete routing table */
- for (unsigned int i = 0; i < table_size; i++)
- for (unsigned int j = 0; j < table_size; j++)
- delete TO_ROUTE_FULL(i, j);
- delete[] routing_table_;
- }
+ /* Delete routing table */
+ for (auto const* route : routing_table_)
+ delete route;
}
void FullZone::get_local_route(NetPoint* src, NetPoint* dst, RouteCreationArgs* res, double* lat)
unsigned int table_size = get_table_size();
- if (not routing_table_)
- routing_table_ = new RouteCreationArgs*[table_size * table_size]();
+ if (routing_table_.empty())
+ routing_table_.resize(table_size * table_size, nullptr);
/* Check that the route does not already exist */
- if (gw_dst) // inter-zone route (to adapt the error message, if any)
+ if (gw_dst && gw_src) // inter-zone route (to adapt the error message, if any)
xbt_assert(nullptr == TO_ROUTE_FULL(src->id(), dst->id()),
"The route between %s@%s and %s@%s already exists (Rq: routes are symmetrical by default).",
src->get_cname(), gw_src->get_cname(), dst->get_cname(), gw_dst->get_cname());
/* (3) Search for a bypass making the path up to the ancestor useless */
const BypassRoute* bypassedRoute = nullptr;
std::pair<kernel::routing::NetPoint*, kernel::routing::NetPoint*> key;
- for (int max = 0; max <= max_index; max++) {
- for (int i = 0; i < max; i++) {
+ for (int max = 0; max <= max_index && not bypassedRoute; max++) {
+ for (int i = 0; i < max && not bypassedRoute; i++) {
if (i <= max_index_src && max <= max_index_dst) {
key = {path_src.at(i)->netpoint_, path_dst.at(max)->netpoint_};
auto bpr = bypass_routes_.find(key);
if (bpr != bypass_routes_.end()) {
bypassedRoute = bpr->second;
- break;
}
}
- if (max <= max_index_src && i <= max_index_dst) {
+ if (not bypassedRoute && max <= max_index_src && i <= max_index_dst) {
key = {path_src.at(max)->netpoint_, path_dst.at(i)->netpoint_};
auto bpr = bypass_routes_.find(key);
if (bpr != bypass_routes_.end()) {
bypassedRoute = bpr->second;
- break;
}
}
}
- if (bypassedRoute)
- break;
-
- if (max <= max_index_src && max <= max_index_dst) {
+ if (not bypassedRoute && max <= max_index_src && max <= max_index_dst) {
key = {path_src.at(max)->netpoint_, path_dst.at(max)->netpoint_};
auto bpr = bypass_routes_.find(key);
if (bpr != bypass_routes_.end()) {
bypassedRoute = bpr->second;
- break;
}
}
}
if (my_src == my_dst)
continue;
- auto* route = new RouteCreationArgs();
+ RouteCreationArgs route;
- get_local_route(my_src, my_dst, route, nullptr);
+ get_local_route(my_src, my_dst, &route, nullptr);
XBT_DEBUG("get_route_and_latency %s -> %s", my_src->get_cname(), my_dst->get_cname());
const char *previous_name;
const char *current_name;
- if (route->gw_src) {
- previous = new_xbt_graph_node(graph, route->gw_src->get_cname(), nodes);
- previous_name = route->gw_src->get_cname();
+ if (route.gw_src) {
+ previous = new_xbt_graph_node(graph, route.gw_src->get_cname(), nodes);
+ previous_name = route.gw_src->get_cname();
} else {
previous = new_xbt_graph_node(graph, my_src->get_cname(), nodes);
previous_name = my_src->get_cname();
}
- for (auto const& link : route->link_list) {
+ for (auto const& link : route.link_list) {
const char* link_name = link->get_cname();
current = new_xbt_graph_node(graph, link_name, nodes);
current_name = link_name;
previous_name = current_name;
}
- if (route->gw_dst) {
- current = new_xbt_graph_node(graph, route->gw_dst->get_cname(), nodes);
- current_name = route->gw_dst->get_cname();
+ if (route.gw_dst) {
+ current = new_xbt_graph_node(graph, route.gw_dst->get_cname(), nodes);
+ current_name = route.gw_dst->get_cname();
} else {
current = new_xbt_graph_node(graph, my_dst->get_cname(), nodes);
current_name = my_dst->get_cname();
}
new_xbt_graph_edge(graph, previous, current, edges);
XBT_DEBUG(" %s -> %s", previous_name, current_name);
-
- delete route;
}
}
}
* both arrays, we can easily assess whether we need to route into this dimension or not.
*/
const unsigned int dsize = dimensions_.size();
- auto* myCoords = new unsigned int[dsize];
- auto* targetCoords = new unsigned int[dsize];
+ std::vector<unsigned int> myCoords(dsize);
+ std::vector<unsigned int> targetCoords(dsize);
unsigned int dim_size_product = 1;
for (unsigned i = 0; i < dsize; i++) {
unsigned cur_dim_size = dimensions_[i];
current_node = next_node;
}
- delete[] myCoords;
- delete[] targetCoords;
}
} // namespace routing
} // namespace kernel
#include "xbt/automaton.hpp"
#include "xbt/system_error.hpp"
+#include <array>
#include <sys/ptrace.h>
#include <sys/wait.h>
checker_side_.start([](evutil_socket_t sig, short events, void* arg) {
auto mc = static_cast<simgrid::mc::ModelChecker*>(arg);
if (events == EV_READ) {
- char buffer[MC_MESSAGE_LENGTH];
- ssize_t size = mc->checker_side_.get_channel().receive(buffer, sizeof(buffer), false);
+ std::array<char, MC_MESSAGE_LENGTH> buffer;
+ ssize_t size = mc->checker_side_.get_channel().receive(buffer.data(), buffer.size(), false);
if (size == -1 && errno != EAGAIN)
throw simgrid::xbt::errno_error();
- if (not mc->handle_message(buffer, size))
+ if (not mc->handle_message(buffer.data(), size))
mc->checker_side_.break_loop();
} else if (events == EV_SIGNAL) {
if (sig == SIGCHLD)
#endif
}
-static const std::pair<const char*, const char*> ignored_local_variables[] = {
- std::pair<const char*, const char*>{ "e", "*" },
- std::pair<const char*, const char*>{ "_log_ev", "*" },
+static constexpr auto ignored_local_variables = {
+ std::make_pair("e", "*"),
+ std::make_pair("_log_ev", "*"),
- /* Ignore local variable about time used for tracing */
- std::pair<const char*, const char*>{ "start_time", "*" },
+ /* Ignore local variable about time used for tracing */
+ std::make_pair("start_time", "*"),
};
void ModelChecker::setup_ignore()
{
const RemoteSimulation& process = this->get_remote_simulation();
- for (std::pair<const char*, const char*> const& var :
- ignored_local_variables)
+ for (auto const& var : ignored_local_variables)
process.ignore_local_variable(var.first, var.second);
/* Static variable used for tracing */
void ModelChecker::resume(RemoteSimulation& process)
{
- int res = checker_side_.get_channel().send(MC_MESSAGE_CONTINUE);
+ int res = checker_side_.get_channel().send(MessageType::CONTINUE);
if (res)
throw xbt::errno_error();
process.clear_cache();
memcpy(&base_message, buffer, sizeof(base_message));
switch(base_message.type) {
- case MC_MESSAGE_IGNORE_HEAP:
- {
- s_mc_message_ignore_heap_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
-
- IgnoredHeapRegion region;
- region.block = message.block;
- region.fragment = message.fragment;
- region.address = message.address;
- region.size = message.size;
- get_remote_simulation().ignore_heap(region);
- break;
+ case MessageType::IGNORE_HEAP: {
+ s_mc_message_ignore_heap_t message;
+ xbt_assert(size == sizeof(message), "Broken message");
+ memcpy(&message, buffer, sizeof(message));
+
+ IgnoredHeapRegion region;
+ region.block = message.block;
+ region.fragment = message.fragment;
+ region.address = message.address;
+ region.size = message.size;
+ get_remote_simulation().ignore_heap(region);
+ break;
}
- case MC_MESSAGE_UNIGNORE_HEAP:
- {
- s_mc_message_ignore_memory_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
- get_remote_simulation().unignore_heap((void*)(std::uintptr_t)message.addr, message.size);
- break;
+ case MessageType::UNIGNORE_HEAP: {
+ s_mc_message_ignore_memory_t message;
+ xbt_assert(size == sizeof(message), "Broken message");
+ memcpy(&message, buffer, sizeof(message));
+ get_remote_simulation().unignore_heap((void*)(std::uintptr_t)message.addr, message.size);
+ break;
}
- case MC_MESSAGE_IGNORE_MEMORY:
- {
- s_mc_message_ignore_memory_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
- this->get_remote_simulation().ignore_region(message.addr, message.size);
- break;
+ case MessageType::IGNORE_MEMORY: {
+ s_mc_message_ignore_memory_t message;
+ xbt_assert(size == sizeof(message), "Broken message");
+ memcpy(&message, buffer, sizeof(message));
+ this->get_remote_simulation().ignore_region(message.addr, message.size);
+ break;
}
- case MC_MESSAGE_STACK_REGION:
- {
- s_mc_message_stack_region_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
- this->get_remote_simulation().stack_areas().push_back(message.stack_region);
+ case MessageType::STACK_REGION: {
+ s_mc_message_stack_region_t message;
+ xbt_assert(size == sizeof(message), "Broken message");
+ memcpy(&message, buffer, sizeof(message));
+ this->get_remote_simulation().stack_areas().push_back(message.stack_region);
+ } break;
+
+ case MessageType::REGISTER_SYMBOL: {
+ s_mc_message_register_symbol_t message;
+ xbt_assert(size == sizeof(message), "Broken message");
+ memcpy(&message, buffer, sizeof(message));
+ xbt_assert(not message.callback, "Support for client-side function proposition is not implemented.");
+ XBT_DEBUG("Received symbol: %s", message.name.data());
+
+ if (property_automaton == nullptr)
+ property_automaton = xbt_automaton_new();
+
+ const RemoteSimulation* process = &this->get_remote_simulation();
+ RemotePtr<int> address = remote((int*)message.data);
+ xbt::add_proposition(property_automaton, message.name.data(),
+ [process, address]() { return process->read(address); });
+
+ break;
}
- break;
- case MC_MESSAGE_REGISTER_SYMBOL:
- {
- s_mc_message_register_symbol_t message;
- xbt_assert(size == sizeof(message), "Broken message");
- memcpy(&message, buffer, sizeof(message));
- xbt_assert(not message.callback, "Support for client-side function proposition is not implemented.");
- XBT_DEBUG("Received symbol: %s", message.name);
+ case MessageType::WAITING:
+ return false;
- if (property_automaton == nullptr)
- property_automaton = xbt_automaton_new();
+ case MessageType::ASSERTION_FAILED:
+ MC_report_assertion_error();
+ this->exit(SIMGRID_MC_EXIT_SAFETY);
- RemoteSimulation* process = &this->get_remote_simulation();
- RemotePtr<int> address = remote((int*)message.data);
- xbt::add_proposition(property_automaton, message.name, [process, address]() { return process->read(address); });
-
- break;
- }
-
- case MC_MESSAGE_WAITING:
- return false;
-
- case MC_MESSAGE_ASSERTION_FAILED:
- MC_report_assertion_error();
- this->exit(SIMGRID_MC_EXIT_SAFETY);
-
- default:
- xbt_die("Unexpected message from model-checked application");
+ default:
+ xbt_die("Unexpected message from model-checked application");
}
return true;
}
{
s_mc_message_simcall_handle_t m;
memset(&m, 0, sizeof(m));
- m.type = MC_MESSAGE_SIMCALL_HANDLE;
+ m.type = MessageType::SIMCALL_HANDLE;
m.pid = transition.pid_;
m.value = transition.argument_;
checker_side_.get_channel().send(m);
bool ModelChecker::checkDeadlock()
{
- int res = checker_side_.get_channel().send(MC_MESSAGE_DEADLOCK_CHECK);
+ int res = checker_side_.get_channel().send(MessageType::DEADLOCK_CHECK);
xbt_assert(res == 0, "Could not check deadlock state");
s_mc_message_int_t message;
ssize_t s = checker_side_.get_channel().receive(message);
xbt_assert(s != -1, "Could not receive message");
- xbt_assert(s == sizeof(message) && message.type == MC_MESSAGE_DEADLOCK_CHECK_REPLY,
+ xbt_assert(s == sizeof(message) && message.type == MessageType::DEADLOCK_CHECK_REPLY,
"Received unexpected message %s (%i, size=%i) "
- "expected MC_MESSAGE_DEADLOCK_CHECK_REPLY (%i, size=%i)",
- MC_message_type_name(message.type), (int)message.type, (int)s, (int)MC_MESSAGE_DEADLOCK_CHECK_REPLY,
+ "expected MessageType::DEADLOCK_CHECK_REPLY (%i, size=%i)",
+ MC_message_type_name(message.type), (int)message.type, (int)s, (int)MessageType::DEADLOCK_CHECK_REPLY,
(int)sizeof(message));
return message.value != 0;
}
#include "xbt/log.h"
#include "xbt/system_error.hpp"
+#include <array>
#include <memory>
+#include <string>
#include <fcntl.h>
#ifdef __linux__
// modifying its .got.plt during snapshot.
setenv("LC_BIND_NOW", "1", 1);
- char buffer[64];
- int res = std::snprintf(buffer, sizeof(buffer), "%i", socket);
- xbt_assert((size_t)res < sizeof(buffer) && res != -1);
- setenv(MC_ENV_SOCKET_FD, buffer, 1);
+ setenv(MC_ENV_SOCKET_FD, std::to_string(socket).c_str(), 1);
code();
}
bool Session::actor_is_enabled(aid_t pid) const
{
- s_mc_message_actor_enabled_t msg{MC_MESSAGE_ACTOR_ENABLED, pid};
+ s_mc_message_actor_enabled_t msg{simgrid::mc::MessageType::ACTOR_ENABLED, pid};
model_checker_->channel().send(msg);
- char buff[MC_MESSAGE_LENGTH];
- ssize_t received = model_checker_->channel().receive(buff, MC_MESSAGE_LENGTH, true);
+ std::array<char, MC_MESSAGE_LENGTH> buff;
+ ssize_t received = model_checker_->channel().receive(buff.data(), buff.size(), true);
xbt_assert(received == sizeof(s_mc_message_int_t), "Unexpected size in answer to ACTOR_ENABLED");
- return ((s_mc_message_int_t*)buff)->value;
+ return ((s_mc_message_int_t*)buff.data())->value;
}
simgrid::mc::Session* session;
#include <sys/wait.h>
#include <memory>
#include <boost/range/algorithm.hpp>
+#include "src/mc/mc_api.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_VisitedState, mc, "Logging specific to state equality detection mechanisms");
+using mcapi = simgrid::mc::mc_api;
+
namespace simgrid {
namespace mc {
/** @brief Save the current state */
VisitedState::VisitedState(unsigned long state_number) : num(state_number)
-{
- simgrid::mc::RemoteSimulation* process = &(mc_model_checker->get_remote_simulation());
- this->heap_bytes_used = mmalloc_get_bytes_used_remote(
- process->get_heap()->heaplimit,
- process->get_malloc_info());
-
- this->actors_count = mc_model_checker->get_remote_simulation().actors().size();
-
+{
+ this->heap_bytes_used = mcapi::get().get_remote_heap_bytes();
+ this->actors_count = mcapi::get().get_actors_size();
this->system_state = std::make_shared<simgrid::mc::Snapshot>(state_number);
}
new_state->num, graph_state->num_);
auto range =
- boost::range::equal_range(states_, new_state.get(), simgrid::mc::DerefAndCompareByActorsCountAndUsedHeap());
+ boost::range::equal_range(states_, new_state.get(), mcapi::get().compare_pair());
if (compare_snapshots)
for (auto i = range.first; i != range.second; ++i) {
auto& visited_state = *i;
- if (snapshot_equal(visited_state->system_state.get(), new_state->system_state.get())) {
+ if (mcapi::get().snapshot_equal(visited_state->system_state.get(), new_state->system_state.get())) {
// The state has been visited:
std::unique_ptr<simgrid::mc::VisitedState> old_state =
+++ /dev/null
-/* Copyright (c) 2016-2020. 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 "src/mc/checker/Checker.hpp"
-#include "src/mc/ModelChecker.hpp"
-#include "xbt/asserts.h"
-
-namespace simgrid {
-namespace mc {
-
-Checker::Checker(Session& s) : session_(&s)
-{
- xbt_assert(mc_model_checker);
- xbt_assert(mc_model_checker->getChecker() == nullptr);
- mc_model_checker->setChecker(this);
-}
-
-} // namespace mc
-} // namespace simgrid
#ifndef SIMGRID_MC_CHECKER_HPP
#define SIMGRID_MC_CHECKER_HPP
-//#include "src/mc/Session.hpp"
-#include "src/mc/mc_forward.hpp"
-#include "src/mc/mc_record.hpp"
+#include "src/mc/mc_api.hpp"
namespace simgrid {
namespace mc {
* have all the necessary features). */
// abstract
class Checker {
- Session* session_;
-
public:
- explicit Checker(Session& session);
+ inline explicit Checker() { mc_api::get().set_checker(this); }
// No copy:
Checker(Checker const&) = delete;
/** Log additional information about the state of the model-checker */
virtual void log_state() = 0;
-
-protected:
- Session& get_session() { return *session_; }
};
// External constructors so that the types (and the types of their content) remain hidden
-XBT_PUBLIC Checker* createLivenessChecker(Session& session);
-XBT_PUBLIC Checker* createSafetyChecker(Session& session);
-XBT_PUBLIC Checker* createCommunicationDeterminismChecker(Session& session);
+XBT_PUBLIC Checker* createLivenessChecker();
+XBT_PUBLIC Checker* createSafetyChecker();
+XBT_PUBLIC Checker* createCommunicationDeterminismChecker();
} // namespace mc
} // namespace simgrid
#include "src/mc/checker/CommunicationDeterminismChecker.hpp"
#include "src/kernel/activity/MailboxImpl.hpp"
-#include "src/mc/Session.hpp"
#include "src/mc/mc_config.hpp"
#include "src/mc/mc_exit.hpp"
#include "src/mc/mc_private.hpp"
#include <cstdint>
-using simgrid::mc::remote;
+using mcapi = simgrid::mc::mc_api;
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_comm_determinism, mc, "Logging specific to MC communication determinism detection");
/********** Static functions ***********/
-static e_mc_comm_pattern_difference_t compare_comm_pattern(const simgrid::mc::PatternCommunication* comm1,
- const simgrid::mc::PatternCommunication* comm2)
+static simgrid::mc::CommPatternDifference compare_comm_pattern(const simgrid::mc::PatternCommunication* comm1,
+ const simgrid::mc::PatternCommunication* comm2)
{
- if(comm1->type != comm2->type)
- return TYPE_DIFF;
+ using simgrid::mc::CommPatternDifference;
+ if (comm1->type != comm2->type)
+ return CommPatternDifference::TYPE;
if (comm1->rdv != comm2->rdv)
- return RDV_DIFF;
+ return CommPatternDifference::RDV;
if (comm1->src_proc != comm2->src_proc)
- return SRC_PROC_DIFF;
+ return CommPatternDifference::SRC_PROC;
if (comm1->dst_proc != comm2->dst_proc)
- return DST_PROC_DIFF;
+ return CommPatternDifference::DST_PROC;
if (comm1->tag != comm2->tag)
- return TAG_DIFF;
+ return CommPatternDifference::TAG;
if (comm1->data.size() != comm2->data.size())
- return DATA_SIZE_DIFF;
+ return CommPatternDifference::DATA_SIZE;
if (comm1->data != comm2->data)
- return DATA_DIFF;
- return NONE_DIFF;
+ return CommPatternDifference::DATA;
+ return CommPatternDifference::NONE;
}
-static char* print_determinism_result(e_mc_comm_pattern_difference_t diff, int process,
+static void patterns_copy(std::vector<simgrid::mc::PatternCommunication*>& dest,
+ std::vector<simgrid::mc::PatternCommunication> const& source)
+{
+ dest.clear();
+ for (simgrid::mc::PatternCommunication const& comm : source) {
+ auto* copy_comm = new simgrid::mc::PatternCommunication(comm.dup());
+ dest.push_back(copy_comm);
+ }
+}
+
+static void restore_communications_pattern(simgrid::mc::State* state)
+{
+ for (size_t i = 0; i < initial_communications_pattern.size(); i++)
+ initial_communications_pattern[i].index_comm = state->communication_indices_[i];
+
+ for (unsigned long i = 0; i < mcapi::get().get_maxpid(); i++)
+ patterns_copy(incomplete_communications_pattern[i], state->incomplete_comm_pattern_[i]);
+}
+
+static char* print_determinism_result(simgrid::mc::CommPatternDifference diff, aid_t process,
const simgrid::mc::PatternCommunication* comm, unsigned int cursor)
{
char* type;
char* res;
if (comm->type == simgrid::mc::PatternCommunicationType::send)
- type = bprintf("The send communications pattern of the process %d is different!", process - 1);
+ type = bprintf("The send communications pattern of the process %ld is different!", process - 1);
else
- type = bprintf("The recv communications pattern of the process %d is different!", process - 1);
-
- switch(diff) {
- case TYPE_DIFF:
- res = bprintf("%s Different type for communication #%u", type, cursor);
- break;
- case RDV_DIFF:
- res = bprintf("%s Different rdv for communication #%u", type, cursor);
- break;
- case TAG_DIFF:
- res = bprintf("%s Different tag for communication #%u", type, cursor);
- break;
- case SRC_PROC_DIFF:
- res = bprintf("%s Different source for communication #%u", type, cursor);
- break;
- case DST_PROC_DIFF:
- res = bprintf("%s Different destination for communication #%u", type, cursor);
- break;
- case DATA_SIZE_DIFF:
- res = bprintf("%s Different data size for communication #%u", type, cursor);
- break;
- case DATA_DIFF:
- res = bprintf("%s Different data for communication #%u", type, cursor);
- break;
- default:
- res = nullptr;
- break;
+ type = bprintf("The recv communications pattern of the process %ld is different!", process - 1);
+
+ using simgrid::mc::CommPatternDifference;
+ switch (diff) {
+ case CommPatternDifference::TYPE:
+ res = bprintf("%s Different type for communication #%u", type, cursor);
+ break;
+ case CommPatternDifference::RDV:
+ res = bprintf("%s Different rdv for communication #%u", type, cursor);
+ break;
+ case CommPatternDifference::TAG:
+ res = bprintf("%s Different tag for communication #%u", type, cursor);
+ break;
+ case CommPatternDifference::SRC_PROC:
+ res = bprintf("%s Different source for communication #%u", type, cursor);
+ break;
+ case CommPatternDifference::DST_PROC:
+ res = bprintf("%s Different destination for communication #%u", type, cursor);
+ break;
+ case CommPatternDifference::DATA_SIZE:
+ res = bprintf("%s Different data size for communication #%u", type, cursor);
+ break;
+ case CommPatternDifference::DATA:
+ res = bprintf("%s Different data for communication #%u", type, cursor);
+ break;
+ default:
+ res = nullptr;
+ break;
}
return res;
}
static void update_comm_pattern(simgrid::mc::PatternCommunication* comm_pattern,
- simgrid::mc::RemotePtr<simgrid::kernel::activity::CommImpl> comm_addr)
+ const simgrid::kernel::activity::CommImpl* comm_addr)
{
- // HACK, type punning
- simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_comm;
- mc_model_checker->get_remote_simulation().read(temp_comm, comm_addr);
- const simgrid::kernel::activity::CommImpl* comm = temp_comm.get_buffer();
-
- smx_actor_t src_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(comm->src_actor_.get()));
- smx_actor_t dst_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(comm->dst_actor_.get()));
+ auto src_proc = mcapi::get().get_src_actor(comm_addr);
+ auto dst_proc = mcapi::get().get_dst_actor(comm_addr);
comm_pattern->src_proc = src_proc->get_pid();
comm_pattern->dst_proc = dst_proc->get_pid();
- comm_pattern->src_host = MC_smx_actor_get_host_name(src_proc);
- comm_pattern->dst_host = MC_smx_actor_get_host_name(dst_proc);
- if (comm_pattern->data.empty() && comm->src_buff_ != nullptr) {
- size_t buff_size;
- mc_model_checker->get_remote_simulation().read(&buff_size, remote(comm->dst_buff_size_));
- comm_pattern->data.resize(buff_size);
- mc_model_checker->get_remote_simulation().read_bytes(comm_pattern->data.data(), comm_pattern->data.size(),
- remote(comm->src_buff_));
- }
+ comm_pattern->src_host = mcapi::get().get_actor_host_name(src_proc);
+ comm_pattern->dst_host = mcapi::get().get_actor_host_name(dst_proc);
+
+ if (comm_pattern->data.empty())
+ comm_pattern->data = mcapi::get().get_pattern_comm_data(comm_addr);
}
namespace simgrid {
namespace mc {
-void CommunicationDeterminismChecker::deterministic_comm_pattern(int process, const PatternCommunication* comm,
+void CommunicationDeterminismChecker::deterministic_comm_pattern(aid_t process, const PatternCommunication* comm,
int backtracking)
{
if (not backtracking) {
- PatternCommunicationList& list = initial_communications_pattern[process];
- e_mc_comm_pattern_difference_t diff = compare_comm_pattern(list.list[list.index_comm].get(), comm);
+ PatternCommunicationList& list = initial_communications_pattern[process];
+ CommPatternDifference diff = compare_comm_pattern(list.list[list.index_comm].get(), comm);
- if (diff != NONE_DIFF) {
+ if (diff != CommPatternDifference::NONE) {
if (comm->type == PatternCommunicationType::send) {
this->send_deterministic = false;
if (this->send_diff != nullptr)
XBT_INFO("%s", this->send_diff);
xbt_free(this->send_diff);
this->send_diff = nullptr;
- mc::session->log_state();
- mc_model_checker->exit(SIMGRID_MC_EXIT_NON_DETERMINISM);
+ mcapi::get().log_state();
+ mcapi::get().mc_exit(SIMGRID_MC_EXIT_NON_DETERMINISM);
} else if (_sg_mc_comms_determinism && (not this->send_deterministic && not this->recv_deterministic)) {
XBT_INFO("****************************************************");
XBT_INFO("***** Non-deterministic communications pattern *****");
xbt_free(this->recv_diff);
this->recv_diff = nullptr;
}
- mc::session->log_state();
- mc_model_checker->exit(SIMGRID_MC_EXIT_NON_DETERMINISM);
+ mcapi::get().log_state();
+ mcapi::get().mc_exit(SIMGRID_MC_EXIT_NON_DETERMINISM);
}
}
}
/********** Non Static functions ***********/
-void CommunicationDeterminismChecker::get_comm_pattern(smx_simcall_t request, e_mc_call_type_t call_type,
- int backtracking)
+void CommunicationDeterminismChecker::get_comm_pattern(smx_simcall_t request, CallType call_type, int backtracking)
{
- const smx_actor_t issuer = MC_smx_simcall_get_issuer(request);
+ const smx_actor_t issuer = mcapi::get().simcall_get_issuer(request);
const mc::PatternCommunicationList& initial_pattern = initial_communications_pattern[issuer->get_pid()];
const std::vector<PatternCommunication*>& incomplete_pattern = incomplete_communications_pattern[issuer->get_pid()];
auto pattern = std::make_unique<PatternCommunication>();
pattern->index = initial_pattern.index_comm + incomplete_pattern.size();
- if (call_type == MC_CALL_TYPE_SEND) {
+ if (call_type == CallType::SEND) {
/* Create comm pattern */
pattern->type = PatternCommunicationType::send;
- pattern->comm_addr = static_cast<kernel::activity::CommImpl*>(simcall_comm_isend__getraw__result(request));
-
- Remote<kernel::activity::CommImpl> temp_synchro;
- mc_model_checker->get_remote_simulation().read(temp_synchro, remote(pattern->comm_addr));
- const kernel::activity::CommImpl* synchro = temp_synchro.get_buffer();
-
- char* remote_name = mc_model_checker->get_remote_simulation().read<char*>(RemotePtr<char*>(
- (uint64_t)(synchro->get_mailbox() ? &synchro->get_mailbox()->name_ : &synchro->mbox_cpy->name_)));
- pattern->rdv = mc_model_checker->get_remote_simulation().read_string(RemotePtr<char>(remote_name));
- pattern->src_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(synchro->src_actor_.get()))->get_pid();
- pattern->src_host = MC_smx_actor_get_host_name(issuer);
+ pattern->comm_addr = mcapi::get().get_comm_isend_raw_addr(request);
+ pattern->rdv = mcapi::get().get_pattern_comm_rdv(pattern->comm_addr);
+ pattern->src_proc = mcapi::get().get_pattern_comm_src_proc(pattern->comm_addr);
+ pattern->src_host = mc_api::get().get_actor_host_name(issuer);
#if HAVE_SMPI
- simgrid::smpi::Request mpi_request;
- mc_model_checker->get_remote_simulation().read(
- &mpi_request, remote(static_cast<smpi::Request*>(simcall_comm_isend__get__data(request))));
- pattern->tag = mpi_request.tag();
+ pattern->tag = mcapi::get().get_smpi_request_tag(request, simgrid::simix::Simcall::COMM_ISEND);
#endif
+ pattern->data = mcapi::get().get_pattern_comm_data(pattern->comm_addr);
- if (synchro->src_buff_ != nullptr) {
- pattern->data.resize(synchro->src_buff_size_);
- mc_model_checker->get_remote_simulation().read_bytes(pattern->data.data(), pattern->data.size(),
- remote(synchro->src_buff_));
- }
#if HAVE_SMPI
- if(mpi_request.detached()){
+ auto send_detached = mcapi::get().check_send_request_detached(request);
+ if (send_detached) {
if (this->initial_communications_pattern_done) {
/* Evaluate comm determinism */
this->deterministic_comm_pattern(pattern->src_proc, pattern.get(), backtracking);
return;
}
#endif
- } else if (call_type == MC_CALL_TYPE_RECV) {
- pattern->type = PatternCommunicationType::receive;
- pattern->comm_addr = static_cast<kernel::activity::CommImpl*>(simcall_comm_irecv__getraw__result(request));
+ } else if (call_type == CallType::RECV) {
+ pattern->type = PatternCommunicationType::receive;
+ pattern->comm_addr = mcapi::get().get_comm_isend_raw_addr(request);
#if HAVE_SMPI
- smpi::Request mpi_request;
- mc_model_checker->get_remote_simulation().read(
- &mpi_request, remote(static_cast<smpi::Request*>(simcall_comm_irecv__get__data(request))));
- pattern->tag = mpi_request.tag();
+ pattern->tag = mcapi::get().get_smpi_request_tag(request, simgrid::simix::Simcall::COMM_IRECV);
#endif
-
- Remote<kernel::activity::CommImpl> temp_comm;
- mc_model_checker->get_remote_simulation().read(temp_comm, remote(pattern->comm_addr));
- const kernel::activity::CommImpl* comm = temp_comm.get_buffer();
-
- char* remote_name;
- mc_model_checker->get_remote_simulation().read(
- &remote_name, remote(comm->get_mailbox() ? &xbt::string::to_string_data(comm->get_mailbox()->name_).data
- : &xbt::string::to_string_data(comm->mbox_cpy->name_).data));
- pattern->rdv = mc_model_checker->get_remote_simulation().read_string(RemotePtr<char>(remote_name));
- pattern->dst_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(comm->dst_actor_.get()))->get_pid();
- pattern->dst_host = MC_smx_actor_get_host_name(issuer);
+ auto comm_addr = pattern->comm_addr;
+ pattern->rdv = mcapi::get().get_pattern_comm_rdv(comm_addr);
+ pattern->dst_proc = mcapi::get().get_pattern_comm_dst_proc(comm_addr);
+ pattern->dst_host = mcapi::get().get_actor_host_name(issuer);
} else
- xbt_die("Unexpected call_type %i", (int) call_type);
+ xbt_die("Unexpected call_type %i", (int)call_type);
XBT_DEBUG("Insert incomplete comm pattern %p for process %ld", pattern.get(), issuer->get_pid());
incomplete_communications_pattern[issuer->get_pid()].push_back(pattern.release());
}
-void CommunicationDeterminismChecker::complete_comm_pattern(RemotePtr<kernel::activity::CommImpl> comm_addr,
- unsigned int issuer, int backtracking)
+void CommunicationDeterminismChecker::complete_comm_pattern(const kernel::activity::CommImpl* comm_addr, aid_t issuer,
+ int backtracking)
{
/* Complete comm pattern */
std::vector<PatternCommunication*>& incomplete_pattern = incomplete_communications_pattern[issuer];
auto current_comm_pattern =
std::find_if(begin(incomplete_pattern), end(incomplete_pattern),
- [&comm_addr](const PatternCommunication* comm) { return remote(comm->comm_addr) == comm_addr; });
+ [&comm_addr](const PatternCommunication* comm) { return mcapi::get().comm_addr_equal(comm->comm_addr, comm_addr); });
if (current_comm_pattern == std::end(incomplete_pattern))
xbt_die("Corresponding communication not found!");
update_comm_pattern(*current_comm_pattern, comm_addr);
std::unique_ptr<PatternCommunication> comm_pattern(*current_comm_pattern);
- XBT_DEBUG("Remove incomplete comm pattern for process %u at cursor %zd", issuer,
+ XBT_DEBUG("Remove incomplete comm pattern for process %ld at cursor %zd", issuer,
std::distance(begin(incomplete_pattern), current_comm_pattern));
incomplete_pattern.erase(current_comm_pattern);
}
}
-CommunicationDeterminismChecker::CommunicationDeterminismChecker(Session& s) : Checker(s)
-{
-}
+CommunicationDeterminismChecker::CommunicationDeterminismChecker() : Checker() {}
CommunicationDeterminismChecker::~CommunicationDeterminismChecker() = default;
std::vector<std::string> trace;
for (auto const& state : stack_) {
smx_simcall_t req = &state->executed_req_;
- if (req)
- trace.push_back(request_to_string(req, state->transition_.argument_, RequestType::executed));
+ trace.push_back(mcapi::get().request_to_string(req, state->transition_.argument_, RequestType::executed));
}
return trace;
}
}
}
XBT_INFO("Expanded states = %lu", expanded_states_count_);
- XBT_INFO("Visited states = %lu", mc_model_checker->visited_states);
- XBT_INFO("Executed transitions = %lu", mc_model_checker->executed_transitions);
+ XBT_INFO("Visited states = %lu", mcapi::get().mc_get_visited_states());
+ XBT_INFO("Executed transitions = %lu", mcapi::get().mc_get_executed_trans());
XBT_INFO("Send-deterministic : %s", this->send_deterministic ? "Yes" : "No");
if (_sg_mc_comms_determinism)
XBT_INFO("Recv-deterministic : %s", this->recv_deterministic ? "Yes" : "No");
void CommunicationDeterminismChecker::prepare()
{
- const int maxpid = MC_smx_get_maxpid();
+ const auto maxpid = mcapi::get().get_maxpid();
initial_communications_pattern.resize(maxpid);
incomplete_communications_pattern.resize(maxpid);
XBT_DEBUG("********* Start communication determinism verification *********");
/* Get an enabled actor and insert it in the interleave set of the initial state */
- for (auto& actor : mc_model_checker->get_remote_simulation().actors())
- if (mc::actor_is_enabled(actor.copy.get_buffer()))
+ auto actors = mcapi::get().get_actors();
+ for (auto& actor : actors)
+ if (mcapi::get().actor_is_enabled(actor.copy.get_buffer()->get_pid()))
initial_state->add_interleaving_set(actor.copy.get_buffer());
stack_.push_back(std::move(initial_state));
static inline bool all_communications_are_finished()
{
- for (size_t current_actor = 1; current_actor < MC_smx_get_maxpid(); current_actor++) {
+ auto maxpid = mcapi::get().get_maxpid();
+ for (size_t current_actor = 1; current_actor < maxpid; current_actor++) {
if (not incomplete_communications_pattern[current_actor].empty()) {
XBT_DEBUG("Some communications are not finished, cannot stop the exploration! State not visited.");
return false;
/* Intermediate backtracking */
State* last_state = stack_.back().get();
if (last_state->system_state_) {
- last_state->system_state_->restore(&mc_model_checker->get_remote_simulation());
- MC_restore_communications_pattern(last_state);
+ mc_api::get().restore_state(last_state->system_state_);
+ restore_communications_pattern(last_state);
return;
}
/* Restore the initial state */
- mc::session->restore_initial_state();
+ mcapi::get().restore_initial_state();
- unsigned n = MC_smx_get_maxpid();
+ unsigned long n = mcapi::get().get_maxpid();
assert(n == incomplete_communications_pattern.size());
assert(n == initial_communications_pattern.size());
- for (unsigned j=0; j < n ; j++) {
+ for (unsigned long j = 0; j < n; j++) {
incomplete_communications_pattern[j].clear();
initial_communications_pattern[j].index_comm = 0;
}
if (state == stack_.back())
break;
- int req_num = state->transition_.argument_;
+ int req_num = state->transition_.argument_;
const s_smx_simcall* saved_req = &state->executed_req_;
xbt_assert(saved_req);
/* because we got a copy of the executed request, we have to fetch the
real one, pointed by the request field of the issuer process */
- const smx_actor_t issuer = MC_smx_simcall_get_issuer(saved_req);
+ const smx_actor_t issuer = mcapi::get().simcall_get_issuer(saved_req);
smx_simcall_t req = &issuer->simcall_;
/* TODO : handle test and testany simcalls */
- e_mc_call_type_t call = MC_get_call_type(req);
- mc_model_checker->handle_simcall(state->transition_);
- MC_handle_comm_pattern(call, req, req_num, 1);
- mc_model_checker->wait_for_requests();
+ CallType call = MC_get_call_type(req);
+ mcapi::get().handle_simcall(state->transition_);
+ handle_comm_pattern(call, req, req_num, 1);
+ mcapi::get().mc_wait_for_requests();
/* Update statistics */
- mc_model_checker->visited_states++;
- mc_model_checker->executed_transitions++;
+ mcapi::get().mc_inc_visited_states();
+ mcapi::get().mc_inc_executed_trans();
+ }
+}
+
+void CommunicationDeterminismChecker::handle_comm_pattern(simgrid::mc::CallType call_type, smx_simcall_t req, int value, int backtracking)
+{
+ using simgrid::mc::CallType;
+ switch(call_type) {
+ case CallType::NONE:
+ break;
+ case CallType::SEND:
+ case CallType::RECV:
+ get_comm_pattern(req, call_type, backtracking);
+ break;
+ case CallType::WAIT:
+ case CallType::WAITANY: {
+ const simgrid::kernel::activity::CommImpl* comm_addr = nullptr;
+ if (call_type == CallType::WAIT)
+ comm_addr = mcapi::get().get_comm_wait_raw_addr(req);
+ else
+ comm_addr = mcapi::get().get_comm_waitany_raw_addr(req, value);
+ auto simcall_issuer = mcapi::get().simcall_get_issuer(req);
+ complete_comm_pattern(comm_addr, simcall_issuer->get_pid(), backtracking);
+ } break;
+ default:
+ xbt_die("Unexpected call type %i", (int)call_type);
}
}
void CommunicationDeterminismChecker::real_run()
{
std::unique_ptr<VisitedState> visited_state = nullptr;
- smx_simcall_t req = nullptr;
+ smx_simcall_t req = nullptr;
while (not stack_.empty()) {
/* Get current state */
cur_state->interleave_size());
/* Update statistics */
- mc_model_checker->visited_states++;
+ mcapi::get().mc_inc_visited_states();
if (stack_.size() <= (std::size_t)_sg_mc_max_depth)
- req = MC_state_choose_request(cur_state);
+ req = mcapi::get().mc_state_choose_request(cur_state);
else
req = nullptr;
if (req != nullptr && visited_state == nullptr) {
int req_num = cur_state->transition_.argument_;
- XBT_DEBUG("Execute: %s", request_to_string(req, req_num, RequestType::simix).c_str());
+ XBT_DEBUG("Execute: %s", mcapi::get().request_to_string(req, req_num, RequestType::simix).c_str());
std::string req_str;
if (dot_output != nullptr)
- req_str = request_get_dot_output(req, req_num);
+ req_str = mcapi::get().request_get_dot_output(req, req_num);
- mc_model_checker->executed_transitions++;
+ mcapi::get().mc_inc_executed_trans();
/* TODO : handle test and testany simcalls */
- e_mc_call_type_t call = MC_CALL_TYPE_NONE;
+ CallType call = CallType::NONE;
if (_sg_mc_comms_determinism || _sg_mc_send_determinism)
call = MC_get_call_type(req);
/* Answer the request */
- mc_model_checker->handle_simcall(cur_state->transition_);
+ mcapi::get().handle_simcall(cur_state->transition_);
/* After this call req is no longer useful */
- MC_handle_comm_pattern(call, req, req_num, 0);
+ handle_comm_pattern(call, req, req_num, 0);
/* Wait for requests (schedules processes) */
- mc_model_checker->wait_for_requests();
+ mcapi::get().mc_wait_for_requests();
/* Create the new expanded state */
++expanded_states_count_;
if (visited_state == nullptr) {
/* Get enabled actors and insert them in the interleave set of the next state */
- for (auto& actor : mc_model_checker->get_remote_simulation().actors())
- if (simgrid::mc::actor_is_enabled(actor.copy.get_buffer()))
+ auto actors = mcapi::get().get_actors();
+ for (auto& actor : actors)
+ if (mcapi::get().actor_is_enabled(actor.copy.get_buffer()->get_pid()))
next_state->add_interleaving_set(actor.copy.get_buffer());
if (dot_output != nullptr)
stack_.push_back(std::move(next_state));
} else {
- if (stack_.size() > (std::size_t) _sg_mc_max_depth)
+ if (stack_.size() > (std::size_t)_sg_mc_max_depth)
XBT_WARN("/!\\ Max depth reached! /!\\ ");
else if (visited_state != nullptr)
XBT_DEBUG("State already visited (equal to state %d), exploration stopped on this path.",
- visited_state->original_num == -1 ? visited_state->num : visited_state->original_num);
+ visited_state->original_num == -1 ? visited_state->num : visited_state->original_num);
else
XBT_DEBUG("There are no more processes to interleave. (depth %zu)", stack_.size());
visited_state = nullptr;
/* Check for deadlocks */
- if (mc_model_checker->checkDeadlock()) {
- MC_show_deadlock();
+ if (mcapi::get().mc_check_deadlock()) {
+ mcapi::get().mc_show_deadlock();
throw simgrid::mc::DeadlockError();
}
}
}
- mc::session->log_state();
+ mcapi::get().log_state();
}
void CommunicationDeterminismChecker::run()
{
XBT_INFO("Check communication determinism");
- mc::session->initialize();
+ mcapi::get().session_initialize();
this->prepare();
this->real_run();
}
-Checker* createCommunicationDeterminismChecker(Session& s)
+Checker* createCommunicationDeterminismChecker()
{
- return new CommunicationDeterminismChecker(s);
+ return new CommunicationDeterminismChecker();
}
} // namespace mc
class XBT_PRIVATE CommunicationDeterminismChecker : public Checker {
public:
- explicit CommunicationDeterminismChecker(Session& session);
+ explicit CommunicationDeterminismChecker();
~CommunicationDeterminismChecker() override;
void run() override;
RecordTrace get_record_trace() override;
void prepare();
void real_run();
void log_state() override;
- void deterministic_comm_pattern(int process, const PatternCommunication* comm, int backtracking);
+ void deterministic_comm_pattern(aid_t process, const PatternCommunication* comm, int backtracking);
void restoreState();
+ void handle_comm_pattern(simgrid::mc::CallType call_type, smx_simcall_t req, int value, int backtracking);
public:
// These are used by functions which should be moved in CommunicationDeterminismChecker:
- void get_comm_pattern(smx_simcall_t request, e_mc_call_type_t call_type, int backtracking);
- void complete_comm_pattern(RemotePtr<kernel::activity::CommImpl> comm_addr, unsigned int issuer, int backtracking);
+ void get_comm_pattern(smx_simcall_t request, CallType call_type, int backtracking);
+ void complete_comm_pattern(const kernel::activity::CommImpl* comm_addr, aid_t issuer, int backtracking);
private:
/** Stack representing the position in the exploration graph */
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/mc/checker/LivenessChecker.hpp"
-#include "src/mc/Session.hpp"
#include "src/mc/mc_config.hpp"
#include "src/mc/mc_exit.hpp"
#include "src/mc/mc_private.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_liveness, mc, "Logging specific to algorithms for liveness properties verification");
+using mcapi = simgrid::mc::mc_api;
+
/********* Static functions *********/
namespace simgrid {
std::shared_ptr<State> graph_state)
: num(pair_num), automaton_state(automaton_state)
{
- RemoteSimulation* process = &(mc_model_checker->get_remote_simulation());
-
this->graph_state = std::move(graph_state);
if (this->graph_state->system_state_ == nullptr)
this->graph_state->system_state_ = std::make_shared<Snapshot>(pair_num);
- this->heap_bytes_used = mmalloc_get_bytes_used_remote(process->get_heap()->heaplimit, process->get_malloc_info());
-
- this->actors_count = mc_model_checker->get_remote_simulation().actors().size();
-
+ this->heap_bytes_used = mcapi::get().get_remote_heap_bytes();
+ this->actors_count = mcapi::get().get_actors_size();
this->other_num = -1;
this->atomic_propositions = std::move(atomic_propositions);
}
case xbt_automaton_exp_label::AUT_NOT:
return not evaluate_label(l->u.exp_not, values);
case xbt_automaton_exp_label::AUT_PREDICAT:{
- unsigned int cursor = 0;
- xbt_automaton_propositional_symbol_t p = nullptr;
- xbt_dynar_foreach(simgrid::mc::property_automaton->propositional_symbols, cursor, p) {
- if (std::strcmp(xbt_automaton_propositional_symbol_get_name(p), l->u.predicat) == 0)
- return values[cursor] != 0;
- }
+ auto cursor = mcapi::get().compare_automaton_exp_label(l);
+ if(cursor >= 0)
+ return values[cursor] != 0;
xbt_die("Missing predicate");
break;
}
std::shared_ptr<const std::vector<int>> LivenessChecker::get_proposition_values() const
{
- std::vector<int> values;
- unsigned int cursor = 0;
- xbt_automaton_propositional_symbol_t ps = nullptr;
- xbt_dynar_foreach (mc::property_automaton->propositional_symbols, cursor, ps)
- values.push_back(xbt_automaton_propositional_symbol_evaluate(ps));
+ auto values = mcapi::get().automaton_propositional_symbol_evaluate();
return std::make_shared<const std::vector<int>>(std::move(values));
}
auto new_pair =
std::make_shared<VisitedPair>(pair->num, pair->automaton_state, pair->atomic_propositions, pair->graph_state);
- auto res = boost::range::equal_range(acceptance_pairs_, new_pair.get(), DerefAndCompareByActorsCountAndUsedHeap());
+ auto res = boost::range::equal_range(acceptance_pairs_, new_pair.get(), mcapi::get().compare_pair());
if (pair->search_cycle) for (auto i = res.first; i != res.second; ++i) {
std::shared_ptr<simgrid::mc::VisitedPair> const& pair_test = *i;
- if (xbt_automaton_state_compare(pair_test->automaton_state, new_pair->automaton_state) != 0 ||
+ if (mcapi::get().automaton_state_compare(pair_test->automaton_state, new_pair->automaton_state) != 0 ||
*(pair_test->atomic_propositions) != *(new_pair->atomic_propositions) ||
- not snapshot_equal(pair_test->graph_state->system_state_.get(), new_pair->graph_state->system_state_.get()))
+ not mcapi::get().snapshot_equal(pair_test->graph_state->system_state_.get(), new_pair->graph_state->system_state_.get()))
continue;
XBT_INFO("Pair %d already reached (equal to pair %d) !", new_pair->num, pair_test->num);
exploration_stack_.pop_back();
if(_sg_mc_checkpoint > 0) {
const Pair* pair = exploration_stack_.back().get();
if (pair->graph_state->system_state_) {
- pair->graph_state->system_state_->restore(&mc_model_checker->get_remote_simulation());
+ mcapi::get().restore_state(pair->graph_state->system_state_);
return;
}
}
/* Restore the initial state */
- mc::session->restore_initial_state();
+ mcapi::get().restore_initial_state();
/* Traverse the stack from the initial state and re-execute the transitions */
int depth = 1;
smx_simcall_t req = nullptr;
- if (saved_req != nullptr) {
- /* because we got a copy of the executed request, we have to fetch the
- real one, pointed by the request field of the issuer process */
- const smx_actor_t issuer = MC_smx_simcall_get_issuer(saved_req);
- req = &issuer->simcall_;
+ /* because we got a copy of the executed request, we have to fetch the
+ real one, pointed by the request field of the issuer process */
+ const smx_actor_t issuer = mcapi::get().simcall_get_issuer(saved_req);
+ req = &issuer->simcall_;
- /* Debug information */
- XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth,
- request_to_string(req, req_num, simgrid::mc::RequestType::simix).c_str(), state.get());
- }
+ /* Debug information */
+ XBT_DEBUG("Replay (depth = %d) : %s (%p)", depth,
+ mcapi::get().request_to_string(req, req_num, simgrid::mc::RequestType::simix).c_str(), state.get());
- this->get_session().execute(state->transition_);
+ mcapi::get().execute(state->transition_);
}
/* Update statistics */
visited_pairs_count_++;
- mc_model_checker->executed_transitions++;
+ mcapi::get().mc_inc_executed_trans();
depth++;
}
visited_pair =
std::make_shared<VisitedPair>(pair->num, pair->automaton_state, pair->atomic_propositions, pair->graph_state);
- auto range = boost::range::equal_range(visited_pairs_, visited_pair.get(), DerefAndCompareByActorsCountAndUsedHeap());
+ auto range = boost::range::equal_range(visited_pairs_, visited_pair.get(), mcapi::get().compare_pair());
for (auto i = range.first; i != range.second; ++i) {
const VisitedPair* pair_test = i->get();
- if (xbt_automaton_state_compare(pair_test->automaton_state, visited_pair->automaton_state) != 0 ||
+ if (mcapi::get().automaton_state_compare(pair_test->automaton_state, visited_pair->automaton_state) != 0 ||
*(pair_test->atomic_propositions) != *(visited_pair->atomic_propositions) ||
- not snapshot_equal(pair_test->graph_state->system_state_.get(), visited_pair->graph_state->system_state_.get()))
+ not mcapi::get().snapshot_equal(pair_test->graph_state->system_state_.get(), visited_pair->graph_state->system_state_.get()))
continue;
if (pair_test->other_num == -1)
visited_pair->other_num = pair_test->num;
}
}
-LivenessChecker::LivenessChecker(Session& s) : Checker(s)
+LivenessChecker::LivenessChecker() : Checker()
{
}
{
XBT_INFO("Expanded pairs = %lu", expanded_pairs_count_);
XBT_INFO("Visited pairs = %lu", visited_pairs_count_);
- XBT_INFO("Executed transitions = %lu", mc_model_checker->executed_transitions);
+ XBT_INFO("Executed transitions = %lu", mcapi::get().mc_get_executed_trans());
}
void LivenessChecker::show_acceptance_cycle(std::size_t depth)
XBT_INFO("Counter-example that violates formula:");
for (auto const& s : this->get_textual_trace())
XBT_INFO(" %s", s.c_str());
- mc::dumpRecordPath();
- mc::session->log_state();
+ mcapi::get().dump_record_path();
+ mcapi::get().log_state();
XBT_INFO("Counter-example depth: %zu", depth);
}
for (std::shared_ptr<Pair> const& pair : exploration_stack_) {
int req_num = pair->graph_state->transition_.argument_;
smx_simcall_t req = &pair->graph_state->executed_req_;
- if (req && req->call_ != SIMCALL_NONE)
- trace.push_back(request_to_string(req, req_num, RequestType::executed));
+ if (req->call_ != simix::Simcall::NONE)
+ trace.push_back(mcapi::get().request_to_string(req, req_num, RequestType::executed));
}
return trace;
}
else
next_pair->depth = 1;
/* Get enabled actors and insert them in the interleave set of the next graph_state */
- for (auto& actor : mc_model_checker->get_remote_simulation().actors())
- if (mc::actor_is_enabled(actor.copy.get_buffer()))
+ auto actors = mcapi::get().get_actors();
+ for (auto& actor : actors)
+ if (mcapi::get().actor_is_enabled(actor.copy.get_buffer()->get_pid()))
next_pair->graph_state->add_interleaving_set(actor.copy.get_buffer());
next_pair->requests = next_pair->graph_state->interleave_size();
/* FIXME : get search_cycle value for each accepting state */
void LivenessChecker::run()
{
XBT_INFO("Check the liveness property %s", _sg_mc_property_file.get().c_str());
- MC_automaton_load(_sg_mc_property_file.get().c_str());
+ mcapi::get().automaton_load(_sg_mc_property_file.get().c_str());
XBT_DEBUG("Starting the liveness algorithm");
- mc::session->initialize();
+ mcapi::get().session_initialize();
/* Initialize */
this->previous_pair_ = 0;
// For each initial state of the property automaton, push a
// (application_state, automaton_state) pair to the exploration stack:
- unsigned int cursor = 0;
- xbt_automaton_state_t automaton_state;
- xbt_dynar_foreach (mc::property_automaton->states, cursor, automaton_state)
+ auto automaton_stack = mcapi::get().get_automaton_state();
+ for (auto* automaton_state : automaton_stack) {
if (automaton_state->type == -1)
exploration_stack_.push_back(this->create_pair(nullptr, automaton_state, propos));
+ }
/* Actually run the double DFS search for counter-examples */
while (not exploration_stack_.empty()) {
std::shared_ptr<Pair> current_pair = exploration_stack_.back();
/* Update current state in buchi automaton */
- mc::property_automaton->current_state = current_pair->automaton_state;
+ mcapi::get().set_property_automaton(current_pair->automaton_state);
XBT_DEBUG(
"********************* ( Depth = %d, search_cycle = %d, interleave size = %zu, pair_num = %d, requests = %d)",
}
}
- smx_simcall_t req = MC_state_choose_request(current_pair->graph_state.get());
+ smx_simcall_t req = mcapi::get().mc_state_choose_request(current_pair->graph_state.get());
int req_num = current_pair->graph_state->transition_.argument_;
if (dot_output != nullptr) {
this->previous_request_.clear();
}
this->previous_pair_ = current_pair->num;
- this->previous_request_ = request_get_dot_output(req, req_num);
+ this->previous_request_ = mcapi::get().request_get_dot_output(req, req_num);
if (current_pair->search_cycle)
fprintf(dot_output, "%d [shape=doublecircle];\n", current_pair->num);
fflush(dot_output);
}
- XBT_DEBUG("Execute: %s", request_to_string(req, req_num, RequestType::simix).c_str());
+ XBT_DEBUG("Execute: %s", mcapi::get().request_to_string(req, req_num, RequestType::simix).c_str());
/* Update stats */
- mc_model_checker->executed_transitions++;
+ mcapi::get().mc_inc_executed_trans();
+
if (not current_pair->exploration_started)
visited_pairs_count_++;
/* Answer the request */
- mc_model_checker->handle_simcall(current_pair->graph_state->transition_);
+ mcapi::get().handle_simcall(current_pair->graph_state->transition_);
/* Wait for requests (schedules processes) */
- mc_model_checker->wait_for_requests();
+ mcapi::get().mc_wait_for_requests();
current_pair->requests--;
current_pair->exploration_started = true;
// For each enabled transition in the property automaton, push a
// (application_state, automaton_state) pair to the exploration stack:
- for (int i = xbt_dynar_length(current_pair->automaton_state->out) - 1; i >= 0; i--) {
- const xbt_automaton_transition* transition_succ =
- xbt_dynar_get_as(current_pair->automaton_state->out, i, xbt_automaton_transition_t);
- if (evaluate_label(transition_succ->label, *prop_values))
- exploration_stack_.push_back(this->create_pair(current_pair.get(), transition_succ->dst, prop_values));
- }
+ for (int i = mcapi::get().get_dynar_length(current_pair->automaton_state->out) - 1; i >= 0; i--) {
+ auto transition_succ_label = mcapi::get().get_automaton_transition_label(current_pair->automaton_state->out, i);
+ auto transition_succ_dst = mcapi::get().get_automaton_transition_dst(current_pair->automaton_state->out, i);
+ if (evaluate_label(transition_succ_label, *prop_values))
+ exploration_stack_.push_back(this->create_pair(current_pair.get(), transition_succ_dst, prop_values));
+ }
}
XBT_INFO("No property violation found.");
- mc::session->log_state();
+ mcapi::get().log_state();
}
-Checker* createLivenessChecker(Session& s)
+Checker* createLivenessChecker()
{
- return new LivenessChecker(s);
+ return new LivenessChecker();
}
} // namespace mc
class XBT_PRIVATE LivenessChecker : public Checker {
public:
- explicit LivenessChecker(Session& session);
+ explicit LivenessChecker();
~LivenessChecker() override = default;
void run() override;
RecordTrace get_record_trace() override;
#include <xbt/log.h>
#include <xbt/sysdep.h>
-#include "src/mc/Session.hpp"
#include "src/mc/Transition.hpp"
#include "src/mc/VisitedState.hpp"
#include "src/mc/checker/SafetyChecker.hpp"
#include "src/xbt/mmalloc/mmprivate.h"
+using mcapi = simgrid::mc::mc_api;
+
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_safety, mc, "Logging specific to MC safety verification ");
namespace simgrid {
void SafetyChecker::check_non_termination(const State* current_state)
{
for (auto state = stack_.rbegin(); state != stack_.rend(); ++state)
- if (snapshot_equal((*state)->system_state_.get(), current_state->system_state_.get())) {
+ if (mcapi::get().snapshot_equal((*state)->system_state_.get(), current_state->system_state_.get())) {
XBT_INFO("Non-progressive cycle: state %d -> state %d", (*state)->num_, current_state->num_);
XBT_INFO("******************************************");
XBT_INFO("*** NON-PROGRESSIVE CYCLE DETECTED ***");
XBT_INFO("******************************************");
XBT_INFO("Counter-example execution trace:");
- for (auto const& s : mc_model_checker->getChecker()->get_textual_trace())
+ auto checker = mcapi::get().mc_get_checker();
+ for (auto const& s : checker->get_textual_trace())
XBT_INFO(" %s", s.c_str());
- dumpRecordPath();
- session->log_state();
+ mcapi::get().dump_record_path();
+ mcapi::get().log_state();
throw TerminationError();
}
for (auto const& state : stack_) {
int value = state->transition_.argument_;
smx_simcall_t req = &state->executed_req_;
- if (req)
- trace.push_back(request_to_string(req, value, RequestType::executed));
+ trace.push_back(mcapi::get().request_to_string(req, value, RequestType::executed));
}
return trace;
}
void SafetyChecker::log_state() // override
{
XBT_INFO("Expanded states = %lu", expanded_states_count_);
- XBT_INFO("Visited states = %lu", mc_model_checker->visited_states);
- XBT_INFO("Executed transitions = %lu", mc_model_checker->executed_transitions);
+ XBT_INFO("Visited states = %lu", mcapi::get().mc_get_visited_states());
+ XBT_INFO("Executed transitions = %lu", mcapi::get().mc_get_executed_trans());
}
void SafetyChecker::run()
XBT_VERB("Exploration depth=%zu (state=%p, num %d)(%zu interleave)", stack_.size(), state, state->num_,
state->interleave_size());
- mc_model_checker->visited_states++;
+ mcapi::get().mc_inc_visited_states();
// Backtrack if we reached the maximum depth
if (stack_.size() > (std::size_t)_sg_mc_max_depth) {
// Search an enabled transition in the current state; backtrack if the interleave set is empty
// get_request also sets state.transition to be the one corresponding to the returned req
- smx_simcall_t req = MC_state_choose_request(state);
+ smx_simcall_t req = mcapi::get().mc_state_choose_request(state);
// req is now the transition of the process that was selected to be executed
if (req == nullptr) {
// If there are processes to interleave and the maximum depth has not been
// reached then perform one step of the exploration algorithm.
- XBT_DEBUG("Execute: %s", request_to_string(req, state->transition_.argument_, RequestType::simix).c_str());
+ XBT_DEBUG("Execute: %s", mcapi::get().request_to_string(req, state->transition_.argument_, RequestType::simix).c_str());
std::string req_str;
if (dot_output != nullptr)
- req_str = request_get_dot_output(req, state->transition_.argument_);
+ req_str = mcapi::get().request_get_dot_output(req, state->transition_.argument_);
- mc_model_checker->executed_transitions++;
+ mcapi::get().mc_inc_executed_trans();
/* Actually answer the request: let execute the selected request (MCed does one step) */
- this->get_session().execute(state->transition_);
+ mcapi::get().execute(state->transition_);
/* Create the new expanded state (copy the state of MCed into our MCer data) */
++expanded_states_count_;
/* If this is a new state (or if we don't care about state-equality reduction) */
if (visited_state_ == nullptr) {
/* Get an enabled process and insert it in the interleave set of the next state */
- for (auto& remoteActor : mc_model_checker->get_remote_simulation().actors()) {
+ auto actors = mcapi::get().get_actors();
+ for (auto& remoteActor : actors) {
auto actor = remoteActor.copy.get_buffer();
- if (actor_is_enabled(actor)) {
+ if (mcapi::get().actor_is_enabled(actor->get_pid())) {
next_state->add_interleaving_set(actor);
if (reductionMode_ == ReductionMode::dpor)
break; // With DPOR, we take the first enabled transition
}
XBT_INFO("No property violation found.");
- session->log_state();
+ mcapi::get().log_state();
}
void SafetyChecker::backtrack()
stack_.pop_back();
/* Check for deadlocks */
- if (mc_model_checker->checkDeadlock()) {
- MC_show_deadlock();
+ if (mcapi::get().mc_check_deadlock()) {
+ mcapi::get().mc_show_deadlock();
throw DeadlockError();
}
stack_.pop_back();
if (reductionMode_ == ReductionMode::dpor) {
smx_simcall_t req = &state->internal_req_;
- if (req->call_ == SIMCALL_MUTEX_LOCK || req->call_ == SIMCALL_MUTEX_TRYLOCK)
+ if (req->call_ == simix::Simcall::MUTEX_LOCK || req->call_ == simix::Simcall::MUTEX_TRYLOCK)
xbt_die("Mutex is currently not supported with DPOR, use --cfg=model-check/reduction:none");
- const kernel::actor::ActorImpl* issuer = MC_smx_simcall_get_issuer(req);
+ const kernel::actor::ActorImpl* issuer = mcapi::get().simcall_get_issuer(req);
for (auto i = stack_.rbegin(); i != stack_.rend(); ++i) {
State* prev_state = i->get();
- if (request_depend(req, &prev_state->internal_req_)) {
+ if (mcapi::get().request_depend(req, &prev_state->internal_req_)) {
if (XBT_LOG_ISENABLED(mc_safety, xbt_log_priority_debug)) {
XBT_DEBUG("Dependent Transitions:");
int value = prev_state->transition_.argument_;
smx_simcall_t prev_req = &prev_state->executed_req_;
- XBT_DEBUG("%s (state=%d)", simgrid::mc::request_to_string(prev_req, value, RequestType::internal).c_str(),
+ XBT_DEBUG("%s (state=%d)", mcapi::get().request_to_string(prev_req, value, RequestType::internal).c_str(),
prev_state->num_);
value = state->transition_.argument_;
prev_req = &state->executed_req_;
- XBT_DEBUG("%s (state=%d)", simgrid::mc::request_to_string(prev_req, value, RequestType::executed).c_str(),
+ XBT_DEBUG("%s (state=%d)", mcapi::get().request_to_string(prev_req, value, RequestType::executed).c_str(),
state->num_);
}
XBT_DEBUG("Process %p is in done set", req->issuer_);
break;
} else if (req->issuer_ == prev_state->internal_req_.issuer_) {
- XBT_DEBUG("Simcall %s and %s with same issuer", SIMIX_simcall_name(req->call_),
- SIMIX_simcall_name(prev_state->internal_req_.call_));
+ XBT_DEBUG("Simcall %s and %s with same issuer", mcapi::get().simcall_get_name(req->call_),
+ mcapi::get().simcall_get_name(prev_state->internal_req_.call_));
break;
} else {
- const kernel::actor::ActorImpl* previous_issuer = MC_smx_simcall_get_issuer(&prev_state->internal_req_);
+ const kernel::actor::ActorImpl* previous_issuer = mcapi::get().simcall_get_issuer(&prev_state->internal_req_);
XBT_DEBUG("Simcall %s, process %ld (state %d) and simcall %s, process %ld (state %d) are independent",
- SIMIX_simcall_name(req->call_), issuer->get_pid(), state->num_,
- SIMIX_simcall_name(prev_state->internal_req_.call_), previous_issuer->get_pid(), prev_state->num_);
+ mcapi::get().simcall_get_name(req->call_), issuer->get_pid(), state->num_,
+ mcapi::get().simcall_get_name(prev_state->internal_req_.call_), previous_issuer->get_pid(), prev_state->num_);
}
}
}
/* Intermediate backtracking */
const State* last_state = stack_.back().get();
if (last_state->system_state_) {
- last_state->system_state_->restore(&mc_model_checker->get_remote_simulation());
+ mc_api::get().restore_state(last_state->system_state_);
return;
}
/* Restore the initial state */
- session->restore_initial_state();
+ mcapi::get().restore_initial_state();
/* Traverse the stack from the state at position start and re-execute the transitions */
for (std::unique_ptr<State> const& state : stack_) {
if (state == stack_.back())
break;
- session->execute(state->transition_);
+ mcapi::get().execute(state->transition_);
/* Update statistics */
- mc_model_checker->visited_states++;
- mc_model_checker->executed_transitions++;
+ mcapi::get().mc_inc_visited_states();
+ mcapi::get().mc_inc_executed_trans();
}
}
-SafetyChecker::SafetyChecker(Session& s) : Checker(s)
+SafetyChecker::SafetyChecker() : Checker()
{
reductionMode_ = reduction_mode;
if (_sg_mc_termination)
XBT_INFO("Check a safety property. Reduction is: %s.",
(reductionMode_ == ReductionMode::none ? "none"
: (reductionMode_ == ReductionMode::dpor ? "dpor" : "unknown")));
- session->initialize();
+
+ mcapi::get().session_initialize();
XBT_DEBUG("Starting the safety algorithm");
XBT_DEBUG("Initial state");
/* Get an enabled actor and insert it in the interleave set of the initial state */
- for (auto& actor : mc_model_checker->get_remote_simulation().actors())
- if (actor_is_enabled(actor.copy.get_buffer())) {
+ auto actors = mcapi::get().get_actors();
+ for (auto& actor : actors)
+ if (mcapi::get().actor_is_enabled(actor.copy.get_buffer()->get_pid())) {
initial_state->add_interleaving_set(actor.copy.get_buffer());
if (reductionMode_ != ReductionMode::none)
break;
stack_.push_back(std::move(initial_state));
}
-Checker* createSafetyChecker(Session& s)
+Checker* createSafetyChecker()
{
- return new SafetyChecker(s);
+ return new SafetyChecker();
}
} // namespace mc
ReductionMode reductionMode_ = ReductionMode::unset;
public:
- explicit SafetyChecker(Session& session);
+ explicit SafetyChecker();
~SafetyChecker() override = default;
void run() override;
RecordTrace get_record_trace() override;
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/sg_config.hpp"
-#include "src/mc/Session.hpp"
#include "src/mc/checker/Checker.hpp"
#include "src/mc/mc_config.hpp"
#include "src/mc/mc_exit.hpp"
#include <memory>
#include <unistd.h>
+using mcapi = simgrid::mc::mc_api;
+
static inline
char** argvdup(int argc, char** argv)
{
return argv_copy;
}
-static std::unique_ptr<simgrid::mc::Checker> create_checker(simgrid::mc::Session& session)
+static std::unique_ptr<simgrid::mc::Checker> create_checker()
{
if (_sg_mc_comms_determinism || _sg_mc_send_determinism)
- return std::unique_ptr<simgrid::mc::Checker>(simgrid::mc::createCommunicationDeterminismChecker(session));
+ return std::unique_ptr<simgrid::mc::Checker>(simgrid::mc::createCommunicationDeterminismChecker());
else if (_sg_mc_property_file.get().empty())
- return std::unique_ptr<simgrid::mc::Checker>(simgrid::mc::createSafetyChecker(session));
+ return std::unique_ptr<simgrid::mc::Checker>(simgrid::mc::createSafetyChecker());
else
- return std::unique_ptr<simgrid::mc::Checker>(simgrid::mc::createLivenessChecker(session));
+ return std::unique_ptr<simgrid::mc::Checker>(simgrid::mc::createLivenessChecker());
}
int main(int argc, char** argv)
smpi_init_options(); // only performed once
#endif
sg_config_init(&argc, argv);
- simgrid::mc::session = new simgrid::mc::Session([argv_copy] {
- int i = 1;
- while (argv_copy[i] != nullptr && argv_copy[i][0] == '-')
- i++;
- xbt_assert(argv_copy[i] != nullptr,
- "Unable to find a binary to exec on the command line. Did you only pass config flags?");
- execvp(argv_copy[i], argv_copy + i);
- xbt_die("The model-checked process failed to exec(): %s", strerror(errno));
- });
+ mcapi::get().initialize(argv_copy);
delete[] argv_copy;
- auto checker = create_checker(*simgrid::mc::session);
+ auto checker = create_checker();
int res = SIMGRID_MC_EXIT_SUCCESS;
try {
checker->run();
res = SIMGRID_MC_EXIT_LIVENESS;
}
checker = nullptr;
- simgrid::mc::session->close();
+ mcapi::get().s_close();
return res;
}
#include "src/mc/mc_smx.hpp"
#include "src/mc/sosp/Snapshot.hpp"
+#include <algorithm>
+
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_compare, xbt, "Logging specific to mc_compare in mc");
using simgrid::mc::remote;
}
};
-typedef std::array<HeapLocation, 2> HeapLocationPair;
-typedef std::set<HeapLocationPair> HeapLocationPairs;
+using HeapLocationPair = std::array<HeapLocation, 2>;
+using HeapLocationPairs = std::set<HeapLocationPair>;
class HeapArea : public HeapLocation {
public:
static ssize_t heap_comparison_ignore_size(const std::vector<simgrid::mc::IgnoredHeapRegion>* ignore_list,
const void* address)
{
- int start = 0;
- int end = ignore_list->size() - 1;
-
- while (start <= end) {
- unsigned int cursor = (start + end) / 2;
- simgrid::mc::IgnoredHeapRegion const& region = (*ignore_list)[cursor];
- if (region.address == address)
- return region.size;
- if (region.address < address)
- start = cursor + 1;
- if (region.address > address)
- end = cursor - 1;
- }
-
- return -1;
+ auto pos = std::lower_bound(ignore_list->begin(), ignore_list->end(), address,
+ [](auto const& reg, auto const* addr) { return reg.address < addr; });
+ return (pos != ignore_list->end() && pos->address == address) ? pos->size : -1;
}
static bool is_stack(const void *address)
int new_size2 = -1;
Type* new_type1 = nullptr;
- Type* new_type2 = nullptr;
bool match_pairs = false;
// The type of the variable is already known:
if (type) {
- new_type1 = new_type2 = type;
+ new_type1 = type;
}
// Type inference from the block type.
else if (state.types_<1>(block1, frag1) != nullptr || state.types_<2>(block2, frag2) != nullptr) {
+ Type* new_type2 = nullptr;
+
offset1 = (const char*)area1 - (const char*)real_addr_frag1;
offset2 = (const char*)area2 - (const char*)real_addr_frag2;
#include <cstdint>
#include <cstdlib>
+#include <array>
#include <stdexcept> // runtime_error
#include <utility>
#include <vector>
* just a sequence of dwarf instructions. We currently directly use
* `Dwarf_Op` from `dwarf.h` for dwarf instructions.
*/
-typedef std::vector<Dwarf_Op> DwarfExpression;
+using DwarfExpression = std::vector<Dwarf_Op>;
/** Context of evaluation of a DWARF expression
*
/** When an error happens in the execution of a DWARF expression */
class evaluation_error : public std::runtime_error {
public:
- explicit evaluation_error(const char* what) : std::runtime_error(what) {}
+ using std::runtime_error::runtime_error;
};
/** A stack for evaluating a DWARF expression
*/
class ExpressionStack {
public:
- typedef std::uintptr_t value_type;
- static const std::size_t max_size = 64;
+ using value_type = std::uintptr_t;
+ static constexpr std::size_t MAX_SIZE = 64;
private:
// Values of the stack (the top is stack_[size_ - 1]):
- uintptr_t stack_[max_size]{0};
+ std::array<uintptr_t, MAX_SIZE> stack_{{0}};
size_t size_ = 0;
public:
/** Push a value on the top of the stack */
void push(value_type value)
{
- if (size_ == max_size)
+ if (size_ == stack_.size())
throw evaluation_error("DWARF stack overflow");
- stack_[size_++] = value;
+ stack_[size_] = value;
+ size_++;
}
/* Pop a value from the top of the stack */
{
if (size_ == 0)
throw evaluation_error("DWARF stack underflow");
- return stack_[--size_];
+ --size_;
+ return stack_[size_];
}
// These are DWARF operations (DW_OP_foo):
/** A DWARF expression with optional validity constraints */
class LocationListEntry {
public:
- typedef simgrid::xbt::Range<std::uint64_t> range_type;
+ using range_type = simgrid::xbt::Range<std::uint64_t>;
private:
DwarfExpression expression_;
bool valid_for_ip(unw_word_t ip) const { return range_.contain(ip); }
};
-typedef std::vector<LocationListEntry> LocationList;
+using LocationList = std::vector<LocationListEntry>;
/** Location of some variable in memory
*
/* 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 <algorithm>
#include <cstdint>
#include <sys/mman.h> // PROT_READ and friends
#include <vector>
* during the binary search (only at the end) so it is not included
* in the index entry. We could use parallel arrays as well.
*
- * We cannot really use the std:: algorithm for this.
- * We could use std::binary_search by including the high_pc inside
- * the FunctionIndexEntry.
+ * Note the usage of reverse iterators to match the correct interval.
*/
- const FunctionIndexEntry* base = this->functions_index.data();
- int i = 0;
- int j = this->functions_index.size() - 1;
- while (j >= i) {
- int k = i + ((j - i) / 2);
-
- /* In most of the search, we do not dereference the base[k].function.
- * This way the memory accesses are located in the base[k] array. */
- if (ip < base[k].low_pc)
- j = k - 1;
- else if (k < j && ip >= base[k + 1].low_pc)
- i = k + 1;
-
- /* At this point, the search is over.
- * Either we have found the correct function or we do not know
- * any function corresponding to this instruction address.
- * Only at the point do we dereference the function pointer. */
- else if ((std::uint64_t)ip < base[k].function->range.end())
- return base[k].function;
- else
- return nullptr;
- }
- return nullptr;
+ auto pos = std::lower_bound(this->functions_index.rbegin(), this->functions_index.rend(), ip,
+ [](auto const& func, auto const* addr) { return func.low_pc > addr; });
+
+ /* At this point, the search is over.
+ * Either we have found the correct function or we do not know
+ * any function corresponding to this instruction address.
+ * Only at the point do we dereference the function pointer. */
+ return (pos != this->functions_index.rend() && reinterpret_cast<std::uint64_t>(ip) < pos->function->range.end())
+ ? pos->function
+ : nullptr;
}
-const Variable* ObjectInformation::find_variable(const char* name) const
+const Variable* ObjectInformation::find_variable(const char* var_name) const
{
- for (Variable const& variable : this->global_variables) {
- if (variable.name == name)
- return &variable;
- }
- return nullptr;
+ auto pos = std::lower_bound(this->global_variables.begin(), this->global_variables.end(), var_name,
+ [](auto const& var, const char* name) { return var.name < name; });
+ return (pos != this->global_variables.end() && pos->name == var_name) ? &(*pos) : nullptr;
}
-void ObjectInformation::remove_global_variable(const char* name)
+void ObjectInformation::remove_global_variable(const char* var_name)
{
- typedef std::vector<Variable>::size_type size_type;
-
- if (this->global_variables.empty())
- return;
-
// Binary search:
- size_type first = 0;
- size_type last = this->global_variables.size() - 1;
-
- while (first <= last) {
- size_type cursor = first + (last - first) / 2;
- const Variable& current_var = this->global_variables[cursor];
- int cmp = current_var.name.compare(name);
-
- if (cmp == 0) {
- // Find the whole range:
- first = cursor;
- while (first != 0 && this->global_variables[first - 1].name == name)
- first--;
- size_type size = this->global_variables.size();
- last = cursor;
- while (last != size - 1 && this->global_variables[last + 1].name == name)
- last++;
-
- // Remove the whole range:
- this->global_variables.erase(this->global_variables.begin() + first, this->global_variables.begin() + last + 1);
-
- return;
- } else if (cmp < 0)
- first = cursor + 1;
- else if (cursor != 0)
- last = cursor - 1;
- else
- break;
- }
+ auto pos1 = std::lower_bound(this->global_variables.begin(), this->global_variables.end(), var_name,
+ [](auto const& var, const char* name) { return var.name < name; });
+ // Find the whole range:
+ auto pos2 = std::upper_bound(pos1, this->global_variables.end(), var_name,
+ [](const char* name, auto const& var) { return name < var.name; });
+ // Remove the whole range:
+ this->global_variables.erase(pos1, pos2);
}
/** Ignore a local variable in a scope
static void remove_local_variable(Frame& scope, const char* var_name, const char* subprogram_name,
Frame const& subprogram)
{
- typedef std::vector<Variable>::size_type size_type;
-
// If the current subprogram matches the given name:
- if ((subprogram_name == nullptr || (not subprogram.name.empty() && subprogram.name == subprogram_name)) &&
- not scope.variables.empty()) {
+ if (subprogram_name == nullptr || (not subprogram.name.empty() && subprogram.name == subprogram_name)) {
// Try to find the variable and remove it:
- size_type start = 0;
- size_type end = scope.variables.size() - 1;
// Binary search:
- while (start <= end) {
- size_type cursor = start + (end - start) / 2;
- const Variable& current_var = scope.variables[cursor];
- int compare = current_var.name.compare(var_name);
- if (compare == 0) {
- // Variable found, remove it:
- scope.variables.erase(scope.variables.begin() + cursor);
- break;
- } else if (compare < 0)
- start = cursor + 1;
- else if (cursor != 0)
- end = cursor - 1;
- else
- break;
+ auto pos = std::lower_bound(scope.variables.begin(), scope.variables.end(), var_name,
+ [](auto const& var, const char* name) { return var.name < name; });
+ if (pos != scope.variables.end() && pos->name == var_name) {
+ // Variable found, remove it:
+ scope.variables.erase(pos);
}
}
*/
class Member {
public:
- typedef int flags_type;
+ using flags_type = int;
static constexpr flags_type INHERITANCE_FLAG = 1;
static constexpr flags_type VIRTUAL_POINTER_FLAG = 2;
#include "src/mc/mc_private.hpp"
#include "src/mc/remote/RemoteSimulation.hpp"
+#include <algorithm>
+#include <array>
#include <cinttypes>
#include <cstdint>
#include <cstdlib>
return std::vector<char>();
}
-static char hexdigits[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
-
/** Binary data to hexadecimal */
static inline std::array<char, 2> to_hex(std::uint8_t byte)
{
+ constexpr std::array<char, 16> hexdigits{
+ {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}};
// Horrid double braces!
// Apparently, this is needed in C++11 (not in C++14).
return {{hexdigits[byte >> 4], hexdigits[byte & 0xF]}};
{
std::string res;
res.resize(2 * count);
- for (std::size_t i = 0; i < count; i++) {
- std::array<char, 2> hex_byte = to_hex(data[i]);
- for (int j = 0; j < 2; ++j)
- res[2 * i + j] = hex_byte[j];
- }
+ for (std::size_t i = 0; i < count; i++)
+ std::copy_n(cbegin(to_hex(data[i])), 2, &res[2 * i]);
return res;
}
class UnwindContext {
simgrid::mc::AddressSpace* address_space_ = nullptr;
simgrid::mc::RemoteSimulation* process_ = nullptr;
- unw_context_t unwind_context_;
+ unw_context_t unwind_context_ = {};
public:
void initialize(simgrid::mc::RemoteSimulation* process, unw_context_t* c);
--- /dev/null
+#include "mc_api.hpp"
+
+#include "src/kernel/activity/MailboxImpl.hpp"
+#include "src/kernel/activity/MutexImpl.hpp"
+#include "src/mc/Session.hpp"
+#include "src/mc/mc_comm_pattern.hpp"
+#include "src/mc/mc_private.hpp"
+#include "src/mc/mc_smx.hpp"
+#include "src/mc/remote/RemoteSimulation.hpp"
+#include "src/mc/mc_pattern.hpp"
+#include "src/mc/checker/SimcallInspector.hpp"
+#include <xbt/asserts.h>
+#include <xbt/log.h>
+// #include <xbt/dynar.h>
+
+#if HAVE_SMPI
+#include "src/smpi/include/smpi_request.hpp"
+#endif
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_api, mc, "Logging specific to MC Fasade APIs ");
+
+using Simcall = simgrid::simix::Simcall;
+
+namespace simgrid {
+namespace mc {
+
+static inline const char* get_color(int id)
+{
+ static constexpr std::array<const char*, 13> colors{{"blue", "red", "green3", "goldenrod", "brown", "purple",
+ "magenta", "turquoise4", "gray25", "forestgreen", "hotpink",
+ "lightblue", "tan"}};
+ return colors[id % colors.size()];
+}
+
+static char *pointer_to_string(void *pointer)
+{
+ if (XBT_LOG_ISENABLED(mc_api, xbt_log_priority_verbose))
+ return bprintf("%p", pointer);
+
+ return xbt_strdup("(verbose only)");
+}
+
+static char *buff_size_to_string(size_t buff_size)
+{
+ if (XBT_LOG_ISENABLED(mc_api, xbt_log_priority_verbose))
+ return bprintf("%zu", buff_size);
+
+ return xbt_strdup("(verbose only)");
+}
+
+/* Search an enabled transition for the given process.
+ *
+ * This can be seen as an iterator returning the next transition of the process.
+ *
+ * We only consider the processes that are both
+ * - marked "to be interleaved" in their ActorState (controlled by the checker algorithm).
+ * - which simcall can currently be executed (like a comm where the other partner is already known)
+ * Once we returned the last enabled transition of a process, it is marked done.
+ *
+ * Things can get muddled with the WAITANY and TESTANY simcalls, that are rewritten on the fly to a bunch of WAIT
+ * (resp TEST) transitions using the transition.argument field to remember what was the last returned sub-transition.
+ */
+static inline smx_simcall_t MC_state_choose_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
+{
+ /* reset the outgoing transition */
+ simgrid::mc::ActorState* procstate = &state->actor_states_[actor->get_pid()];
+ state->transition_.pid_ = -1;
+ state->transition_.argument_ = -1;
+ state->executed_req_.call_ = Simcall::NONE;
+
+ if (not simgrid::mc::actor_is_enabled(actor))
+ return nullptr; // Not executable in the application
+
+ smx_simcall_t req = nullptr;
+ switch (actor->simcall_.call_) {
+ case Simcall::COMM_WAITANY:
+ state->transition_.argument_ = -1;
+ while (procstate->times_considered < simcall_comm_waitany__get__count(&actor->simcall_)) {
+ if (simgrid::mc::request_is_enabled_by_idx(&actor->simcall_, procstate->times_considered)) {
+ state->transition_.argument_ = procstate->times_considered;
+ ++procstate->times_considered;
+ break;
+ }
+ ++procstate->times_considered;
+ }
+
+ if (procstate->times_considered >= simcall_comm_waitany__get__count(&actor->simcall_))
+ procstate->set_done();
+ if (state->transition_.argument_ != -1)
+ req = &actor->simcall_;
+ break;
+
+ case Simcall::COMM_TESTANY: {
+ unsigned start_count = procstate->times_considered;
+ state->transition_.argument_ = -1;
+ while (procstate->times_considered < simcall_comm_testany__get__count(&actor->simcall_)) {
+ if (simgrid::mc::request_is_enabled_by_idx(&actor->simcall_, procstate->times_considered)) {
+ state->transition_.argument_ = procstate->times_considered;
+ ++procstate->times_considered;
+ break;
+ }
+ ++procstate->times_considered;
+ }
+
+ if (procstate->times_considered >= simcall_comm_testany__get__count(&actor->simcall_))
+ procstate->set_done();
+
+ if (state->transition_.argument_ != -1 || start_count == 0)
+ req = &actor->simcall_;
+
+ break;
+ }
+
+ case Simcall::COMM_WAIT: {
+ simgrid::mc::RemotePtr<simgrid::kernel::activity::CommImpl> remote_act =
+ remote(simcall_comm_wait__getraw__comm(&actor->simcall_));
+ simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_act;
+ mc_model_checker->get_remote_simulation().read(temp_act, remote_act);
+ const simgrid::kernel::activity::CommImpl* act = temp_act.get_buffer();
+ if (act->src_actor_.get() && act->dst_actor_.get())
+ state->transition_.argument_ = 0; // OK
+ else if (act->src_actor_.get() == nullptr && act->type_ == simgrid::kernel::activity::CommImpl::Type::READY &&
+ act->detached())
+ state->transition_.argument_ = 0; // OK
+ else
+ state->transition_.argument_ = -1; // timeout
+ procstate->set_done();
+ req = &actor->simcall_;
+ break;
+ }
+
+ case Simcall::MC_RANDOM: {
+ int min_value = simcall_mc_random__get__min(&actor->simcall_);
+ state->transition_.argument_ = procstate->times_considered + min_value;
+ procstate->times_considered++;
+ if (state->transition_.argument_ == simcall_mc_random__get__max(&actor->simcall_))
+ procstate->set_done();
+ req = &actor->simcall_;
+ break;
+ }
+
+ default:
+ procstate->set_done();
+ state->transition_.argument_ = 0;
+ req = &actor->simcall_;
+ break;
+ }
+ if (not req)
+ return nullptr;
+
+ state->transition_.pid_ = actor->get_pid();
+ state->executed_req_ = *req;
+ // Fetch the data of the request and translate it:
+ state->internal_req_ = *req;
+
+ /* The waitany and testany request are transformed into a wait or test request over the corresponding communication
+ * action so it can be treated later by the dependence function. */
+ switch (req->call_) {
+ case Simcall::COMM_WAITANY: {
+ state->internal_req_.call_ = Simcall::COMM_WAIT;
+ simgrid::kernel::activity::CommImpl* remote_comm;
+ remote_comm = mc_model_checker->get_remote_simulation().read(
+ remote(simcall_comm_waitany__get__comms(req) + state->transition_.argument_));
+ mc_model_checker->get_remote_simulation().read(state->internal_comm_, remote(remote_comm));
+ simcall_comm_wait__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
+ simcall_comm_wait__set__timeout(&state->internal_req_, 0);
+ break;
+ }
+
+ case Simcall::COMM_TESTANY:
+ state->internal_req_.call_ = Simcall::COMM_TEST;
+
+ if (state->transition_.argument_ > 0) {
+ simgrid::kernel::activity::CommImpl* remote_comm = mc_model_checker->get_remote_simulation().read(
+ remote(simcall_comm_testany__get__comms(req) + state->transition_.argument_));
+ mc_model_checker->get_remote_simulation().read(state->internal_comm_, remote(remote_comm));
+ }
+
+ simcall_comm_test__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
+ simcall_comm_test__set__result(&state->internal_req_, state->transition_.argument_);
+ break;
+
+ case Simcall::COMM_WAIT:
+ mc_model_checker->get_remote_simulation().read_bytes(&state->internal_comm_, sizeof(state->internal_comm_),
+ remote(simcall_comm_wait__getraw__comm(req)));
+ simcall_comm_wait__set__comm(&state->executed_req_, state->internal_comm_.get_buffer());
+ simcall_comm_wait__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
+ break;
+
+ case Simcall::COMM_TEST:
+ mc_model_checker->get_remote_simulation().read_bytes(&state->internal_comm_, sizeof(state->internal_comm_),
+ remote(simcall_comm_test__getraw__comm(req)));
+ simcall_comm_test__set__comm(&state->executed_req_, state->internal_comm_.get_buffer());
+ simcall_comm_test__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
+ break;
+
+ default:
+ /* No translation needed */
+ break;
+ }
+
+ return req;
+}
+
+void mc_api::initialize(char** argv)
+{
+ simgrid::mc::session = new simgrid::mc::Session([argv] {
+ int i = 1;
+ while (argv[i] != nullptr && argv[i][0] == '-')
+ i++;
+ xbt_assert(argv[i] != nullptr,
+ "Unable to find a binary to exec on the command line. Did you only pass config flags?");
+ execvp(argv[i], argv + i);
+ xbt_die("The model-checked process failed to exec(): %s", strerror(errno));
+ });
+}
+
+std::vector<simgrid::mc::ActorInformation>& mc_api::get_actors() const
+{
+ return mc_model_checker->get_remote_simulation().actors();
+}
+
+bool mc_api::actor_is_enabled(aid_t pid) const
+{
+ return session->actor_is_enabled(pid);
+}
+
+unsigned long mc_api::get_maxpid() const
+{
+ return MC_smx_get_maxpid();
+}
+
+int mc_api::get_actors_size() const
+{
+ return mc_model_checker->get_remote_simulation().actors().size();
+}
+
+bool mc_api::comm_addr_equal(const kernel::activity::CommImpl* comm_addr1, const kernel::activity::CommImpl* comm_addr2) const
+{
+ return remote(comm_addr1) == remote(comm_addr2);
+}
+
+kernel::activity::CommImpl* mc_api::get_comm_isend_raw_addr(smx_simcall_t request) const
+{
+ auto comm_addr = simcall_comm_isend__getraw__result(request);
+ return static_cast<kernel::activity::CommImpl*>(comm_addr);
+}
+
+kernel::activity::CommImpl* mc_api::get_comm_wait_raw_addr(smx_simcall_t request) const
+{
+ return simcall_comm_wait__getraw__comm(request);
+}
+
+kernel::activity::CommImpl* mc_api::get_comm_waitany_raw_addr(smx_simcall_t request, int value) const
+{
+ auto addr = mc_model_checker->get_remote_simulation().read(remote(simcall_comm_waitany__getraw__comms(request) + value));
+ return static_cast<simgrid::kernel::activity::CommImpl*>(addr);
+}
+
+std::string mc_api::get_pattern_comm_rdv(void* addr) const
+{
+ Remote<kernel::activity::CommImpl> temp_synchro;
+ mc_model_checker->get_remote_simulation().read(temp_synchro, remote((simgrid::kernel::activity::CommImpl*)addr));
+ const kernel::activity::CommImpl* synchro = temp_synchro.get_buffer();
+
+ char* remote_name = mc_model_checker->get_remote_simulation().read<char*>(RemotePtr<char*>(
+ (uint64_t)(synchro->get_mailbox() ? &synchro->get_mailbox()->get_name() : &synchro->mbox_cpy->get_name())));
+ auto rdv = mc_model_checker->get_remote_simulation().read_string(RemotePtr<char>(remote_name));
+ return rdv;
+}
+
+unsigned long mc_api::get_pattern_comm_src_proc(void* addr) const
+{
+ Remote<kernel::activity::CommImpl> temp_synchro;
+ mc_model_checker->get_remote_simulation().read(temp_synchro, remote((simgrid::kernel::activity::CommImpl*)addr));
+ const kernel::activity::CommImpl* synchro = temp_synchro.get_buffer();
+ auto src_proc = mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(synchro->src_actor_.get()))->get_pid();
+ return src_proc;
+}
+
+unsigned long mc_api::get_pattern_comm_dst_proc(void* addr) const
+{
+ Remote<kernel::activity::CommImpl> temp_synchro;
+ mc_model_checker->get_remote_simulation().read(temp_synchro, remote((simgrid::kernel::activity::CommImpl*)addr));
+ const kernel::activity::CommImpl* synchro = temp_synchro.get_buffer();
+ auto src_proc = mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(synchro->dst_actor_.get()))->get_pid();
+ return src_proc;
+}
+
+std::vector<char> mc_api::get_pattern_comm_data(void* addr) const
+{
+ Remote<kernel::activity::CommImpl> temp_synchro;
+ mc_model_checker->get_remote_simulation().read(temp_synchro, remote((simgrid::kernel::activity::CommImpl*)addr));
+ const kernel::activity::CommImpl* synchro = temp_synchro.get_buffer();
+
+ std::vector<char> buffer {};
+ if (synchro->src_buff_ != nullptr) {
+ buffer.resize(synchro->src_buff_size_);
+ mc_model_checker->get_remote_simulation().read_bytes(buffer.data(), buffer.size(),
+ remote(synchro->src_buff_));
+ }
+ return buffer;
+}
+
+std::vector<char> mc_api::get_pattern_comm_data(const kernel::activity::CommImpl* comm_addr) const
+{
+ simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_comm;
+ mc_model_checker->get_remote_simulation().read(temp_comm, remote((kernel::activity::CommImpl*)comm_addr));
+ const simgrid::kernel::activity::CommImpl* comm = temp_comm.get_buffer();
+
+ std::vector<char> buffer {};
+ if (comm->src_buff_ != nullptr) {
+ buffer.resize(comm->src_buff_size_);
+ mc_model_checker->get_remote_simulation().read_bytes(buffer.data(), buffer.size(),
+ remote(comm->src_buff_));
+ }
+ return buffer;
+}
+
+const char* mc_api::get_actor_host_name(smx_actor_t actor) const
+{
+ const char* host_name = MC_smx_actor_get_host_name(actor);
+ return host_name;
+}
+
+#if HAVE_SMPI
+bool mc_api::check_send_request_detached(smx_simcall_t const& simcall) const
+{
+ simgrid::smpi::Request mpi_request;
+ mc_model_checker->get_remote_simulation().read(
+ &mpi_request, remote(static_cast<smpi::Request*>(simcall_comm_isend__get__data(simcall))));
+ return mpi_request.detached();
+}
+#endif
+
+smx_actor_t mc_api::get_src_actor(const kernel::activity::CommImpl* comm_addr) const
+{
+ simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_comm;
+ mc_model_checker->get_remote_simulation().read(temp_comm, remote((kernel::activity::CommImpl*)comm_addr));
+ const simgrid::kernel::activity::CommImpl* comm = temp_comm.get_buffer();
+
+ auto src_proc = mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(comm->src_actor_.get()));
+ return src_proc;
+}
+
+smx_actor_t mc_api::get_dst_actor(const kernel::activity::CommImpl* comm_addr) const
+{
+ simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_comm;
+ mc_model_checker->get_remote_simulation().read(temp_comm, remote((kernel::activity::CommImpl*)comm_addr));
+ const simgrid::kernel::activity::CommImpl* comm = temp_comm.get_buffer();
+
+ auto dst_proc = mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(comm->dst_actor_.get()));
+ return dst_proc;
+}
+
+std::size_t mc_api::get_remote_heap_bytes() const
+{
+ RemoteSimulation& process = mc_model_checker->get_remote_simulation();
+ auto heap_bytes_used = mmalloc_get_bytes_used_remote(process.get_heap()->heaplimit, process.get_malloc_info());
+ return heap_bytes_used;
+}
+
+void mc_api::session_initialize() const
+{
+ session->initialize();
+}
+
+ModelChecker* mc_api::get_model_checker() const
+{
+ return mc_model_checker;
+}
+
+void mc_api::mc_inc_visited_states() const
+{
+ mc_model_checker->visited_states++;
+}
+
+void mc_api::mc_inc_executed_trans() const
+{
+ mc_model_checker->executed_transitions++;
+}
+
+unsigned long mc_api::mc_get_visited_states() const
+{
+ return mc_model_checker->visited_states;
+}
+
+unsigned long mc_api::mc_get_executed_trans() const
+{
+ return mc_model_checker->executed_transitions;
+}
+
+bool mc_api::mc_check_deadlock() const
+{
+ return mc_model_checker->checkDeadlock();
+}
+
+void mc_api::mc_show_deadlock() const
+{
+ MC_show_deadlock();
+}
+
+smx_actor_t mc_api::simcall_get_issuer(s_smx_simcall const* req) const
+{
+ return MC_smx_simcall_get_issuer(req);
+}
+
+bool mc_api::mc_is_null() const
+{
+ auto is_null = (mc_model_checker == nullptr) ? true : false;
+ return is_null;
+}
+
+Checker* mc_api::mc_get_checker() const
+{
+ return mc_model_checker->getChecker();
+}
+
+void mc_api::set_checker(Checker* const checker) const
+{
+ xbt_assert(mc_model_checker);
+ xbt_assert(mc_model_checker->getChecker() == nullptr);
+ mc_model_checker->setChecker(checker);
+}
+
+RemoteSimulation& mc_api::mc_get_remote_simulation() const
+{
+ return mc_model_checker->get_remote_simulation();
+}
+
+void mc_api::handle_simcall(Transition const& transition) const
+{
+ mc_model_checker->handle_simcall(transition);
+}
+
+void mc_api::mc_wait_for_requests() const
+{
+ mc_model_checker->wait_for_requests();
+}
+
+void mc_api::mc_exit(int status) const
+{
+ mc_model_checker->exit(status);
+}
+
+std::string const& mc_api::mc_get_host_name(std::string const& hostname) const
+{
+ return mc_model_checker->get_host_name(hostname);
+}
+
+void mc_api::dump_record_path() const
+{
+ simgrid::mc::dumpRecordPath();
+}
+
+smx_simcall_t mc_api::mc_state_choose_request(simgrid::mc::State* state) const
+{
+ for (auto& actor : mc_model_checker->get_remote_simulation().actors()) {
+ /* Only consider the actors that were marked as interleaving by the checker algorithm */
+ if (not state->actor_states_[actor.copy.get_buffer()->get_pid()].is_todo())
+ continue;
+
+ smx_simcall_t res = MC_state_choose_request_for_process(state, actor.copy.get_buffer());
+ if (res)
+ return res;
+ }
+ return nullptr;
+}
+
+bool mc_api::request_depend(smx_simcall_t req1, smx_simcall_t req2) const
+{
+ return simgrid::mc::request_depend(req1, req2);
+}
+
+std::string mc_api::request_to_string(smx_simcall_t req, int value, RequestType request_type) const
+{
+ xbt_assert(mc_model_checker != nullptr, "Must be called from MCer");
+
+ if (req->inspector_ != nullptr)
+ return req->inspector_->to_string();
+
+ bool use_remote_comm = true;
+ switch(request_type) {
+ case simgrid::mc::RequestType::simix:
+ use_remote_comm = true;
+ break;
+ case simgrid::mc::RequestType::executed:
+ case simgrid::mc::RequestType::internal:
+ use_remote_comm = false;
+ break;
+ default:
+ THROW_IMPOSSIBLE;
+ }
+
+ const char* type = nullptr;
+ char *args = nullptr;
+
+ smx_actor_t issuer = MC_smx_simcall_get_issuer(req);
+
+ switch (req->call_) {
+ case Simcall::COMM_ISEND: {
+ type = "iSend";
+ char* p = pointer_to_string(simcall_comm_isend__get__src_buff(req));
+ char* bs = buff_size_to_string(simcall_comm_isend__get__src_buff_size(req));
+ if (issuer->get_host())
+ args = bprintf("src=(%ld)%s (%s), buff=%s, size=%s", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
+ MC_smx_actor_get_name(issuer), p, bs);
+ else
+ args = bprintf("src=(%ld)%s, buff=%s, size=%s", issuer->get_pid(), MC_smx_actor_get_name(issuer), p, bs);
+ xbt_free(bs);
+ xbt_free(p);
+ break;
+ }
+
+ case Simcall::COMM_IRECV: {
+ size_t* remote_size = simcall_comm_irecv__get__dst_buff_size(req);
+ size_t size = 0;
+ if (remote_size)
+ mc_model_checker->get_remote_simulation().read_bytes(&size, sizeof(size), remote(remote_size));
+
+ type = "iRecv";
+ char* p = pointer_to_string(simcall_comm_irecv__get__dst_buff(req));
+ char* bs = buff_size_to_string(size);
+ if (issuer->get_host())
+ args = bprintf("dst=(%ld)%s (%s), buff=%s, size=%s", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
+ MC_smx_actor_get_name(issuer), p, bs);
+ else
+ args = bprintf("dst=(%ld)%s, buff=%s, size=%s", issuer->get_pid(), MC_smx_actor_get_name(issuer), p, bs);
+ xbt_free(bs);
+ xbt_free(p);
+ break;
+ }
+
+ case Simcall::COMM_WAIT: {
+ simgrid::kernel::activity::CommImpl* remote_act = simcall_comm_wait__getraw__comm(req);
+ char* p;
+ if (value == -1) {
+ type = "WaitTimeout";
+ p = pointer_to_string(remote_act);
+ args = bprintf("comm=%s", p);
+ } else {
+ type = "Wait";
+ p = pointer_to_string(remote_act);
+
+ simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_synchro;
+ const simgrid::kernel::activity::CommImpl* act;
+ if (use_remote_comm) {
+ mc_model_checker->get_remote_simulation().read(temp_synchro, remote(remote_act));
+ act = temp_synchro.get_buffer();
+ } else
+ act = remote_act;
+
+ smx_actor_t src_proc =
+ mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(act->src_actor_.get()));
+ smx_actor_t dst_proc =
+ mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(act->dst_actor_.get()));
+ args = bprintf("comm=%s [(%ld)%s (%s)-> (%ld)%s (%s)]", p, src_proc ? src_proc->get_pid() : 0,
+ src_proc ? MC_smx_actor_get_host_name(src_proc) : "",
+ src_proc ? MC_smx_actor_get_name(src_proc) : "", dst_proc ? dst_proc->get_pid() : 0,
+ dst_proc ? MC_smx_actor_get_host_name(dst_proc) : "",
+ dst_proc ? MC_smx_actor_get_name(dst_proc) : "");
+ }
+ xbt_free(p);
+ break;
+ }
+
+ case Simcall::COMM_TEST: {
+ simgrid::kernel::activity::CommImpl* remote_act = simcall_comm_test__getraw__comm(req);
+ simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_synchro;
+ const simgrid::kernel::activity::CommImpl* act;
+ if (use_remote_comm) {
+ mc_model_checker->get_remote_simulation().read(temp_synchro, remote(remote_act));
+ act = temp_synchro.get_buffer();
+ } else
+ act = remote_act;
+
+ char* p;
+ if (act->src_actor_.get() == nullptr || act->dst_actor_.get() == nullptr) {
+ type = "Test FALSE";
+ p = pointer_to_string(remote_act);
+ args = bprintf("comm=%s", p);
+ } else {
+ type = "Test TRUE";
+ p = pointer_to_string(remote_act);
+
+ smx_actor_t src_proc =
+ mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(act->src_actor_.get()));
+ smx_actor_t dst_proc =
+ mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(act->dst_actor_.get()));
+ args = bprintf("comm=%s [(%ld)%s (%s) -> (%ld)%s (%s)]", p, src_proc->get_pid(),
+ MC_smx_actor_get_name(src_proc), MC_smx_actor_get_host_name(src_proc), dst_proc->get_pid(),
+ MC_smx_actor_get_name(dst_proc), MC_smx_actor_get_host_name(dst_proc));
+ }
+ xbt_free(p);
+ break;
+ }
+
+ case Simcall::COMM_WAITANY: {
+ type = "WaitAny";
+ size_t count = simcall_comm_waitany__get__count(req);
+ if (count > 0) {
+ simgrid::kernel::activity::CommImpl* remote_sync;
+ remote_sync =
+ mc_model_checker->get_remote_simulation().read(remote(simcall_comm_waitany__get__comms(req) + value));
+ char* p = pointer_to_string(remote_sync);
+ args = bprintf("comm=%s (%d of %zu)", p, value + 1, count);
+ xbt_free(p);
+ } else
+ args = bprintf("comm at idx %d", value);
+ break;
+ }
+
+ case Simcall::COMM_TESTANY:
+ if (value == -1) {
+ type = "TestAny FALSE";
+ args = xbt_strdup("-");
+ } else {
+ type = "TestAny";
+ args = bprintf("(%d of %zu)", value + 1, simcall_comm_testany__get__count(req));
+ }
+ break;
+
+ case Simcall::MUTEX_TRYLOCK:
+ case Simcall::MUTEX_LOCK: {
+ if (req->call_ == Simcall::MUTEX_LOCK)
+ type = "Mutex LOCK";
+ else
+ type = "Mutex TRYLOCK";
+
+ simgrid::mc::Remote<simgrid::kernel::activity::MutexImpl> mutex;
+ mc_model_checker->get_remote_simulation().read_bytes(mutex.get_buffer(), sizeof(mutex),
+ remote(req->call_ == Simcall::MUTEX_LOCK
+ ? simcall_mutex_lock__get__mutex(req)
+ : simcall_mutex_trylock__get__mutex(req)));
+ args = bprintf("locked = %d, owner = %d, sleeping = n/a", mutex.get_buffer()->is_locked(),
+ mutex.get_buffer()->get_owner() != nullptr
+ ? (int)mc_model_checker->get_remote_simulation()
+ .resolve_actor(simgrid::mc::remote(mutex.get_buffer()->get_owner()))
+ ->get_pid()
+ : -1);
+ break;
+ }
+
+ case Simcall::MC_RANDOM:
+ type = "MC_RANDOM";
+ args = bprintf("%d", value);
+ break;
+
+ default:
+ type = SIMIX_simcall_name(req->call_);
+ args = bprintf("??");
+ break;
+ }
+
+ std::string str;
+ if (args != nullptr)
+ str = simgrid::xbt::string_printf("[(%ld)%s (%s)] %s(%s)", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
+ MC_smx_actor_get_name(issuer), type, args);
+ else
+ str = simgrid::xbt::string_printf("[(%ld)%s (%s)] %s ", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
+ MC_smx_actor_get_name(issuer), type);
+ xbt_free(args);
+ return str;
+}
+
+std::string mc_api::request_get_dot_output(smx_simcall_t req, int value) const
+{
+ const smx_actor_t issuer = MC_smx_simcall_get_issuer(req);
+ const char* color = get_color(issuer->get_pid() - 1);
+
+ if (req->inspector_ != nullptr)
+ return simgrid::xbt::string_printf("label = \"%s\", color = %s, fontcolor = %s",
+ req->inspector_->dot_label().c_str(), color, color);
+
+ std::string label;
+
+ switch (req->call_) {
+ case Simcall::COMM_ISEND:
+ if (issuer->get_host())
+ label = xbt::string_printf("[(%ld)%s] iSend", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
+ else
+ label = bprintf("[(%ld)] iSend", issuer->get_pid());
+ break;
+
+ case Simcall::COMM_IRECV:
+ if (issuer->get_host())
+ label = xbt::string_printf("[(%ld)%s] iRecv", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
+ else
+ label = xbt::string_printf("[(%ld)] iRecv", issuer->get_pid());
+ break;
+
+ case Simcall::COMM_WAIT:
+ if (value == -1) {
+ if (issuer->get_host())
+ label = xbt::string_printf("[(%ld)%s] WaitTimeout", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
+ else
+ label = xbt::string_printf("[(%ld)] WaitTimeout", issuer->get_pid());
+ } else {
+ kernel::activity::ActivityImpl* remote_act = simcall_comm_wait__getraw__comm(req);
+ Remote<kernel::activity::CommImpl> temp_comm;
+ mc_model_checker->get_remote_simulation().read(temp_comm,
+ remote(static_cast<kernel::activity::CommImpl*>(remote_act)));
+ const kernel::activity::CommImpl* comm = temp_comm.get_buffer();
+
+ const kernel::actor::ActorImpl* src_proc =
+ mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(comm->src_actor_.get()));
+ const kernel::actor::ActorImpl* dst_proc =
+ mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(comm->dst_actor_.get()));
+ if (issuer->get_host())
+ label =
+ xbt::string_printf("[(%ld)%s] Wait [(%ld)->(%ld)]", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
+ src_proc ? src_proc->get_pid() : 0, dst_proc ? dst_proc->get_pid() : 0);
+ else
+ label = xbt::string_printf("[(%ld)] Wait [(%ld)->(%ld)]", issuer->get_pid(),
+ src_proc ? src_proc->get_pid() : 0, dst_proc ? dst_proc->get_pid() : 0);
+ }
+ break;
+
+ case Simcall::COMM_TEST: {
+ kernel::activity::ActivityImpl* remote_act = simcall_comm_test__getraw__comm(req);
+ Remote<simgrid::kernel::activity::CommImpl> temp_comm;
+ mc_model_checker->get_remote_simulation().read(temp_comm,
+ remote(static_cast<kernel::activity::CommImpl*>(remote_act)));
+ const kernel::activity::CommImpl* comm = temp_comm.get_buffer();
+ if (comm->src_actor_.get() == nullptr || comm->dst_actor_.get() == nullptr) {
+ if (issuer->get_host())
+ label = xbt::string_printf("[(%ld)%s] Test FALSE", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
+ else
+ label = bprintf("[(%ld)] Test FALSE", issuer->get_pid());
+ } else {
+ if (issuer->get_host())
+ label = xbt::string_printf("[(%ld)%s] Test TRUE", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
+ else
+ label = xbt::string_printf("[(%ld)] Test TRUE", issuer->get_pid());
+ }
+ break;
+ }
+
+ case Simcall::COMM_WAITANY: {
+ size_t comms_size = simcall_comm_waitany__get__count(req);
+ if (issuer->get_host())
+ label = xbt::string_printf("[(%ld)%s] WaitAny [%d of %zu]", issuer->get_pid(),
+ MC_smx_actor_get_host_name(issuer), value + 1, comms_size);
+ else
+ label = xbt::string_printf("[(%ld)] WaitAny [%d of %zu]", issuer->get_pid(), value + 1, comms_size);
+ break;
+ }
+
+ case Simcall::COMM_TESTANY:
+ if (value == -1) {
+ if (issuer->get_host())
+ label = xbt::string_printf("[(%ld)%s] TestAny FALSE", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
+ else
+ label = xbt::string_printf("[(%ld)] TestAny FALSE", issuer->get_pid());
+ } else {
+ if (issuer->get_host())
+ label =
+ xbt::string_printf("[(%ld)%s] TestAny TRUE [%d of %lu]", issuer->get_pid(),
+ MC_smx_actor_get_host_name(issuer), value + 1, simcall_comm_testany__get__count(req));
+ else
+ label = xbt::string_printf("[(%ld)] TestAny TRUE [%d of %lu]", issuer->get_pid(), value + 1,
+ simcall_comm_testany__get__count(req));
+ }
+ break;
+
+ case Simcall::MUTEX_TRYLOCK:
+ label = xbt::string_printf("[(%ld)] Mutex TRYLOCK", issuer->get_pid());
+ break;
+
+ case Simcall::MUTEX_LOCK:
+ label = xbt::string_printf("[(%ld)] Mutex LOCK", issuer->get_pid());
+ break;
+
+ case Simcall::MC_RANDOM:
+ if (issuer->get_host())
+ label = xbt::string_printf("[(%ld)%s] MC_RANDOM (%d)", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
+ value);
+ else
+ label = xbt::string_printf("[(%ld)] MC_RANDOM (%d)", issuer->get_pid(), value);
+ break;
+
+ default:
+ THROW_UNIMPLEMENTED;
+ }
+
+ return xbt::string_printf("label = \"%s\", color = %s, fontcolor = %s", label.c_str(), color, color);
+}
+
+const char* mc_api::simcall_get_name(simgrid::simix::Simcall kind) const
+{
+ return SIMIX_simcall_name(kind);
+}
+
+#if HAVE_SMPI
+int mc_api::get_smpi_request_tag(smx_simcall_t const& simcall, simgrid::simix::Simcall type) const
+{
+ simgrid::smpi::Request mpi_request;
+ void* simcall_data = nullptr;
+ if (type == Simcall::COMM_ISEND)
+ simcall_data = simcall_comm_isend__get__data(simcall);
+ else if (type == Simcall::COMM_IRECV)
+ simcall_data = simcall_comm_irecv__get__data(simcall);
+ mc_model_checker->get_remote_simulation().read(&mpi_request, remote(static_cast<smpi::Request*>(simcall_data)));
+ return mpi_request.tag();
+}
+#endif
+
+void mc_api::restore_state(std::shared_ptr<simgrid::mc::Snapshot> system_state) const
+{
+ system_state->restore(&mc_model_checker->get_remote_simulation());
+}
+
+void mc_api::log_state() const
+{
+ session->log_state();
+}
+
+bool mc_api::snapshot_equal(const Snapshot* s1, const Snapshot* s2) const
+{
+ return simgrid::mc::snapshot_equal(s1, s2);
+}
+
+simgrid::mc::Snapshot* mc_api::take_snapshot(int num_state) const
+{
+ auto snapshot = new simgrid::mc::Snapshot(num_state);
+ return snapshot;
+}
+
+void mc_api::s_close() const
+{
+ session->close();
+}
+
+void mc_api::restore_initial_state() const
+{
+ session->restore_initial_state();
+}
+
+void mc_api::execute(Transition const& transition) const
+{
+ session->execute(transition);
+}
+
+#if SIMGRID_HAVE_MC
+void mc_api::automaton_load(const char *file) const
+{
+ MC_automaton_load(file);
+}
+#endif
+
+std::vector<int> mc_api::automaton_propositional_symbol_evaluate() const
+{
+ unsigned int cursor = 0;
+ std::vector<int> values;
+ xbt_automaton_propositional_symbol_t ps = nullptr;
+ xbt_dynar_foreach (mc::property_automaton->propositional_symbols, cursor, ps)
+ values.push_back(xbt_automaton_propositional_symbol_evaluate(ps));
+ return values;
+}
+
+std::vector<xbt_automaton_state_t> mc_api::get_automaton_state() const
+{
+ std::vector<xbt_automaton_state_t> automaton_stack;
+ unsigned int cursor = 0;
+ xbt_automaton_state_t automaton_state;
+ xbt_dynar_foreach (mc::property_automaton->states, cursor, automaton_state)
+ if (automaton_state->type == -1)
+ automaton_stack.push_back(automaton_state);
+ return automaton_stack;
+}
+
+int mc_api::compare_automaton_exp_label(const xbt_automaton_exp_label* l) const
+{
+ unsigned int cursor = 0;
+ xbt_automaton_propositional_symbol_t p = nullptr;
+ xbt_dynar_foreach (simgrid::mc::property_automaton->propositional_symbols, cursor, p) {
+ if (std::strcmp(xbt_automaton_propositional_symbol_get_name(p), l->u.predicat) == 0)
+ return cursor;
+ }
+ return -1;
+}
+
+void mc_api::set_property_automaton(xbt_automaton_state_t const& automaton_state) const
+{
+ mc::property_automaton->current_state = automaton_state;
+}
+
+xbt_automaton_exp_label_t mc_api::get_automaton_transition_label(xbt_dynar_t const& dynar, int index) const
+{
+ const xbt_automaton_transition* transition =
+ xbt_dynar_get_as(dynar, index, xbt_automaton_transition_t);
+ return transition->label;
+}
+
+xbt_automaton_state_t mc_api::get_automaton_transition_dst(xbt_dynar_t const& dynar, int index) const
+{
+ const xbt_automaton_transition* transition =
+ xbt_dynar_get_as(dynar, index, xbt_automaton_transition_t);
+ return transition->dst;
+}
+
+} // namespace mc
+} // namespace simgrid
--- /dev/null
+#ifndef SIMGRID_MC_API_HPP
+#define SIMGRID_MC_API_HPP
+
+#include <memory>
+#include <vector>
+
+#include "simgrid/forward.h"
+#include "src/mc/mc_forward.hpp"
+#include "src/mc/mc_request.hpp"
+#include "src/mc/mc_state.hpp"
+#include "src/mc/mc_record.hpp"
+#include "xbt/automaton.hpp"
+#include "xbt/base.h"
+
+namespace simgrid {
+namespace mc {
+
+/*
+** This class aimes to implement FACADE APIs for simgrid. The FACADE layer sits between the CheckerSide
+** (Unfolding_Checker, DPOR, ...) layer and the
+** AppSide layer. The goal is to drill down into the entagled details in the CheckerSide layer and break down the
+** detailes in a way that the CheckerSide eventually
+** be capable to acquire the required information through the FACADE layer rather than the direct access to the AppSide.
+*/
+
+class mc_api {
+private:
+ mc_api() = default;
+
+ struct DerefAndCompareByActorsCountAndUsedHeap {
+ template <class X, class Y> bool operator()(X const& a, Y const& b) const
+ {
+ return std::make_pair(a->actors_count, a->heap_bytes_used) < std::make_pair(b->actors_count, b->heap_bytes_used);
+ }
+ };
+
+
+public:
+ // No copy:
+ mc_api(mc_api const&) = delete;
+ void operator=(mc_api const&) = delete;
+
+ static mc_api& get()
+ {
+ static mc_api mcapi;
+ return mcapi;
+ }
+
+ void initialize(char** argv);
+
+ // ACTOR APIs
+ std::vector<simgrid::mc::ActorInformation>& get_actors() const;
+ bool actor_is_enabled(aid_t pid) const;
+ unsigned long get_maxpid() const;
+ int get_actors_size() const;
+
+ // COMMUNICATION APIs
+ bool comm_addr_equal(const kernel::activity::CommImpl* comm_addr1, const kernel::activity::CommImpl* comm_addr2) const;
+ kernel::activity::CommImpl* get_comm_isend_raw_addr(smx_simcall_t request) const;
+ kernel::activity::CommImpl* get_comm_wait_raw_addr(smx_simcall_t request) const;
+ kernel::activity::CommImpl* get_comm_waitany_raw_addr(smx_simcall_t request, int value) const;
+ std::string get_pattern_comm_rdv(void* addr) const;
+ unsigned long get_pattern_comm_src_proc(void* addr) const;
+ unsigned long get_pattern_comm_dst_proc(void* addr) const;
+ std::vector<char> get_pattern_comm_data(void* addr) const;
+ std::vector<char> get_pattern_comm_data(const kernel::activity::CommImpl* comm_addr) const;
+ const char* get_actor_host_name(smx_actor_t actor) const;
+#if HAVE_SMPI
+ bool check_send_request_detached(smx_simcall_t const& simcall) const;
+#endif
+ smx_actor_t get_src_actor(const kernel::activity::CommImpl* comm_addr) const;
+ smx_actor_t get_dst_actor(const kernel::activity::CommImpl* comm_addr) const;
+
+ // REMOTE APIs
+ std::size_t get_remote_heap_bytes() const;
+
+ // MODEL CHECKER APIs
+ ModelChecker* get_model_checker() const;
+ void mc_inc_visited_states() const;
+ void mc_inc_executed_trans() const;
+ unsigned long mc_get_visited_states() const;
+ unsigned long mc_get_executed_trans() const;
+ bool mc_check_deadlock() const;
+ void mc_show_deadlock() const;
+ bool mc_is_null() const;
+ Checker* mc_get_checker() const;
+ void set_checker(Checker* const checker) const;
+ RemoteSimulation& mc_get_remote_simulation() const;
+ void handle_simcall(Transition const& transition) const;
+ void mc_wait_for_requests() const;
+ XBT_ATTRIB_NORETURN void mc_exit(int status) const;
+ std::string const& mc_get_host_name(std::string const& hostname) const;
+ void dump_record_path() const;
+ smx_simcall_t mc_state_choose_request(simgrid::mc::State* state) const;
+
+ // SIMCALL APIs
+ bool request_depend(smx_simcall_t req1, smx_simcall_t req2) const;
+ std::string request_to_string(smx_simcall_t req, int value, RequestType request_type) const;
+ std::string request_get_dot_output(smx_simcall_t req, int value) const;
+ const char *simcall_get_name(simgrid::simix::Simcall kind) const;
+ smx_actor_t simcall_get_issuer(s_smx_simcall const* req) const;
+#if HAVE_SMPI
+ int get_smpi_request_tag(smx_simcall_t const& simcall, simgrid::simix::Simcall type) const;
+#endif
+
+ // STATE APIs
+ void restore_state(std::shared_ptr<simgrid::mc::Snapshot> system_state) const;
+ void log_state() const;
+ void restore_initial_state() const;
+
+ // SNAPSHOT APIs
+ bool snapshot_equal(const Snapshot* s1, const Snapshot* s2) const;
+ simgrid::mc::Snapshot* take_snapshot(int num_state) const;
+
+ // SESSION APIs
+ void session_initialize() const;
+ void s_close() const;
+ void execute(Transition const& transition) const;
+
+ // AUTOMATION APIs
+ #if SIMGRID_HAVE_MC
+ void automaton_load(const char *file) const;
+ #endif
+ std::vector<int> automaton_propositional_symbol_evaluate() const;
+ std::vector<xbt_automaton_state_t> get_automaton_state() const;
+ int compare_automaton_exp_label(const xbt_automaton_exp_label* l) const;
+ void set_property_automaton(xbt_automaton_state_t const& automaton_state) const;
+ inline DerefAndCompareByActorsCountAndUsedHeap compare_pair() const {
+ return DerefAndCompareByActorsCountAndUsedHeap();
+ }
+ inline int automaton_state_compare(const_xbt_automaton_state_t const& s1, const_xbt_automaton_state_t const& s2) const {
+ return xbt_automaton_state_compare(s1, s2);
+ }
+ xbt_automaton_exp_label_t get_automaton_transition_label(xbt_dynar_t const& dynar, int index) const;
+ xbt_automaton_state_t get_automaton_transition_dst(xbt_dynar_t const& dynar, int index) const;
+
+ // DYNAR APIs
+ inline unsigned long get_dynar_length(const_xbt_dynar_t const& dynar) const {
+ return xbt_dynar_length(dynar);
+ }
+};
+
+} // namespace mc
+} // namespace simgrid
+
+#endif
simix_global->run_all_actors();
for (smx_actor_t const& process : simix_global->actors_that_ran) {
const s_smx_simcall* req = &process->simcall_;
- if (req->call_ != SIMCALL_NONE && not simgrid::mc::request_is_visible(req))
+ if (req->call_ != simix::Simcall::NONE && not simgrid::mc::request_is_visible(req))
process->simcall_handle(0);
}
}
// Called from both MCer and MCed:
bool actor_is_enabled(smx_actor_t actor)
{
+// #del
#if SIMGRID_HAVE_MC
// If in the MCer, ask the client app since it has all the data
if (mc_model_checker != nullptr) {
return simgrid::mc::session->actor_is_enabled(actor->get_pid());
}
#endif
+// #
// Now, we are in the client app, no need for remote memory reading.
smx_simcall_t req = &actor->simcall_;
if (req->inspector_ != nullptr)
return req->inspector_->is_enabled();
+ using simix::Simcall;
switch (req->call_) {
- case SIMCALL_NONE:
+ case Simcall::NONE:
return false;
- case SIMCALL_COMM_WAIT: {
+ case Simcall::COMM_WAIT: {
/* FIXME: check also that src and dst processes are not suspended */
const kernel::activity::CommImpl* act = simcall_comm_wait__getraw__comm(req);
return (act->src_actor_ && act->dst_actor_);
}
- case SIMCALL_COMM_WAITANY: {
+ case Simcall::COMM_WAITANY: {
simgrid::kernel::activity::CommImpl** comms = simcall_comm_waitany__get__comms(req);
size_t count = simcall_comm_waitany__get__count(req);
for (unsigned int index = 0; index < count; ++index) {
return false;
}
- case SIMCALL_MUTEX_LOCK: {
+ case Simcall::MUTEX_LOCK: {
const kernel::activity::MutexImpl* mutex = simcall_mutex_lock__get__mutex(req);
if (mutex->get_owner() == nullptr)
return mutex->get_owner()->get_pid() == req->issuer_->get_pid();
}
- case SIMCALL_SEM_ACQUIRE: {
+ case Simcall::SEM_ACQUIRE: {
static int warned = 0;
if (not warned)
XBT_INFO("Using semaphore in model-checked code is still experimental. Use at your own risk");
return true;
}
- case SIMCALL_COND_WAIT: {
+ case Simcall::COND_WAIT: {
static int warned = 0;
if (not warned)
XBT_INFO("Using condition variables in model-checked code is still experimental. Use at your own risk");
xbt_assert(mc_model_checker == nullptr, "This should be called from the client side");
#endif
- return (req->inspector_ != nullptr && req->inspector_->is_visible()) || req->call_ == SIMCALL_COMM_ISEND ||
- req->call_ == SIMCALL_COMM_IRECV || req->call_ == SIMCALL_COMM_WAIT || req->call_ == SIMCALL_COMM_WAITANY ||
- req->call_ == SIMCALL_COMM_TEST || req->call_ == SIMCALL_COMM_TESTANY || req->call_ == SIMCALL_MC_RANDOM ||
- req->call_ == SIMCALL_MUTEX_LOCK || req->call_ == SIMCALL_MUTEX_TRYLOCK || req->call_ == SIMCALL_MUTEX_UNLOCK;
+ using simix::Simcall;
+ return (req->inspector_ != nullptr && req->inspector_->is_visible()) || req->call_ == Simcall::COMM_ISEND ||
+ req->call_ == Simcall::COMM_IRECV || req->call_ == Simcall::COMM_WAIT || req->call_ == Simcall::COMM_WAITANY ||
+ req->call_ == Simcall::COMM_TEST || req->call_ == Simcall::COMM_TESTANY || req->call_ == Simcall::MC_RANDOM ||
+ req->call_ == Simcall::MUTEX_LOCK || req->call_ == Simcall::MUTEX_TRYLOCK ||
+ req->call_ == Simcall::MUTEX_UNLOCK;
}
}
+++ /dev/null
-/* Copyright (c) 2007-2020. 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 <cstring>
-
-#include "src/mc/checker/CommunicationDeterminismChecker.hpp"
-#include "src/mc/mc_smx.hpp"
-
-using simgrid::mc::remote;
-
-static void MC_patterns_copy(std::vector<simgrid::mc::PatternCommunication*>& dest,
- std::vector<simgrid::mc::PatternCommunication> const& source)
-{
- dest.clear();
- for (simgrid::mc::PatternCommunication const& comm : source) {
- auto* copy_comm = new simgrid::mc::PatternCommunication(comm.dup());
- dest.push_back(copy_comm);
- }
-}
-
-void MC_restore_communications_pattern(simgrid::mc::State* state)
-{
- for (unsigned i = 0; i < initial_communications_pattern.size(); i++)
- initial_communications_pattern[i].index_comm = state->communication_indices_[i];
-
- for (unsigned i = 0; i < MC_smx_get_maxpid(); i++)
- MC_patterns_copy(incomplete_communications_pattern[i], state->incomplete_comm_pattern_[i]);
-}
-
-void MC_state_copy_incomplete_communications_pattern(simgrid::mc::State* state)
-{
- state->incomplete_comm_pattern_.clear();
- for (unsigned i=0; i < MC_smx_get_maxpid(); i++) {
- std::vector<simgrid::mc::PatternCommunication> res;
- for (auto const& comm : incomplete_communications_pattern[i])
- res.push_back(comm->dup());
- state->incomplete_comm_pattern_.push_back(std::move(res));
- }
-}
-
-void MC_state_copy_index_communications_pattern(simgrid::mc::State* state)
-{
- state->communication_indices_.clear();
- for (auto const& list_process_comm : initial_communications_pattern)
- state->communication_indices_.push_back(list_process_comm.index_comm);
-}
-
-void MC_handle_comm_pattern(e_mc_call_type_t call_type, smx_simcall_t req, int value, int backtracking)
-{
- // HACK, do not rely on the Checker implementation outside of it
- auto* checker = static_cast<simgrid::mc::CommunicationDeterminismChecker*>(mc_model_checker->getChecker());
-
- switch(call_type) {
- case MC_CALL_TYPE_NONE:
- break;
- case MC_CALL_TYPE_SEND:
- case MC_CALL_TYPE_RECV:
- checker->get_comm_pattern(req, call_type, backtracking);
- break;
- case MC_CALL_TYPE_WAIT:
- case MC_CALL_TYPE_WAITANY:
- {
- simgrid::mc::RemotePtr<simgrid::kernel::activity::CommImpl> comm_addr{nullptr};
- if (call_type == MC_CALL_TYPE_WAIT)
- comm_addr = remote(simcall_comm_wait__getraw__comm(req));
-
- else {
- simgrid::kernel::activity::ActivityImpl* addr;
- addr = mc_model_checker->get_remote_simulation().read(remote(simcall_comm_waitany__getraw__comms(req) + value));
- comm_addr = remote(static_cast<simgrid::kernel::activity::CommImpl*>(addr));
- }
- checker->complete_comm_pattern(comm_addr, MC_smx_simcall_get_issuer(req)->get_pid(), backtracking);
- }
- break;
- default:
- xbt_die("Unexpected call type %i", (int)call_type);
- }
-}
#define SIMGRID_MC_COMM_PATTERN_H
#include <vector>
-
-#include "smpi/smpi.h"
-#include "src/mc/mc_state.hpp"
+#include "src/mc/mc_pattern.hpp"
namespace simgrid {
namespace mc {
+enum class CallType {
+ NONE,
+ SEND,
+ RECV,
+ WAIT,
+ WAITANY,
+};
+
+enum class CommPatternDifference {
+ NONE,
+ TYPE,
+ RDV,
+ TAG,
+ SRC_PROC,
+ DST_PROC,
+ DATA_SIZE,
+ DATA,
+};
+
struct PatternCommunicationList {
unsigned int index_comm = 0;
std::vector<std::unique_ptr<simgrid::mc::PatternCommunication>> list;
};
-}
-}
+} // namespace mc
+} // namespace simgrid
extern XBT_PRIVATE std::vector<simgrid::mc::PatternCommunicationList> initial_communications_pattern;
extern XBT_PRIVATE std::vector<std::vector<simgrid::mc::PatternCommunication*>> incomplete_communications_pattern;
-enum e_mc_call_type_t {
- MC_CALL_TYPE_NONE,
- MC_CALL_TYPE_SEND,
- MC_CALL_TYPE_RECV,
- MC_CALL_TYPE_WAIT,
- MC_CALL_TYPE_WAITANY,
-};
-
-enum e_mc_comm_pattern_difference_t {
- NONE_DIFF,
- TYPE_DIFF,
- RDV_DIFF,
- TAG_DIFF,
- SRC_PROC_DIFF,
- DST_PROC_DIFF,
- DATA_SIZE_DIFF,
- DATA_DIFF,
-};
-
-static inline e_mc_call_type_t MC_get_call_type(const s_smx_simcall* req)
+static inline simgrid::mc::CallType MC_get_call_type(const s_smx_simcall* req)
{
+ using simgrid::mc::CallType;
+ using simgrid::simix::Simcall;
switch (req->call_) {
- case SIMCALL_COMM_ISEND:
- return MC_CALL_TYPE_SEND;
- case SIMCALL_COMM_IRECV:
- return MC_CALL_TYPE_RECV;
- case SIMCALL_COMM_WAIT:
- return MC_CALL_TYPE_WAIT;
- case SIMCALL_COMM_WAITANY:
- return MC_CALL_TYPE_WAITANY;
+ case Simcall::COMM_ISEND:
+ return CallType::SEND;
+ case Simcall::COMM_IRECV:
+ return CallType::RECV;
+ case Simcall::COMM_WAIT:
+ return CallType::WAIT;
+ case Simcall::COMM_WAITANY:
+ return CallType::WAITANY;
default:
- return MC_CALL_TYPE_NONE;
+ return CallType::NONE;
}
}
-XBT_PRIVATE void MC_handle_comm_pattern(e_mc_call_type_t call_type, smx_simcall_t request, int value, int backtracking);
-
-XBT_PRIVATE void MC_restore_communications_pattern(simgrid::mc::State* state);
-
-XBT_PRIVATE void MC_state_copy_incomplete_communications_pattern(simgrid::mc::State* state);
-XBT_PRIVATE void MC_state_copy_index_communications_pattern(simgrid::mc::State* state);
-
#endif
simgrid::config::Flag<bool> _sg_mc_comms_determinism{
"model-check/communications-determinism",
- {"model-check/communications_determinism"},
"Whether to enable the detection of communication determinism",
false,
[](bool) {
simgrid::config::Flag<bool> _sg_mc_send_determinism{
"model-check/send-determinism",
- {"model-check/send_determinism"},
"Enable/disable the detection of send-determinism in the communications schemes",
false,
[](bool) {
}};
simgrid::config::Flag<int> _sg_mc_max_depth{"model-check/max-depth",
- {"model-check/max_depth"},
"Maximal exploration depth (default: 1000)",
1000,
[](int) { _mc_cfg_cb_check("max depth value"); }};
simgrid::config::Flag<std::string> _sg_mc_dot_output_file{
"model-check/dot-output",
- {"model-check/dot_output"},
"Name of dot output file corresponding to graph state",
"",
[](const std::string&) { _mc_cfg_cb_check("file name for a dot output of graph state"); }};
#include "src/mc/sosp/Snapshot.hpp"
#include "xbt/backtrace.hpp"
+#include <array>
#include <libunwind.h>
#endif
void dumpStack(FILE* file, unw_cursor_t* cursor)
{
int nframe = 0;
- char buffer[100];
+ std::array<char, 100> buffer;
unw_word_t off;
do {
- const char* name = not unw_get_proc_name(cursor, buffer, 100, &off) ? buffer : "?";
+ const char* name = not unw_get_proc_name(cursor, buffer.data(), buffer.size(), &off) ? buffer.data() : "?";
// Unmangle C++ names:
auto realname = simgrid::xbt::demangle(name);
namespace simgrid {
namespace mc {
-typedef std::uint64_t hash_type;
+using hash_type = std::uint64_t;
XBT_PRIVATE hash_type hash(simgrid::mc::Snapshot const& snapshot);
--- /dev/null
+/* Copyright (c) 2007-2020. The SimGrid Team. All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef SIMGRID_MC_PATTERN_H
+#define SIMGRID_MC_PATTERN_H
+
+#include "src/kernel/activity/CommImpl.hpp"
+
+namespace simgrid {
+namespace mc {
+
+enum class PatternCommunicationType {
+ none = 0,
+ send = 1,
+ receive = 2,
+};
+
+class PatternCommunication {
+public:
+ int num = 0;
+ simgrid::kernel::activity::CommImpl* comm_addr;
+ PatternCommunicationType type = PatternCommunicationType::send;
+ unsigned long src_proc = 0;
+ unsigned long dst_proc = 0;
+ const char* src_host = nullptr;
+ const char* dst_host = nullptr;
+ std::string rdv;
+ std::vector<char> data;
+ int tag = 0;
+ int index = 0;
+
+ PatternCommunication() { std::memset(&comm_addr, 0, sizeof(comm_addr)); }
+
+ PatternCommunication dup() const
+ {
+ simgrid::mc::PatternCommunication res;
+ // num?
+ res.comm_addr = this->comm_addr;
+ res.type = this->type;
+ // src_proc?
+ // dst_proc?
+ res.dst_proc = this->dst_proc;
+ res.dst_host = this->dst_host;
+ res.rdv = this->rdv;
+ res.data = this->data;
+ // tag?
+ res.index = this->index;
+ return res;
+ }
+};
+
+/* On every state, each actor has an entry of the following type.
+ * This represents both the actor and its transition because
+ * an actor cannot have more than one enabled transition at a given time.
+ */
+class ActorState {
+ /* Possible exploration status of an actor transition in a state.
+ * Either the checker did not consider the transition, or it was considered and still to do, or considered and done.
+ */
+ enum class InterleavingType {
+ /** This actor transition is not considered by the checker (yet?) */
+ disabled = 0,
+ /** The checker algorithm decided that this actor transitions should be done at some point */
+ todo,
+ /** The checker algorithm decided that this should be done, but it was done in the meanwhile */
+ done,
+ };
+
+ /** Exploration control information */
+ InterleavingType state = InterleavingType::disabled;
+
+public:
+ /** Number of times that the process was considered to be executed */
+ // TODO, make this private
+ unsigned int times_considered = 0;
+
+ bool is_disabled() const { return this->state == InterleavingType::disabled; }
+ bool is_done() const { return this->state == InterleavingType::done; }
+ bool is_todo() const { return this->state == InterleavingType::todo; }
+ /** Mark that we should try executing this process at some point in the future of the checker algorithm */
+ void consider()
+ {
+ this->state = InterleavingType::todo;
+ this->times_considered = 0;
+ }
+ void set_done() { this->state = InterleavingType::done; }
+};
+
+} // namespace mc
+} // namespace simgrid
+
+#endif
#include "src/mc/mc_forward.hpp"
#include "src/xbt/memory_map.hpp"
-namespace simgrid {
-namespace mc {
-
-struct DerefAndCompareByActorsCountAndUsedHeap {
- template <class X, class Y> bool operator()(X const& a, Y const& b) const
- {
- return std::make_pair(a->actors_count, a->heap_bytes_used) < std::make_pair(b->actors_count, b->heap_bytes_used);
- }
-};
-}
-}
-
/********************************* MC Global **********************************/
XBT_PRIVATE void MC_init_dot_output();
if (not process)
xbt_die("Unexpected process (pid:%d).", transition.pid_);
const s_smx_simcall* simcall = &(process->simcall_);
- if (simcall == nullptr || simcall->call_ == SIMCALL_NONE)
+ if (simcall->call_ == simix::Simcall::NONE)
xbt_die("No simcall for process %d.", transition.pid_);
if (not simgrid::mc::request_is_visible(simcall) || not simgrid::mc::actor_is_enabled(process))
xbt_die("Unexpected simcall.");
namespace simgrid {
namespace mc {
-typedef std::vector<Transition> RecordTrace;
+using RecordTrace = std::vector<Transition>;
/** Convert a string representation of the path into an array of `simgrid::mc::Transition`
*/
#include <array>
using simgrid::mc::remote;
+using simgrid::simix::Simcall;
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_request, mc, "Logging specific to MC (request)");
-static char *pointer_to_string(void *pointer);
-static char *buff_size_to_string(size_t size);
-
static inline simgrid::kernel::activity::CommImpl* MC_get_comm(smx_simcall_t r)
{
switch (r->call_) {
- case SIMCALL_COMM_WAIT:
+ case Simcall::COMM_WAIT:
return simcall_comm_wait__getraw__comm(r);
- case SIMCALL_COMM_TEST:
+ case Simcall::COMM_TEST:
return simcall_comm_test__getraw__comm(r);
default:
return nullptr;
smx_mailbox_t MC_get_mbox(smx_simcall_t r)
{
switch (r->call_) {
- case SIMCALL_COMM_ISEND:
+ case Simcall::COMM_ISEND:
return simcall_comm_isend__get__mbox(r);
- case SIMCALL_COMM_IRECV:
+ case Simcall::COMM_IRECV:
return simcall_comm_irecv__get__mbox(r);
default:
return nullptr;
static inline
bool request_depend_asymmetric(smx_simcall_t r1, smx_simcall_t r2)
{
- if (r1->call_ == SIMCALL_COMM_ISEND && r2->call_ == SIMCALL_COMM_IRECV)
+ if (r1->call_ == Simcall::COMM_ISEND && r2->call_ == Simcall::COMM_IRECV)
return false;
- if (r1->call_ == SIMCALL_COMM_IRECV && r2->call_ == SIMCALL_COMM_ISEND)
+ if (r1->call_ == Simcall::COMM_IRECV && r2->call_ == Simcall::COMM_ISEND)
return false;
// Those are internal requests, we do not need indirection because those objects are copies:
const kernel::activity::CommImpl* synchro1 = MC_get_comm(r1);
const kernel::activity::CommImpl* synchro2 = MC_get_comm(r2);
- if ((r1->call_ == SIMCALL_COMM_ISEND || r1->call_ == SIMCALL_COMM_IRECV) && r2->call_ == SIMCALL_COMM_WAIT) {
+ if ((r1->call_ == Simcall::COMM_ISEND || r1->call_ == Simcall::COMM_IRECV) && r2->call_ == Simcall::COMM_WAIT) {
const kernel::activity::MailboxImpl* mbox = MC_get_mbox(r1);
if (mbox != synchro2->mbox_cpy
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;
}
/* FIXME: the following rule assumes that the result of the isend/irecv call is not stored in a buffer used in the
* test call. */
#if 0
- if((r1->call == SIMCALL_COMM_ISEND || r1->call == SIMCALL_COMM_IRECV)
- && r2->call == SIMCALL_COMM_TEST)
+ if((r1->call == Simcall::COMM_ISEND || r1->call == Simcall::COMM_IRECV)
+ && r2->call == Simcall::COMM_TEST)
return false;
#endif
- if (r1->call_ == SIMCALL_COMM_WAIT && (r2->call_ == SIMCALL_COMM_WAIT || r2->call_ == SIMCALL_COMM_TEST) &&
+ if (r1->call_ == Simcall::COMM_WAIT && (r2->call_ == Simcall::COMM_WAIT || r2->call_ == Simcall::COMM_TEST) &&
(synchro1->src_actor_.get() == nullptr || synchro1->dst_actor_.get() == nullptr))
return false;
- if (r1->call_ == SIMCALL_COMM_TEST &&
+ if (r1->call_ == Simcall::COMM_TEST &&
(simcall_comm_test__get__comm(r1) == nullptr || synchro1->src_buff_ == nullptr || synchro1->dst_buff_ == nullptr))
return false;
- if (r1->call_ == SIMCALL_COMM_TEST && r2->call_ == SIMCALL_COMM_WAIT && synchro1->src_buff_ == synchro2->src_buff_ &&
- synchro1->dst_buff_ == synchro2->dst_buff_)
+ if (r1->call_ == Simcall::COMM_TEST && r2->call_ == Simcall::COMM_WAIT &&
+ synchro1->src_buff_ == synchro2->src_buff_ && synchro1->dst_buff_ == synchro2->dst_buff_)
return false;
- if (r1->call_ == SIMCALL_COMM_WAIT && r2->call_ == SIMCALL_COMM_TEST && synchro1->src_buff_ != nullptr &&
+ if (r1->call_ == Simcall::COMM_WAIT && r2->call_ == Simcall::COMM_TEST && 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;
/* Wait with timeout transitions are not considered by the independence theorem, thus we consider them as dependent with all other transitions */
- 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))
+ 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 (req1->call_ != req2->call_)
const kernel::activity::CommImpl* synchro2 = MC_get_comm(req2);
switch (req1->call_) {
- case SIMCALL_COMM_ISEND:
+ case Simcall::COMM_ISEND:
return simcall_comm_isend__get__mbox(req1) == simcall_comm_isend__get__mbox(req2);
- case SIMCALL_COMM_IRECV:
+ case Simcall::COMM_IRECV:
return simcall_comm_irecv__get__mbox(req1) == simcall_comm_irecv__get__mbox(req2);
- case SIMCALL_COMM_WAIT:
+ 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 &&
} // namespace mc
} // namespace simgrid
-static char *pointer_to_string(void *pointer)
-{
- if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
- return bprintf("%p", pointer);
-
- return xbt_strdup("(verbose only)");
-}
-
-static char *buff_size_to_string(size_t buff_size)
-{
- if (XBT_LOG_ISENABLED(mc_request, xbt_log_priority_verbose))
- return bprintf("%zu", buff_size);
-
- return xbt_strdup("(verbose only)");
-}
-
-
-std::string simgrid::mc::request_to_string(smx_simcall_t req, int value, simgrid::mc::RequestType request_type)
-{
- xbt_assert(mc_model_checker != nullptr, "Must be called from MCer");
-
- if (req->inspector_ != nullptr)
- return req->inspector_->to_string();
-
- bool use_remote_comm = true;
- switch(request_type) {
- case simgrid::mc::RequestType::simix:
- use_remote_comm = true;
- break;
- case simgrid::mc::RequestType::executed:
- case simgrid::mc::RequestType::internal:
- use_remote_comm = false;
- break;
- default:
- THROW_IMPOSSIBLE;
- }
-
- const char* type = nullptr;
- char *args = nullptr;
-
- smx_actor_t issuer = MC_smx_simcall_get_issuer(req);
-
- switch (req->call_) {
- case SIMCALL_COMM_ISEND: {
- type = "iSend";
- char* p = pointer_to_string(simcall_comm_isend__get__src_buff(req));
- char* bs = buff_size_to_string(simcall_comm_isend__get__src_buff_size(req));
- if (issuer->get_host())
- args = bprintf("src=(%ld)%s (%s), buff=%s, size=%s", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
- MC_smx_actor_get_name(issuer), p, bs);
- else
- args = bprintf("src=(%ld)%s, buff=%s, size=%s", issuer->get_pid(), MC_smx_actor_get_name(issuer), p, bs);
- xbt_free(bs);
- xbt_free(p);
- break;
- }
-
- case SIMCALL_COMM_IRECV: {
- size_t* remote_size = simcall_comm_irecv__get__dst_buff_size(req);
- size_t size = 0;
- if (remote_size)
- mc_model_checker->get_remote_simulation().read_bytes(&size, sizeof(size), remote(remote_size));
-
- type = "iRecv";
- char* p = pointer_to_string(simcall_comm_irecv__get__dst_buff(req));
- char* bs = buff_size_to_string(size);
- if (issuer->get_host())
- args = bprintf("dst=(%ld)%s (%s), buff=%s, size=%s", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
- MC_smx_actor_get_name(issuer), p, bs);
- else
- args = bprintf("dst=(%ld)%s, buff=%s, size=%s", issuer->get_pid(), MC_smx_actor_get_name(issuer), p, bs);
- xbt_free(bs);
- xbt_free(p);
- break;
- }
-
- case SIMCALL_COMM_WAIT: {
- simgrid::kernel::activity::CommImpl* remote_act = simcall_comm_wait__getraw__comm(req);
- char* p;
- if (value == -1) {
- type = "WaitTimeout";
- p = pointer_to_string(remote_act);
- args = bprintf("comm=%s", p);
- } else {
- type = "Wait";
- p = pointer_to_string(remote_act);
-
- simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_synchro;
- const simgrid::kernel::activity::CommImpl* act;
- if (use_remote_comm) {
- mc_model_checker->get_remote_simulation().read(temp_synchro, remote(remote_act));
- act = temp_synchro.get_buffer();
- } else
- act = remote_act;
-
- smx_actor_t src_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(act->src_actor_.get()));
- smx_actor_t dst_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(act->dst_actor_.get()));
- args = bprintf("comm=%s [(%ld)%s (%s)-> (%ld)%s (%s)]", p, src_proc ? src_proc->get_pid() : 0,
- src_proc ? MC_smx_actor_get_host_name(src_proc) : "",
- src_proc ? MC_smx_actor_get_name(src_proc) : "", dst_proc ? dst_proc->get_pid() : 0,
- dst_proc ? MC_smx_actor_get_host_name(dst_proc) : "",
- dst_proc ? MC_smx_actor_get_name(dst_proc) : "");
- }
- xbt_free(p);
- break;
- }
-
- case SIMCALL_COMM_TEST: {
- simgrid::kernel::activity::CommImpl* remote_act = simcall_comm_test__getraw__comm(req);
- simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_synchro;
- const simgrid::kernel::activity::CommImpl* act;
- if (use_remote_comm) {
- mc_model_checker->get_remote_simulation().read(temp_synchro, remote(remote_act));
- act = temp_synchro.get_buffer();
- } else
- act = remote_act;
-
- char* p;
- if (act->src_actor_.get() == nullptr || act->dst_actor_.get() == nullptr) {
- type = "Test FALSE";
- p = pointer_to_string(remote_act);
- args = bprintf("comm=%s", p);
- } else {
- type = "Test TRUE";
- p = pointer_to_string(remote_act);
-
- smx_actor_t src_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(act->src_actor_.get()));
- smx_actor_t dst_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(simgrid::mc::remote(act->dst_actor_.get()));
- args = bprintf("comm=%s [(%ld)%s (%s) -> (%ld)%s (%s)]", p, src_proc->get_pid(),
- MC_smx_actor_get_name(src_proc), MC_smx_actor_get_host_name(src_proc), dst_proc->get_pid(),
- MC_smx_actor_get_name(dst_proc), MC_smx_actor_get_host_name(dst_proc));
- }
- xbt_free(p);
- break;
- }
-
- case SIMCALL_COMM_WAITANY: {
- type = "WaitAny";
- size_t count = simcall_comm_waitany__get__count(req);
- if (count > 0) {
- simgrid::kernel::activity::CommImpl* remote_sync;
- remote_sync =
- mc_model_checker->get_remote_simulation().read(remote(simcall_comm_waitany__get__comms(req) + value));
- char* p = pointer_to_string(remote_sync);
- args = bprintf("comm=%s (%d of %zu)", p, value + 1, count);
- xbt_free(p);
- } else
- args = bprintf("comm at idx %d", value);
- break;
- }
-
- case SIMCALL_COMM_TESTANY:
- if (value == -1) {
- type = "TestAny FALSE";
- args = xbt_strdup("-");
- } else {
- type = "TestAny";
- args = bprintf("(%d of %zu)", value + 1, simcall_comm_testany__get__count(req));
- }
- break;
-
- case SIMCALL_MUTEX_TRYLOCK:
- case SIMCALL_MUTEX_LOCK: {
- if (req->call_ == SIMCALL_MUTEX_LOCK)
- type = "Mutex LOCK";
- else
- type = "Mutex TRYLOCK";
-
- simgrid::mc::Remote<simgrid::kernel::activity::MutexImpl> mutex;
- mc_model_checker->get_remote_simulation().read_bytes(mutex.get_buffer(), sizeof(mutex),
- remote(req->call_ == SIMCALL_MUTEX_LOCK
- ? simcall_mutex_lock__get__mutex(req)
- : simcall_mutex_trylock__get__mutex(req)));
- args = bprintf("locked = %d, owner = %d, sleeping = n/a", mutex.get_buffer()->is_locked(),
- mutex.get_buffer()->get_owner() != nullptr
- ? (int)mc_model_checker->get_remote_simulation()
- .resolve_actor(simgrid::mc::remote(mutex.get_buffer()->get_owner()))
- ->get_pid()
- : -1);
- break;
- }
-
- case SIMCALL_MC_RANDOM:
- type = "MC_RANDOM";
- args = bprintf("%d", value);
- break;
-
- default:
- type = SIMIX_simcall_name(req->call_);
- args = bprintf("??");
- break;
- }
-
- std::string str;
- if (args != nullptr)
- str = simgrid::xbt::string_printf("[(%ld)%s (%s)] %s(%s)", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
- MC_smx_actor_get_name(issuer), type, args);
- else
- str = simgrid::xbt::string_printf("[(%ld)%s (%s)] %s ", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
- MC_smx_actor_get_name(issuer), type);
- xbt_free(args);
- return str;
-}
-
namespace simgrid {
namespace mc {
{
kernel::activity::CommImpl* remote_act = nullptr;
switch (req->call_) {
- case SIMCALL_COMM_WAIT:
+ case Simcall::COMM_WAIT:
/* FIXME: check also that src and dst processes are not suspended */
remote_act = simcall_comm_wait__getraw__comm(req);
break;
- case SIMCALL_COMM_WAITANY:
- remote_act = mc_model_checker->get_remote_simulation().read(remote(simcall_comm_testany__get__comms(req) + idx));
+ case Simcall::COMM_WAITANY:
+ remote_act = mc_model_checker->get_remote_simulation().read(remote(simcall_comm_waitany__get__comms(req) + idx));
break;
- case SIMCALL_COMM_TESTANY:
+ case Simcall::COMM_TESTANY:
remote_act = mc_model_checker->get_remote_simulation().read(remote(simcall_comm_testany__get__comms(req) + idx));
break;
return comm->src_actor_.get() && comm->dst_actor_.get();
}
-static inline const char* get_color(int id)
-{
- static constexpr std::array<const char*, 13> colors{{"blue", "red", "green3", "goldenrod", "brown", "purple",
- "magenta", "turquoise4", "gray25", "forestgreen", "hotpink",
- "lightblue", "tan"}};
- return colors[id % colors.size()];
-}
-
-std::string request_get_dot_output(smx_simcall_t req, int value)
-{
- const smx_actor_t issuer = MC_smx_simcall_get_issuer(req);
- const char* color = get_color(issuer->get_pid() - 1);
-
- if (req->inspector_ != nullptr)
- return simgrid::xbt::string_printf("label = \"%s\", color = %s, fontcolor = %s",
- req->inspector_->dot_label().c_str(), color, color);
-
- std::string label;
-
- switch (req->call_) {
- case SIMCALL_COMM_ISEND:
- if (issuer->get_host())
- label = xbt::string_printf("[(%ld)%s] iSend", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
- else
- label = bprintf("[(%ld)] iSend", issuer->get_pid());
- break;
-
- case SIMCALL_COMM_IRECV:
- if (issuer->get_host())
- label = xbt::string_printf("[(%ld)%s] iRecv", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
- else
- label = xbt::string_printf("[(%ld)] iRecv", issuer->get_pid());
- break;
-
- case SIMCALL_COMM_WAIT:
- if (value == -1) {
- if (issuer->get_host())
- label = xbt::string_printf("[(%ld)%s] WaitTimeout", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
- else
- label = xbt::string_printf("[(%ld)] WaitTimeout", issuer->get_pid());
- } else {
- kernel::activity::ActivityImpl* remote_act = simcall_comm_wait__getraw__comm(req);
- Remote<kernel::activity::CommImpl> temp_comm;
- mc_model_checker->get_remote_simulation().read(temp_comm,
- remote(static_cast<kernel::activity::CommImpl*>(remote_act)));
- const kernel::activity::CommImpl* comm = temp_comm.get_buffer();
-
- const kernel::actor::ActorImpl* src_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(comm->src_actor_.get()));
- const kernel::actor::ActorImpl* dst_proc =
- mc_model_checker->get_remote_simulation().resolve_actor(mc::remote(comm->dst_actor_.get()));
- if (issuer->get_host())
- label =
- xbt::string_printf("[(%ld)%s] Wait [(%ld)->(%ld)]", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
- src_proc ? src_proc->get_pid() : 0, dst_proc ? dst_proc->get_pid() : 0);
- else
- label = xbt::string_printf("[(%ld)] Wait [(%ld)->(%ld)]", issuer->get_pid(),
- src_proc ? src_proc->get_pid() : 0, dst_proc ? dst_proc->get_pid() : 0);
- }
- break;
-
- case SIMCALL_COMM_TEST: {
- kernel::activity::ActivityImpl* remote_act = simcall_comm_test__getraw__comm(req);
- Remote<simgrid::kernel::activity::CommImpl> temp_comm;
- mc_model_checker->get_remote_simulation().read(temp_comm,
- remote(static_cast<kernel::activity::CommImpl*>(remote_act)));
- const kernel::activity::CommImpl* comm = temp_comm.get_buffer();
- if (comm->src_actor_.get() == nullptr || comm->dst_actor_.get() == nullptr) {
- if (issuer->get_host())
- label = xbt::string_printf("[(%ld)%s] Test FALSE", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
- else
- label = bprintf("[(%ld)] Test FALSE", issuer->get_pid());
- } else {
- if (issuer->get_host())
- label = xbt::string_printf("[(%ld)%s] Test TRUE", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
- else
- label = xbt::string_printf("[(%ld)] Test TRUE", issuer->get_pid());
- }
- break;
- }
-
- case SIMCALL_COMM_WAITANY: {
- size_t comms_size = simcall_comm_waitany__get__count(req);
- if (issuer->get_host())
- label = xbt::string_printf("[(%ld)%s] WaitAny [%d of %zu]", issuer->get_pid(),
- MC_smx_actor_get_host_name(issuer), value + 1, comms_size);
- else
- label = xbt::string_printf("[(%ld)] WaitAny [%d of %zu]", issuer->get_pid(), value + 1, comms_size);
- break;
- }
-
- case SIMCALL_COMM_TESTANY:
- if (value == -1) {
- if (issuer->get_host())
- label = xbt::string_printf("[(%ld)%s] TestAny FALSE", issuer->get_pid(), MC_smx_actor_get_host_name(issuer));
- else
- label = xbt::string_printf("[(%ld)] TestAny FALSE", issuer->get_pid());
- } else {
- if (issuer->get_host())
- label =
- xbt::string_printf("[(%ld)%s] TestAny TRUE [%d of %lu]", issuer->get_pid(),
- MC_smx_actor_get_host_name(issuer), value + 1, simcall_comm_testany__get__count(req));
- else
- label = xbt::string_printf("[(%ld)] TestAny TRUE [%d of %lu]", issuer->get_pid(), value + 1,
- simcall_comm_testany__get__count(req));
- }
- break;
-
- case SIMCALL_MUTEX_TRYLOCK:
- label = xbt::string_printf("[(%ld)] Mutex TRYLOCK", issuer->get_pid());
- break;
-
- case SIMCALL_MUTEX_LOCK:
- label = xbt::string_printf("[(%ld)] Mutex LOCK", issuer->get_pid());
- break;
-
- case SIMCALL_MC_RANDOM:
- if (issuer->get_host())
- label = xbt::string_printf("[(%ld)%s] MC_RANDOM (%d)", issuer->get_pid(), MC_smx_actor_get_host_name(issuer),
- value);
- else
- label = xbt::string_printf("[(%ld)] MC_RANDOM (%d)", issuer->get_pid(), value);
- break;
-
- default:
- THROW_UNIMPLEMENTED;
- }
-
- return xbt::string_printf("label = \"%s\", color = %s, fontcolor = %s", label.c_str(), color, color);
-}
-
} // namespace mc
} // namespace simgrid
XBT_PRIVATE bool request_depend(smx_simcall_t req1, smx_simcall_t req2);
-XBT_PRIVATE std::string request_to_string(smx_simcall_t req, int value, simgrid::mc::RequestType type);
-
XBT_PRIVATE bool request_is_enabled_by_idx(smx_simcall_t req, unsigned int idx);
-
-XBT_PRIVATE std::string request_get_dot_output(smx_simcall_t req, int value);
}
}
auto remote_string_address =
remote(reinterpret_cast<const simgrid::xbt::string_data*>(&actor->get_host()->get_name()));
simgrid::xbt::string_data remote_string = process->read(remote_string_address);
- char hostname[remote_string.len];
- process->read_bytes(hostname, remote_string.len + 1, remote(remote_string.data));
- info->hostname = mc_model_checker->get_host_name(hostname).c_str();
+ std::vector<char> hostname(remote_string.len + 1);
+ // no need to read the terminating null byte, and thus hostname[remote_string.len] is guaranteed to be '\0'
+ process->read_bytes(hostname.data(), remote_string.len, remote(remote_string.data));
+ info->hostname = mc_model_checker->get_host_name(hostname.data()).c_str();
return info->hostname;
}
const char* MC_smx_actor_get_name(smx_actor_t actor)
{
- const simgrid::mc::RemoteSimulation* process = &mc_model_checker->get_remote_simulation();
if (mc_model_checker == nullptr)
return actor->get_cname();
+ const simgrid::mc::RemoteSimulation* process = &mc_model_checker->get_remote_simulation();
+
simgrid::mc::ActorInformation* info = actor_info_cast(actor);
if (info->name.empty()) {
simgrid::xbt::string_data string_data = simgrid::xbt::string::to_string_data(actor->name_);
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/mc/mc_state.hpp"
-#include "src/mc/mc_comm_pattern.hpp"
#include "src/mc/mc_config.hpp"
-#include "src/mc/mc_request.hpp"
-#include "src/mc/mc_smx.hpp"
+#include "src/mc/mc_api.hpp"
#include <boost/range/algorithm.hpp>
using simgrid::mc::remote;
+using mcapi = simgrid::mc::mc_api;
namespace simgrid {
namespace mc {
State::State(unsigned long state_number) : num_(state_number)
{
this->internal_comm_.clear();
-
- actor_states_.resize(MC_smx_get_maxpid());
+ auto maxpid = mcapi::get().get_maxpid();
+ actor_states_.resize(maxpid);
/* Stateful model checking */
if ((_sg_mc_checkpoint > 0 && (state_number % _sg_mc_checkpoint == 0)) || _sg_mc_termination) {
- system_state_ = std::make_shared<simgrid::mc::Snapshot>(num_);
+ auto snapshot_ptr = mcapi::get().take_snapshot(num_);
+ system_state_ = std::shared_ptr<simgrid::mc::Snapshot>(snapshot_ptr);
if (_sg_mc_comms_determinism || _sg_mc_send_determinism) {
- MC_state_copy_incomplete_communications_pattern(this);
- MC_state_copy_index_communications_pattern(this);
+ copy_incomplete_comm_pattern();
+ copy_index_comm_pattern();
}
}
}
return this->transition_;
}
-}
-}
-
-/* Search an enabled transition for the given process.
- *
- * This can be seen as an iterator returning the next transition of the process.
- *
- * We only consider the processes that are both
- * - marked "to be interleaved" in their ActorState (controlled by the checker algorithm).
- * - which simcall can currently be executed (like a comm where the other partner is already known)
- * Once we returned the last enabled transition of a process, it is marked done.
- *
- * Things can get muddled with the WAITANY and TESTANY simcalls, that are rewritten on the fly to a bunch of WAIT
- * (resp TEST) transitions using the transition.argument field to remember what was the last returned sub-transition.
- */
-static inline smx_simcall_t MC_state_choose_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
+void State::copy_incomplete_comm_pattern()
{
- /* reset the outgoing transition */
- simgrid::mc::ActorState* procstate = &state->actor_states_[actor->get_pid()];
- state->transition_.pid_ = -1;
- state->transition_.argument_ = -1;
- state->executed_req_.call_ = SIMCALL_NONE;
-
- if (not simgrid::mc::actor_is_enabled(actor))
- return nullptr; // Not executable in the application
-
- smx_simcall_t req = nullptr;
- switch (actor->simcall_.call_) {
- case SIMCALL_COMM_WAITANY:
- state->transition_.argument_ = -1;
- while (procstate->times_considered < simcall_comm_waitany__get__count(&actor->simcall_)) {
- if (simgrid::mc::request_is_enabled_by_idx(&actor->simcall_, procstate->times_considered)) {
- state->transition_.argument_ = procstate->times_considered;
- ++procstate->times_considered;
- break;
- }
- ++procstate->times_considered;
- }
-
- if (procstate->times_considered >= simcall_comm_waitany__get__count(&actor->simcall_))
- procstate->set_done();
- if (state->transition_.argument_ != -1)
- req = &actor->simcall_;
- break;
-
- case SIMCALL_COMM_TESTANY: {
- unsigned start_count = procstate->times_considered;
- state->transition_.argument_ = -1;
- while (procstate->times_considered < simcall_comm_testany__get__count(&actor->simcall_)) {
- if (simgrid::mc::request_is_enabled_by_idx(&actor->simcall_, procstate->times_considered)) {
- state->transition_.argument_ = procstate->times_considered;
- ++procstate->times_considered;
- break;
- }
- ++procstate->times_considered;
- }
-
- if (procstate->times_considered >= simcall_comm_testany__get__count(&actor->simcall_))
- procstate->set_done();
-
- if (state->transition_.argument_ != -1 || start_count == 0)
- req = &actor->simcall_;
-
- break;
- }
-
- case SIMCALL_COMM_WAIT: {
- simgrid::mc::RemotePtr<simgrid::kernel::activity::CommImpl> remote_act =
- remote(simcall_comm_wait__getraw__comm(&actor->simcall_));
- simgrid::mc::Remote<simgrid::kernel::activity::CommImpl> temp_act;
- mc_model_checker->get_remote_simulation().read(temp_act, remote_act);
- const simgrid::kernel::activity::CommImpl* act = temp_act.get_buffer();
- if (act->src_actor_.get() && act->dst_actor_.get())
- state->transition_.argument_ = 0; // OK
- else if (act->src_actor_.get() == nullptr && act->type_ == simgrid::kernel::activity::CommImpl::Type::READY &&
- act->detached())
- state->transition_.argument_ = 0; // OK
- else
- state->transition_.argument_ = -1; // timeout
- procstate->set_done();
- req = &actor->simcall_;
- break;
- }
-
- case SIMCALL_MC_RANDOM: {
- int min_value = simcall_mc_random__get__min(&actor->simcall_);
- state->transition_.argument_ = procstate->times_considered + min_value;
- procstate->times_considered++;
- if (state->transition_.argument_ == simcall_mc_random__get__max(&actor->simcall_))
- procstate->set_done();
- req = &actor->simcall_;
- break;
- }
-
- default:
- procstate->set_done();
- state->transition_.argument_ = 0;
- req = &actor->simcall_;
- break;
+ incomplete_comm_pattern_.clear();
+ for (unsigned long i = 0; i < mcapi::get().get_maxpid(); i++) {
+ std::vector<simgrid::mc::PatternCommunication> res;
+ for (auto const& comm : incomplete_communications_pattern[i])
+ res.push_back(comm->dup());
+ incomplete_comm_pattern_.push_back(std::move(res));
}
- if (not req)
- return nullptr;
-
- state->transition_.pid_ = actor->get_pid();
- state->executed_req_ = *req;
- // Fetch the data of the request and translate it:
- state->internal_req_ = *req;
-
- /* The waitany and testany request are transformed into a wait or test request over the corresponding communication
- * action so it can be treated later by the dependence function. */
- switch (req->call_) {
- case SIMCALL_COMM_WAITANY: {
- state->internal_req_.call_ = SIMCALL_COMM_WAIT;
- simgrid::kernel::activity::CommImpl* remote_comm;
- remote_comm = mc_model_checker->get_remote_simulation().read(
- remote(simcall_comm_waitany__get__comms(req) + state->transition_.argument_));
- mc_model_checker->get_remote_simulation().read(state->internal_comm_, remote(remote_comm));
- simcall_comm_wait__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
- simcall_comm_wait__set__timeout(&state->internal_req_, 0);
- break;
- }
-
- case SIMCALL_COMM_TESTANY:
- state->internal_req_.call_ = SIMCALL_COMM_TEST;
-
- if (state->transition_.argument_ > 0) {
- simgrid::kernel::activity::CommImpl* remote_comm = mc_model_checker->get_remote_simulation().read(
- remote(simcall_comm_testany__get__comms(req) + state->transition_.argument_));
- mc_model_checker->get_remote_simulation().read(state->internal_comm_, remote(remote_comm));
- }
-
- simcall_comm_test__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
- simcall_comm_test__set__result(&state->internal_req_, state->transition_.argument_);
- break;
-
- case SIMCALL_COMM_WAIT:
- mc_model_checker->get_remote_simulation().read_bytes(&state->internal_comm_, sizeof(state->internal_comm_),
- remote(simcall_comm_wait__getraw__comm(req)));
- simcall_comm_wait__set__comm(&state->executed_req_, state->internal_comm_.get_buffer());
- simcall_comm_wait__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
- break;
-
- case SIMCALL_COMM_TEST:
- mc_model_checker->get_remote_simulation().read_bytes(&state->internal_comm_, sizeof(state->internal_comm_),
- remote(simcall_comm_test__getraw__comm(req)));
- simcall_comm_test__set__comm(&state->executed_req_, state->internal_comm_.get_buffer());
- simcall_comm_test__set__comm(&state->internal_req_, state->internal_comm_.get_buffer());
- break;
-
- default:
- /* No translation needed */
- break;
- }
-
- return req;
}
-smx_simcall_t MC_state_choose_request(simgrid::mc::State* state)
+void State::copy_index_comm_pattern()
{
- for (auto& actor : mc_model_checker->get_remote_simulation().actors()) {
- /* Only consider the actors that were marked as interleaving by the checker algorithm */
- if (not state->actor_states_[actor.copy.get_buffer()->get_pid()].is_todo())
- continue;
+ communication_indices_.clear();
+ for (auto const& list_process_comm : initial_communications_pattern)
+ this->communication_indices_.push_back(list_process_comm.index_comm);
+}
- smx_simcall_t res = MC_state_choose_request_for_process(state, actor.copy.get_buffer());
- if (res)
- return res;
- }
- return nullptr;
+}
}
#ifndef SIMGRID_MC_STATE_HPP
#define SIMGRID_MC_STATE_HPP
-#include "src/kernel/activity/CommImpl.hpp"
#include "src/mc/Transition.hpp"
#include "src/mc/sosp/Snapshot.hpp"
+#include "src/mc/mc_comm_pattern.hpp"
namespace simgrid {
namespace mc {
-enum class PatternCommunicationType {
- none = 0,
- send = 1,
- receive = 2,
-};
-
-class PatternCommunication {
-public:
- int num = 0;
- simgrid::kernel::activity::CommImpl* comm_addr;
- PatternCommunicationType type = PatternCommunicationType::send;
- unsigned long src_proc = 0;
- unsigned long dst_proc = 0;
- const char* src_host = nullptr;
- const char* dst_host = nullptr;
- std::string rdv;
- std::vector<char> data;
- int tag = 0;
- int index = 0;
-
- PatternCommunication() { std::memset(&comm_addr, 0, sizeof(comm_addr)); }
-
- PatternCommunication dup() const
- {
- simgrid::mc::PatternCommunication res;
- // num?
- res.comm_addr = this->comm_addr;
- res.type = this->type;
- // src_proc?
- // dst_proc?
- res.dst_proc = this->dst_proc;
- res.dst_host = this->dst_host;
- res.rdv = this->rdv;
- res.data = this->data;
- // tag?
- res.index = this->index;
- return res;
- }
-};
-
-/* On every state, each actor has an entry of the following type.
- * This represents both the actor and its transition because
- * an actor cannot have more than one enabled transition at a given time.
- */
-class ActorState {
- /* Possible exploration status of an actor transition in a state.
- * Either the checker did not consider the transition, or it was considered and still to do, or considered and done.
- */
- enum class InterleavingType {
- /** This actor transition is not considered by the checker (yet?) */
- disabled = 0,
- /** The checker algorithm decided that this actor transitions should be done at some point */
- todo,
- /** The checker algorithm decided that this should be done, but it was done in the meanwhile */
- done,
- };
-
- /** Exploration control information */
- InterleavingType state = InterleavingType::disabled;
-
-public:
- /** Number of times that the process was considered to be executed */
- // TODO, make this private
- unsigned int times_considered = 0;
-
- bool is_disabled() const { return this->state == InterleavingType::disabled; }
- bool is_done() const { return this->state == InterleavingType::done; }
- bool is_todo() const { return this->state == InterleavingType::todo; }
- /** Mark that we should try executing this process at some point in the future of the checker algorithm */
- void consider()
- {
- this->state = InterleavingType::todo;
- this->times_considered = 0;
- }
- void set_done() { this->state = InterleavingType::done; }
-};
-
/* A node in the exploration graph (kind-of) */
class XBT_PRIVATE State {
public:
/* Internal translation of the executed_req simcall
*
- * SIMCALL_COMM_TESTANY is translated to a SIMCALL_COMM_TEST
- * and SIMCALL_COMM_WAITANY to a SIMCALL_COMM_WAIT.
+ * Simcall::COMM_TESTANY is translated to a Simcall::COMM_TEST
+ * and Simcall::COMM_WAITANY to a Simcall::COMM_WAIT.
*/
s_smx_simcall internal_req_;
this->actor_states_[actor->get_pid()].consider();
}
Transition get_transition() const;
+
+private:
+ void copy_incomplete_comm_pattern();
+ void copy_index_comm_pattern();
};
}
}
-XBT_PRIVATE smx_simcall_t MC_state_choose_request(simgrid::mc::State* state);
-
#endif
}
// Send result:
- s_mc_message_int_t answer{MC_MESSAGE_DEADLOCK_CHECK_REPLY, deadlock};
+ s_mc_message_int_t answer{MessageType::DEADLOCK_CHECK_REPLY, deadlock};
xbt_assert(channel_.send(answer) == 0, "Could not send response");
}
void AppSide::handle_continue(const s_mc_message_t*) const
smx_actor_t process = SIMIX_process_from_PID(message->pid);
xbt_assert(process != nullptr, "Invalid pid %lu", message->pid);
process->simcall_handle(message->value);
- if (channel_.send(MC_MESSAGE_WAITING))
+ if (channel_.send(MessageType::WAITING))
xbt_die("Could not send MESSAGE_WAITING to model-checker");
}
void AppSide::handle_actor_enabled(const s_mc_message_actor_enabled_t* msg) const
{
bool res = simgrid::mc::actor_is_enabled(SIMIX_process_from_PID(msg->aid));
- s_mc_message_int_t answer{MC_MESSAGE_ACTOR_ENABLED_REPLY, res};
+ s_mc_message_int_t answer{MessageType::ACTOR_ENABLED_REPLY, res};
channel_.send(answer);
}
while (true) {
XBT_DEBUG("Waiting messages from model-checker");
- char message_buffer[MC_MESSAGE_LENGTH];
- ssize_t received_size = channel_.receive(&message_buffer, sizeof(message_buffer));
+ std::array<char, MC_MESSAGE_LENGTH> message_buffer;
+ ssize_t received_size = channel_.receive(message_buffer.data(), message_buffer.size());
xbt_assert(received_size >= 0, "Could not receive commands from the model-checker");
- const s_mc_message_t* message = (s_mc_message_t*)message_buffer;
+ const s_mc_message_t* message = (s_mc_message_t*)message_buffer.data();
switch (message->type) {
- case MC_MESSAGE_DEADLOCK_CHECK:
+ case MessageType::DEADLOCK_CHECK:
assert_msg_size("DEADLOCK_CHECK", s_mc_message_t);
handle_deadlock_check(message);
break;
- case MC_MESSAGE_CONTINUE:
+ case MessageType::CONTINUE:
assert_msg_size("MESSAGE_CONTINUE", s_mc_message_t);
handle_continue(message);
return;
- case MC_MESSAGE_SIMCALL_HANDLE:
+ case MessageType::SIMCALL_HANDLE:
assert_msg_size("SIMCALL_HANDLE", s_mc_message_simcall_handle_t);
- handle_simcall((s_mc_message_simcall_handle_t*)message_buffer);
+ handle_simcall((s_mc_message_simcall_handle_t*)message_buffer.data());
break;
- case MC_MESSAGE_ACTOR_ENABLED:
+ case MessageType::ACTOR_ENABLED:
assert_msg_size("ACTOR_ENABLED", s_mc_message_actor_enabled_t);
- handle_actor_enabled((s_mc_message_actor_enabled_t*)message_buffer);
+ handle_actor_enabled((s_mc_message_actor_enabled_t*)message_buffer.data());
break;
default:
- xbt_die("Received unexpected message %s (%i)", MC_message_type_name(message->type), message->type);
+ xbt_die("Received unexpected message %s (%i)", MC_message_type_name(message->type),
+ static_cast<int>(message->type));
break;
}
}
{
while (true) {
simgrid::mc::wait_for_requests();
- xbt_assert(channel_.send(MC_MESSAGE_WAITING) == 0, "Could not send WAITING message to model-checker");
+ xbt_assert(channel_.send(MessageType::WAITING) == 0, "Could not send WAITING message to model-checker");
this->handle_messages();
}
}
void AppSide::report_assertion_failure() const
{
- if (channel_.send(MC_MESSAGE_ASSERTION_FAILED))
+ if (channel_.send(MessageType::ASSERTION_FAILED))
xbt_die("Could not send assertion to model-checker");
this->handle_messages();
}
void AppSide::ignore_memory(void* addr, std::size_t size) const
{
s_mc_message_ignore_memory_t message;
- message.type = MC_MESSAGE_IGNORE_MEMORY;
+ message.type = MessageType::IGNORE_MEMORY;
message.addr = (std::uintptr_t)addr;
message.size = size;
if (channel_.send(message))
const s_xbt_mheap_t* heap = mmalloc_get_current_heap();
s_mc_message_ignore_heap_t message;
- message.type = MC_MESSAGE_IGNORE_HEAP;
+ message.type = MessageType::IGNORE_HEAP;
message.address = address;
message.size = size;
message.block = ((char*)address - (char*)heap->heapbase) / BLOCKSIZE + 1;
void AppSide::unignore_heap(void* address, std::size_t size) const
{
s_mc_message_ignore_memory_t message;
- message.type = MC_MESSAGE_UNIGNORE_HEAP;
+ message.type = MessageType::UNIGNORE_HEAP;
message.addr = (std::uintptr_t)address;
message.size = size;
if (channel_.send(message))
void AppSide::declare_symbol(const char* name, int* value) const
{
s_mc_message_register_symbol_t message;
- message.type = MC_MESSAGE_REGISTER_SYMBOL;
- if (strlen(name) + 1 > sizeof(message.name))
+ message.type = MessageType::REGISTER_SYMBOL;
+ if (strlen(name) + 1 > message.name.size())
xbt_die("Symbol is too long");
- strncpy(message.name, name, sizeof(message.name));
+ strncpy(message.name.data(), name, message.name.size());
message.callback = nullptr;
message.data = value;
if (channel_.send(message))
region.block = ((char*)stack - (char*)heap->heapbase) / BLOCKSIZE + 1;
s_mc_message_stack_region_t message;
- message.type = MC_MESSAGE_STACK_REGION;
+ message.type = MessageType::STACK_REGION;
message.stack_region = region;
if (channel_.send(message))
xbt_die("Could not send STACK_REGION to model-checker");
/** @brief Send a message; returns 0 on success or errno on failure */
int Channel::send(const void* message, size_t size) const
{
- XBT_DEBUG("Send %s", MC_message_type_name(*(e_mc_message_type*)message));
+ XBT_DEBUG("Send %s", MC_message_type_name(*(MessageType*)message));
while (::send(this->socket_, message, size, 0) == -1) {
if (errno != EINTR)
return errno;
{
ssize_t res = recv(this->socket_, message, size, block ? 0 : MSG_DONTWAIT);
if (res != -1)
- XBT_DEBUG("Receive %s", MC_message_type_name(*(e_mc_message_type*)message));
+ XBT_DEBUG("Receive %s", MC_message_type_name(*(MessageType*)message));
return res;
}
}
// Send
int send(const void* message, size_t size) const;
- int send(e_mc_message_type type) const
+ int send(MessageType type) const
{
s_mc_message_t message = {type};
return this->send(&message, sizeof(message));
#include <libunwind-ptrace.h>
#include <sys/mman.h> // PROT_*
+#include <algorithm>
#include <memory>
+#include <string>
using simgrid::mc::remote;
"libcrypt",
"libcrypto",
"libcurl",
+ "libcurl-gnutls",
"libcxxrt",
"libdebuginfod",
"libdl",
"libelf",
"libevent",
"libexecinfo",
+ "libffi",
"libflang",
"libflangrti",
"libgcc_s",
+ "libgmp",
+ "libgnutls",
+ "libgcrypt",
"libgfortran",
+ "libgpg-error",
"libgssapi_krb5",
+ "libhogweed",
"libidn2",
"libimf",
"libintlc",
"libkrb5support", /*odd behaviour on fedora rawhide ... remove these when fixed*/
"liblber",
"libldap",
+ "libldap_r",
"liblua5.1",
"liblua5.3",
"liblzma",
"libm",
+ "libmd",
+ "libnettle",
"libnghttp2",
"libomp",
+ "libp11-kit",
"libpapi",
"libpcre2",
"libpfm",
"libquadmath",
"libresolv",
"librt",
+ "librtmp",
"libsasl2",
"libselinux",
"libssh",
"libssl",
"libstdc++",
"libsvml",
+ "libtasn1",
"libtsan", /* gcc sanitizers */
"libubsan", /* gcc sanitizers */
"libunistring",
"libz",
"libzstd"};
-static bool is_simgrid_lib(const std::string& libname)
-{
- return libname == "libsimgrid";
-}
-
static bool is_filtered_lib(const std::string& libname)
{
return std::find(begin(filtered_libraries), end(filtered_libraries), libname) != end(filtered_libraries);
int open_vm(pid_t pid, int flags)
{
- const size_t buffer_size = 30;
- char buffer[buffer_size];
- int res = snprintf(buffer, buffer_size, "/proc/%lli/mem", (long long)pid);
- if (res < 0 || (size_t)res >= buffer_size) {
- errno = ENAMETOOLONG;
- return -1;
- }
- return open(buffer, flags);
+ std::string buffer = "/proc/" + std::to_string(pid) + "/mem";
+ return open(buffer.c_str(), flags);
}
// ***** RemoteSimulation
this->maestro_stack_end_ = nullptr;
this->object_infos.resize(0);
this->binary_info = nullptr;
- this->libsimgrid_info = nullptr;
std::vector<simgrid::xbt::VmMap> const& maps = this->memory_map_;
this->object_infos.push_back(info);
if (is_executable)
this->binary_info = info;
- else if (is_simgrid_lib(libname))
- this->libsimgrid_info = info;
}
// Resolve time (including across different objects):
region.addr = addr;
region.size = size;
- if (ignored_regions_.empty()) {
- ignored_regions_.push_back(region);
- return;
- }
-
- unsigned int cursor = 0;
- const IgnoredRegion* current_region = nullptr;
-
- int start = 0;
- int end = ignored_regions_.size() - 1;
- while (start <= end) {
- cursor = (start + end) / 2;
- current_region = &ignored_regions_[cursor];
- if (current_region->addr == addr) {
- if (current_region->size == size)
- return;
- else if (current_region->size < size)
- start = cursor + 1;
- else
- end = cursor - 1;
- } else if (current_region->addr < addr)
- start = cursor + 1;
- else
- end = cursor - 1;
- }
-
- std::size_t position;
- if (current_region->addr == addr) {
- if (current_region->size < size)
- position = cursor + 1;
- else
- position = cursor;
- } else if (current_region->addr < addr)
- position = cursor + 1;
- else
- position = cursor;
- ignored_regions_.insert(ignored_regions_.begin() + position, region);
+ auto pos = std::lower_bound(ignored_regions_.begin(), ignored_regions_.end(), region,
+ [](auto const& reg1, auto const& reg2) {
+ return reg1.addr < reg2.addr || (reg1.addr == reg2.addr && reg1.size < reg2.size);
+ });
+ if (pos == ignored_regions_.end() || pos->addr != addr || pos->size != size)
+ ignored_regions_.insert(pos, region);
}
void RemoteSimulation::ignore_heap(IgnoredHeapRegion const& region)
{
- if (ignored_heap_.empty()) {
- ignored_heap_.push_back(std::move(region));
- return;
- }
-
- typedef std::vector<IgnoredHeapRegion>::size_type size_type;
-
- size_type start = 0;
- size_type end = ignored_heap_.size() - 1;
-
// Binary search the position of insertion:
- size_type cursor;
- while (start <= end) {
- cursor = start + (end - start) / 2;
- auto const& current_region = ignored_heap_[cursor];
- if (current_region.address == region.address)
- return;
- else if (current_region.address < region.address)
- start = cursor + 1;
- else if (cursor != 0)
- end = cursor - 1;
- // Avoid underflow:
- else
- break;
+ auto pos = std::lower_bound(ignored_heap_.begin(), ignored_heap_.end(), region.address,
+ [](auto const& reg, auto const* addr) { return reg.address < addr; });
+ if (pos == ignored_heap_.end() || pos->address != region.address) {
+ // Insert it:
+ ignored_heap_.insert(pos, region);
}
-
- // Insert it mc_heap_ignore_region_t:
- if (ignored_heap_[cursor].address < region.address)
- ++cursor;
- ignored_heap_.insert(ignored_heap_.begin() + cursor, region);
}
void RemoteSimulation::unignore_heap(void* address, size_t size)
{
- typedef std::vector<IgnoredHeapRegion>::size_type size_type;
-
- size_type start = 0;
- size_type end = ignored_heap_.size() - 1;
-
// Binary search:
- size_type cursor;
- while (start <= end) {
- cursor = (start + end) / 2;
- auto const& region = ignored_heap_[cursor];
- if (region.address < address)
- start = cursor + 1;
- else if ((char*)region.address <= ((char*)address + size)) {
- ignored_heap_.erase(ignored_heap_.begin() + cursor);
- return;
- } else if (cursor != 0)
- end = cursor - 1;
- // Avoid underflow:
- else
- break;
- }
+ auto pos = std::lower_bound(ignored_heap_.begin(), ignored_heap_.end(), address,
+ [](auto const& reg, auto const* addr) { return reg.address < addr; });
+ if (pos != ignored_heap_.end() && static_cast<char*>(pos->address) <= static_cast<char*>(address) + size)
+ ignored_heap_.erase(pos);
}
void RemoteSimulation::ignore_local_variable(const char* var_name, const char* frame_name) const
// object info
// TODO, make private (first, objectify simgrid::mc::ObjectInformation*)
std::vector<std::shared_ptr<ObjectInformation>> object_infos;
- std::shared_ptr<ObjectInformation> libsimgrid_info;
std::shared_ptr<ObjectInformation> binary_info;
// Copies of MCed SMX data structures
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/mc/remote/mc_protocol.h"
+#include <array>
-const char* MC_message_type_name(e_mc_message_type type)
+const char* MC_message_type_name(simgrid::mc::MessageType type)
{
- switch (type) {
- case MC_MESSAGE_NONE:
- return "NONE";
- case MC_MESSAGE_CONTINUE:
- return "CONTINUE";
- case MC_MESSAGE_IGNORE_HEAP:
- return "IGNORE_HEAP";
- case MC_MESSAGE_UNIGNORE_HEAP:
- return "UNIGNORE_HEAP";
- case MC_MESSAGE_IGNORE_MEMORY:
- return "IGNORE_MEMORY";
- case MC_MESSAGE_STACK_REGION:
- return "STACK_REGION";
- case MC_MESSAGE_REGISTER_SYMBOL:
- return "REGISTER_SYMBOL";
- case MC_MESSAGE_DEADLOCK_CHECK:
- return "DEADLOCK_CHECK";
- case MC_MESSAGE_DEADLOCK_CHECK_REPLY:
- return "DEADLOCK_CHECK_REPLY";
- case MC_MESSAGE_WAITING:
- return "WAITING";
- case MC_MESSAGE_SIMCALL_HANDLE:
- return "SIMCALL_HANDLE";
- case MC_MESSAGE_ASSERTION_FAILED:
- return "ASSERTION_FAILED";
-
- case MC_MESSAGE_ACTOR_ENABLED:
- return "ACTOR_ENABLED";
- case MC_MESSAGE_ACTOR_ENABLED_REPLY:
- return "ACTOR_ENABLED_REPLY";
-
- default:
- return "?";
- }
+ constexpr std::array<const char*, 14> names{{"NONE", "CONTINUE", "IGNORE_HEAP", "UNIGNORE_HEAP", "IGNORE_MEMORY",
+ "STACK_REGION", "REGISTER_SYMBOL", "DEADLOCK_CHECK",
+ "DEADLOCK_CHECK_REPLY", "WAITING", "SIMCALL_HANDLE", "ASSERTION_FAILED",
+ "ACTOR_ENABLED", "ACTOR_ENABLED_REPLY"}};
+ return names[static_cast<int>(type)];
}
#ifndef SIMGRID_MC_PROTOCOL_H
#define SIMGRID_MC_PROTOCOL_H
-#include "mc/datatypes.h"
-#include "simgrid/forward.h"
-#include "stdint.h"
-
-SG_BEGIN_DECL
-
// ***** Environment variables for passing context to the model-checked process
/** Environment variable name used to pass the communication socket.
*/
#define MC_ENV_SOCKET_FD "SIMGRID_MC_SOCKET_FD"
-// ***** Messages
+#ifdef __cplusplus
-enum e_mc_message_type {
- MC_MESSAGE_NONE,
- MC_MESSAGE_CONTINUE,
- MC_MESSAGE_IGNORE_HEAP,
- MC_MESSAGE_UNIGNORE_HEAP,
- MC_MESSAGE_IGNORE_MEMORY,
- MC_MESSAGE_STACK_REGION,
- MC_MESSAGE_REGISTER_SYMBOL,
- MC_MESSAGE_DEADLOCK_CHECK,
- MC_MESSAGE_DEADLOCK_CHECK_REPLY,
- MC_MESSAGE_WAITING,
- MC_MESSAGE_SIMCALL_HANDLE,
- MC_MESSAGE_ASSERTION_FAILED,
- MC_MESSAGE_ACTOR_ENABLED,
- MC_MESSAGE_ACTOR_ENABLED_REPLY
+#include "mc/datatypes.h"
+#include "simgrid/forward.h" // aid_t
+#include <array>
+#include <cstdint>
+
+// ***** Messages
+namespace simgrid {
+namespace mc {
+
+enum class MessageType {
+ NONE,
+ CONTINUE,
+ IGNORE_HEAP,
+ UNIGNORE_HEAP,
+ IGNORE_MEMORY,
+ STACK_REGION,
+ REGISTER_SYMBOL,
+ DEADLOCK_CHECK,
+ DEADLOCK_CHECK_REPLY,
+ WAITING,
+ SIMCALL_HANDLE,
+ ASSERTION_FAILED,
+ ACTOR_ENABLED,
+ ACTOR_ENABLED_REPLY
};
-#define MC_MESSAGE_LENGTH 512
+} // namespace mc
+} // namespace simgrid
+
+constexpr unsigned MC_MESSAGE_LENGTH = 512;
/** Basic structure for a MC message
*
/* Basic structure: all message start with a message type */
struct s_mc_message_t {
- enum e_mc_message_type type;
+ simgrid::mc::MessageType type;
};
struct s_mc_message_int_t {
- enum e_mc_message_type type;
+ simgrid::mc::MessageType type;
uint64_t value;
};
/* Client->Server */
struct s_mc_message_ignore_heap_t {
- enum e_mc_message_type type;
+ simgrid::mc::MessageType type;
int block;
int fragment;
void* address;
};
struct s_mc_message_ignore_memory_t {
- enum e_mc_message_type type;
+ simgrid::mc::MessageType type;
uint64_t addr;
size_t size;
};
struct s_mc_message_stack_region_t {
- enum e_mc_message_type type;
+ simgrid::mc::MessageType type;
s_stack_region_t stack_region;
};
struct s_mc_message_register_symbol_t {
- enum e_mc_message_type type;
- char name[128];
+ simgrid::mc::MessageType type;
+ std::array<char, 128> name;
int (*callback)(void*);
void* data;
};
/* Server -> client */
struct s_mc_message_simcall_handle_t {
- enum e_mc_message_type type;
+ simgrid::mc::MessageType type;
unsigned long pid;
int value;
};
struct s_mc_message_restore_t {
- enum e_mc_message_type type;
+ simgrid::mc::MessageType type;
int index;
};
struct s_mc_message_actor_enabled_t {
- enum e_mc_message_type type;
+ simgrid::mc::MessageType type;
aid_t aid; // actor ID
};
-XBT_PRIVATE const char* MC_message_type_name(enum e_mc_message_type type);
-
-SG_END_DECL
+XBT_PRIVATE const char* MC_message_type_name(simgrid::mc::MessageType type);
+#endif // __cplusplus
#endif
*/
class PageStore {
public: // Types
- typedef std::uint64_t hash_type;
+ using hash_type = std::uint64_t;
private:
// Types
// We are using a cheap hash to index a page.
// We should expect collision and we need to associate multiple page indices
// to the same hash.
- typedef std::unordered_set<std::size_t> page_set_type;
- typedef std::unordered_map<hash_type, page_set_type> pages_map_type;
+ using page_set_type = std::unordered_set<std::size_t>;
+ using pages_map_type = std::unordered_map<hash_type, page_set_type>;
// Fields:
/** First page */
#include "src/include/catch.hpp"
+#include <array>
#include <cstdint>
#include <cstring>
#include <iostream>
static std::size_t pagesize;
static std::unique_ptr<PageStore> store;
static void* data;
- static size_t pageno[4];
+ static std::array<size_t, 4> pageno;
static int value;
// member functions used by the test suite(s)
std::size_t helper_tests::pagesize = 0;
std::unique_ptr<PageStore> helper_tests::store = nullptr;
void* helper_tests::data = nullptr;
-size_t helper_tests::pageno[4] = {0, 0, 0, 0};
+std::array<size_t, 4> helper_tests::pageno = {{0, 0, 0, 0}};
int helper_tests::value = 0;
void helper_tests::Init()
auto* region = new Region(type, start_addr, size);
region->object_info(object_info);
- snapshot_regions_.push_back(std::unique_ptr<Region>(std::move(region)));
+ snapshot_regions_.push_back(std::unique_ptr<Region>(region));
}
void* Snapshot::read_bytes(void* buffer, std::size_t size, RemotePtr<void> address, ReadOptions options) const
std::string frame_name;
unw_cursor_t unw_cursor;
};
-typedef s_mc_stack_frame_t* mc_stack_frame_t;
+using mc_stack_frame_t = s_mc_stack_frame_t*;
struct s_local_variable_t {
simgrid::mc::Frame* subprogram;
simgrid::mc::Type* type;
void* address;
};
-typedef s_local_variable_t* local_variable_t;
-typedef const s_local_variable_t* const_local_variable_t;
+using local_variable_t = s_local_variable_t*;
+using const_local_variable_t = const s_local_variable_t*;
struct XBT_PRIVATE s_mc_snapshot_stack_t {
std::vector<s_local_variable_t> local_variables;
simgrid::mc::UnwindContext context;
std::vector<s_mc_stack_frame_t> stack_frames;
};
-typedef s_mc_snapshot_stack_t* mc_snapshot_stack_t;
-typedef const s_mc_snapshot_stack_t* const_mc_snapshot_stack_t;
+using mc_snapshot_stack_t = s_mc_snapshot_stack_t*;
+using const_mc_snapshot_stack_t = const s_mc_snapshot_stack_t*;
namespace simgrid {
namespace mc {
// Store region page(s):
size_t byte_size = n * xbt_pagesize;
void* source = mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- INFO("Could not allocate source memory")
+ INFO("Could not allocate source memory");
REQUIRE(source != MAP_FAILED);
// Init memory and take snapshots:
void* destination = mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
INFO("Could not allocate destination memory");
- REQUIRE(source != MAP_FAILED);
+ REQUIRE(destination != MAP_FAILED);
- return {.size = byte_size,
- .src = source,
- .dstn = destination,
- .region0 = std::move(region0),
- .region = std::move(region)};
+ return {.size = byte_size, .src = source, .dstn = destination, .region0 = region0, .region = region};
}
void snap_test_helper::read_whole_region()
{
prologue_return ret = prologue(1);
memcpy(ret.src, &mc_model_checker, sizeof(void*));
- const simgrid::mc::Region* region2 = new simgrid::mc::Region(simgrid::mc::RegionType::Data, ret.src, ret.size);
+ const simgrid::mc::Region region2(simgrid::mc::RegionType::Data, ret.src, ret.size);
INFO("Mismtach in MC_region_read_pointer()");
- REQUIRE(MC_region_read_pointer(region2, ret.src) == mc_model_checker);
+ REQUIRE(MC_region_read_pointer(®ion2, ret.src) == mc_model_checker);
munmap(ret.dstn, ret.size);
munmap(ret.src, ret.size);
delete ret.region0;
delete ret.region;
- delete region2;
}
/*************** End: class snap_test_helper *****************************/
msg_global->process_data_cleanup = nullptr;
simgrid::s4u::Actor::on_termination.connect([](simgrid::s4u::Actor const& actor) {
// free the data if a function was provided
- void* userdata = sg_actor_data(&actor);
+ void* userdata = sg_actor_get_data(&actor);
if (userdata && msg_global->process_data_cleanup)
msg_global->process_data_cleanup(userdata);
});
{
sg_actor_set_host(actor, host);
}
-void MSG_process_join(sg_actor_t actor, double timeout)
+void MSG_process_join(const_sg_actor_t actor, double timeout)
{
sg_actor_join(actor, timeout);
}
xbt_assert(process != nullptr, "Invalid parameter: first parameter must not be nullptr!");
/* get from SIMIX the MSG process data, and then the user data */
- return sg_actor_data(process);
+ return sg_actor_get_data(process);
}
/** @brief Sets the user data of a process.
msg_error_t MSG_process_set_data(msg_process_t process, void* data)
{
xbt_assert(process != nullptr, "Invalid parameter: first parameter must not be nullptr!");
- sg_actor_data_set(process, data);
+ sg_actor_set_data(process, data);
return MSG_OK;
}
}
void* MSG_host_get_data(const_sg_host_t host)
{
- return sg_host_data(host);
+ return sg_host_get_data(host);
}
void MSG_host_set_data(sg_host_t host, void* data)
{
- return sg_host_data_set(host, data);
+ return sg_host_set_data(host, data);
}
xbt_dict_t MSG_host_get_mounted_storage_list(sg_host_t host) // XBT_ATTRIB_DEPRECATED_v330
{
}
double MSG_host_get_speed(const_sg_host_t host)
{
- return sg_host_speed(host);
+ return sg_host_get_speed(host);
}
double MSG_host_get_power_peak_at(const_sg_host_t host, int pstate_index)
{
double MSG_host_get_load(const_sg_host_t host)
{
- return sg_host_load(host);
+ return sg_host_get_load(host);
}
/* ************************** Virtual Machines *************************** */
sg_vm_t MSG_vm_create_core(sg_host_t pm, const char* name)
{
return sg_vm_create_multicore(pm, name, coreAmount);
}
-int MSG_vm_is_created(sg_vm_t vm)
+int MSG_vm_is_created(const_sg_vm_t vm)
{
return sg_vm_is_created(vm);
}
-int MSG_vm_is_running(sg_vm_t vm)
+int MSG_vm_is_running(const_sg_vm_t vm)
{
return sg_vm_is_running(vm);
}
-int MSG_vm_is_suspended(sg_vm_t vm)
+int MSG_vm_is_suspended(const_sg_vm_t vm)
{
return sg_vm_is_suspended(vm);
}
{
sg_sem_release(sem);
}
-int MSG_sem_get_capacity(sg_sem_t sem)
+int MSG_sem_get_capacity(const_sg_sem_t sem)
{
return sg_sem_get_capacity(sem);
}
{
sg_sem_destroy(sem);
}
-int MSG_sem_would_block(sg_sem_t sem)
+int MSG_sem_would_block(const_sg_sem_t sem)
{
return sg_sem_would_block(sem);
}
try {
if (data != nullptr) {
- sg_actor_data_set(actor, data);
+ sg_actor_set_data(actor, data);
xbt_dict_cursor_t cursor = nullptr;
char* key;
char* value;
}
/* Create file on remote host, write it and close it */
- auto* fd = new File(fullpath, dst_host, nullptr);
+ File fd(fullpath, dst_host, nullptr);
if (local_storage_) {
- sg_size_t write_size = fd->local_storage_->write(read_size);
- fd->local_storage_->extension<FileSystemStorageExt>()->incr_used_size(write_size);
- (*(fd->local_storage_->extension<FileSystemStorageExt>()->get_content()))[path_] = size_;
+ sg_size_t write_size = fd.local_storage_->write(read_size);
+ fd.local_storage_->extension<FileSystemStorageExt>()->incr_used_size(write_size);
+ (*(fd.local_storage_->extension<FileSystemStorageExt>()->get_content()))[path_] = size_;
}
if (local_disk_)
- fd->write(read_size);
- delete fd;
+ fd.write(read_size);
return 0;
}
auto* parse_content = new std::map<std::string, sg_size_t>();
- std::ifstream* fs = surf_ifsopen(filename);
+ auto fs = std::unique_ptr<std::ifstream>(surf_ifsopen(filename));
xbt_assert(not fs->fail(), "Cannot open file '%s' (path=%s)", filename.c_str(),
(boost::join(surf_path, ":")).c_str());
parse_content->insert({tokens.front(), size});
}
} while (not fs->eof());
- delete fs;
return parse_content;
}
auto* parse_content = new std::map<std::string, sg_size_t>();
- std::ifstream* fs = surf_ifsopen(filename);
+ auto fs = std::unique_ptr<std::ifstream>(surf_ifsopen(filename));
xbt_assert(not fs->fail(), "Cannot open file '%s' (path=%s)", filename.c_str(),
(boost::join(surf_path, ":")).c_str());
parse_content->insert({tokens.front(), size});
}
} while (not fs->eof());
- delete fs;
return parse_content;
}
simgrid::s4u::Host* remote_host = simgrid::s4u::Host::by_name_or_null(tokens[2]);
xbt_assert(remote_host, "You're trying to access a host that does not exist. Please check your platform file");
- simgrid::s4u::Disk* disk = nullptr;
+ const simgrid::s4u::Disk* disk = nullptr;
for (auto const& d : remote_host->get_disks())
if (d->get_name() == tokens[1]) {
disk = d;
SIMGRID_REGISTER_PLUGIN(host_dvfs, "Dvfs support", &sg_host_dvfs_plugin_init)
-static simgrid::config::Flag<double> cfg_sampling_rate("plugin/dvfs/sampling-rate", {"plugin/dvfs/sampling_rate"},
- "How often should the dvfs plugin check whether the frequency needs to be changed?", 0.1,
- [](double val){if (val != 0.1) sg_host_dvfs_plugin_init();});
+static simgrid::config::Flag<double>
+ cfg_sampling_rate("plugin/dvfs/sampling-rate",
+ "How often should the dvfs plugin check whether the frequency needs to be changed?", 0.1,
+ [](double val) {
+ if (val != 0.1)
+ sg_host_dvfs_plugin_init();
+ });
static simgrid::config::Flag<std::string> cfg_governor("plugin/dvfs/governor",
"Which Governor should be used that adapts the CPU frequency?",
});
static simgrid::config::Flag<int>
- cfg_min_pstate("plugin/dvfs/min-pstate", {"plugin/dvfs/min_pstate"},
+ cfg_min_pstate("plugin/dvfs/min-pstate",
"Which pstate is the minimum (and hence fastest) pstate for this governor?", 0);
static const int max_pstate_not_limited = -1;
static simgrid::config::Flag<int>
- cfg_max_pstate("plugin/dvfs/max-pstate", {"plugin/dvfs/max_pstate"},
+ cfg_max_pstate("plugin/dvfs/max-pstate",
"Which pstate is the maximum (and hence slowest) pstate for this governor?", max_pstate_not_limited);
/** @addtogroup SURF_plugin_load
*/
class Performance : public Governor {
public:
- explicit Performance(simgrid::s4u::Host* ptr) : Governor(ptr) {}
+ using Governor::Governor;
std::string get_name() const override { return "Performance"; }
void update() override { get_host()->set_pstate(get_min_pstate()); }
*/
class Powersave : public Governor {
public:
- explicit Powersave(simgrid::s4u::Host* ptr) : Governor(ptr) {}
+ using Governor::Governor;
std::string get_name() const override { return "Powersave"; }
void update() override { get_host()->set_pstate(get_max_pstate()); }
double freq_up_threshold_ = 0.80;
public:
- explicit OnDemand(simgrid::s4u::Host* ptr) : Governor(ptr) {}
+ using Governor::Governor;
std::string get_name() const override { return "OnDemand"; }
void update() override
double freq_down_threshold_ = .2;
public:
- explicit Conservative(simgrid::s4u::Host* ptr) : Governor(ptr) {}
+ using Governor::Governor;
std::string get_name() const override { return "Conservative"; }
void update() override
while((var = wifi_link->get_constraint()->get_variable(&elem))) {
auto* action = static_cast<kernel::resource::NetworkWifiAction*>(var->get_id());
XBT_DEBUG("cost: %f action value: %f link rate 1: %f link rate 2: %f", action->get_cost(), action->get_variable()->get_value(), wifi_link->get_host_rate(&action->get_src()),wifi_link->get_host_rate(&action->get_dst()));
- action->get_variable();
if(action->get_variable()->get_value()) {
auto it = flowTmp.find(action);
* The value for GUESTOS_NOISE corresponds to the cost of the global action associated to the VM. It corresponds to
* the cost of a VM running no tasks.
*/
- action_ = host_PM->pimpl_cpu->execution_start(0, core_amount);
+ action_ = physical_host_->pimpl_cpu->execution_start(0, core_amount_);
// It's empty for now, so it should not request resources in the PM
update_action_weight();
return this;
}
-VirtualMachine::state VirtualMachine::get_state()
+VirtualMachine::state VirtualMachine::get_state() const
{
return kernel::actor::simcall([this]() { return pimpl_vm_->get_state(); });
}
}
/** @brief Returns whether the given VM has just created, not running. */
-int sg_vm_is_created(sg_vm_t vm)
+int sg_vm_is_created(const_sg_vm_t vm)
{
return vm->get_state() == simgrid::s4u::VirtualMachine::state::CREATED;
}
/** @brief Returns whether the given VM is currently running */
-int sg_vm_is_running(sg_vm_t vm)
+int sg_vm_is_running(const_sg_vm_t vm)
{
return vm->get_state() == simgrid::s4u::VirtualMachine::state::RUNNING;
}
/** @brief Returns whether the given VM is currently suspended, not running. */
-int sg_vm_is_suspended(sg_vm_t vm)
+int sg_vm_is_suspended(const_sg_vm_t vm)
{
return vm->get_state() == simgrid::s4u::VirtualMachine::state::SUSPENDED;
}
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; // deprecated
-xbt::signal<void(Actor const&)> s4u::Actor::on_migration_end; // deprecated
+xbt::signal<void(Actor const&)> s4u::Actor::on_migration_start; // XBT_ATTRIB_DEPRECATED_v329
+xbt::signal<void(Actor const&)> s4u::Actor::on_migration_end; // XBT_ATTRIB_DEPRECATED_v329
xbt::signal<void(Actor const&, Host const& previous_location)> s4u::Actor::on_host_change;
xbt::signal<void(Actor const&)> s4u::Actor::on_termination;
xbt::signal<void(Actor const&)> s4u::Actor::on_destruction;
ActorPtr Actor::init(const std::string& name, s4u::Host* host)
{
- kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
+ const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
kernel::actor::ActorImpl* actor =
kernel::actor::simcall([self, &name, host] { return self->init(name, host).get(); });
return actor->get_iface();
ActorPtr Actor::create(const std::string& name, s4u::Host* host, const std::function<void()>& code)
{
- kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
+ const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
kernel::actor::ActorImpl* actor =
kernel::actor::simcall([self, &name, host, &code] { return self->init(name, host)->start(code); });
// ***** Actor methods *****
-void Actor::join()
+void Actor::join() const
{
join(-1);
}
-void Actor::join(double timeout)
+void Actor::join(double timeout) const
{
kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
- kernel::actor::ActorImpl* target = pimpl_;
+ const kernel::actor::ActorImpl* target = pimpl_;
kernel::actor::simcall_blocking<void>([issuer, target, timeout] {
if (target->finished_) {
// The joined process is already finished, just wake up the issuer right away
void Actor::kill()
{
- kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
+ const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
kernel::actor::simcall([this, self] { self->kill(pimpl_); });
}
void Actor::kill_all()
{
- kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
+ const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
kernel::actor::simcall([self] { self->kill_all(); });
}
{
simgrid::kernel::actor::ActorImpl::self()->get_iface()->set_host(new_host);
}
-void migrate(Host* new_host) // deprecated
+void migrate(Host* new_host) // XBT_ATTRIB_DEPRECATED_v329
{
set_host(new_host);
}
simgrid::kernel::actor::ActorCode function;
if (code)
function = simgrid::xbt::wrap_main(code, argc, argv);
- actor->start(std::move(function));
+ actor->start(function);
}
sg_actor_t sg_actor_create(const char* name, sg_host_t host, xbt_main_func_t code, int argc, const char* const* argv)
{
simgrid::kernel::actor::ActorCode function = simgrid::xbt::wrap_main(code, argc, argv);
- return simgrid::s4u::Actor::init(name, host)->start(std::move(function)).get();
+ return simgrid::s4u::Actor::init(name, host)->start(function).get();
}
void sg_actor_set_stacksize(sg_actor_t actor, unsigned size)
{
actor->set_host(host);
}
-void sg_actor_migrate(sg_actor_t process, sg_host_t host) // deprecated
+void sg_actor_migrate(sg_actor_t process, sg_host_t host) // XBT_ATTRIB_DEPRECATED_v329
{
process->set_host(host);
}
* @param actor the actor to wait for
* @param timeout wait until the actor is over, or the timeout expires
*/
-void sg_actor_join(sg_actor_t actor, double timeout)
+void sg_actor_join(const_sg_actor_t actor, double timeout)
{
actor->join(timeout);
}
return simgrid::s4u::this_actor::get_cname();
}
-void* sg_actor_self_data()
+void* sg_actor_self_get_data()
{
return simgrid::s4u::Actor::self()->get_data();
}
-void sg_actor_self_data_set(void* userdata)
+void sg_actor_self_set_data(void* userdata)
{
simgrid::s4u::Actor::self()->set_data(userdata);
}
+void* sg_actor_self_data() // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_actor_self_get_data();
+}
+
+void sg_actor_self_data_set(void* userdata) // XBT_ATTRIB_DEPRECATED_v330
+{
+ sg_actor_self_set_data(userdata);
+}
+
sg_actor_t sg_actor_self()
{
return simgrid::s4u::Actor::self();
}
-void sg_actor_self_execute(double flops) // XBT_DEPRECATED_v330
+void sg_actor_self_execute(double flops) // XBT_ATTRIB_DEPRECATED_v330
{
simgrid::s4u::this_actor::execute(flops);
}
}
/** @brief Return the user data of a #sg_actor_t */
-void* sg_actor_data(const_sg_actor_t actor)
+void* sg_actor_get_data(const_sg_actor_t actor)
{
return actor->get_data();
}
+
/** @brief Set the user data of a #sg_actor_t */
-void sg_actor_data_set(sg_actor_t actor, void* userdata)
+void sg_actor_set_data(sg_actor_t actor, void* userdata)
{
actor->set_data(userdata);
}
+
+void* sg_actor_data(const_sg_actor_t actor) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_actor_get_data(actor);
+}
+
+void sg_actor_data_set(sg_actor_t actor, void* userdata) // XBT_ATTRIB_DEPRECATED_v330
+{
+ sg_actor_set_data(actor, userdata);
+}
+
/** @brief Add a function to the list of "on_exit" functions for the current process.
* The on_exit functions are the functions executed when your process is killed.
* You should use them to free the data used by your process.
int Comm::wait_any_for(const std::vector<CommPtr>* comms, double timeout)
{
- auto rcomms = std::make_unique<kernel::activity::CommImpl*[]>(comms->size());
- std::transform(begin(*comms), end(*comms), rcomms.get(),
+ std::vector<kernel::activity::CommImpl*> rcomms(comms->size());
+ std::transform(begin(*comms), end(*comms), begin(rcomms),
[](const CommPtr& comm) { return static_cast<kernel::activity::CommImpl*>(comm->pimpl_.get()); });
- int changed_pos = simcall_comm_waitany(rcomms.get(), comms->size(), timeout);
+ int changed_pos = simcall_comm_waitany(rcomms.data(), rcomms.size(), timeout);
if (changed_pos != -1)
comms->at(changed_pos)->release_dependencies();
return changed_pos;
return this;
}
-CommPtr Comm::set_tracing_category(const std::string& category)
-{
- xbt_assert(state_ == State::INITED, "Cannot change the tracing category of an exec after its start");
- tracing_category_ = category;
- return this;
-}
-
Comm* Comm::start()
{
xbt_assert(get_state() == State::INITED || get_state() == State::STARTING,
case State::STARTED:
simcall_comm_wait(get_impl(), timeout);
- on_completion(*Actor::self());
state_ = State::FINISHED;
this->release_dependencies();
break;
default:
THROW_IMPOSSIBLE;
}
+ on_completion(*Actor::self());
return this;
}
int Comm::test_any(const std::vector<CommPtr>* comms)
{
- auto rcomms = std::make_unique<kernel::activity::CommImpl*[]>(comms->size());
- std::transform(begin(*comms), end(*comms), rcomms.get(),
+ std::vector<kernel::activity::CommImpl*> rcomms(comms->size());
+ std::transform(begin(*comms), end(*comms), begin(rcomms),
[](const CommPtr& comm) { return static_cast<kernel::activity::CommImpl*>(comm->pimpl_.get()); });
- int changed_pos = simcall_comm_testany(rcomms.get(), comms->size());
+ int changed_pos = simcall_comm_testany(rcomms.data(), rcomms.size());
if (changed_pos != -1)
comms->at(changed_pos)->release_dependencies();
return changed_pos;
/* **************************** Public C interface *************************** */
-const char* sg_disk_name(const_sg_disk_t disk)
+const char* sg_disk_get_name(const_sg_disk_t disk)
{
return disk->get_cname();
}
{
return disk->write(size);
}
-void* sg_disk_data(const_sg_disk_t disk)
+
+void* sg_disk_get_data(const_sg_disk_t disk)
{
return disk->get_data();
}
-void sg_disk_data_set(sg_disk_t disk, void* data)
+
+void sg_disk_set_data(sg_disk_t disk, void* data)
{
disk->set_data(data);
}
XBT_DEBUG("PARSE TIME: %g", (end - start));
}
-void Engine::register_function(const std::string& name, int (*code)(int, char**)) // deprecated
+void Engine::register_function(const std::string& name, int (*code)(int, char**)) // XBT_ATTRIB_DEPRECATED_v329
{
kernel::actor::ActorCodeFactory code_factory = [code](std::vector<std::string> args) {
return xbt::wrap_main(code, std::move(args));
};
- register_function(name, std::move(code_factory));
+ register_function(name, code_factory);
}
-void Engine::register_default(int (*code)(int, char**)) // deprecated
+void Engine::register_default(int (*code)(int, char**)) // XBT_ATTRIB_DEPRECATED_v329
{
register_default([code](std::vector<std::string> args) { return xbt::wrap_main(code, std::move(args)); });
}
kernel::actor::ActorCodeFactory code_factory = [code](std::vector<std::string> args) {
return xbt::wrap_main(code, std::move(args));
};
- register_function(name, std::move(code_factory));
+ register_function(name, code_factory);
}
/** Registers the main function of an actor that will be launched from the deployment file */
void Engine::register_function(const std::string& name, const std::function<void(std::vector<std::string>)>& code)
{
- kernel::actor::ActorCodeFactory code_factory = [code](std::vector<std::string> args) {
+ kernel::actor::ActorCodeFactory code_factory = [code{code}](std::vector<std::string> args) mutable {
return std::bind(std::move(code), std::move(args));
};
- register_function(name, std::move(code_factory));
+ register_function(name, code_factory);
}
/** Registers a function as the default main function of actors
*
int Exec::wait_any_for(std::vector<ExecPtr>* execs, double timeout)
{
- auto rexecs = std::make_unique<kernel::activity::ExecImpl*[]>(execs->size());
- std::transform(begin(*execs), end(*execs), rexecs.get(),
+ std::vector<kernel::activity::ExecImpl*> rexecs(execs->size());
+ std::transform(begin(*execs), end(*execs), begin(rexecs),
[](const ExecPtr& exec) { return static_cast<kernel::activity::ExecImpl*>(exec->pimpl_.get()); });
- int changed_pos = simcall_execution_waitany_for(rexecs.get(), execs->size(), timeout);
+ int changed_pos = simcall_execution_waitany_for(rexecs.data(), rexecs.size(), timeout);
if (changed_pos != -1)
execs->at(changed_pos)->release_dependencies();
return changed_pos;
void Host::turn_off()
{
if (is_on()) {
- kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
+ const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
kernel::actor::simcall([this, self] {
for (VirtualMachine* const& vm : vm::VirtualMachineImpl::allVms_)
if (vm->get_pm() == this) {
return kernel::actor::simcall([this] { return this->pimpl_->get_disks(); });
}
-void Host::add_disk(Disk* disk)
+void Host::add_disk(const Disk* disk)
{
kernel::actor::simcall([this, disk] { this->pimpl_->add_disk(disk); });
}
// ========= Layering madness ==============*
// ========== User data Layer ==========
-void* sg_host_data(const_sg_host_t host)
+void* sg_host_get_data(const_sg_host_t host)
{
return host->get_data();
}
-void sg_host_data_set(sg_host_t host, void* userdata)
+void sg_host_set_data(sg_host_t host, void* userdata)
{
host->set_data(userdata);
}
-void* sg_host_user(sg_host_t host) // deprecated
+void* sg_host_data(const_sg_host_t host) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_host_get_data(host);
+}
+void sg_host_data_set(sg_host_t host, void* userdata) // XBT_ATTRIB_DEPRECATED_v330
+{
+ sg_host_set_data(host, userdata);
+}
+void* sg_host_user(sg_host_t host) // XBT_ATTRIB_DEPRECATED_v328
{
return host->get_data();
}
-void sg_host_user_set(sg_host_t host, void* userdata) // deprecated
+void sg_host_user_set(sg_host_t host, void* userdata) // XBT_ATTRIB_DEPRECATED_v328
{
host->set_data(userdata);
}
-void sg_host_user_destroy(sg_host_t host) // deprecated
+void sg_host_user_destroy(sg_host_t host) // XBT_ATTRIB_DEPRECATED_v328
{
host->set_data(nullptr);
}
// ========= storage related functions ============
-void sg_host_disks(const_sg_host_t host, unsigned int* disk_count, sg_disk_t** disks)
+void sg_host_get_disks(const_sg_host_t host, unsigned int* disk_count, sg_disk_t** disks)
{
std::vector<sg_disk_t> list = host->get_disks();
*disk_count = list.size();
// =========== user-level functions ===============
// ================================================
/** @brief Returns the total speed of a host */
-double sg_host_speed(const_sg_host_t host)
+double sg_host_get_speed(const_sg_host_t host)
{
return host->get_speed();
}
+double sg_host_speed(const_sg_host_t host) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_host_get_speed(host);
+}
+
/** @brief Return the speed of the processor (in flop/s) at a given pstate. See also @ref plugin_energy.
*
* @param host host to test
* @param to where to
* @param links [OUT] where to store the list of links (must exist, cannot be nullptr).
*/
-void sg_host_route(const_sg_host_t from, const_sg_host_t to, xbt_dynar_t links)
+void sg_host_get_route(const_sg_host_t from, const_sg_host_t to, xbt_dynar_t links)
{
std::vector<simgrid::s4u::Link*> vlinks;
from->route_to(to, vlinks, nullptr);
* @param from where from
* @param to where to
*/
-double sg_host_route_latency(const_sg_host_t from, const_sg_host_t to)
+double sg_host_get_route_latency(const_sg_host_t from, const_sg_host_t to)
{
std::vector<simgrid::s4u::Link*> vlinks;
double res = 0;
* @param from where from
* @param to where to
*/
-double sg_host_route_bandwidth(const_sg_host_t from, const_sg_host_t to)
+double sg_host_get_route_bandwidth(const_sg_host_t from, const_sg_host_t to)
{
double min_bandwidth = -1.0;
return min_bandwidth;
}
+void sg_host_route(const_sg_host_t from, const_sg_host_t to, xbt_dynar_t links) // XBT_ATTRIB_DEPRECATED_v330
+{
+ sg_host_get_route(from, to, links);
+}
+
+double sg_host_route_latency(const_sg_host_t from, const_sg_host_t to) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_host_get_route_latency(from, to);
+}
+
+double sg_host_route_bandwidth(const_sg_host_t from, const_sg_host_t to) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_host_get_route_bandwidth(from, to);
+}
+
void sg_host_sendto(sg_host_t from, sg_host_t to, double byte_amount)
{
from->sendto(to, byte_amount);
return res;
}
-double sg_host_load(const_sg_host_t host)
+double sg_host_get_load(const_sg_host_t host)
{
return host->get_load();
}
+
+double sg_host_load(const_sg_host_t host) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_host_get_load(host);
+}
/* **************************** Public C interface *************************** */
-const char* sg_link_name(const_sg_link_t link)
+const char* sg_link_get_name(const_sg_link_t link)
{
return link->get_cname();
}
+
+const char* sg_link_name(const_sg_link_t link) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_link_get_name(link);
+}
+
sg_link_t sg_link_by_name(const char* name)
{
return simgrid::s4u::Link::by_name(name);
{
return link->get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::FATPIPE;
}
-double sg_link_bandwidth(const_sg_link_t link)
+
+double sg_link_get_bandwidth(const_sg_link_t link)
{
return link->get_bandwidth();
}
-void sg_link_bandwidth_set(sg_link_t link, double value)
+void sg_link_set_bandwidth(sg_link_t link, double value)
{
return link->set_bandwidth(value);
}
-double sg_link_latency(const_sg_link_t link)
+double sg_link_bandwidth(const_sg_link_t link) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_link_get_bandwidth(link);
+}
+
+void sg_link_bandwidth_set(sg_link_t link, double value) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_link_set_bandwidth(link, value);
+}
+
+double sg_link_get_latency(const_sg_link_t link)
{
return link->get_latency();
}
-void sg_link_latency_set(sg_link_t link, double value)
+
+void sg_link_set_latency(sg_link_t link, double value)
{
return link->set_latency(value);
}
-void* sg_link_data(const_sg_link_t link)
+
+double sg_link_latency(const_sg_link_t link) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_link_get_latency(link);
+}
+
+void sg_link_latency_set(sg_link_t link, double value) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_link_set_latency(link, value);
+}
+
+void* sg_link_get_data(const_sg_link_t link)
{
return link->get_data();
}
-void sg_link_data_set(sg_link_t link, void* data)
+
+void sg_link_set_data(sg_link_t link, void* data)
{
link->set_data(data);
}
+
+void* sg_link_data(const_sg_link_t link) // XBT_ATTRIB_DEPRECATED_v330
+{
+ return sg_link_get_data(link);
+}
+
+void sg_link_data_set(sg_link_t link, void* data) // XBT_ATTRIB_DEPRECATED_v330
+{
+ sg_link_set_data(link, data);
+}
+
int sg_link_count()
{
return simgrid::s4u::Engine::get_instance()->get_link_count();
kernel::actor::simcall([this] { sem_->release(); });
}
-int Semaphore::get_capacity()
+int Semaphore::get_capacity() const
{
return kernel::actor::simcall([this] { return sem_->get_capacity(); });
}
-int Semaphore::would_block()
+int Semaphore::would_block() const
{
return kernel::actor::simcall([this] { return sem_->would_block(); });
}
sem->release();
}
-int sg_sem_get_capacity(sg_sem_t sem)
+int sg_sem_get_capacity(const_sg_sem_t sem)
{
return sem->get_capacity();
}
* Note that the returned value may be wrong right after the function call, when you try to use it...
* But that's a classical semaphore issue, and SimGrid's semaphore are not different to usual ones here.
*/
-int sg_sem_would_block(sg_sem_t sem)
+int sg_sem_would_block(const_sg_sem_t sem)
{
return sem->would_block();
}
if (bytes_amount != nullptr)
for (int j = 0; j < host_count; j++)
if (bytes_amount[i * host_count + j] != 0)
- time += (sg_host_route_latency(host_list[i], host_list[j]) +
- bytes_amount[i * host_count + j] / sg_host_route_bandwidth(host_list[i], host_list[j]));
+ time += (sg_host_get_route_latency(host_list[i], host_list[j]) +
+ bytes_amount[i * host_count + j] / sg_host_get_route_bandwidth(host_list[i], host_list[j]));
if (time > max_time)
max_time = time;
void SD_task_schedulel(SD_task_t task, int count, ...)
{
va_list ap;
- auto* list = new sg_host_t[count];
+ std::vector<sg_host_t> list(count);
va_start(ap, count);
for (int i=0; i<count; i++)
list[i] = va_arg(ap, sg_host_t);
va_end(ap);
- SD_task_schedulev(task, count, list);
- delete[] list;
+ SD_task_schedulev(task, count, list.data());
}
simgrid::config::bind_flag(sg_maxmin_precision, "maxmin/precision",
"Numerical precision used when computing resource sharing (in flops/sec or bytes/sec)");
- simgrid::config::bind_flag(sg_concurrency_limit, "maxmin/concurrency-limit", {"maxmin/concurrency_limit"},
+ simgrid::config::bind_flag(sg_concurrency_limit, "maxmin/concurrency-limit",
"Maximum number of concurrent variables in the maxmim system. Also limits the number of "
"processes on each host, at higher level. (default: -1 means no such limitation)");
/* The parameters of network models */
sg_latency_factor = 13.01; // comes from the default LV08 network model
- simgrid::config::bind_flag(sg_latency_factor, "network/latency-factor", {"network/latency_factor"},
+ simgrid::config::bind_flag(sg_latency_factor, "network/latency-factor",
"Correction factor to apply to the provided latency (default value set by network model)");
sg_bandwidth_factor = 0.97; // comes from the default LV08 network model
simgrid::config::bind_flag(
- sg_bandwidth_factor, "network/bandwidth-factor", {"network/bandwidth_factor"},
+ sg_bandwidth_factor, "network/bandwidth-factor",
"Correction factor to apply to the provided bandwidth (default value set by network model)");
sg_weight_S_parameter = 20537; // comes from the default LV08 network model
simgrid::config::bind_flag(
- sg_weight_S_parameter, "network/weight-S", {"network/weight_S"},
+ sg_weight_S_parameter, "network/weight-S",
"Correction factor to apply to the weight of competing streams (default value set by network model)");
simgrid::config::declare_flag<double>("network/loopback-lat",
"Update the constraint set propagating recursively to others constraints "
"(off by default unless optim is set to lazy)",
"no");
- simgrid::config::alias("cpu/maxmin-selective-update", {"cpu/maxmin_selective_update"});
simgrid::config::declare_flag<bool>("network/maxmin-selective-update", "Update the constraint set propagating "
"recursively to others constraints (off by "
"default unless optim is set to lazy)",
"no");
- simgrid::config::alias("network/maxmin-selective-update", {"network/maxmin_selective_update"});
simgrid::config::declare_flag<int>("contexts/stack-size", "Stack size of contexts in KiB (not with threads)",
8 * 1024, [](int value) { smx_context_stack_size = value * 1024; });
- simgrid::config::alias("contexts/stack-size", {"contexts/stack_size"});
/* guard size for contexts stacks in memory pages */
#if defined(_WIN32) || (PTH_STACKGROWTH != -1)
simgrid::config::declare_flag<int>("contexts/guard-size", "Guard size for contexts stacks in memory pages",
default_guard_size,
[](int value) { smx_context_guard_size = value * xbt_pagesize; });
- simgrid::config::alias("contexts/guard-size", {"contexts/guard_size"});
simgrid::config::declare_flag<int>("contexts/nthreads", "Number of parallel threads used to execute user contexts", 1,
&SIMIX_context_set_nthreads);
"meaning if(size >=thresholdN ) return valueN.",
"65472:0.940694;15424:0.697866;9376:0.58729;5776:1.08739;3484:0.77493;"
"1426:0.608902;732:0.341987;257:0.338112;0:0.812084");
- simgrid::config::alias("smpi/bw-factor", {"smpi/bw_factor"});
simgrid::config::declare_flag<std::string>("smpi/lat-factor", "Latency factors for smpi.",
"65472:11.6436;15424:3.48845;9376:2.59299;5776:2.18796;3484:1.88101;"
"1426:1.61075;732:1.9503;257:1.95341;0:2.01467");
- simgrid::config::alias("smpi/lat-factor", {"smpi/lat_factor"});
simgrid::config::declare_flag<std::string>("smpi/IB-penalty-factors",
"Correction factor to communications using Infiniband model with "
"contention (default value based on Stampede cluster profiling)",
"0.965;0.925;1.35");
- simgrid::config::alias("smpi/IB-penalty-factors", {"smpi/IB_penalty_factors"});
/* Others */
simgrid::config::declare_flag<bool>(
return simcall_BODY_execution_waitany_for(execs, count, timeout);
}
-void simcall_process_join(smx_actor_t process, double timeout) // XBT_DEPRECATED_v328
+void simcall_process_join(smx_actor_t process, double timeout) // XBT_ATTRIB_DEPRECATED_v328
{
simgrid::kernel::actor::ActorImpl::self()->join(process, timeout);
}
-void simcall_process_suspend(smx_actor_t process) // XBT_DEPRECATED_v328
+void simcall_process_suspend(smx_actor_t process) // XBT_ATTRIB_DEPRECATED_v328
{
process->get_iface()->suspend();
}
unsigned int simcall_comm_waitany(simgrid::kernel::activity::ActivityImplPtr comms[], size_t count,
double timeout) // XBT_ATTRIB_DEPRECATED_v330
{
- auto rcomms = std::make_unique<simgrid::kernel::activity::CommImpl*[]>(count);
- std::transform(comms, comms + count, rcomms.get(), [](const simgrid::kernel::activity::ActivityImplPtr& comm) {
+ std::vector<simgrid::kernel::activity::CommImpl*> rcomms(count);
+ std::transform(comms, comms + count, begin(rcomms), [](const simgrid::kernel::activity::ActivityImplPtr& comm) {
return static_cast<simgrid::kernel::activity::CommImpl*>(comm.get());
});
- return simcall_BODY_comm_waitany(rcomms.get(), count, timeout);
+ return simcall_BODY_comm_waitany(rcomms.data(), rcomms.size(), timeout);
}
unsigned int simcall_comm_waitany(simgrid::kernel::activity::CommImpl* comms[], size_t count, double timeout)
{
if (count == 0)
return -1;
- auto rcomms = std::make_unique<simgrid::kernel::activity::CommImpl*[]>(count);
- std::transform(comms, comms + count, rcomms.get(), [](const simgrid::kernel::activity::ActivityImplPtr& comm) {
+ std::vector<simgrid::kernel::activity::CommImpl*> rcomms(count);
+ std::transform(comms, comms + count, begin(rcomms), [](const simgrid::kernel::activity::ActivityImplPtr& comm) {
return static_cast<simgrid::kernel::activity::CommImpl*>(comm.get());
});
- return simcall_BODY_comm_testany(rcomms.get(), count);
+ return simcall_BODY_comm_testany(rcomms.data(), rcomms.size());
}
int simcall_comm_testany(simgrid::kernel::activity::CommImpl* comms[], size_t count)
/* ************************************************************************** */
/** @brief returns a printable string representing a simcall */
-const char *SIMIX_simcall_name(e_smx_simcall_t kind) {
- return simcall_names[kind];
+const char* SIMIX_simcall_name(Simcall kind)
+{
+ return simcall_names[static_cast<int>(kind)];
}
namespace simgrid {
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
+using simgrid::simix::Simcall;
+
template<class R, class... T>
-inline static R simcall(e_smx_simcall_t call, T const&... t)
+inline static R simcall(Simcall call, T const&... t)
{
smx_actor_t self = SIMIX_process_self();
simgrid::simix::marshal(&self->simcall_, call, t...);
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_execution_waitany_for(&SIMIX_process_self()->simcall_, execs, count, timeout);
- return simcall<int, simgrid::kernel::activity::ExecImpl**, size_t, double>(SIMCALL_EXECUTION_WAITANY_FOR, execs, count, timeout);
+ return simcall<int, simgrid::kernel::activity::ExecImpl**, size_t, double>(Simcall::EXECUTION_WAITANY_FOR, execs, count, timeout);
}
inline static void simcall_BODY_comm_send(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate, unsigned char* src_buff, size_t src_buff_size, simix_match_func_t match_fun, simix_copy_data_func_t copy_data_fun, void* data, double timeout)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_comm_send(&SIMIX_process_self()->simcall_, sender, mbox, task_size, rate, src_buff, src_buff_size, match_fun, copy_data_fun, data, timeout);
- return simcall<void, smx_actor_t, smx_mailbox_t, double, double, unsigned char*, size_t, simix_match_func_t, simix_copy_data_func_t, void*, double>(SIMCALL_COMM_SEND, sender, mbox, task_size, rate, src_buff, src_buff_size, match_fun, copy_data_fun, data, timeout);
+ return simcall<void, smx_actor_t, smx_mailbox_t, double, double, unsigned char*, size_t, simix_match_func_t, simix_copy_data_func_t, void*, double>(Simcall::COMM_SEND, sender, mbox, task_size, rate, src_buff, src_buff_size, match_fun, copy_data_fun, data, timeout);
}
inline static boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl> simcall_BODY_comm_isend(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate, unsigned char* src_buff, size_t src_buff_size, simix_match_func_t match_fun, simix_clean_func_t clean_fun, simix_copy_data_func_t copy_data_fun, void* data, bool detached)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_comm_isend(&SIMIX_process_self()->simcall_, sender, mbox, task_size, rate, src_buff, src_buff_size, match_fun, clean_fun, copy_data_fun, data, detached);
- return simcall<boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl>, smx_actor_t, smx_mailbox_t, double, double, unsigned char*, size_t, simix_match_func_t, simix_clean_func_t, simix_copy_data_func_t, void*, bool>(SIMCALL_COMM_ISEND, sender, mbox, task_size, rate, src_buff, src_buff_size, match_fun, clean_fun, copy_data_fun, data, detached);
+ return simcall<boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl>, smx_actor_t, smx_mailbox_t, double, double, unsigned char*, size_t, simix_match_func_t, simix_clean_func_t, simix_copy_data_func_t, void*, bool>(Simcall::COMM_ISEND, sender, mbox, task_size, rate, src_buff, src_buff_size, match_fun, clean_fun, copy_data_fun, data, detached);
}
inline static void simcall_BODY_comm_recv(smx_actor_t receiver, smx_mailbox_t mbox, unsigned char* dst_buff, size_t* dst_buff_size, simix_match_func_t match_fun, simix_copy_data_func_t copy_data_fun, void* data, double timeout, double rate)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_comm_recv(&SIMIX_process_self()->simcall_, receiver, mbox, dst_buff, dst_buff_size, match_fun, copy_data_fun, data, timeout, rate);
- return simcall<void, smx_actor_t, smx_mailbox_t, unsigned char*, size_t*, simix_match_func_t, simix_copy_data_func_t, void*, double, double>(SIMCALL_COMM_RECV, receiver, mbox, dst_buff, dst_buff_size, match_fun, copy_data_fun, data, timeout, rate);
+ return simcall<void, smx_actor_t, smx_mailbox_t, unsigned char*, size_t*, simix_match_func_t, simix_copy_data_func_t, void*, double, double>(Simcall::COMM_RECV, receiver, mbox, dst_buff, dst_buff_size, match_fun, copy_data_fun, data, timeout, rate);
}
inline static boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl> simcall_BODY_comm_irecv(smx_actor_t receiver, smx_mailbox_t mbox, unsigned char* dst_buff, size_t* dst_buff_size, simix_match_func_t match_fun, simix_copy_data_func_t copy_data_fun, void* data, double rate)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_comm_irecv(&SIMIX_process_self()->simcall_, receiver, mbox, dst_buff, dst_buff_size, match_fun, copy_data_fun, data, rate);
- return simcall<boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl>, smx_actor_t, smx_mailbox_t, unsigned char*, size_t*, simix_match_func_t, simix_copy_data_func_t, void*, double>(SIMCALL_COMM_IRECV, receiver, mbox, dst_buff, dst_buff_size, match_fun, copy_data_fun, data, rate);
+ return simcall<boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl>, smx_actor_t, smx_mailbox_t, unsigned char*, size_t*, simix_match_func_t, simix_copy_data_func_t, void*, double>(Simcall::COMM_IRECV, receiver, mbox, dst_buff, dst_buff_size, match_fun, copy_data_fun, data, rate);
}
inline static int simcall_BODY_comm_waitany(simgrid::kernel::activity::CommImpl** comms, size_t count, double timeout)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_comm_waitany(&SIMIX_process_self()->simcall_, comms, count, timeout);
- return simcall<int, simgrid::kernel::activity::CommImpl**, size_t, double>(SIMCALL_COMM_WAITANY, comms, count, timeout);
+ return simcall<int, simgrid::kernel::activity::CommImpl**, size_t, double>(Simcall::COMM_WAITANY, comms, count, timeout);
}
inline static void simcall_BODY_comm_wait(simgrid::kernel::activity::CommImpl* comm, double timeout)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_comm_wait(&SIMIX_process_self()->simcall_, comm, timeout);
- return simcall<void, simgrid::kernel::activity::CommImpl*, double>(SIMCALL_COMM_WAIT, comm, timeout);
+ return simcall<void, simgrid::kernel::activity::CommImpl*, double>(Simcall::COMM_WAIT, comm, timeout);
}
inline static bool simcall_BODY_comm_test(simgrid::kernel::activity::CommImpl* comm)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_comm_test(&SIMIX_process_self()->simcall_, comm);
- return simcall<bool, simgrid::kernel::activity::CommImpl*>(SIMCALL_COMM_TEST, comm);
+ return simcall<bool, simgrid::kernel::activity::CommImpl*>(Simcall::COMM_TEST, comm);
}
inline static int simcall_BODY_comm_testany(simgrid::kernel::activity::CommImpl** comms, size_t count)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_comm_testany(&SIMIX_process_self()->simcall_, comms, count);
- return simcall<int, simgrid::kernel::activity::CommImpl**, size_t>(SIMCALL_COMM_TESTANY, comms, count);
+ return simcall<int, simgrid::kernel::activity::CommImpl**, size_t>(Simcall::COMM_TESTANY, comms, count);
}
inline static void simcall_BODY_mutex_lock(smx_mutex_t mutex)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_mutex_lock(&SIMIX_process_self()->simcall_, mutex);
- return simcall<void, smx_mutex_t>(SIMCALL_MUTEX_LOCK, mutex);
+ return simcall<void, smx_mutex_t>(Simcall::MUTEX_LOCK, mutex);
}
inline static int simcall_BODY_mutex_trylock(smx_mutex_t mutex)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_mutex_trylock(&SIMIX_process_self()->simcall_, mutex);
- return simcall<int, smx_mutex_t>(SIMCALL_MUTEX_TRYLOCK, mutex);
+ return simcall<int, smx_mutex_t>(Simcall::MUTEX_TRYLOCK, mutex);
}
inline static void simcall_BODY_mutex_unlock(smx_mutex_t mutex)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_mutex_unlock(&SIMIX_process_self()->simcall_, mutex);
- return simcall<void, smx_mutex_t>(SIMCALL_MUTEX_UNLOCK, mutex);
+ return simcall<void, smx_mutex_t>(Simcall::MUTEX_UNLOCK, mutex);
}
inline static void simcall_BODY_cond_wait(smx_cond_t cond, smx_mutex_t mutex)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_cond_wait(&SIMIX_process_self()->simcall_, cond, mutex);
- return simcall<void, smx_cond_t, smx_mutex_t>(SIMCALL_COND_WAIT, cond, mutex);
+ return simcall<void, smx_cond_t, smx_mutex_t>(Simcall::COND_WAIT, cond, mutex);
}
inline static int simcall_BODY_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_cond_wait_timeout(&SIMIX_process_self()->simcall_, cond, mutex, timeout);
- return simcall<int, smx_cond_t, smx_mutex_t, double>(SIMCALL_COND_WAIT_TIMEOUT, cond, mutex, timeout);
+ return simcall<int, smx_cond_t, smx_mutex_t, double>(Simcall::COND_WAIT_TIMEOUT, cond, mutex, timeout);
}
inline static void simcall_BODY_sem_acquire(smx_sem_t sem)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_sem_acquire(&SIMIX_process_self()->simcall_, sem);
- return simcall<void, smx_sem_t>(SIMCALL_SEM_ACQUIRE, sem);
+ return simcall<void, smx_sem_t>(Simcall::SEM_ACQUIRE, sem);
}
inline static int simcall_BODY_sem_acquire_timeout(smx_sem_t sem, double timeout)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_sem_acquire_timeout(&SIMIX_process_self()->simcall_, sem, timeout);
- return simcall<int, smx_sem_t, double>(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem, timeout);
+ return simcall<int, smx_sem_t, double>(Simcall::SEM_ACQUIRE_TIMEOUT, sem, timeout);
}
inline static int simcall_BODY_mc_random(int min, int max)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
simcall_HANDLER_mc_random(&SIMIX_process_self()->simcall_, min, max);
- return simcall<int, int, int>(SIMCALL_MC_RANDOM, min, max);
+ return simcall<int, int, int>(Simcall::MC_RANDOM, min, max);
}
inline static void simcall_BODY_run_kernel(std::function<void()> const* code)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
SIMIX_run_kernel(code);
- return simcall<void, std::function<void()> const*>(SIMCALL_RUN_KERNEL, code);
+ return simcall<void, std::function<void()> const*>(Simcall::RUN_KERNEL, code);
}
inline static void simcall_BODY_run_blocking(std::function<void()> const* code)
{
if (false) /* Go to that function to follow the code flow through the simcall barrier */
SIMIX_run_blocking(code);
- return simcall<void, std::function<void()> const*>(SIMCALL_RUN_BLOCKING, code);
+ return simcall<void, std::function<void()> const*>(Simcall::RUN_BLOCKING, code);
}
/** @endcond */
* That's not about http://en.wikipedia.org/wiki/Poop, despite the odor :)
*/
+namespace simgrid {
+namespace simix {
/**
* @brief All possible simcalls.
*/
-enum e_smx_simcall_t {
- SIMCALL_NONE,
- SIMCALL_EXECUTION_WAITANY_FOR,
- SIMCALL_COMM_SEND,
- SIMCALL_COMM_ISEND,
- SIMCALL_COMM_RECV,
- SIMCALL_COMM_IRECV,
- SIMCALL_COMM_WAITANY,
- SIMCALL_COMM_WAIT,
- SIMCALL_COMM_TEST,
- SIMCALL_COMM_TESTANY,
- SIMCALL_MUTEX_LOCK,
- SIMCALL_MUTEX_TRYLOCK,
- SIMCALL_MUTEX_UNLOCK,
- SIMCALL_COND_WAIT,
- SIMCALL_COND_WAIT_TIMEOUT,
- SIMCALL_SEM_ACQUIRE,
- SIMCALL_SEM_ACQUIRE_TIMEOUT,
- SIMCALL_MC_RANDOM,
- SIMCALL_RUN_KERNEL,
- SIMCALL_RUN_BLOCKING,
- NUM_SIMCALLS
+enum class Simcall {
+ NONE,
+ EXECUTION_WAITANY_FOR,
+ COMM_SEND,
+ COMM_ISEND,
+ COMM_RECV,
+ COMM_IRECV,
+ COMM_WAITANY,
+ COMM_WAIT,
+ COMM_TEST,
+ COMM_TESTANY,
+ MUTEX_LOCK,
+ MUTEX_TRYLOCK,
+ MUTEX_UNLOCK,
+ COND_WAIT,
+ COND_WAIT_TIMEOUT,
+ SEM_ACQUIRE,
+ SEM_ACQUIRE_TIMEOUT,
+ MC_RANDOM,
+ RUN_KERNEL,
+ RUN_BLOCKING,
};
+
+constexpr int NUM_SIMCALLS = 20;
+} // namespace simix
+} // namespace simgrid
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);
+using simgrid::simix::Simcall;
/** @brief Simcalls' names (generated from src/simix/simcalls.in) */
-constexpr std::array<const char*, NUM_SIMCALLS> simcall_names{{
- "SIMCALL_NONE",
- "SIMCALL_EXECUTION_WAITANY_FOR",
- "SIMCALL_COMM_SEND",
- "SIMCALL_COMM_ISEND",
- "SIMCALL_COMM_RECV",
- "SIMCALL_COMM_IRECV",
- "SIMCALL_COMM_WAITANY",
- "SIMCALL_COMM_WAIT",
- "SIMCALL_COMM_TEST",
- "SIMCALL_COMM_TESTANY",
- "SIMCALL_MUTEX_LOCK",
- "SIMCALL_MUTEX_TRYLOCK",
- "SIMCALL_MUTEX_UNLOCK",
- "SIMCALL_COND_WAIT",
- "SIMCALL_COND_WAIT_TIMEOUT",
- "SIMCALL_SEM_ACQUIRE",
- "SIMCALL_SEM_ACQUIRE_TIMEOUT",
- "SIMCALL_MC_RANDOM",
- "SIMCALL_RUN_KERNEL",
- "SIMCALL_RUN_BLOCKING",
+constexpr std::array<const char*, simgrid::simix::NUM_SIMCALLS> simcall_names{{
+ "Simcall::NONE",
+ "Simcall::EXECUTION_WAITANY_FOR",
+ "Simcall::COMM_SEND",
+ "Simcall::COMM_ISEND",
+ "Simcall::COMM_RECV",
+ "Simcall::COMM_IRECV",
+ "Simcall::COMM_WAITANY",
+ "Simcall::COMM_WAIT",
+ "Simcall::COMM_TEST",
+ "Simcall::COMM_TESTANY",
+ "Simcall::MUTEX_LOCK",
+ "Simcall::MUTEX_TRYLOCK",
+ "Simcall::MUTEX_UNLOCK",
+ "Simcall::COND_WAIT",
+ "Simcall::COND_WAIT_TIMEOUT",
+ "Simcall::SEM_ACQUIRE",
+ "Simcall::SEM_ACQUIRE_TIMEOUT",
+ "Simcall::MC_RANDOM",
+ "Simcall::RUN_KERNEL",
+ "Simcall::RUN_BLOCKING",
}};
/** @private
if (context_->wannadie())
return;
switch (simcall_.call_) {
- case SIMCALL_EXECUTION_WAITANY_FOR:
+ case Simcall::EXECUTION_WAITANY_FOR:
simcall_HANDLER_execution_waitany_for(&simcall_, simgrid::simix::unmarshal<simgrid::kernel::activity::ExecImpl**>(simcall_.args_[0]), simgrid::simix::unmarshal<size_t>(simcall_.args_[1]), simgrid::simix::unmarshal<double>(simcall_.args_[2]));
break;
- case SIMCALL_COMM_SEND:
+ case Simcall::COMM_SEND:
simcall_HANDLER_comm_send(&simcall_, simgrid::simix::unmarshal<smx_actor_t>(simcall_.args_[0]), simgrid::simix::unmarshal<smx_mailbox_t>(simcall_.args_[1]), simgrid::simix::unmarshal<double>(simcall_.args_[2]), simgrid::simix::unmarshal<double>(simcall_.args_[3]), simgrid::simix::unmarshal<unsigned char*>(simcall_.args_[4]), simgrid::simix::unmarshal<size_t>(simcall_.args_[5]), simgrid::simix::unmarshal<simix_match_func_t>(simcall_.args_[6]), simgrid::simix::unmarshal<simix_copy_data_func_t>(simcall_.args_[7]), simgrid::simix::unmarshal<void*>(simcall_.args_[8]), simgrid::simix::unmarshal<double>(simcall_.args_[9]));
break;
- case SIMCALL_COMM_ISEND:
+ case Simcall::COMM_ISEND:
simgrid::simix::marshal<boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl>>(simcall_.result_, simcall_HANDLER_comm_isend(&simcall_, simgrid::simix::unmarshal<smx_actor_t>(simcall_.args_[0]), simgrid::simix::unmarshal<smx_mailbox_t>(simcall_.args_[1]), simgrid::simix::unmarshal<double>(simcall_.args_[2]), simgrid::simix::unmarshal<double>(simcall_.args_[3]), simgrid::simix::unmarshal<unsigned char*>(simcall_.args_[4]), simgrid::simix::unmarshal<size_t>(simcall_.args_[5]), simgrid::simix::unmarshal<simix_match_func_t>(simcall_.args_[6]), simgrid::simix::unmarshal<simix_clean_func_t>(simcall_.args_[7]), simgrid::simix::unmarshal<simix_copy_data_func_t>(simcall_.args_[8]), simgrid::simix::unmarshal<void*>(simcall_.args_[9]), simgrid::simix::unmarshal<bool>(simcall_.args_[10])));
simcall_answer();
break;
- case SIMCALL_COMM_RECV:
+ case Simcall::COMM_RECV:
simcall_HANDLER_comm_recv(&simcall_, simgrid::simix::unmarshal<smx_actor_t>(simcall_.args_[0]), simgrid::simix::unmarshal<smx_mailbox_t>(simcall_.args_[1]), simgrid::simix::unmarshal<unsigned char*>(simcall_.args_[2]), simgrid::simix::unmarshal<size_t*>(simcall_.args_[3]), simgrid::simix::unmarshal<simix_match_func_t>(simcall_.args_[4]), simgrid::simix::unmarshal<simix_copy_data_func_t>(simcall_.args_[5]), simgrid::simix::unmarshal<void*>(simcall_.args_[6]), simgrid::simix::unmarshal<double>(simcall_.args_[7]), simgrid::simix::unmarshal<double>(simcall_.args_[8]));
break;
- case SIMCALL_COMM_IRECV:
+ case Simcall::COMM_IRECV:
simgrid::simix::marshal<boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl>>(simcall_.result_, simcall_HANDLER_comm_irecv(&simcall_, simgrid::simix::unmarshal<smx_actor_t>(simcall_.args_[0]), simgrid::simix::unmarshal<smx_mailbox_t>(simcall_.args_[1]), simgrid::simix::unmarshal<unsigned char*>(simcall_.args_[2]), simgrid::simix::unmarshal<size_t*>(simcall_.args_[3]), simgrid::simix::unmarshal<simix_match_func_t>(simcall_.args_[4]), simgrid::simix::unmarshal<simix_copy_data_func_t>(simcall_.args_[5]), simgrid::simix::unmarshal<void*>(simcall_.args_[6]), simgrid::simix::unmarshal<double>(simcall_.args_[7])));
simcall_answer();
break;
- case SIMCALL_COMM_WAITANY:
+ case Simcall::COMM_WAITANY:
simcall_HANDLER_comm_waitany(&simcall_, simgrid::simix::unmarshal<simgrid::kernel::activity::CommImpl**>(simcall_.args_[0]), simgrid::simix::unmarshal<size_t>(simcall_.args_[1]), simgrid::simix::unmarshal<double>(simcall_.args_[2]));
break;
- case SIMCALL_COMM_WAIT:
+ case Simcall::COMM_WAIT:
simcall_HANDLER_comm_wait(&simcall_, simgrid::simix::unmarshal<simgrid::kernel::activity::CommImpl*>(simcall_.args_[0]), simgrid::simix::unmarshal<double>(simcall_.args_[1]));
break;
- case SIMCALL_COMM_TEST:
+ case Simcall::COMM_TEST:
simcall_HANDLER_comm_test(&simcall_, simgrid::simix::unmarshal<simgrid::kernel::activity::CommImpl*>(simcall_.args_[0]));
break;
- case SIMCALL_COMM_TESTANY:
+ case Simcall::COMM_TESTANY:
simcall_HANDLER_comm_testany(&simcall_, simgrid::simix::unmarshal<simgrid::kernel::activity::CommImpl**>(simcall_.args_[0]), simgrid::simix::unmarshal<size_t>(simcall_.args_[1]));
break;
- case SIMCALL_MUTEX_LOCK:
+ case Simcall::MUTEX_LOCK:
simcall_HANDLER_mutex_lock(&simcall_, simgrid::simix::unmarshal<smx_mutex_t>(simcall_.args_[0]));
break;
- case SIMCALL_MUTEX_TRYLOCK:
+ case Simcall::MUTEX_TRYLOCK:
simgrid::simix::marshal<int>(simcall_.result_, simcall_HANDLER_mutex_trylock(&simcall_, simgrid::simix::unmarshal<smx_mutex_t>(simcall_.args_[0])));
simcall_answer();
break;
- case SIMCALL_MUTEX_UNLOCK:
+ case Simcall::MUTEX_UNLOCK:
simcall_HANDLER_mutex_unlock(&simcall_, simgrid::simix::unmarshal<smx_mutex_t>(simcall_.args_[0]));
simcall_answer();
break;
- case SIMCALL_COND_WAIT:
+ case Simcall::COND_WAIT:
simcall_HANDLER_cond_wait(&simcall_, simgrid::simix::unmarshal<smx_cond_t>(simcall_.args_[0]), simgrid::simix::unmarshal<smx_mutex_t>(simcall_.args_[1]));
break;
- case SIMCALL_COND_WAIT_TIMEOUT:
+ case Simcall::COND_WAIT_TIMEOUT:
simcall_HANDLER_cond_wait_timeout(&simcall_, simgrid::simix::unmarshal<smx_cond_t>(simcall_.args_[0]), simgrid::simix::unmarshal<smx_mutex_t>(simcall_.args_[1]), simgrid::simix::unmarshal<double>(simcall_.args_[2]));
break;
- case SIMCALL_SEM_ACQUIRE:
+ case Simcall::SEM_ACQUIRE:
simcall_HANDLER_sem_acquire(&simcall_, simgrid::simix::unmarshal<smx_sem_t>(simcall_.args_[0]));
break;
- case SIMCALL_SEM_ACQUIRE_TIMEOUT:
+ case Simcall::SEM_ACQUIRE_TIMEOUT:
simcall_HANDLER_sem_acquire_timeout(&simcall_, simgrid::simix::unmarshal<smx_sem_t>(simcall_.args_[0]), simgrid::simix::unmarshal<double>(simcall_.args_[1]));
break;
- case SIMCALL_MC_RANDOM:
+ case Simcall::MC_RANDOM:
simgrid::simix::marshal<int>(simcall_.result_, simcall_HANDLER_mc_random(&simcall_, simgrid::simix::unmarshal<int>(simcall_.args_[0]), simgrid::simix::unmarshal<int>(simcall_.args_[1])));
simcall_answer();
break;
- case SIMCALL_RUN_KERNEL:
+ case Simcall::RUN_KERNEL:
SIMIX_run_kernel(simgrid::simix::unmarshal<std::function<void()> const*>(simcall_.args_[0]));
simcall_answer();
break;
- case SIMCALL_RUN_BLOCKING:
+ case Simcall::RUN_BLOCKING:
SIMIX_run_blocking(simgrid::simix::unmarshal<std::function<void()> const*>(simcall_.args_[0]));
break;
- case NUM_SIMCALLS:
- break;
- case SIMCALL_NONE:
+ case Simcall::NONE:
throw std::invalid_argument(simgrid::xbt::string_printf("Asked to do the noop syscall on %s@%s",
get_cname(),
sg_host_get_name(get_host())));
#include <boost/intrusive_ptr.hpp>
/********************************* Simcalls *********************************/
-#include "popping_enum.hpp" /* Definition of e_smx_simcall_t, with one value per simcall */
+#include "popping_enum.hpp" /* Definition of Simcall, with one value per simcall */
-XBT_PUBLIC_DATA const std::array<const char*, NUM_SIMCALLS> simcall_names; /* Name of each simcall */
+XBT_PUBLIC_DATA const std::array<const char*, simgrid::simix::NUM_SIMCALLS> simcall_names; /* Name of each simcall */
-typedef bool (*simix_match_func_t)(void*, void*, simgrid::kernel::activity::CommImpl*);
-typedef void (*simix_copy_data_func_t)(simgrid::kernel::activity::CommImpl*, void*, size_t);
-typedef void (*simix_clean_func_t)(void*);
-typedef void (*FPtr)(); // Hide the ugliness
+using simix_match_func_t = bool (*)(void*, void*, simgrid::kernel::activity::CommImpl*);
+using simix_copy_data_func_t = void (*)(simgrid::kernel::activity::CommImpl*, void*, size_t);
+using simix_clean_func_t = void (*)(void*);
+using FPtr = void (*)(); // Hide the ugliness
/* Pack all possible scalar types in an union */
union u_smx_scalar {
* @brief Represents a simcall to the kernel.
*/
struct s_smx_simcall {
- e_smx_simcall_t call_ = SIMCALL_NONE;
+ simgrid::simix::Simcall call_ = simgrid::simix::Simcall::NONE;
smx_actor_t issuer_ = nullptr;
smx_timer_t timeout_cb_ = nullptr; // Callback to timeouts
simgrid::mc::SimcallInspector* inspector_ = nullptr; // makes that simcall observable by the MC
int mc_value_ = 0;
- u_smx_scalar args_[11] = {};
+ std::array<u_smx_scalar, 11> args_ = {};
u_smx_scalar result_ = {};
};
/******************************** General *************************************/
-XBT_PRIVATE const char* SIMIX_simcall_name(e_smx_simcall_t kind);
+XBT_PRIVATE const char* SIMIX_simcall_name(simgrid::simix::Simcall kind);
XBT_PRIVATE void SIMIX_run_kernel(std::function<void()> const* code);
XBT_PRIVATE void SIMIX_run_blocking(std::function<void()> const* code);
}
/** Initialize the simcall */
-template <class... A> inline void marshal(smx_simcall_t simcall, e_smx_simcall_t call, A const&... a)
+template <class... A> inline void marshal(smx_simcall_t simcall, Simcall call, A const&... a)
{
simcall->call_ = call;
- memset(&simcall->result_, 0, sizeof(simcall->result_));
- memset(simcall->args_, 0, sizeof(simcall->args_));
+ memset(&simcall->result_, 0, sizeof simcall->result_);
+ memset(simcall->args_.data(), 0, simcall->args_.size() * sizeof simcall->args_[0]);
marshal_args<0>(simcall, a...);
}
}
return True
def enum(self):
- return ' SIMCALL_%s,' % (self.name.upper())
+ return ' %s,' % (self.name.upper())
def string(self):
- return ' "SIMCALL_%s",' % self.name.upper()
+ return ' "Simcall::%s",' % self.name.upper()
def accessors(self):
res = []
indent = ' '
args = ["simgrid::simix::unmarshal<%s>(simcall_.args_[%d])" % (arg.rettype(), i)
for i, arg in enumerate(self.args)]
- res.append(indent + 'case SIMCALL_%s:' % (self.name.upper()))
+ res.append(indent + 'case Simcall::%s:' % (self.name.upper()))
if self.need_handler:
call = "simcall_HANDLER_%s(&simcall_%s%s)" % (self.name,
", " if args else "",
else:
res.append(' SIMIX_%s(%s);' % (self.name,
', '.join(arg.name for arg in self.args)))
- res.append(' return simcall<%s%s>(SIMCALL_%s%s);' % (
+ res.append(' return simcall<%s%s>(Simcall::%s%s);' % (
self.res.rettype(),
"".join([", " + arg.rettype() for i, arg in enumerate(self.args)]),
self.name.upper(),
# popping_enum.hpp
#
fd = header("popping_enum.hpp")
+ fd.write('namespace simgrid {\n')
+ fd.write('namespace simix {\n')
fd.write('/**\n')
fd.write(' * @brief All possible simcalls.\n')
fd.write(' */\n')
- fd.write('enum e_smx_simcall_t {\n')
- fd.write(' SIMCALL_NONE,\n')
+ fd.write('enum class Simcall {\n')
+ fd.write(' NONE,\n')
handle(fd, Simcall.enum, simcalls, simcalls_dict)
- fd.write(' NUM_SIMCALLS\n')
fd.write('};\n')
+ fd.write('\n')
+ fd.write('constexpr int NUM_SIMCALLS = ' + str(1 + len(simcalls)) + ';\n')
+ fd.write('} // namespace simix\n')
+ fd.write('} // namespace simgrid\n')
fd.close()
#
fd.write('\n')
fd.write('XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_popping);\n\n')
+ fd.write('using simgrid::simix::Simcall;')
+ fd.write('\n')
fd.write(
'/** @brief Simcalls\' names (generated from src/simix/simcalls.in) */\n')
- fd.write('constexpr std::array<const char*, NUM_SIMCALLS> simcall_names{{\n')
+ fd.write('constexpr std::array<const char*, simgrid::simix::NUM_SIMCALLS> simcall_names{{\n')
- fd.write(' "SIMCALL_NONE",\n')
+ fd.write(' "Simcall::NONE",\n')
handle(fd, Simcall.string, simcalls, simcalls_dict)
fd.write('}};\n\n')
handle(fd, Simcall.case, simcalls, simcalls_dict)
- fd.write(' case NUM_SIMCALLS:\n')
- fd.write(' break;\n')
- fd.write(' case SIMCALL_NONE:\n')
+ fd.write(' case Simcall::NONE:\n')
fd.write(' throw std::invalid_argument(simgrid::xbt::string_printf("Asked to do the noop syscall on %s@%s",\n')
fd.write(' get_cname(),\n')
fd.write(' sg_host_get_name(get_host())));\n')
fd.write('''
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
+using simgrid::simix::Simcall;
+
template<class R, class... T>
-inline static R simcall(e_smx_simcall_t call, T const&... t)
+inline static R simcall(Simcall call, T const&... t)
{
smx_actor_t self = SIMIX_process_self();
simgrid::simix::marshal(&self->simcall_, call, t...);
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_deployment, simix, "Logging specific to SIMIX (deployment)");
-void SIMIX_init_application() // XBT_DEPRECATED_v329
+void SIMIX_init_application() // XBT_ATTRIB_DEPRECATED_v329
{
sg_platf_exit();
sg_platf_init();
}
-void SIMIX_launch_application(const std::string& file) // XBT_DEPRECATED_v329
+void SIMIX_launch_application(const std::string& file) // XBT_ATTRIB_DEPRECATED_v329
{
simgrid_load_deployment(file.c_str());
}
-void SIMIX_function_register(const std::string& name, xbt_main_func_t code) // XBT_DEPRECATED_v329
+void SIMIX_function_register(const std::string& name, xbt_main_func_t code) // XBT_ATTRIB_DEPRECATED_v329
{
simgrid::s4u::Engine::get_instance()->register_function(name, code);
}
-void SIMIX_function_register(const std::string& name, void (*code)(std::vector<std::string>)) // XBT_DEPRECATED_v329
+void SIMIX_function_register(const std::string& name,
+ void (*code)(std::vector<std::string>)) // XBT_ATTRIB_DEPRECATED_v329
{
simgrid::s4u::Engine::get_instance()->register_function(name, code);
}
-void SIMIX_function_register_default(xbt_main_func_t code) // XBT_DEPRECATED_v329
+void SIMIX_function_register_default(xbt_main_func_t code) // XBT_ATTRIB_DEPRECATED_v329
{
simgrid::s4u::Engine::get_instance()->register_default(code);
}
xbt_assert(parse_code, "Function '%s' unknown", process_function);
actor.function = process_function;
- actor.host = process_host;
actor.kill_time = process_kill_time;
actor.start_time = process_start_time;
actor.restart_on_failure = false;
namespace simgrid {
namespace simix {
-config::Flag<bool> cfg_verbose_exit{"debug/verbose-exit", {"verbose-exit"}, "Display the actor status at exit", true};
+config::Flag<bool> cfg_verbose_exit{"debug/verbose-exit",
+ {"verbose-exit"}, // XBT_ATTRIB_DEPRECATED_v327(option alias)
+ "Display the actor status at exit",
+ true};
} // namespace simix
} // namespace simgrid
}
}
-config::Flag<double> cfg_breakpoint{
- "debug/breakpoint", {"simix/breakpoint"}, "When non-negative, raise a SIGTRAP after given (simulated) time", -1.0};
+config::Flag<double> cfg_breakpoint{"debug/breakpoint",
+ {"simix/breakpoint"}, // XBT_ATTRIB_DEPRECATED_v327(option alias)
+ "When non-negative, raise a SIGTRAP after given (simulated) time",
+ -1.0};
} // namespace simix
} // namespace simgrid
*/
for (auto const& actor : simix_global->actors_that_ran) {
- if (actor->simcall_.call_ != SIMCALL_NONE) {
+ if (actor->simcall_.call_ != simgrid::simix::Simcall::NONE) {
actor->simcall_handle(0);
}
}
#include "smpi_win.hpp"
#include "src/smpi/include/smpi_actor.hpp"
+#include <string>
+
static int running_processes = 0;
void smpi_init_fortran_types()
size--;
name++;
}
- char* tname = xbt_new(char,size+1);
- strncpy(tname, name, size);
- tname[size]='\0';
- *ierr = MPI_Win_set_name(simgrid::smpi::Win::f2c(*win), tname);
- xbt_free(tname);
+ std::string tname(name, size);
+ *ierr = MPI_Win_set_name(simgrid::smpi::Win::f2c(*win), tname.c_str());
}
void mpi_win_get_name_(int* win, char* name, int* len, int* ierr)
keylen--;
key++;
}
- char* tkey = xbt_new(char,keylen+1);
- strncpy(tkey, key, keylen);
- tkey[keylen]='\0';
+ std::string tkey(key, keylen);
while(value[valuelen-1]==' ')
valuelen--;
valuelen--;
value++;
}
- char* tvalue = xbt_new(char,valuelen+1);
- strncpy(tvalue, value, valuelen);
- tvalue[valuelen]='\0';
+ std::string tvalue(value, valuelen);
- *ierr = MPI_Info_set( simgrid::smpi::Info::f2c(*info), tkey, tvalue);
- xbt_free(tkey);
- xbt_free(tvalue);
+ *ierr = MPI_Info_set(simgrid::smpi::Info::f2c(*info), tkey.c_str(), tvalue.c_str());
}
void mpi_info_get_(int* info, char* key, int* valuelen, char* value, int* flag, int* ierr, unsigned int keylen)
keylen--;
key++;
}
- char* tkey = xbt_new(char,keylen+1);
- strncpy(tkey, key, keylen);
- tkey[keylen]='\0';
- *ierr = MPI_Info_get(simgrid::smpi::Info::f2c(*info),tkey,*valuelen, value, flag);
- xbt_free(tkey);
+ std::string tkey(key, keylen);
+ *ierr = MPI_Info_get(simgrid::smpi::Info::f2c(*info), tkey.c_str(), *valuelen, value, flag);
if(*flag!=0){
int replace=0;
for (int i = 0; i < *valuelen; i++) {
keylen--;
key++;
}
- char* tkey = xbt_new(char, keylen+1);
- strncpy(tkey, key, keylen);
- tkey[keylen]='\0';
- *ierr = MPI_Info_get_valuelen( simgrid::smpi::Info::f2c(*info), tkey, valuelen, flag);
- xbt_free(tkey);
+ std::string tkey(key, keylen);
+ *ierr = MPI_Info_get_valuelen(simgrid::smpi::Info::f2c(*info), tkey.c_str(), valuelen, flag);
}
void mpi_info_delete_ (int* info, char *key, int* ierr, unsigned int keylen){
keylen--;
key++;
}
- char* tkey = xbt_new(char, keylen+1);
- strncpy(tkey, key, keylen);
- tkey[keylen]='\0';
- *ierr = MPI_Info_delete(simgrid::smpi::Info::f2c(*info), tkey);
- xbt_free(tkey);
+ std::string tkey(key, keylen);
+ *ierr = MPI_Info_delete(simgrid::smpi::Info::f2c(*info), tkey.c_str());
}
void mpi_info_get_nkeys_ ( int* info, int *nkeys, int* ierr){
void mpi_info_get_nthkey_ ( int* info, int* n, char *key, int* ierr, unsigned int keylen){
*ierr = MPI_Info_get_nthkey( simgrid::smpi::Info::f2c(*info), *n, key);
- for (unsigned int i = strlen(key); i < keylen; i++)
+ for (auto i = static_cast<unsigned>(strlen(key)); i < keylen; i++)
key[i]=' ';
}
void mpi_alltoallw_ ( void *sendbuf, int *sendcnts, int *sdispls, int* old_sendtypes, void *recvbuf, int *recvcnts,
int *rdispls, int* old_recvtypes, int* comm, int* ierr){
int size = simgrid::smpi::Comm::f2c(*comm)->size();
- auto* sendtypes = new MPI_Datatype[size];
- auto* recvtypes = new MPI_Datatype[size];
+ std::vector<MPI_Datatype> sendtypes(size);
+ std::vector<MPI_Datatype> recvtypes(size);
for(int i=0; i< size; i++){
if(FORT_IN_PLACE(sendbuf)!=MPI_IN_PLACE)
sendtypes[i] = simgrid::smpi::Datatype::f2c(old_sendtypes[i]);
recvtypes[i] = simgrid::smpi::Datatype::f2c(old_recvtypes[i]);
}
sendbuf = static_cast<char *>( FORT_IN_PLACE(sendbuf));
- *ierr = MPI_Alltoallw( sendbuf, sendcnts, sdispls, sendtypes, recvbuf, recvcnts, rdispls,
- recvtypes, simgrid::smpi::Comm::f2c(*comm));
- delete[] sendtypes;
- delete[] recvtypes;
+ *ierr = MPI_Alltoallw(sendbuf, sendcnts, sdispls, sendtypes.data(), recvbuf, recvcnts, rdispls, recvtypes.data(),
+ simgrid::smpi::Comm::f2c(*comm));
}
void mpi_exscan_ (void *sendbuf, void *recvbuf, int* count, int* datatype, int* op, int* comm, int* ierr){
int *rdispls, int* old_recvtypes, int* comm, int* request, int* ierr){
MPI_Request req;
int size = simgrid::smpi::Comm::f2c(*comm)->size();
- auto* sendtypes = new MPI_Datatype[size];
- auto* recvtypes = new MPI_Datatype[size];
+ std::vector<MPI_Datatype> sendtypes(size);
+ std::vector<MPI_Datatype> recvtypes(size);
for(int i=0; i< size; i++){
if(FORT_IN_PLACE(sendbuf)!=MPI_IN_PLACE)
sendtypes[i] = simgrid::smpi::Datatype::f2c(old_sendtypes[i]);
recvtypes[i] = simgrid::smpi::Datatype::f2c(old_recvtypes[i]);
}
sendbuf = static_cast<char *>( FORT_IN_PLACE(sendbuf));
- *ierr = MPI_Ialltoallw( sendbuf, sendcnts, sdispls, sendtypes, recvbuf, recvcnts, rdispls,
- recvtypes, simgrid::smpi::Comm::f2c(*comm), &req);
+ *ierr = MPI_Ialltoallw(sendbuf, sendcnts, sdispls, sendtypes.data(), recvbuf, recvcnts, rdispls, recvtypes.data(),
+ simgrid::smpi::Comm::f2c(*comm), &req);
if(*ierr == MPI_SUCCESS) {
*request = req->add_f();
}
- delete[] sendtypes;
- delete[] recvtypes;
}
void mpi_iexscan_ (void *sendbuf, void *recvbuf, int* count, int* datatype, int* op, int* comm, int* request, int* ierr){
#include "smpi_errhandler.hpp"
#include "smpi_info.hpp"
+#include <string>
+
extern "C" { // This should really use the C linkage to be usable from Fortran
void mpi_comm_rank_(int* comm, int* rank, int* ierr) {
int count;
for(count=MPI_MAX_OBJECT_NAME-1; count>=0 && name[count]==' '; count--);
count+=1;
- char* tname = xbt_new(char, count+1);
- strncpy(tname, name, count);
- tname[count]='\0';
- *ierr = MPI_Comm_set_name (simgrid::smpi::Comm::f2c(*comm), tname);
- xbt_free(tname);
+ std::string tname(name, count);
+ *ierr = MPI_Comm_set_name(simgrid::smpi::Comm::f2c(*comm), tname.c_str());
}
void mpi_comm_dup_with_info_ (int* comm, int* info, int* newcomm, int* ierr){
*ierr = MPI_Start(&req);
}
-void mpi_startall_(int* count, int* requests, int* ierr) {
- MPI_Request* reqs;
-
- reqs = xbt_new(MPI_Request, *count);
+void mpi_startall_(int* count, int* requests, int* ierr)
+{
+ std::vector<MPI_Request> reqs(*count);
for (int i = 0; i < *count; i++) {
reqs[i] = simgrid::smpi::Request::f2c(requests[i]);
}
- *ierr = MPI_Startall(*count, reqs);
- xbt_free(reqs);
+ *ierr = MPI_Startall(*count, reqs.data());
}
void mpi_wait_(int* request, MPI_Status* status, int* ierr) {
}
}
-void mpi_waitany_(int* count, int* requests, int* index, MPI_Status* status, int* ierr) {
- MPI_Request* reqs;
-
- reqs = xbt_new(MPI_Request, *count);
+void mpi_waitany_(int* count, int* requests, int* index, MPI_Status* status, int* ierr)
+{
+ std::vector<MPI_Request> reqs(*count);
for (int i = 0; i < *count; i++) {
reqs[i] = simgrid::smpi::Request::f2c(requests[i]);
}
- *ierr = MPI_Waitany(*count, reqs, index, status);
+ *ierr = MPI_Waitany(*count, reqs.data(), index, status);
if(*index!=MPI_UNDEFINED){
if(reqs[*index]==MPI_REQUEST_NULL){
simgrid::smpi::Request::free_f(requests[*index]);
}
*index=*index+1;
}
- xbt_free(reqs);
}
-void mpi_waitall_(int* count, int* requests, MPI_Status* status, int* ierr) {
- MPI_Request* reqs;
- int i;
-
- reqs = xbt_new(MPI_Request, *count);
- for(i = 0; i < *count; i++) {
+void mpi_waitall_(int* count, int* requests, MPI_Status* status, int* ierr)
+{
+ std::vector<MPI_Request> reqs(*count);
+ for (int i = 0; i < *count; i++) {
reqs[i] = simgrid::smpi::Request::f2c(requests[i]);
}
- *ierr = MPI_Waitall(*count, reqs, FORT_STATUSES_IGNORE(status));
- for(i = 0; i < *count; i++) {
- if(reqs[i]==MPI_REQUEST_NULL){
- simgrid::smpi::Request::free_f(requests[i]);
- requests[i]=MPI_FORTRAN_REQUEST_NULL;
- }
+ *ierr = MPI_Waitall(*count, reqs.data(), FORT_STATUSES_IGNORE(status));
+ for (int i = 0; i < *count; i++) {
+ if (reqs[i] == MPI_REQUEST_NULL) {
+ simgrid::smpi::Request::free_f(requests[i]);
+ requests[i] = MPI_FORTRAN_REQUEST_NULL;
+ }
}
-
- xbt_free(reqs);
}
void mpi_waitsome_ (int* incount, int* requests, int *outcount, int *indices, MPI_Status* status, int* ierr)
{
- MPI_Request* reqs;
- int i;
-
- reqs = xbt_new(MPI_Request, *incount);
- for(i = 0; i < *incount; i++) {
+ std::vector<MPI_Request> reqs(*incount);
+ for (int i = 0; i < *incount; i++) {
reqs[i] = simgrid::smpi::Request::f2c(requests[i]);
}
- *ierr = MPI_Waitsome(*incount, reqs, outcount, indices, status);
- for(i=0;i<*outcount;i++){
+ *ierr = MPI_Waitsome(*incount, reqs.data(), outcount, indices, status);
+ for (int i = 0; i < *outcount; i++) {
if(reqs[indices[i]]==MPI_REQUEST_NULL){
simgrid::smpi::Request::free_f(requests[indices[i]]);
requests[indices[i]]=MPI_FORTRAN_REQUEST_NULL;
}
indices[i]++;
}
- xbt_free(reqs);
}
void mpi_test_ (int * request, int *flag, MPI_Status * status, int* ierr){
}
}
-void mpi_testall_ (int* count, int * requests, int *flag, MPI_Status * statuses, int* ierr){
- int i;
- MPI_Request* reqs = xbt_new(MPI_Request, *count);
- for(i = 0; i < *count; i++) {
+void mpi_testall_(int* count, int* requests, int* flag, MPI_Status* statuses, int* ierr)
+{
+ std::vector<MPI_Request> reqs(*count);
+ for (int i = 0; i < *count; i++) {
reqs[i] = simgrid::smpi::Request::f2c(requests[i]);
}
- *ierr= MPI_Testall(*count, reqs, flag, FORT_STATUSES_IGNORE(statuses));
- for(i = 0; i < *count; i++) {
+ *ierr = MPI_Testall(*count, reqs.data(), flag, FORT_STATUSES_IGNORE(statuses));
+ for (int i = 0; i < *count; i++) {
if(reqs[i]==MPI_REQUEST_NULL){
simgrid::smpi::Request::free_f(requests[i]);
requests[i]=MPI_FORTRAN_REQUEST_NULL;
}
}
- xbt_free(reqs);
}
void mpi_testany_ (int* count, int* requests, int *index, int *flag, MPI_Status* status, int* ierr)
{
- MPI_Request* reqs;
-
- reqs = xbt_new(MPI_Request, *count);
+ std::vector<MPI_Request> reqs(*count);
for (int i = 0; i < *count; i++) {
reqs[i] = simgrid::smpi::Request::f2c(requests[i]);
}
- *ierr = MPI_Testany(*count, reqs, index, flag, FORT_STATUS_IGNORE(status));
+ *ierr = MPI_Testany(*count, reqs.data(), index, flag, FORT_STATUS_IGNORE(status));
if(*index!=MPI_UNDEFINED){
if(reqs[*index]==MPI_REQUEST_NULL){
simgrid::smpi::Request::free_f(requests[*index]);
}
*index=*index+1;
}
- xbt_free(reqs);
}
-void mpi_testsome_ (int* incount, int* requests, int* outcount, int* indices, MPI_Status* statuses, int* ierr) {
- MPI_Request* reqs;
- int i;
-
- reqs = xbt_new(MPI_Request, *incount);
- for(i = 0; i < *incount; i++) {
+void mpi_testsome_(int* incount, int* requests, int* outcount, int* indices, MPI_Status* statuses, int* ierr)
+{
+ std::vector<MPI_Request> reqs(*incount);
+ for (int i = 0; i < *incount; i++) {
reqs[i] = simgrid::smpi::Request::f2c(requests[i]);
indices[i]=0;
}
- *ierr = MPI_Testsome(*incount, reqs, outcount, indices, FORT_STATUSES_IGNORE(statuses));
- for(i=0;i<*incount;i++){
+ *ierr = MPI_Testsome(*incount, reqs.data(), outcount, indices, FORT_STATUSES_IGNORE(statuses));
+ for (int i = 0; i < *incount; i++) {
if(reqs[indices[i]]==MPI_REQUEST_NULL){
simgrid::smpi::Request::free_f(requests[indices[i]]);
requests[indices[i]]=MPI_FORTRAN_REQUEST_NULL;
}
indices[i]++;
}
- xbt_free(reqs);
}
void mpi_probe_ (int* source, int* tag, int* comm, MPI_Status* status, int* ierr) {
#include "smpi_comm.hpp"
#include "smpi_datatype.hpp"
+#include <string>
+
extern "C" { // This should really use the C linkage to be usable from Fortran
void mpi_type_extent_(int* datatype, MPI_Aint * extent, int* ierr){
}
}
-void mpi_type_set_name_ (int* datatype, char * name, int* ierr, int size){
- char* tname = xbt_new(char, size+1);
- strncpy(tname, name, size);
- tname[size]='\0';
- *ierr = MPI_Type_set_name(simgrid::smpi::Datatype::f2c(*datatype), tname);
- xbt_free(tname);
+void mpi_type_set_name_(int* datatype, char* name, int* ierr, int size)
+{
+ std::string tname(name, size);
+ *ierr = MPI_Type_set_name(simgrid::smpi::Datatype::f2c(*datatype), tname.c_str());
}
void mpi_type_get_name_ (int* datatype, char * name, int* len, int* ierr){
void mpi_type_hindexed_ (int* count, int* blocklens, int* indices, int* old_type, int* newtype, int* ierr) {
MPI_Datatype tmp;
- auto* indices_aint = new MPI_Aint[*count];
+ std::vector<MPI_Aint> indices_aint(*count);
for(int i=0; i<*count; i++)
indices_aint[i]=indices[i];
- *ierr = MPI_Type_hindexed(*count, blocklens, indices_aint, simgrid::smpi::Datatype::f2c(*old_type), &tmp);
+ *ierr = MPI_Type_hindexed(*count, blocklens, indices_aint.data(), simgrid::smpi::Datatype::f2c(*old_type), &tmp);
if(*ierr == MPI_SUCCESS) {
*newtype = tmp->add_f();
}
- delete[] indices_aint;
}
void mpi_type_create_hindexed_(int* count, int* blocklens, MPI_Aint* indices, int* old_type, int* newtype, int* ierr){
void mpi_type_struct_ (int* count, int* blocklens, int* indices, int* old_types, int* newtype, int* ierr) {
MPI_Datatype tmp;
- auto* types = static_cast<MPI_Datatype*>(xbt_malloc(*count * sizeof(MPI_Datatype)));
- auto* indices_aint = new MPI_Aint[*count];
+ std::vector<MPI_Aint> indices_aint(*count);
+ std::vector<MPI_Datatype> types(*count);
for (int i = 0; i < *count; i++) {
indices_aint[i]=indices[i];
types[i] = simgrid::smpi::Datatype::f2c(old_types[i]);
}
- *ierr = MPI_Type_struct(*count, blocklens, indices_aint, types, &tmp);
+ *ierr = MPI_Type_struct(*count, blocklens, indices_aint.data(), types.data(), &tmp);
if(*ierr == MPI_SUCCESS) {
*newtype = tmp->add_f();
}
- xbt_free(types);
- delete[] indices_aint;
}
void mpi_type_create_struct_(int* count, int* blocklens, MPI_Aint* indices, int* old_types, int* newtype, int* ierr){
MPI_Datatype tmp;
- auto* types = static_cast<MPI_Datatype*>(xbt_malloc(*count * sizeof(MPI_Datatype)));
+ std::vector<MPI_Datatype> types(*count);
for (int i = 0; i < *count; i++) {
types[i] = simgrid::smpi::Datatype::f2c(old_types[i]);
}
- *ierr = MPI_Type_create_struct(*count, blocklens, indices, types, &tmp);
+ *ierr = MPI_Type_create_struct(*count, blocklens, indices, types.data(), &tmp);
if(*ierr == MPI_SUCCESS) {
*newtype = tmp->add_f();
}
- xbt_free(types);
}
void mpi_pack_ (void* inbuf, int* incount, int* type, void* outbuf, int* outcount, int* position, int* comm, int* ierr) {
int PMPI_Get_processor_name(char *name, int *resultlen)
{
- strncpy(name, sg_host_self()->get_cname(),
- strlen(sg_host_self()->get_cname()) < MPI_MAX_PROCESSOR_NAME - 1 ? strlen(sg_host_self()->get_cname()) + 1
- : MPI_MAX_PROCESSOR_NAME - 1);
- *resultlen = strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
+ int len = std::min<int>(sg_host_self()->get_name().size(), MPI_MAX_PROCESSOR_NAME - 1);
+ std::string(sg_host_self()->get_name()).copy(name, len);
+ name[len] = '\0';
+ *resultlen = len;
return MPI_SUCCESS;
}
int PMPI_Alloc_mem(MPI_Aint size, MPI_Info /*info*/, void* baseptr)
{
void *ptr = xbt_malloc(size);
- if(ptr==nullptr)
- return MPI_ERR_NO_MEM;
- else {
- *static_cast<void**>(baseptr) = ptr;
- return MPI_SUCCESS;
- }
+ *static_cast<void**>(baseptr) = ptr;
+ return MPI_SUCCESS;
}
int PMPI_Free_mem(void *baseptr){
int PMPI_Error_string(int errorcode, char* string, int* resultlen)
{
- static const char* smpi_error_string[] = {FOREACH_ERROR(GENERATE_STRING)};
- constexpr int nerrors = (sizeof smpi_error_string) / (sizeof smpi_error_string[0]);
- if (errorcode < 0 || errorcode >= nerrors || string == nullptr)
+ static const std::vector<const char*> smpi_error_string = {FOREACH_ERROR(GENERATE_STRING)};
+ if (errorcode < 0 || static_cast<size_t>(errorcode) >= smpi_error_string.size() || string == nullptr)
return MPI_ERR_ARG;
int len = snprintf(string, MPI_MAX_ERROR_STRING, "%s", smpi_error_string[errorcode]);
#include "smpi_op.hpp"
#include "src/smpi/include/smpi_actor.hpp"
-#include <memory>
+#include <vector>
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(smpi_pmpi);
- static const void* smpi_get_in_place_buf(const void* inplacebuf, const void* otherbuf,std::unique_ptr<unsigned char[]>& tmp_sendbuf, int count, MPI_Datatype datatype){
+static const void* smpi_get_in_place_buf(const void* inplacebuf, const void* otherbuf,
+ std::vector<unsigned char>& tmp_sendbuf, int count, MPI_Datatype datatype)
+{
if (inplacebuf == MPI_IN_PLACE) {
- tmp_sendbuf = std::make_unique<unsigned char[]>(count * datatype->get_extent());
- simgrid::smpi::Datatype::copy(otherbuf, count, datatype, tmp_sendbuf.get(), count, datatype);
- return tmp_sendbuf.get();
+ tmp_sendbuf.resize(count * datatype->get_extent());
+ simgrid::smpi::Datatype::copy(otherbuf, count, datatype, tmp_sendbuf.data(), count, datatype);
+ return tmp_sendbuf.data();
}else{
return inplacebuf;
}
CHECK_OP(5)
smpi_bench_end();
- std::unique_ptr<unsigned char[]> tmp_sendbuf;
+ std::vector<unsigned char> tmp_sendbuf;
const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype);
int rank = simgrid::s4u::this_actor::get_pid();
smpi_bench_end();
int rank = simgrid::s4u::this_actor::get_pid();
- std::unique_ptr<unsigned char[]> tmp_sendbuf;
+ std::vector<unsigned char> tmp_sendbuf;
const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype);
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Scan" : "PMPI_Iscan",
smpi_bench_end();
int rank = simgrid::s4u::this_actor::get_pid();
- std::unique_ptr<unsigned char[]> tmp_sendbuf;
+ std::vector<unsigned char> tmp_sendbuf;
const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, count, datatype);
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Exscan" : "PMPI_Iexscan",
trace_recvcounts->push_back(recvcounts[i] * dt_send_size);
totalcount += recvcounts[i];
}
- std::unique_ptr<unsigned char[]> tmp_sendbuf;
+ std::vector<unsigned char> tmp_sendbuf;
const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, totalcount, datatype);
TRACE_smpi_comm_in(rank, request == MPI_REQUEST_IGNORED ? "PMPI_Reduce_scatter" : "PMPI_Ireduce_scatter",
int rank = simgrid::s4u::this_actor::get_pid();
int dt_send_size = datatype->is_replayable() ? 1 : datatype->size();
auto* trace_recvcounts = new std::vector<int>(recvcount * dt_send_size); // copy data to avoid bad free
- std::unique_ptr<unsigned char[]> tmp_sendbuf;
+ std::vector<unsigned char> tmp_sendbuf;
const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, recvcount * count, datatype);
TRACE_smpi_comm_in(
new simgrid::instr::VarCollTIData(request == MPI_REQUEST_IGNORED ? "reducescatter" : "ireducescatter", -1, 0,
nullptr, -1, trace_recvcounts, simgrid::smpi::Datatype::encode(datatype), ""));
- auto* recvcounts = new int[count];
+ std::vector<int> recvcounts(count);
for (int i = 0; i < count; i++)
recvcounts[i] = recvcount;
if (request == MPI_REQUEST_IGNORED)
- simgrid::smpi::colls::reduce_scatter(real_sendbuf, recvbuf, recvcounts, datatype, op, comm);
+ simgrid::smpi::colls::reduce_scatter(real_sendbuf, recvbuf, recvcounts.data(), datatype, op, comm);
else
- simgrid::smpi::colls::ireduce_scatter(real_sendbuf, recvbuf, recvcounts, datatype, op, comm, request);
- delete[] recvcounts;
+ simgrid::smpi::colls::ireduce_scatter(real_sendbuf, recvbuf, recvcounts.data(), datatype, op, comm, request);
TRACE_smpi_comm_out(rank);
smpi_bench_begin();
int rank = simgrid::s4u::this_actor::get_pid();
int real_sendcount = sendcount;
MPI_Datatype real_sendtype = sendtype;
-
- std::unique_ptr<unsigned char[]> tmp_sendbuf;
+
+ std::vector<unsigned char> tmp_sendbuf;
const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, recvcount * comm->size(), recvtype);
if (sendbuf == MPI_IN_PLACE) {
maxsize = (recvdispls[i] + recvcounts[i]) * dt_size_recv;
}
- std::unique_ptr<unsigned char[]> tmp_sendbuf;
- std::unique_ptr<int[]> tmp_sendcounts;
- std::unique_ptr<int[]> tmp_senddispls;
+ std::vector<unsigned char> tmp_sendbuf;
+ std::vector<int> tmp_sendcounts;
+ std::vector<int> tmp_senddispls;
const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, maxsize, MPI_CHAR);
if (sendbuf == MPI_IN_PLACE) {
- tmp_sendcounts = std::make_unique<int[]>(size);
- std::copy(recvcounts, recvcounts + size, tmp_sendcounts.get());
- real_sendcounts = tmp_sendcounts.get();
- tmp_senddispls = std::make_unique<int[]>(size);
- std::copy(recvdispls, recvdispls + size, tmp_senddispls.get());
- real_senddispls = tmp_senddispls.get();
+ tmp_sendcounts.assign(recvcounts, recvcounts + size);
+ real_sendcounts = tmp_sendcounts.data();
+ tmp_senddispls.assign(recvdispls, recvdispls + size);
+ real_senddispls = tmp_senddispls.data();
real_sendtype = recvtype;
}
maxsize = recvdispls[i] + (recvcounts[i] * recvtypes[i]->size());
}
- std::unique_ptr<unsigned char[]> tmp_sendbuf;
- std::unique_ptr<int[]> tmp_sendcounts;
- std::unique_ptr<int[]> tmp_senddispls;
- std::unique_ptr<MPI_Datatype[]> tmp_sendtypes;
+ std::vector<unsigned char> tmp_sendbuf;
+ std::vector<int> tmp_sendcounts;
+ std::vector<int> tmp_senddispls;
+ std::vector<MPI_Datatype> tmp_sendtypes;
const void* real_sendbuf = smpi_get_in_place_buf(sendbuf, recvbuf, tmp_sendbuf, maxsize, MPI_CHAR);
if (sendbuf == MPI_IN_PLACE) {
- tmp_sendcounts = std::make_unique<int[]>(size);
- std::copy(recvcounts, recvcounts + size, tmp_sendcounts.get());
- real_sendcounts = tmp_sendcounts.get();
- tmp_senddispls = std::make_unique<int[]>(size);
- std::copy(recvdispls, recvdispls + size, tmp_senddispls.get());
- real_senddispls = tmp_senddispls.get();
- tmp_sendtypes = std::make_unique<MPI_Datatype[]>(size);
- std::copy(recvtypes, recvtypes + size, tmp_sendtypes.get());
- real_sendtypes = tmp_sendtypes.get();
+ tmp_sendcounts.assign(recvcounts, recvcounts + size);
+ real_sendcounts = tmp_sendcounts.data();
+ tmp_senddispls.assign(recvdispls, recvdispls + size);
+ real_senddispls = tmp_senddispls.data();
+ tmp_sendtypes.assign(recvtypes, recvtypes + size);
+ real_sendtypes = tmp_sendtypes.data();
}
for (int i = 0; i < size; i++) { // copy data to avoid bad free
int size = datatype->get_extent() * count;
xbt_assert(size > 0);
- void* recvbuf = xbt_new0(char, size);
- retval = MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf, count, datatype, src, recvtag, comm, status);
+ std::vector<char> recvbuf(size);
+ retval =
+ MPI_Sendrecv(buf, count, datatype, dst, sendtag, recvbuf.data(), count, datatype, src, recvtag, comm, status);
if(retval==MPI_SUCCESS){
- simgrid::smpi::Datatype::copy(recvbuf, count, datatype, buf, count, datatype);
+ simgrid::smpi::Datatype::copy(recvbuf.data(), count, datatype, buf, count, datatype);
}
- xbt_free(recvbuf);
return retval;
}
CHECK_NEGATIVE(2, MPI_ERR_OTHER, size)
CHECK_NEGATIVE(3, MPI_ERR_OTHER, disp_unit)
void* ptr = xbt_malloc(size);
- if(ptr==nullptr)
- return MPI_ERR_NO_MEM;
smpi_bench_end();
*static_cast<void**>(base) = ptr;
*win = new simgrid::smpi::Win( ptr, size, disp_unit, info, comm,1);
int rank = comm->rank();
if(rank==0){
ptr = xbt_malloc(size*comm->size());
- if(ptr==nullptr)
- return MPI_ERR_NO_MEM;
}
smpi_bench_end();
simgrid::smpi::colls::bcast(&ptr, sizeof(void*), MPI_BYTE, 0, comm);
recvcnts[i] = node_sizes[i] * recvcnt;
}
- void* sendbuf=((char*)recvbuf)+recvtype->get_extent()*displs[leader_comm->rank()];
+ void* sendtmpbuf = ((char*)recvbuf) + recvtype->get_extent() * displs[leader_comm->rank()];
- mpi_errno = colls::allgatherv(sendbuf, (recvcnt * local_size), recvtype, recvbuf, recvcnts, displs,
- recvtype, leader_comm);
- delete[] displs;
- delete[] recvcnts;
+ mpi_errno = colls::allgatherv(sendtmpbuf, (recvcnt * local_size), recvtype, recvbuf, recvcnts, displs,
+ recvtype, leader_comm);
+ delete[] displs;
+ delete[] recvcnts;
} else {
void* sendtmpbuf=((char*)recvbuf)+recvtype->get_extent()*(recvcnt*local_size)*leader_comm->rank();
counts[0] = count/2;
if (count % 2 != 0) counts[0]++;
counts[1] = count - counts[0];
- if ( segsize > 0 ) {
- /* Note that ompi_datatype_type_size() will never return a negative
- value in typelng; it returns an int [vs. an unsigned type]
- because of the MPI spec. */
- if (segsize < ((uint32_t)type_size)) {
- segsize = type_size; /* push segsize up to hold one type */
- }
- segcount[0] = segcount[1] = segsize / type_size;
- num_segments[0] = counts[0]/segcount[0];
- if ((counts[0] % segcount[0]) != 0) num_segments[0]++;
- num_segments[1] = counts[1]/segcount[1];
- if ((counts[1] % segcount[1]) != 0) num_segments[1]++;
- } else {
- segcount[0] = counts[0];
- segcount[1] = counts[1];
- num_segments[0] = num_segments[1] = 1;
+
+ /* Note that ompi_datatype_type_size() will never return a negative
+ value in typelng; it returns an int [vs. an unsigned type]
+ because of the MPI spec. */
+ if (segsize < ((uint32_t)type_size)) {
+ segsize = type_size; /* push segsize up to hold one type */
}
+ segcount[0] = segcount[1] = segsize / type_size;
+ num_segments[0] = counts[0] / segcount[0];
+ if ((counts[0] % segcount[0]) != 0)
+ num_segments[0]++;
+ num_segments[1] = counts[1] / segcount[1];
+ if ((counts[1] % segcount[1]) != 0)
+ num_segments[1]++;
/* if the message is too small to be split into segments */
if( (counts[0] == 0 || counts[1] == 0) ||
extern XBT_PRIVATE MPI_Comm MPI_COMM_UNINITIALIZED;
-typedef SMPI_Cart_topology* MPIR_Cart_Topology;
-
-typedef SMPI_Graph_topology* MPIR_Graph_Topology;
-
-typedef SMPI_Dist_Graph_topology* MPIR_Dist_Graph_Topology;
+using MPIR_Cart_Topology = SMPI_Cart_topology*;
+using MPIR_Graph_Topology = SMPI_Graph_topology*;
+using MPIR_Dist_Graph_Topology = SMPI_Dist_Graph_topology*;
XBT_PRIVATE simgrid::smpi::ActorExt* smpi_process();
XBT_PRIVATE simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor);
void* address;
int file_descriptor;
};
-typedef s_smpi_privatization_region_t* smpi_privatization_region_t;
+using smpi_privatization_region_t = s_smpi_privatization_region_t*;
extern XBT_PRIVATE int smpi_loaded_page;
XBT_PRIVATE smpi_privatization_region_t smpi_init_global_memory_segment_process();
#define TOPAGE(addr) (void*)(((unsigned long)(addr) / xbt_pagesize) * xbt_pagesize)
/** Used only if PAPI is compiled in, but integrated anyway so that this file does not depend on internal_config.h (to speed builds) */
-typedef std::vector<std::pair</* counter name */ std::string, /* counter value */ long long>> papi_counter_t;
+using papi_counter_t = std::vector<std::pair</* counter name */ std::string, /* counter value */ long long>>;
struct papi_process_data {
papi_counter_t counter_data;
int event_set;
XBT_PRIVATE void private_execute_flops(double flops);
-
#define CHECK_ARGS(test, errcode, ...) \
if (test) { \
- if((errcode) != MPI_SUCCESS) \
+ int error_code_ = (errcode); \
+ if (error_code_ != MPI_SUCCESS) \
XBT_WARN(__VA_ARGS__); \
- return (errcode); \
+ return error_code_; \
}
#define CHECK_MPI_NULL(num, val, err, ptr) \
};
class Datatype : public F2C, public Keyval{
- char* name_ = nullptr;
+ std::string name_ = "";
/* The id here is the (unique) datatype id used for this datastructure.
* It's default value is set to -1 since some code expects this return value
* when no other id has been assigned
static int keyval_id_;
Datatype_contents* contents_ = nullptr;
- Datatype(int id, int size, MPI_Aint lb, MPI_Aint ub, int flags);
- Datatype(char* name, int id, int size, MPI_Aint lb, MPI_Aint ub, int flags);
+ Datatype(int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags);
+ Datatype(const char* name, int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags);
Datatype(int size, MPI_Aint lb, MPI_Aint ub, int flags);
- Datatype(char* name, int size, MPI_Aint lb, MPI_Aint ub, int flags);
Datatype(Datatype* datatype, int* ret);
Datatype(const Datatype&) = delete;
Datatype& operator=(const Datatype&) = delete;
~Datatype() override;
- char* name() const { return name_; }
+ const char* name() const { return name_.c_str(); }
size_t size() const { return size_; }
MPI_Aint lb() const { return lb_; }
MPI_Aint ub() const { return ub_; }
#define SMPI_F2C_HPP_INCLUDED
#include <unordered_map>
-#include <string>
-
-#define KEY_SIZE (sizeof(int) * 2 + 1)
namespace simgrid{
namespace smpi{
class F2C {
- private:
- // We use a single lookup table for every type.
- // Beware of collisions if id in mpif.h is not unique
- static std::unordered_map<std::string, F2C*>* f2c_lookup_;
- static int f2c_id_;
- int my_f2c_id_ = -1;
-
- protected:
- static std::unordered_map<std::string, F2C*>* f2c_lookup();
- static void set_f2c_lookup(std::unordered_map<std::string, F2C*>* map);
- static int f2c_id();
- static void f2c_id_increment();
-
- public:
- char* get_my_key(char* key);
- static char* get_key(char* key, int id);
- static void delete_lookup();
- static std::unordered_map<std::string, F2C*>* lookup();
- F2C();
- virtual ~F2C() = default;
-
- //Override these to handle specific values.
- virtual int add_f();
- static void free_f(int id);
- virtual int c2f();
- static void print_f2c_lookup();
- // This method should be overridden in all subclasses to avoid casting the result when calling it.
- // For the default one, the MPI_*_NULL returned is assumed to be NULL.
- static F2C* f2c(int id);
+private:
+ // We use a single lookup table for every type.
+ // Beware of collisions if id in mpif.h is not unique
+ static std::unordered_map<int, F2C*>* f2c_lookup_;
+ static int f2c_id_;
+ int my_f2c_id_ = -1;
+
+protected:
+ static void set_f2c_lookup(std::unordered_map<int, F2C*>* map) { f2c_lookup_ = map; }
+ static int f2c_id() { return f2c_id_; }
+ static void f2c_id_increment() { f2c_id_++; }
+
+public:
+ static void delete_lookup() { delete f2c_lookup_; }
+ static std::unordered_map<int, F2C*>* lookup() { return f2c_lookup_; }
+ F2C();
+ virtual ~F2C() = default;
+
+ // Override these to handle specific values.
+ virtual int add_f();
+ static void free_f(int id) { f2c_lookup_->erase(id); }
+ virtual int c2f();
+ static void print_f2c_lookup();
+ // This method should be overridden in all subclasses to avoid casting the result when calling it.
+ // For the default one, the MPI_*_NULL returned is assumed to be NULL.
+ static F2C* f2c(int id);
};
}
MPI_Offset max_offset =
min_offset +
count * datatype->get_extent(); // cheating, as we don't care about exact data location, we can skip extent
- auto* min_offsets = new MPI_Offset[size];
- auto* max_offsets = new MPI_Offset[size];
- simgrid::smpi::colls::allgather(&min_offset, 1, MPI_OFFSET, min_offsets, 1, MPI_OFFSET, comm_);
- simgrid::smpi::colls::allgather(&max_offset, 1, MPI_OFFSET, max_offsets, 1, MPI_OFFSET, comm_);
+ std::vector<MPI_Offset> min_offsets(size);
+ std::vector<MPI_Offset> max_offsets(size);
+ simgrid::smpi::colls::allgather(&min_offset, 1, MPI_OFFSET, min_offsets.data(), 1, MPI_OFFSET, comm_);
+ simgrid::smpi::colls::allgather(&max_offset, 1, MPI_OFFSET, max_offsets.data(), 1, MPI_OFFSET, comm_);
MPI_Offset min = min_offset;
MPI_Offset max = max_offset;
MPI_Offset tot = 0;
XBT_CDEBUG(smpi_pmpi, "my offsets to read : %lld:%lld, global min and max %lld:%lld", min_offset, max_offset, min,
max);
if (empty == 1) {
- delete[] min_offsets;
- delete[] max_offsets;
- status->count = 0;
+ if (status != MPI_STATUS_IGNORE)
+ status->count = 0;
return MPI_SUCCESS;
}
MPI_Offset total = max - min;
if (total == tot && (datatype->flags() & DT_FLAG_CONTIGUOUS)) {
- delete[] min_offsets;
- delete[] max_offsets;
// contiguous. Just have each proc perform its read
if (status != MPI_STATUS_IGNORE)
status->count = count * datatype->size();
MPI_Offset my_chunk_start = (max - min + 1) / size * rank;
MPI_Offset my_chunk_end = ((max - min + 1) / size * (rank + 1));
XBT_CDEBUG(smpi_pmpi, "my chunks to read : %lld:%lld", my_chunk_start, my_chunk_end);
- auto* send_sizes = new int[size];
- auto* recv_sizes = new int[size];
- auto* send_disps = new int[size];
- auto* recv_disps = new int[size];
+ std::vector<int> send_sizes(size);
+ std::vector<int> recv_sizes(size);
+ std::vector<int> send_disps(size);
+ std::vector<int> recv_disps(size);
int total_sent = 0;
for (int i = 0; i < size; i++) {
send_sizes[i] = 0;
seek(min_offset, MPI_SEEK_SET);
T(this, sendbuf, totreads / datatype->size(), datatype, status);
}
- simgrid::smpi::colls::alltoall(send_sizes, 1, MPI_INT, recv_sizes, 1, MPI_INT, comm_);
+ simgrid::smpi::colls::alltoall(send_sizes.data(), 1, MPI_INT, recv_sizes.data(), 1, MPI_INT, comm_);
int total_recv = 0;
for (int i = 0; i < size; i++) {
recv_disps[i] = total_recv;
total_recv += recv_sizes[i];
}
// Set buf value to avoid copying dumb data
- simgrid::smpi::colls::alltoallv(sendbuf, send_sizes, send_disps, MPI_BYTE, buf, recv_sizes, recv_disps, MPI_BYTE,
- comm_);
+ simgrid::smpi::colls::alltoallv(sendbuf, send_sizes.data(), send_disps.data(), MPI_BYTE, buf, recv_sizes.data(),
+ recv_disps.data(), MPI_BYTE, comm_);
if (status != MPI_STATUS_IGNORE)
status->count = count * datatype->size();
smpi_free_tmp_buffer(sendbuf);
- delete[] send_sizes;
- delete[] recv_sizes;
- delete[] send_disps;
- delete[] recv_disps;
- delete[] min_offsets;
- delete[] max_offsets;
return MPI_SUCCESS;
}
}
int refcount;
};
-typedef s_smpi_key_elem_t* smpi_key_elem;
+using smpi_key_elem = s_smpi_key_elem_t*;
namespace simgrid{
namespace smpi{
#include "smpi/smpi.h"
#include "smpi_f2c.hpp"
+#include <memory>
+
namespace simgrid{
namespace smpi{
-typedef struct s_smpi_mpi_generalized_request_funcs {
+struct smpi_mpi_generalized_request_funcs_t {
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_;
int refcount_;
MPI_Op op_;
int cancelled_; // tri-state
- smpi_mpi_generalized_request_funcs generalized_funcs;
+ std::unique_ptr<smpi_mpi_generalized_request_funcs_t> generalized_funcs;
MPI_Request* nbc_requests_;
int nbc_requests_size_;
static bool match_common(MPI_Request req, MPI_Request sender, MPI_Request receiver);
#include "smpi_status.hpp"
#include <memory>
-typedef std::shared_ptr<SMPI_Topology> MPI_Topology;
+using MPI_Topology = std::shared_ptr<SMPI_Topology>;
namespace simgrid{
namespace smpi{
int assert_ = 0;
MPI_Info info_;
MPI_Comm comm_;
- std::vector<MPI_Request> *requests_;
- s4u::MutexPtr mut_;
- s4u::Barrier* bar_;
- MPI_Win* connected_wins_;
- char* name_;
- int opened_;
- MPI_Group group_;
- int count_; //for ordering the accs
- s4u::MutexPtr lock_mut_;
- s4u::MutexPtr atomic_mut_;
+ std::vector<MPI_Request> requests_;
+ s4u::MutexPtr mut_ = s4u::Mutex::create();
+ s4u::Barrier* bar_ = nullptr;
+ std::vector<MPI_Win> connected_wins_;
+ std::string name_;
+ int opened_ = 0;
+ MPI_Group group_ = MPI_GROUP_NULL;
+ int count_ = 0; // for ordering the accs
+ s4u::MutexPtr lock_mut_ = s4u::Mutex::create();
+ s4u::MutexPtr atomic_mut_ = s4u::Mutex::create();
std::list<int> lockers_;
int rank_; // to identify owner for barriers in MPI_COMM_WORLD
- int mode_; // exclusive or shared lock
+ int mode_ = 0; // exclusive or shared lock
int allocated_;
int dynamic_;
- MPI_Errhandler errhandler_;
+ MPI_Errhandler errhandler_ = MPI_ERRORS_ARE_FATAL;
public:
static std::unordered_map<int, smpi_key_elem> keyvals_;
XBT_DEBUG("Recv tracing from %d to %d, tag %d, with key %s", src, dst, tag, key.c_str());
simgrid::instr::Container::get_root()->get_link("MPI_LINK")->end_event(smpi_container(dst), "PTP", key);
}
-
-/**************** Functions to trace the migration of tasks. *****************/
-void TRACE_smpi_process_change_host(int rank, const_sg_host_t new_host)
-{
- if (not TRACE_smpi_is_enabled()) return;
-
- /** The key is (most likely) used to match the events in the trace */
- static long long int counter = 0;
- std::string key = std::to_string(counter);
- counter++;
-
- // start link (= tell the trace that this rank moves from A to B)
- auto* cont = smpi_container(rank);
- simgrid::instr::Container::get_root()->get_link("MIGRATE_LINK")->start_event(cont, "M", key);
-
- // Destroy container of this rank on this host
- cont->remove_from_parent();
-
- // Setup container on new host
- TRACE_smpi_setup_container(rank, new_host);
-
- // end link
- cont = smpi_container(rank); // This points to the newly created container
- simgrid::instr::Container::get_root()->get_link("MIGRATE_LINK")->end_event(cont, "M", key);
-}
#ifndef WIN32
#include <sys/mman.h>
#endif
+#include <cerrno>
#include <cmath>
#if HAVE_PAPI
void smpi_execute_benched(double duration)
{
smpi_bench_end();
- double speed = sg_host_speed(sg_host_self());
+ double speed = sg_host_get_speed(sg_host_self());
smpi_execute_flops(duration*speed);
smpi_bench_begin();
}
#if _POSIX_TIMERS > 0
int smpi_clock_gettime(clockid_t clk_id, struct timespec* tp)
{
+ if (not tp) {
+ errno = EFAULT;
+ return -1;
+ }
if (not smpi_process())
return clock_gettime(clk_id, tp);
//there is only one time in SMPI, so clk_id is ignored.
smpi_bench_end();
double now = SIMIX_get_clock();
- if (tp) {
- tp->tv_sec = static_cast<time_t>(now);
- tp->tv_nsec = static_cast<long int>((now - tp->tv_sec) * 1e9);
- }
+ tp->tv_sec = static_cast<time_t>(now);
+ tp->tv_nsec = static_cast<long int>((now - tp->tv_sec) * 1e9);
if (smpi_wtime_sleep > 0)
simgrid::s4u::this_actor::sleep_for(smpi_wtime_sleep);
smpi_bench_begin();
std::ifstream fstream(filename);
xbt_assert(fstream.is_open(), "Could not open file %s. Does it exist?", filename.c_str());
std::string line;
- typedef boost::tokenizer<boost::escaped_list_separator<char>> Tokenizer;
+ using Tokenizer = boost::tokenizer<boost::escaped_list_separator<char>>;
std::getline(fstream, line); // Skip the header line
while (std::getline(fstream, line)) {
Tokenizer tok(line);
return;
simgrid::config::declare_flag<bool>("smpi/display-timing", "Whether we should display the timing after simulation.", false);
simgrid::config::declare_flag<bool>("smpi/keep-temps", "Whether we should keep the generated temporary files.", false);
+ simgrid::config::declare_flag<std::string>("smpi/tmpdir", "tmp dir for dlopen files", "/tmp");
simgrid::config::declare_flag<std::string>("smpi/coll-selector", "Which collective selector to use", "default");
simgrid::config::declare_flag<std::string>("smpi/gather", "Which collective to use for gather", "");
"smpi/ois", "Small messages timings (MPI_Isend minimum time for small messages)", "0:0:0:0:0");
simgrid::config::declare_flag<std::string>(
"smpi/or", "Small messages timings (MPI_Recv minimum time for small messages)", "0:0:0:0:0");
- simgrid::config::alias("smpi/display-timing", {"smpi/display_timing"});
- simgrid::config::alias("smpi/coll-selector", {"smpi/coll_selector"});
- simgrid::config::alias("smpi/simulate-computation", {"smpi/simulate_computation"});
- simgrid::config::alias("smpi/shared-malloc", {"smpi/use_shared_malloc", "smpi/use-shared-malloc"});
- simgrid::config::alias("smpi/host-speed", {"smpi/running_power", "smpi/running-power"});
- simgrid::config::alias("smpi/cpu-threshold", {"smpi/cpu_threshold"});
- simgrid::config::alias("smpi/async-small-thresh", {"smpi/async_small_thres", "smpi/async_small_thresh"});
- simgrid::config::alias("smpi/send-is-detached-thresh", {"smpi/send_is_detached_thres", "smpi/send_is_detached_thresh"});
- simgrid::config::alias("smpi/privatization", {"smpi/privatize_global_variables", "smpi/privatize-global-variables"});
- simgrid::config::alias("smpi/reduce_scatter", {"smpi/reduce-scatter"});
_smpi_options_initialized=true;
}
#include "src/simix/smx_private.hpp"
#include "src/smpi/include/smpi_actor.hpp"
#include "xbt/config.hpp"
+#include "xbt/file.hpp"
#include <algorithm>
+#include <array>
#include <boost/algorithm/string.hpp> /* split */
#include <boost/tokenizer.hpp>
#include <cinttypes>
XBT_ERROR("Could not initialize PAPI library; is it correctly installed and linked?"
" Expected version is %u", PAPI_VER_CURRENT);
- typedef boost::tokenizer<boost::char_separator<char>> Tokenizer;
+ using Tokenizer = boost::tokenizer<boost::char_separator<char>>;
boost::char_separator<char> separator_units(";");
std::string str = smpi_cfg_papi_events_file();
Tokenizer tokens(str, separator_units);
#endif
}
-
-
-typedef std::function<int(int argc, char *argv[])> smpi_entry_point_type;
-typedef int (* smpi_c_entry_point_type)(int argc, char **argv);
-typedef void (*smpi_fortran_entry_point_type)();
+using smpi_entry_point_type = std::function<int(int argc, char* argv[])>;
+using smpi_c_entry_point_type = int (*)(int argc, char** argv);
+using smpi_fortran_entry_point_type = void (*)();
template <typename F>
static int smpi_run_entry_point(const F& entry_point, const std::string& executable_path, std::vector<std::string> args)
}
#endif
// If this point is reached, sendfile() actually is not available. Copy file by hand.
- const int bufsize = 1024 * 1024 * 4;
- auto* buf = new char[bufsize];
- while (int got = read(fdin, buf, bufsize)) {
+ std::vector<unsigned char> buf(1024 * 1024 * 4);
+ while (ssize_t got = read(fdin, buf.data(), buf.size())) {
if (got == -1) {
xbt_assert(errno == EINTR, "Cannot read from %s", src.c_str());
} else {
- const char* p = buf;
- int todo = got;
- while (int done = write(fdout, p, todo)) {
+ const unsigned char* p = buf.data();
+ ssize_t todo = got;
+ while (ssize_t done = write(fdout, p, todo)) {
if (done == -1) {
xbt_assert(errno == EINTR, "Cannot write into %s", target.c_str());
} else {
}
}
}
- delete[] buf;
close(fdin);
close(fdout);
}
#if not defined(__APPLE__) && not defined(__HAIKU__)
static int visit_libs(struct dl_phdr_info* info, size_t, void* data)
{
- auto* libname = static_cast<char*>(data);
- const char *path = info->dlpi_name;
- if(strstr(path, libname)){
- strncpy(libname, path, 512);
+ auto* libname = static_cast<std::string*>(data);
+ std::string path = info->dlpi_name;
+ if (path.find(*libname) != std::string::npos) {
+ *libname = std::move(path);
return 1;
}
-
return 0;
}
#endif
for (auto const& libname : privatize_libs) {
// load the library once to add it to the local libs, to get the absolute path
void* libhandle = dlopen(libname.c_str(), RTLD_LAZY);
+ xbt_assert(libhandle != nullptr,
+ "Cannot dlopen %s - check your settings in smpi/privatize-libs", libname.c_str());
// get library name from path
- char fullpath[512] = {'\0'};
- strncpy(fullpath, libname.c_str(), 511);
+ std::string fullpath = libname;
#if not defined(__APPLE__) && not defined(__HAIKU__)
- xbt_assert(0 != dl_iterate_phdr(visit_libs, fullpath),
- "Can't find a linked %s - check your settings in smpi/privatize-libs", fullpath);
- XBT_DEBUG("Extra lib to privatize '%s' found", fullpath);
+ XBT_ATTRIB_UNUSED int dl_iterate_res = dl_iterate_phdr(visit_libs, &fullpath);
+ xbt_assert(dl_iterate_res != 0, "Can't find a linked %s - check your settings in smpi/privatize-libs",
+ fullpath.c_str());
+ XBT_DEBUG("Extra lib to privatize '%s' found", fullpath.c_str());
#else
xbt_die("smpi/privatize-libs is not (yet) compatible with OSX nor with Haiku");
#endif
- privatize_libs_paths.emplace_back(fullpath);
+ privatize_libs_paths.emplace_back(std::move(fullpath));
dlclose(libhandle);
}
}
return std::function<void()>([executable, fdin_size, args] {
static std::size_t rank = 0;
// Copy the dynamic library:
- std::string target_executable =
- executable + "_" + std::to_string(getpid()) + "_" + std::to_string(rank) + ".so";
+ simgrid::xbt::Path path(executable);
+ std::string target_executable = simgrid::config::get_value<std::string>("smpi/tmpdir") + "/" +
+ path.get_base_name() + "_" + std::to_string(getpid()) + "_" + std::to_string(rank) + ".so";
smpi_copy_file(executable, target_executable, fdin_size);
// if smpi/privatize-libs is set, duplicate pointed lib and link each executable copy to a different one.
unsigned int pad = 7;
if (libname.length() < pad)
pad = libname.length();
- std::string target_lib =
- std::string(pad - std::to_string(rank).length(), '0') + std::to_string(rank) + libname.substr(pad);
+ std::string target_libname = std::string(pad - std::to_string(rank).length(), '0') + std::to_string(rank) + libname.substr(pad);
+ std::string target_lib = simgrid::config::get_value<std::string>("smpi/tmpdir") + "/" + target_libname;
target_libs.push_back(target_lib);
XBT_DEBUG("copy lib %s to %s, with size %lld", libpath.c_str(), target_lib.c_str(), (long long)fdin_size2);
smpi_copy_file(libpath, target_lib, fdin_size2);
- std::string sedcommand = "sed -i -e 's/" + libname + "/" + target_lib + "/g' " + target_executable;
+ std::string sedcommand = "sed -i -e 's/" + libname + "/" + target_libname + "/g' " + target_executable;
int status = system(sedcommand.c_str());
xbt_assert(status == 0, "error while applying sed command %s \n", sedcommand.c_str());
}
/* Here we are making the assumption that a suitable empty region
following the rw- area is the end of the data segment. It would
be better to check with the size of the data segment. */
- ++i;
- if (i != map.end() && i->pathname.empty() && (i->prot & PROT_RWX) == PROT_RW &&
- (char*)i->start_addr == smpi_data_exe_start + smpi_data_exe_size) {
+ auto j = i + 1;
+ if (j != map.end() && j->pathname.empty() && (j->prot & PROT_RWX) == PROT_RW &&
+ (char*)j->start_addr == smpi_data_exe_start + smpi_data_exe_size) {
// Only count the portion of this region not present in the initial map.
- auto found = std::find_if(initial_vm_map.begin(), initial_vm_map.end(), [&i](const simgrid::xbt::VmMap& m) {
- return i->start_addr <= m.start_addr && m.start_addr < i->end_addr;
+ auto found = std::find_if(initial_vm_map.begin(), initial_vm_map.end(), [&j](const simgrid::xbt::VmMap& m) {
+ return j->start_addr <= m.start_addr && m.start_addr < j->end_addr;
});
- auto end_addr = (found == initial_vm_map.end() ? i->end_addr : found->start_addr);
+ auto end_addr = (found == initial_vm_map.end() ? j->end_addr : found->start_addr);
smpi_data_exe_size = (char*)end_addr - smpi_data_exe_start;
}
return;
};
}
-typedef std::tuple</*sender*/ int, /* receiver */ int, /* tag */ int> req_key_t;
-typedef std::unordered_map<req_key_t, MPI_Request, hash_tuple::hash<std::tuple<int,int,int>>> req_storage_t;
+using req_key_t = std::tuple</*sender*/ int, /* receiver */ int, /* tag */ int>;
+using req_storage_t = std::unordered_map<req_key_t, MPI_Request, hash_tuple::hash<std::tuple<int, int, int>>>;
void log_timed_action(const simgrid::xbt::ReplayAction& action, double clock)
{
unsigned int count_requests = storage[simgrid::s4u::this_actor::get_pid()].size();
XBT_DEBUG("There are %ud elements in reqq[*]", count_requests);
if (count_requests > 0) {
- auto* requests = new MPI_Request[count_requests];
+ std::vector<MPI_Request> requests(count_requests);
unsigned int i=0;
for (auto const& pair : storage[simgrid::s4u::this_actor::get_pid()].get_store()) {
requests[i] = pair.second;
i++;
}
- simgrid::smpi::Request::waitall(count_requests, requests, MPI_STATUSES_IGNORE);
- delete[] requests;
+ simgrid::smpi::Request::waitall(count_requests, requests.data(), MPI_STATUSES_IGNORE);
}
active_processes--;
* \ | |
* ----
*/
-#include <map>
+#include <array>
#include <cstring>
+#include <map>
#include "private.hpp"
#include "xbt/config.hpp"
#ifndef WIN32
#include <sys/mman.h>
#endif
-#include <cstdio>
-#include <fcntl.h>
-#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
};
std::unordered_map<smpi_source_location, shared_data_t, std::hash<std::string>> allocs;
-typedef decltype(allocs)::value_type shared_data_key_type;
+using shared_data_key_type = decltype(allocs)::value_type;
struct shared_metadata_t {
size_t size;
std::map<std::string, void*> calls;
#ifndef WIN32
-static int smpi_shared_malloc_bogusfile = -1;
-static int smpi_shared_malloc_bogusfile_huge_page = -1;
-static unsigned long smpi_shared_malloc_blocksize = 1UL << 20;
+int smpi_shared_malloc_bogusfile = -1;
+int smpi_shared_malloc_bogusfile_huge_page = -1;
+unsigned long smpi_shared_malloc_blocksize = 1UL << 20;
#endif
}
* The others are not.
*/
-void* smpi_shared_malloc_partial(size_t size, size_t* shared_block_offsets, int nb_shared_blocks)
+void* smpi_shared_malloc_partial(size_t size, const size_t* shared_block_offsets, int nb_shared_blocks)
{
std::string huge_page_mount_point = simgrid::config::get_value<std::string>("smpi/shared-malloc-hugepage");
bool use_huge_page = not huge_page_mount_point.empty();
smpi_shared_malloc_bogusfile = mkstemp(name);
XBT_DEBUG("bogusfile : %s\n", name);
unlink(name);
- const char* dumb = new char[smpi_shared_malloc_blocksize](); // zero initialized
- ssize_t err = write(smpi_shared_malloc_bogusfile, dumb, smpi_shared_malloc_blocksize);
- if(err<0)
+ int err = ftruncate(smpi_shared_malloc_bogusfile, smpi_shared_malloc_blocksize);
+ if (err != 0)
xbt_die("Could not write bogus file for shared malloc");
- delete[] dumb;
}
int mmap_base_flag = MAP_FIXED | MAP_SHARED | MAP_POPULATE;
return smpi_shared_malloc_local(size, file, line);
} else if (smpi_cfg_shared_malloc() == SharedMallocType::GLOBAL) {
int nb_shared_blocks = 1;
- size_t shared_block_offsets[2] = {0, size};
- return smpi_shared_malloc_partial(size, shared_block_offsets, nb_shared_blocks);
+ const std::array<size_t, 2> shared_block_offsets = {{0, size}};
+ return smpi_shared_malloc_partial(size, shared_block_offsets.data(), nb_shared_blocks);
}
XBT_DEBUG("Classic allocation of %zu bytes", size);
return ::operator new(size);
std::vector<s_smpi_factor_t> smpi_factor;
/** Setup the tokenizer that parses the string **/
- typedef boost::tokenizer<boost::char_separator<char>> Tokenizer;
+ using Tokenizer = boost::tokenizer<boost::char_separator<char>>;
boost::char_separator<char> sep(";");
boost::char_separator<char> factor_separator(":");
Tokenizer tokens(smpi_coef_string, sep);
if (this == MPI_COMM_UNINITIALIZED)
return smpi_process()->comm_world()->split(color, key);
int system_tag = -123;
- int* recvbuf;
MPI_Group group_root = nullptr;
MPI_Group group_out = nullptr;
int myrank = this->rank();
int size = this->size();
/* Gather all colors and keys on rank 0 */
- int* sendbuf = xbt_new(int, 2);
- sendbuf[0] = color;
- sendbuf[1] = key;
- if (myrank == 0) {
- recvbuf = xbt_new(int, 2 * size);
- } else {
- recvbuf = nullptr;
- }
- gather__default(sendbuf, 2, MPI_INT, recvbuf, 2, MPI_INT, 0, this);
- xbt_free(sendbuf);
+ const std::array<int, 2> sendbuf = {{color, key}};
+ std::vector<int> recvbuf;
+ if (myrank == 0)
+ recvbuf.resize(2 * size);
+ gather__default(sendbuf.data(), 2, MPI_INT, recvbuf.data(), 2, MPI_INT, 0, this);
/* Do the actual job */
if (myrank == 0) {
- MPI_Group* group_snd = xbt_new(MPI_Group, size);
+ std::vector<MPI_Group> group_snd(size);
std::vector<std::pair<int, int>> rankmap;
rankmap.reserve(size);
for (int i = 0; i < size; i++) {
s4u::Actor* actor = group->actor(rankmap[j].second);
group_out->set_mapping(actor, j);
}
- MPI_Request* requests = xbt_new(MPI_Request, rankmap.size());
+ std::vector<MPI_Request> requests(rankmap.size());
int reqs = 0;
for (auto const& rank : rankmap) {
if (rank.second != 0) {
if(i != 0 && group_out != MPI_COMM_WORLD->group() && group_out != MPI_GROUP_EMPTY)
Group::unref(group_out);
- Request::waitall(reqs, requests, MPI_STATUS_IGNORE);
- xbt_free(requests);
+ Request::waitall(reqs, requests.data(), MPI_STATUS_IGNORE);
}
}
- xbt_free(recvbuf);
- xbt_free(group_snd);
group_out = group_root; /* exit with root's group */
} else {
if(color != MPI_UNDEFINED) {
return MPI_COMM_SELF;
} else if(id==0){
return MPI_COMM_WORLD;
- } else if(F2C::f2c_lookup() != nullptr && id >= 0) {
- char key[KEY_SIZE];
- const auto& lookup = F2C::f2c_lookup();
- auto comm = lookup->find(get_key(key, id));
+ } else if (F2C::lookup() != nullptr && id >= 0) {
+ const auto& lookup = F2C::lookup();
+ auto comm = lookup->find(id);
return comm == lookup->end() ? MPI_COMM_NULL : static_cast<MPI_Comm>(comm->second);
} else {
return MPI_COMM_NULL;
}
void Comm::free_f(int id) {
- char key[KEY_SIZE];
- F2C::f2c_lookup()->erase(get_key(key, id));
+ F2C::lookup()->erase(id);
}
void Comm::add_rma_win(MPI_Win win){
#include "src/smpi/include/smpi_actor.hpp"
#include <algorithm>
+#include <array>
#include <functional>
#include <string>
}
// for predefined types, so refcount_ = 0.
-Datatype::Datatype(char* name, int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags)
+Datatype::Datatype(const char* name, int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags)
: name_(name), id(std::to_string(ident)), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(0)
{
id2type_lookup.insert({id, this});
cleanup_attr<Datatype>();
delete contents_;
- xbt_free(name_);
}
int Datatype::copy_attrs(Datatype* datatype){
if (datatype->refcount_ > 0)
datatype->refcount_--;
- if (datatype->refcount_ == 0 && not(datatype->flags_ & DT_FLAG_PREDEFINED))
- delete datatype;
-
#if SIMGRID_HAVE_MC
if(MC_is_active())
MC_ignore(&(datatype->refcount_), sizeof(datatype->refcount_));
#endif
+
+ if (datatype->refcount_ == 0 && not(datatype->flags_ & DT_FLAG_PREDEFINED))
+ delete datatype;
}
void Datatype::commit()
void Datatype::get_name(char* name, int* length) const
{
- if(name_!=nullptr){
- *length = strlen(name_);
- strncpy(name, name_, *length+1);
- }else{
- *length = 0;
+ *length = static_cast<int>(name_.length());
+ if (not name_.empty()) {
+ name_.copy(name, *length);
+ name[*length] = '\0';
}
}
-void Datatype::set_name(const char* name){
- if(name_!=nullptr && (flags_ & DT_FLAG_PREDEFINED) == 0)
- xbt_free(name_);
- name_ = xbt_strdup(name);
+void Datatype::set_name(const char* name)
+{
+ name_ = name;
}
int Datatype::pack(const void* inbuf, int incount, void* outbuf, int outcount, int* position, const Comm*)
int count = sendcount < recvcount ? sendcount : recvcount;
XBT_DEBUG("Copying %d bytes from %p to %p", count, sendbuf, recvbuf);
if (not(sendtype->flags() & DT_FLAG_DERIVED) && not(recvtype->flags() & DT_FLAG_DERIVED)) {
- if (not smpi_process()->replaying())
+ if (not smpi_process()->replaying() && count > 0)
memcpy(recvbuf, sendbuf, count);
} else if (not(sendtype->flags() & DT_FLAG_DERIVED)) {
recvtype->unserialize(sendbuf, recvbuf, count / recvtype->size(), MPI_REPLACE);
/* in this situation the data are contiguous thus it's not required to serialize and unserialize it*/
*new_type = new Datatype(count * block_length * old_type->size(), 0, ((count -1) * stride + block_length)*
old_type->size(), DT_FLAG_CONTIGUOUS);
- int ints[3] = {count, block_length, stride};
- (*new_type)->contents_ = new Datatype_contents(MPI_COMBINER_VECTOR, 3, ints, 0, nullptr, 1, &old_type);
+ const std::array<int, 3> ints = {{count, block_length, stride}};
+ (*new_type)->contents_ = new Datatype_contents(MPI_COMBINER_VECTOR, 3, ints.data(), 0, nullptr, 1, &old_type);
retval=MPI_SUCCESS;
}
return retval;
}else{
/* in this situation the data are contiguous thus it's not required to serialize and unserialize it*/
*new_type = new Datatype(count * block_length * old_type->size(), 0, count * block_length * old_type->size(), DT_FLAG_CONTIGUOUS);
- int ints[2] = {count, block_length};
- (*new_type)->contents_ = new Datatype_contents(MPI_COMBINER_HVECTOR, 2, ints, 1, &stride, 1, &old_type);
+ const std::array<int, 2> ints = {{count, block_length}};
+ (*new_type)->contents_ = new Datatype_contents(MPI_COMBINER_HVECTOR, 2, ints.data(), 1, &stride, 1, &old_type);
retval=MPI_SUCCESS;
}
return retval;
tmp = *newtype;
}
- MPI_Aint lbs[1] = {lb * extent};
- int sizes [1]={1};
+ const MPI_Aint lbs = lb * extent;
+ const int sizes = 1;
//handle LB and UB with a resized call
- create_hindexed( 1, sizes, lbs, tmp, newtype);
+ create_hindexed(1, &sizes, &lbs, tmp, newtype);
unref(tmp);
tmp = *newtype;
}
int Datatype::create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, MPI_Datatype *newtype){
- int blocks[3] = {1, 1, 1};
- MPI_Aint disps[3] = {lb, 0, lb + extent};
- MPI_Datatype types[3] = {MPI_LB, oldtype, MPI_UB};
+ const std::array<int, 3> blocks = {{1, 1, 1}};
+ const std::array<MPI_Aint, 3> disps = {{lb, 0, lb + extent}};
+ const std::array<MPI_Datatype, 3> types = {{MPI_LB, oldtype, MPI_UB}};
- *newtype = new simgrid::smpi::Type_Struct(oldtype->size(), lb, lb + extent, DT_FLAG_DERIVED, 3, blocks, disps, types);
+ *newtype = new simgrid::smpi::Type_Struct(oldtype->size(), lb, lb + extent, DT_FLAG_DERIVED, 3, blocks.data(),
+ disps.data(), types.data());
(*newtype)->addflag(~DT_FLAG_COMMITED);
return MPI_SUCCESS;
#include "smpi_op.hpp"
#include <xbt/log.h>
+#include <array>
#include <cstring>
namespace simgrid{
}
Type_Hvector::Type_Hvector(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int block_length, MPI_Aint stride, MPI_Datatype old_type): Datatype(size, lb, ub, flags), block_count_(count), block_length_(block_length), block_stride_(stride), old_type_(old_type){
- int ints[2] = {count, block_length};
- contents_ = new Datatype_contents(MPI_COMBINER_HVECTOR, 2, ints, 1, &stride, 1, &old_type);
+ const std::array<int, 2> ints = {{count, block_length}};
+ contents_ = new Datatype_contents(MPI_COMBINER_HVECTOR, 2, ints.data(), 1, &stride, 1, &old_type);
old_type->ref();
}
Type_Hvector::~Type_Hvector(){
: Type_Hvector(size, lb, ub, flags, count, block_length, stride * old_type->get_extent(), old_type)
{
delete contents_;
- int ints[3] = {count, block_length, stride};
- contents_ = new Datatype_contents(MPI_COMBINER_VECTOR, 3, ints, 0, nullptr, 1, &old_type);
+ const std::array<int, 3> ints = {{count, block_length, stride}};
+ contents_ = new Datatype_contents(MPI_COMBINER_VECTOR, 3, ints.data(), 0, nullptr, 1, &old_type);
}
int Type_Vector::clone(MPI_Datatype* type)
, block_indices_(new MPI_Aint[count])
, old_type_(old_type)
{
- auto* ints = new int[count + 1];
+ std::vector<int> ints(count + 1);
ints[0]=count;
for(int i=1;i<=count;i++)
ints[i]=block_lengths[i-1];
- contents_ = new Datatype_contents(MPI_COMBINER_HINDEXED, count+1, ints, count, block_indices, 1, &old_type);
- delete[] ints;
+ contents_ = new Datatype_contents(MPI_COMBINER_HINDEXED, count + 1, ints.data(), count, block_indices, 1, &old_type);
old_type_->ref();
for (int i = 0; i < count; i++) {
block_lengths_[i] = block_lengths[i];
: Type_Hindexed(size, lb, ub, flags, count, block_lengths, block_indices, old_type, old_type->get_extent())
{
delete contents_;
- auto* ints = new int[2 * count + 1];
+ std::vector<int> ints(2 * count + 1);
ints[0]=count;
for(int i=1;i<=count;i++)
ints[i]=block_lengths[i-1];
for(int i=count+1;i<=2*count;i++)
ints[i]=block_indices[i-count-1];
- contents_ = new Datatype_contents(MPI_COMBINER_INDEXED, 2*count+1, ints, 0, nullptr, 1, &old_type);
- delete[] ints;
+ contents_ = new Datatype_contents(MPI_COMBINER_INDEXED, 2 * count + 1, ints.data(), 0, nullptr, 1, &old_type);
}
int Type_Indexed::clone(MPI_Datatype* type)
, block_indices_(new MPI_Aint[count])
, old_types_(new MPI_Datatype[count])
{
- auto* ints = new int[count + 1];
+ std::vector<int> ints(count + 1);
ints[0]=count;
for(int i=1;i<=count;i++)
ints[i]=block_lengths[i-1];
- contents_ = new Datatype_contents(MPI_COMBINER_INDEXED, count+1, ints, count, block_indices, count, old_types);
- delete[] ints;
+ contents_ =
+ new Datatype_contents(MPI_COMBINER_INDEXED, count + 1, ints.data(), count, block_indices, count, old_types);
for (int i = 0; i < count; i++) {
block_lengths_[i]=block_lengths[i];
block_indices_[i]=block_indices[i];
namespace smpi{
MPI_Errhandler Errhandler::f2c(int id) {
- if(F2C::f2c_lookup() != nullptr && id >= 0) {
- char key[KEY_SIZE];
- return static_cast<MPI_Errhandler>(F2C::f2c_lookup()->at(get_key(key, id)));
+ if (F2C::lookup() != nullptr && id >= 0) {
+ return static_cast<MPI_Errhandler>(F2C::lookup()->at(id));
} else {
return MPI_ERRHANDLER_NULL;
}
#include "private.hpp"
#include "src/smpi/include/smpi_actor.hpp"
-#include <cstdio>
-
int mpi_in_place_;
int mpi_bottom_;
int mpi_status_ignore_;
namespace simgrid{
namespace smpi{
-std::unordered_map<std::string, F2C*>* F2C::f2c_lookup_ = nullptr;
+std::unordered_map<int, F2C*>* F2C::f2c_lookup_ = nullptr;
int F2C::f2c_id_ = 0;
// Keep it non trivially-constructible, or it will break MC+smpi on FreeBSD with Clang (don't ask why)
F2C::F2C() = default;
-std::unordered_map<std::string, F2C*>* F2C::f2c_lookup()
-{
- return f2c_lookup_;
-}
-
-void F2C::set_f2c_lookup(std::unordered_map<std::string, F2C*>* map)
-{
- f2c_lookup_ = map;
-}
-
-void F2C::f2c_id_increment(){
- f2c_id_++;
-}
-
-int F2C::f2c_id(){
- return f2c_id_;
-}
-
-char* F2C::get_my_key(char* key) {
- std::snprintf(key, KEY_SIZE, "%d", my_f2c_id_);
- return key;
-}
-
-char* F2C::get_key(char* key, int id) {
- std::snprintf(key, KEY_SIZE, "%d", id);
- return key;
-}
-
-void F2C::delete_lookup(){
- delete f2c_lookup_;
-}
-
-std::unordered_map<std::string, F2C*>* F2C::lookup()
-{
- return f2c_lookup_;
-}
-
-void F2C::free_f(int id)
-{
- char key[KEY_SIZE];
- f2c_lookup_->erase(get_key(key,id));
-}
-
int F2C::add_f()
{
if (f2c_lookup_ == nullptr)
- f2c_lookup_ = new std::unordered_map<std::string, F2C*>();
+ f2c_lookup_ = new std::unordered_map<int, F2C*>();
- char key[KEY_SIZE];
- my_f2c_id_=f2c_id_;
- (*f2c_lookup_)[get_my_key(key)] = this;
+ my_f2c_id_ = f2c_id();
+ (*f2c_lookup_)[my_f2c_id_] = this;
f2c_id_increment();
return my_f2c_id_;
}
int F2C::c2f()
{
if (f2c_lookup_ == nullptr) {
- f2c_lookup_ = new std::unordered_map<std::string, F2C*>();
+ f2c_lookup_ = new std::unordered_map<int, F2C*>();
}
if(my_f2c_id_==-1)
F2C* F2C::f2c(int id)
{
if (f2c_lookup_ == nullptr)
- f2c_lookup_ = new std::unordered_map<std::string, F2C*>();
+ f2c_lookup_ = new std::unordered_map<int, F2C*>();
if(id >= 0){
- char key[KEY_SIZE];
- auto comm = f2c_lookup_->find(get_key(key,id));
+ auto comm = f2c_lookup_->find(id);
return comm == f2c_lookup_->end() ? nullptr : comm->second;
}else
return nullptr;
int oldsize = size_;
int newsize = oldsize - n;
*newgroup = new Group(newsize);
- auto* to_exclude = new int[size_];
- for (int i = 0; i < oldsize; i++)
- to_exclude[i]=0;
- for (int i = 0; i < n; i++)
- to_exclude[ranks[i]]=1;
+ std::vector<bool> to_exclude(size_, false);
+ for (int i = 0; i < n; i++)
+ to_exclude[ranks[i]] = true;
int j = 0;
for (int i = 0; i < oldsize; i++) {
- if(to_exclude[i]==0){
+ if (not to_exclude[i]) {
s4u::Actor* actor = this->actor(i);
(*newgroup)->set_mapping(actor, j);
j++;
}
}
- delete[] to_exclude;
return MPI_SUCCESS;
}
MPI_Group Group::f2c(int id) {
if(id == -2) {
return MPI_GROUP_EMPTY;
- } else if(F2C::f2c_lookup() != nullptr && id >= 0) {
- char key[KEY_SIZE];
- return static_cast<MPI_Group>(F2C::f2c_lookup()->at(get_key(key, id)));
+ } else if (F2C::lookup() != nullptr && id >= 0) {
+ return static_cast<MPI_Group>(F2C::lookup()->at(id));
} else {
return MPI_GROUP_NULL;
}
}
#define LAND_OP(a, b) (b) = (a) && (b)
#define LOR_OP(a, b) (b) = (a) || (b)
-#define LXOR_OP(a, b) (b) = (not(a) && (b)) || ((a) && not(b))
+#define LXOR_OP(a, b) (b) = bool(a) != bool(b)
#define BAND_OP(a, b) (b) &= (a)
#define BOR_OP(a, b) (b) |= (a)
#define BXOR_OP(a, b) (b) ^= (a)
#include "src/smpi/include/smpi_actor.hpp"
#include <algorithm>
+#include <array>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_request, smpi, "Logging specific to SMPI (request)");
else
refcount_ = 0;
cancelled_ = 0;
- generalized_funcs=nullptr;
nbc_requests_=nullptr;
nbc_requests_size_=0;
init_buffer(count);
if((*request)->refcount_==0){
if ((*request)->flags_ & MPI_REQ_GENERALIZED){
((*request)->generalized_funcs)->free_fn(((*request)->generalized_funcs)->extra_state);
- delete (*request)->generalized_funcs;
}else{
Comm::unref((*request)->comm_);
Datatype::unref((*request)->old_type_);
void *recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag,
MPI_Comm comm, MPI_Status * status)
{
- MPI_Request requests[2];
- MPI_Status stats[2];
+ std::array<MPI_Request, 2> requests;
+ std::array<MPI_Status, 2> stats;
int myid = simgrid::s4u::this_actor::get_pid();
if ((comm->group()->actor(dst)->get_pid() == myid) && (comm->group()->actor(src)->get_pid() == myid)) {
Datatype::copy(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype);
}
requests[0] = isend_init(sendbuf, sendcount, sendtype, dst, sendtag, comm);
requests[1] = irecv_init(recvbuf, recvcount, recvtype, src, recvtag, comm);
- startall(2, requests);
- waitall(2, requests, stats);
+ startall(2, requests.data());
+ waitall(2, requests.data(), stats.data());
unref(&requests[0]);
unref(&requests[1]);
if(status != MPI_STATUS_IGNORE) {
}
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)
+ // 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
+ xbt_assert(*request != MPI_REQUEST_NULL);
+
static int nsleeps = 1;
int ret = MPI_SUCCESS;
return ret;
}
}
- if (*request != MPI_REQUEST_NULL &&
- ((*request)->flags_ & MPI_REQ_GENERALIZED)
- && !((*request)->flags_ & MPI_REQ_COMPLETE))
+ if (((*request)->flags_ & MPI_REQ_GENERALIZED) && !((*request)->flags_ & MPI_REQ_COMPLETE))
*flag=0;
if (*flag) {
- finish_wait(request,status);
+ finish_wait(request, status); // may invalidate *request
if (*request != MPI_REQUEST_NULL && ((*request)->flags_ & MPI_REQ_GENERALIZED)){
+ MPI_Status tmp_status;
MPI_Status* mystatus;
- if(status==MPI_STATUS_IGNORE){
- mystatus=new MPI_Status();
+ if (status == MPI_STATUS_IGNORE) {
+ mystatus = &tmp_status;
Status::empty(mystatus);
- }else{
- mystatus=status;
+ } 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)
} else {
finish_wait(&requests[*index],status);
if (requests[*index] != MPI_REQUEST_NULL && (requests[*index]->flags_ & MPI_REQ_GENERALIZED)){
+ MPI_Status tmp_status;
MPI_Status* mystatus;
- if(status==MPI_STATUS_IGNORE){
- mystatus=new MPI_Status();
+ if (status == MPI_STATUS_IGNORE) {
+ mystatus = &tmp_status;
Status::empty(mystatus);
- }else{
- mystatus=status;
+ } 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))
int Request::wait(MPI_Request * request, MPI_Status * status)
{
+ // assume that *request is not MPI_REQUEST_NULL (filtered in PMPI_Wait before)
+ xbt_assert(*request != MPI_REQUEST_NULL);
+
int ret=MPI_SUCCESS;
// Are we waiting on a request meant for non blocking collectives ?
// If so, wait for all the subrequests.
}
}
- if (*request != MPI_REQUEST_NULL && ((*request)->flags_ & MPI_REQ_GENERALIZED)){
- MPI_Status* mystatus;
+ if ((*request)->flags_ & MPI_REQ_GENERALIZED) {
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();
+ }
+ MPI_Status tmp_status;
+ MPI_Status* mystatus;
+ if (status == MPI_STATUS_IGNORE) {
+ mystatus = &tmp_status;
Status::empty(mystatus);
- }else{
- mystatus=status;
+ } 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);
+ finish_wait(request, status); // may invalidate *request
if (*request != MPI_REQUEST_NULL && (((*request)->flags_ & MPI_REQ_NON_PERSISTENT) != 0))
*request = MPI_REQUEST_NULL;
return ret;
MPI_Request Request::f2c(int id)
{
- char key[KEY_SIZE];
if(id==MPI_FORTRAN_REQUEST_NULL)
return MPI_REQUEST_NULL;
- return static_cast<MPI_Request>(F2C::f2c_lookup()->at(get_key(key,id)));
+ return static_cast<MPI_Request>(F2C::lookup()->at(id));
}
void Request::free_f(int id)
{
if (id != MPI_FORTRAN_REQUEST_NULL) {
- char key[KEY_SIZE];
- F2C::f2c_lookup()->erase(get_key(key, id));
+ F2C::lookup()->erase(id);
}
}
(*request)->flags_ |= MPI_REQ_GENERALIZED;
(*request)->flags_ |= MPI_REQ_PERSISTENT;
(*request)->refcount_ = 1;
- ((*request)->generalized_funcs) = new s_smpi_mpi_generalized_request_funcs_t;
+ ((*request)->generalized_funcs) = std::make_unique<smpi_mpi_generalized_request_funcs_t>();
((*request)->generalized_funcs)->query_fn=query_fn;
((*request)->generalized_funcs)->free_fn=free_fn;
((*request)->generalized_funcs)->cancel_fn=cancel_fn;
#include "smpi_comm.hpp"
#include "smpi_topo.hpp"
#include "xbt/sysdep.h"
-#include <cmath>
+
+#include <algorithm>
#include <vector>
/* static functions */
-static int assignnodes(int ndim, int nfactor, const int* pfacts, int** pdims);
-static int getfactors(int num, int *nfators, int **factors);
-
+static int assignnodes(int ndim, const std::vector<int>& factors, std::vector<int>& dims);
+static int getfactors(int num, std::vector<int>& factors);
namespace simgrid{
namespace smpi{
Topo_Cart* Topo_Cart::sub(const int remain_dims[], MPI_Comm *newcomm) {
int oldNDims = ndims_;
- int *newDims = nullptr;
- int *newPeriodic = nullptr;
+ std::vector<int> newDims;
+ std::vector<int> newPeriodic;
if (remain_dims == nullptr && oldNDims != 0) {
return nullptr;
}
if (newNDims > 0) {
- newDims = new int[newNDims];
- newPeriodic = new int[newNDims];
+ newDims.resize(newNDims);
+ newPeriodic.resize(newNDims);
// that should not segfault
int j = 0;
}
Topo_Cart* res;
if (newNDims == 0){
- res = new Topo_Cart(getComm(), newNDims, newDims, newPeriodic, 0, newcomm);
+ res = new Topo_Cart(getComm(), newNDims, newDims.data(), newPeriodic.data(), 0, newcomm);
} else {
*newcomm = getComm()->split(color, getComm()->rank());
- auto topo = std::make_shared<Topo_Cart>(getComm(), newNDims, newDims, newPeriodic, 0, nullptr);
+ auto topo = std::make_shared<Topo_Cart>(getComm(), newNDims, newDims.data(), newPeriodic.data(), 0, nullptr);
res = topo.get();
res->setComm(*newcomm);
(*newcomm)->set_topo(topo);
}
- delete[] newDims;
- delete[] newPeriodic;
return res;
}
return MPI_ERR_DIMS;
}
- auto* position = new int[ndims_];
- this->coords(getComm()->rank(), ndims_, position);
+ std::vector<int> position(ndims_);
+ this->coords(getComm()->rank(), ndims_, position.data());
position[direction] += disp;
if(position[direction] < 0 ||
position[direction] >=dims_[direction]) {
if(periodic_[direction]) {
position[direction] %=dims_[direction];
- this->rank(position, rank_dest);
+ this->rank(position.data(), rank_dest);
} else {
*rank_dest = MPI_PROC_NULL;
}
} else {
- this->rank(position, rank_dest);
+ this->rank(position.data(), rank_dest);
}
position[direction] = position_[direction] - disp;
if(position[direction] < 0 || position[direction] >=dims_[direction]) {
if(periodic_[direction]) {
position[direction] %=dims_[direction];
- this->rank(position, rank_source);
+ this->rank(position.data(), rank_source);
} else {
*rank_source = MPI_PROC_NULL;
}
} else {
- this->rank(position, rank_source);
+ this->rank(position.data(), rank_source);
}
- delete[] position;
return MPI_SUCCESS;
}
/* Get # of free-to-be-assigned processes and # of free dimensions */
int freeprocs = nnodes;
int freedims = 0;
- const int* p = dims;
for (int i = 0; i < ndims; ++i) {
- if (*p == 0) {
+ if (dims[i] == 0) {
++freedims;
- } else if ((*p < 0) || ((nnodes % *p) != 0)) {
+ } else if ((dims[i] < 0) || ((nnodes % dims[i]) != 0)) {
return MPI_ERR_DIMS;
} else {
- freeprocs /= *p;
+ freeprocs /= dims[i];
}
- p++;
}
if (freedims == 0) {
if (freeprocs == 1) {
for (int i = 0; i < ndims; ++i) {
- if (*dims == 0) {
- *dims = 1;
+ if (dims[i] == 0) {
+ dims[i] = 1;
}
- dims++;
}
return MPI_SUCCESS;
}
/* Factor the number of free processes */
- int nfactors;
- int *factors;
- int err = getfactors(freeprocs, &nfactors, &factors);
+ std::vector<int> factors;
+ int err = getfactors(freeprocs, factors);
if (MPI_SUCCESS != err)
return err;
/* Assign free processes to free dimensions */
- int *procs;
- err = assignnodes(freedims, nfactors, factors, &procs);
+ std::vector<int> procs;
+ err = assignnodes(freedims, factors, procs);
if (MPI_SUCCESS != err)
return err;
/* Return assignment results */
- p = procs;
+ auto p = procs.begin();
for (int i = 0; i < ndims; ++i) {
- if (*dims == 0) {
- *dims = *p++;
+ if (dims[i] == 0) {
+ dims[i] = *p++;
}
- dims++;
}
- delete[] factors;
- delete[] procs;
-
/* all done */
return MPI_SUCCESS;
}
* - sort dimensions in decreasing order
* - dimensions array dynamically allocated
* Accepts: - # of dimensions
- * - # of prime factors
- * - array of prime factors
- * - ptr to array of dimensions (returned value)
+ * - std::vector of prime factors
+ * - reference to std::vector of dimensions (returned value)
* Returns: - 0 or ERROR
*/
-static int assignnodes(int ndim, int nfactor, const int* pfacts, int** pdims)
+static int assignnodes(int ndim, const std::vector<int>& factors, std::vector<int>& dims)
{
- int *pmin;
-
if (0 >= ndim) {
return MPI_ERR_DIMS;
}
/* Allocate and initialize the bins */
- auto* bins = new int[ndim];
+ dims.clear();
+ dims.resize(ndim, 1);
- *pdims = bins;
- int *p = bins;
-
- for (int i = 0 ; i < ndim; ++i) {
- *p = 1;
- p++;
- }
/* Loop assigning factors from the highest to the lowest */
- for (int j = nfactor - 1; j >= 0; --j) {
- int f = pfacts[j];
+ for (auto pfact = factors.crbegin(); pfact != factors.crend(); ++pfact) {
/* Assign a factor to the smallest bin */
- pmin = bins;
- p = pmin + 1;
- for (int i = 1; i < ndim; ++i) {
- if (*p < *pmin) {
- pmin = p;
- }
- p++;
- }
- *pmin *= f;
+ auto pmin = std::min_element(dims.begin(), dims.end());
+ *pmin *= *pfact;
}
- /* Sort dimensions in decreasing order (O(n^2) for now) */
- pmin = bins;
- for (int i = 0; i < ndim - 1; ++i) {
- p = pmin + 1;
- for (int j = i + 1; j < ndim; ++j) {
- if (*p > *pmin) {
- int n = *p;
- *p = *pmin;
- *pmin = n;
- }
- p++;
- }
- pmin++;
- }
+ /* Sort dimensions in decreasing order */
+ std::sort(dims.begin(), dims.end(), std::greater<>());
return MPI_SUCCESS;
}
*
* Function: - factorize a number
* Accepts: - number
- * - # prime factors
- * - array of prime factors
+ * - reference to std::vector of prime factors
* Returns: - MPI_SUCCESS or ERROR
*/
-static int getfactors(int num, int *nfactors, int **factors) {
- if(num < 2) {
- (*nfactors) = 0;
- (*factors) = nullptr;
+static int getfactors(int num, std::vector<int>& factors)
+{
+ factors.clear();
+ if (num < 2) {
return MPI_SUCCESS;
}
- /* Allocate the array of prime factors which cannot exceed log_2(num) entries */
- int sqrtnum = ceil(sqrt(double(num)));
- int size = ceil(log(double(num)) / log(2.0));
- *factors = new int[size];
- int i = 0;
/* determine all occurrences of factor 2 */
while((num % 2) == 0) {
num /= 2;
- (*factors)[i++] = 2;
+ factors.push_back(2);
}
/* determine all occurrences of uneven prime numbers up to sqrt(num) */
- for(int d = 3; (num > 1) && (d < sqrtnum); d += 2) {
+ for (int d = 3; (num > 1) && (d * d < num); d += 2) {
while((num % d) == 0) {
num /= d;
- (*factors)[i++] = d;
+ factors.push_back(d);
}
}
/* as we looped only up to sqrt(num) one factor > sqrt(num) may be left over */
if(num != 1) {
- (*factors)[i++] = num;
+ factors.push_back(num);
}
- (*nfactors) = i;
return MPI_SUCCESS;
}
-
#include "smpi_request.hpp"
#include "src/smpi/include/smpi_actor.hpp"
+#include <algorithm>
+
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_rma, smpi, "Logging specific to SMPI (RMA operations)");
, disp_unit_(disp_unit)
, info_(info)
, comm_(comm)
+ , connected_wins_(comm->size())
, rank_(comm->rank())
, allocated_(allocated)
, dynamic_(dynamic)
XBT_DEBUG("Creating window");
if(info!=MPI_INFO_NULL)
info->ref();
- int comm_size = comm->size();
- name_ = nullptr;
- opened_ = 0;
- group_ = MPI_GROUP_NULL;
- requests_ = new std::vector<MPI_Request>();
- mut_ = s4u::Mutex::create();
- lock_mut_ = s4u::Mutex::create();
- atomic_mut_ = s4u::Mutex::create();
- connected_wins_ = new MPI_Win[comm_size];
connected_wins_[rank_] = this;
- count_ = 0;
if(rank_==0){
- bar_ = new s4u::Barrier(comm_size);
+ bar_ = new s4u::Barrier(comm->size());
}
- mode_=0;
- errhandler_=MPI_ERRORS_ARE_FATAL;
errhandler_->ref();
comm->add_rma_win(this);
comm->ref();
- colls::allgather(&(connected_wins_[rank_]), sizeof(MPI_Win), MPI_BYTE, connected_wins_, sizeof(MPI_Win), MPI_BYTE,
- comm);
+ colls::allgather(&connected_wins_[rank_], sizeof(MPI_Win), MPI_BYTE, connected_wins_.data(), sizeof(MPI_Win),
+ MPI_BYTE, comm);
colls::bcast(&(bar_), sizeof(s4u::Barrier*), MPI_BYTE, 0, comm);
int finished = finish_comms();
XBT_DEBUG("Win destructor - Finished %d RMA calls", finished);
- delete requests_;
- delete[] connected_wins_;
- if (name_ != nullptr){
- xbt_free(name_);
- }
if (info_ != MPI_INFO_NULL)
simgrid::smpi::Info::unref(info_);
if (errhandler_ != MPI_ERRHANDLER_NULL)
void Win::get_name(char* name, int* length) const
{
- if(name_==nullptr){
- *length=0;
- name=nullptr;
- return;
+ *length = static_cast<int>(name_.length());
+ if (not name_.empty()) {
+ name_.copy(name, *length);
+ name[*length] = '\0';
}
- *length = strlen(name_);
- strncpy(name, name_, *length+1);
}
void Win::get_group(MPI_Group* group){
}
void Win::set_name(const char* name){
- name_ = xbt_strdup(name);
+ name_ = name;
}
int Win::fence(int assert)
// Without this, the vector could get redimensioned when another process pushes.
// This would result in the array used by Request::waitall() to be invalidated.
// Another solution would be to copy the data and cleanup the vector *before* Request::waitall
- std::vector<MPI_Request> *reqs = requests_;
- int size = static_cast<int>(reqs->size());
+
// start all requests that have been prepared by another process
- if (size > 0) {
- MPI_Request* treqs = &(*reqs)[0];
+ if (not requests_.empty()) {
+ int size = static_cast<int>(requests_.size());
+ MPI_Request* treqs = requests_.data();
Request::waitall(size, treqs, MPI_STATUSES_IGNORE);
}
count_=0;
MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Request* request)
{
//get receiver pointer
- const Win* recv_win = connected_wins_[target_rank];
+ Win* recv_win = connected_wins_[target_rank];
if(opened_==0){//check that post/start has been done
// no fence or start .. lock ok ?
*request=sreq;
}else{
mut_->lock();
- requests_->push_back(sreq);
+ requests_.push_back(sreq);
mut_->unlock();
}
//push request to receiver's win
recv_win->mut_->lock();
- recv_win->requests_->push_back(rreq);
+ recv_win->requests_.push_back(rreq);
rreq->start();
recv_win->mut_->unlock();
} else {
MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Request* request)
{
//get sender pointer
- const Win* send_win = connected_wins_[target_rank];
+ Win* send_win = connected_wins_[target_rank];
if(opened_==0){//check that post/start has been done
// no fence or start .. lock ok ?
sreq->start();
//push request to receiver's win
send_win->mut_->lock();
- send_win->requests_->push_back(sreq);
+ send_win->requests_.push_back(sreq);
send_win->mut_->unlock();
//start recv
*request=rreq;
}else{
mut_->lock();
- requests_->push_back(rreq);
+ requests_.push_back(rreq);
mut_->unlock();
}
} else {
{
XBT_DEBUG("Entering MPI_Win_Accumulate");
//get receiver pointer
- const Win* recv_win = connected_wins_[target_rank];
+ Win* recv_win = connected_wins_[target_rank];
if(opened_==0){//check that post/start has been done
// no fence or start .. lock ok ?
sreq->start();
// push request to receiver's win
recv_win->mut_->lock();
- recv_win->requests_->push_back(rreq);
+ recv_win->requests_.push_back(rreq);
rreq->start();
recv_win->mut_->unlock();
*request = sreq;
} else {
mut_->lock();
- requests_->push_back(sreq);
+ requests_.push_back(sreq);
mut_->unlock();
}
int i = 0;
int j = 0;
int size = group->size();
- MPI_Request* reqs = xbt_new0(MPI_Request, size);
+ std::vector<MPI_Request> reqs(size);
XBT_DEBUG("Entering MPI_Win_Start");
while (j != size) {
j++;
}
size = i;
- Request::startall(size, reqs);
- Request::waitall(size, reqs, MPI_STATUSES_IGNORE);
+ Request::startall(size, reqs.data());
+ Request::waitall(size, reqs.data(), MPI_STATUSES_IGNORE);
for (i = 0; i < size; i++) {
Request::unref(&reqs[i]);
}
- xbt_free(reqs);
opened_++; //we're open for business !
group_=group;
group->ref();
int i = 0;
int j = 0;
int size = group->size();
- MPI_Request* reqs = xbt_new0(MPI_Request, size);
+ std::vector<MPI_Request> reqs(size);
XBT_DEBUG("Entering MPI_Win_Post");
while(j!=size){
}
size=i;
- Request::startall(size, reqs);
- Request::waitall(size, reqs, MPI_STATUSES_IGNORE);
+ Request::startall(size, reqs.data());
+ Request::waitall(size, reqs.data(), MPI_STATUSES_IGNORE);
for(i=0;i<size;i++){
Request::unref(&reqs[i]);
}
- xbt_free(reqs);
opened_++; //we're open for business !
group_=group;
group->ref();
int i = 0;
int j = 0;
int size = group_->size();
- MPI_Request* reqs = xbt_new0(MPI_Request, size);
+ std::vector<MPI_Request> reqs(size);
while(j!=size){
int dst = comm_->group()->rank(group_->actor(j));
}
size=i;
XBT_DEBUG("Win_complete - Sending sync messages to %d processes", size);
- Request::startall(size, reqs);
- Request::waitall(size, reqs, MPI_STATUSES_IGNORE);
+ Request::startall(size, reqs.data());
+ Request::waitall(size, reqs.data(), MPI_STATUSES_IGNORE);
for(i=0;i<size;i++){
Request::unref(&reqs[i]);
}
- xbt_free(reqs);
int finished = finish_comms();
XBT_DEBUG("Win_complete - Finished %d RMA calls", finished);
int i = 0;
int j = 0;
int size = group_->size();
- MPI_Request* reqs = xbt_new0(MPI_Request, size);
+ std::vector<MPI_Request> reqs(size);
while(j!=size){
int src = comm_->group()->rank(group_->actor(j));
}
size=i;
XBT_DEBUG("Win_wait - Receiving sync messages from %d processes", size);
- Request::startall(size, reqs);
- Request::waitall(size, reqs, MPI_STATUSES_IGNORE);
+ Request::startall(size, reqs.data());
+ Request::waitall(size, reqs.data(), MPI_STATUSES_IGNORE);
for(i=0;i<size;i++){
Request::unref(&reqs[i]);
}
- xbt_free(reqs);
int finished = finish_comms();
XBT_DEBUG("Win_wait - Finished %d RMA calls", finished);
int Win::finish_comms(){
mut_->lock();
//Finish own requests
- std::vector<MPI_Request> *reqqs = requests_;
- int size = static_cast<int>(reqqs->size());
+ int size = static_cast<int>(requests_.size());
if (size > 0) {
- MPI_Request* treqs = &(*reqqs)[0];
+ MPI_Request* treqs = requests_.data();
Request::waitall(size, treqs, MPI_STATUSES_IGNORE);
- reqqs->clear();
+ requests_.clear();
}
mut_->unlock();
return size;
int Win::finish_comms(int rank){
mut_->lock();
- //Finish own requests
- std::vector<MPI_Request> *reqqs = requests_;
- int size = static_cast<int>(reqqs->size());
+ // Finish own requests
+ // Let's see if we're either the destination or the sender of this request
+ // because we only wait for requests that we are responsible for.
+ // Also use the process id here since the request itself returns from src()
+ // and dst() the process id, NOT the rank (which only exists in the context of a communicator).
+ int proc_id = comm_->group()->actor(rank)->get_pid();
+ auto it = std::stable_partition(begin(requests_), end(requests_), [proc_id](const MPI_Request& req) {
+ return (req == MPI_REQUEST_NULL || (req->src() != proc_id && req->dst() != proc_id));
+ });
+ std::vector<MPI_Request> myreqqs(it, end(requests_));
+ requests_.erase(it, end(requests_));
+ int size = static_cast<int>(myreqqs.size());
if (size > 0) {
- size = 0;
- std::vector<MPI_Request> myreqqs;
- auto iter = reqqs->begin();
- int proc_id = comm_->group()->actor(rank)->get_pid();
- while (iter != reqqs->end()){
- // Let's see if we're either the destination or the sender of this request
- // because we only wait for requests that we are responsible for.
- // Also use the process id here since the request itself returns from src()
- // and dst() the process id, NOT the rank (which only exists in the context of a communicator).
- if (((*iter) != MPI_REQUEST_NULL) && (((*iter)->src() == proc_id) || ((*iter)->dst() == proc_id))) {
- myreqqs.push_back(*iter);
- iter = reqqs->erase(iter);
- size++;
- } else {
- ++iter;
- }
- }
- if(size >0){
- MPI_Request* treqs = &myreqqs[0];
- Request::waitall(size, treqs, MPI_STATUSES_IGNORE);
- myreqqs.clear();
- }
+ MPI_Request* treqs = myreqqs.data();
+ Request::waitall(size, treqs, MPI_STATUSES_IGNORE);
+ myreqqs.clear();
}
mut_->unlock();
return size;
/* 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/plugins/load_balancer.h>
#include <simgrid/s4u/Actor.hpp>
#include <src/instr/instr_smpi.hpp>
#include <src/smpi/include/smpi_actor.hpp>
+++ /dev/null
-/* Copyright (c) 2006-2020. 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 <algorithm>
-#include <map>
-#include <unordered_map>
-#include <queue>
-
-#include <boost/heap/fibonacci_heap.hpp>
-#include <simgrid/plugins/load.h>
-#include <src/smpi/plugins/load_balancer/load_balancer.hpp>
-
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(plugin_load_balancer);
-
-namespace simgrid {
-namespace plugin {
-namespace loadbalancer {
-
-class XBT_PRIVATE compare_hosts {
-public:
- bool operator()(s4u::Host* const a, s4u::Host* const b) const;
-};
-
-typedef boost::heap::fibonacci_heap<s4u::Host*, boost::heap::compare<compare_hosts>>::handle_type heap_handle;
-
-/** Structure that imitates a std::pair, but it allows us to use meaningful names instead of .first and .second */
-struct XBT_PRIVATE pair_handle_load
-{
- heap_handle update_handle;
- double load;
-};
-
-static std::map<s4u::Host* const, pair_handle_load> additional_load;
-
-bool compare_hosts::operator()(s4u::Host* const a, s4u::Host* const b) const
-{
- return additional_load[a].load > additional_load[b].load;
-}
-
-void LoadBalancer::run()
-{
- const s4u::Engine* engine = s4u::Engine::get_instance();
- std::vector<s4u::Host*> available_hosts =
- engine->get_filtered_hosts([](const s4u::Host* host) { return host->is_on(); });
- xbt_assert(available_hosts.size() > 0, "No hosts available; are they all switched off?");
-
- // TODO: Account for daemon background load (-> use especially the availability file)
-
- std::vector<s4u::ActorPtr> all_actors =
- engine->get_filtered_actors([](s4u::ActorPtr actor) { return not actor->is_daemon(); });
-
- for (auto const& actor : all_actors) {
- new_mapping.assign(actor, actor->get_host());
- }
- // Sort the actors, from highest to lowest load; we then just iterate over these actors
- std::sort(all_actors.begin(), all_actors.end(), [this](s4u::ActorPtr a, s4u::ActorPtr b) {
- return actor_computation[a->get_pid()] > actor_computation[b->get_pid()];
- });
-
- // Sort the hosts. Use a heap datastructure, because we have to reorder
- // after a host got another actor assigned (or moved from).
- // We can't use std::priorityQueue here because we modify *two* elements: The top element, which
- // we can access and which has the lowest load, gets a new actor assigned.
- // However, the host losing that actor must be updated as well.
- // std::priorityQueue is immutable and hence doesn't work for us.
- //
- // This heap contains the least loaded host at the top
- boost::heap::fibonacci_heap<s4u::Host*, boost::heap::compare<compare_hosts>> usable_hosts;
- for (auto& host : available_hosts) {
- std::vector<s4u::ActorPtr> actors = host->get_all_actors();
- heap_handle update_handle = usable_hosts.push(host); // Required to update elements in the heap
- additional_load[host] = {update_handle, 0}; // Save the handle for later
- const double total_flops_computed = sg_host_get_computed_flops(host);
- for (auto const& actor : actors) {
- additional_load[host].load += actor_computation[actor->get_pid()] / total_flops_computed; // Normalize load - this allows comparison
- // even between hosts with different frequencies
- XBT_DEBUG("Actor %li -> %f", actor->get_pid(), actor_computation[actor->get_pid()]);
- }
- usable_hosts.increase(update_handle);
- XBT_DEBUG("Host %s initialized to %f", host->get_cname(), additional_load[host].load);
- }
-
- // Implementation of the Greedy algorithm
- for (auto const& actor : all_actors) {
- s4u::Host* target_host = usable_hosts.top(); // This is the host with the lowest load
-
- s4u::Host* cur_mapped_host = new_mapping.get_host(actor);
- if (target_host != cur_mapped_host
- && additional_load[target_host].load + actor_computation[actor->get_pid()] < additional_load[cur_mapped_host].load
- && new_mapping.count_actors(cur_mapped_host) > 1) {
- usable_hosts.pop();
- XBT_DEBUG("Assigning %li from %s to %s -- actor_load: %f -- host_load: %f", actor->get_pid(), actor->get_host()->get_cname(), target_host->get_cname(), actor_computation[actor->get_pid()], additional_load[target_host].load);
- additional_load[cur_mapped_host].load = std::max<double>(0.0, additional_load[cur_mapped_host].load - actor_computation[actor->get_pid()]); // No negative loads, please!
- usable_hosts.update(additional_load[cur_mapped_host].update_handle, cur_mapped_host);
- additional_load[target_host].load += actor_computation[actor->get_pid()];
-
- new_mapping.assign(actor, target_host);
-
- XBT_DEBUG("Assigning actor %li to host %s", actor->get_pid(), target_host->get_cname());
-
- XBT_DEBUG("host_load: %f after the assignment", additional_load[target_host].load);
- additional_load[target_host].update_handle = usable_hosts.push(target_host); // Save update handle for later
- }
- }
-
- while (!usable_hosts.empty()) {
- s4u::Host* host = usable_hosts.top();
- usable_hosts.pop();
-
- sg_host_load_reset(host); // Reset host load for next iterations
-
- if (XBT_LOG_ISENABLED(plugin_load_balancer, e_xbt_log_priority_t::xbt_log_priority_debug)) {
- /* Debug messages that allow us to verify the load for each host */
- XBT_DEBUG("Host: %s, load total: %f", host->get_cname(), additional_load[host].load);
- double load_verif = 0.0;
- new_mapping.for_each_actor(host, [this, &load_verif](s4u::ActorPtr actor) {
- load_verif += actor_computation[actor->get_pid()];
- XBT_DEBUG(" %li (load: %f)", actor->get_pid(), actor_computation[actor->get_pid()]);
- });
- XBT_DEBUG("Host load verification: %f", load_verif);
- }
- }
- for (auto& elem : actor_computation) { // Reset actor load
- elem.second = 0;
- }
-}
-
-s4u::Host* LoadBalancer::get_mapping(s4u::ActorPtr actor)
-{
- return new_mapping.get_host(actor);
-}
-
-void LoadBalancer::record_actor_computation(s4u::Actor const& actor, double load)
-{
- actor_computation[actor.get_pid()] += load;
-}
-} // namespace loadbalancer
-} // namespace plugin
-} // namespace simgrid
+++ /dev/null
-/* Copyright (c) 2006-2020. The SimGrid Team. All rights reserved. */
-
-/* This program is free software; you can redistribute it and/or modify it
- * under the terms of the license (GNU LGPL) which comes with this package. */
-
-#ifndef HAVE_SG_PLUGIN_LB
-#define HAVE_SG_PLUGIN_LB
-
-#include <simgrid/s4u.hpp>
-
-namespace simgrid {
-namespace plugin {
-namespace loadbalancer {
-
-class XBT_PRIVATE Mapping {
-public:
- /** Each host can have an arbitrary number of actors -> multimap **/
- typedef std::unordered_multimap<s4u::Host*, s4u::ActorPtr> host_to_actors_map_t;
- host_to_actors_map_t host_to_actors;
-
- /** Each actor gets assigned to exactly one host -> map **/
- std::map<s4u::ActorPtr, s4u::Host*> actor_to_host;
-
- void assign(s4u::ActorPtr actor, s4u::Host* host)
- {
- /* Remove "actor" from its old host -> get all elements that have the current host as key **/
- auto range = host_to_actors.equal_range(/* current host */actor_to_host[actor]);
- for (auto it = range.first; it != range.second; it++) {
- if (it->second == actor) {
- host_to_actors.erase(it); // unassign this actor
- break;
- }
- }
-
- actor_to_host[actor] = host;
- host_to_actors.insert({host, actor});
- }
-
- s4u::Host* get_host(s4u::ActorPtr actor) const { return actor_to_host.at(actor); }
-
- unsigned int count_actors(s4u::Host* host) const
- {
- return host_to_actors.count(host); // TODO This is linear in the size of the map. Maybe replace by constant lookup through another map?
- }
-
- void for_each_actor(s4u::Host* host, const std::function<void(s4u::ActorPtr)>& callback)
- {
- auto range = host_to_actors.equal_range(host);
- std::for_each(range.first, range.second,
- [&callback](host_to_actors_map_t::value_type const& x) { callback(x.second); });
- }
-};
-
-class XBT_PRIVATE LoadBalancer
-{
- Mapping new_mapping;
- std::map</*proc id*/int, double> actor_computation;
-
-public:
- void run();
- void assign(s4u::ActorPtr actor, s4u::Host* host);
-
- /** FIXME These are functions used for testing and should be re-written or removed */
- s4u::Host* get_mapping(s4u::ActorPtr);
- void record_actor_computation(s4u::Actor const& actor, double load);
-};
-
-} // namespace loadbalancer
-} // namespace plugin
-} // namespace simgrid
-#endif
+++ /dev/null
-/* Copyright (c) 2018-2020. 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/plugins/load_balancer.h>
-#include <simgrid/s4u.hpp>
-#include <simgrid/smpi/replay.hpp>
-#include <smpi/smpi.h>
-#include <src/smpi/include/smpi_comm.hpp>
-#include <src/smpi/include/smpi_actor.hpp>
-#include <src/smpi/plugins/ampi/instr_ampi.hpp>
-#include <src/smpi/plugins/ampi/ampi.hpp>
-#include <xbt/replay.hpp>
-
-#include "src/kernel/activity/ExecImpl.hpp"
-#include "src/kernel/actor/ActorImpl.hpp"
-#include "src/smpi/plugins/load_balancer/load_balancer.hpp" // This is not yet ready to be public
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(plugin_load_balancer, smpi, "Logging specific to the SMPI load balancing plugin");
-
-static simgrid::config::Flag<int> cfg_migration_frequency("smpi/plugin/lb/migration-frequency", {"smpi/plugin/lb/migration_frequency"},
- "After how many calls to the migration function should the migration be actually executed?", 10,
- [](double val){if (val != 10) sg_load_balancer_plugin_init();});
-
-namespace simgrid {
-namespace smpi {
-namespace plugin {
-
-static simgrid::plugin::loadbalancer::LoadBalancer lb;
-
-class MigrateParser : public replay::ActionArgParser {
-public:
- double memory_consumption;
- void parse(xbt::ReplayAction& action, const std::string&) override
- {
- // The only parameter is the amount of memory used by the current process.
- CHECK_ACTION_PARAMS(action, 1, 0);
- memory_consumption = std::stod(action[2]);
- }
-};
-
-/* This function simulates what happens when the original application calls (A)MPI_Migrate. It executes the load
- * balancing heuristics, makes the necessary migrations and updates the task mapping in the load balancer.
- */
-class MigrateAction : public replay::ReplayAction<smpi::plugin::MigrateParser> {
-public:
- explicit MigrateAction() : ReplayAction("Migrate") {}
- void kernel(xbt::ReplayAction&) override
- {
- static std::map<s4u::ActorPtr, int> migration_call_counter;
- static s4u::Barrier smpilb_bar(smpi_get_universe_size());
- s4u::Host* cur_host = s4u::this_actor::get_host();
- s4u::Host* migrate_to_host;
-
- TRACE_migration_call(get_pid(), nullptr);
-
- // We only migrate every "cfg_migration_frequency"-times, not at every call
- migration_call_counter[s4u::Actor::self()]++;
- if ((migration_call_counter[s4u::Actor::self()] % config::get_value<int>(cfg_migration_frequency.get_name())) !=
- 0) {
- return;
- }
-
- // TODO cheinrich: Why do we need this barrier?
- smpilb_bar.wait();
-
- static bool was_executed = false;
- if (not was_executed) {
- was_executed = true;
- XBT_DEBUG("Process %li runs the load balancer", get_pid());
- smpi_bench_begin();
- lb.run();
- smpi_bench_end();
- }
-
- // This barrier is required to ensure that the mapping has been computed and is available
- smpilb_bar.wait();
- was_executed = false; // Must stay behind this barrier so that all processes have passed the if clause
-
- migrate_to_host = lb.get_mapping(simgrid::s4u::Actor::self());
- if (cur_host != migrate_to_host) { // Origin and dest are not the same -> migrate
- std::vector<s4u::Host*> migration_hosts = {cur_host, migrate_to_host};
- std::vector<double> comp_amount = {0, 0};
- std::vector<double> comm_amount = {0, /*must not be 0*/ std::max(get_args().memory_consumption, 1.0), 0, 0};
-
- xbt_os_timer_t timer = smpi_process()->timer();
- xbt_os_threadtimer_start(timer);
- s4u::this_actor::parallel_execute(migration_hosts, comp_amount, comm_amount);
- xbt_os_threadtimer_stop(timer);
- smpi_execute(xbt_os_timer_elapsed(timer));
-
- // Update the process and host mapping in SimGrid.
- XBT_DEBUG("Migrating process %li from %s to %s", get_pid(), cur_host->get_cname(), migrate_to_host->get_cname());
- TRACE_smpi_process_change_host(get_pid(), migrate_to_host);
- s4u::this_actor::set_host(migrate_to_host);
- }
-
- smpilb_bar.wait();
-
- smpi_bench_begin();
- }
-};
-
-/******************************************************************************
- * Code to include the duration of iterations in the trace. *
- ******************************************************************************/
-
-// FIXME Move declaration
-XBT_PRIVATE void action_iteration_in(xbt::ReplayAction& action);
-void action_iteration_in(xbt::ReplayAction& action)
-{
- CHECK_ACTION_PARAMS(action, 0, 0)
- TRACE_Iteration_in(s4u::this_actor::get_pid(), nullptr);
- smpi::plugin::ampi::on_iteration_in(*MPI_COMM_WORLD->group()->actor(std::stol(action[0])));
-}
-
-XBT_PRIVATE void action_iteration_out(xbt::ReplayAction& action);
-void action_iteration_out(xbt::ReplayAction& action)
-{
- CHECK_ACTION_PARAMS(action, 0, 0)
- TRACE_Iteration_out(s4u::this_actor::get_pid(), nullptr);
- ampi::on_iteration_out(*MPI_COMM_WORLD->group()->actor(std::stol(action[0])));
-}
-} // namespace plugin
-} // namespace smpi
-} // namespace simgrid
-
-/** @ingroup plugin_loadbalancer
- * @brief Initializes the load balancer plugin
- * @details The load balancer plugin supports several AMPI load balancers that move ranks
- * around, based on their host's load.
- */
-void sg_load_balancer_plugin_init()
-{
- static bool done = false;
- if (!done) {
- done = true;
- simgrid::s4u::Exec::on_completion.connect([](simgrid::s4u::Actor const& actor, simgrid::s4u::Exec const& exec) {
- simgrid::smpi::plugin::lb.record_actor_computation(actor, exec.get_cost());
- });
-
- xbt_replay_action_register(
- "migrate", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::plugin::MigrateAction().execute(action); });
- xbt_replay_action_register("iteration_in", simgrid::smpi::plugin::action_iteration_in);
- xbt_replay_action_register("iteration_out", simgrid::smpi::plugin::action_iteration_out);
- }
-}
echo "Warning: smpicc pretends to be a regular compiler (SMPI_PRETEND_CC is set). Produced binaries will not be usable in SimGrid."
fi
if [ "x${SMPI_NO_UNDEFINED_CHECK}" = "x" ]; then
- list_add LINKARGS "-lsimgrid" ${LINKER_UNDEFINED_ERROR:+"-Wl,-undefined,error"}
+ list_add LINKARGS "-lsimgrid" "-lm" ${LINKER_UNDEFINED_ERROR:+"-Wl,-undefined,error"}
fi
else
list_add CFLAGS "-fPIC"
echo "Warning: smpicc pretends to be a regular compiler (SMPI_PRETEND_CC is set). Produced binaries will not be usable in SimGrid."
fi
if [ "x${SMPI_NO_UNDEFINED_CHECK}" = "x" ]; then
- list_add LINKARGS "-lsimgrid" ${LINKER_UNDEFINED_ERROR:+"-Wl,-z,defs"}
+ list_add LINKARGS "-lsimgrid" "-lm" ${LINKER_UNDEFINED_ERROR:+"-Wl,-z,defs"}
fi
fi
echo "Warning: smpicc pretends to be a regular compiler (SMPI_PRETEND_CC is set). Produced binaries will not be usable in SimGrid."
fi
if [ "x${SMPI_NO_UNDEFINED_CHECK}" = "x" ]; then
- list_add LINKARGS "-lsimgrid" ${LINKER_UNDEFINED_ERROR:+"-Wl,-undefined,error"}
+ list_add LINKARGS "-lsimgrid" "-lm" ${LINKER_UNDEFINED_ERROR:+"-Wl,-undefined,error"}
fi
else
list_add CXXFLAGS "-fPIC"
echo "Warning: smpicc pretends to be a regular compiler (SMPI_PRETEND_CC is set). Produced binaries will not be usable in SimGrid."
fi
if [ "x${SMPI_NO_UNDEFINED_CHECK}" = "x" ]; then
- list_add LINKARGS "-lsimgrid" ${LINKER_UNDEFINED_ERROR:+"-Wl,-z,defs"}
+ list_add LINKARGS "-lsimgrid" "-lm" ${LINKER_UNDEFINED_ERROR:+"-Wl,-z,defs"}
fi
fi
SIMOPTS="--cfg=surf/precision:1e-9 --cfg=network/model:SMPI"
+SMPITMPDIR="$(dirname $(mktemp -u))"
+
#usage to print the way this script should be called
usage () {
cat <<EOF
-np <numprocs> # use that amount of processes from the hostfile.
# By default, all processes of the hostfile are used.
-no-privatize # Disable the globals privatization, that is activated by default
+ -tmpdir # Directory used to store temporary files. Defaults to system's.
-trace-ti # activate time independent tracing (for replay, default in smpi_simgrid.txt)
-trace # activate tracing (Paje, default in smpi_simgrid.trace)
-trace-comment <comment> # put a comment on the top of the trace file
MAPOPT=1
shift 1
;;
+ "-tmpdir")
+ SMPITMPDIR="$2"
+ shift 1
+ ;;
"-trace")
TRACE_ACTIVE="true"
shift 1
esac
done
+#setup tmp dir
+SIMOPTS="$SIMOPTS --cfg=smpi/tmpdir:$SMPITMPDIR"
+export LD_LIBRARY_PATH="$SMPITMPDIR:$LD_LIBRARY_PATH"
+
if [ -n "${APP_TRACES}" ] ; then
if [ $# -eq 0 ] ; then
EXEC="@SMPIREPLAYMAIN@"
void HostImpl::set_disks(const std::vector<kernel::resource::DiskImpl*>& disks, s4u::Host* host)
{
- disks_ = std::move(disks);
+ disks_ = disks;
for (auto d : disks_)
d->set_host(host);
}
void remove_actor(kernel::actor::ActorImpl* actor) { xbt::intrusive_erase(actor_list_, *actor); }
void add_actor_at_boot(kernel::actor::ProcessArg* arg) { actors_at_boot_.emplace_back(arg); }
- typedef boost::intrusive::list<
+ using ActorList = boost::intrusive::list<
kernel::actor::ActorImpl,
boost::intrusive::member_hook<kernel::actor::ActorImpl, boost::intrusive::list_member_hook<>,
- &kernel::actor::ActorImpl::host_actor_list_hook>>
- ActorList;
+ &kernel::actor::ActorImpl::host_actor_list_hook>>;
// FIXME: make these private
ActorList actor_list_;
*/
class StorageImpl : public Resource, public xbt::PropertyHolder {
s4u::Storage piface_;
- lmm::Constraint* constraint_read_; /* Constraint for maximum write bandwidth*/
+ lmm::Constraint* constraint_read_; /* Constraint for maximum read bandwidth*/
lmm::Constraint* constraint_write_; /* Constraint for maximum write bandwidth*/
std::string typeId_;
*/
class XBT_PUBLIC CpuModel : public Model {
public:
- explicit CpuModel(Model::UpdateAlgo algo) : Model(algo) {}
+ using Model::Model;
/**
* @brief Create a Cpu
*/
static xbt::signal<void(CpuAction const&, Action::State)> on_state_change;
- CpuAction(Model* model, double cost, bool failed) : Action(model, cost, failed) {}
- CpuAction(Model* model, double cost, bool failed, lmm::Variable* var) : Action(model, cost, failed, var) {}
+ using Action::Action;
void set_state(Action::State state) override;
boost::intrusive::list_member_hook<> action_ti_hook;
};
-typedef boost::intrusive::member_hook<CpuTiAction, boost::intrusive::list_member_hook<>, &CpuTiAction::action_ti_hook> ActionTiListOptions;
-typedef boost::intrusive::list<CpuTiAction, ActionTiListOptions > ActionTiList;
+using ActionTiListOptions =
+ boost::intrusive::member_hook<CpuTiAction, boost::intrusive::list_member_hook<>, &CpuTiAction::action_ti_hook>;
+using ActionTiList = boost::intrusive::list<CpuTiAction, ActionTiListOptions>;
/************
* Resource *
boost::intrusive::list_member_hook<> cpu_ti_hook;
};
-typedef boost::intrusive::member_hook<CpuTi, boost::intrusive::list_member_hook<>, &CpuTi::cpu_ti_hook> CpuTiListOptions;
-typedef boost::intrusive::list<CpuTi, CpuTiListOptions> CpuTiList;
+using CpuTiListOptions =
+ boost::intrusive::member_hook<CpuTi, boost::intrusive::list_member_hook<>, &CpuTi::cpu_ti_hook>;
+using CpuTiList = boost::intrusive::list<CpuTi, CpuTiListOptions>;
/*********
* Model *
namespace kernel {
namespace resource {
-NetworkCm02Model::NetworkCm02Model(kernel::lmm::System* (*make_new_lmm_system)(bool))
+NetworkCm02Model::NetworkCm02Model()
: NetworkModel(simgrid::config::get_value<std::string>("network/optim") == "Full" ? Model::UpdateAlgo::FULL
: Model::UpdateAlgo::LAZY)
{
select = true;
}
- set_maxmin_system(make_new_lmm_system(select));
+ set_maxmin_system(new lmm::System(select));
loopback_ = NetworkCm02Model::create_link("__loopback__",
std::vector<double>{simgrid::config::get_value<double>("network/loopback-bw")},
simgrid::config::get_value<double>("network/loopback-lat"),
class NetworkCm02Model : public NetworkModel {
public:
- explicit NetworkCm02Model(lmm::System* (*make_new_sys)(bool) = &lmm::make_new_maxmin_system);
+ NetworkCm02Model();
~NetworkCm02Model() override = default;
LinkImpl* create_link(const std::string& name, const std::vector<double>& bandwidths, double latency,
s4u::Link::SharingPolicy policy) override;
friend Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate);
public:
- NetworkCm02Action(Model* model, s4u::Host& src, s4u::Host& dst, double cost, bool failed)
- : NetworkAction(model, src, dst, cost, failed){};
+ using NetworkAction::NetworkAction;
~NetworkCm02Action() override = default;
void update_remains_lazy(double now) override;
};
/** @brief Command-line option 'network/TCP-gamma' -- see @ref options_model_network_gamma */
simgrid::config::Flag<double> NetworkModel::cfg_tcp_gamma(
- "network/TCP-gamma", {"network/TCP_gamma"},
+ "network/TCP-gamma",
"Size of the biggest TCP window (cat /proc/sys/net/ipv4/tcp_[rw]mem for recv/send window; "
"Use the last given value, which is the max window size)",
4194304.0);
static config::Flag<double> cfg_tcp_gamma;
static config::Flag<bool> cfg_crosstraffic;
- explicit NetworkModel(Model::UpdateAlgo algo) : Model(algo) {}
+ using Model::Model;
NetworkModel(const NetworkModel&) = delete;
NetworkModel& operator=(const NetworkModel&) = delete;
~NetworkModel() override;
ns3_socket = elm.first;
SgFlow* sgFlow = elm.second;
NetworkNS3Action * action = sgFlow->action_;
- XBT_DEBUG("Processing socket %p (action %p)",sgFlow,action);
+ XBT_DEBUG("Processing flow %p (socket %s, action %p)", sgFlow, ns3_socket.c_str(), action);
// Because NS3 stops as soon as a flow is finished, the other flows that ends at the same time may remains in an
// inconsistent state (i.e. remains_ == 0 but finished_ == false).
// However, SimGrid considers sometimes that an action with remains_ == 0 is finished.
}
}
- static int port_number = 1025; // Port number is limited from 1025 to 65 000
+ static uint16_t port_number = 1;
ns3::Ptr<ns3::Node> src_node = src->get_netpoint()->extension<NetPointNs3>()->ns3_node_;
ns3::Ptr<ns3::Node> dst_node = dst->get_netpoint()->extension<NetPointNs3>()->ns3_node_;
sink_from_sock.insert({transform_socket_ptr(sock), apps});
sock->Bind(ns3::InetSocketAddress(port_number));
-
ns3::Simulator::ScheduleNow(&start_flow, sock, addr.c_str(), port_number);
- port_number++;
- if(port_number > 65000){
- port_number = 1025;
+ port_number = 1 + (port_number % UINT16_MAX);
+ if (port_number == 1)
XBT_WARN("Too many connections! Port number is saturated. Trying to use the oldest ports.");
- }
s4u::Link::on_communicate(*this);
}
int NetworkWifiLink::get_host_count() const
{
- return host_rates_.size();
+ return static_cast<int>(host_rates_.size());
}
void NetworkWifiLink::refresh_decay_bandwidths(){
XBT_DEBUG("Process %s@%s will be started at time %f", arg->name.c_str(), arg->host->get_cname(), start_time);
simgrid::simix::Timer::set(start_time, [arg, auto_restart]() {
simgrid::kernel::actor::ActorImplPtr new_actor = simgrid::kernel::actor::ActorImpl::create(
- arg->name.c_str(), std::move(arg->code), arg->data, arg->host, arg->properties.get(), nullptr);
+ arg->name.c_str(), arg->code, arg->data, arg->host, arg->properties.get(), nullptr);
if (arg->kill_time >= 0)
new_actor->set_kill_time(arg->kill_time);
if (auto_restart)
try {
simgrid::kernel::actor::ActorImplPtr new_actor = nullptr;
- new_actor = simgrid::kernel::actor::ActorImpl::create(arg->name.c_str(), std::move(code), nullptr, host,
+ new_actor = simgrid::kernel::actor::ActorImpl::create(arg->name.c_str(), code, nullptr, host,
arg->properties.get(), nullptr);
/* The actor creation will fail if the host is currently dead, but that's fine */
if (arg->kill_time >= 0)
/** @brief The list of all host models (pick one with --cfg=host/model:) */
XBT_PUBLIC_DATA const std::vector<surf_model_description_t> surf_host_model_description;
-/**********
- * Action *
- **********/
-
#endif /* SURF_MODEL_H_ */
double loopback_bw = 0;
double loopback_lat = 0;
double limiter_link = 0;
- ClusterTopology topology;
+ ClusterTopology topology = ClusterTopology::FLAT;
std::string topo_parameters;
- std::unordered_map<std::string, std::string>* properties;
+ std::unordered_map<std::string, std::string>* properties = nullptr;
std::string router_id;
- simgrid::s4u::Link::SharingPolicy sharing_policy;
- simgrid::s4u::Link::SharingPolicy bb_sharing_policy;
+ simgrid::s4u::Link::SharingPolicy sharing_policy = simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX;
+ simgrid::s4u::Link::SharingPolicy bb_sharing_policy = simgrid::s4u::Link::SharingPolicy::SHARED;
};
class CabinetCreationArgs {
break;
}
}
- surf_parse_error(std::move(msg));
+ surf_parse_error(msg);
}
double surf_parse_get_double(const std::string& s)
XBT_DEBUG("pstate: %s", A_surfxml_host_pstate);
host.core_amount = surf_parse_get_int(A_surfxml_host_core);
- host.speed_trace = nullptr;
if (A_surfxml_host_availability___file[0] != '\0') {
XBT_WARN("The availability_file attribute in <host> is now deprecated. Please, use 'speed_file' instead.");
host.speed_trace = simgrid::kernel::profile::Profile::from_file(A_surfxml_host_availability___file);
void ETag_surfxml_backbone(){
simgrid::kernel::routing::LinkCreationArgs link;
- link.properties = nullptr;
link.id = std::string(A_surfxml_backbone_id);
link.bandwidths.push_back(xbt_parse_get_bandwidth(
surf_parsed_filename, surf_parse_lineno, A_surfxml_backbone_bandwidth, "bandwidth of backbone", link.id.c_str()));
route.src = sg_netpoint_by_name_or_null(A_surfxml_route_src); // tested to not be nullptr in start tag
route.dst = sg_netpoint_by_name_or_null(A_surfxml_route_dst); // tested to not be nullptr in start tag
- route.gw_src = nullptr;
- route.gw_dst = nullptr;
- route.symmetrical = (A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES);
+ route.symmetrical = (A_surfxml_route_symmetrical == AU_surfxml_route_symmetrical ||
+ A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_YES ||
+ A_surfxml_route_symmetrical == A_surfxml_route_symmetrical_yes);
route.link_list.swap(parsed_link_list);
ASroute.link_list.swap(parsed_link_list);
- switch (A_surfxml_zoneRoute_symmetrical) {
- case AU_surfxml_zoneRoute_symmetrical:
- case A_surfxml_zoneRoute_symmetrical_YES:
- ASroute.symmetrical = true;
- break;
- case A_surfxml_zoneRoute_symmetrical_NO:
- ASroute.symmetrical = false;
- break;
- default:
- THROW_IMPOSSIBLE;
- }
+ ASroute.symmetrical = (A_surfxml_zoneRoute_symmetrical == AU_surfxml_zoneRoute_symmetrical ||
+ A_surfxml_zoneRoute_symmetrical == A_surfxml_zoneRoute_symmetrical_YES ||
+ A_surfxml_zoneRoute_symmetrical == A_surfxml_zoneRoute_symmetrical_yes);
sg_platf_new_route(&ASroute);
}
route.src = sg_netpoint_by_name_or_null(A_surfxml_bypassRoute_src); // tested to not be nullptr in start tag
route.dst = sg_netpoint_by_name_or_null(A_surfxml_bypassRoute_dst); // tested to not be nullptr in start tag
- route.gw_src = nullptr;
- route.gw_dst = nullptr;
route.symmetrical = false;
route.link_list.swap(parsed_link_list);
for (std::string key : keys) {
if (simgrid::config::is_default(key.c_str())) {
std::string cfg = key + ":" + current_property_set->at(key);
- simgrid::config::set_parse(std::move(cfg));
+ simgrid::config::set_parse(cfg);
} else
XBT_INFO("The custom configuration '%s' is already defined by user!", key.c_str());
}
namespace {
-static bool parse_bool(const char* value)
+bool parse_bool(const char* value)
{
for (const char* true_value : {"yes", "on", "true", "1"})
if (std::strcmp(true_value, value) == 0)
throw std::range_error("not a boolean");
}
-static double parse_double(const char* value)
+double parse_double(const char* value)
{
char* end;
errno = 0;
return res;
}
-static long int parse_long(const char* value)
+long int parse_long(const char* value)
{
char* end;
errno = 0;
#include "catch.hpp"
+#include <string>
+
constexpr int NB_ELEM = 5000;
TEST_CASE("xbt::dynar: generic C vector", "dynar")
SECTION("Dynars of strings")
{
unsigned int iter;
- char buf[1024];
char* s1;
char* s2;
d = xbt_dynar_new(sizeof(char*), &xbt_free_ref);
/* 1. Populate the dynar */
for (int i = 0; i < NB_ELEM; i++) {
- snprintf(buf, 1023, "%d", i);
- s1 = xbt_strdup(buf);
+ std::string val = std::to_string(i);
+ s1 = xbt_strdup(val.c_str());
xbt_dynar_push(d, &s1);
}
for (int i = 0; i < NB_ELEM; i++) {
- snprintf(buf, 1023, "%d", i);
+ std::string val = std::to_string(i);
xbt_dynar_shift(d, &s2);
- REQUIRE(not strcmp(buf, s2)); // The retrieved value is not the same than the injected one
+ REQUIRE(s2 == val); // The retrieved value is not the same than the injected one
xbt_free(s2);
}
xbt_dynar_free(&d); /* This code is used both as example and as regression test, so we try to */
INFO("==== Unshift, traverse and pop " << NB_ELEM << " strings");
d = xbt_dynar_new(sizeof(char**), &xbt_free_ref);
for (int i = 0; i < NB_ELEM; i++) {
- snprintf(buf, 1023, "%d", i);
- s1 = xbt_strdup(buf);
+ std::string val = std::to_string(i);
+ s1 = xbt_strdup(val.c_str());
xbt_dynar_unshift(d, &s1);
}
/* 2. Traverse the dynar with the macro */
xbt_dynar_foreach (d, iter, s1) {
- snprintf(buf, 1023, "%u", NB_ELEM - iter - 1);
- REQUIRE(not strcmp(buf, s1)); // The retrieved value is not the same than the injected one
+ std::string val = std::to_string(NB_ELEM - iter - 1);
+ REQUIRE(s1 == val); // The retrieved value is not the same than the injected one
}
/* 3. Traverse the dynar with the macro */
for (int i = 0; i < NB_ELEM; i++) {
- snprintf(buf, 1023, "%d", i);
+ std::string val = std::to_string(i);
xbt_dynar_pop(d, &s2);
- REQUIRE(not strcmp(buf, s2)); // The retrieved value is not the same than the injected one
+ REQUIRE(s2 == val); // The retrieved value is not the same than the injected one
xbt_free(s2);
}
/* 4. Free the resources */
INFO("==== Push " << NB_ELEM << " strings, insert " << (NB_ELEM / 5) << " strings in the middle, shift everything");
d = xbt_dynar_new(sizeof(char*), &xbt_free_ref);
for (int i = 0; i < NB_ELEM; i++) {
- snprintf(buf, 1023, "%d", i);
- s1 = xbt_strdup(buf);
+ std::string val = std::to_string(i);
+ s1 = xbt_strdup(val.c_str());
xbt_dynar_push(d, &s1);
}
for (int i = 0; i < NB_ELEM / 5; i++) {
- snprintf(buf, 1023, "%d", i);
- s1 = xbt_strdup(buf);
+ std::string val = std::to_string(i);
+ s1 = xbt_strdup(val.c_str());
xbt_dynar_insert_at(d, NB_ELEM / 2, &s1);
}
for (int i = 0; i < NB_ELEM / 2; i++) {
- snprintf(buf, 1023, "%d", i);
+ std::string val = std::to_string(i);
xbt_dynar_shift(d, &s2);
- REQUIRE(not strcmp(buf, s2)); // The retrieved value is not the same than the injected one at the beginning
+ REQUIRE(s2 == val); // The retrieved value is not the same than the injected one at the beginning
xbt_free(s2);
}
for (int i = (NB_ELEM / 5) - 1; i >= 0; i--) {
- snprintf(buf, 1023, "%d", i);
+ std::string val = std::to_string(i);
xbt_dynar_shift(d, &s2);
- REQUIRE(not strcmp(buf, s2)); // The retrieved value is not the same than the injected one in the middle
+ REQUIRE(s2 == val); // The retrieved value is not the same than the injected one in the middle
xbt_free(s2);
}
for (int i = NB_ELEM / 2; i < NB_ELEM; i++) {
- snprintf(buf, 1023, "%d", i);
+ std::string val = std::to_string(i);
xbt_dynar_shift(d, &s2);
- REQUIRE(not strcmp(buf, s2)); // The retrieved value is not the same than the injected one at the end
+ REQUIRE(s2 == val); // The retrieved value is not the same than the injected one at the end
xbt_free(s2);
}
xbt_dynar_free(&d); /* This code is used both as example and as regression test, so we try to */
<< ". free the rest");
d = xbt_dynar_new(sizeof(char*), &xbt_free_ref);
for (int i = 0; i < NB_ELEM; i++) {
- snprintf(buf, 1023, "%d", i);
- s1 = xbt_strdup(buf);
+ std::string val = std::to_string(i);
+ s1 = xbt_strdup(val.c_str());
xbt_dynar_push(d, &s1);
}
for (int i = 2 * (NB_ELEM / 5); i < 4 * (NB_ELEM / 5); i++) {
- snprintf(buf, 1023, "%d", i);
+ std::string val = std::to_string(i);
xbt_dynar_remove_at(d, 2 * (NB_ELEM / 5), &s2);
- REQUIRE(not strcmp(buf, s2)); // Remove a bad value
+ REQUIRE(s2 == val); // Remove a bad value
xbt_free(s2);
}
xbt_dynar_free(&d); /* end_of_doxygen */
auto name = simgrid::xbt::demangle(typeid(exception).name());
auto* with_context = dynamic_cast<const simgrid::Exception*>(&exception);
- if (with_context != nullptr)
+ if (with_context != nullptr) {
XBT_LOG(prio, "%s %s by %s/%d: %s", context, name.get(), with_context->throw_point().procname_.c_str(),
with_context->throw_point().pid_, exception.what());
- else
+ // Do we have a backtrace?
+ if (not simgrid::config::get_value<bool>("exception/cutpath")) {
+ auto backtrace = with_context->resolve_backtrace();
+ XBT_LOG(prio, " -> %s", backtrace.c_str());
+ }
+ } else {
XBT_LOG(prio, "%s %s: %s", context, name.get(), exception.what());
-
- // Do we have a backtrace?
- if (with_context != nullptr && not simgrid::config::get_value<bool>("exception/cutpath")) {
- auto backtrace = with_context->resolve_backtrace();
- XBT_LOG(prio, " -> %s", backtrace.c_str());
}
+ } catch (...) {
+ // Don't log exceptions we got when trying to log exception
+ XBT_LOG(prio, "Ignoring exception caught while while trying to log an exception!");
+ }
+ try {
// Do we have a nested exception?
auto* with_nested = dynamic_cast<const std::nested_exception*>(&exception);
- if (with_nested == nullptr || with_nested->nested_ptr() == nullptr)
- return;
- try {
+ if (with_nested != nullptr && with_nested->nested_ptr() != nullptr)
with_nested->rethrow_nested();
- } catch (const std::exception& nested_exception) {
- log_exception(prio, "Caused by", nested_exception);
- }
+ } catch (const std::exception& nested_exception) {
+ log_exception(prio, "Caused by", nested_exception);
+ } catch (...) {
// We could catch nested_exception or WithContextException but we don't bother:
- catch (...) {
- XBT_LOG(prio, "Caused by an unknown exception");
- }
- }
- catch (...) {
- // Don't log exceptions we got when trying to log exception
- XBT_LOG(prio, "Ignoring exception caught while while trying to log an exception!");
+ XBT_LOG(prio, "Caused by an unknown exception");
}
}
xbt_assert(cat->layout, "No valid layout for the appender of category %s", cat->name);
/* First, try with a static buffer */
- int done = 0;
+ bool done = false;
std::array<char, XBT_LOG_STATIC_BUFFER_SIZE> buff;
ev->buffer = buff.data();
ev->buffer_size = buff.size();
};
struct xbt_log_layout_s {
- int (*do_layout)(const s_xbt_log_layout_t* l, xbt_log_event_t event, const char* fmt);
+ bool (*do_layout)(const s_xbt_log_layout_t* l, xbt_log_event_t event, const char* fmt);
void (*free_)(const s_xbt_log_layout_t* l);
void *data;
};
abort();
}
- if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type)) {
+ if (size > ((size_t)1 << (type - 1)) && size <= ((size_t)1 << type)) {
/* The new size is the same kind of fragment. */
result = ptr;
{
SECTION("Using XBT_RNG_xbt")
{
+ simgrid::xbt::random::set_implem_xbt();
simgrid::xbt::random::set_mersenne_seed(12345);
REQUIRE_THAT(simgrid::xbt::random::exponential(25), EpsilonApprox(0.00291934351538427348));
REQUIRE(simgrid::xbt::random::uniform_int(1, 6) == 4);
int count; //negative for roll
long int limit;
};
-typedef struct xbt_log_append2_file_s* xbt_log_append2_file_t;
+using xbt_log_append2_file_t = xbt_log_append2_file_s*;
static constexpr const char* APPEND2_END_TOKEN = "\n[End of log]\n";
static constexpr const char* APPEND2_END_TOKEN_CLEAR = "\n ";
" when: %%d: date %%r: app. age\n"
" other: %%%%: %% %%n: new line %%e: plain space\n";
-#define check_overflow(len) \
- if ((rem_size -= (len)) > 0) { \
- p += (len); \
- } else \
- return 0
+#define check_overflow(len) \
+ if ((rem_size -= (len)) > 0) { \
+ p += (len); \
+ } else \
+ return false
#define set_sz_from_precision() \
if (true) { \
#define show_int(data) show_it((data), "d")
#define show_double(data) show_it((data), "f")
-static int xbt_log_layout_format_doit(const s_xbt_log_layout_t* l, xbt_log_event_t ev, const char* msg_fmt)
+static bool xbt_log_layout_format_doit(const s_xbt_log_layout_t* l, xbt_log_event_t ev, const char* msg_fmt)
{
char *p = ev->buffer;
int rem_size = ev->buffer_size;
auto* q = static_cast<char*>(l->data);
while (*q != '\0') {
- if (*q == '%') {
- q++;
- do {
- switch (*q) {
- case '\0':
- fprintf(stderr, "Layout format (%s) ending with %%\n", (char*)l->data);
- xbt_abort();
- case '%':
- *p = '%';
- check_overflow(1);
- break;
- case 'n': /* platform-dependant line separator; LOG4J compliant */
- *p = '\n';
- check_overflow(1);
- break;
- case 'e': /* plain space; SimGrid extension */
- *p = ' ';
- check_overflow(1);
- break;
- case '.': /* precision specifier */
- precision = static_cast<int>(strtol(q + 1, &q, 10));
- continue; /* conversion specifier still not found, continue reading */
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': /* length modifier */
- length = static_cast<int>(strtol(q, &q, 10));
- continue; /* conversion specifier still not found, continue reading */
- case 'c': /* category name; LOG4J compliant
- should accept a precision postfix to show the hierarchy */
- show_string(ev->cat->name);
- break;
- case 'p': /* priority name; LOG4J compliant */
- show_string(xbt_log_priority_names[ev->priority]);
- break;
- case 'h': /* host name; SimGrid extension */
- show_string(sg_host_self_get_name());
- break;
- case 't': /* thread/process name; LOG4J compliant */
- case 'P': /* process name; SimGrid extension */
- show_string(xbt_procname());
- break;
- case 'i': /* process PID name; SimGrid extension */
- show_int(xbt_getpid());
- break;
- case 'F': /* file name; LOG4J compliant */
- show_string(ev->fileName);
- break;
- case 'l': { /* location; LOG4J compliant */
- int sz;
- set_sz_from_precision();
- int len = snprintf(p, sz, "%s:%d", ev->fileName, ev->lineNum);
- check_overflow(std::min(sz, len));
- break;
- }
- case 'L': /* line number; LOG4J compliant */
- show_int(ev->lineNum);
- break;
- case 'M': /* method (ie, function) name; LOG4J compliant */
- show_string(ev->functionName);
- break;
- case 'd': /* date; LOG4J compliant */
- show_double(simgrid_get_clock());
- break;
- case 'r': /* application age; LOG4J compliant */
- show_double(simgrid_get_clock());
- break;
- case 'm': { /* user-provided message; LOG4J compliant */
- int sz;
- set_sz_from_precision();
- va_list ap;
- va_copy(ap, ev->ap);
- int len = vsnprintf(p, sz, msg_fmt, ap);
- va_end(ap);
- check_overflow(std::min(sz, len));
- break;
- }
- default:
- fprintf(stderr, ERRMSG, *q, (char*)l->data);
- xbt_abort();
- }
- break; /* done, continue normally */
- } while (true);
- } else {
+ if (*q != '%') {
*p = *q;
check_overflow(1);
+ q++;
+ continue;
}
+
+ // *q == '%'
+ q++;
+ do {
+ switch (*q) {
+ case '\0':
+ fprintf(stderr, "Layout format (%s) ending with %%\n", (char*)l->data);
+ xbt_abort();
+ case '%':
+ *p = '%';
+ check_overflow(1);
+ break;
+ case 'n': /* platform-dependant line separator; LOG4J compliant */
+ *p = '\n';
+ check_overflow(1);
+ break;
+ case 'e': /* plain space; SimGrid extension */
+ *p = ' ';
+ check_overflow(1);
+ break;
+ case '.': /* precision specifier */
+ precision = static_cast<int>(strtol(q + 1, &q, 10));
+ continue; /* conversion specifier still not found, continue reading */
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': /* length modifier */
+ length = static_cast<int>(strtol(q, &q, 10));
+ continue; /* conversion specifier still not found, continue reading */
+ case 'c': /* category name; LOG4J compliant
+ should accept a precision postfix to show the hierarchy */
+ show_string(ev->cat->name);
+ break;
+ case 'p': /* priority name; LOG4J compliant */
+ show_string(xbt_log_priority_names[ev->priority]);
+ break;
+ case 'h': /* host name; SimGrid extension */
+ show_string(sg_host_self_get_name());
+ break;
+ case 't': /* thread/process name; LOG4J compliant */
+ case 'P': /* process name; SimGrid extension */
+ show_string(xbt_procname());
+ break;
+ case 'i': /* process PID name; SimGrid extension */
+ show_int(xbt_getpid());
+ break;
+ case 'F': /* file name; LOG4J compliant */
+ show_string(ev->fileName);
+ break;
+ case 'l': { /* location; LOG4J compliant */
+ int sz;
+ set_sz_from_precision();
+ int len = snprintf(p, sz, "%s:%d", ev->fileName, ev->lineNum);
+ check_overflow(std::min(sz, len));
+ break;
+ }
+ case 'L': /* line number; LOG4J compliant */
+ show_int(ev->lineNum);
+ break;
+ case 'M': /* method (ie, function) name; LOG4J compliant */
+ show_string(ev->functionName);
+ break;
+ case 'd': /* date; LOG4J compliant */
+ case 'r': /* application age; LOG4J compliant */
+ show_double(simgrid_get_clock());
+ break;
+ case 'm': { /* user-provided message; LOG4J compliant */
+ int sz;
+ set_sz_from_precision();
+ va_list ap;
+ va_copy(ap, ev->ap);
+ int len = vsnprintf(p, sz, msg_fmt, ap);
+ va_end(ap);
+ check_overflow(std::min(sz, len));
+ break;
+ }
+ default:
+ fprintf(stderr, ERRMSG, *q, (char*)l->data);
+ xbt_abort();
+ }
+ break; /* done, continue normally */
+ } while (true);
q++;
}
*p = '\0';
- return 1;
+ return true;
}
static void xbt_log_layout_format_free(const s_xbt_log_layout_t* lay)
do { \
rem_size -= (len); \
if (rem_size <= 0) \
- return 0; \
+ return false; \
p += (len); \
} while (0)
-static int xbt_log_layout_simple_doit(const s_xbt_log_layout_t*, xbt_log_event_t ev, const char* fmt)
+static bool xbt_log_layout_simple_doit(const s_xbt_log_layout_t*, xbt_log_event_t ev, const char* fmt)
{
char *p = ev->buffer;
int rem_size = ev->buffer_size;
check_overflow(1);
*p = '\0';
- return 1;
+ return true;
}
xbt_log_layout_t xbt_log_layout_simple_new(const char*)
int xbt_initialized = 0;
simgrid::config::Flag<bool> cfg_dbg_clean_atexit{
"debug/clean-atexit",
- {"clean-atexit"},
+ {"clean-atexit"}, // XBT_ATTRIB_DEPRECATED_v327(option alias)
"Whether to cleanup SimGrid at exit. Disable it if your code segfaults after its end.",
true};
// if it's for me, I'm done
std::string evtname = action->front();
- if (evtname.compare(name) == 0) {
+ if (evtname.compare(name) == 0)
return action;
- } else {
- // Else, I have to store it for the relevant colleague
- std::queue<ReplayAction*>* otherqueue = nullptr;
- auto act = action_queues.find(evtname);
- if (act != action_queues.end()) {
- otherqueue = act->second;
- } else { // Damn. Create the queue of that guy
- otherqueue = new std::queue<ReplayAction*>();
- action_queues.insert({evtname, otherqueue});
- }
- otherqueue->push(action);
+
+ // Else, I have to store it for the relevant colleague
+ std::queue<ReplayAction*>* otherqueue = nullptr;
+ auto act = action_queues.find(evtname);
+ if (act != action_queues.end()) {
+ otherqueue = act->second;
+ } else { // Damn. Create the queue of that guy
+ otherqueue = new std::queue<ReplayAction*>();
+ action_queues.insert({evtname, otherqueue});
}
+ otherqueue->push(action);
}
// end of file reached while searching in vain for more work
} else {
#include "xbt/string.hpp"
#include <array>
-/** @brief Splits a string into a dynar of strings
- *
- * @param s: the string to split
- * @param sep: a string of all chars to consider as separator.
- *
- * By default (with sep=nullptr), these characters are used as separator:
- *
- * - " " (ASCII 32 (0x20)) space.
- * - "\t" (ASCII 9 (0x09)) tab.
- * - "\n" (ASCII 10 (0x0A)) line feed.
- * - "\r" (ASCII 13 (0x0D)) carriage return.
- * - "\0" (ASCII 0 (0x00)) nullptr.
- * - "\x0B" (ASCII 11 (0x0B)) vertical tab.
- */
-xbt_dynar_t xbt_str_split(const char *s, const char *sep)
-{
- xbt_dynar_t res = xbt_dynar_new(sizeof(char *), &xbt_free_ref);
- const char *sep_dflt = " \t\n\r\x0B";
- std::array<bool, 256> is_sep;
-
- /* check what are the separators */
- is_sep.fill(false);
- if (not sep) {
- while (*sep_dflt)
- is_sep[(unsigned char)*sep_dflt++] = true;
- } else {
- while (*sep)
- is_sep[(unsigned char)*sep++] = true;
- }
- is_sep[0] = true; /* End of string is also separator */
-
- /* Do the job */
- const char* p = s;
- const char* q = s;
- int done = 0;
-
- if (s[0] == '\0')
- return res;
-
- while (not done) {
- char *topush;
- while (not is_sep[(unsigned char)*q]) {
- q++;
- }
- if (*q == '\0')
- done = 1;
-
- topush = (char*) xbt_malloc(q - p + 1);
- memcpy(topush, p, q - p);
- topush[q - p] = '\0';
- xbt_dynar_push(res, &topush);
- p = ++q;
- }
-
- return res;
-}
-
/** @brief Just like @ref xbt_str_split_quoted (Splits a string into a dynar of strings), but without memory allocation
*
* The string passed as argument must be writable (not const)
xbt_dynar_t res = xbt_dynar_new(sizeof(char *), nullptr);
char* beg;
char* end; /* pointers around the parsed chunk */
- int in_simple_quote = 0;
- int in_double_quote = 0;
- int done = 0;
- int ctn = 0; /* Got something in this block */
+ bool in_simple_quote = false;
+ bool in_double_quote = false;
+ bool done = false;
+ bool ctn = false; /* Got something in this block */
if (s[0] == '\0')
return res;
while (not done) {
switch (*end) {
case '\\':
- ctn = 1;
+ ctn = true;
/* Protected char; move it closer */
memmove(end, end + 1, strlen(end));
if (*end == '\0')
end++; /* Pass the protected char */
break;
case '\'':
- ctn = 1;
+ ctn = true;
if (not in_double_quote) {
in_simple_quote = not in_simple_quote;
memmove(end, end + 1, strlen(end));
}
break;
case '"':
- ctn = 1;
+ ctn = true;
if (not in_simple_quote) {
in_double_quote = not in_double_quote;
memmove(end, end + 1, strlen(end));
}
if (in_simple_quote || in_double_quote) {
end++;
- } else {
- if (*end == '\0')
- done = 1;
-
- *end = '\0';
- if (ctn) {
- /* Found a separator. Push the string if contains something */
- xbt_dynar_push(res, &beg);
- }
- ctn = 0;
-
- if (done)
- break;
-
- beg = ++end;
- /* trim within the string, manually to speed things up */
- while (*beg == ' ')
- beg++;
- end = beg;
+ break;
+ }
+ if (*end == '\0')
+ done = true;
+
+ *end = '\0';
+ if (ctn) {
+ /* Found a separator. Push the string if contains something */
+ xbt_dynar_push(res, &beg);
}
+ ctn = false;
+
+ if (done)
+ break;
+
+ beg = ++end;
+ /* trim within the string, manually to speed things up */
+ while (*beg == ' ')
+ beg++;
+ end = beg;
break;
default:
- ctn = 1;
+ ctn = true;
end++;
}
}
ENDIF()
ADD_TESH(mc-random-bug-replay --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/mc/random-bug --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/mc/random-bug random-bug-replay.tesh)
+
+if(enable_coverage)
+ ADD_TEST(cover-mc-mutex-handling ${CMAKE_CURRENT_BINARY_DIR}/mutex-handling/mutex-handling ${CMAKE_HOME_DIRECTORY}/examples/platforms/small_platform.xml)
+endif()
static void basic_test(simgrid::dwarf::ExpressionContext const& state)
{
- try {
- std::array<Dwarf_Op, 60> ops;
+ std::array<Dwarf_Op, 60> ops;
- uintptr_t a = rnd_engine();
- uintptr_t b = rnd_engine();
+ uintptr_t a = rnd_engine();
+ uintptr_t b = rnd_engine();
- simgrid::dwarf::ExpressionStack stack;
+ simgrid::dwarf::ExpressionStack stack;
- bool caught_ex = false;
- try {
- ops[0].atom = DW_OP_drop;
- simgrid::dwarf::execute(ops.data(), 1, state, stack);
- } catch (const simgrid::dwarf::evaluation_error&) {
- caught_ex = true;
- }
- if (not caught_ex)
- fprintf(stderr, "Exception expected");
+ bool caught_ex = false;
+ try {
+ ops[0].atom = DW_OP_drop;
+ simgrid::dwarf::execute(ops.data(), 1, state, stack);
+ } catch (const simgrid::dwarf::evaluation_error&) {
+ caught_ex = true;
+ }
+ if (not caught_ex)
+ fprintf(stderr, "Exception expected");
+ try {
ops[0].atom = DW_OP_lit21;
simgrid::dwarf::execute(ops.data(), 1, state, stack);
assert(stack.size() == 1);
#!/usr/bin/env tesh
! expect return 1
! output display
-$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/mutex-handling ${srcdir:=.}/examples/platforms/small_platform.xml ${srcdir:=.}/teshsuite/mc/mutex-handling/mutex-handling_d.xml
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/mutex-handling ${srcdir:=.}/examples/platforms/small_platform.xml
! expect return 1
! output display
! timeout 30
-$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/without-mutex-handling ${srcdir:=.}/examples/platforms/small_platform.xml ${srcdir:=.}/teshsuite/mc/mutex-handling/mutex-handling_d.xml
+$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/without-mutex-handling ${srcdir:=.}/examples/platforms/small_platform.xml
XBT_LOG_NEW_DEFAULT_CATEGORY(random_bug, "For this example");
-enum { ABORT, ASSERT, PRINTF } behavior;
+enum class Behavior { ABORT, ASSERT, PRINTF };
+
+Behavior behavior;
/** A fake application with a bug occurring for some random values */
static void app()
int x = MC_random(0, 5);
int y = MC_random(0, 5);
- if (behavior == ASSERT) {
+ if (behavior == Behavior::ASSERT) {
MC_assert(x != 3 || y != 4);
- } else if (behavior == PRINTF) {
+ } else if (behavior == Behavior::PRINTF) {
if (x == 3 && y == 4)
XBT_ERROR("Error reached");
- } else { // behavior == ABORT
+ } else { // behavior == Behavior::ABORT
abort();
}
}
xbt_assert(argc == 3, "Usage: random-bug raise|assert <platformfile>");
if (strcmp(argv[1], "abort") == 0) {
XBT_INFO("Behavior: abort");
- behavior = ABORT;
+ behavior = Behavior::ABORT;
} else if (strcmp(argv[1], "assert") == 0) {
XBT_INFO("Behavior: assert");
- behavior = ASSERT;
+ behavior = Behavior::ASSERT;
} else if (strcmp(argv[1], "printf") == 0) {
XBT_INFO("Behavior: printf");
- behavior = PRINTF;
+ behavior = Behavior::PRINTF;
} else {
xbt_die("Please use either 'abort', 'assert' or 'printf' as first parameter, to specify what to do when the error "
"is found.");
host-on-off host-on-off-actors host-on-off-recv
basic-link-test evaluate-get-route-time evaluate-parse-time is-router
storage_client_server listen_async pid
- trace-integration)
+ trace-integration
+ vm-live-migration)
add_executable (${x} EXCLUDE_FROM_ALL ${x}/${x}.cpp)
target_link_libraries(${x} simgrid)
set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x})
## Some need to be run with all factories, some don't need tesh to run
foreach(x actor actor-autorestart actor-suspend
activity-lifecycle comm-get-sender wait-any-for
- cloud-interrupt-migration cloud-two-execs concurrent_rw)
+ cloud-interrupt-migration cloud-two-execs concurrent_rw
+ vm-live-migration)
set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${x}/${x}.tesh)
ADD_TESH_FACTORIES(tesh-s4u-${x} "thread;ucontext;raw;boost" --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/s4u/${x} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x} --setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_BINARY_DIR}/teshsuite/s4u/${x} ${CMAKE_HOME_DIRECTORY}/teshsuite/s4u/${x}/${x}.tesh)
endforeach()
# The output is not relevant
ADD_TEST(tesh-s4u-comm-pt2pt ${CMAKE_BINARY_DIR}/teshsuite/s4u/comm-pt2pt/comm-pt2pt ${CMAKE_HOME_DIRECTORY}/examples/platforms/cluster_backbone.xml)
+if(enable_coverage)
+ foreach (example evaluate-get-route-time evaluate-parse-time)
+ ADD_TEST(cover-${example} ${CMAKE_CURRENT_BINARY_DIR}/${example}/${example} ${CMAKE_HOME_DIRECTORY}/examples/platforms/g5k.xml)
+ endforeach()
+endif()
+
# NS-3 specific tests
if(SIMGRID_HAVE_NS3)
foreach(x ns3-simultaneous-send-rcv ns3-from-src-to-itself)
${CMAKE_CURRENT_SOURCE_DIR}/trace-integration/test-hbp1-c0s2-c1s1.xml
${CMAKE_CURRENT_SOURCE_DIR}/trace-integration/test-hbp1-c1s1-c1s2.xml
${CMAKE_CURRENT_SOURCE_DIR}/trace-integration/test-hbp1-c1s1-c3s2.xml
- ${CMAKE_CURRENT_SOURCE_DIR}/trace-integration/test-hbp2.5-hbp1.5.xml PARENT_SCOPE)
+ ${CMAKE_CURRENT_SOURCE_DIR}/trace-integration/test-hbp2.5-hbp1.5.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/vm-live-migration/platform.xml
+ PARENT_SCOPE)
int main(int argc, char** argv)
{
- const simgrid::s4u::Engine* engine = new simgrid::s4u::Engine(&argc, argv);
+ simgrid::s4u::Engine engine(&argc, argv);
- engine->load_platform(argv[1]);
+ engine.load_platform(argv[1]);
simgrid::s4u::Host* host = simgrid::s4u::Host::by_name("Tremblay");
simgrid::s4u::Actor::create("Suspender", host, Suspender());
receiver = simgrid::s4u::Actor::create("Receiver", host, Receiver());
- engine->run();
+ engine.run();
return 0;
}
XBT_INFO("Link count: %zu", links.size());
std::sort(links.begin(), links.end(), [](const simgrid::s4u::Link* a, const simgrid::s4u::Link* b) {
- return strcmp(sg_link_name(a), sg_link_name(b)) < 0;
+ return strcmp(sg_link_get_name(a), sg_link_get_name(b)) < 0;
});
for (const auto& l : links) {
static void run_test_process(const std::string& name, simgrid::s4u::Host* location, int size)
{
std::vector<std::string> arg = {std::to_string(size)};
- simgrid::s4u::Actor::create(std::move(name), location, computation_fun, arg);
+ simgrid::s4u::Actor::create(name, location, computation_fun, arg);
}
static void test_energy_consumption(const std::string& name, int nb_cores)
/*
for i in $(seq 1 20); do
- teshsuite/s4u/evaluate-get-route-time/evaluate-get-route-time examples/platforms/cluster_backbone.xml 1
+ teshsuite/s4u/evaluate-get-route-time/evaluate-get-route-time examples/platforms/cluster_backbone.xml
sleep 1
done
*/
--- /dev/null
+<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+ <zone id="world" routing="Full">
+ <host id="host1" speed="1Gf" core="1">
+ <prop id="wattage_per_state" value="0.0:0.0:4.0" />
+ <prop id="wattage_off" value="0.0" />
+ </host>
+
+ <host id="host2" speed="2Gf" core="1">
+ <prop id="wattage_per_state" value="0.0:0.0:4.0" />
+ <prop id="wattage_off" value="0.0" />
+ </host>
+
+ <link bandwidth="1.25GBps" id="link" latency="0" sharing_policy="FATPIPE" />
+
+ <route src="host1" dst="host2">
+ <link_ctn id="link" />
+ </route>
+</zone>
+</platform>
--- /dev/null
+/* Copyright (c) 2007-2020. 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/plugins/energy.h"
+#include "simgrid/plugins/live_migration.h"
+#include "simgrid/s4u.hpp"
+#include <cmath>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(example, "Messages specific for this example");
+
+static void task_executor()
+{
+ simgrid::s4u::ExecPtr ptr = simgrid::s4u::this_actor::exec_init(3000000000.0)->start();
+
+ // ptr->test(); // Harmless
+ simgrid::s4u::this_actor::sleep_for(3); // Breaks everything
+
+ ptr->wait();
+ const auto* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(ptr->get_host());
+ xbt_assert(vm != nullptr, "Hey, I expected to run on a VM");
+ XBT_INFO("Task done. It's running on %s@%s that runs at %.0ef/s. host2 runs at %.0ef/s", vm->get_cname(),
+ vm->get_pm()->get_cname(), vm->get_speed(), simgrid::s4u::Host::by_name("host2")->get_speed());
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ simgrid::s4u::Engine::set_config("network/model:CM02"); // Much less realistic, but easier to compute manually
+
+ sg_vm_live_migration_plugin_init();
+ sg_host_energy_plugin_init();
+
+ xbt_assert(argc == 2, "Usage: %s platform.xml\n", argv[0]);
+
+ e.load_platform(argv[1]);
+ auto* pm = simgrid::s4u::Host::by_name("host1");
+ auto* vm = new simgrid::s4u::VirtualMachine("VM0", pm, 1 /*nCores*/);
+ vm->set_ramsize(1250000000)->start();
+ simgrid::s4u::Actor::create("executor", vm, task_executor);
+
+ simgrid::s4u::Actor::create("migration", pm, [vm]() {
+ XBT_INFO("%s migration started", vm->get_cname());
+ const auto* old = vm->get_pm();
+
+ sg_vm_migrate(vm, simgrid::s4u::Host::by_name("host2"));
+
+ XBT_INFO("VM '%s' migrated from '%s' to '%s'", vm->get_cname(), old->get_cname(), vm->get_pm()->get_cname());
+ });
+
+ e.run();
+ return 0;
+}
--- /dev/null
+
+$ ./vm-live-migration ${srcdir}/platform.xml
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'CM02'
+> [host1:migration:(2) 0.000000] [example/INFO] VM0 migration started
+> [host1:migration:(2) 1.000000] [example/INFO] VM 'VM0' migrated from 'host1' to 'host2'
+> [VM0:executor:(1) 3.000000] [example/INFO] Task done. It's running on VM0@host2 that runs at 2e+09f/s. host2 runs at 2e+09f/s
+> [3.000000] [surf_energy/INFO] Total energy consumption: 8.000000 Joules (used hosts: 8.000000 Joules; unused/idle hosts: 0.000000)
+> [3.000000] [surf_energy/INFO] Energy consumption of host host1: 4.000000 Joules
+> [3.000000] [surf_energy/INFO] Energy consumption of host host2: 4.000000 Joules
#include <stdio.h>
#include "simgrid/simdag.h"
-int main(int argc, char **argv)
+static void test_one_link(const sg_host_t* hosts)
{
- SD_init(&argc, argv);
-
- /* creation of the environment */
- SD_create_environment(argv[1]);
- fprintf(stderr, "Workstation number: %zu, link number: %d\n", sg_host_count(), sg_link_count());
+ const_sg_host_t h1 = hosts[0];
+ const_sg_host_t h2 = hosts[1];
+ const char* name1 = sg_host_get_name(h1);
+ const char* name2 = sg_host_get_name(h2);
- sg_host_t *hosts = sg_host_list();
- if (argc >= 3) {
- if (!strcmp(argv[2], "ONE_LINK")) {
- const_sg_host_t h1 = hosts[0];
- const_sg_host_t h2 = hosts[1];
- const char *name1 = sg_host_get_name(h1);
- const char *name2 = sg_host_get_name(h2);
+ fprintf(stderr, "Route between %s and %s\n", name1, name2);
+ xbt_dynar_t route = xbt_dynar_new(sizeof(SD_link_t), NULL);
+ sg_host_get_route(h1, h2, route);
+ fprintf(stderr, "Route size %lu\n", xbt_dynar_length(route));
+ unsigned int i;
+ SD_link_t link;
+ xbt_dynar_foreach (route, i, link)
+ fprintf(stderr, " Link %s: latency = %f, bandwidth = %f\n", sg_link_get_name(link), sg_link_get_latency(link),
+ sg_link_get_bandwidth(link));
+ fprintf(stderr, "Route latency = %f, route bandwidth = %f\n", sg_host_get_route_latency(h1, h2),
+ sg_host_get_route_bandwidth(h1, h2));
+ xbt_dynar_free_container(&route);
+}
+static void test_full_link(const sg_host_t* hosts)
+{
+ size_t list_size = sg_host_count();
+ for (size_t i = 0; i < list_size; i++) {
+ const_sg_host_t h1 = hosts[i];
+ const char* name1 = sg_host_get_name(h1);
+ for (size_t j = 0; j < list_size; j++) {
+ const_sg_host_t h2 = hosts[j];
+ const char* name2 = sg_host_get_name(h2);
fprintf(stderr, "Route between %s and %s\n", name1, name2);
xbt_dynar_t route = xbt_dynar_new(sizeof(SD_link_t), NULL);
- sg_host_route(h1, h2, route);
- fprintf(stderr, "Route size %lu\n", xbt_dynar_length(route));
- unsigned int i;
+ sg_host_get_route(h1, h2, route);
+ fprintf(stderr, " Route size %lu\n", xbt_dynar_length(route));
+ unsigned int k;
SD_link_t link;
- xbt_dynar_foreach(route, i, link)
- fprintf(stderr, " Link %s: latency = %f, bandwidth = %f\n", sg_link_name(link),
- sg_link_latency(link), sg_link_bandwidth(link));
- fprintf(stderr, "Route latency = %f, route bandwidth = %f\n",
- sg_host_route_latency(h1, h2), sg_host_route_bandwidth(h1, h2));
+ xbt_dynar_foreach (route, k, link)
+ fprintf(stderr, " Link %s: latency = %f, bandwidth = %f\n", sg_link_get_name(link), sg_link_get_latency(link),
+ sg_link_get_bandwidth(link));
+ fprintf(stderr, " Route latency = %f, route bandwidth = %f\n", sg_host_get_route_latency(h1, h2),
+ sg_host_get_route_bandwidth(h1, h2));
xbt_dynar_free_container(&route);
}
- if (!strcmp(argv[2], "FULL_LINK")) {
- size_t list_size = sg_host_count();
- for (size_t i = 0; i < list_size; i++) {
- const_sg_host_t h1 = hosts[i];
- const char *name1 = sg_host_get_name(h1);
- for (size_t j = 0; j < list_size; j++) {
- const_sg_host_t h2 = hosts[j];
- const char *name2 = sg_host_get_name(h2);
- fprintf(stderr, "Route between %s and %s\n", name1, name2);
- xbt_dynar_t route = xbt_dynar_new(sizeof(SD_link_t), NULL);
- sg_host_route(h1, h2, route);
- fprintf(stderr, " Route size %lu\n", xbt_dynar_length(route));
- unsigned int k;
- SD_link_t link;
- xbt_dynar_foreach(route, k, link)
- fprintf(stderr, " Link %s: latency = %f, bandwidth = %f\n",
- sg_link_name(link), sg_link_latency(link), sg_link_bandwidth(link));
- fprintf(stderr, " Route latency = %f, route bandwidth = %f\n",
- sg_host_route_latency(h1, h2), sg_host_route_bandwidth(h1, h2));
- xbt_dynar_free_container(&route);
- }
- }
- }
+ }
+}
+
+int main(int argc, char** argv)
+{
+ SD_init(&argc, argv);
+
+ /* creation of the environment */
+ SD_create_environment(argv[1]);
+ fprintf(stderr, "Workstation number: %zu, link number: %d\n", sg_host_count(), sg_link_count());
+
+ sg_host_t* hosts = sg_host_list();
+ if (argc >= 3) {
+ if (!strcmp(argv[2], "ONE_LINK"))
+ test_one_link(hosts);
+ if (!strcmp(argv[2], "FULL_LINK"))
+ test_full_link(hosts);
if (!strcmp(argv[2], "PROP"))
fprintf(stderr,"SG_TEST_mem: %s\n", sg_host_get_property_value(sg_host_by_name("host1"), "SG_TEST_mem"));
}
[](const_sg_host_t a, const_sg_host_t b) { return strcmp(sg_host_get_name(a), sg_host_get_name(b)) < 0; });
for (size_t i = 0; i < totalHosts; i++) {
- std::printf(" <host id=\"%s\" speed=\"%.0f\"", hosts[i]->get_cname(), sg_host_speed(hosts[i]));
+ std::printf(" <host id=\"%s\" speed=\"%.0f\"", hosts[i]->get_cname(), sg_host_get_speed(hosts[i]));
const std::unordered_map<std::string, std::string>* props = hosts[i]->get_properties();
if (hosts[i]->get_core_count() > 1) {
std::printf(" core=\"%d\"", hosts[i]->get_core_count());
simgrid::s4u::Link** links = sg_link_list();
std::sort(links, links + totalLinks, [](const simgrid::s4u::Link* a, const simgrid::s4u::Link* b) {
- return strcmp(sg_link_name(a), sg_link_name(b)) < 0;
+ return strcmp(sg_link_get_name(a), sg_link_get_name(b)) < 0;
});
for (size_t i = 0; i < totalLinks; i++) {
std::vector<simgrid::kernel::resource::LinkImpl*> route;
simgrid::kernel::routing::NetPoint* dst = host2->get_netpoint();
simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr);
- if (not route.empty()) {
- std::printf(" <route src=\"%s\" dst=\"%s\">\n ", host1->get_cname(), host2->get_cname());
- for (auto const& link : route)
- std::printf("<link_ctn id=\"%s\"/>", link->get_cname());
- std::printf("\n </route>\n");
- }
+ if (route.empty())
+ continue;
+ std::printf(" <route src=\"%s\" dst=\"%s\">\n ", host1->get_cname(), host2->get_cname());
+ for (auto const& link : route)
+ std::printf("<link_ctn id=\"%s\"/>", link->get_cname());
+ std::printf("\n </route>\n");
}
for (auto const& dst : netpoints) { // to router
- if (dst->is_router()) {
- std::printf(" <route src=\"%s\" dst=\"%s\">\n ", host1->get_cname(), dst->get_cname());
- std::vector<simgrid::kernel::resource::LinkImpl*> route;
- simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr);
- for (auto const& link : route)
- std::printf("<link_ctn id=\"%s\"/>", link->get_cname());
- std::printf("\n </route>\n");
- }
+ if (not dst->is_router())
+ continue;
+ std::printf(" <route src=\"%s\" dst=\"%s\">\n ", host1->get_cname(), dst->get_cname());
+ std::vector<simgrid::kernel::resource::LinkImpl*> route;
+ simgrid::kernel::routing::NetZoneImpl::get_global_route(src, dst, route, nullptr);
+ for (auto const& link : route)
+ std::printf("<link_ctn id=\"%s\"/>", link->get_cname());
+ std::printf("\n </route>\n");
}
}
for (auto const& value1 : netpoints) { // Routes from router
- if (value1->is_router()) {
- for (auto const& value2 : netpoints) { // to router
- if (value2->is_router()) {
- std::printf(" <route src=\"%s\" dst=\"%s\">\n ", value1->get_cname(), value2->get_cname());
- std::vector<simgrid::kernel::resource::LinkImpl*> route;
- simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, value2, route, nullptr);
- for (auto const& link : route)
- std::printf("<link_ctn id=\"%s\"/>", link->get_cname());
- std::printf("\n </route>\n");
- }
- }
- for (unsigned int it_dst = 0; it_dst < totalHosts; it_dst++) { // Routes to host
- const simgrid::s4u::Host* host2 = hosts[it_dst];
- std::printf(" <route src=\"%s\" dst=\"%s\">\n ", value1->get_cname(), host2->get_cname());
- std::vector<simgrid::kernel::resource::LinkImpl*> route;
- simgrid::kernel::routing::NetPoint* netcardDst = host2->get_netpoint();
- simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, netcardDst, route, nullptr);
- for (auto const& link : route)
- std::printf("<link_ctn id=\"%s\"/>", link->get_cname());
- std::printf("\n </route>\n");
- }
+ if (not value1->is_router())
+ continue;
+ for (auto const& value2 : netpoints) { // to router
+ if (not value2->is_router())
+ continue;
+ std::printf(" <route src=\"%s\" dst=\"%s\">\n ", value1->get_cname(), value2->get_cname());
+ std::vector<simgrid::kernel::resource::LinkImpl*> route;
+ simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, value2, route, nullptr);
+ for (auto const& link : route)
+ std::printf("<link_ctn id=\"%s\"/>", link->get_cname());
+ std::printf("\n </route>\n");
+ }
+ for (unsigned int it_dst = 0; it_dst < totalHosts; it_dst++) { // Routes to host
+ const simgrid::s4u::Host* host2 = hosts[it_dst];
+ std::printf(" <route src=\"%s\" dst=\"%s\">\n ", value1->get_cname(), host2->get_cname());
+ std::vector<simgrid::kernel::resource::LinkImpl*> route;
+ simgrid::kernel::routing::NetPoint* netcardDst = host2->get_netpoint();
+ simgrid::kernel::routing::NetZoneImpl::get_global_route(value1, netcardDst, route, nullptr);
+ for (auto const& link : route)
+ std::printf("<link_ctn id=\"%s\"/>", link->get_cname());
+ std::printf("\n </route>\n");
}
}
xbt_free(hosts);
static void thread_create_wrapper(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[])
{
int the_global_rank = global_rank;
- struct threadwrap* t = (struct threadwrap*)sg_actor_self_data();
+ struct threadwrap* t = (struct threadwrap*)sg_actor_self_get_data();
XBT_INFO("new thread has parameter rank %d and global variable rank %d", ((struct param*)(t->param))->rank,
the_global_rank);
SMPI_thread_create();
threadwrap->f = f;
threadwrap->param = param;
sg_actor_t actor = sg_actor_init(name, sg_host_self());
- sg_actor_data_set(actor, threadwrap);
+ sg_actor_set_data(actor, threadwrap);
sg_actor_start(actor, thread_create_wrapper, 0, NULL);
}
C
C (C) 2003 by Argonne National Laboratory.
C See COPYRIGHT in top-level directory.
+C
+ subroutine uop( cin, cout, count, datatype )
+ implicit none
+ include 'mpif.h'
+ integer cin(*), cout(*)
+ integer count, datatype
+ integer i
+
+ if (.false.) then
+ if (datatype .ne. MPI_INTEGER) then
+ write(6,*) 'Invalid datatype passed to user_op()'
+ return
+ endif
+ endif
+
+ do i=1, count
+ cout(i) = cin(i) + cout(i)
+ enddo
+ end
C
program main
implicit none
call mtest_finalize( errs )
call mpi_finalize( ierr )
end
-C
- subroutine uop( cin, cout, count, datatype )
- implicit none
- include 'mpif.h'
- integer cin(*), cout(*)
- integer count, datatype
- integer i
-
- if (.false.) then
- if (datatype .ne. MPI_INTEGER) then
- write(6,*) 'Invalid datatype passed to user_op()'
- return
- endif
- endif
-
- do i=1, count
- cout(i) = cin(i) + cout(i)
- enddo
- end
C
C (C) 2011 by Argonne National Laboratory.
C See COPYRIGHT in top-level directory.
+C
+ subroutine uop( cin, cout, count, datatype )
+ implicit none
+ include 'mpif.h'
+ integer cin(*), cout(*)
+ integer count, datatype
+ integer i
+
+ if (.false.) then
+ if (datatype .ne. MPI_INTEGER) then
+ write(6,*) 'Invalid datatype ',datatype,
+ & ' passed to user_op()'
+ return
+ endif
+ endif
+
+ do i=1, count
+ cout(i) = cin(i) + cout(i)
+ enddo
+ end
C
C Test of reduce scatter.
C
call mpi_finalize( ierr )
end
-C
- subroutine uop( cin, cout, count, datatype )
- implicit none
- include 'mpif.h'
- integer cin(*), cout(*)
- integer count, datatype
- integer i
-
- if (.false.) then
- if (datatype .ne. MPI_INTEGER) then
- write(6,*) 'Invalid datatype ',datatype,
- & ' passed to user_op()'
- return
- endif
- endif
-
- do i=1, count
- cout(i) = cin(i) + cout(i)
- enddo
- end
C
C Test Fortran MPI_Reduce_local with MPI_OP_SUM and with user-defined operation.
C
+ subroutine user_op( invec, outvec, count, datatype )
+ implicit none
+ include 'mpif.h'
+ integer invec(*), outvec(*)
+ integer count, datatype
+ integer ii
+
+ if (datatype .ne. MPI_INTEGER) then
+ write(6,*) 'Invalid datatype passed to user_op()'
+ return
+ endif
+
+ do ii=1, count
+ outvec(ii) = invec(ii) * 2 + outvec(ii)
+ enddo
+
+ end
+
program main
implicit none
include 'mpif.h'
call mpi_finalize(ierr)
end
-
- subroutine user_op( invec, outvec, count, datatype )
- implicit none
- include 'mpif.h'
- integer invec(*), outvec(*)
- integer count, datatype
- integer ii
-
- if (datatype .ne. MPI_INTEGER) then
- write(6,*) 'Invalid datatype passed to user_op()'
- return
- endif
-
- do ii=1, count
- outvec(ii) = invec(ii) * 2 + outvec(ii)
- enddo
-
- end
C
C Test user-defined operations. This tests a simple commutative operation
C
+ subroutine uop( cin, cout, count, datatype )
+ implicit none
+ include 'mpif.h'
+ integer cin(*), cout(*)
+ integer count, datatype
+ integer i
+
+C if (datatype .ne. MPI_INTEGER) then
+C print *, 'Invalid datatype (',datatype,') passed to user_op()'
+C return
+C endif
+
+ do i=1, count
+ cout(i) = cin(i) + cout(i)
+ enddo
+ end
+
program main
implicit none
include 'mpif.h'
call mtest_finalize(errs)
call mpi_finalize(ierr)
end
-
- subroutine uop( cin, cout, count, datatype )
- implicit none
- include 'mpif.h'
- integer cin(*), cout(*)
- integer count, datatype
- integer i
-
-C if (datatype .ne. MPI_INTEGER) then
-C print *, 'Invalid datatype (',datatype,') passed to user_op()'
-C return
-C endif
-
- do i=1, count
- cout(i) = cin(i) + cout(i)
- enddo
- end
!
! (C) 2003 by Argonne National Laboratory.
! See COPYRIGHT in top-level directory.
+!
+ subroutine uop( cin, cout, count, datatype )
+ use mpi
+ integer cin(*), cout(*)
+ integer count, datatype
+ integer i
+
+ if (.false.) then
+ if (datatype .ne. MPI_INTEGER) then
+ write(6,*) 'Invalid datatype passed to user_op()'
+ return
+ endif
+ endif
+
+ do i=1, count
+ cout(i) = cin(i) + cout(i)
+ enddo
+ end
!
program main
use mpi
call mtest_finalize( errs )
call mpi_finalize( ierr )
end
-!
- subroutine uop( cin, cout, count, datatype )
- use mpi
- integer cin(*), cout(*)
- integer count, datatype
- integer i
-
- if (.false.) then
- if (datatype .ne. MPI_INTEGER) then
- write(6,*) 'Invalid datatype passed to user_op()'
- return
- endif
- endif
-
- do i=1, count
- cout(i) = cin(i) + cout(i)
- enddo
- end
! (C) 2011 by Argonne National Laboratory.
! See COPYRIGHT in top-level directory.
!
+ subroutine uop( cin, cout, count, datatype )
+ use mpi
+ integer cin(*), cout(*)
+ integer count, datatype
+ integer i
+
+ if (.false.) then
+ if (datatype .ne. MPI_INTEGER) then
+ write(6,*) 'Invalid datatype ',datatype,' passed to user_op()'
+ return
+ endif
+ endif
+
+ do i=1, count
+ cout(i) = cin(i) + cout(i)
+ enddo
+ end
!
! Test of reduce scatter.
!
call mpi_finalize( ierr )
end
-
- subroutine uop( cin, cout, count, datatype )
- use mpi
- integer cin(*), cout(*)
- integer count, datatype
- integer i
-
- if (.false.) then
- if (datatype .ne. MPI_INTEGER) then
- write(6,*) 'Invalid datatype ',datatype,' passed to user_op()'
- return
- endif
- endif
-
- do i=1, count
- cout(i) = cin(i) + cout(i)
- enddo
- end
!
! Test Fortran MPI_Reduce_local with MPI_OP_SUM and with user-defined operation.
!
+ subroutine user_op( invec, outvec, count, datatype )
+ use mpi
+ integer invec(*), outvec(*)
+ integer count, datatype
+ integer ii
+
+ if (datatype .ne. MPI_INTEGER) then
+ write(6,*) 'Invalid datatype passed to user_op()'
+ return
+ endif
+
+ do ii=1, count
+ outvec(ii) = invec(ii) * 2 + outvec(ii)
+ enddo
+
+ end
+
program main
use mpi
integer max_buf_size
call mpi_finalize(ierr)
end
-
- subroutine user_op( invec, outvec, count, datatype )
- use mpi
- integer invec(*), outvec(*)
- integer count, datatype
- integer ii
-
- if (datatype .ne. MPI_INTEGER) then
- write(6,*) 'Invalid datatype passed to user_op()'
- return
- endif
-
- do ii=1, count
- outvec(ii) = invec(ii) * 2 + outvec(ii)
- enddo
-
- end
!
! Test user-defined operations. This tests a simple commutative operation
!
+ subroutine uop( cin, cout, count, datatype )
+ use mpi
+ integer cin(*), cout(*)
+ integer count, datatype
+ integer i
+
+ if (datatype .ne. MPI_INTEGER) then
+ print *, 'Invalid datatype (',datatype,') passed to user_op()'
+ return
+ endif
+
+ do i=1, count
+ cout(i) = cin(i) + cout(i)
+ enddo
+ end
+
program main
use mpi
external uop
call mtest_finalize(errs)
call mpi_finalize(ierr)
end
-
- subroutine uop( cin, cout, count, datatype )
- use mpi
- integer cin(*), cout(*)
- integer count, datatype
- integer i
-
- if (datatype .ne. MPI_INTEGER) then
- print *, 'Invalid datatype (',datatype,') passed to user_op()'
- return
- endif
-
- do i=1, count
- cout(i) = cin(i) + cout(i)
- enddo
- end
switch (ret) {
case 0:
- found++;
- break;
case 's':
found ++;
break;
switch (ret) {
case 0:
- found++;
- break;
case 's':
found ++;
break;
int main(int argc, char **argv)
{
int rank;
- struct { int a;int c; double b;int tab[2][3];} value;
+ struct {
+ int a;
+ int c;
+ double b;
+ int tab[2][3];
+ } value = {0};
MPI_Datatype mystruct;
int blocklens[3];
MPI_Aint indices[3];
double a = 1.0;
double b = 10.0;
- lmm::System* Sys = lmm::make_new_maxmin_system(false);
- lmm::Constraint* L1 = Sys->constraint_new(nullptr, a);
- lmm::Constraint* L2 = Sys->constraint_new(nullptr, b);
- lmm::Constraint* L3 = Sys->constraint_new(nullptr, a);
+ lmm::System Sys(false);
+ lmm::Constraint* L1 = Sys.constraint_new(nullptr, a);
+ lmm::Constraint* L2 = Sys.constraint_new(nullptr, b);
+ lmm::Constraint* L3 = Sys.constraint_new(nullptr, a);
- lmm::Variable* R_1_2_3 = Sys->variable_new(nullptr, 1.0, -1.0, 3);
- lmm::Variable* R_1 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
- lmm::Variable* R_2 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
- lmm::Variable* R_3 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
+ lmm::Variable* R_1_2_3 = Sys.variable_new(nullptr, 1.0, -1.0, 3);
+ lmm::Variable* R_1 = Sys.variable_new(nullptr, 1.0, -1.0, 1);
+ lmm::Variable* R_2 = Sys.variable_new(nullptr, 1.0, -1.0, 1);
+ lmm::Variable* R_3 = Sys.variable_new(nullptr, 1.0, -1.0, 1);
- Sys->update_variable_penalty(R_1_2_3, 1.0);
- Sys->update_variable_penalty(R_1, 1.0);
- Sys->update_variable_penalty(R_2, 1.0);
- Sys->update_variable_penalty(R_3, 1.0);
+ Sys.update_variable_penalty(R_1_2_3, 1.0);
+ Sys.update_variable_penalty(R_1, 1.0);
+ Sys.update_variable_penalty(R_2, 1.0);
+ Sys.update_variable_penalty(R_3, 1.0);
- Sys->expand(L1, R_1_2_3, 1.0);
- Sys->expand(L2, R_1_2_3, 1.0);
- Sys->expand(L3, R_1_2_3, 1.0);
+ Sys.expand(L1, R_1_2_3, 1.0);
+ Sys.expand(L2, R_1_2_3, 1.0);
+ Sys.expand(L3, R_1_2_3, 1.0);
- Sys->expand(L1, R_1, 1.0);
- Sys->expand(L2, R_2, 1.0);
- Sys->expand(L3, R_3, 1.0);
+ Sys.expand(L1, R_1, 1.0);
+ Sys.expand(L2, R_2, 1.0);
+ Sys.expand(L3, R_3, 1.0);
- Sys->solve();
+ Sys.solve();
PRINT_VAR(R_1_2_3);
PRINT_VAR(R_1);
PRINT_VAR(R_2);
PRINT_VAR(R_3);
- Sys->variable_free(R_1_2_3);
- Sys->variable_free(R_1);
- Sys->variable_free(R_2);
- Sys->variable_free(R_3);
- delete Sys;
+ Sys.variable_free(R_1_2_3);
+ Sys.variable_free(R_1);
+ Sys.variable_free(R_2);
+ Sys.variable_free(R_3);
}
static void test2()
{
- lmm::System* Sys = lmm::make_new_maxmin_system(false);
+ lmm::System Sys(false);
- lmm::Constraint* CPU1 = Sys->constraint_new(nullptr, 200.0);
- lmm::Constraint* CPU2 = Sys->constraint_new(nullptr, 100.0);
+ lmm::Constraint* CPU1 = Sys.constraint_new(nullptr, 200.0);
+ lmm::Constraint* CPU2 = Sys.constraint_new(nullptr, 100.0);
- lmm::Variable* T1 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
- lmm::Variable* T2 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
+ lmm::Variable* T1 = Sys.variable_new(nullptr, 1.0, -1.0, 1);
+ lmm::Variable* T2 = Sys.variable_new(nullptr, 1.0, -1.0, 1);
- Sys->update_variable_penalty(T1, 1.0);
- Sys->update_variable_penalty(T2, 1.0);
+ Sys.update_variable_penalty(T1, 1.0);
+ Sys.update_variable_penalty(T2, 1.0);
- Sys->expand(CPU1, T1, 1.0);
- Sys->expand(CPU2, T2, 1.0);
+ Sys.expand(CPU1, T1, 1.0);
+ Sys.expand(CPU2, T2, 1.0);
- Sys->solve();
+ Sys.solve();
PRINT_VAR(T1);
PRINT_VAR(T2);
- Sys->variable_free(T1);
- Sys->variable_free(T2);
- delete Sys;
+ Sys.variable_free(T1);
+ Sys.variable_free(T2);
}
static void test3()
A[13][14] = 1.0;
A[14][15] = 1.0;
- lmm::System* Sys = lmm::make_new_maxmin_system(false);
+ lmm::System Sys(false);
/* Creates the constraints */
std::array<lmm::Constraint*, 15> tmp_cnst;
for (int i = 0; i < 15; i++)
- tmp_cnst[i] = Sys->constraint_new(nullptr, B[i]);
+ tmp_cnst[i] = Sys.constraint_new(nullptr, B[i]);
/* Creates the variables */
std::array<lmm::Variable*, 16> tmp_var;
for (int j = 0; j < 16; j++) {
- tmp_var[j] = Sys->variable_new(nullptr, 1.0, -1.0, 15);
- Sys->update_variable_penalty(tmp_var[j], 1.0);
+ tmp_var[j] = Sys.variable_new(nullptr, 1.0, -1.0, 15);
+ Sys.update_variable_penalty(tmp_var[j], 1.0);
}
/* Link constraints and variables */
for (int i = 0; i < 15; i++)
for (int j = 0; j < 16; j++)
if (A[i][j] != 0.0)
- Sys->expand(tmp_cnst[i], tmp_var[j], 1.0);
+ Sys.expand(tmp_cnst[i], tmp_var[j], 1.0);
- Sys->solve();
+ Sys.solve();
for (int j = 0; j < 16; j++)
PRINT_VAR(tmp_var[j]);
for (int j = 0; j < 16; j++)
- Sys->variable_free(tmp_var[j]);
- delete Sys;
+ Sys.variable_free(tmp_var[j]);
}
int main(int argc, char** argv)
static double test(int nb_cnst, int nb_var, int nb_elem, unsigned int pw_base_limit, unsigned int pw_max_limit,
double rate_no_limit, int max_share, int mode)
{
- auto* cnst = new simgrid::kernel::lmm::Constraint*[nb_cnst];
- auto* var = new simgrid::kernel::lmm::Variable*[nb_var];
- auto* used = new int[nb_cnst];
+ std::vector<simgrid::kernel::lmm::Constraint*> constraints(nb_cnst);
+ std::vector<simgrid::kernel::lmm::Variable*> variables(nb_var);
/* We cannot activate the selective update as we pass nullptr as an Action when creating the variables */
- auto* Sys = new simgrid::kernel::lmm::System(false);
+ simgrid::kernel::lmm::System Sys(false);
- for (int i = 0; i < nb_cnst; i++) {
- cnst[i] = Sys->constraint_new(nullptr, simgrid::xbt::random::uniform_real(0.0, 10.0));
+ for (auto& cnst : constraints) {
+ cnst = Sys.constraint_new(nullptr, simgrid::xbt::random::uniform_real(0.0, 10.0));
int l;
if (rate_no_limit > simgrid::xbt::random::uniform_real(0.0, 1.0)) {
// Look at what happens when there is no concurrency limit
// Badly logarithmically random concurrency limit in [2^pw_base_limit+1,2^pw_base_limit+2^pw_max_limit]
l = (1 << pw_base_limit) + (1 << simgrid::xbt::random::uniform_int(0, pw_max_limit - 1));
}
- cnst[i]->set_concurrency_limit(l);
+ cnst->set_concurrency_limit(l);
}
- for (int i = 0; i < nb_var; i++) {
- var[i] = Sys->variable_new(nullptr, 1.0, -1.0, nb_elem);
+ for (auto& var : variables) {
+ var = Sys.variable_new(nullptr, 1.0, -1.0, nb_elem);
//Have a few variables with a concurrency share of two (e.g. cross-traffic in some cases)
short concurrency_share = 1 + static_cast<short>(simgrid::xbt::random::uniform_int(0, max_share - 1));
- var[i]->set_concurrency_share(concurrency_share);
+ var->set_concurrency_share(concurrency_share);
- for (int j = 0; j < nb_cnst; j++)
- used[j] = 0;
+ std::vector<int> used(nb_cnst, 0);
for (int j = 0; j < nb_elem; j++) {
int k;
do {
k = simgrid::xbt::random::uniform_int(0, nb_cnst - 1);
} while (used[k] >= concurrency_share);
- Sys->expand(cnst[k], var[i], simgrid::xbt::random::uniform_real(0.0, 1.5));
- Sys->expand_add(cnst[k], var[i], simgrid::xbt::random::uniform_real(0.0, 1.5));
+ Sys.expand(constraints[k], var, simgrid::xbt::random::uniform_real(0.0, 1.5));
+ Sys.expand_add(constraints[k], var, simgrid::xbt::random::uniform_real(0.0, 1.5));
used[k]++;
}
}
fprintf(stderr, "Starting to solve(%i)\n", simgrid::xbt::random::uniform_int(0, 999));
double date = xbt_os_time();
- Sys->solve();
+ Sys.solve();
date = (xbt_os_time() - date) * 1e6;
if(mode==2){
fprintf(stderr,"Max concurrency:\n");
int l=0;
for (int i = 0; i < nb_cnst; i++) {
- int j = cnst[i]->get_concurrency_maximum();
- int k = cnst[i]->get_concurrency_limit();
+ int j = constraints[i]->get_concurrency_maximum();
+ int k = constraints[i]->get_concurrency_limit();
xbt_assert(k<0 || j<=k);
if(j>l)
l=j;
fprintf(stderr,"(%i):%i/%i ",i,j,k);
- cnst[i]->reset_concurrency_maximum();
- xbt_assert(not cnst[i]->get_concurrency_maximum());
+ constraints[i]->reset_concurrency_maximum();
+ xbt_assert(not constraints[i]->get_concurrency_maximum());
if(i%10==9)
fprintf(stderr,"\n");
}
fprintf(stderr,"\nTotal maximum concurrency is %i\n",l);
- Sys->print();
+ Sys.print();
}
- for (int i = 0; i < nb_var; i++)
- Sys->variable_free(var[i]);
- delete Sys;
- delete[] cnst;
- delete[] var;
- delete[] used;
+ for (auto const& var : variables)
+ Sys.variable_free(var);
return date;
}
src/smpi/include/smpi_status.hpp
src/smpi/include/smpi_topo.hpp
src/smpi/include/smpi_win.hpp
- src/smpi/plugins/sampi_loadbalancer.cpp
src/smpi/plugins/ampi/ampi.cpp
src/smpi/plugins/ampi/ampi.hpp
src/smpi/plugins/ampi/instr_ampi.cpp
src/smpi/plugins/ampi/instr_ampi.hpp
- src/smpi/plugins/load_balancer/LoadBalancer.cpp
- src/smpi/plugins/load_balancer/load_balancer.hpp
src/surf/network_smpi.cpp
src/surf/network_ib.cpp
src/smpi/bindings/smpi_mpi.cpp
src/kernel/resource/profile/FutureEvtSet.hpp
src/kernel/resource/profile/Profile.cpp
src/kernel/resource/profile/Profile.hpp
+ src/kernel/resource/profile/StochasticDatedValue.cpp
+ src/kernel/resource/profile/StochasticDatedValue.hpp
src/kernel/routing/ClusterZone.cpp
src/kernel/routing/DijkstraZone.cpp
)
set(MC_SRC
- src/mc/checker/Checker.cpp
src/mc/checker/Checker.hpp
src/mc/checker/CommunicationDeterminismChecker.cpp
src/mc/checker/CommunicationDeterminismChecker.hpp
src/mc/checker/SimcallInspector.hpp
src/mc/checker/LivenessChecker.cpp
src/mc/checker/LivenessChecker.hpp
-
+
src/mc/inspect/DwarfExpression.hpp
src/mc/inspect/DwarfExpression.cpp
src/mc/inspect/Frame.hpp
src/mc/mc_forward.hpp
src/mc/Session.cpp
src/mc/Session.hpp
- src/mc/mc_comm_pattern.cpp
src/mc/mc_comm_pattern.hpp
+ src/mc/mc_pattern.hpp
src/mc/compare.cpp
+ src/mc/mc_api.cpp
+ src/mc/mc_api.hpp
src/mc/mc_hash.hpp
src/mc/mc_hash.cpp
src/mc/mc_ignore.hpp
include/simgrid/plugins/file_system.h
include/simgrid/plugins/live_migration.h
include/simgrid/plugins/load.h
- include/simgrid/plugins/load_balancer.h
include/simgrid/smpi/replay.hpp
include/simgrid/instr.h
include/simgrid/mailbox.h
examples/smpi/replay_multiple_manual_deploy/CMakeLists.txt
examples/python/CMakeLists.txt
examples/deprecated/java/CMakeLists.txt
- examples/deprecated/msg/CMakeLists.txt
examples/deprecated/msg/mc/CMakeLists.txt
examples/deprecated/simdag/CMakeLists.txt
set(warnCFLAGS "${warnCFLAGS} -Wclobbered -Wno-error=clobbered -Wno-unused-local-typedefs -Wno-error=attributes -Wno-error=maybe-uninitialized")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
- # ignore remark #1418: external function definition with no prior declaration
+ # ignore remarks:
+ # 191: type qualifier is meaningless on cast type
+ # 1418: external function definition with no prior declaration
# 2196: routine is both "inline" and "noinline"
+ # 2651: attribute does not apply to any entity
# 3179: deprecated conversion of string literal to char* (should be const char*)
- # 191: type qualifier is meaningless on cast type
+ # set as warning:
# 597: entity-kind "entity" will not be called for implicit or explicit conversions
# 2330: argument of type "type" is incompatible with parameter of type "type" (dropping qualifiers)
# 11003: no IR in object file xxxx; was the source file compiled with xxxx
- set(warnCFLAGS "${warnCFLAGS} -diag-disable=1418,191,2196,3179 -diag-warning=2330,597,11003")
+ set(warnCFLAGS "${warnCFLAGS} -diag-disable=191,1418,2196,2651,3179 -diag-warning=597,2330,11003")
endif()
set(warnCXXFLAGS "${warnCFLAGS} -Wall -Wextra -Wunused -Wmissing-declarations -Wpointer-arith -Wchar-subscripts -Wcomment -Wformat -Wwrite-strings -Wno-unused-function -Wno-unused-parameter -Wno-strict-aliasing")
cd "$WORKSPACE"
#convert all gcov reports to xml cobertura reports
- gcovr -r . --xml-pretty -e teshsuite -u -o "$BUILDFOLDER"/xml_coverage.xml
+ gcovr -r . --xml-pretty -e teshsuite -e examples/smpi/NAS -e examples/smpi/mc -u -o "$BUILDFOLDER"/xml_coverage.xml
xsltproc "$WORKSPACE"/tools/jenkins/ctest2junit.xsl build/Testing/"$( head -n 1 < build/Testing/TAG )"/Test.xml > CTestResults_memcheck.xml
#generate sloccount report
#generate PVS-studio report
EXCLUDEDPATH="-e $WORKSPACE/src/include/catch.hpp -e $WORKSPACE/src/include/xxhash.hpp -e $WORKSPACE/teshsuite/smpi/mpich3-test/ -e $WORKSPACE/teshsuite/smpi/isp/ -e *_dtd.c -e *_dtd.h -e *yy.c -e $WORKSPACE/src/xbt/automaton/ -e $WORKSPACE/src/smpi/colls/ -e $WORKSPACE/examples/smpi/NAS/ -e $WORKSPACE/examples/smpi/gemm/gemm.c -e $WORKSPACE/src/msg/ -e $WORKSPACE/include/msg/ -e $WORKSPACE/examples/deprecated/ -e $WORKSPACE/teshsuite/msg/"
pvs-studio-analyzer analyze -f "$BUILDFOLDER"/compile_commands.json -o "$WORKSPACE"/pvs.log $EXCLUDEDPATH -j$NUMPROC
- #disable V1042 (copyleft), V521 (commas in catch.hpp)
- plog-converter -t xml -o "$WORKSPACE"/pvs.plog -d V1042,V521 "$WORKSPACE"/pvs.log
+ # Disable:
+ # V521 Such expressions using the ',' operator are dangerous. (-> commas in catch.hpp),
+ # V1042 This file is marked with copyleft license, which requires you to open the derived source code.
+ # V1056 The predefined identifier '__func__' always contains the string 'operator()' inside function body of the overloaded 'operator()'.
+ plog-converter -t xml -o "$WORKSPACE"/pvs.plog -d V521,V1042,V1056 "$WORKSPACE"/pvs.log
fi || exit 42
export LC_ALL=C
echo "XXXX Cleanup previous attempts. Remaining content of /tmp:"
+rm -f /tmp/cc*
+rm -f /tmp/*.so
rm -rf /tmp/simgrid-java*
rm -rf /var/tmp/simgrid-java*
rm -rf /tmp/jvm-*
MAY_DISABLE_SOURCE_CHANGE="-DCMAKE_DISABLE_SOURCE_CHANGES=ON"
fi
+if [ "$os" = "CentOS" ] && [ "$(ld -v | cut -d\ -f4)" = "2.30-85.el8" ]; then
+ echo "Temporary disable LTO, believed to be broken on this system."
+ MAY_DISABLE_LTO=-Denable_lto=OFF
+else
+ MAY_DISABLE_LTO=
+fi
+
cmake -G"$GENERATOR" ${INSTALL:+-DCMAKE_INSTALL_PREFIX=$INSTALL} \
-Denable_debug=ON -Denable_documentation=OFF -Denable_coverage=OFF \
-Denable_model-checking=$(onoff test "$build_mode" = "ModelChecker") \
-Denable_memcheck=$(onoff test "$build_mode" = "DynamicAnalysis") \
-Denable_compile_warnings=$(onoff test "$GENERATOR" != "MSYS Makefiles") -Denable_smpi=ON \
-Denable_ns3=$(onoff test "$have_NS3" = "yes" -a "$build_mode" = "Debug") \
- -Denable_jedule=OFF -Denable_lua=OFF ${MAY_DISABLE_SOURCE_CHANGE} \
+ -Denable_jedule=OFF -Denable_lua=OFF ${MAY_DISABLE_SOURCE_CHANGE} ${MAY_DISABLE_LTO} \
-Denable_java=$(onoff test "$build_mode" = "ModelChecker") \
-Denable_msg=$(onoff test "$build_mode" = "ModelChecker") \
-DLTO_EXTRA_FLAG="auto" \
get_python(){
found=$(grep -c "Compile Python bindings .....: ON" ./consoleText)
if [ "$found" != 0 ]; then
- grep -m 1 "Found PythonInterp" ./consoleText| sed "s/.*-- Found PythonInterp.*found suitable version \"\([a-zA-Z0-9\.]*\)\",.*/\1/g"
+ grep -m 1 "Found Python3" ./consoleText| sed "s/.*-- Found Python3.*found version \"\([a-zA-Z0-9\.]*\)\".*/\1/g"
else
echo ""
fi
for node in "${nodes[@]}"
do
- wget --quiet ${BUILD_URL}/build_mode=Debug,node=${node}/consoleText >/dev/null 2>&1
+ wget --quiet --output-document=consoleText \
+ ${BUILD_URL}/build_mode=Debug,node=${node}/consoleText \
+ ${BUILD_URL}/build_mode=ModelChecker,node=${node}/consoleText \
+ >/dev/null 2>&1
if [ ! -f consoleText ]; then
echo "file not existing for node ${node}"
exit 1
Memcheck:Leak
fun:malloc
...
- obj:*/libcgraph.so*
fun:aaglex
fun:aagparse
fun:agconcat
else:
input_filename = sys.argv[i]
i = i + 1
-if input_filename == None:
+if input_filename is None:
sys.stderr.write("Missing input file\n")
sys.exit(1)
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"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".*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