container: simgrid/unstable
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Build and test BatSim
run: |
set -e
options: --user 0
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Build and test BigDFT
run: |
set -e
container: simgrid/unstable
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Build and test StarPU
run: |
set -e
container: simgrid/unstable
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Build and test WRENCH
run: |
set -e
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Init options
run: |
echo "CC=${{ matrix.config.cc }}" >> $GITHUB_ENV
steps:
- name: Checkout repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: build
run: |
SimGrid (3.32.1) not released yet (target december 22)
General:
+ - SimGrid now requires a compiler with C++17 support for public headers too.
+ Sibling projects should upgrade their FindSimGrid.cmake
- Remove the MSG API: its EOL was scheduled for 2020.
- Remove the Java bindings: they were limited to the MSG interface.
- On Windows, you now need to install WSL2 as the native builds are now disabled.
It was not really working anyway.
- Support for 32bits architecture is not tested anymore on our CI infrastructure.
It may break in the future, but we think that nobody's using SimGrid on 32 bits.
- - Remove the surf module. It was replaced by the kernel/models module, and that
+ - Remove the surf module. It was replaced by the kernel/models module, and that
refactoring took almost 10 years to properly complete.
S4U:
possible.
- Allow to set a concurrency limit on disks and hosts, as it was already the case for links.
- Rename Link::get_usage() to Link::get_load() for consistency with Host::
+ - Every signal now come with a static version that is invoked for every object of that class,
+ and an instance version that is invoked for this specific object only. For example,
+ s4u::Actor::on_suspend_cb() adds a callback that is invoked for the suspend of any actor while
+ s4u::Actor::on_this_suspend_cb() adds a callback for this specific actor only.
+ - Activity::on_suspended_cb() is renamed to Activity::on_suspend_cb(), and fired right before the suspend.
+ - Activity::on_resumed_cb() is renamed to Activity::on_resume_cb(), and fired right before the resume.
+ - Resource::on_state_change_cb() is renamed to Resource::on_onoff_cb() to distinguish from the
+ Activity::on_state_change_cb() that is related to the activity state machine, not on/off.
+ - Activity signals (veto, suspend, resume, completion) are now specialized by activity class.
+ That is, callbacks registered in Exec::on_suspend_cb will not be fired for Comms nor Ios.
+
+New S4U plugins:
+ - Operation: They are designed to represent workflows, i.e, graphs of repeatable Activities.
+ See the examples under examples/cpp/operation-* and the documentation in the Plugins page.
+ - Battery: Enable the management of batteries on hosts.
+ See the examples under examples/cpp/battery-* and the documentation in the Plugins page.
+ - Photovoltaic: Enable the management of photovoltaic panels on hosts.
+ See the examples under examples/cpp/photovoltaic-* and the documentation in the Plugins page.
-New plugin: Operation
- - Operations are designed to represent workflows, i.e, graphs of repeatable Activities.
- - Documentation: https://simgrid.frama.io/simgrid/Plugins.html#operation
- - Examples: examples/cpp/operation-*
-
-New plugin: Battery
- - Enable the management of batteries on hosts.
- - Documentation: https://simgrid.frama.io/simgrid/Plugins.html#battery
- - Examples: examples/cpp/battery-*
-
Kernel:
- optimize an internal datastructure (use a set instead of a list for ongoing activities),
leading to a potentially big performance gain, in particular with many detached comms.
- Synchronize the MBI tests with upstream.
- Show the full actor bactraces when replaying a MC trace (with model-check/replay)
and the status of all actors on deadlocks in MC mode.
- - The safety/stateless aspects of the MC are now enabled by default in all simgrid builds.
- Liveness and stateful aspects are still controled by the enabling_model-checking
+ - The safety/stateless aspects of the MC are now enabled by default in all simgrid builds.
+ Liveness and stateful aspects are still controled by the enabling_model-checking
configuration option.
- Stateless model-checking is now usable on any system, including Mac OSX and ARM processors.
Important user-visible changes:
- SimGrid now requires a compiler with C++14 support.
- Sibling projects should upgrade their FindSimgrid.cmake
+ Sibling projects should upgrade their FindSimGrid.cmake
- Surf precision default value is now 1e-9, instead of 1e-5. This was changed as
several users had difficulties to understand issues when using high bandwidth or
small latency events. The new value was already the default for SMPI and
# (code to use with SimGrid v3.19+)
# #endif
#
-# Since SimGrid header files require C++14, so we set CMAKE_CXX_STANDARD to 14.
+# Since SimGrid header files require C++17, so we set CMAKE_CXX_STANDARD to 17.
# Change this variable in your own file if you need a later standard.
#
cmake_minimum_required(VERSION 2.8.12)
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_path(SimGrid_INCLUDE_DIR
INTERFACE_COMPILE_FEATURES cxx_alias_templates
IMPORTED_LOCATION ${SimGrid_LIBRARY}
)
- # We need C++14, so check for it just in case the user removed it since compiling SimGrid
+ # We need C++17, so check for it just in case the user removed it since compiling SimGrid
if (NOT CMAKE_VERSION VERSION_LESS 3.8)
- # 3.8+ allows us to simply require C++14 (or higher)
- set_property(TARGET SimGrid::SimGrid PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_14)
- elseif (NOT CMAKE_VERSION VERSION_LESS 3.1)
- # 3.1+ is similar but for certain features. We pick just one
- set_property(TARGET SimGrid::SimGrid PROPERTY INTERFACE_COMPILE_FEATURES cxx_attribute_deprecated)
+ # 3.8+ allows us to simply require C++17 (or higher)
+ set_property(TARGET SimGrid::SimGrid PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_17)
else ()
- # Old CMake can't do much. Just check the CXX_FLAGS and inform the user when a C++14 feature does not work
+ # Old CMake can't do much. Just check the CXX_FLAGS and inform the user when a C++17 feature does not work
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_CXX_FLAGS}")
check_cxx_source_compiles("
-#if __cplusplus < 201402L
+#if __cplusplus < 201703L
#error
#else
int main(){}
#endif
-" _SIMGRID_CXX14_ENABLED)
- if (NOT _SIMGRID_CXX14_ENABLED)
- message(WARNING "C++14 is required to use SimGrid. Enable it with e.g. -std=c++14")
+" _SIMGRID_CXX17_ENABLED)
+ if (NOT _SIMGRID_CXX17_ENABLED)
+ message(WARNING "C++17 is required to use SimGrid. Enable it with e.g. -std=c++17")
endif ()
unset(_SIMGRID_CXX14_ENABLED CACHE)
endif ()
include examples/cpp/network-ns3/s4u-network-ns3.cpp
include examples/cpp/network-wifi/s4u-network-wifi.cpp
include examples/cpp/network-wifi/s4u-network-wifi.tesh
+include examples/cpp/operation-io/s4u-operation-io.cpp
+include examples/cpp/operation-io/s4u-operation-io.tesh
include examples/cpp/operation-simple/s4u-operation-simple.cpp
include examples/cpp/operation-simple/s4u-operation-simple.tesh
include examples/cpp/operation-switch-host/s4u-operation-switch-host.cpp
include examples/cpp/operation-switch-host/s4u-operation-switch-host.tesh
include examples/cpp/operation-variable-load/s4u-operation-variable-load.cpp
include examples/cpp/operation-variable-load/s4u-operation-variable-load.tesh
+include examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.cpp
+include examples/cpp/photovoltaic-simple/s4u-photovoltaic-simple.tesh
include examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.cpp
include examples/cpp/platform-comm-serialize/s4u-platform-comm-serialize.tesh
include examples/cpp/platform-failures/s4u-platform-failures.cpp
include examples/python/io-degradation/io-degradation.tesh
include examples/python/network-nonlinear/network-nonlinear.py
include examples/python/network-nonlinear/network-nonlinear.tesh
+include examples/python/operation-io/operation-io.py
+include examples/python/operation-io/operation-io.tesh
+include examples/python/operation-simple/operation-simple.py
+include examples/python/operation-simple/operation-simple.tesh
+include examples/python/operation-switch-host/operation-switch-host.py
+include examples/python/operation-switch-host/operation-switch-host.tesh
+include examples/python/operation-variable-load/operation-variable-load.py
+include examples/python/operation-variable-load/operation-variable-load.tesh
include examples/python/platform-comm-serialize/platform-comm-serialize.py
include examples/python/platform-comm-serialize/platform-comm-serialize.tesh
include examples/python/platform-failures/platform-failures.py
include examples/platforms/optorsim/gridpp_grid_2004.conf
include examples/platforms/optorsim/lcg_sept2004_grid.conf
include examples/platforms/optorsim/transform_optorsim_platform.pl
+include examples/platforms/photovoltaic_platform.xml
include examples/platforms/profiles/fafard_state.profile
include examples/platforms/profiles/faulty_host.profile
include examples/platforms/profiles/ginette_state.profile
include include/simgrid/plugins/load.h
include include/simgrid/plugins/ns3.hpp
include include/simgrid/plugins/operation.hpp
+include include/simgrid/plugins/photovoltaic.hpp
include include/simgrid/s4u.hpp
include include/simgrid/s4u/Activity.hpp
include include/simgrid/s4u/Actor.hpp
include src/plugins/link_energy_wifi.cpp
include src/plugins/link_load.cpp
include src/plugins/operation.cpp
+include src/plugins/photovoltaic.cpp
include src/plugins/vm/VmLiveMigration.cpp
include src/plugins/vm/VmLiveMigration.hpp
include src/plugins/vm/dirty_page_tracking.cpp
@code{cpp}
template<class F>
-typename std::result_of<F()>::type kernelImmediate(F&& code)
+typename std::result_of_t<F()> kernelImmediate(F&& code)
{
// If we are in the simulation kernel, we take the fast path and
// execute the code directly without simcall
// If we are in the application, pass the code to the simulation
// kernel which executes it for us and reports the result:
- typedef typename std::result_of<F()>::type R;
+ typedef typename std::result_of_t<F()> R;
simgrid::xbt::Result<R> result;
simcall_run_kernel([&]{
xbt_assert(SIMIX_is_maestro(), "Not in maestro");
Configuring ns-3
^^^^^^^^^^^^^^^^
-**Option** ``ns3/TcpModel`` **Default:** "default" (ns-3 default)
+**Option** ``ns3/NetworkModel`` **Default:** "default" (ns-3 default TCP)
-When using ns-3, there is an extra item ``ns3/TcpModel``, corresponding
-to the ``ns3::TcpL4Protocol::SocketType`` configuration item in
-ns-3. The only valid values (enforced on the SimGrid side) are
-'default' (no change to the ns-3 configuration), 'NewReno' or 'Reno' or
-'Tahoe'.
+When using ns-3, the item ``ns3/NetworkModel`` can be used to switch between TCP or UDP, and switch the used TCP variante. If
+the item is left unchanged, ns-3 uses the default TCP implementation. With a value of "UDP", ns-3 is set to use UDP instead.
+With the value of either 'NewReno' or 'Cubic', the ``ns3::TcpL4Protocol::SocketType`` configuration item in ns-3 is set to the
+corresponding protocol.
**Option** ``ns3/seed`` **Default:** "" (don't set the seed in ns-3)
Partial list of existing signals in s4u:
-- :cpp:func:`Actor::on_creation <simgrid::s4u::Actor::on_creation_cb>`
+- In actors:
+ :cpp:func:`Actor::on_creation <simgrid::s4u::Actor::on_creation_cb>`
:cpp:func:`Actor::on_suspend <simgrid::s4u::Actor::on_suspend_cb>`
+ :cpp:func:`Actor::on_this_suspend <simgrid::s4u::Actor::on_this_suspend_cb>`
:cpp:func:`Actor::on_resume <simgrid::s4u::Actor::on_resume_cb>`
+ :cpp:func:`Actor::on_this_resume <simgrid::s4u::Actor::on_this_resume_cb>`
:cpp:func:`Actor::on_sleep <simgrid::s4u::Actor::on_sleep_cb>`
+ :cpp:func:`Actor::on_this_sleep <simgrid::s4u::Actor::on_this_sleep_cb>`
:cpp:func:`Actor::on_wake_up <simgrid::s4u::Actor::on_wake_up_cb>`
+ :cpp:func:`Actor::on_this_wake_up <simgrid::s4u::Actor::on_this_wake_up_cb>`
:cpp:func:`Actor::on_host_change <simgrid::s4u::Actor::on_host_change_cb>`
+ :cpp:func:`Actor::on_this_host_change <simgrid::s4u::Actor::on_this_host_change_cb>`
:cpp:func:`Actor::on_termination <simgrid::s4u::Actor::on_termination_cb>`
+ :cpp:func:`Actor::on_this_termination <simgrid::s4u::Actor::on_this_termination_cb>`
:cpp:func:`Actor::on_destruction <simgrid::s4u::Actor::on_destruction_cb>`
-- :cpp:func:`Comm::on_send <simgrid::s4u::Comm::on_send_cb>`
- :cpp:func:`Comm::on_recv <simgrid::s4u::Comm::on_recv_cb>`
- :cpp:func:`Comm::on_completion <simgrid::s4u::Comm::on_completion_cb>`
-- :cpp:func:`CommImpl::on_start <simgrid::s4u::Comm::on_start_cb>`
- :cpp:func:`CommImpl::on_completion <simgrid::s4u::Comm::on_completion_cb>`
-- :cpp:func:`Disk::on_creation <simgrid::s4u::Disk::on_creation_cb>`
- :cpp:func:`Disk::on_destruction <simgrid::s4u::Disk::on_destruction_cb>`
- :cpp:func:`Disk::on_state_change <simgrid::s4u::Disk::on_state_change_cb>`
-- :cpp:func:`Engine::on_platform_creation <simgrid::s4u::Engine::on_platform_creation_cb>`
+- In the engine:
+ :cpp:func:`Engine::on_platform_creation <simgrid::s4u::Engine::on_platform_creation_cb>`
:cpp:func:`Engine::on_platform_created <simgrid::s4u::Engine::on_platform_created_cb>`
:cpp:func:`Engine::on_time_advance <simgrid::s4u::Engine::on_time_advance_cb>`
:cpp:func:`Engine::on_simulation_end <simgrid::s4u::Engine::on_simulation_end_cb>`
:cpp:func:`Engine::on_deadlock <simgrid::s4u::Engine::on_deadlock_cb>`
-- :cpp:func:`Exec::on_start <simgrid::s4u::Exec::on_start_cb>`
- :cpp:func:`Exec::on_completion <simgrid::s4u::Exec::on_completion_cb>`
-- :cpp:func:`Host::on_creation <simgrid::s4u::Host::on_creation_cb>`
- :cpp:func:`Host::on_destruction <simgrid::s4u::Host::on_destruction_cb>`
- :cpp:func:`Host::on_state_change <simgrid::s4u::Host::on_state_change_cb>`
- :cpp:func:`Host::on_speed_change <simgrid::s4u::Host::on_speed_change_cb>`
-- :cpp:func:`Io::on_start <simgrid::s4u::Io::on_start_cb>`
- :cpp:func:`Io::on_completion <simgrid::s4u::Io::on_completion_cb>`
-- :cpp:func:`Link::on_creation <simgrid::s4u::Link::on_creation_cb>`
- :cpp:func:`Link::on_destruction <simgrid::s4u::Link::on_destruction_cb>`
- :cpp:func:`Link::on_state_change <simgrid::s4u::Link::on_state_change_cb>`
- :cpp:func:`Link::on_speed_change <simgrid::s4u::Link::on_bandwidth_change_cb>`
- :cpp:func:`Link::on_communication_state_change <simgrid::s4u::Link::on_communication_state_change_cb>`
-- :cpp:func:`NetZone::on_creation <simgrid::s4u::NetZone::on_creation_cb>`
- :cpp:func:`NetZone::on_seal <simgrid::s4u::NetZone::on_seal_cb>`
-- :cpp:func:`VirtualMachine::on_start <simgrid::s4u::VirtualMachine::on_start_cb>`
- :cpp:func:`VirtualMachine::on_started <simgrid::s4u::VirtualMachine::on_started_cb>`
- :cpp:func:`VirtualMachine::on_suspend <simgrid::s4u::VirtualMachine::on_suspend_cb>`
- :cpp:func:`VirtualMachine::on_resume <simgrid::s4u::VirtualMachine::on_resume_cb>`
- :cpp:func:`VirtualMachine::on_migration_start <simgrid::s4u::VirtualMachine::on_migration_start_cb>`
- :cpp:func:`VirtualMachine::on_migration_end <simgrid::s4u::VirtualMachine::on_migration_end_cb>`
+
+- In resources:
+
+ - :cpp:func:`Disk::on_creation <simgrid::s4u::Disk::on_creation_cb>`
+ :cpp:func:`Disk::on_destruction <simgrid::s4u::Disk::on_destruction_cb>`
+ :cpp:func:`Disk::on_this_destruction <simgrid::s4u::Disk::on_this_destruction_cb>`
+ :cpp:func:`Disk::on_onoff <simgrid::s4u::Disk::on_onoff_cb>`
+ :cpp:func:`Disk::on_this_onoff <simgrid::s4u::Disk::on_this_onoff_cb>`
+ - :cpp:func:`Host::on_creation <simgrid::s4u::Host::on_creation_cb>`
+ :cpp:func:`Host::on_destruction <simgrid::s4u::Host::on_destruction_cb>`
+ :cpp:func:`Host::on_this_destruction <simgrid::s4u::Host::on_this_destruction_cb>`
+ :cpp:func:`Host::on_onoff <simgrid::s4u::Host::on_onoff_cb>`
+ :cpp:func:`Host::on_this_onoff <simgrid::s4u::Host::on_this_onoff_cb>`
+ :cpp:func:`Host::on_speed_change <simgrid::s4u::Host::on_speed_change_cb>`
+ :cpp:func:`Host::on_this_speed_change <simgrid::s4u::Host::on_this_speed_change_cb>`
+ :cpp:func:`Host::on_exec_state_change <simgrid::s4u::Host::on_exec_state_change_cb>`
+ - :cpp:func:`Link::on_creation <simgrid::s4u::Link::on_creation_cb>`
+ :cpp:func:`Link::on_destruction <simgrid::s4u::Link::on_destruction_cb>`
+ :cpp:func:`Link::on_this_destruction <simgrid::s4u::Link::on_this_destruction_cb>`
+ :cpp:func:`Link::on_onoff <simgrid::s4u::Link::on_onoff_cb>`
+ :cpp:func:`Link::on_this_onoff <simgrid::s4u::Link::on_this_onoff_cb>`
+ :cpp:func:`Link::on_bandwidth_change <simgrid::s4u::Link::on_bandwidth_change_cb>`
+ :cpp:func:`Link::on_this_bandwidth_change <simgrid::s4u::Link::on_this_bandwidth_change_cb>`
+ :cpp:func:`Link::on_communication_state_change <simgrid::s4u::Link::on_communication_state_change_cb>`
+
+ - :cpp:func:`NetZone::on_creation <simgrid::s4u::NetZone::on_creation_cb>`
+ :cpp:func:`NetZone::on_seal <simgrid::s4u::NetZone::on_seal_cb>`
+ - :cpp:func:`VirtualMachine::on_start <simgrid::s4u::VirtualMachine::on_start_cb>`
+ :cpp:func:`VirtualMachine::on_this_start <simgrid::s4u::VirtualMachine::on_this_start_cb>`
+ :cpp:func:`VirtualMachine::on_started <simgrid::s4u::VirtualMachine::on_started_cb>`
+ :cpp:func:`VirtualMachine::on_this_started <simgrid::s4u::VirtualMachine::on_this_started_cb>`
+ :cpp:func:`VirtualMachine::on_suspend <simgrid::s4u::VirtualMachine::on_suspend_cb>`
+ :cpp:func:`VirtualMachine::on_this_suspend <simgrid::s4u::VirtualMachine::on_this_suspend_cb>`
+ :cpp:func:`VirtualMachine::on_resume <simgrid::s4u::VirtualMachine::on_resume_cb>`
+ :cpp:func:`VirtualMachine::on_this_resume <simgrid::s4u::VirtualMachine::on_this_resume_cb>`
+ :cpp:func:`VirtualMachine::on_migration_start <simgrid::s4u::VirtualMachine::on_migration_start_cb>`
+ :cpp:func:`VirtualMachine::on_this_migration_start <simgrid::s4u::VirtualMachine::on_this_migration_start_cb>`
+ :cpp:func:`VirtualMachine::on_migration_end <simgrid::s4u::VirtualMachine::on_migration_end_cb>`
+ :cpp:func:`VirtualMachine::on_this_migration_end <simgrid::s4u::VirtualMachine::on_this_migration_end_cb>`
+
+- In activities:
+
+ - :cpp:func:`Comm::on_send <simgrid::s4u::Comm::on_send_cb>`
+ :cpp:func:`Comm::on_recv <simgrid::s4u::Comm::on_recv_cb>`
+ - :cpp:func:`Comm::on_start <simgrid::s4u::Comm::on_start_cb>`
+ :cpp:func:`Comm::on_this_start <simgrid::s4u::Comm::on_this_start_cb>`
+ :cpp:func:`Comm::on_completion <simgrid::s4u::Comm::on_completion_cb>`
+ :cpp:func:`Comm::on_this_completion <simgrid::s4u::Comm::on_this_completion_cb>`
+ :cpp:func:`Comm::on_suspend <simgrid::s4u::Comm::on_suspend_cb>`
+ :cpp:func:`Comm::on_this_suspend <simgrid::s4u::Comm::on_this_suspend_cb>`
+ :cpp:func:`Comm::on_resume <simgrid::s4u::Comm::on_resume_cb>`
+ :cpp:func:`Comm::on_this_resume <simgrid::s4u::Comm::on_this_resume_cb>`
+ :cpp:func:`Comm::on_veto <simgrid::s4u::Comm::on_veto_cb>`
+ :cpp:func:`Comm::on_this_veto <simgrid::s4u::Comm::on_this_veto_cb>`
+ - :cpp:func:`Exec::on_start <simgrid::s4u::Exec::on_start_cb>`
+ :cpp:func:`Exec::on_this_start <simgrid::s4u::Exec::on_this_start_cb>`
+ :cpp:func:`Exec::on_completion <simgrid::s4u::Exec::on_completion_cb>`
+ :cpp:func:`Exec::on_this_completion <simgrid::s4u::Exec::on_this_completion_cb>`
+ :cpp:func:`Exec::on_suspend <simgrid::s4u::Exec::on_suspend_cb>`
+ :cpp:func:`Exec::on_this_suspend <simgrid::s4u::Exec::on_this_suspend_cb>`
+ :cpp:func:`Exec::on_resume <simgrid::s4u::Exec::on_resume_cb>`
+ :cpp:func:`Exec::on_this_resume <simgrid::s4u::Exec::on_this_resume_cb>`
+ :cpp:func:`Exec::on_veto <simgrid::s4u::Exec::on_veto_cb>`
+ :cpp:func:`Exec::on_this_veto <simgrid::s4u::Exec::on_this_veto_cb>`
+ - :cpp:func:`Io::on_start <simgrid::s4u::Io::on_start_cb>`
+ :cpp:func:`Io::on_this_start <simgrid::s4u::Io::on_this_start_cb>`
+ :cpp:func:`Io::on_completion <simgrid::s4u::Io::on_completion_cb>`
+ :cpp:func:`Io::on_this_completion <simgrid::s4u::Io::on_this_completion_cb>`
+ :cpp:func:`Io::on_suspend <simgrid::s4u::Io::on_suspend_cb>`
+ :cpp:func:`Io::on_this_suspend <simgrid::s4u::Io::on_this_suspend_cb>`
+ :cpp:func:`Io::on_resume <simgrid::s4u::Io::on_resume_cb>`
+ :cpp:func:`Io::on_this_resume <simgrid::s4u::Io::on_this_resume_cb>`
+ :cpp:func:`Io::on_veto <simgrid::s4u::Io::on_veto_cb>`
+ :cpp:func:`Io::on_this_veto <simgrid::s4u::Io::on_this_veto_cb>`
Existing Plugins
****************
.. doxygengroup:: plugin_operation
+.. _plugin_photovoltaic:
+
+Photovoltaic
+===========
+
+.. doxygengroup:: plugin_photovoltaic
+
.. LocalWords: SimGrid
cmake_minimum_required(VERSION 2.8.12)
project(MyFirstSimulator)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
find_package(SimGrid REQUIRED)
If you wish to develop your plugin or modify SimGrid using
Eclipse. You have to run cmake and import it as a Makefile project.
-Next, you have to activate C++14 in your build settings, add -std=c++14
+Next, you have to activate C++17 in your build settings, add -std=c++17
in the CDT GCC Built-in compiler settings.
.. image:: /img/eclipseScreenShot.png
.. doxygenfunction:: simgrid::s4u::Actor::on_creation_cb
.. doxygenfunction:: simgrid::s4u::Actor::on_suspend_cb
+ .. doxygenfunction:: simgrid::s4u::Actor::on_this_suspend_cb
.. doxygenfunction:: simgrid::s4u::Actor::on_host_change_cb
+ .. doxygenfunction:: simgrid::s4u::Actor::on_this_host_change_cb
.. doxygenfunction:: simgrid::s4u::Actor::on_resume_cb
+ .. doxygenfunction:: simgrid::s4u::Actor::on_this_resume_cb
.. doxygenfunction:: simgrid::s4u::Actor::on_sleep_cb
+ .. doxygenfunction:: simgrid::s4u::Actor::on_this_sleep_cb
.. doxygenfunction:: simgrid::s4u::Actor::on_wake_up_cb
+ .. doxygenfunction:: simgrid::s4u::Actor::on_this_wake_up_cb
.. doxygenfunction:: simgrid::s4u::Actor::on_termination_cb
+ .. doxygenfunction:: simgrid::s4u::Actor::on_this_termination_cb
.. doxygenfunction:: simgrid::s4u::Actor::on_destruction_cb
+ .. doxygenfunction:: simgrid::s4u::Actor::on_this_destruction_cb
.. _API_s4u_this_actor:
.. doxygenfunction:: simgrid::s4u::Disk::on_creation_cb
.. doxygenfunction:: simgrid::s4u::Disk::on_destruction_cb
- .. doxygenfunction:: simgrid::s4u::Disk::on_state_change_cb
+ .. doxygenfunction:: simgrid::s4u::Disk::on_this_destruction_cb
+ .. doxygenfunction:: simgrid::s4u::Disk::on_onoff_cb
+ .. doxygenfunction:: simgrid::s4u::Disk::on_this_onoff_cb
.. _API_s4u_Host:
.. doxygenfunction:: simgrid::s4u::Host::on_creation_cb
.. doxygenfunction:: simgrid::s4u::Host::on_destruction_cb
+ .. doxygenfunction:: simgrid::s4u::Host::on_this_destruction_cb
.. doxygenfunction:: simgrid::s4u::Host::on_speed_change_cb
- .. doxygenfunction:: simgrid::s4u::Host::on_state_change_cb
+ .. doxygenfunction:: simgrid::s4u::Host::on_this_speed_change_cb
+ .. doxygenfunction:: simgrid::s4u::Host::on_onoff_cb
+ .. doxygenfunction:: simgrid::s4u::Host::on_this_onoff_cb
+ .. doxygenfunction:: simgrid::s4u::Host::on_exec_state_change_cb
.. _API_s4u_Link:
.. group-tab:: C++
.. doxygenfunction:: simgrid::s4u::Link::on_bandwidth_change_cb
+ .. doxygenfunction:: simgrid::s4u::Link::on_this_bandwidth_change_cb
.. doxygenfunction:: simgrid::s4u::Link::on_communication_state_change_cb
.. doxygenfunction:: simgrid::s4u::Link::on_creation_cb
.. doxygenfunction:: simgrid::s4u::Link::on_destruction_cb
- .. doxygenfunction:: simgrid::s4u::Link::on_state_change_cb
+ .. doxygenfunction:: simgrid::s4u::Link::on_this_destruction_cb
+ .. doxygenfunction:: simgrid::s4u::Link::on_onoff_cb
+ .. doxygenfunction:: simgrid::s4u::Link::on_this_onoff_cb
.. _API_s4u_NetZone:
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_creation_cb
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_destruction_cb
+ .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_destruction_cb
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_migration_end_cb
+ .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_migration_end_cb
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_migration_start_cb
+ .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_migration_start_cb
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_resume_cb
+ .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_resume_cb
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_shutdown_cb
+ .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_shutdown_cb
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_start_cb
+ .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_start_cb
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_started_cb
+ .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_started_cb
.. doxygenfunction:: simgrid::s4u::VirtualMachine::on_suspend_cb
+ .. doxygenfunction:: simgrid::s4u::VirtualMachine::on_this_suspend_cb
.. _API_s4u_Activity:
.. doxygenfunction:: simgrid::s4u::Activity::resume
.. doxygenfunction:: simgrid::s4u::Activity::is_suspended
-Signals
--------
-
-.. tabs::
-
- .. group-tab:: C++
-
- .. doxygenfunction:: simgrid::s4u::Activity::on_completion_cb
- .. doxygenfunction:: simgrid::s4u::Activity::on_suspended_cb
- .. doxygenfunction:: simgrid::s4u::Activity::on_resumed_cb
-
.. _API_s4u_Comm:
=============
.. doxygenfunction:: simgrid::s4u::Comm::on_recv_cb
.. doxygenfunction:: simgrid::s4u::Comm::on_send_cb
+ .. doxygenfunction:: simgrid::s4u::Comm::on_completion_cb
+ .. doxygenfunction:: simgrid::s4u::Comm::on_suspended_cb
+ .. doxygenfunction:: simgrid::s4u::Comm::on_resumed_cb
+ .. doxygenfunction:: simgrid::s4u::Comm::on_veto_cb
+
.. _API_s4u_Exec:
=============
.. doxygenfunction:: simgrid::s4u::Exec::on_start_cb
.. doxygenfunction:: simgrid::s4u::Exec::on_completion_cb
+ .. doxygenfunction:: simgrid::s4u::Exec::on_completion_cb
+ .. doxygenfunction:: simgrid::s4u::Exec::on_suspended_cb
+ .. doxygenfunction:: simgrid::s4u::Exec::on_resumed_cb
+ .. doxygenfunction:: simgrid::s4u::Exec::on_veto_cb
+
.. _API_s4u_Io:
===========
.. doxygenfunction:: simgrid::s4u::Io::on_start_cb
.. doxygenfunction:: simgrid::s4u::Io::on_completion_cb
+ .. doxygenfunction:: simgrid::s4u::Io::on_completion_cb
+ .. doxygenfunction:: simgrid::s4u::Io::on_suspended_cb
+ .. doxygenfunction:: simgrid::s4u::Io::on_resumed_cb
+ .. doxygenfunction:: simgrid::s4u::Io::on_veto_cb
+
.. _API_s4u_Synchronizations:
=======================
cmake_minimum_required(VERSION 2.8.12)
project(tuto_disk)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/" "../../../")
find_package(SimGrid REQUIRED)
cmake_minimum_required(VERSION 2.8.12)
project(tuto_network)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/" "../../../")
find_package(SimGrid REQUIRED)
mc-bugged1 mc-bugged1-liveness mc-bugged2 mc-bugged2-liveness mc-centralized-mutex mc-electric-fence mc-failing-assert
network-ns3 network-ns3-wifi network-wifi
io-async io-priority io-degradation io-file-system io-file-remote io-disk-raw io-dependent
- operation-simple operation-variable-load operation-switch-host
+ operation-io operation-simple operation-variable-load operation-switch-host
+ photovoltaic-simple
platform-comm-serialize platform-failures platform-profile platform-properties
plugin-host-load plugin-link-load plugin-prodcons
replay-comm replay-io
--setenv srcdir=${CMAKE_CURRENT_SOURCE_DIR}/${example}
--cd ${CMAKE_CURRENT_SOURCE_DIR}/${example}
${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-nodpor.tesh)
- endif()
+ endif()
set(tesh_files ${tesh_files} ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-statequality.tesh)
set(tesh_files ${tesh_files} ${CMAKE_HOME_DIRECTORY}/examples/cpp/${example}/s4u-${example}-nodpor.tesh)
endforeach()
int main(int argc, char* argv[])
{
sg4::Engine e(&argc, argv);
- sg_storage_file_system_init();
e.load_platform(argv[1]);
auto tremblay = e.host_by_name("Tremblay");
auto jupiter = e.host_by_name("Jupiter");
// Display the details on vetoed activities
- sg4::Activity::on_veto_cb([](const sg4::Activity& a) {
- XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", a.get_cname(),
- (a.dependencies_solved() ? "solved" : "NOT solved"), (a.is_assigned() ? "assigned" : "NOT assigned"));
+ sg4::Exec::on_veto_cb([](sg4::Exec const& exec) {
+ XBT_INFO("Execution '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(),
+ (exec.dependencies_solved() ? "solved" : "NOT solved"), (exec.is_assigned() ? "assigned" : "NOT assigned"));
+ });
+ sg4::Comm::on_veto_cb([](sg4::Comm const& comm) {
+ XBT_INFO("Communication '%s' vetoed. Dependencies: %s; Ressources: %s", comm.get_cname(),
+ (comm.dependencies_solved() ? "solved" : "NOT solved"), (comm.is_assigned() ? "assigned" : "NOT assigned"));
});
- sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
- if (const auto* exec = dynamic_cast<sg4::Exec const*>(&activity))
- XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
- exec->get_finish_time());
- if (const auto* comm = dynamic_cast<sg4::Comm const*>(&activity))
- XBT_INFO("Activity '%s' is complete", comm->get_cname());
+ sg4::Exec::on_completion_cb([](sg4::Exec const& exec) {
+ XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(),
+ exec.get_finish_time());
+ });
+ sg4::Comm::on_completion_cb([](sg4::Comm const& comm) {
+ XBT_INFO("Comm '%s' is complete", comm.get_cname());
});
// Create a small DAG: parent->transfer->child
#!/usr/bin/env tesh
$ ${bindir:=.}/s4u-dag-comm ${platfdir}/two_hosts.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
-> [ 0.000000] (0:maestro@) Activity 'parent' vetoed. Dependencies: solved; Ressources: NOT assigned
-> [ 0.000000] (0:maestro@) Activity 'transfer' vetoed. Dependencies: NOT solved; Ressources: NOT assigned
-> [ 0.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned
+> [ 0.000000] (0:maestro@) Execution 'parent' vetoed. Dependencies: solved; Ressources: NOT assigned
+> [ 0.000000] (0:maestro@) Communication 'transfer' vetoed. Dependencies: NOT solved; Ressources: NOT assigned
+> [ 0.000000] (0:maestro@) Execution 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned
> [ 0.000000] (0:maestro@) 'parent' is assigned to a resource and all dependencies are solved. Let's start
-> [ 0.000000] (0:maestro@) Activity 'transfer' vetoed. Dependencies: NOT solved; Ressources: NOT assigned
-> [ 0.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: assigned
-> [ 0.000000] (0:maestro@) Activity 'transfer' vetoed. Dependencies: NOT solved; Ressources: assigned
-> [ 1.000000] (0:maestro@) Activity 'parent' is complete (start time: 0.000000, finish time: 1.000000)
+> [ 0.000000] (0:maestro@) Communication 'transfer' vetoed. Dependencies: NOT solved; Ressources: NOT assigned
+> [ 0.000000] (0:maestro@) Execution 'child' vetoed. Dependencies: NOT solved; Ressources: assigned
+> [ 0.000000] (0:maestro@) Communication 'transfer' vetoed. Dependencies: NOT solved; Ressources: assigned
+> [ 1.000000] (0:maestro@) Exec 'parent' is complete (start time: 0.000000, finish time: 1.000000)
> [ 1.000000] (0:maestro@) Remove a dependency from 'parent' on 'transfer'
> [ 1.000000] (0:maestro@) 'transfer' is assigned to a resource and all dependencies are solved. Let's start
-> [ 2.083775] (0:maestro@) Activity 'transfer' is complete
> [ 2.083775] (0:maestro@) Remove a dependency from 'transfer' on 'child'
> [ 2.083775] (0:maestro@) 'child' is assigned to a resource and all dependencies are solved. Let's start
-> [ 3.083775] (0:maestro@) Activity 'child' is complete (start time: 2.083775, finish time: 3.083775)
+> [ 2.083775] (0:maestro@) Comm 'transfer' is complete
+> [ 3.083775] (0:maestro@) Exec 'child' is complete (start time: 2.083775, finish time: 3.083775)
> [ 3.083775] (0:maestro@) Simulation time 3.08378
auto* faulty = e.host_by_name("Faulty Host");
auto* safe = e.host_by_name("Safe Host");
- sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
- const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
- if (exec == nullptr) // Only Execs are concerned here
- return;
- if (exec->get_state() == sg4::Activity::State::FINISHED)
- XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
- exec->get_finish_time());
- if (exec->get_state() == sg4::Activity::State::FAILED) {
- if (exec->is_parallel())
- XBT_INFO("Activity '%s' has failed. %.f %% remain to be done", exec->get_cname(),
- 100 * exec->get_remaining_ratio());
+ sg4::Exec::on_completion_cb([](sg4::Exec const& exec) {
+ if (exec.get_state() == sg4::Activity::State::FINISHED)
+ XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(),
+ exec.get_finish_time());
+ if (exec.get_state() == sg4::Activity::State::FAILED) {
+ if (exec.is_parallel())
+ XBT_INFO("Activity '%s' has failed. %.f %% remain to be done", exec.get_cname(),
+ 100 * exec.get_remaining_ratio());
else
- XBT_INFO("Activity '%s' has failed. %.f flops remain to be done", exec->get_cname(), exec->get_remaining());
+ XBT_INFO("Activity '%s' has failed. %.f flops remain to be done", exec.get_cname(), exec.get_remaining());
}
});
}
}
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", activity.get_cname(),
- activity.get_start_time(), activity.get_finish_time());
+ simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) {
+ XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(),
+ exec.get_start_time(), exec.get_finish_time());
+ });
+
+ simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) {
+ XBT_INFO("Comm '%s' is complete (start time: %f, finish time: %f)", comm.get_cname(),
+ comm.get_start_time(), comm.get_finish_time());
});
e.run();
#!/usr/bin/env tesh
$ ${bindir:=.}/s4u-dag-from-dax-simple --log=no_loc ${platfdir}/small_platform.xml ${srcdir:=.}/dag.xml
-> [0.000000] [dag_from_dax_simple/INFO] Activity 'root' is complete (start time: 0.000000, finish time: 0.000000)
-> [33.394394] [dag_from_dax_simple/INFO] Activity 'root_i2_2@c2' is complete (start time: 0.000000, finish time: 33.394394)
-> [39.832311] [dag_from_dax_simple/INFO] Activity 'root_i1_1@c1' is complete (start time: 0.000000, finish time: 39.832311)
-> [467.988690] [dag_from_dax_simple/INFO] Activity '1@c1' is complete (start time: 39.832311, finish time: 467.988690)
-> [543.077868] [dag_from_dax_simple/INFO] Activity '1@c1_o1_3@c3' is complete (start time: 467.988690, finish time: 543.077868)
-> [2785.832267] [dag_from_dax_simple/INFO] Activity '2@c2' is complete (start time: 33.394394, finish time: 2785.832267)
-> [3886.807417] [dag_from_dax_simple/INFO] Activity '3@c3' is complete (start time: 2785.832267, finish time: 3886.807417)
-> [3887.221639] [dag_from_dax_simple/INFO] Activity '3@c3_o3_end' is complete (start time: 3886.807417, finish time: 3887.221639)
-> [3887.221639] [dag_from_dax_simple/INFO] Activity 'end' is complete (start time: 3887.221639, finish time: 3887.221639)
\ No newline at end of file
+> [0.000000] [dag_from_dax_simple/INFO] Exec 'root' is complete (start time: 0.000000, finish time: 0.000000)
+> [33.394394] [dag_from_dax_simple/INFO] Comm 'root_i2_2@c2' is complete (start time: 0.000000, finish time: 33.394394)
+> [39.832311] [dag_from_dax_simple/INFO] Comm 'root_i1_1@c1' is complete (start time: 0.000000, finish time: 39.832311)
+> [467.988690] [dag_from_dax_simple/INFO] Exec '1@c1' is complete (start time: 39.832311, finish time: 467.988690)
+> [543.077868] [dag_from_dax_simple/INFO] Comm '1@c1_o1_3@c3' is complete (start time: 467.988690, finish time: 543.077868)
+> [2785.832267] [dag_from_dax_simple/INFO] Exec '2@c2' is complete (start time: 33.394394, finish time: 2785.832267)
+> [3886.807417] [dag_from_dax_simple/INFO] Exec '3@c3' is complete (start time: 2785.832267, finish time: 3886.807417)
+> [3887.221639] [dag_from_dax_simple/INFO] Comm '3@c3_o3_end' is complete (start time: 3886.807417, finish time: 3887.221639)
+> [3887.221639] [dag_from_dax_simple/INFO] Exec 'end' is complete (start time: 3887.221639, finish time: 3887.221639)
\ No newline at end of file
}
}
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", activity.get_cname(),
- activity.get_start_time(), activity.get_finish_time());
+ simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) {
+ XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(),
+ exec.get_start_time(), exec.get_finish_time());
+ });
+
+ simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) {
+ XBT_INFO("Comm '%s' is complete (start time: %f, finish time: %f)", comm.get_cname(),
+ comm.get_start_time(), comm.get_finish_time());
});
e.run();
#!/usr/bin/env tesh
$ ${bindir:=.}/s4u-dag-from-dot-simple --log=no_loc ${platfdir}/small_platform.xml ${srcdir:=.}/dag.dot
-> [0.000000] [dag_from_dot_simple/INFO] Activity 'root' is complete (start time: 0.000000, finish time: 0.000000)
-> [33.394394] [dag_from_dot_simple/INFO] Activity 'root->c2' is complete (start time: 0.000000, finish time: 33.394394)
-> [39.832311] [dag_from_dot_simple/INFO] Activity 'root->c1' is complete (start time: 0.000000, finish time: 39.832311)
-> [50.026511] [dag_from_dot_simple/INFO] Activity 'c1' is complete (start time: 39.832311, finish time: 50.026511)
-> [98.928629] [dag_from_dot_simple/INFO] Activity 'c2' is complete (start time: 33.394394, finish time: 98.928629)
-> [125.115689] [dag_from_dot_simple/INFO] Activity 'c1->c3' is complete (start time: 50.026511, finish time: 125.115689)
-> [151.329383] [dag_from_dot_simple/INFO] Activity 'c3' is complete (start time: 125.115689, finish time: 151.329383)
-> [151.743605] [dag_from_dot_simple/INFO] Activity 'c3->end' is complete (start time: 151.329383, finish time: 151.743605)
-> [151.743605] [dag_from_dot_simple/INFO] Activity 'end' is complete (start time: 151.743605, finish time: 151.743605)
\ No newline at end of file
+> [0.000000] [dag_from_dot_simple/INFO] Exec 'root' is complete (start time: 0.000000, finish time: 0.000000)
+> [33.394394] [dag_from_dot_simple/INFO] Comm 'root->c2' is complete (start time: 0.000000, finish time: 33.394394)
+> [39.832311] [dag_from_dot_simple/INFO] Comm 'root->c1' is complete (start time: 0.000000, finish time: 39.832311)
+> [50.026511] [dag_from_dot_simple/INFO] Exec 'c1' is complete (start time: 39.832311, finish time: 50.026511)
+> [98.928629] [dag_from_dot_simple/INFO] Exec 'c2' is complete (start time: 33.394394, finish time: 98.928629)
+> [125.115689] [dag_from_dot_simple/INFO] Comm 'c1->c3' is complete (start time: 50.026511, finish time: 125.115689)
+> [151.329383] [dag_from_dot_simple/INFO] Exec 'c3' is complete (start time: 125.115689, finish time: 151.329383)
+> [151.743605] [dag_from_dot_simple/INFO] Comm 'c3->end' is complete (start time: 151.329383, finish time: 151.743605)
+> [151.743605] [dag_from_dot_simple/INFO] Exec 'end' is complete (start time: 151.743605, finish time: 151.743605)
\ No newline at end of file
std::vector<simgrid::s4u::ActivityPtr> dag = simgrid::s4u::create_DAG_from_json(argv[2]);
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", activity.get_cname(),
- activity.get_start_time(), activity.get_finish_time());
+ simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) {
+ XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(),
+ exec.get_start_time(), exec.get_finish_time());
+ });
+
+ simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) {
+ XBT_INFO("Comm '%s' is complete (start time: %f, finish time: %f)", comm.get_cname(),
+ comm.get_start_time(), comm.get_finish_time());
});
e.run();
#!/usr/bin/env tesh
$ ${bindir:=.}/s4u-dag-from-json-simple --log=no_loc ${platfdir}/small_platform.xml ${srcdir:=.}/dag.json
-> [10.194200] [dag_from_json_simple/INFO] Activity 'c1' is complete (start time: 0.000000, finish time: 10.194200)
-> [65.534235] [dag_from_json_simple/INFO] Activity 'c2' is complete (start time: 0.000000, finish time: 65.534235)
-> [85.283378] [dag_from_json_simple/INFO] Activity 't1' is complete (start time: 10.194200, finish time: 85.283378)
-> [111.497072] [dag_from_json_simple/INFO] Activity 'c3' is complete (start time: 85.283378, finish time: 111.497072)
\ No newline at end of file
+> [10.194200] [dag_from_json_simple/INFO] Exec 'c1' is complete (start time: 0.000000, finish time: 10.194200)
+> [65.534235] [dag_from_json_simple/INFO] Exec 'c2' is complete (start time: 0.000000, finish time: 65.534235)
+> [85.283378] [dag_from_json_simple/INFO] Comm 't1' is complete (start time: 10.194200, finish time: 85.283378)
+> [111.497072] [dag_from_json_simple/INFO] Exec 'c3' is complete (start time: 85.283378, finish time: 111.497072)
\ No newline at end of file
int main(int argc, char* argv[])
{
sg4::Engine e(&argc, argv);
- sg_storage_file_system_init();
e.load_platform(argv[1]);
auto bob = e.host_by_name("bob");
auto carl = e.host_by_name("carl");
// Display the details on vetoed activities
- sg4::Activity::on_veto_cb([](const sg4::Activity& a) {
- XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", a.get_cname(),
- (a.dependencies_solved() ? "solved" : "NOT solved"), (a.is_assigned() ? "assigned" : "NOT assigned"));
+ sg4::Exec::on_veto_cb([](sg4::Exec const& exec) {
+ XBT_INFO("Exec '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(),
+ (exec.dependencies_solved() ? "solved" : "NOT solved"), (exec.is_assigned() ? "assigned" : "NOT assigned"));
+ });
+ sg4::Io::on_veto_cb([](sg4::Io const& io) {
+ XBT_INFO("Io '%s' vetoed. Dependencies: %s; Ressources: %s", io.get_cname(),
+ (io.dependencies_solved() ? "solved" : "NOT solved"), (io.is_assigned() ? "assigned" : "NOT assigned"));
});
- sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
- const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
- if (exec == nullptr) // Only Execs are concerned here
- return;
- XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
- exec->get_finish_time());
+ sg4::Exec::on_completion_cb([](sg4::Exec const& exec) {
+ XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(),
+ exec.get_finish_time());
});
// Create a small DAG: parent->write_output->read_input->child
$ ${bindir:=.}/s4u-dag-io ${platfdir}/hosts_with_disks.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
> [ 0.000000] (0:maestro@) 'parent' is assigned to a resource and all dependencies are solved. Let's start
-> [ 0.000000] (0:maestro@) Activity 'write' vetoed. Dependencies: NOT solved; Ressources: assigned
-> [ 0.000000] (0:maestro@) Activity 'read' vetoed. Dependencies: NOT solved; Ressources: assigned
-> [ 0.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: assigned
-> [ 1.000000] (0:maestro@) Activity 'parent' is complete (start time: 0.000000, finish time: 1.000000)
+> [ 0.000000] (0:maestro@) Io 'write' vetoed. Dependencies: NOT solved; Ressources: assigned
+> [ 0.000000] (0:maestro@) Io 'read' vetoed. Dependencies: NOT solved; Ressources: assigned
+> [ 0.000000] (0:maestro@) Exec 'child' vetoed. Dependencies: NOT solved; Ressources: assigned
+> [ 1.000000] (0:maestro@) Exec 'parent' is complete (start time: 0.000000, finish time: 1.000000)
> [ 1.000000] (0:maestro@) Remove a dependency from 'parent' on 'write'
> [ 1.000000] (0:maestro@) 'write' is assigned to a resource and all dependencies are solved. Let's start
> [ 26.000000] (0:maestro@) Remove a dependency from 'write' on 'read'
> [ 26.000000] (0:maestro@) 'read' is assigned to a resource and all dependencies are solved. Let's start
> [ 36.000000] (0:maestro@) Remove a dependency from 'read' on 'child'
> [ 36.000000] (0:maestro@) 'child' is assigned to a resource and all dependencies are solved. Let's start
-> [ 37.000000] (0:maestro@) Activity 'child' is complete (start time: 36.000000, finish time: 37.000000)
+> [ 37.000000] (0:maestro@) Exec 'child' is complete (start time: 36.000000, finish time: 37.000000)
> [ 37.000000] (0:maestro@) Simulation time 37
// We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential
// start time
data_available = *comm->get_data<double>() + redist_time;
- }
+ }
/* no transfer, control dependency */
- if (const auto* exec = dynamic_cast<sg4::Exec*>(parent.get()))
- data_available = exec->get_finish_time();
+ if (const auto* parent_exec = dynamic_cast<sg4::Exec*>(parent.get()))
+ data_available = parent_exec->get_finish_time();
if (last_data_available < data_available)
last_data_available = data_available;
std::set<sg4::Activity*> vetoed;
e.track_vetoed_activities(&vetoed);
- sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
+ sg4::Exec::on_completion_cb([](sg4::Exec const& exec) {
// when an Exec completes, we need to set the potential start time of all its ouput comms
- const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
- if (exec == nullptr) // Only Execs are concerned here
- return;
- for (const auto& succ : exec->get_successors()) {
+ for (const auto& succ : exec.get_successors()) {
auto* comm = dynamic_cast<sg4::Comm*>(succ.get());
if (comm != nullptr) {
- auto* finish_time = new double(exec->get_finish_time());
+ auto* finish_time = new double(exec.get_finish_time());
// We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential start
// time
comm->set_data(finish_time);
auto dax = sg4::create_DAG_from_DAX(argv[2]);
/* Schedule the root first */
- double finish_time;
+ double root_finish_time;
auto* root = static_cast<sg4::Exec*>(dax.front().get());
- auto host = get_best_host(root, &finish_time);
+ auto* host = get_best_host(root, &root_finish_time);
schedule_on(root, host);
e.run();
}
/* Cleanup memory */
- for (auto const& h : e.get_all_hosts())
+ for (auto const* h : e.get_all_hosts())
delete h->get_data<double>();
XBT_INFO("Simulation Time: %f", simgrid_get_clock());
auto fafard = e.host_by_name("Fafard");
// Display the details on vetoed activities
- sg4::Activity::on_veto_cb([](const sg4::Activity& a) {
- const auto& exec = static_cast<const sg4::Exec&>(a); // all activities are execs in this example
-
- XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(),
+ sg4::Exec::on_veto_cb([](sg4::Exec const& exec) {
+ XBT_INFO("Execution '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(),
(exec.dependencies_solved() ? "solved" : "NOT solved"),
(exec.is_assigned() ? "assigned" : "NOT assigned"));
});
- sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
- const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
- if (exec == nullptr) // Only Execs are concerned here
- return;
- XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
- exec->get_finish_time());
+ sg4::Exec::on_completion_cb([](sg4::Exec const& exec) {
+ XBT_INFO("Execution '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(),
+ exec.get_finish_time());
});
// Define an amount of work that should take 1 second to execute.
$ ${bindir:=.}/s4u-dag-simple ${platfdir}/small_platform.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
> [ 0.000000] (0:maestro@) 'parent 1' is assigned to a resource and all dependencies are solved. Let's start
> [ 0.000000] (0:maestro@) 'parent 2' is assigned to a resource and all dependencies are solved. Let's start
-> [ 0.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned
-> [ 2.000000] (0:maestro@) Activity 'parent 1' is complete (start time: 0.000000, finish time: 2.000000)
+> [ 0.000000] (0:maestro@) Execution 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned
+> [ 2.000000] (0:maestro@) Execution 'parent 1' is complete (start time: 0.000000, finish time: 2.000000)
> [ 2.000000] (0:maestro@) Remove a dependency from 'parent 1' on 'child'
> [ 2.000000] (0:maestro@) Activity child not ready.
-> [ 3.000000] (0:maestro@) Activity 'parent 2' is complete (start time: 0.000000, finish time: 3.000000)
+> [ 3.000000] (0:maestro@) Execution 'parent 2' is complete (start time: 0.000000, finish time: 3.000000)
> [ 3.000000] (0:maestro@) Remove a dependency from 'parent 2' on 'child'
-> [ 3.000000] (0:maestro@) Activity 'child' vetoed. Dependencies: solved; Ressources: NOT assigned
+> [ 3.000000] (0:maestro@) Execution 'child' vetoed. Dependencies: solved; Ressources: NOT assigned
> [ 3.000000] (0:maestro@) Activity child's dependencies are resolved. Let's assign it to Fafard.
> [ 3.000000] (0:maestro@) 'child' is assigned to a resource and all dependencies are solved. Let's start
-> [ 4.000000] (0:maestro@) Activity 'child' is complete (start time: 3.000000, finish time: 4.000000)
+> [ 4.000000] (0:maestro@) Execution 'child' is complete (start time: 3.000000, finish time: 4.000000)
> [ 4.000000] (0:maestro@) Simulation time 4
c1->start();
c2->start();
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", activity.get_cname(),
- activity.get_start_time(), activity.get_finish_time());
+ simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) {
+ XBT_INFO("Exec '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(),
+ exec.get_start_time(), exec.get_finish_time());
+ });
+ simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) {
+ XBT_INFO("Comm '%s' is complete (start time: %f, finish time: %f)", comm.get_cname(),
+ comm.get_start_time(), comm.get_finish_time());
});
e.run();
#!/usr/bin/env tesh
$ ${bindir:=.}/s4u-dag-tuto --log=no_loc ${platfdir}/small_platform.xml
-> [10.194200] [dag_tuto/INFO] Activity 'c1' is complete (start time: 0.000000, finish time: 10.194200)
-> [65.534235] [dag_tuto/INFO] Activity 'c2' is complete (start time: 0.000000, finish time: 65.534235)
-> [85.283378] [dag_tuto/INFO] Activity 't1' is complete (start time: 10.194200, finish time: 85.283378)
-> [111.497072] [dag_tuto/INFO] Activity 'c3' is complete (start time: 85.283378, finish time: 111.497072)
\ No newline at end of file
+> [10.194200] [dag_tuto/INFO] Exec 'c1' is complete (start time: 0.000000, finish time: 10.194200)
+> [65.534235] [dag_tuto/INFO] Exec 'c2' is complete (start time: 0.000000, finish time: 65.534235)
+> [85.283378] [dag_tuto/INFO] Comm 't1' is complete (start time: 10.194200, finish time: 85.283378)
+> [111.497072] [dag_tuto/INFO] Exec 'c3' is complete (start time: 85.283378, finish time: 111.497072)
\ No newline at end of file
#ifndef _KADEMLIA_TASK_HPP_
#define _KADEMLIA_TASK_HPP_
+#include "answer.hpp"
#include "s4u-dht-kademlia.hpp"
#include "simgrid/s4u.hpp"
// ========= A new ptask with computation and a timeout =========
start = sg4::Engine::get_clock();
- std::vector<double> cpu_amounts5{flopAmount, flopAmount};
- std::vector<double> com_amounts5{0, 0, 0, 0};
XBT_INFO("Run a task with computation on two hosts and a timeout of 20s.");
try {
+ std::vector<double> cpu_amounts5{flopAmount, flopAmount};
+ std::vector<double> com_amounts5{0, 0, 0, 0};
sg4::this_actor::exec_init(hosts, cpu_amounts5, com_amounts5)->wait_for(20);
} catch (const simgrid::TimeoutException &){
XBT_INFO("Finished WITH timeout");
sg4::Actor::create("worker", e.host_by_name("Fafard"), worker);
- sg4::Activity::on_veto_cb([&e](sg4::Activity& a) {
- auto& exec = static_cast<sg4::Exec&>(a);
+ sg4::Exec::on_veto_cb([&e](sg4::Exec& exec) {
// First display the situation
XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(),
int main(int argc, char* argv[])
{
sg4::Engine e(&argc, argv);
- sg_storage_file_system_init();
e.load_platform(argv[1]);
sg4::Actor::create("bob", e.host_by_name("bob"), test);
> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3'
> [C1:worker(2) 1.104600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1
+p 2hosts 1link NewReno (no timing change)
+
+$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/onelink.xml ${srcdir}/onelink_d.xml --cfg=network/model:ns-3 --cfg=ns3/NetworkModel:NewReno "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n"
+> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3'
+> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'ns3/NetworkModel' to 'NewReno'
+> [:maestro(0) 0.000000] [res_ns3/INFO] Switching Tcp protocol to 'NewReno'
+> [C1:worker(2) 1.104600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1
+
+p 2hosts 1link Cubic (no timing change)
+
+$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/onelink.xml ${srcdir}/onelink_d.xml --cfg=network/model:ns-3 --cfg=ns3/NetworkModel:Cubic "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n"
+> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3'
+> [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'ns3/NetworkModel' to 'Cubic'
+> [:maestro(0) 0.000000] [res_ns3/INFO] Switching Tcp protocol to 'Cubic'
+> [C1:worker(2) 1.104600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1
+
+p 2hosts 1link UDP
+
+# $ ${bindir:=.}/s4u-network-ns3 ${platfdir}/onelink.xml ${srcdir}/onelink_d.xml --cfg=network/model:ns-3 --cfg=ns3/NetworkModel:UDP "--log=root.fmt:[%h:%a(%i)%e%r]%e[%c/%p]%e%m%n"
+# > [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3'
+# > [:maestro(0) 0.000000] [xbt_cfg/INFO] Configuration change: Set 'ns3/NetworkModel' to 'UDP'
+# > [:maestro(0) 0.000000] [res_ns3/INFO] Switching network protocol to 'UDP'
+# > [C1:worker(2) 1.104600] [s4u_test/INFO] FLOW[1] : Receive 10000 bytes from S1 to C1
+
p Crosstraffic TCP option DISABLED
$ ${bindir:=.}/s4u-network-ns3 ${platfdir}/crosstraffic.xml ${srcdir}/crosstraffic_d.xml --cfg=network/model:ns-3 --cfg=network/crosstraffic:0
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'ns-3'
--- /dev/null
+/* Copyright (c) 2017-2023. 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 example demonstrate basic use of the operation plugin.
+ *
+ * We model the following graph:
+ *
+ * exec1 -> comm -> exec2
+ *
+ * exec1 and exec2 are execution operations.
+ * comm is a communication operation.
+ */
+
+#include <simgrid/plugins/file_system.h>
+#include "simgrid/plugins/operation.hpp"
+#include "simgrid/s4u.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(operation_simple, "Messages specific for this operation example");
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ e.load_platform(argv[1]);
+ simgrid::plugins::Operation::init();
+
+ // Retrieve hosts
+ auto bob = e.host_by_name("bob");
+ auto carl = e.host_by_name("carl");
+
+ // Create operations
+ auto exec1 = simgrid::plugins::ExecOp::init("exec1", 1e9, bob);
+ auto exec2 = simgrid::plugins::ExecOp::init("exec2", 1e9, carl);
+ auto write = simgrid::plugins::IoOp::init("write", 1e7, bob->get_disks().front(), simgrid::s4u::Io::OpType::WRITE);
+ auto read = simgrid::plugins::IoOp::init("read", 1e7, carl->get_disks().front(), simgrid::s4u::Io::OpType::READ);
+
+ // Create the graph by defining dependencies between operations
+ exec1->add_successor(write);
+ write->add_successor(read);
+ read->add_successor(exec2);
+
+ // Add a function to be called when operations end for log purpose
+ simgrid::plugins::Operation::on_end_cb([](const simgrid::plugins::Operation* op) {
+ XBT_INFO("Operation %s finished (%d)", op->get_name().c_str(), op->get_count());
+ });
+
+ // Enqueue two executions for operation exec1
+ exec1->enqueue_execs(2);
+
+ // Start the simulation
+ e.run();
+ return 0;
+}
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-operation-io ${platfdir}/hosts_with_disks.xml
+> [1.000000] [operation_simple/INFO] Operation exec1 finished (1)
+> [1.250000] [operation_simple/INFO] Operation write finished (1)
+> [1.350000] [operation_simple/INFO] Operation read finished (1)
+> [2.000000] [operation_simple/INFO] Operation exec1 finished (2)
+> [2.250000] [operation_simple/INFO] Operation write finished (2)
+> [2.350000] [operation_simple/INFO] Operation exec2 finished (1)
+> [2.350000] [operation_simple/INFO] Operation read finished (2)
+> [3.350000] [operation_simple/INFO] Operation exec2 finished (2)
--- /dev/null
+/* Copyright (c) 2003-2023. 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/photovoltaic.hpp"
+#include "simgrid/s4u.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(photovoltaic_simple, "Messages specific for this s4u example");
+
+static void manager()
+{
+ auto pv_panel = simgrid::s4u::Engine::get_instance()->host_by_name("pv_panel");
+ std::vector<std::pair<double, double>> solar_irradiance = {{1, 10}, {100, 5}, {200, 20}};
+ for (auto [t, s] : solar_irradiance) {
+ simgrid::s4u::this_actor::sleep_until(t);
+ sg_photovoltaic_set_solar_irradiance(pv_panel, s);
+ XBT_INFO("%s power: %f", pv_panel->get_cname(), sg_photovoltaic_get_power(pv_panel));
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+ e.load_platform(argv[1]);
+ sg_photovoltaic_plugin_init();
+ simgrid::s4u::Actor::create("manager", e.host_by_name("pv_panel"), manager);
+ e.run();
+ return 0;
+}
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-photovoltaic-simple ${platfdir}/photovoltaic_platform.xml
+> [pv_panel:manager:(1) 1.000000] [photovoltaic_simple/INFO] pv_panel power: 8.000000
+> [pv_panel:manager:(1) 100.000000] [photovoltaic_simple/INFO] pv_panel power: 4.000000
+> [pv_panel:manager:(1) 200.000000] [photovoltaic_simple/INFO] pv_panel power: 16.000000
> %EndEventDef
> 0 1 0 HOST
> 6 0.000000 1 1 0 "Tremblay"
+> 2 2 1 HOST_STATE
+> 5 3 2 receive "1 0 0"
+> 5 4 2 send "0 0 1"
+> 5 5 2 execute "0 1 1"
> 6 0.000000 2 1 0 "Jupiter"
> 6 0.000000 3 1 0 "Fafard"
> 6 0.000000 4 1 0 "Ginette"
> 6 0.000000 5 1 0 "Bourassa"
> 6 0.000000 6 1 0 "Jacquelin"
> 6 0.000000 7 1 0 "Boivin"
-> 0 2 0 LINK
-> 6 0.000000 8 2 0 "6"
-> 6 0.000000 9 2 0 "3"
-> 6 0.000000 10 2 0 "7"
-> 6 0.000000 11 2 0 "9"
-> 6 0.000000 12 2 0 "2"
-> 6 0.000000 13 2 0 "8"
-> 6 0.000000 14 2 0 "1"
-> 6 0.000000 15 2 0 "4"
-> 6 0.000000 16 2 0 "0"
-> 6 0.000000 17 2 0 "5"
-> 6 0.000000 18 2 0 "145"
-> 6 0.000000 19 2 0 "10"
-> 6 0.000000 20 2 0 "11"
-> 6 0.000000 21 2 0 "16"
-> 6 0.000000 22 2 0 "17"
-> 6 0.000000 23 2 0 "44"
-> 6 0.000000 24 2 0 "47"
-> 6 0.000000 25 2 0 "54"
-> 6 0.000000 26 2 0 "56"
-> 6 0.000000 27 2 0 "59"
-> 6 0.000000 28 2 0 "78"
-> 6 0.000000 29 2 0 "79"
-> 6 0.000000 30 2 0 "80"
-> 6 0.000000 31 2 0 "loopback"
-> 4 3 0 2 2 0-LINK2-LINK2
-> 4 4 0 1 2 0-HOST1-LINK2
-> 4 5 0 2 1 0-LINK2-HOST1
-> 15 0.000000 3 0 topology 12 0
-> 16 0.000000 3 0 topology 16 0
-> 15 0.000000 3 0 topology 9 1
-> 16 0.000000 3 0 topology 16 1
-> 15 0.000000 3 0 topology 16 2
-> 16 0.000000 3 0 topology 14 2
-> 15 0.000000 3 0 topology 21 3
-> 16 0.000000 3 0 topology 19 3
-> 15 0.000000 3 0 topology 8 4
-> 16 0.000000 3 0 topology 19 4
-> 15 0.000000 3 0 topology 19 5
-> 16 0.000000 3 0 topology 20 5
-> 15 0.000000 3 0 topology 8 6
-> 16 0.000000 3 0 topology 20 6
-> 15 0.000000 3 0 topology 27 7
-> 16 0.000000 3 0 topology 18 7
-> 15 0.000000 4 0 topology 5 8
-> 16 0.000000 4 0 topology 18 8
-> 15 0.000000 4 0 topology 4 9
-> 16 0.000000 4 0 topology 18 9
-> 15 0.000000 4 0 topology 2 10
-> 16 0.000000 4 0 topology 18 10
-> 15 0.000000 3 0 topology 16 11
-> 16 0.000000 3 0 topology 21 11
-> 15 0.000000 3 0 topology 21 12
-> 16 0.000000 3 0 topology 22 12
-> 15 0.000000 3 0 topology 9 13
-> 16 0.000000 3 0 topology 12 13
-> 15 0.000000 3 0 topology 15 14
-> 16 0.000000 3 0 topology 9 14
-> 15 0.000000 4 0 topology 1 15
-> 16 0.000000 4 0 topology 9 15
-> 15 0.000000 3 0 topology 20 16
-> 16 0.000000 3 0 topology 23 16
-> 15 0.000000 3 0 topology 23 17
-> 16 0.000000 3 0 topology 24 17
-> 15 0.000000 4 0 topology 5 18
-> 16 0.000000 4 0 topology 24 18
-> 15 0.000000 4 0 topology 4 19
-> 16 0.000000 4 0 topology 24 19
-> 15 0.000000 4 0 topology 2 20
-> 16 0.000000 4 0 topology 24 20
-> 15 0.000000 3 0 topology 11 21
-> 16 0.000000 3 0 topology 15 21
-> 15 0.000000 4 0 topology 1 22
-> 16 0.000000 4 0 topology 15 22
-> 15 0.000000 3 0 topology 12 23
-> 16 0.000000 3 0 topology 17 23
-> 15 0.000000 3 0 topology 9 24
-> 16 0.000000 3 0 topology 17 24
-> 15 0.000000 3 0 topology 22 25
-> 16 0.000000 3 0 topology 25 25
-> 15 0.000000 3 0 topology 12 26
-> 16 0.000000 3 0 topology 25 26
-> 15 0.000000 3 0 topology 25 27
-> 16 0.000000 3 0 topology 26 27
-> 15 0.000000 3 0 topology 26 28
-> 16 0.000000 3 0 topology 27 28
-> 15 0.000000 3 0 topology 14 29
-> 16 0.000000 3 0 topology 8 29
-> 15 0.000000 3 0 topology 13 30
-> 16 0.000000 3 0 topology 8 30
-> 15 0.000000 3 0 topology 11 31
-> 16 0.000000 3 0 topology 8 31
-> 15 0.000000 3 0 topology 8 32
-> 16 0.000000 3 0 topology 10 32
-> 15 0.000000 3 0 topology 30 33
-> 16 0.000000 3 0 topology 28 33
-> 15 0.000000 4 0 topology 3 34
-> 16 0.000000 4 0 topology 28 34
-> 15 0.000000 3 0 topology 28 35
-> 16 0.000000 3 0 topology 29 35
-> 15 0.000000 4 0 topology 3 36
-> 16 0.000000 4 0 topology 30 36
-> 15 0.000000 3 0 topology 14 37
-> 16 0.000000 3 0 topology 13 37
-> 15 0.000000 3 0 topology 29 38
-> 16 0.000000 3 0 topology 11 38
-> 15 0.000000 4 0 topology 1 39
-> 16 0.000000 4 0 topology 11 39
-> 15 0.000000 5 0 topology 24 40
-> 16 0.000000 5 0 topology 7 40
-> 15 0.000000 5 0 topology 10 41
-> 16 0.000000 5 0 topology 5 41
-> 15 0.000000 5 0 topology 13 42
-> 16 0.000000 5 0 topology 3 42
-> 15 0.000000 5 0 topology 17 43
-> 16 0.000000 5 0 topology 4 43
-> 15 0.000000 5 0 topology 18 44
-> 16 0.000000 5 0 topology 6 44
-> 15 0.000000 5 0 topology 11 45
-> 16 0.000000 5 0 topology 2 45
-> 0 6 1 ACTOR
-> 6 0.000000 32 6 3 "emigrant-1"
-> 2 7 6 ACTOR_STATE
-> 5 8 7 suspend "1 0 1"
-> 5 9 7 sleep "1 1 0"
-> 5 10 7 receive "1 0 0"
-> 5 11 7 send "0 0 1"
-> 5 12 7 execute "0 1 1"
-> 4 13 0 6 6 ACTOR_LINK
-> 6 0.000000 33 6 1 "policeman-2"
-> 12 0.000000 7 32 9
-> 12 0.000000 7 33 11
-> 13 2.000000 7 32
-> 12 2.000000 7 32 10
-> 13 2.025708 7 33
-> 12 2.025708 7 33 11
-> 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"
-> 16 2.025708 13 0 M 34 0
-> 12 2.025708 7 34 9
-> 13 4.025708 7 34
-> 12 4.025708 7 34 10
-> 13 4.025903 7 33
-> 12 4.025903 7 33 11
-> 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"
-> 16 4.025903 13 0 M 35 1
-> 12 4.025903 7 35 9
-> 13 6.025903 7 35
-> 12 6.025903 7 35 10
-> 13 6.044918 7 33
-> 12 6.044918 7 33 11
-> 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"
-> 16 6.044918 13 0 M 36 2
-> 12 6.044918 7 36 9
-> 13 8.044918 7 36
-> 12 8.044918 7 36 10
-> 13 8.070626 7 33
-> 12 8.070626 7 33 11
-> 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"
-> 16 8.070626 13 0 M 37 3
-> 12 8.070626 7 37 9
-> 13 10.070626 7 37
-> 12 10.070626 7 37 10
-> 13 10.087178 7 33
-> 12 10.087178 7 33 11
-> 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"
-> 16 10.087178 13 0 M 38 4
-> 12 10.087178 7 38 9
-> 13 12.087178 7 38
-> 12 12.087178 7 38 10
-> 13 12.112617 7 33
-> 12 12.112617 7 33 11
-> 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"
-> 16 12.112617 13 0 M 39 5
-> 12 12.112617 7 39 9
-> 13 14.112617 7 39
-> 12 14.112617 7 39 10
-> 13 14.138325 7 33
-> 12 14.138325 7 33 11
-> 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"
-> 16 14.138325 13 0 M 40 6
-> 12 14.138325 7 40 9
-> 13 16.138325 7 40
-> 12 16.138325 7 40 10
-> 13 16.138521 7 33
-> 12 16.138521 7 33 11
-> 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"
-> 16 16.138521 13 0 M 41 7
-> 12 16.138521 7 41 9
-> 13 18.138521 7 41
-> 12 18.138521 7 41 10
-> 13 18.155073 7 33
-> 13 18.155073 7 41
-> 7 18.155073 6 33
-> 7 18.155073 6 41
-> 7 18.155073 2 16
-> 7 18.155073 2 14
-> 7 18.155073 2 19
-> 7 18.155073 2 20
-> 7 18.155073 2 18
-> 7 18.155073 2 21
-> 7 18.155073 2 22
-> 7 18.155073 2 12
-> 7 18.155073 2 9
-> 7 18.155073 2 15
-> 7 18.155073 2 23
-> 7 18.155073 2 24
-> 7 18.155073 2 17
-> 7 18.155073 2 25
-> 7 18.155073 2 26
-> 7 18.155073 2 27
-> 7 18.155073 2 8
-> 7 18.155073 2 10
-> 7 18.155073 2 28
-> 7 18.155073 2 29
-> 7 18.155073 2 13
-> 7 18.155073 2 30
-> 7 18.155073 2 11
+> 0 6 0 LINK
+> 6 0.000000 8 6 0 "6"
+> 6 0.000000 9 6 0 "3"
+> 6 0.000000 10 6 0 "7"
+> 6 0.000000 11 6 0 "9"
+> 6 0.000000 12 6 0 "2"
+> 6 0.000000 13 6 0 "8"
+> 6 0.000000 14 6 0 "1"
+> 6 0.000000 15 6 0 "4"
+> 6 0.000000 16 6 0 "0"
+> 6 0.000000 17 6 0 "5"
+> 6 0.000000 18 6 0 "145"
+> 6 0.000000 19 6 0 "10"
+> 6 0.000000 20 6 0 "11"
+> 6 0.000000 21 6 0 "16"
+> 6 0.000000 22 6 0 "17"
+> 6 0.000000 23 6 0 "44"
+> 6 0.000000 24 6 0 "47"
+> 6 0.000000 25 6 0 "54"
+> 6 0.000000 26 6 0 "56"
+> 6 0.000000 27 6 0 "59"
+> 6 0.000000 28 6 0 "78"
+> 6 0.000000 29 6 0 "79"
+> 6 0.000000 30 6 0 "80"
+> 6 0.000000 31 6 0 "loopback"
+> 4 7 0 6 6 0-LINK6-LINK6
+> 4 8 0 1 6 0-HOST1-LINK6
+> 4 9 0 6 1 0-LINK6-HOST1
+> 15 0.000000 7 0 topology 12 0
+> 16 0.000000 7 0 topology 16 0
+> 15 0.000000 7 0 topology 9 1
+> 16 0.000000 7 0 topology 16 1
+> 15 0.000000 7 0 topology 16 2
+> 16 0.000000 7 0 topology 14 2
+> 15 0.000000 7 0 topology 21 3
+> 16 0.000000 7 0 topology 19 3
+> 15 0.000000 7 0 topology 8 4
+> 16 0.000000 7 0 topology 19 4
+> 15 0.000000 7 0 topology 19 5
+> 16 0.000000 7 0 topology 20 5
+> 15 0.000000 7 0 topology 8 6
+> 16 0.000000 7 0 topology 20 6
+> 15 0.000000 7 0 topology 27 7
+> 16 0.000000 7 0 topology 18 7
+> 15 0.000000 8 0 topology 5 8
+> 16 0.000000 8 0 topology 18 8
+> 15 0.000000 8 0 topology 4 9
+> 16 0.000000 8 0 topology 18 9
+> 15 0.000000 8 0 topology 2 10
+> 16 0.000000 8 0 topology 18 10
+> 15 0.000000 7 0 topology 16 11
+> 16 0.000000 7 0 topology 21 11
+> 15 0.000000 7 0 topology 21 12
+> 16 0.000000 7 0 topology 22 12
+> 15 0.000000 7 0 topology 9 13
+> 16 0.000000 7 0 topology 12 13
+> 15 0.000000 7 0 topology 15 14
+> 16 0.000000 7 0 topology 9 14
+> 15 0.000000 8 0 topology 1 15
+> 16 0.000000 8 0 topology 9 15
+> 15 0.000000 7 0 topology 20 16
+> 16 0.000000 7 0 topology 23 16
+> 15 0.000000 7 0 topology 23 17
+> 16 0.000000 7 0 topology 24 17
+> 15 0.000000 8 0 topology 5 18
+> 16 0.000000 8 0 topology 24 18
+> 15 0.000000 8 0 topology 4 19
+> 16 0.000000 8 0 topology 24 19
+> 15 0.000000 8 0 topology 2 20
+> 16 0.000000 8 0 topology 24 20
+> 15 0.000000 7 0 topology 11 21
+> 16 0.000000 7 0 topology 15 21
+> 15 0.000000 8 0 topology 1 22
+> 16 0.000000 8 0 topology 15 22
+> 15 0.000000 7 0 topology 12 23
+> 16 0.000000 7 0 topology 17 23
+> 15 0.000000 7 0 topology 9 24
+> 16 0.000000 7 0 topology 17 24
+> 15 0.000000 7 0 topology 22 25
+> 16 0.000000 7 0 topology 25 25
+> 15 0.000000 7 0 topology 12 26
+> 16 0.000000 7 0 topology 25 26
+> 15 0.000000 7 0 topology 25 27
+> 16 0.000000 7 0 topology 26 27
+> 15 0.000000 7 0 topology 26 28
+> 16 0.000000 7 0 topology 27 28
+> 15 0.000000 7 0 topology 14 29
+> 16 0.000000 7 0 topology 8 29
+> 15 0.000000 7 0 topology 13 30
+> 16 0.000000 7 0 topology 8 30
+> 15 0.000000 7 0 topology 11 31
+> 16 0.000000 7 0 topology 8 31
+> 15 0.000000 7 0 topology 8 32
+> 16 0.000000 7 0 topology 10 32
+> 15 0.000000 7 0 topology 30 33
+> 16 0.000000 7 0 topology 28 33
+> 15 0.000000 8 0 topology 3 34
+> 16 0.000000 8 0 topology 28 34
+> 15 0.000000 7 0 topology 28 35
+> 16 0.000000 7 0 topology 29 35
+> 15 0.000000 8 0 topology 3 36
+> 16 0.000000 8 0 topology 30 36
+> 15 0.000000 7 0 topology 14 37
+> 16 0.000000 7 0 topology 13 37
+> 15 0.000000 7 0 topology 29 38
+> 16 0.000000 7 0 topology 11 38
+> 15 0.000000 8 0 topology 1 39
+> 16 0.000000 8 0 topology 11 39
+> 15 0.000000 9 0 topology 24 40
+> 16 0.000000 9 0 topology 7 40
+> 15 0.000000 9 0 topology 10 41
+> 16 0.000000 9 0 topology 5 41
+> 15 0.000000 9 0 topology 13 42
+> 16 0.000000 9 0 topology 3 42
+> 15 0.000000 9 0 topology 17 43
+> 16 0.000000 9 0 topology 4 43
+> 15 0.000000 9 0 topology 18 44
+> 16 0.000000 9 0 topology 6 44
+> 15 0.000000 9 0 topology 11 45
+> 16 0.000000 9 0 topology 2 45
+> 0 10 1 ACTOR
+> 6 0.000000 32 10 3 "emigrant-1"
+> 2 11 10 ACTOR_STATE
+> 5 12 11 suspend "1 0 1"
+> 5 13 11 sleep "1 1 0"
+> 5 14 11 receive "1 0 0"
+> 5 15 11 send "0 0 1"
+> 5 16 11 execute "0 1 1"
+> 4 17 0 10 10 ACTOR_LINK
+> 6 0.000000 33 10 1 "policeman-2"
+> 12 0.000000 11 32 13
+> 12 0.000000 11 33 15
+> 13 2.000000 11 32
+> 12 2.000000 11 32 14
+> 13 2.025708 11 33
+> 13 2.025708 11 32
+> 12 2.025708 11 33 15
+> 15 2.025708 17 0 M 32 0
+> 7 2.025708 10 32
+> 6 2.025708 34 10 1 "emigrant-1"
+> 16 2.025708 17 0 M 34 0
+> 12 2.025708 11 34 13
+> 13 4.025708 11 34
+> 12 4.025708 11 34 14
+> 13 4.025903 11 33
+> 13 4.025903 11 34
+> 12 4.025903 11 33 15
+> 15 4.025903 17 0 M 34 1
+> 7 4.025903 10 34
+> 6 4.025903 35 10 2 "emigrant-1"
+> 16 4.025903 17 0 M 35 1
+> 12 4.025903 11 35 13
+> 13 6.025903 11 35
+> 12 6.025903 11 35 14
+> 13 6.044918 11 33
+> 13 6.044918 11 35
+> 12 6.044918 11 33 15
+> 15 6.044918 17 0 M 35 2
+> 7 6.044918 10 35
+> 6 6.044918 36 10 3 "emigrant-1"
+> 16 6.044918 17 0 M 36 2
+> 12 6.044918 11 36 13
+> 13 8.044918 11 36
+> 12 8.044918 11 36 14
+> 13 8.070626 11 33
+> 13 8.070626 11 36
+> 12 8.070626 11 33 15
+> 15 8.070626 17 0 M 36 3
+> 7 8.070626 10 36
+> 6 8.070626 37 10 4 "emigrant-1"
+> 16 8.070626 17 0 M 37 3
+> 12 8.070626 11 37 13
+> 13 10.070626 11 37
+> 12 10.070626 11 37 14
+> 13 10.087178 11 33
+> 13 10.087178 11 37
+> 12 10.087178 11 33 15
+> 15 10.087178 17 0 M 37 4
+> 7 10.087178 10 37
+> 6 10.087178 38 10 5 "emigrant-1"
+> 16 10.087178 17 0 M 38 4
+> 12 10.087178 11 38 13
+> 13 12.087178 11 38
+> 12 12.087178 11 38 14
+> 13 12.112617 11 33
+> 13 12.112617 11 38
+> 12 12.112617 11 33 15
+> 15 12.112617 17 0 M 38 5
+> 7 12.112617 10 38
+> 6 12.112617 39 10 3 "emigrant-1"
+> 16 12.112617 17 0 M 39 5
+> 12 12.112617 11 39 13
+> 13 14.112617 11 39
+> 12 14.112617 11 39 14
+> 13 14.138325 11 33
+> 13 14.138325 11 39
+> 12 14.138325 11 33 15
+> 15 14.138325 17 0 M 39 6
+> 7 14.138325 10 39
+> 6 14.138325 40 10 1 "emigrant-1"
+> 16 14.138325 17 0 M 40 6
+> 12 14.138325 11 40 13
+> 13 16.138325 11 40
+> 12 16.138325 11 40 14
+> 13 16.138521 11 33
+> 13 16.138521 11 40
+> 12 16.138521 11 33 15
+> 15 16.138521 17 0 M 40 7
+> 7 16.138521 10 40
+> 6 16.138521 41 10 4 "emigrant-1"
+> 16 16.138521 17 0 M 41 7
+> 12 16.138521 11 41 13
+> 13 18.138521 11 41
+> 12 18.138521 11 41 14
+> 13 18.155073 11 33
+> 13 18.155073 11 41
+> 7 18.155073 10 33
+> 7 18.155073 10 41
+> 7 18.155073 6 16
+> 7 18.155073 6 14
+> 7 18.155073 6 19
+> 7 18.155073 6 20
+> 7 18.155073 6 18
+> 7 18.155073 6 21
+> 7 18.155073 6 22
+> 7 18.155073 6 12
+> 7 18.155073 6 9
+> 7 18.155073 6 15
+> 7 18.155073 6 23
+> 7 18.155073 6 24
+> 7 18.155073 6 17
+> 7 18.155073 6 25
+> 7 18.155073 6 26
+> 7 18.155073 6 27
+> 7 18.155073 6 8
+> 7 18.155073 6 10
+> 7 18.155073 6 28
+> 7 18.155073 6 29
+> 7 18.155073 6 13
+> 7 18.155073 6 30
+> 7 18.155073 6 11
> 7 18.155073 1 7
> 7 18.155073 1 5
> 7 18.155073 1 3
> 7 18.155073 1 6
> 7 18.155073 1 2
> 7 18.155073 1 1
-> 7 18.155073 2 31
+> 7 18.155073 6 31
$ rm -f procmig.trace
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+ <zone id="world" routing="Floyd">
+ <host id="pv_panel" speed="0f">
+ <prop id="photovoltaic_area" value="4" />
+ <prop id="photovoltaic_conversion_efficiency" value="0.2" />
+ </host>
+ </zone>
+</platform>
comm-wait comm-waitall comm-waitallfor comm-waitany comm-failure comm-host2host comm-pingpong
comm-ready comm-suspend comm-testany comm-throttling comm-waitallfor comm-waituntil
exec-async exec-basic exec-dvfs exec-remote exec-ptask
+ operation-io operation-simple operation-switch-host operation-variable-load
platform-comm-serialize platform-profile platform-failures
network-nonlinear clusters-multicpu io-degradation exec-cpu-nonlinear
synchro-barrier synchro-mutex synchro-semaphore)
--- /dev/null
+# Copyright (c) 2006-2023. 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.
+
+from argparse import ArgumentParser
+import sys
+from simgrid import Engine, Operation, ExecOp, IoOp, IoOpType
+
+def parse():
+ parser = ArgumentParser()
+ parser.add_argument(
+ '--platform',
+ type=str,
+ required=True,
+ help='path to the platform description'
+ )
+ return parser.parse_args()
+
+def callback(op):
+ print(f'[{Engine.clock}] Operation {op} finished ({op.count})')
+
+if __name__ == '__main__':
+ args = parse()
+ e = Engine(sys.argv)
+ e.load_platform(args.platform)
+ Operation.init()
+
+ # Retrieve hosts
+ bob = e.host_by_name('bob')
+ carl = e.host_by_name('carl')
+
+ # Create operations
+ exec1 = ExecOp.init("exec1", 1e9, bob)
+ exec2 = ExecOp.init("exec2", 1e9, carl)
+ write = IoOp.init("write", 1e7, bob.disks[0], IoOpType.WRITE)
+ read = IoOp.init("read", 1e7, carl.disks[0], IoOpType.READ)
+
+ # Create the graph by defining dependencies between operations
+ exec1.add_successor(write)
+ write.add_successor(read)
+ read.add_successor(exec2)
+
+ # Add a function to be called when operations end for log purpose
+ Operation.on_end_cb(callback)
+
+ # Enqueue two executions for operation exec1
+ exec1.enqueue_execs(2)
+
+ # runs the simulation
+ e.run()
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/operation-io.py --platform ${platfdir}/hosts_with_disks.xml
+> [1.0] Operation ExecOp(exec1) finished (1)
+> [1.25] Operation IoOp(write) finished (1)
+> [1.35] Operation IoOp(read) finished (1)
+> [2.0] Operation ExecOp(exec1) finished (2)
+> [2.25] Operation IoOp(write) finished (2)
+> [2.35] Operation ExecOp(exec2) finished (1)
+> [2.35] Operation IoOp(read) finished (2)
+> [3.35] Operation ExecOp(exec2) finished (2)
+
--- /dev/null
+# Copyright (c) 2006-2023. 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 example demonstrates basic use of the operation plugin.
+We model the following graph:
+
+exec1 -> comm -> exec2
+
+exec1 and exec2 are execution operations.
+comm is a communication operation.
+"""
+
+from argparse import ArgumentParser
+import sys
+from simgrid import Engine, Operation, CommOp, ExecOp
+
+def parse():
+ parser = ArgumentParser()
+ parser.add_argument(
+ '--platform',
+ type=str,
+ required=True,
+ help='path to the platform description'
+ )
+ return parser.parse_args()
+
+def callback(op):
+ print(f'[{Engine.clock}] Operation {op} finished ({op.count})')
+
+if __name__ == '__main__':
+ args = parse()
+ e = Engine(sys.argv)
+ e.load_platform(args.platform)
+ Operation.init()
+
+ # Retrieve hosts
+ tremblay = e.host_by_name('Tremblay')
+ jupiter = e.host_by_name('Jupiter')
+
+ # Create operations
+ exec1 = ExecOp.init("exec1", 1e9, tremblay)
+ exec2 = ExecOp.init("exec2", 1e9, jupiter)
+ comm = CommOp.init("comm", 1e7, tremblay, jupiter)
+
+ # Create the graph by defining dependencies between operations
+ exec1.add_successor(comm)
+ comm.add_successor(exec2)
+
+ # Add a function to be called when operations end for log purpose
+ Operation.on_end_cb(callback)
+
+ # Enqueue two executions for operation exec1
+ exec1.enqueue_execs(2)
+
+ # runs the simulation
+ e.run()
+
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/operation-simple.py --platform ${platfdir}/small_platform.xml
+> [10.194199500484224] Operation ExecOp(exec1) finished (1)
+> [11.714617112501687] Operation CommOp(comm) finished (1)
+> [20.388399000968448] Operation ExecOp(exec1) finished (2)
+> [21.90881661298591] Operation CommOp(comm) finished (2)
+> [24.82146412938331] Operation ExecOp(exec2) finished (1)
+> [37.92831114626493] Operation ExecOp(exec2) finished (2)
--- /dev/null
+# Copyright (c) 2006-2023. 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 example demonstrates how to dynamically modify a graph of operations.
+ *
+ * Assuming we have two instances of a service placed on different hosts,
+ * we want to send data alternatively to thoses instances.
+ *
+ * We consider the following graph:
+
+ comm1
+ ┌────────────────────────┐
+ │ │
+ │ Fafard │
+ │ ┌───────┐ │
+ │ ┌──────►│ exec1 ├─┘
+ ▼ │ └───────┘
+ Tremblay ──┤comm0
+ ▲ │ Jupiter
+ │ │ ┌───────┐
+ │ └──────►│ exec2 ├─┐
+ │ └───────┘ │
+ │ │
+ └────────────────────────┘
+ comm2
+ */
+ """
+
+from argparse import ArgumentParser
+import sys
+from simgrid import Engine, Operation, CommOp, ExecOp
+
+def parse():
+ parser = ArgumentParser()
+ parser.add_argument(
+ '--platform',
+ type=str,
+ required=True,
+ help='path to the platform description'
+ )
+ return parser.parse_args()
+
+def callback(op):
+ print(f'[{Engine.clock}] Operation {op} finished ({op.count})')
+
+def switch(op, hosts, execs):
+ comm0.destination = hosts[op.count % 2]
+ comm0.remove_successor(execs[op.count % 2 - 1])
+ comm0.add_successor(execs[op.count % 2])
+
+if __name__ == '__main__':
+ args = parse()
+ e = Engine(sys.argv)
+ e.load_platform(args.platform)
+ Operation.init()
+
+ # Retrieve hosts
+ tremblay = e.host_by_name('Tremblay')
+ jupiter = e.host_by_name('Jupiter')
+ fafard = e.host_by_name('Fafard')
+
+ # Create operations
+ comm0 = CommOp.init("comm0")
+ comm0.bytes = 1e7
+ comm0.source = tremblay
+ exec1 = ExecOp.init("exec1", 1e9, jupiter)
+ exec2 = ExecOp.init("exec2", 1e9, fafard)
+ comm1 = CommOp.init("comm1", 1e7, jupiter, tremblay)
+ comm2 = CommOp.init("comm2", 1e7, fafard, tremblay)
+
+ # Create the initial graph by defining dependencies between operations
+ exec1.add_successor(comm1)
+ exec2.add_successor(comm2)
+
+ # Add a function to be called when operations end for log purpose
+ Operation.on_end_cb(callback)
+
+ # Add a function to be called before each executions of comm0
+ # This function modifies the graph of operations by adding or removing
+ # successors to comm0
+ comm0.on_this_start(lambda op: switch(op, [jupiter, fafard], [exec1,exec2]))
+
+ # Enqueue two executions for operation exec1
+ comm0.enqueue_execs(4)
+
+ # runs the simulation
+ e.run()
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/operation-switch-host.py --platform ${platfdir}/small_platform.xml
+> [1.5204176120174615] Operation CommOp(comm0) finished (1)
+> [2.873012467069035] Operation CommOp(comm0) finished (2)
+> [4.393430079086497] Operation CommOp(comm0) finished (3)
+> [5.74602493413807] Operation CommOp(comm0) finished (4)
+> [14.62726462889908] Operation ExecOp(exec1) finished (1)
+> [15.979859483950655] Operation ExecOp(exec2) finished (1)
+> [16.14768224091654] Operation CommOp(comm1) finished (1)
+> [17.33245433900223] Operation CommOp(comm2) finished (1)
+> [27.7341116457807] Operation ExecOp(exec1) finished (2)
+> [29.086706500832275] Operation ExecOp(exec2) finished (2)
+> [29.25452925779816] Operation CommOp(comm1) finished (2)
+> [30.43930135588385] Operation CommOp(comm2) finished (2)
--- /dev/null
+# Copyright (c) 2006-2023. 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 example demonstrates how to create a variable load for operations.
+We consider the following graph:
+
+comm -> exec
+
+With a small load each comm operation is followed by an exec operation.
+With a heavy load there is a burst of comm before the exec operation can even finish once.
+"""
+
+from argparse import ArgumentParser
+import sys
+from simgrid import Engine, Operation, CommOp, ExecOp, Actor, this_actor
+
+def parse():
+ parser = ArgumentParser()
+ parser.add_argument(
+ '--platform',
+ type=str,
+ required=True,
+ help='path to the platform description'
+ )
+ return parser.parse_args()
+
+def callback(op):
+ print(f'[{Engine.clock}] Operation {op} finished ({op.count})')
+
+def variable_load(op):
+ print('--- Small load ---')
+ for i in range(3):
+ op.enqueue_execs(1)
+ this_actor.sleep_for(100)
+ this_actor.sleep_for(1000)
+ print('--- Heavy load ---')
+ for i in range(3):
+ op.enqueue_execs(1)
+ this_actor.sleep_for(1)
+
+if __name__ == '__main__':
+ args = parse()
+ e = Engine(sys.argv)
+ e.load_platform(args.platform)
+ Operation.init()
+
+ # Retrieve hosts
+ tremblay = e.host_by_name('Tremblay')
+ jupiter = e.host_by_name('Jupiter')
+
+ # Create operations
+ comm = CommOp.init("comm", 1e7, tremblay, jupiter)
+ exec = ExecOp.init("exec", 1e9, jupiter)
+
+ # Create the graph by defining dependencies between operations
+ comm.add_successor(exec)
+
+ # Add a function to be called when operations end for log purpose
+ Operation.on_end_cb(callback)
+
+ # Create the actor that will inject load during the simulation
+ Actor.create("input", tremblay, variable_load, comm)
+
+ # runs the simulation
+ e.run()
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/operation-variable-load.py --platform ${platfdir}/small_platform.xml
+> --- Small load ---
+> [1.5204176120174615] Operation CommOp(comm) finished (1)
+> [14.62726462889908] Operation ExecOp(exec) finished (1)
+> [101.52041761201747] Operation CommOp(comm) finished (2)
+> [114.62726462889908] Operation ExecOp(exec) finished (2)
+> [201.52041761201744] Operation CommOp(comm) finished (3)
+> [214.62726462889907] Operation ExecOp(exec) finished (3)
+> --- Heavy load ---
+> [1301.5204176120174] Operation CommOp(comm) finished (4)
+> [1303.0408352240347] Operation CommOp(comm) finished (5)
+> [1304.561252836052] Operation CommOp(comm) finished (6)
+> [1314.627264628899] Operation ExecOp(exec) finished (4)
+> [1327.7341116457806] Operation ExecOp(exec) finished (5)
+> [1340.8409586626622] Operation ExecOp(exec) finished (6)
+
+
}
namespace resource {
class Action;
+class CpuAction;
class CpuImpl;
class Model;
class Resource;
#include <set>
#include <string>
-namespace simgrid {
-namespace instr {
+namespace simgrid::instr {
/* User-variables related functions*/
/* for host variables */
XBT_PUBLIC void declare_host_variable(const std::string& variable, const std::string& color = "");
XBT_PUBLIC void platform_graph_export_graphviz(const std::string& output_filename);
/* Function used by graphicator (transform a SimGrid platform file in a CSV file with the network topology) */
XBT_PUBLIC void platform_graph_export_csv(const std::string& output_filename);
-} // namespace instr
-} // namespace simgrid
+} // namespace simgrid::instr
#endif
SG_BEGIN_DECL
#include <simgrid/forward.h>
#include <functional>
-namespace simgrid {
-namespace kernel {
-namespace profile {
-
+namespace simgrid::kernel::profile {
/** @brief Modeling of the availability profile (due to an external load) or the churn
*
static Profile* from_callback(const std::string& name, const std::function<UpdateCb>& cb, double repeat_delay);
};
-} // namespace profile
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::profile
#endif /* SIMGRID_KERNEL_PROFILEBUILDER_HPP */
#include <boost/heap/fibonacci_heap.hpp>
-namespace simgrid {
-namespace kernel {
-namespace timer {
+namespace simgrid::kernel::timer {
inline auto& kernel_timers() // avoid static initialization order fiasco
{
static bool execute_all();
};
-} // namespace timer
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::timer
#endif /* SRC_KERNEL_TIMER_TIMER_HPP_ */
#include <boost/heap/pairing_heap.hpp>
#include <boost/optional.hpp>
#include <string>
+#include <string_view>
static constexpr double NO_MAX_DURATION = -1.0;
-namespace simgrid {
-namespace kernel {
-namespace resource {
+namespace simgrid::kernel::resource {
using heap_element_type = std::pair<double, Action*>;
using heap_type =
/** @brief Get the tracing category associated to the current action */
const std::string& get_category() const { return category_; }
/** @brief Set the tracing category of the current Action */
- void set_category(const std::string& category) { category_ = category; }
+ void set_category(std::string_view category) { category_ = category; }
/** @brief Get the sharing_penalty (RTT or 1/thread_count) of the current Action */
double get_sharing_penalty() const { return sharing_penalty_; };
void set_suspend_state(Action::SuspendStates state) { suspended_ = state; }
};
-} // namespace resource
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::resource
#endif
#include <simgrid/kernel/resource/Action.hpp>
#include <unordered_map>
-namespace simgrid {
-namespace kernel {
-namespace resource {
+namespace simgrid::kernel::resource {
class XBT_PUBLIC Model {
public:
ActionHeap action_heap_;
};
-} // namespace resource
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::resource
#endif
#include <unordered_map>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/**
* @brief Placeholder for old ClusterZone class
return node_pos_with_loopback(id) + (has_limiter_ ? 1 : 0);
}
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_CLUSTER_HPP_ */
#include <simgrid/kernel/routing/RoutedZone.hpp>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone with an explicit routing computed on need with Dijkstra
void add_route(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst,
const std::vector<s4u::LinkInRoute>& link_list, bool symmetrical) override;
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_DIJKSTRA_HPP_ */
#include <simgrid/kernel/routing/ClusterZone.hpp>
#include <simgrid/s4u/Link.hpp>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
class DragonflyRouter {
public:
unsigned int num_links_per_link_ = 1; // splitduplex -> 2, only for local link
std::vector<DragonflyRouter> routers_;
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif
#include <simgrid/kernel/routing/NetZoneImpl.hpp>
#include <xbt/asserts.h>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone with no routing, useful with the constant network model
void get_graph(const s_xbt_graph_t* graph, std::map<std::string, xbt_node_t, std::less<>>* /*nodes*/,
std::map<std::string, xbt_edge_t, std::less<>>* /*edges*/) override;
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_NONE_HPP_ */
#include <simgrid/kernel/routing/ClusterZone.hpp>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
class XBT_PRIVATE FatTreeLink;
void build_upper_levels(const s4u::ClusterCallbacks& set_callbacks);
void generate_dot_file(const std::string& filename = "fat_tree.dot") const;
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif
#include <simgrid/kernel/routing/RoutedZone.hpp>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone with an explicit routing computed at initialization with Floyd-Warshal
void add_route(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst,
const std::vector<s4u::LinkInRoute>& link_list, bool symmetrical) override;
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_FLOYD_HPP_ */
#include <simgrid/kernel/routing/RoutedZone.hpp>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone with an explicit routing provided by the user
void add_route(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst,
const std::vector<s4u::LinkInRoute>& link_list, bool symmetrical) override;
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_FULL_HPP_ */
extern template class XBT_PUBLIC xbt::Extendable<kernel::routing::NetPoint>;
-namespace kernel {
-namespace routing {
+namespace kernel::routing {
/** @ingroup ROUTING_API
* @brief Network cards are the vertices in the graph representing the network, used to compute paths between nodes.
NetPoint::Type component_type_;
NetZoneImpl* englobing_zone_ = nullptr;
};
-} // namespace routing
-} // namespace kernel
+} // namespace kernel::routing
} // namespace simgrid
XBT_PUBLIC simgrid::kernel::routing::NetPoint* sg_netpoint_by_name_or_null(const char* name);
#include <unordered_set>
#include <vector>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
class Route {
public:
virtual resource::StandardLinkImpl* do_create_link(const std::string& name, const std::vector<double>& bandwidths);
void add_child(NetZoneImpl* new_zone);
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_NETZONEIMPL_HPP */
#include <simgrid/kernel/routing/NetZoneImpl.hpp>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone with an explicit routing (abstract class)
void add_route_check_params(NetPoint* src, NetPoint* dst, NetPoint* gw_src, NetPoint* gw_dst,
const std::vector<s4u::LinkInRoute>& link_list, bool symmetrical) const;
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_GENERIC_HPP_ */
#include <unordered_map>
#include <unordered_set>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone where components are connected following a star topology
bool symmetrical) const;
std::unordered_map<unsigned long, StarRoute> routes_;
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_KERNEL_ROUTING_STARZONE_HPP_ */
#include <vector>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone using a Torus topology
static std::vector<unsigned long> parse_topo_parameters(const std::string& topo_parameters);
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif
#include <simgrid/kernel/routing/StarZone.hpp>
#include <xbt/Extendable.hpp>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone modeling peers connected to the cloud through a private link
std::vector<double> coords;
};
} // namespace vivaldi
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_VIVALDI_HPP_ */
#include <simgrid/kernel/routing/RoutedZone.hpp>
-namespace simgrid {
-namespace kernel {
-namespace routing {
+namespace simgrid::kernel::routing {
/** @ingroup ROUTING_API
* @brief NetZone modeling a Wifi zone
void get_local_route(const NetPoint* src, const NetPoint* dst, Route* into, double* latency) override;
NetPoint* get_access_point() const { return access_point_; }
};
-} // namespace routing
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::routing
#endif /* SIMGRID_ROUTING_WIFI_HPP_ */
/** Stock implementation of a generic monitored queue to solve the producer-consumer problem */
-namespace simgrid {
-namespace plugin {
+namespace simgrid::plugin {
template <typename T> class ProducerConsumer;
template <typename T> using ProducerConsumerPtr = boost::intrusive_ptr<ProducerConsumer<T>>;
*/
ProducerConsumer* set_max_queue_size(unsigned int max_queue_size)
{
- const std::lock_guard<s4u::Mutex> lock(*mutex_);
+ const std::scoped_lock lock(*mutex_);
max_queue_size_ = max_queue_size;
return this;
}
*/
s4u::CommPtr put_async(T* data, size_t simulated_size_in_bytes)
{
- std::unique_lock<s4u::Mutex> lock(*mutex_);
+ std::unique_lock lock(*mutex_);
s4u::CommPtr comm = nullptr;
XBT_CVERB(producer_consumer, (size() < max_queue_size_) ? "can put" : "must wait");
*/
s4u::CommPtr get_async(T** data)
{
- std::unique_lock<s4u::Mutex> lock(*mutex_);
+ std::unique_lock lock(*mutex_);
s4u::CommPtr comm = nullptr;
XBT_CVERB(producer_consumer, empty() ? "must wait" : "can get");
while (empty())
}
};
-} // namespace plugin
-} // namespace simgrid
+} // namespace simgrid::plugin
#endif // SIMGRID_PLUGIN_PRODUCERCONSUMER_HPP
#define SIMGRID_PLUGINS_OPERATION_H_
#include <simgrid/s4u/Activity.hpp>
+#include <simgrid/s4u/Io.hpp>
#include <xbt/Extendable.hpp>
#include <atomic>
using CommOpPtr = boost::intrusive_ptr<CommOp>;
XBT_PUBLIC void intrusive_ptr_release(CommOp* c);
XBT_PUBLIC void intrusive_ptr_add_ref(CommOp* c);
+class IoOp;
+using IoOpPtr = boost::intrusive_ptr<IoOp>;
+XBT_PUBLIC void intrusive_ptr_release(IoOp* i);
+XBT_PUBLIC void intrusive_ptr_add_ref(IoOp* i);
struct ExtendedAttributeActivity {
static simgrid::xbt::Extension<simgrid::s4u::Activity, ExtendedAttributeActivity> EXTENSION_ID;
};
class Operation {
-private:
static bool inited_;
std::set<Operation*> successors_ = {};
std::map<Operation*, unsigned int> predecessors_ = {};
int count_ = 0;
bool working_ = false;
s4u::ActivityPtr current_activity_;
- std::function<void(Operation*)> end_func_;
- std::function<void(Operation*)> start_func_;
+ std::vector<std::function<void(Operation*)>> end_func_handlers_;
+ std::vector<std::function<void(Operation*)>> start_func_handlers_;
explicit Operation(const std::string& name);
virtual ~Operation() = default;
virtual void execute() = 0;
};
class ExecOp : public Operation {
-private:
s4u::Host* host_;
explicit ExecOp(const std::string& name);
};
class CommOp : public Operation {
-private:
s4u::Host* source_;
s4u::Host* destination_;
s4u::Host* get_destination() const { return destination_; }
CommOpPtr set_bytes(double bytes);
double get_bytes() const { return get_amount(); }
- friend void inline intrusive_ptr_release(CommOp* c) { intrusive_ptr_release(static_cast<Operation*>(c)); }
+ friend void inline intrusive_ptr_release(CommOp* c) { intrusive_ptr_release(static_cast<Operation*>(c)); }
friend void inline intrusive_ptr_add_ref(CommOp* c) { intrusive_ptr_add_ref(static_cast<Operation*>(c)); }
+};
+
+class IoOp : public Operation {
+ s4u::Disk* disk_;
+ s4u::Io::OpType type_;
+ explicit IoOp(const std::string& name);
+ void execute() override;
+public:
+ static IoOpPtr init(const std::string& name);
+ static IoOpPtr init(const std::string& name, double bytes, s4u::Disk* disk, s4u::Io::OpType type);
+ IoOpPtr set_disk(s4u::Disk* disk);
+ s4u::Disk* get_disk() const { return disk_; }
+ IoOpPtr set_bytes(double bytes);
+ double get_bytes() { return get_amount(); }
+ IoOpPtr set_op_type(s4u::Io::OpType type);
+ s4u::Io::OpType get_op_type() { return type_; }
+
+ friend void inline intrusive_ptr_release(IoOp* i) { intrusive_ptr_release(static_cast<Operation*>(i)); }
+ friend void inline intrusive_ptr_add_ref(IoOp* i) { intrusive_ptr_add_ref(static_cast<Operation*>(i)); }
};
} // namespace simgrid::plugins
#endif
--- /dev/null
+#ifndef SIMGRID_PLUGINS_PHOTOVOLTAIC_H_
+#define SIMGRID_PLUGINS_PHOTOVOLTAIC_H_
+
+#include <simgrid/config.h>
+#include <simgrid/forward.h>
+#include <xbt/base.h>
+
+SG_BEGIN_DECL
+
+XBT_PUBLIC void sg_photovoltaic_plugin_init();
+
+XBT_PUBLIC void sg_photovoltaic_set_solar_irradiance(const_sg_host_t host, double s);
+
+XBT_PUBLIC double sg_photovoltaic_get_power(const_sg_host_t host);
+
+SG_END_DECL
+
+#endif
#include <simgrid/forward.h>
#include <stdexcept>
#include <string>
+#include <string_view>
#include <vector>
#include <xbt/Extendable.hpp>
#include <xbt/asserts.h>
{
if(this == a)
throw std::invalid_argument("Cannot be its own successor");
- auto p = std::find_if(successors_.begin(), successors_.end(), [a](ActivityPtr const& i){ return i.get() == a.get(); });
- if (p != successors_.end())
+
+ if (std::any_of(begin(successors_), end(successors_), [a](ActivityPtr const& i) { return i.get() == a.get(); }))
throw std::invalid_argument("Dependency already exists");
successors_.push_back(a);
if(this == a)
throw std::invalid_argument("Cannot ask to remove itself from successors list");
- auto p = std::find_if(successors_.begin(), successors_.end(), [a](ActivityPtr const& i){ return i.get() == a.get(); });
- if (p != successors_.end()){
- successors_.erase(p);
- a->dependencies_.erase({this});
- } else
+ auto p =
+ std::find_if(successors_.begin(), successors_.end(), [a](ActivityPtr const& i) { return i.get() == a.get(); });
+ if (p == successors_.end())
throw std::invalid_argument("Dependency does not exist. Can not be removed.");
+
+ successors_.erase(p);
+ a->dependencies_.erase({this});
}
static std::set<Activity*>* vetoed_activities_;
* It is forbidden to change the amount of work once the Activity is started */
Activity* set_remaining(double remains);
-private:
- static xbt::signal<void(Activity&)> on_veto;
- static xbt::signal<void(Activity const&)> on_completion;
- static xbt::signal<void(Activity const&)> on_suspended;
- static xbt::signal<void(Activity const&)> on_resumed;
+ virtual void fire_on_completion() const = 0;
+ virtual void fire_on_this_completion() const = 0;
+ virtual void fire_on_suspend() const = 0;
+ virtual void fire_on_this_suspend() const = 0;
+ virtual void fire_on_resume() const = 0;
+ virtual void fire_on_this_resume() const = 0;
+ virtual void fire_on_veto() const = 0;
+ virtual void fire_on_this_veto() const = 0;
public:
- /*! Add a callback fired each time that the activity fails to start because of a veto (e.g., unsolved dependency or no
- * resource assigned) */
- static void on_veto_cb(const std::function<void(Activity&)>& cb) { on_veto.connect(cb); }
- /*! Add a callback fired when the activity completes (either normally, cancelled or failed) */
- static void on_completion_cb(const std::function<void(Activity const&)>& cb) { on_completion.connect(cb); }
- /*! Add a callback fired when the activity is suspended */
- static void on_suspended_cb(const std::function<void(Activity const&)>& cb) { on_suspended.connect(cb); }
- /*! Add a callback fired when the activity is resumed after being suspended */
- static void on_resumed_cb(const std::function<void(Activity const&)>& cb) { on_resumed.connect(cb); }
-
XBT_ATTRIB_DEPRECATED_v334("All start() are vetoable now. Please use start() ") void vetoable_start()
{
start();
} else {
if (vetoed_activities_ != nullptr)
vetoed_activities_->insert(this);
- on_veto(*this);
+ fire_on_veto();
+ fire_on_this_veto();
}
}
// released by the on_completion() callbacks.
ActivityPtr keepalive(this);
state_ = state;
- on_completion(*this);
+ fire_on_completion();
+ fire_on_this_completion();
if (state == State::FINISHED)
release_dependencies();
}
std::string name_ = "unnamed";
std::string tracing_category_ = "";
+protected:
+ inline static xbt::signal<void(AnyActivity const&)> on_completion;
+ xbt::signal<void(AnyActivity const&)> on_this_completion;
+ inline static xbt::signal<void(AnyActivity const&)> on_suspend;
+ xbt::signal<void(AnyActivity const&)> on_this_suspend;
+ inline static xbt::signal<void(AnyActivity const&)> on_resume;
+ xbt::signal<void(AnyActivity const&)> on_this_resume;
+ inline static xbt::signal<void(AnyActivity&)> on_veto;
+ xbt::signal<void(AnyActivity&)> on_this_veto;
+
public:
+ /*! \static Add a callback fired when any activity completes (either normally, cancelled or failed) */
+ static void on_completion_cb(const std::function<void(AnyActivity const&)>& cb) { on_completion.connect(cb); }
+ /*! Add a callback fired when this specific activity completes (either normally, cancelled or failed) */
+ void on_this_completion_cb(const std::function<void(AnyActivity const&)>& cb) { on_this_completion.connect(cb); }
+ /*! \static Add a callback fired when any activity is suspended */
+ static void on_suspend_cb(const std::function<void(AnyActivity const&)>& cb) { on_suspend.connect(cb); }
+ /*! Add a callback fired when this specific activity is suspended */
+ void on_this_suspend_cb(const std::function<void(AnyActivity const&)>& cb) { on_this_suspend.connect(cb); }
+ /*! \static Add a callback fired when any activity is resumed after being suspended */
+ static void on_resume_cb(const std::function<void(AnyActivity const&)>& cb) { on_resume.connect(cb); }
+ /*! Add a callback fired when this specific activity is resumed after being suspended */
+ void on_this_resume_cb(const std::function<void(AnyActivity const&)>& cb) { on_this_resume.connect(cb); }
+ /*! \static Add a callback fired each time that any activity fails to start because of a veto (e.g., unsolved
+ * dependency or no resource assigned) */
+ static void on_veto_cb(const std::function<void(AnyActivity&)>& cb) { on_veto.connect(cb); }
+ /*! Add a callback fired each time that this specific activity fails to start because of a veto (e.g., unsolved
+ * dependency or no resource assigned) */
+ void on_this_veto_cb(const std::function<void(AnyActivity&)>& cb) { on_this_veto.connect(cb); }
+
+ XBT_ATTRIB_DEPRECATED_v337("Please use on_suspend_cb() instead") static void on_suspended_cb(
+ const std::function<void(Activity const&)>& cb) { on_suspend.connect(cb); }
+ XBT_ATTRIB_DEPRECATED_v337("Please use on_resume_cb() instead") static void on_resumed_cb(
+ const std::function<void(Activity const&)>& cb) { on_resume.connect(cb); }
+
+
AnyActivity* add_successor(ActivityPtr a)
{
Activity::add_successor(a);
Activity::remove_successor(a);
return static_cast<AnyActivity*>(this);
}
- AnyActivity* set_name(const std::string& name)
+ AnyActivity* set_name(std::string_view name)
{
name_ = name;
return static_cast<AnyActivity*>(this);
const std::string& get_name() const override { return name_; }
const char* get_cname() const override { return name_.c_str(); }
- AnyActivity* set_tracing_category(const std::string& category)
+ AnyActivity* set_tracing_category(std::string_view category)
{
- xbt_assert(get_state() == State::INITED, "Cannot change the tracing category of an activity after its start");
+ xbt_assert(get_state() == State::INITED || get_state() == State::STARTING,
+ "Cannot change the tracing category of an activity after its start");
tracing_category_ = category;
return static_cast<AnyActivity*>(this);
}
AnyActivity* cancel() { return static_cast<AnyActivity*>(Activity::cancel()); }
AnyActivity* wait() { return wait_for(-1.0); }
- virtual AnyActivity* wait_for(double timeout) { return static_cast<AnyActivity*>(Activity::wait_for(timeout)); }
+ virtual AnyActivity* wait_for(double timeout) {
+ return static_cast<AnyActivity*>(Activity::wait_for(timeout));
+ }
#ifndef DOXYGEN
/* The refcounting is done in the ancestor class, Activity, but we want each of the classes benefiting of the CRTP
int get_refcount() const;
// ***** Actor creation *****
- /** Retrieve a reference to myself */
+ /** \static
+ * Retrieve a reference to myself
+ */
static Actor* self();
private:
static xbt::signal<void(Actor&)> on_creation;
static xbt::signal<void(Actor const&)> on_suspend;
+ xbt::signal<void(Actor const&)> on_this_suspend;
static xbt::signal<void(Actor const&)> on_resume;
+ xbt::signal<void(Actor const&)> on_this_resume;
static xbt::signal<void(Actor const&)> on_sleep;
+ xbt::signal<void(Actor const&)> on_this_sleep;
static xbt::signal<void(Actor const&)> on_wake_up;
+ xbt::signal<void(Actor const&)> on_this_wake_up;
static xbt::signal<void(const Actor&, const Host& previous_location)> on_host_change;
+ xbt::signal<void(const Actor&, const Host& previous_location)> on_this_host_change;
static xbt::signal<void(Actor const&)> on_termination;
+ xbt::signal<void(Actor const&)> on_this_termination;
static xbt::signal<void(Actor const&)> on_destruction;
+ xbt::signal<void(Actor const&)> on_this_destruction;
public:
- /** Add a callback fired when a new actor has been created **/
+ /** \static Add a callback fired when a new actor has been created **/
static void on_creation_cb(const std::function<void(Actor&)>& cb) { on_creation.connect(cb); }
- /** Add a callback fired when an actor has been suspended**/
+ /** \static Add a callback fired when any actor is suspended (right before the suspend) **/
static void on_suspend_cb(const std::function<void(Actor const&)>& cb) { on_suspend.connect(cb); }
- /** Add a callback fired when an actor has been resumed **/
+ /** Add a callback fired when this specific actor is suspended (right before the suspend) **/
+ void on_this_suspend_cb(const std::function<void(Actor const&)>& cb) { on_this_suspend.connect(cb); }
+ /** \static Add a callback fired when any actor is resumed (right before the resume) **/
static void on_resume_cb(const std::function<void(Actor const&)>& cb) { on_resume.connect(cb); }
- /** Add a callback fired when an actor starts sleeping **/
+ /** Add a callback fired when this specific actor is resumed (right before the resume) **/
+ void on_this_resume_cb(const std::function<void(Actor const&)>& cb) { on_this_resume.connect(cb); }
+ /** \static Add a callback fired when any actor starts sleeping **/
static void on_sleep_cb(const std::function<void(Actor const&)>& cb) { on_sleep.connect(cb); }
- /** Add a callback fired when an actor wakes up from a sleep **/
+ /** Add a callback fired when this specific actor starts sleeping **/
+ void on_this_sleep_cb(const std::function<void(Actor const&)>& cb) { on_this_sleep.connect(cb); }
+ /** \static Add a callback fired when any actor wakes up from a sleep **/
static void on_wake_up_cb(const std::function<void(Actor const&)>& cb) { on_wake_up.connect(cb); }
- /** Add a callback fired when an actor is has been migrated to another host **/
+ /** Add a callback fired when this specific actor wakes up from a sleep **/
+ void on_this_wake_up_cb(const std::function<void(Actor const&)>& cb) { on_this_wake_up.connect(cb); }
+ /** \static Add a callback fired when any actor is has been migrated to another host **/
static void on_host_change_cb(const std::function<void(const Actor&, const Host& previous_location)>& cb)
{
on_host_change.connect(cb);
}
+ /** Add a callback fired when this specific actor is has been migrated to another host **/
+ void on_this_host_change_cb(const std::function<void(const Actor&, const Host& previous_location)>& cb)
+ {
+ on_this_host_change.connect(cb);
+ }
- /** Add a callback fired when an actor terminates its code.
+ /** \static
+ * Add a callback fired when any actor terminates its code.
* @beginrst
* The actor may continue to exist if it is still referenced in the simulation, but it's not active anymore.
* If you want to free extra data when the actor's destructor is called, use :cpp:func:`Actor::on_destruction_cb`.
* @endrst
*/
static void on_termination_cb(const std::function<void(Actor const&)>& cb) { on_termination.connect(cb); }
- /** Add a callback fired when an actor is about to disappear (its destructor was called).
- * This signal is fired for any destructed actor, which is mostly useful when designing plugins and extensions.
- * If you want to react to the end of the actor's code, use Actor::on_termination instead.
- * If you want to register to the termination of a given actor, use this_actor::on_exit() instead.*/
+ /** Add a callback fired when this specific actor terminates its code.
+ * @beginrst
+ * The actor may continue to exist if it is still referenced in the simulation, but it's not active anymore.
+ * If you want to free extra data when the actor's destructor is called, use :cpp:func:`Actor::on_this_destruction_cb`.
+ * @endrst
+ */
+ void on_this_termination_cb(const std::function<void(Actor const&)>& cb) { on_this_termination.connect(cb); }
+ /** \static Add a callback fired when an actor is about to disappear (its destructor was called).
+ * This signal is fired for any destructed actor, which is mostly useful when designing plugins and extensions. */
static void on_destruction_cb(const std::function<void(Actor const&)>& cb) { on_destruction.connect(cb); }
+ /** Add a callback fired when this specific actor is about to disappear (its destructor was called). */
+ void on_this_destruction_cb(const std::function<void(Actor const&)>& cb) { on_this_destruction.connect(cb); }
- /** Create an actor from a @c std::function<void()>.
+ /** \static
+ * Create an actor from a @c std::function<void()>.
* If the actor is restarted, it gets a fresh copy of the function.
* @verbatim embed:rst:inline See the :ref:`example <s4u_ex_actors_create>`. @endverbatim */
static ActorPtr create(const std::string& name, s4u::Host* host, const std::function<void()>& code);
- /** Create an actor, but don't start it yet.
+ /** \static
+ * Create an actor, but don't start it yet.
*
- * This is useful to set some properties or extension before actually starting it */
+ * This is useful to set some properties or extension before actually starting it */
static ActorPtr init(const std::string& name, s4u::Host* host);
ActorPtr set_stacksize(unsigned stacksize);
/** Start a previously initialized actor */
ActorPtr start(const std::function<void()>& code, std::vector<std::string> args);
- /** Create an actor from a callable thing.
+ /** \static
+ * Create an actor from a callable thing.
* @verbatim embed:rst:inline See the :ref:`example <s4u_ex_actors_create>`. @endverbatim */
template <class F> static ActorPtr create(const std::string& name, s4u::Host* host, F code)
{
return create(name, host, std::function<void()>(std::move(code)));
}
- /** Create an actor using a callable thing and its arguments.
+ /** \static
+ * Create an actor using a callable thing and its arguments.
*
* Note that the arguments will be copied, so move-only parameters are forbidden.
* @verbatim embed:rst:inline See the :ref:`example <s4u_ex_actors_create>`. @endverbatim */
return create(name, host, std::bind(std::move(code), std::move(args)...));
}
- /** Create actor from function name and a vector of strings as arguments.
+ /** \static
+ * Create actor from function name and a vector of strings as arguments.
* @verbatim embed:rst:inline See the :ref:`example <s4u_ex_actors_create>`. @endverbatim */
static ActorPtr create(const std::string& name, s4u::Host* host, const std::string& function,
std::vector<std::string> args);
/** Returns whether or not this actor has been daemonized or not **/
bool is_daemon() const;
+
static bool is_maestro();
/** Retrieves the name of that actor as a C++ string */
*/
void kill();
- /** Retrieves the actor that have the given PID (or nullptr if not existing) */
+ /** \static
+ * Retrieves the actor that have the given PID (or nullptr if not existing)
+ */
static ActorPtr by_pid(aid_t pid);
/** Wait for the actor to finish.
/** Kill that actor and restart it from start. */
Actor* restart();
- /** Kill all actors (but the issuer). Being killed is not something that actors can delay or avoid. */
+ /** \static
+ * Kill all actors (but the issuer). Being killed is not something that actors can delay or avoid.
+ */
static void kill_all();
/** Returns the internal implementation of this actor */
#include <atomic>
#include <future>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
class XBT_PUBLIC Barrier {
kernel::activity::BarrierImpl* pimpl_;
Barrier& operator=(Barrier const&) = delete;
#endif
- /** Creates a barrier for the given amount of actors */
+ /** \static Creates a barrier for the given amount of actors */
static BarrierPtr create(unsigned int expected_actors);
/** Blocks into the barrier. Every waiting actors will be unlocked once the expected amount of actors reaches the barrier */
int wait();
friend XBT_PUBLIC void intrusive_ptr_release(Barrier* barrier);
#endif
};
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif
#include <string>
#include <vector>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** @brief Communication async
*
* Represents all asynchronous communications, that you can test or wait onto.
*/
class XBT_PUBLIC Comm : public Activity_T<Comm> {
friend Mailbox; // Factory of comms
+ friend kernel::activity::CommImpl;
/* specified for normal mailbox-based communications*/
Mailbox* mailbox_ = nullptr;
kernel::actor::ActorImpl* sender_ = nullptr;
Comm() = default;
Comm* do_start() override;
-public:
- /* signals and related callbacks */
-#ifndef DOXYGEN
- /* FIXME signals should be private */
+protected:
static xbt::signal<void(Comm const&)> on_send;
+ xbt::signal<void(Comm const&)> on_this_send;
static xbt::signal<void(Comm const&)> on_recv;
- static xbt::signal<void(Comm const&)> on_start;
-#endif
+ xbt::signal<void(Comm const&)> on_this_recv;
+ inline static xbt::signal<void(Comm const&)> on_start;
+ xbt::signal<void(Comm const&)> on_this_start;
+
+ void fire_on_completion() const override {
+ /* The completion signal of a Comm has to be thrown only once and not by the sender AND the receiver.
+ then Comm::on_completion is thrown in the kernel in CommImpl::finish.
+ */
+ }
+ void fire_on_this_completion() const override {
+ /* The completion signal of a Comm has to be thrown only once and not by the sender AND the receiver.
+ then Comm::on_completion is thrown in the kernel in CommImpl::finish.
+ */
+ }
+ void fire_on_suspend() const override { on_suspend(*this); }
+ void fire_on_this_suspend() const override { on_this_suspend(*this); }
+ void fire_on_resume() const override { on_resume(*this); }
+ void fire_on_this_resume() const override { on_this_resume(*this); }
+ void fire_on_veto() const override { on_veto(const_cast<Comm&>(*this)); }
+ void fire_on_this_veto() const override { on_this_veto(const_cast<Comm&>(*this)); }
+public:
+ /*! \static Add a callback fired when the send of any Comm is posted */
static void on_send_cb(const std::function<void(Comm const&)>& cb) { on_send.connect(cb); }
+ /*! Add a callback fired when the send of this specific Comm is posted */
+ void on_this_send_cb(const std::function<void(Comm const&)>& cb) { on_send.connect(cb); }
+ /*! \static Add a callback fired when the recv of any Comm is posted */
static void on_recv_cb(const std::function<void(Comm const&)>& cb) { on_recv.connect(cb); }
+ /*! Add a callback fired when the recv of this specific Comm is posted */
+ void on_this_recv_cb(const std::function<void(Comm const&)>& cb) { on_this_recv.connect(cb); }
+ /*! \static Add a callback fired when any Comm starts */
static void on_start_cb(const std::function<void(Comm const&)>& cb) { on_start.connect(cb); }
- /* More callbacks */
+ /*! Add a callback fired when this specific Comm starts */
+ void on_this_start_cb(const std::function<void(Comm const&)>& cb) { on_this_start.connect(cb); }
+
CommPtr set_copy_data_callback(const std::function<void(kernel::activity::CommImpl*, void*, size_t)>& callback);
XBT_ATTRIB_DEPRECATED_v337("Please manifest if you actually need this function") static void copy_buffer_callback(
kernel::activity::CommImpl*, void*, size_t);
const std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)>& copy_data_fun,
void* data, double timeout, double rate);
- /* "One-sided" communications. This way of communicating bypasses the mailbox and actors mechanism. It creates a
+ /* \static
+ * "One-sided" communications. This way of communicating bypasses the mailbox and actors mechanism. It creates a
* communication (vetoabled, asynchronous, or synchronous) directly between two hosts. There is really no limit on
* the hosts involved. In particular, the actor creating such a communication does not have to be on one of the
* involved hosts! Enjoy the comfort of the simulator :)
bool is_assigned() const override;
Actor* get_sender() const;
+ Actor* get_receiver() const;
/* Comm life cycle */
/** Start the comm, and ignore its result. It can be completely forgotten after that. */
Comm* wait_for(double timeout) override;
- /*! take a vector s4u::CommPtr and return the rank of the first finished one (or -1 if none is done). */
+ /*! \static take a vector s4u::CommPtr and return the rank of the first finished one (or -1 if none is done). */
static ssize_t test_any(const std::vector<CommPtr>& comms);
- /*! take a vector s4u::CommPtr and return when one of them is finished.
+ /*! \static 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 ssize_t wait_any(const std::vector<CommPtr>& comms) { return wait_any_for(comms, -1); }
- /*! Same as wait_any, but with a timeout. Return -1 if the timeout occurs.*/
+ /*! \static Same as wait_any, but with a timeout. Return -1 if the timeout occurs.*/
static ssize_t wait_any_for(const std::vector<CommPtr>& comms, double timeout);
- /*! take a vector s4u::CommPtr and return when all of them is finished. */
+ /*! \static take a vector s4u::CommPtr and return when all of them is finished. */
static void wait_all(const std::vector<CommPtr>& comms);
- /*! Same as wait_all, but with a timeout. Return the number of terminated comm (less than comms.size() if the timeout
- * occurs). */
+ /*! \static Same as wait_all, but with a timeout. Return the number of terminated comm (less than comms.size() if
+ * the timeout occurs). */
static size_t wait_all_for(const std::vector<CommPtr>& comms, double timeout);
};
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_COMM_HPP */
#include <future>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/**
* @beginrst
#endif
public:
- /** Create a new condition variable and return a smart pointer
+ /** \static Create a new condition variable and return a smart pointer
*
* @beginrst
* You should only manipulate :cpp:type:`simgrid::s4u::ConditionVariablePtr`, as created by this function (see also :ref:`s4u_raii`).
void notify_all();
};
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif
Disk* seal();
/* The signals */
- /** @brief Add a callback fired when a new Disk is created */
+ /** @brief \static Add a callback fired when a new Disk is created */
static void on_creation_cb(const std::function<void(Disk&)>& cb) { on_creation.connect(cb); }
- /** @brief Add a callback fired when a Disk is destroyed */
+ /** @brief \static Add a callback fired when any Disk is destroyed */
static void on_destruction_cb(const std::function<void(Disk const&)>& cb) { on_destruction.connect(cb); }
- /** @brief Add a callback fired when a Disk's state changes */
- static void on_state_change_cb(const std::function<void(Disk const&)>& cb) { on_state_change.connect(cb); }
+ /** @brief Add a callback fired when this specific Disk is destroyed */
+ void on_this_destruction_cb(const std::function<void(Disk const&)>& cb) { on_this_destruction.connect(cb); }
+ /** @brief \static Add a callback fired when any Disk is turned on or off */
+ static void on_onoff_cb(const std::function<void(Disk const&)>& cb)
+ {
+ on_onoff.connect(cb);
+ }
+ /** @brief Add a callback fired when this specific Disk is turned on or off */
+ void on_this_onoff_cb(const std::function<void(Disk const&)>& cb)
+ {
+ on_this_onoff.connect(cb);
+ }
+
+ XBT_ATTRIB_DEPRECATED_v337("Please use on_onoff_cb() instead") static void on_state_change_cb(
+ const std::function<void(Disk const&)>& cb)
+ {
+ on_onoff.connect(cb);
+ }
private:
static xbt::signal<void(Disk&)> on_creation;
static xbt::signal<void(Disk const&)> on_destruction;
- static xbt::signal<void(Disk const&)> on_state_change;
+ xbt::signal<void(Disk const&)> on_this_destruction;
+ static xbt::signal<void(Disk const&)> on_onoff;
+ xbt::signal<void(Disk const&)> on_this_onoff;
};
} // namespace s4u
#include <utility>
#include <vector>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** @brief Simulation engine
*
* This is a singleton containing all the main functions of the simulation.
/** @brief Retrieves all netzones of the type indicated by the template argument */
template <class T> std::vector<T*> get_filtered_netzones() const
{
- static_assert(std::is_base_of<kernel::routing::NetZoneImpl, T>::value,
+ static_assert(std::is_base_of_v<kernel::routing::NetZoneImpl, T>,
"Filtering netzones is only possible for subclasses of kernel::routing::NetZoneImpl");
std::vector<T*> res;
get_filtered_netzones_recursive(get_netzone_root(), &res);
template <class T>
XBT_PRIVATE void get_filtered_netzones_recursive(const s4u::NetZone* current, std::vector<T*>* whereto)
{
- static_assert(std::is_base_of<kernel::routing::NetZoneImpl, T>::value,
+ static_assert(std::is_base_of_v<kernel::routing::NetZoneImpl, T>,
"Filtering netzones is only possible for subclasses of kernel::routing::NetZoneImpl");
for (auto const& elem : current->get_children()) {
get_filtered_netzones_recursive(elem, whereto);
}
}
#endif
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_ENGINE_HPP */
#include <simgrid/s4u/Actor.hpp>
#include <xbt/ex.h>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** Computation Activity, representing the asynchronous executions.
*
void reset() const;
- static xbt::signal<void(Exec const&)> on_start;
+ inline static xbt::signal<void(Exec const&)> on_start;
+ xbt::signal<void(Exec const&)> on_this_start;
+ void fire_on_completion() const override { on_completion(*this); }
+ void fire_on_this_completion() const override { on_this_completion(*this); }
+ void fire_on_suspend() const override { on_suspend(*this); }
+ void fire_on_this_suspend() const override { on_this_suspend(*this); }
+ void fire_on_resume() const override { on_resume(*this); }
+ void fire_on_this_resume() const override { on_this_resume(*this); }
+ void fire_on_veto() const override { on_veto(const_cast<Exec&>(*this)); }
+ void fire_on_this_veto() const override { on_this_veto(const_cast<Exec&>(*this)); }
public:
#ifndef DOXYGEN
Exec(Exec const&) = delete;
Exec& operator=(Exec const&) = delete;
#endif
- /*! Signal fired each time that an execution actually starts (no veto) */
+ /*! \static Signal fired each time that any execution actually starts (no veto) */
static void on_start_cb(const std::function<void(Exec const&)>& cb) { on_start.connect(cb); }
+ /*! Signal fired each time that this specific execution actually starts (no veto) */
+ void on_this_start_cb(const std::function<void(Exec const&)>& cb) { on_this_start.connect(cb); }
+ /*! \static Initiate the creation of an Exec. Setters have to be called afterwards */
static ExecPtr init();
- /*! take a vector of s4u::ExecPtr and return when one of them is finished.
+ /*! \static take a vector of s4u::ExecPtr and return when one of them is finished.
* The return value is the rank of the first finished ExecPtr. */
static ssize_t wait_any(const std::vector<ExecPtr>& execs) { return wait_any_for(execs, -1); }
- /*! Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/
+ /*! \static Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/
static ssize_t wait_any_for(const std::vector<ExecPtr>& execs, double timeout);
/** @brief On sequential executions, returns the amount of flops that remain to be done; This cannot be used on
bool is_assigned() const override;
};
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_EXEC_HPP */
#define SIMGRID_S4U_HOST_HPP
#include <simgrid/forward.h>
+#include <simgrid/kernel/resource/Action.hpp>
#include <xbt/Extendable.hpp>
#include <xbt/signal.hpp>
kernel::resource::CpuImpl* pimpl_cpu_ = nullptr;
kernel::routing::NetPoint* pimpl_netpoint_ = nullptr;
+#ifndef DOXYGEN
+ friend kernel::resource::CpuAction; // signal exec_state_changed
+#endif
public:
explicit Host(kernel::resource::HostImpl* pimpl) : pimpl_(pimpl) {}
static xbt::signal<void(Host&)> on_creation;
static xbt::signal<void(Host const&)> on_destruction;
+ xbt::signal<void(Host const&)> on_this_destruction;
+ static xbt::signal<void(kernel::resource::CpuAction&, kernel::resource::Action::State)> on_exec_state_change;
public:
static xbt::signal<void(Host const&)> on_speed_change;
- static xbt::signal<void(Host const&)> on_state_change;
+ xbt::signal<void(Host const&)> on_this_speed_change;
+ static xbt::signal<void(Host const&)> on_onoff;
+ xbt::signal<void(Host const&)> on_this_onoff;
+
#endif
- /** Add a callback fired on each newly created host */
+ /** \static Add a callback fired on each newly created host */
static void on_creation_cb(const std::function<void(Host&)>& cb) { on_creation.connect(cb); }
- /** Add a callback fired when the machine is turned on or off (called AFTER the change) */
- static void on_state_change_cb(const std::function<void(Host const&)>& cb) { on_state_change.connect(cb); }
- /** Add a callback fired when the speed of the machine is changed (called AFTER the change)
+ /** \static Add a callback fired when any machine is turned on or off (called AFTER the change) */
+ static void on_onoff_cb(const std::function<void(Host const&)>& cb)
+ {
+ on_onoff.connect(cb);
+ }
+ XBT_ATTRIB_DEPRECATED_v337("Please use on_onoff_cb() instead") static void on_state_change_cb(
+ const std::function<void(Host const&)>& cb)
+ {
+ on_onoff.connect(cb);
+ }
+ /** Add a callback fired when this specific machine is turned on or off (called AFTER the change) */
+ void on_this_onoff_cb(const std::function<void(Host const&)>& cb)
+ {
+ on_this_onoff.connect(cb);
+ }
+ /** \static Add a callback fired when the speed of any machine is changed (called AFTER the change)
* (either because of a pstate switch or because of an external load event coming from the profile) */
static void on_speed_change_cb(const std::function<void(Host const&)>& cb) { on_speed_change.connect(cb); }
- /** Add a callback fired just before destructing a host */
+ /** Add a callback fired when the speed of this specific machine is changed (called AFTER the change)
+ * (either because of a pstate switch or because of an external load event coming from the profile) */
+ void on_this_speed_change_cb(const std::function<void(Host const&)>& cb)
+ {
+ on_this_speed_change.connect(cb);
+ }
+ /** \static Add a callback fired just before destructing any host */
static void on_destruction_cb(const std::function<void(Host const&)>& cb) { on_destruction.connect(cb); }
+ /** Add a callback fired just before destructing this specific host */
+ void on_this_destruction_cb(const std::function<void(Host const&)>& cb)
+ {
+ on_this_destruction.connect(cb);
+ }
+ /** \static Add a callback fired when the state of any exec activity changes */
+ static void on_exec_state_change_cb(
+ const std::function<void(kernel::resource::CpuAction&, kernel::resource::Action::State previous)>& cb)
+ {
+ on_exec_state_change.connect(cb);
+ }
virtual void destroy();
#ifndef DOXYGEN
Host& operator=(Host const&) = delete;
#endif
- /** Retrieve a host from its name, or return nullptr */
+ /** \static Retrieve a host from its name, or return nullptr */
static Host* by_name_or_null(const std::string& name);
- /** Retrieve a host from its name, or die */
+ /** \static Retrieve a host from its name, or die */
static Host* by_name(const std::string& name);
- /** Retrieves the host on which the running actor is located */
+ /** \static Retrieves the host on which the running actor is located */
static Host* current();
/** Retrieves the name of that host as a C++ string */
Host* set_concurrency_limit(int limit);
int get_concurrency_limit() const;
- /** @brief Convert the CPU's speed from string to double */
+ /** \static @brief Convert the CPU's speed from string to double */
static std::vector<double> convert_pstate_speed_vector(const std::vector<std::string>& speed_per_state);
/**
* @brief Set the CPU's speed
#include <string>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** I/O Activity, representing the asynchronous disk access.
*
friend kernel::EngineImpl;
#endif
- static xbt::signal<void(Io const&)> on_start;
+ inline static xbt::signal<void(Io const&)> on_start;
+ xbt::signal<void(Io const&)> on_this_start;
protected:
explicit Io(kernel::activity::IoImplPtr pimpl);
Io* do_start() override;
+ void fire_on_completion() const override { on_completion(*this); }
+ void fire_on_this_completion() const override { on_this_completion(*this); }
+ void fire_on_suspend() const override { on_suspend(*this); }
+ void fire_on_this_suspend() const override { on_this_suspend(*this); }
+ void fire_on_resume() const override { on_resume(*this); }
+ void fire_on_this_resume() const override { on_this_resume(*this); }
+ void fire_on_veto() const override { on_veto(const_cast<Io&>(*this)); }
+ void fire_on_this_veto() const override { on_this_veto(const_cast<Io&>(*this)); }
public:
enum class OpType { READ, WRITE };
+ /*! \static Signal fired each time that any I/O actually starts (no veto) */
static void on_start_cb(const std::function<void(Io const&)>& cb) { on_start.connect(cb); }
+ /*! Signal fired each time this specific I/O actually starts (no veto) */
+ void on_this_start_cb(const std::function<void(Io const&)>& cb) { on_this_start.connect(cb); }
+ /*! \static Initiate the creation of an I/O. Setters have to be called afterwards */
static IoPtr init();
- /*! take a vector of s4u::IoPtr and return when one of them is finished.
+ /*! \static take a vector of s4u::IoPtr and return when one of them is finished.
* The return value is the rank of the first finished IoPtr. */
static ssize_t wait_any(const std::vector<IoPtr>& ios) { return wait_any_for(ios, -1); }
- /*! Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/
+ /*! \static Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.*/
static ssize_t wait_any_for(const std::vector<IoPtr>& ios, double timeout);
double get_remaining() const override;
bool is_assigned() const override;
};
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_IO_HPP */
kernel::resource::StandardLinkImpl* get_impl() const;
- /** @brief Retrieve a link from its name */
+ /** \static @brief Retrieve a link from its name */
static Link* by_name(const std::string& name);
static Link* by_name_or_null(const std::string& name);
private:
#ifndef DOXYGEN
static xbt::signal<void(Link&)> on_creation;
- static xbt::signal<void(Link const&)> on_state_change;
+ static xbt::signal<void(Link const&)> on_onoff;
+ xbt::signal<void(Link const&)> on_this_onoff;
static xbt::signal<void(Link const&)> on_bandwidth_change;
+ xbt::signal<void(Link const&)> on_this_bandwidth_change;
static xbt::signal<void(kernel::resource::NetworkAction&, kernel::resource::Action::State)>
on_communication_state_change;
static xbt::signal<void(Link const&)> on_destruction;
+ xbt::signal<void(Link const&)> on_this_destruction;
#endif
public:
/* The signals */
- /** @brief Add a callback fired when a new Link is created */
+ /** \static @brief Add a callback fired when a new Link is created */
static void on_creation_cb(const std::function<void(Link&)>& cb) { on_creation.connect(cb); }
- /** @brief Add a callback fired when the state of a Link changes (when it is turned on or off) */
- static void on_state_change_cb(const std::function<void(Link const&)>& cb) { on_state_change.connect(cb); }
- /** @brief Add a callback fired when the bandwidth of a Link changes */
+ /** \static @brief Add a callback fired when any Link is turned on or off */
+ static void on_onoff_cb(const std::function<void(Link const&)>& cb)
+ {
+ on_onoff.connect(cb);
+ }
+ /** @brief Add a callback fired when this specific Link is turned on or off */
+ void on_this_onoff_cb(const std::function<void(Link const&)>& cb)
+ {
+ on_this_onoff.connect(cb);
+ }
+ /** \static @brief Add a callback fired when the bandwidth of any Link changes */
static void on_bandwidth_change_cb(const std::function<void(Link const&)>& cb) { on_bandwidth_change.connect(cb); }
- /** @brief Add a callback fired when a communication changes it state (ready/done/cancel) */
+ /** @brief Add a callback fired when the bandwidth of this specific Link changes */
+ void on_this_bandwidth_change_cb(const std::function<void(Link const&)>& cb)
+ {
+ on_this_bandwidth_change.connect(cb);
+ }
+ /** \static @brief Add a callback fired when a communication changes it state (ready/done/cancel) */
static void on_communication_state_change_cb(
const std::function<void(kernel::resource::NetworkAction&, kernel::resource::Action::State)>& cb)
{
on_communication_state_change.connect(cb);
}
- /** @brief Add a callback fired when a Link is destroyed */
+ /** \static @brief Add a callback fired when any Link is destroyed */
static void on_destruction_cb(const std::function<void(Link const&)>& cb) { on_destruction.connect(cb); }
+ /** @brief Add a callback fired when this specific Link is destroyed */
+ void on_this_destruction_cb(const std::function<void(Link const&)>& cb)
+ {
+ on_this_destruction.connect(cb);
+ }
+
+ XBT_ATTRIB_DEPRECATED_v337("Please use on_onoff_cb() instead") static void on_state_change_cb(
+ const std::function<void(Link const&)>& cb)
+ {
+ on_onoff.connect(cb);
+ }
};
/**
/** @brief Get the link direction down */
Link* get_link_down() const;
- /** @brief Retrieve a link from its name */
+ /** \static @brief Retrieve a link from its name */
static SplitDuplexLink* by_name(const std::string& name);
};
#include <memory>
#include <string>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** @brief Mailboxes: Network rendez-vous points. */
class XBT_PUBLIC Mailbox {
/** @brief Retrieves the name of that mailbox as a C string */
const char* get_cname() const;
- /** Retrieve the mailbox associated to the given name. Mailboxes are created on demand. */
+ /** \static Retrieve the mailbox associated to the given name. Mailboxes are created on demand. */
static Mailbox* by_name(const std::string& name);
/** Returns whether the mailbox contains queued communications */
get_async<T>(&res)->wait_for(timeout);
return res;
}
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_MAILBOX_HPP */
#include <simgrid/forward.h>
#include <xbt/asserts.h>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** @brief A classical mutex, but blocking in the simulation world.
*
#endif
public:
- /** Constructs a new mutex */
+ /** \static Constructs a new mutex */
static MutexPtr create();
void lock();
void unlock();
bool try_lock();
};
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_MUTEX_HPP */
#include <utility>
#include <vector>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** @brief Networking Zones
*
#endif
public:
+ /** \static Add a callback fired on each newly created NetZone */
static void on_creation_cb(const std::function<void(NetZone const&)>& cb) { on_creation.connect(cb); }
+ /** \static Add a callback fired on each newly sealed NetZone */
static void on_seal_cb(const std::function<void(NetZone const&)>& cb) { on_seal.connect(cb); }
/**
const DragonflyParams& parameters, const ClusterCallbacks& set_callbacks,
double bandwidth, double latency, Link::SharingPolicy sharing_policy);
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_NETZONE_HPP */
#include <simgrid/forward.h>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** @brief A classical semaphore, but blocking in the simulation world
*
#endif
public:
- /** Constructs a new semaphore */
+ /** \static Constructs a new semaphore */
static SemaphorePtr create(unsigned int initial_capacity);
void acquire();
bool would_block() const;
};
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif /* SIMGRID_S4U_SEMAPHORE_HPP */
#include <simgrid/s4u/Host.hpp>
#include <xbt/utility.hpp>
-namespace simgrid {
-namespace s4u {
+namespace simgrid::s4u {
/** @brief Host extension for the VMs */
class VmHostExt {
/* Signals about the life cycle of the VM */
static xbt::signal<void(VirtualMachine&)> on_vm_creation;
static xbt::signal<void(VirtualMachine const&)> on_start;
+ xbt::signal<void(VirtualMachine const&)> on_this_start;
static xbt::signal<void(VirtualMachine const&)> on_started;
+ xbt::signal<void(VirtualMachine const&)> on_this_started;
static xbt::signal<void(VirtualMachine const&)> on_shutdown;
+ xbt::signal<void(VirtualMachine const&)> on_this_shutdown;
static xbt::signal<void(VirtualMachine const&)> on_suspend;
+ xbt::signal<void(VirtualMachine const&)> on_this_suspend;
static xbt::signal<void(VirtualMachine const&)> on_resume;
+ xbt::signal<void(VirtualMachine const&)> on_this_resume;
static xbt::signal<void(VirtualMachine const&)> on_migration_start;
+ xbt::signal<void(VirtualMachine const&)> on_this_migration_start;
static xbt::signal<void(VirtualMachine const&)> on_migration_end;
+ xbt::signal<void(VirtualMachine const&)> on_this_migration_end;
static xbt::signal<void(VirtualMachine const&)> on_vm_destruction;
+ xbt::signal<void(VirtualMachine const&)> on_this_vm_destruction;
#ifndef DOXYGEN
friend kernel::resource::VirtualMachineImpl; // calls signals from Impl
State get_state() const;
/* Callbacks on signals */
+ /*! \static Add a callback fired when any VM is created */
static void on_creation_cb(const std::function<void(VirtualMachine&)>& cb) { on_vm_creation.connect(cb); }
+ /*! \static Add a callback fired when any VM starts */
static void on_start_cb(const std::function<void(VirtualMachine const&)>& cb) { on_start.connect(cb); }
+ /*! Add a callback fired when this specific VM starts */
+ void on_this_start_cb(const std::function<void(VirtualMachine const&)>& cb)
+ {
+ on_this_start.connect(cb);
+ }
+ /*! \static Add a callback fired when any VM is actually started */
static void on_started_cb(const std::function<void(VirtualMachine const&)>& cb) { on_started.connect(cb); }
+ /*! Add a callback fired when this specific VM is actually started */
+ void on_this_started_cb(const std::function<void(VirtualMachine const&)>& cb)
+ {
+ on_this_started.connect(cb);
+ }
+ /*! \static Add a callback fired when any VM is shut down */
static void on_shutdown_cb(const std::function<void(VirtualMachine const&)>& cb) { on_shutdown.connect(cb); }
+ /*! Add a callback fired when this specific VM is shut down */
+ void on_this_shutdown_cb(const std::function<void(VirtualMachine const&)>& cb)
+ {
+ on_this_shutdown.connect(cb);
+ }
+ /*! \static Add a callback fired when any VM is suspended*/
static void on_suspend_cb(const std::function<void(VirtualMachine const&)>& cb) { on_suspend.connect(cb); }
+ /*! Add a callback fired when this specific VM is suspended*/
+ void on_this_suspend_cb(const std::function<void(VirtualMachine const&)>& cb)
+ {
+ on_this_suspend.connect(cb);
+ }
+ /*! \static Add a callback fired when any VM is resumed*/
static void on_resume_cb(const std::function<void(VirtualMachine const&)>& cb) { on_resume.connect(cb); }
+ /*! Add a callback fired when this specific VM is resumed*/
+ void on_this_resume_cb(const std::function<void(VirtualMachine const&)>& cb)
+ {
+ on_this_resume.connect(cb);
+ }
+ /*! \static Add a callback fired when any VM is destroyed*/
static void on_destruction_cb(const std::function<void(VirtualMachine const&)>& cb) { on_vm_destruction.connect(cb); }
+ /*! Add a callback fired when this specific VM is destroyed*/
+ void on_this_destruction_cb(const std::function<void(VirtualMachine const&)>& cb)
+ {
+ on_this_vm_destruction.connect(cb);
+ }
+ /*! \static Add a callback fired when any VM starts a migration*/
static void on_migration_start_cb(const std::function<void(VirtualMachine const&)>& cb)
{
on_migration_start.connect(cb);
}
+ /*! Add a callback fired when this specific VM starts a migration*/
+ void on_this_migration_start_cb(const std::function<void(VirtualMachine const&)>& cb)
+ {
+ on_this_migration_start.connect(cb);
+ }
+ /*! \static Add a callback fired when any VM ends a migration*/
static void on_migration_end_cb(const std::function<void(VirtualMachine const&)>& cb)
{
on_migration_end.connect(cb);
}
+ /*! Add a callback fired when this specific VM ends a migration*/
+ void on_this_migration_end_cb(const std::function<void(VirtualMachine const&)>& cb)
+ {
+ on_this_migration_end.connect(cb);
+ }
};
-} // namespace s4u
-} // namespace simgrid
+} // namespace simgrid::s4u
#endif
XBT_PUBLIC void simcall_run_object_access(std::function<void()> const& code,
simgrid::kernel::actor::ObjectAccessSimcallItem* item);
-namespace simgrid {
-namespace kernel {
-namespace actor {
+namespace simgrid::kernel::actor {
/** Execute some code in kernel context on behalf of the user code.
*
simcall_blocking(std::forward<F>(code), static_cast<SimcallObserver*>(observer));
return observer->get_result();
}
-// compact namespaces are C++17 and this is a public header file so let's stick to C++14
-} // namespace actor
-} // namespace kernel
-} // namespace simgrid
+} // namespace simgrid::kernel::actor
#endif
#ifdef __cplusplus
#include <boost/intrusive_ptr.hpp>
-namespace simgrid {
-namespace smpi {
+namespace simgrid::smpi {
class Colls;
class Comm;
class Topo_Dist_Graph;
class Win;
-}
-}
+} // namespace simgrid::smpi
using SMPI_Comm = simgrid::smpi::Comm;
using SMPI_Datatype = simgrid::smpi::Datatype;
#include <limits>
#include <vector>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
template<class T, class U> class Extension;
template<class T> class Extendable;
// Initialized with a first element, to save space for void* user data
template <class T> std::vector<std::function<void(void*)>> Extendable<T>::deleters_{1};
-}
-}
+} // namespace simgrid::xbt
#endif
#include <string>
#include <unordered_map>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/** @brief a PropertyHolder can be given a set of textual properties
*
template <class Assoc> void set_properties(const Assoc& properties);
};
-} // namespace xbt
-} // namespace simgrid
+} // namespace simgrid::xbt
#endif
#include <xbt/automaton.h>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/** Add a proposition to an automaton (the C++ way)
*
a, id, [](auto* cb) -> int { return (*(F*)cb)(); }, callback, [](auto* cb) -> void { delete (F*)cb; });
}
-}
-}
+} // namespace simgrid::xbt
#endif
XBT_PUBLIC void xbt_backtrace_display_current();
SG_END_DECL
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
class BacktraceImpl;
/** A backtrace
void display() const;
};
-}
-}
+} // namespace simgrid::xbt
#endif
#include <xbt/sysdep.h>
#include <xbt/utility.hpp>
-namespace simgrid {
-namespace config {
+namespace simgrid::config {
class Config;
*/
// F is a checker, F : T& -> ()
template <class T, class F>
-typename std::enable_if_t<std::is_same<void, decltype(std::declval<F>()(std::declval<const T&>()))>::value, void>
+typename std::enable_if_t<std::is_same_v<void, decltype(std::declval<F>()(std::declval<const T&>()))>, void>
bind_flag(T& value, const char* name, const char* description, F callback)
{
declare_flag(name, description, value, std::function<void(const T&)>([&value, callback](const T& val) {
}
template <class T, class F>
-typename std::enable_if_t<std::is_same<void, decltype(std::declval<F>()(std::declval<const T&>()))>::value, void>
+typename std::enable_if_t<std::is_same_v<void, decltype(std::declval<F>()(std::declval<const T&>()))>, void>
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));
}
template <class F>
-typename std::enable_if_t<std::is_same<void, decltype(std::declval<F>()(std::declval<const std::string&>()))>::value,
- void>
+typename std::enable_if_t<std::is_same_v<void, decltype(std::declval<F>()(std::declval<const std::string&>()))>, void>
bind_flag(std::string& value, const char* name, const char* description,
const std::map<std::string, std::string, std::less<>>& valid_values, F callback)
{
mesg += std::string("Possible values for option ") + name + ":\n";
else
mesg += "Invalid value '" + val + "' for option " + name + ". Possible values:\n";
- for (auto const& kv : valid_values)
- mesg += " - '" + kv.first + "': " + kv.second + (kv.first == value ? " <=== DEFAULT" : "") + "\n";
+ for (auto const& [v, descr] : valid_values)
+ mesg += " - '" + v + "': " + descr + (v == value ? " <=== DEFAULT" : "") + "\n";
xbt_die("%s", mesg.c_str());
}));
}
template <class F>
-typename std::enable_if_t<std::is_same<void, decltype(std::declval<F>()(std::declval<const std::string&>()))>::value,
- void>
+typename std::enable_if_t<std::is_same_v<void, decltype(std::declval<F>()(std::declval<const std::string&>()))>, void>
bind_flag(std::string& value, const char* name, std::initializer_list<const char*> aliases, const char* description,
const std::map<std::string, std::string, std::less<>>& valid_values, F callback)
{
*/
// F is a predicate, F : T const& -> bool
template <class T, class F>
-typename std::enable_if_t<std::is_same<bool, decltype(std::declval<F>()(std::declval<const T&>()))>::value, void>
+typename std::enable_if_t<std::is_same_v<bool, decltype(std::declval<F>()(std::declval<const T&>()))>, void>
bind_flag(T& value, const char* name, const char* description, F callback)
{
declare_flag(name, description, value, std::function<void(const T&)>([&value, callback](const T& val) {
XBT_PUBLIC void show_aliases();
XBT_PUBLIC void help();
-} // namespace config
-} // namespace simgrid
+} // namespace simgrid::config
#endif
#include <vector>
#include <xbt/base.h>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
void path_push(std::string const& str);
void path_pop();
private:
std::string path_;
};
-}}
+} // namespace simgrid::xbt
#endif /* XBT_FILE_HPP */
#include <utility>
#include <vector>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
template <class F> class MainFunction {
F code_;
* @endcode
**/
template <class F, class Tuple>
-constexpr auto apply(F&& f, Tuple&& t) -> decltype(
- simgrid::xbt::bits::apply(std::forward<F>(f), std::forward<Tuple>(t),
- std::make_index_sequence<std::tuple_size<typename std::decay_t<Tuple>>::value>()))
+constexpr auto apply(F&& f, Tuple&& t)
+ -> decltype(simgrid::xbt::bits::apply(std::forward<F>(f), std::forward<Tuple>(t),
+ std::make_index_sequence<std::tuple_size_v<typename std::decay_t<Tuple>>>()))
{
return simgrid::xbt::bits::apply(std::forward<F>(f), std::forward<Tuple>(t),
- std::make_index_sequence<std::tuple_size<typename std::decay_t<Tuple>>::value>());
+ std::make_index_sequence<std::tuple_size_v<typename std::decay_t<Tuple>>>());
}
template<class T> class Task;
return code(std::forward<Args>(args)...);
},
// Destroy:
- std::is_trivially_destructible<F>::value ?
+ std::is_trivially_destructible_v<F> ?
static_cast<destroy_function>(nullptr) :
[](TaskUnion& buffer) {
auto* code = reinterpret_cast<F*>(&buffer);
return Task<decltype(code(std::move(args)...))()>(std::move(task));
}
-} // namespace xbt
-} // namespace simgrid
+} // namespace simgrid::xbt
#endif
#include <simgrid/Exception.hpp>
#include <xbt/log.h>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/** Display information about an exception
*
XBT_PUBLIC void install_exception_handler();
-} // namespace xbt
-} // namespace simgrid
+} // namespace simgrid::xbt
-#endif
\ No newline at end of file
+#endif
#include <utility>
#include <xbt/ex.h>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/** A value or an exception (or nothing)
*
{
fulfill_promise(promise, [&future] { return std::forward<F>(future).get(); });
}
-}
-}
+} // namespace simgrid::xbt
#endif
#include <random>
#include <string>
-namespace simgrid {
-namespace xbt {
-namespace random {
+namespace simgrid::xbt::random {
/** A random number generator.
*
* @param sd Standard deviation of the normal distribution
*/
double normal(double mean, double sd);
-} // namespace random
-} // namespace xbt
-} // namespace simgrid
+} // namespace simgrid::xbt::random
#endif
#include <algorithm>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/** Describes a contiguous inclusive-exclusive [a,b) range of values */
template<class T> class Range {
bool contain(T const& x) const { return begin_ <= x && end_ > x; }
};
-}
-}
+} // namespace simgrid::xbt
#endif
#include <queue>
#include <unordered_map>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/* To split the file if a unique one is given (specific variable for the other case live in runner()) */
using ReplayAction = std::vector<std::string>;
* xbt_replay_set_tracefile(). If trace_filename is not nullptr, then it's not shared and this trace file is for this
* actor only */
XBT_PUBLIC int replay_runner(const char* actor_name, const char* trace_filename = nullptr);
-}
-}
+} // namespace simgrid::xbt
using action_fun = std::function<void(simgrid::xbt::ReplayAction&)>;
XBT_PUBLIC void xbt_replay_action_register(const char* action_name, const action_fun& function);
#include <map>
#include <utility>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
template <class S> class signal;
/** Fire that signal, invoking all callbacks */
R operator()(P... args) const
{
- for (auto const& handler : handlers_)
- handler.second(args...);
+ for (auto const& [_, callback] : handlers_)
+ callback(args...);
}
/** Remove a callback */
void disconnect(unsigned int id) { handlers_.erase(id); }
/** Remove all callbacks */
void disconnect_slots() { handlers_.clear(); }
};
-}
-}
+} // namespace simgrid::xbt
#endif
#include <cstdlib>
#include <string>
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/** Create a C++ string from a C-style format
*
*/
XBT_PUBLIC std::string string_vprintf(const char* fmt, va_list ap) XBT_ATTRIB_PRINTF(1, 0);
-} // namespace xbt
-}
-#endif
\ No newline at end of file
+} // namespace simgrid::xbt
+#endif
#ifndef SIMGRID_MC_SYSTEM_ERROR_HPP
#define SIMGRID_MC_SYSTEM_ERROR_HPP
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/** A `error_category` suitable to be used with `errno`
*
return std::system_error(errno_code(), what);
}
-}
-}
+} // namespace simgrid::xbt
#endif
} \
enum class EnumType { __VA_ARGS__ } /* defined here to handle trailing semicolon */
-namespace simgrid {
-namespace xbt {
+namespace simgrid::xbt {
/** @brief Replacement for C++20's std::type_identity_t
*/
list.erase(list.iterator_to(elem));
}
-} // namespace xbt
-} // namespace simgrid
+} // namespace simgrid::xbt
#endif
# Disable some rules on some files
-sonar.issue.ignore.multicriteria=c1,c2a,c2b,c3,c5a,c5b,c6a,c6b,c7,c8,c9,c10a,c10b,c10c,cex1a,cex1b,cex2a,cex2b,cex3,cex4,cxx17a,cxx17b,cxx17c,cxx17d,cxx17e,cxx17f,cxx17g,f1,p1,s1,s2,s3,s4,s5
+sonar.issue.ignore.multicriteria=c1,c2a,c2b,c3,c5a,c5b,c6a,c6b,c7,c8,c9,c10a,c10b,c10c,cex1a,cex1b,cex2a,cex2b,cex3,cex4,f1,p1,s1,s2,s3,s4,s5
# Pointers should not be cast to integral types
# But we need that for smpi and other places
sonar.issue.ignore.multicriteria.cex4.ruleKey=c:S995
sonar.issue.ignore.multicriteria.cex4.resourceKey=examples/**/*.c
-# Ignore these C++17 rules in public headers, where we still support C++14
-
-# C++17: Concise syntax should be used for concatenatable namespaces
-sonar.issue.ignore.multicriteria.cxx17a.ruleKey=cpp:S5812
-sonar.issue.ignore.multicriteria.cxx17a.resourceKey=include/**/*
-# C++17: "if","switch", and range-based for loop initializer should be used to reduce scope of variables
-sonar.issue.ignore.multicriteria.cxx17b.ruleKey=cpp:S6004
-sonar.issue.ignore.multicriteria.cxx17b.resourceKey=include/**/*.hpp
-# C++17: Structured binding should be used
-sonar.issue.ignore.multicriteria.cxx17c.ruleKey=cpp:S6005
-sonar.issue.ignore.multicriteria.cxx17c.resourceKey=include/**/*.hpp
-# C++17: "std::string_view" should be used to pass a read-only string to a function
-sonar.issue.ignore.multicriteria.cxx17d.ruleKey=cpp:S6009
-sonar.issue.ignore.multicriteria.cxx17d.resourceKey=include/**/*.hpp
-# C++17: Redundant class template arguments should not be used
-sonar.issue.ignore.multicriteria.cxx17e.ruleKey=cpp:S6012
-sonar.issue.ignore.multicriteria.cxx17e.resourceKey=include/**/*.hpp
-# C++17: The "_t" and "_v" version of type traits should be used instead of "::type" and "::value"
-sonar.issue.ignore.multicriteria.cxx17f.ruleKey=cpp:S6020
-sonar.issue.ignore.multicriteria.cxx17f.resourceKey=include/**/*.hpp
-# C++17: "std::scoped_lock" should be used instead of "std::lock_guard"
-sonar.issue.ignore.multicriteria.cxx17g.ruleKey=cpp:S5997
-sonar.issue.ignore.multicriteria.cxx17g.resourceKey=include/**/*.hpp
-
# "reinterpret_cast" should not be used
# But we need this to interface C and Fortran
sonar.issue.ignore.multicriteria.f1.ruleKey=cpp:S3630
#include "simgrid/kernel/ProfileBuilder.hpp"
#include "simgrid/kernel/routing/NetPoint.hpp"
#include <simgrid/Exception.hpp>
+#include <simgrid/plugins/operation.hpp>
#include <simgrid/s4u/Actor.hpp>
#include <simgrid/s4u/Barrier.hpp>
#include <simgrid/s4u/Comm.hpp>
#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/Exec.hpp>
#include <simgrid/s4u/Host.hpp>
+#include <simgrid/s4u/Io.hpp>
#include <simgrid/s4u/Link.hpp>
#include <simgrid/s4u/Mailbox.hpp>
#include <simgrid/s4u/Mutex.hpp>
#include <vector>
namespace py = pybind11;
+using simgrid::plugins::CommOp;
+using simgrid::plugins::CommOpPtr;
+using simgrid::plugins::ExecOp;
+using simgrid::plugins::ExecOpPtr;
+using simgrid::plugins::IoOp;
+using simgrid::plugins::IoOpPtr;
+using simgrid::plugins::Operation;
+using simgrid::plugins::OperationPtr;
using simgrid::s4u::Actor;
using simgrid::s4u::ActorPtr;
using simgrid::s4u::Barrier;
using simgrid::s4u::BarrierPtr;
using simgrid::s4u::Comm;
using simgrid::s4u::CommPtr;
+using simgrid::s4u::Disk;
using simgrid::s4u::Engine;
using simgrid::s4u::Host;
+using simgrid::s4u::Io;
using simgrid::s4u::Link;
using simgrid::s4u::Mailbox;
using simgrid::s4u::Mutex;
params[i - 1] = py::cast(args[i]);
const auto fun_or_class = py::reinterpret_borrow<py::object>(fun_or_class_p);
- py::object res = fun_or_class(*params);
+ py::object res = fun_or_class(*params);
/* If I was passed a class, I just built an instance, so I need to call it now */
if (py::isinstance<py::function>(res))
res();
"Retrieve the netpoint associated to this zone")
.def("seal", &simgrid::s4u::NetZone::seal, "Seal this NetZone")
.def_property_readonly("name", &simgrid::s4u::NetZone::get_name,
- "The name of this network zone (read-only property).");
+ "The name of this network zone (read-only property).")
+ .def(
+ "__repr__", [](const simgrid::s4u::NetZone net) { return "NetZone(" + net.get_name() + ")"; },
+ "Textual representation of the NetZone");
/* Class ClusterCallbacks */
py::class_<simgrid::s4u::ClusterCallbacks>(m, "ClusterCallbacks", "Callbacks used to create cluster zones")
return self.attr("netpoint");
})
.def_property_readonly("netpoint", &Host::get_netpoint, "Retrieve the netpoint associated to this zone")
+ .def_property_readonly("disks", &Host::get_disks, "The list of disks on this host (read-only).")
.def("get_disks", &Host::get_disks, "Retrieve the list of disks in this host")
.def("set_core_count",
[](py::object self, double count) // XBT_ATTRIB_DEPRECATED_v334
}
});
},
- "");
+ "")
+ .def(
+ "__repr__", [](const Host* h) { return "Host(" + h->get_name() + ")"; },
+ "Textual representation of the Host");
py::enum_<simgrid::s4u::Host::SharingPolicy>(host, "SharingPolicy")
.value("NONLINEAR", simgrid::s4u::Host::SharingPolicy::NONLINEAR)
"Set sharing policy for this disk", py::arg("op"), py::arg("policy"),
py::arg("cb") = simgrid::s4u::NonLinearResourceCb())
.def("seal", &simgrid::s4u::Disk::seal, py::call_guard<py::gil_scoped_release>(), "Seal this disk")
- .def_property_readonly("name", &simgrid::s4u::Disk::get_name, "The name of this disk (read-only property).");
+ .def_property_readonly("name", &simgrid::s4u::Disk::get_name, "The name of this disk (read-only property).")
+ .def(
+ "__repr__", [](const Disk* d) { return "Disk(" + d->get_name() + ")"; },
+ "Textual representation of the Disk");
py::enum_<simgrid::s4u::Disk::SharingPolicy>(disk, "SharingPolicy")
.value("NONLINEAR", simgrid::s4u::Disk::SharingPolicy::NONLINEAR)
.value("LINEAR", simgrid::s4u::Disk::SharingPolicy::LINEAR)
.def_property_readonly("name", &Link::get_name, "The name of this link")
.def_property_readonly("bandwidth", &Link::get_bandwidth,
"The bandwidth (in bytes per second) (read-only property).")
- .def_property_readonly("latency", &Link::get_latency, "The latency (in seconds) (read-only property).");
-
+ .def_property_readonly("latency", &Link::get_latency, "The latency (in seconds) (read-only property).")
+ .def(
+ "__repr__", [](const Link* l) { return "Link(" + l->get_name() + ")"; },
+ "Textual representation of the Link");
py::enum_<Link::SharingPolicy>(link, "SharingPolicy")
.value("NONLINEAR", Link::SharingPolicy::NONLINEAR)
.value("WIFI", Link::SharingPolicy::WIFI)
py::class_<simgrid::s4u::Mailbox, std::unique_ptr<Mailbox, py::nodelete>>(
m, "Mailbox", "Mailbox. See the C++ documentation for details.")
.def(
- "__str__", [](const Mailbox* self) { return "Mailbox(" + self->get_name() + ")"; },
- "Textual representation of the Mailbox`")
+ "__repr__", [](const Mailbox* self) { return "Mailbox(" + self->get_name() + ")"; },
+ "Textual representation of the Mailbox")
.def_static("by_name", &Mailbox::by_name, py::call_guard<py::gil_scoped_release>(), py::arg("name"),
"Retrieve a Mailbox from its name")
.def_property_readonly("name", &Mailbox::get_name, "The name of that mailbox (read-only property).")
.def("acquire_timeout", &Semaphore::acquire_timeout, py::call_guard<py::gil_scoped_release>(), py::arg("timeout"),
"Acquire on the semaphore object with no timeout. Blocks until the semaphore is acquired or return "
"true if it has not been acquired after the specified timeout.")
- .def("release", &Semaphore::release, py::call_guard<py::gil_scoped_release>(),
- "Release the semaphore.")
+ .def("release", &Semaphore::release, py::call_guard<py::gil_scoped_release>(), "Release the semaphore.")
.def_property_readonly("capacity", &Semaphore::get_capacity, py::call_guard<py::gil_scoped_release>(),
"Get the semaphore capacity.")
.def_property_readonly("would_block", &Semaphore::would_block, py::call_guard<py::gil_scoped_release>(),
.def("unlock", &Mutex::unlock, py::call_guard<py::gil_scoped_release>(), "Release the mutex.")
// Allow mutexes to be automatically acquired/released with a context manager: `with mutex: ...`
.def("__enter__", &Mutex::lock, py::call_guard<py::gil_scoped_release>())
- .def("__exit__", [](Mutex* self, const py::object&, const py::object&, const py::object&) { self->unlock(); },
- py::call_guard<py::gil_scoped_release>());
+ .def(
+ "__exit__", [](Mutex* self, const py::object&, const py::object&, const py::object&) { self->unlock(); },
+ py::call_guard<py::gil_scoped_release>());
/* Class Barrier */
- py::class_<Barrier, BarrierPtr>(m, "Barrier",
- "A classical barrier, but blocking in the simulation world.")
+ py::class_<Barrier, BarrierPtr>(m, "Barrier", "A classical barrier, but blocking in the simulation world.")
.def(py::init<>(&Barrier::create), py::call_guard<py::gil_scoped_release>(), py::arg("expected_actors"),
"Barrier constructor.")
.def("wait", &Barrier::wait, py::call_guard<py::gil_scoped_release>(),
.def("resume", &Actor::resume, py::call_guard<py::gil_scoped_release>(),
"Resume that actor, that was previously suspend()ed.")
.def_static("kill_all", &Actor::kill_all, py::call_guard<py::gil_scoped_release>(),
- "Kill all actors but the caller.");
+ "Kill all actors but the caller.")
+ .def(
+ "__repr__", [](const ActorPtr a) { return "Actor(" + a->get_name() + ")"; },
+ "Textual representation of the Actor");
+
+ /* Enum Class IoOpType */
+ py::enum_<simgrid::s4u::Io::OpType>(m, "IoOpType")
+ .value("READ", simgrid::s4u::Io::OpType::READ)
+ .value("WRITE", simgrid::s4u::Io::OpType::WRITE);
+
+ /* Class Operation */
+ py::class_<Operation, OperationPtr>(m, "Operation", "Operation. See the C++ documentation for details.")
+ .def_static("init", &Operation::init)
+ .def_static(
+ "on_start_cb",
+ [](py::object cb) {
+ cb.inc_ref(); // keep alive after return
+ const py::gil_scoped_release gil_release;
+ Operation::on_start_cb([cb](Operation* op) {
+ const py::gil_scoped_acquire py_context; // need a new context for callback
+ py::reinterpret_borrow<py::function>(cb.ptr())(op);
+ });
+ },
+ "Add a callback called when each operation starts.")
+ .def_static(
+ "on_end_cb",
+ [](py::object cb) {
+ cb.inc_ref(); // keep alive after return
+ const py::gil_scoped_release gil_release;
+ Operation::on_end_cb([cb](Operation* op) {
+ const py::gil_scoped_acquire py_context; // need a new context for callback
+ py::reinterpret_borrow<py::function>(cb.ptr())(op);
+ });
+ },
+ "Add a callback called when each operation ends.")
+ .def_property_readonly("name", &Operation::get_name, "The name of this operation (read-only).")
+ .def_property_readonly("count", &Operation::get_count, "The execution count of this operation (read-only).")
+ .def_property_readonly("successors", &Operation::get_successors, "The successors of this operation (read-only).")
+ .def_property("amount", &Operation::get_amount, &Operation::set_amount,
+ "The amount of work to do for this operation.")
+ .def("enqueue_execs", py::overload_cast<int>(&Operation::enqueue_execs), py::call_guard<py::gil_scoped_release>(),
+ py::arg("n"), "Enqueue executions for this operation.")
+ .def("add_successor", py::overload_cast<OperationPtr>(&Operation::add_successor),
+ py::call_guard<py::gil_scoped_release>(), py::arg("op"), "Add a successor to this operation.")
+ .def("remove_successor", py::overload_cast<OperationPtr>(&Operation::remove_successor),
+ py::call_guard<py::gil_scoped_release>(), py::arg("op"), "Remove a successor of this operation.")
+ .def("remove_all_successors", &Operation::remove_all_successors, py::call_guard<py::gil_scoped_release>(),
+ "Remove all successors of this operation.")
+ .def("on_this_start", py::overload_cast<const std::function<void(Operation*)>&>(&Operation::on_this_start),
+ py::arg("func"), "Add a callback called when this operation starts.")
+ .def("on_this_end", py::overload_cast<const std::function<void(Operation*)>&>(&Operation::on_this_end),
+ py::arg("func"), "Add a callback called when this operation ends.")
+ .def(
+ "__repr__", [](const OperationPtr op) { return "Operation(" + op->get_name() + ")"; },
+ "Textual representation of the Operation");
+
+ /* Class CommOp */
+ py::class_<CommOp, CommOpPtr, Operation>(m, "CommOp",
+ "Communication Operation. See the C++ documentation for details.")
+ .def_static("init", py::overload_cast<const std::string&>(&CommOp::init),
+ py::call_guard<py::gil_scoped_release>(), py::arg("name"), "CommOp constructor")
+ .def_static("init", py::overload_cast<const std::string&, double, Host*, Host*>(&CommOp::init),
+ py::call_guard<py::gil_scoped_release>(), py::arg("name"), py::arg("bytes"), py::arg("source"),
+ py::arg("destination"), "CommOp constructor")
+ .def_property("source", &CommOp::get_source, &CommOp::set_source, "The source of the communication.")
+ .def_property("destination", &CommOp::get_destination, &CommOp::set_destination,
+ "The destination of the communication.")
+ .def_property("bytes", &CommOp::get_bytes, &CommOp::set_bytes, "The amount of bytes to send.")
+ .def(
+ "__repr__", [](const CommOpPtr c) { return "CommOp(" + c->get_name() + ")"; },
+ "Textual representation of the CommOp");
+
+ /* Class ExecOp */
+ py::class_<ExecOp, ExecOpPtr, Operation>(m, "ExecOp", "Execution Operation. See the C++ documentation for details.")
+ .def_static("init", py::overload_cast<const std::string&>(&ExecOp::init),
+ py::call_guard<py::gil_scoped_release>(), py::arg("name"), "ExecOp constructor")
+ .def_static("init", py::overload_cast<const std::string&, double, Host*>(&ExecOp::init),
+ py::call_guard<py::gil_scoped_release>(), py::arg("name"), py::arg("flops"), py::arg("host"),
+ "CommOp constructor.")
+ .def_property("host", &ExecOp::get_host, &ExecOp::set_host, "The host of the execution.")
+ .def_property("flops", &ExecOp::get_flops, &ExecOp::set_flops, "The amount of flops to execute.")
+ .def(
+ "__repr__", [](const ExecOpPtr e) { return "ExecOp(" + e->get_name() + ")"; },
+ "Textual representation of the ExecOp");
+
+ /* Class IoOp */
+ py::class_<IoOp, IoOpPtr, Operation>(m, "IoOp", "IO Operation. See the C++ documentation for details.")
+ .def_static("init", py::overload_cast<const std::string&>(&IoOp::init), py::call_guard<py::gil_scoped_release>(),
+ py::arg("name"), "IoOp constructor")
+ .def_static("init", py::overload_cast<const std::string&, double, Disk*, Io::OpType>(&IoOp::init),
+ py::call_guard<py::gil_scoped_release>(), py::arg("name"), py::arg("bytes"), py::arg("disk"),
+ py::arg("type"), "IoOp constructor.")
+ .def_property("disk", &IoOp::get_disk, &IoOp::set_disk, "The disk of the IO.")
+ .def_property("bytes", &IoOp::get_bytes, &IoOp::set_bytes, "The amount of bytes to process.")
+ .def_property("type", &IoOp::get_bytes, &IoOp::set_bytes, "The type of IO.")
+ .def(
+ "__repr__", [](const IoOpPtr io) { return "IoOp(" + io->get_name() + ")"; },
+ "Textual representation of the IoOp");
}
#include "dax_dtd.c"
#if SIMGRID_HAVE_JSON
+// Disable implicit conversions. See https://github.com/nlohmann/json#implicit-conversions
+#ifdef JSON_USE_IMPLICIT_CONVERSIONS
+#undef JSON_USE_IMPLICIT_CONVERSIONS
+#endif
+#define JSON_USE_IMPLICIT_CONVERSIONS 0
#include <nlohmann/json.hpp>
#include <sstream>
#endif
for (auto const& task: data["workflow"]["tasks"]) {
if (task["type"] == "compute") {
- current = Exec::init()->set_name(task["name"])->set_flops_amount(task["runtime"]);
+ current =
+ Exec::init()->set_name(task["name"].get<std::string>())->set_flops_amount(task["runtime"].get<double>());
if (task.contains("machine"))
- dynamic_cast<Exec*>(current.get())->set_host(simgrid::s4u::Engine::get_instance()->host_by_name(task["machine"]));
+ dynamic_cast<Exec*>(current.get())
+ ->set_host(simgrid::s4u::Engine::get_instance()->host_by_name(task["machine"].get<std::string>()));
}
else if (task["type"] == "transfer"){
- current = Comm::sendto_init()->set_name(task["name"])->set_payload_size(task["bytesWritten"]);
+ current = Comm::sendto_init()
+ ->set_name(task["name"].get<std::string>())
+ ->set_payload_size(task["bytesWritten"].get<double>());
if (task.contains("machine"))
- comms_destinations[current] = simgrid::s4u::Engine::get_instance()->host_by_name(task["machine"]);
+ comms_destinations[current] =
+ simgrid::s4u::Engine::get_instance()->host_by_name(task["machine"].get<std::string>());
if (task["parents"].size() == 1) {
ActivityPtr parent_activity;
for (auto const& activity: dag) {
dag.push_back(current);
for (auto const& parent : task["parents"])
- successors[parent].push_back(current);
+ successors[parent.get<std::string>()].push_back(current);
}
// Assign successors
for (auto const& [parent, successors_list] : successors)
#include <xbt/graph.h>
#include "src/instr/instr_private.hpp"
+#include "src/kernel/activity/ExecImpl.hpp"
#include "src/kernel/resource/CpuImpl.hpp"
#include "src/kernel/resource/NetworkModel.hpp"
root->get_type()->by_name_or_create("MIGRATE_LINK", mpi, mpi);
mpi->by_name_or_create<StateType>("MIGRATE_STATE");
}
+
+ if (TRACE_actor_is_enabled()) {
+ auto* host_type = container->get_type();
+ auto* state = host_type->by_name_or_create<StateType>("HOST_STATE");
+ state->set_calling_container(container);
+ state->add_entity_value("receive", "1 0 0");
+ state->add_entity_value("send", "0 0 1");
+ state->add_entity_value("execute", "0 1 1");
+ }
}
static void on_action_state_change(kernel::resource::Action const& action,
resource_set_utilization("HOST", "speed_used", cpu->get_cname(), action.get_category(), value,
action.get_last_update(), simgrid_get_clock() - action.get_last_update());
- if (const auto* link = dynamic_cast<kernel::resource::StandardLinkImpl*>(resource))
+ else if (const auto* link = dynamic_cast<kernel::resource::StandardLinkImpl*>(resource))
resource_set_utilization("LINK", "bandwidth_used", link->get_cname(), action.get_category(), value,
action.get_last_update(), simgrid_get_clock() - action.get_last_update());
}
}
+static void on_activity_suspend_resume(s4u::Activity const& activity)
+{
+ on_action_state_change(*activity.get_impl()->model_action_, /*ignored*/ kernel::resource::Action::State::STARTED);
+}
+
static void on_platform_created()
{
currentContainer.clear();
s4u::NetZone::on_creation_cb(on_netzone_creation);
- kernel::resource::CpuAction::on_state_change.connect(on_action_state_change);
+ s4u::Host::on_exec_state_change_cb(on_action_state_change);
s4u::Link::on_communication_state_change_cb(on_action_state_change);
+ s4u::Exec::on_suspend_cb(on_activity_suspend_resume);
+ s4u::Exec::on_resume_cb(on_activity_suspend_resume);
if (TRACE_actor_is_enabled()) {
s4u::Actor::on_creation_cb(on_actor_creation);
});
s4u::Actor::on_wake_up_cb(
[](s4u::Actor const& actor) { Container::by_name(instr_pid(actor))->get_state("ACTOR_STATE")->pop_event(); });
- s4u::Exec::on_start_cb([](s4u::Exec const&) {
- Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("execute");
+
+ s4u::Exec::on_start_cb([](s4u::Exec const& e) {
+ std::string pid = instr_pid(*s4u::Actor::self());
+ if (pid == "-0") //Exec is launched directly by Maestro, use the host as container
+ Container::by_name(e.get_host()->get_name())->get_state("HOST_STATE")->push_event("execute");
+ else
+ Container::by_name(pid)->get_state("ACTOR_STATE")->push_event("execute");
+ });
+
+ s4u::Exec::on_completion_cb([](const s4u::Exec& e) {
+ std::string pid = instr_pid(*s4u::Actor::self());
+ if (pid == "-0") //Exec is launched directly by Maestro, use the host as container
+ Container::by_name(e.get_host()->get_name())->get_state("HOST_STATE")->pop_event();
+ else
+ Container::by_name(pid)->get_state("ACTOR_STATE")->pop_event();
+ });
+
+ s4u::Comm::on_completion_cb([](const s4u::Comm& c) {
+ if (c.get_sender()) {
+ Container::by_name(instr_pid(*c.get_sender()))->get_state("ACTOR_STATE")->pop_event();
+ Container::by_name(instr_pid(*c.get_receiver()))->get_state("ACTOR_STATE")->pop_event();
+ } else {
+ Container::by_name(c.get_source()->get_name())->get_state("HOST_STATE")->pop_event();
+ Container::by_name(c.get_destination()->get_name())->get_state("HOST_STATE")->pop_event();
+ }
});
- s4u::Activity::on_completion_cb([](const s4u::Activity&) {
- Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->pop_event();
+ s4u::Comm::on_start_cb([](s4u::Comm const& c) {
+ std::string pid = instr_pid(*s4u::Actor::self());
+ if (pid == "-0") { //Comm is launched directly by Maestro, use the host as container
+ Container::by_name(c.get_source()->get_name())->get_state("HOST_STATE")->push_event("start");
+ Container::by_name(c.get_destination()->get_name())->get_state("HOST_STATE")->push_event("start");
+ }
});
- s4u::Comm::on_send_cb([](s4u::Comm const&) {
+ s4u::Comm::on_send_cb([](s4u::Comm const& c) {
Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("send");
});
- s4u::Comm::on_recv_cb([](s4u::Comm const&) {
+ s4u::Comm::on_recv_cb([](s4u::Comm const& c) {
Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("receive");
});
s4u::Actor::on_host_change_cb(on_actor_host_change);
->get_state("MPI_STATE")
->push_event("computing", new CpuTIData("compute", exec.get_cost()));
});
- s4u::Activity::on_completion_cb([](const s4u::Activity&) {
+ s4u::Exec::on_completion_cb([](const s4u::Exec&) {
Container::by_name("rank-" + std::to_string(s4u::Actor::self()->get_pid()))->get_state("MPI_STATE")->pop_event();
});
}
void ActivityImpl::suspend()
{
- if (model_action_ == nullptr)
+ if (model_action_ == nullptr) {
+ XBT_CRITICAL("POUET");
return;
+ }
XBT_VERB("This activity is suspended (remain: %f)", model_action_->get_remains());
+ get_iface()->fire_on_suspend();
+ get_iface()->fire_on_this_suspend();
model_action_->suspend();
- s4u::Activity::on_suspended(*get_iface());
}
void ActivityImpl::resume()
if (model_action_ == nullptr)
return;
XBT_VERB("This activity is resumed (remain: %f)", model_action_->get_remains());
+ get_iface()->fire_on_resume();
+ get_iface()->fire_on_this_resume();
model_action_->resume();
- s4u::Activity::on_resumed(*get_iface());
}
void ActivityImpl::cancel()
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_network, kernel, "Kernel network-related synchronization");
namespace simgrid::kernel::activity {
-xbt::signal<void(CommImpl const&)> CommImpl::on_start;
-xbt::signal<void(CommImpl const&)> CommImpl::on_completion;
std::function<void(CommImpl*, void*, size_t)> CommImpl::copy_data_callback_ = [](kernel::activity::CommImpl* comm,
void* buff, size_t buff_size) {
model_action_->set_category(get_tracing_category());
set_start_time(model_action_->get_start_time());
set_state(State::RUNNING);
- on_start(*this);
XBT_DEBUG("Starting communication %p from '%s' to '%s' (model action: %p; state: %s)", this, from_->get_cname(),
to_->get_cname(), model_action_, get_state_str());
XBT_DEBUG("CommImpl::finish() comm %p, state %s, src_proc %p, dst_proc %p, detached: %d", this, get_state_str(),
src_actor_.get(), dst_actor_.get(), detached_);
- on_completion(*this);
+ if (get_iface()) {
+ const auto& piface = static_cast<const s4u::Comm&>(*get_iface());
+ s4u::Comm::on_completion(piface);
+ piface.on_this_completion(piface);
+ }
/* Update synchro state */
if (src_timeout_ && src_timeout_->get_state() == resource::Action::State::FINISHED)
void* src_data_ = nullptr; /* User data associated to the communication */
void* dst_data_ = nullptr;
- static xbt::signal<void(CommImpl const&)> on_start;
- static xbt::signal<void(CommImpl const&)> on_completion;
};
} // namespace simgrid::kernel::activity
ActorImpl::~ActorImpl()
{
- if (EngineImpl::has_instance() && not EngineImpl::get_instance()->is_maestro(this))
+ if (EngineImpl::has_instance() && not EngineImpl::get_instance()->is_maestro(this)) {
s4u::Actor::on_destruction(*get_ciface());
+ get_ciface()->on_this_destruction(*get_ciface());
+ }
}
/* Become an actor in the simulation
undaemonize();
s4u::Actor::on_termination(*get_ciface());
+ get_ciface()->on_this_termination(*get_ciface());
while (not mailboxes_.empty())
mailboxes_.back()->set_receiver(nullptr);
void ActivityTestanySimcall::serialize(std::stringstream& stream) const
{
stream << (short)mc::Transition::Type::TESTANY << ' ' << activities_.size() << ' ';
- for (auto const& act : activities_) {
+ for (auto const* act : activities_) {
serialize_activity_test(act, stream);
stream << ' ';
}
std::string ActivityTestanySimcall::to_string() const
{
std::stringstream buffer("TestAny(");
- for (auto const& act : activities_) {
+ for (auto const* act : activities_) {
buffer << to_string_activity_test(act);
}
return buffer.str();
void ActivityWaitanySimcall::serialize(std::stringstream& stream) const
{
stream << (short)mc::Transition::Type::WAITANY << ' ' << activities_.size() << ' ';
- for (auto const& act : activities_) {
+ for (auto const* act : activities_) {
serialize_activity_wait(act, timeout_ > 0, stream);
stream << ' ';
}
std::string ActivityWaitanySimcall::to_string() const
{
std::stringstream buffer("WaitAny(");
- for (auto const& act : activities_) {
+ for (auto const* act : activities_) {
buffer << to_string_activity_wait(act);
}
return buffer.str();
{
std::stringstream debug;
std::copy(container.begin(), container.end(),
- std::ostream_iterator<typename std::remove_reference<decltype(container)>::type::value_type>(debug, " "));
+ std::ostream_iterator<typename std::remove_reference_t<decltype(container)>::value_type>(debug, " "));
return debug.str();
}
void CpuImpl::on_speed_change()
{
s4u::Host::on_speed_change(*piface_);
+ piface_->on_this_speed_change(*piface_);
}
CpuImpl* CpuImpl::set_core_count(int core_count)
set_last_value(get_rate());
}
-xbt::signal<void(CpuAction const&, Action::State)> CpuAction::on_state_change;
-
-void CpuAction::suspend()
-{
- Action::State previous = get_state();
- on_state_change(*this, previous);
- Action::suspend();
-}
-
-void CpuAction::resume()
-{
- Action::State previous = get_state();
- on_state_change(*this, previous);
- Action::resume();
-}
-
void CpuAction::set_state(Action::State state)
{
Action::State previous = get_state();
Action::set_state(state);
- on_state_change(*this, previous);
+ s4u::Host::on_exec_state_change(*this, previous);
}
/** @brief returns a list of all CPUs that this action is using */
public:
using Action::Action;
- /** @brief Signal emitted when the action state changes (ready/running/done, etc)
- * Signature: `void(CpuAction const& action, simgrid::kernel::resource::Action::State previous)`
- */
- static xbt::signal<void(CpuAction const&, Action::State)> on_state_change;
-
void set_state(Action::State state) override;
void update_remains_lazy(double now) override;
std::list<CpuImpl*> cpus() const;
-
- void suspend() override;
- void resume() override;
};
} // namespace simgrid::kernel::resource
void DiskImpl::destroy()
{
s4u::Disk::on_destruction(piface_);
+ piface_.on_this_destruction(piface_);
delete this;
}
{
if (not is_on()) {
Resource::turn_on();
- s4u::Disk::on_state_change(piface_);
+ s4u::Disk::on_onoff(piface_);
+ piface_.on_this_onoff(piface_);
}
}
void DiskImpl::turn_off()
{
if (is_on()) {
Resource::turn_off();
- s4u::Disk::on_state_change(piface_);
+ s4u::Disk::on_onoff(piface_);
+ piface_.on_this_onoff(piface_);
const kernel::lmm::Element* elem = nullptr;
double now = EngineImpl::get_clock();
void HostImpl::destroy()
{
s4u::Host::on_destruction(*this->get_iface());
+ this->get_iface()->on_this_destruction(*this->get_iface());
delete this;
}
void StandardLinkImpl::destroy()
{
s4u::Link::on_destruction(piface_);
+ piface_.on_this_destruction(piface_);
delete this;
}
{
if (not is_on()) {
Resource::turn_on();
- s4u::Link::on_state_change(piface_);
+ s4u::Link::on_onoff(piface_);
+ piface_.on_this_onoff(piface_);
}
}
{
if (is_on()) {
Resource::turn_off();
- s4u::Link::on_state_change(piface_);
+ s4u::Link::on_onoff(piface_);
+ piface_.on_this_onoff(piface_);
const kernel::lmm::Element* elem = nullptr;
double now = EngineImpl::get_clock();
void StandardLinkImpl::on_bandwidth_change() const
{
s4u::Link::on_bandwidth_change(piface_);
+ piface_.on_this_bandwidth_change(piface_);
}
void StandardLinkImpl::set_bandwidth_profile(profile::Profile* profile)
*/
const double virt_overhead = 1; // 0.95
-static void host_state_change(s4u::Host const& host)
+static void host_onoff(s4u::Host const& host)
{
if (not host.is_on()) { // just turned off.
std::vector<s4u::VirtualMachine*> trash;
/* Find all VMs living on that host */
- for (s4u::VirtualMachine* const& vm : VirtualMachineImpl::allVms_)
+ for (auto* vm : VirtualMachineImpl::allVms_)
if (vm->get_pm() == &host)
trash.push_back(vm);
- for (s4u::VirtualMachine* vm : trash)
+ for (auto* vm : trash)
vm->shutdown();
}
}
}
}
-static void remove_active_exec(s4u::Activity const& task)
+static void remove_active_exec(s4u::Exec const& exec)
{
- const auto* exec = dynamic_cast<s4u::Exec const*>(&task);
- if (exec == nullptr)
+ if (not exec.is_assigned())
return;
- if (not exec->is_assigned())
- return;
- const s4u::VirtualMachine* vm = dynamic_cast<s4u::VirtualMachine*>(exec->get_host());
+ const s4u::VirtualMachine* vm = dynamic_cast<s4u::VirtualMachine*>(exec.get_host());
if (vm != nullptr) {
VirtualMachineImpl* vm_impl = vm->get_vm_impl();
- for (int i = 1; i <= exec->get_thread_count(); i++)
+ for (int i = 1; i <= exec.get_thread_count(); i++)
vm_impl->remove_active_exec();
vm_impl->update_action_weight();
}
VMModel::VMModel(const std::string& name) : HostModel(name)
{
- s4u::Host::on_state_change_cb(host_state_change);
+ s4u::Host::on_onoff_cb(host_onoff);
s4u::Exec::on_start_cb(add_active_exec);
- s4u::Activity::on_completion_cb(remove_active_exec);
- s4u::Activity::on_resumed_cb(add_active_activity);
- s4u::Activity::on_suspended_cb(remove_active_activity);
+ s4u::Exec::on_completion_cb(remove_active_exec);
+ s4u::Exec::on_resume_cb(add_active_activity);
+ s4u::Exec::on_suspend_cb(remove_active_activity);
}
double VMModel::next_occurring_event(double now)
**/
/* iterate for all virtual machines */
- for (s4u::VirtualMachine* const& ws_vm : VirtualMachineImpl::allVms_) {
+ for (auto const* ws_vm : VirtualMachineImpl::allVms_) {
if (ws_vm->get_state() == s4u::VirtualMachine::State::SUSPENDED) // Ignore suspended VMs
continue;
void VirtualMachineImpl::start()
{
s4u::VirtualMachine::on_start(*get_iface());
+ get_iface()->on_this_start(*get_iface());
s4u::VmHostExt::ensureVmExtInstalled();
if (physical_host_->extension<s4u::VmHostExt>() == nullptr)
not physical_host_->extension<s4u::VmHostExt>()->overcommit) { /* Need to verify that we don't overcommit */
/* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */
size_t total_ramsize_of_vms = 0;
- for (auto* const& ws_vm : allVms_)
+ for (auto const* ws_vm : allVms_)
if (physical_host_ == ws_vm->get_pm())
total_ramsize_of_vms += ws_vm->get_ramsize();
vm_state_ = s4u::VirtualMachine::State::RUNNING;
s4u::VirtualMachine::on_started(*get_iface());
+ get_iface()->on_this_started(*get_iface());
}
void VirtualMachineImpl::suspend(const actor::ActorImpl* issuer)
{
s4u::VirtualMachine::on_suspend(*get_iface());
+ get_iface()->on_this_suspend(*get_iface());
if (vm_state_ != s4u::VirtualMachine::State::RUNNING)
throw VmFailureException(XBT_THROW_POINT,
vm_state_ = s4u::VirtualMachine::State::RUNNING;
s4u::VirtualMachine::on_resume(*get_iface());
+ get_iface()->on_this_resume(*get_iface());
}
/** @brief Power off a VM.
set_state(s4u::VirtualMachine::State::DESTROYED);
s4u::VirtualMachine::on_shutdown(*get_iface());
+ get_iface()->on_this_shutdown(*get_iface());
}
/** @brief Change the physical host on which the given VM is running
{
is_migrating_ = true;
s4u::VirtualMachine::on_migration_start(*get_iface());
+ get_iface()->on_this_migration_start(*get_iface());
}
void VirtualMachineImpl::end_migration()
{
is_migrating_ = false;
s4u::VirtualMachine::on_migration_end(*get_iface());
+ get_iface()->on_this_migration_end(*get_iface());
}
void VirtualMachineImpl::seal()
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
+#include <simgrid/s4u/Comm.hpp>
#include <simgrid/s4u/Host.hpp>
#include "src/kernel/activity/CommImpl.hpp"
/************
* Resource *
************/
+static void update_bw_comm_start(const s4u::Comm& comm)
+{
+ auto* pimpl = static_cast<activity::CommImpl*>(comm.get_impl());
+
+ auto const* actionWifi = dynamic_cast<const kernel::resource::WifiLinkAction*>(pimpl->model_action_);
+ if (actionWifi == nullptr)
+ return;
+
+ if (auto* link_src = actionWifi->get_src_link()) {
+ link_src->inc_active_flux();
+ }
+ if (auto* link_dst = actionWifi->get_dst_link()) {
+ link_dst->inc_active_flux();
+ }
+}
WifiLinkImpl::WifiLinkImpl(const std::string& name, const std::vector<double>& bandwidths, lmm::System* system)
: StandardLinkImpl(name)
this->set_constraint(system->constraint_new(this, 1));
for (auto bandwidth : bandwidths)
bandwidths_.push_back({bandwidth, 1.0, nullptr});
- kernel::activity::CommImpl::on_start.connect(&update_bw_comm_start);
+ s4u::Comm::on_start_cb(&update_bw_comm_start);
s4u::Link::on_communication_state_change_cb(&update_bw_comm_end);
}
nb_active_flux_--;
}
-void WifiLinkImpl::update_bw_comm_start(const kernel::activity::CommImpl& comm)
-{
- auto const* actionWifi = dynamic_cast<const simgrid::kernel::resource::WifiLinkAction*>(comm.model_action_);
- if (actionWifi == nullptr)
- return;
-
- if (auto* link_src = actionWifi->get_src_link()) {
- link_src->inc_active_flux();
- }
- if (auto* link_dst = actionWifi->get_dst_link()) {
- link_dst->inc_active_flux();
- }
-}
-
void WifiLinkImpl::update_bw_comm_end(const simgrid::kernel::resource::NetworkAction& action,
simgrid::kernel::resource::Action::State /*state*/)
{
void set_latency(double) override;
bool toggle_callback();
- static void update_bw_comm_start(const kernel::activity::CommImpl&);
- static void update_bw_comm_end(const simgrid::kernel::resource::NetworkAction& action,
- simgrid::kernel::resource::Action::State state);
+ static void update_bw_comm_end(const NetworkAction& action, Action::State state);
void inc_active_flux();
void dec_active_flux();
static double wifi_link_dynamic_sharing(const WifiLinkImpl& link, double capacity, int n);
if (cfg_weight_S_parameter > 0) {
action->sharing_penalty_ = std::accumulate(route.begin(), route.end(), action->sharing_penalty_,
- [](double total, StandardLinkImpl* const& link) {
+ [](double total, StandardLinkImpl const* link) {
return total + cfg_weight_S_parameter / link->get_bandwidth();
});
}
engine->get_netzone_root()->set_network_model(net_model);
simgrid::s4u::Link::on_communication_state_change_cb(NetworkIBModel::IB_action_state_changed_callback);
- simgrid::kernel::activity::CommImpl::on_start.connect(NetworkIBModel::IB_comm_start_callback);
+ simgrid::s4u::Comm::on_start_cb(NetworkIBModel::IB_comm_start_callback);
simgrid::s4u::Host::on_creation_cb(NetworkIBModel::IB_create_host_callback);
simgrid::config::set_default<double>("network/weight-S", 8775);
});
ibModel->active_comms.erase(&action);
}
-void NetworkIBModel::IB_comm_start_callback(const activity::CommImpl& comm)
+void NetworkIBModel::IB_comm_start_callback(const s4u::Comm& comm)
{
- auto* action = static_cast<NetworkAction*>(comm.model_action_);
+ auto* action = static_cast<NetworkAction*>(static_cast<activity::CommImpl*>(comm.get_impl())->model_action_);
auto* ibModel = static_cast<NetworkIBModel*>(action->get_model());
auto* act_src = &ibModel->active_nodes.at(action->get_src().get_name());
auto* act_dst = &ibModel->active_nodes.at(action->get_dst().get_name());
static void IB_create_host_callback(s4u::Host const& host);
static void IB_action_state_changed_callback(NetworkAction& action, Action::State /*previous*/);
- static void IB_comm_start_callback(const activity::CommImpl& comm);
+ static void IB_comm_start_callback(const s4u::Comm& comm);
};
} // namespace simgrid::kernel::resource
#endif
*****************/
extern std::map<std::string, SgFlow*, std::less<>> flow_from_sock;
-extern std::map<std::string, ns3::ApplicationContainer, std::less<>> sink_from_sock;
static int number_of_links = 1;
static int number_of_networks = 1;
});
}
-static simgrid::config::Flag<std::string>
- ns3_tcp_model("ns3/TcpModel", "The ns-3 tcp model can be: NewReno or Reno or Tahoe", "default");
+static simgrid::config::Flag<std::string> ns3_network_model_name("ns3/NetworkModel", {"ns3/TcpModel"},
+ "The ns-3 tcp model can be: NewReno or Cubic",
+ "default", [](const std::string&) {});
static simgrid::config::Flag<std::string> ns3_seed(
"ns3/seed",
"The random seed provided to ns-3. Either 'time' to seed with time(), blank to not set (default), or a number.", "",
"LinkEnergy plugin and ns-3 network models are not compatible. Are you looking for Ecofen, maybe?");
NetPointNs3::EXTENSION_ID = routing::NetPoint::extension_create<NetPointNs3>();
+ auto const& NetworkProtocol = ns3_network_model_name.get();
+
+ if (NetworkProtocol == "UDP") {
+ /*UdpClient=0
+UdpEchoClientApplication=0
+UdpEchoServerApplication=0
+UdpL4Protocol=0
+UdpServer=0
+UdpSocket=0
+UdpSocketImpl=0
+UdpTraceClient=0*/
+ LogComponentEnable("UdpSocket", ns3::LOG_LEVEL_DEBUG);
+ LogComponentEnable("UdpL4Protocol", ns3::LOG_LEVEL_DEBUG);
+ } else {
+ ns3::Config::SetDefault("ns3::TcpSocket::SegmentSize", ns3::UintegerValue(1000));
+ ns3::Config::SetDefault("ns3::TcpSocket::DelAckCount", ns3::UintegerValue(1));
+ ns3::Config::SetDefault("ns3::TcpSocketBase::Timestamp", ns3::BooleanValue(false));
+ }
- ns3::Config::SetDefault("ns3::TcpSocket::SegmentSize", ns3::UintegerValue(1000));
- ns3::Config::SetDefault("ns3::TcpSocket::DelAckCount", ns3::UintegerValue(1));
- ns3::Config::SetDefault("ns3::TcpSocketBase::Timestamp", ns3::BooleanValue(false));
-
- if (auto const& TcpProtocol = ns3_tcp_model.get(); TcpProtocol == "default") {
- /* nothing to do */
+ if (NetworkProtocol == "NewReno" || NetworkProtocol == "Cubic") {
+ XBT_INFO("Switching Tcp protocol to '%s'", NetworkProtocol.c_str());
+ ns3::Config::SetDefault("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::Tcp" + NetworkProtocol));
- } else if (TcpProtocol == "Reno" || TcpProtocol == "NewReno" || TcpProtocol == "Tahoe") {
- XBT_INFO("Switching Tcp protocol to '%s'", TcpProtocol.c_str());
- ns3::Config::SetDefault("ns3::TcpL4Protocol::SocketType", ns3::StringValue("ns3::Tcp" + TcpProtocol));
+ } else if (NetworkProtocol == "UDP") {
+ XBT_INFO("Switching network protocol to UDP.");
- } else {
- xbt_die("The ns3/TcpModel must be: NewReno or Reno or Tahoe");
+ } else if (NetworkProtocol != "default") {
+ xbt_die("The ns3/NetworkModel must be: NewReno, Cubic or UDP but it's '%s'", NetworkProtocol.c_str());
}
routing::NetPoint::on_creation.connect([](routing::NetPoint& pt) {
std::vector<StandardLinkImpl*> route;
action->get_src().route_to(&action->get_dst(), route, nullptr);
- for (auto const& link : route)
+ for (auto const* link : route)
instr::resource_set_utilization("LINK", "bandwidth_used", link->get_cname(), action->get_category(),
data_delta_sent / delta, now - delta, delta);
}
delete flow;
flow_from_sock.erase(ns3_socket);
- sink_from_sock.erase(ns3_socket);
}
}
dst->get_netpoint()->get_cname());
ns3::PacketSinkHelper sink("ns3::TcpSocketFactory", ns3::InetSocketAddress(ns3::Ipv4Address::GetAny(), port_number));
- ns3::ApplicationContainer apps = sink.Install(dst_node);
+ sink.Install(dst_node);
ns3::Ptr<ns3::Socket> sock = ns3::Socket::CreateSocket(src_node, ns3::TcpSocketFactory::GetTypeId());
- XBT_DEBUG("Create socket %s for a flow of %.0f Bytes from %s to %s with Interface %s",
- transform_socket_ptr(sock).c_str(), totalBytes, src->get_cname(), dst->get_cname(), addr.c_str());
+ auto sock_addr = transform_socket_ptr(sock);
+ XBT_DEBUG("Create socket %s for a flow of %.0f Bytes from %s to %s with Interface %s", sock_addr.c_str(), totalBytes,
+ src->get_cname(), dst->get_cname(), addr.c_str());
- flow_from_sock.try_emplace(transform_socket_ptr(sock), new SgFlow(static_cast<uint32_t>(totalBytes), this));
- sink_from_sock.try_emplace(transform_socket_ptr(sock), apps);
+ flow_from_sock.try_emplace(sock_addr, new SgFlow(static_cast<uint32_t>(totalBytes), this));
sock->Bind(ns3::InetSocketAddress(port_number));
+
ns3::Simulator::ScheduleNow(&start_flow, sock, addr.c_str(), port_number);
port_number = 1 + (port_number % UINT16_MAX);
ns3::Ptr<ns3::Node> get_ns3node_from_sghost(const simgrid::s4u::Host* host)
{
- xbt_assert(host->get_netpoint()->extension<NetPointNs3>() != nullptr, "Please only use this function on ns-3 nodes");
- return host->get_netpoint()->extension<NetPointNs3>()->ns3_node_;
+ auto* netext = host->get_netpoint()->extension<NetPointNs3>();
+ xbt_assert(netext != nullptr, "Please only use this function on ns-3 nodes");
+ return netext->ns3_node_;
}
} // namespace simgrid
#include "src/kernel/resource/NetworkModel.hpp"
#include "src/kernel/resource/StandardLinkImpl.hpp"
-namespace simgrid ::kernel::resource {
+namespace simgrid::kernel::resource {
class NetworkNS3Model : public NetworkModel {
public:
#include <algorithm>
-std::map<std::string, SgFlow*, std::less<>> flow_from_sock; // ns3::sock -> SgFlow
-std::map<std::string, ns3::ApplicationContainer, std::less<>> sink_from_sock; // ns3::sock -> ns3::PacketSink
+std::map<std::string, SgFlow*, std::less<>> flow_from_sock; // ns3::sock -> SgFlow
static void receive_callback(ns3::Ptr<ns3::Socket> socket);
static void datasent_cb(ns3::Ptr<ns3::Socket> socket, uint32_t dataSent);
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_ns3);
-SgFlow::SgFlow(uint32_t totalBytes, simgrid::kernel::resource::NetworkNS3Action* action)
- : total_bytes_(totalBytes), remaining_(totalBytes), action_(action)
-{
-}
-
static SgFlow* getFlowFromSocket(ns3::Ptr<ns3::Socket> socket)
{
auto it = flow_from_sock.find(transform_socket_ptr(socket));
return (it == flow_from_sock.end()) ? nullptr : it->second;
}
-static ns3::ApplicationContainer* getSinkFromSocket(ns3::Ptr<ns3::Socket> socket)
-{
- auto it = sink_from_sock.find(transform_socket_ptr(socket));
- return (it == sink_from_sock.end()) ? nullptr : &(it->second);
-}
-
static void receive_callback(ns3::Ptr<ns3::Socket> socket)
{
SgFlow* flow = getFlowFromSocket(socket);
static void send_cb(ns3::Ptr<ns3::Socket> sock, uint32_t /*txSpace*/)
{
- SgFlow* flow = getFlowFromSocket(sock);
- const ns3::ApplicationContainer* sink = getSinkFromSocket(sock);
+ SgFlow* flow = getFlowFromSocket(sock);
XBT_DEBUG("Asked to write on F[%p, total: %u, remain: %u]", flow, flow->total_bytes_, flow->remaining_);
if (flow->remaining_ == 0) // all data was already buffered (and socket was already closed)
}
if (flow->buffered_bytes_ >= flow->total_bytes_) {
- XBT_DEBUG("Closing Sockets of flow %p", flow);
- // Closing the sockets of the receiving application
- ns3::Ptr<ns3::PacketSink> app = ns3::DynamicCast<ns3::PacketSink, ns3::Application>(sink->Get(0));
- ns3::Ptr<ns3::Socket> listening_sock = app->GetListeningSocket();
- listening_sock->Close();
- listening_sock->SetRecvCallback(ns3::MakeNullCallback<void, ns3::Ptr<ns3::Socket>>());
- for (ns3::Ptr<ns3::Socket> accepted_sock : app->GetAcceptedSockets())
- accepted_sock->Close();
- // Closing the socket of the sender
+ XBT_DEBUG("Closing sender's socket of flow %p", flow);
sock->Close();
}
}
void start_flow(ns3::Ptr<ns3::Socket> sock, const char* to, uint16_t port_number)
{
SgFlow* flow = getFlowFromSocket(sock);
- ns3::InetSocketAddress serverAddr(to, port_number);
+ ns3::InetSocketAddress serverAddr(to, port_number);
sock->Connect(serverAddr);
- // tell the tcp implementation to call send_cb again
+
+ // tell the network implementation to call send_cb again
// if we blocked and new tx buffer space becomes available
sock->SetSendCallback(MakeCallback(&send_cb));
// Notice when we actually sent some data (mostly for the TRACING module)
#include <ns3/node.h>
#include <ns3/tcp-socket-factory.h>
+#include <ns3/udp-socket-factory.h>
#include <ns3/wifi-module.h>
#include <cstdint>
class XBT_PRIVATE SgFlow {
public:
- SgFlow(uint32_t total_bytes, simgrid::kernel::resource::NetworkNS3Action* action);
+ SgFlow(uint32_t totalBytes, simgrid::kernel::resource::NetworkNS3Action* action)
+ : total_bytes_(totalBytes), remaining_(totalBytes), action_(action)
+ {
+ }
// private:
std::uint32_t buffered_bytes_ = 0;
host_list_[k / host_nb]->route_to(host_list_[k % host_nb], route, &lat);
latency = std::max(latency, lat);
- for (auto const& link : route)
+ for (auto const* link : route)
affected_links.insert(link->get_cname());
}
std::vector<StandardLinkImpl*> route;
host_list_[k / host_nb]->route_to(host_list_[k % host_nb], route, nullptr);
- for (auto const& link : route)
+ for (auto const* link : route)
model->get_maxmin_system()->expand(link->get_constraint(), this->get_variable(), bytes_amount[k]);
}
}
/* 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 HOST_L07_HPP_
+#define HOST_L07_HPP_
+
#include "src/kernel/resource/HostImpl.hpp"
#include "src/kernel/resource/NetworkModel.hpp"
+#include "src/simgrid/math_utils.h"
#include <cstdlib>
#include <vector>
#include <xbt/base.h>
-#ifndef HOST_L07_HPP_
-#define HOST_L07_HPP_
-
namespace simgrid::kernel::resource {
/***********
{
std::vector<NetPoint*> vertices = get_vertices();
- for (auto const& my_src : vertices) {
- for (auto const& my_dst : vertices) {
+ for (auto const* my_src : vertices) {
+ for (auto const* my_dst : vertices) {
if (my_src == my_dst)
continue;
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_torus, ker_platform, "Kernel Torus Routing");
namespace simgrid {
-namespace kernel ::routing {
+namespace kernel::routing {
void TorusZone::create_torus_links(unsigned long id, int rank, unsigned long position)
{
#include "src/kernel/xml/simgrid_dtd.h"
#include <map>
+#include <memory>
#include <string>
#include <vector>
#include <simgrid/Exception.hpp>
#include <simgrid/kernel/routing/NetPoint.hpp>
+#include <simgrid/s4u/Disk.hpp>
#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/Host.hpp>
#include <xbt/file.hpp>
"The most recent formalism that this version of SimGrid understands is v4.1.\n"
"Please update your code, or use another, more adapted, file.");
}
+
+static void add_remote_disks()
+{
+ for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
+ const char* remote_disk_str = host->get_property("remote_disk");
+ if (not remote_disk_str)
+ continue;
+ std::vector<std::string> tokens;
+ boost::split(tokens, remote_disk_str, boost::is_any_of(":"));
+ 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");
+
+ const simgrid::s4u::Disk* disk = nullptr;
+ for (auto const& d : remote_host->get_disks())
+ if (d->get_name() == tokens[1]) {
+ disk = d;
+ break;
+ }
+
+ xbt_assert(disk, "You're trying to mount a disk that does not exist. Please check your platform file");
+ host->add_disk(disk);
+
+ XBT_DEBUG("Host '%s' wants to access a remote disk: %s of %s", host->get_cname(), disk->get_cname(),
+ remote_host->get_cname());
+ XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size());
+ }
+}
+
+static void remove_remote_disks()
+{
+ XBT_DEBUG("Simulation is over, time to unregister remote disks if any");
+ for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
+ const char* remote_disk_str = host->get_property("remote_disk");
+ if (remote_disk_str) {
+ std::vector<std::string> tokens;
+ boost::split(tokens, remote_disk_str, boost::is_any_of(":"));
+ XBT_DEBUG("Host '%s' wants to unmount a remote disk: %s of %s", host->get_cname(),
+ tokens[1].c_str(), tokens[2].c_str());
+ host->remove_disk(tokens[1]);
+ XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size());
+ }
+ }
+}
+
void ETag_simgrid_parse_platform()
{
+ simgrid::s4u::Engine::on_platform_created_cb(&add_remote_disks);
+ simgrid::s4u::Engine::on_simulation_end_cb(&remove_remote_disks);
if (fire_on_platform_created_callback)
simgrid::s4u::Engine::on_platform_created();
+
}
void STag_simgrid_parse_prop()
void STag_simgrid_parse_link___ctn()
{
- const auto engine = simgrid::s4u::Engine::get_instance();
+ const auto* engine = simgrid::s4u::Engine::get_instance();
const simgrid::s4u::Link* link;
simgrid::s4u::LinkInRoute::Direction direction = simgrid::s4u::LinkInRoute::Direction::NONE;
switch (A_simgrid_parse_link___ctn_direction) {
simgrid_parse_assert(not err, "Flex returned an error code");
/* Actually connect the traces now that every elements are created */
- const auto engine = simgrid::s4u::Engine::get_instance();
+ const auto* engine = simgrid::s4u::Engine::get_instance();
for (auto const& [trace, name] : trace_connect_list_host_avail) {
simgrid_parse_assert(traces_set_list.find(trace) != traces_set_list.end(),
const simgrid::kernel::routing::HostLinkCreationArgs* hostlink,
const simgrid::s4u::Link* backbone)
{
- const auto engine = simgrid::s4u::Engine::get_instance();
- auto netpoint = engine->host_by_name(hostlink->id)->get_netpoint();
+ const auto* engine = simgrid::s4u::Engine::get_instance();
+ auto* netpoint = engine->host_by_name(hostlink->id)->get_netpoint();
xbt_assert(netpoint, "Host '%s' not found!", hostlink->id.c_str());
- const auto linkUp = engine->link_by_name_or_null(hostlink->link_up);
- const auto linkDown = engine->link_by_name_or_null(hostlink->link_down);
+ const auto* linkUp = engine->link_by_name_or_null(hostlink->link_up);
+ const auto* linkDown = engine->link_by_name_or_null(hostlink->link_down);
xbt_assert(linkUp, "Link '%s' not found!", hostlink->link_up.c_str());
xbt_assert(linkDown, "Link '%s' not found!", hostlink->link_down.c_str());
namespace simgrid::mc {
static std::string master_socket_name;
-static void cleanup_master_socket()
-{
- if (not master_socket_name.empty())
- unlink(master_socket_name.c_str());
- master_socket_name.clear();
-}
RemoteApp::RemoteApp(const std::vector<char*>& args, bool need_memory_introspection) : app_args_(args)
{
0);
xbt_assert(master_socket_ != -1, "Cannot create the master socket: %s", strerror(errno));
+ master_socket_name = "/tmp/simgrid-mc-" + std::to_string(getpid());
+ master_socket_name.resize(MC_SOCKET_NAME_LEN); // truncate socket name if it's too long
+ master_socket_name.back() = '\0'; // ensure the data are null-terminated
+#ifdef __linux__
+ master_socket_name[0] = '\0'; // abstract socket, automatically removed after close
+#else
+ unlink(master_socket_name.c_str()); // remove possible stale socket before bind
+ atexit([]() {
+ if (not master_socket_name.empty())
+ unlink(master_socket_name.c_str());
+ master_socket_name.clear();
+ });
+#endif
+
struct sockaddr_un serv_addr = {};
serv_addr.sun_family = AF_UNIX;
- snprintf(serv_addr.sun_path, 64, "/tmp/simgrid-mc-%d", getpid());
- master_socket_name = serv_addr.sun_path;
- auto addr_size = offsetof(struct sockaddr_un, sun_path) + strlen(serv_addr.sun_path);
+ master_socket_name.copy(serv_addr.sun_path, MC_SOCKET_NAME_LEN);
- xbt_assert(bind(master_socket_, (struct sockaddr*)&serv_addr, addr_size) >= 0,
- "Cannot bind the master socket to %s: %s.", serv_addr.sun_path, strerror(errno));
- atexit(cleanup_master_socket);
+ xbt_assert(bind(master_socket_, (struct sockaddr*)&serv_addr, sizeof serv_addr) >= 0,
+ "Cannot bind the master socket to %c%s: %s.", (serv_addr.sun_path[0] ? serv_addr.sun_path[0] : '@'),
+ serv_addr.sun_path + 1, strerror(errno));
xbt_assert(listen(master_socket_, SOMAXCONN) >= 0, "Cannot listen to the master socket: %s.", strerror(errno));
application_factory_ = std::make_unique<simgrid::mc::CheckerSide>(app_args_, need_memory_introspection);
- checker_side_ = application_factory_->clone(master_socket_);
+ checker_side_ = application_factory_->clone(master_socket_, master_socket_name);
}
}
-RemoteApp::~RemoteApp()
-{
- checker_side_ = nullptr;
-}
-
void RemoteApp::restore_initial_state()
{
if (initial_snapshot_ == nullptr) // No memory introspection
- checker_side_ = application_factory_->clone(master_socket_);
+ checker_side_ = application_factory_->clone(master_socket_, master_socket_name);
#if SIMGRID_HAVE_STATEFUL_MC
else
initial_snapshot_->restore(*checker_side_->get_remote_memory());
*/
explicit RemoteApp(const std::vector<char*>& args, bool need_memory_introspection);
- ~RemoteApp();
-
void restore_initial_state();
void wait_for_requests();
#ifndef SIMGRID_MC_BASICSTRATEGY_HPP
#define SIMGRID_MC_BASICSTRATEGY_HPP
+#include "Strategy.hpp"
+
namespace simgrid::mc {
/** Basic MC guiding class which corresponds to no guide at all (random choice) */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
-#include "xbt/asserts.h"
-
#ifndef SIMGRID_MC_STRATEGY_HPP
#define SIMGRID_MC_STRATEGY_HPP
+#include "simgrid/forward.h"
+#include "src/mc/api/RemoteApp.hpp"
+#include "xbt/asserts.h"
+#include <map>
+#include <utility>
+
namespace simgrid::mc {
class Strategy {
#ifndef SIMGRID_MC_WAITSTRATEGY_HPP
#define SIMGRID_MC_WAITSTRATEGY_HPP
+#include "Strategy.hpp"
#include "src/mc/transition/Transition.hpp"
namespace simgrid::mc {
public:
WaitStrategy() = default;
~WaitStrategy() override = default;
- WaitStrategy(const BasicStrategy&) = delete;
+ WaitStrategy(const WaitStrategy&) = delete;
WaitStrategy& operator=(const WaitStrategy& guide)
{
taken_wait_ = guide.taken_wait_;
#ifndef SIMGRID_MC_UDPOR_CHECKER_HPP
#define SIMGRID_MC_UDPOR_CHECKER_HPP
+#include "src/mc/api/State.hpp"
#include "src/mc/explo/Exploration.hpp"
#include "src/mc/explo/udpor/Configuration.hpp"
#include "src/mc/explo/udpor/EventSet.hpp"
{
EventSet interesting_bunch{&e2, &e4, &e7, &e8};
- maximal_subsets_iterator first(C, [&](const UnfoldingEvent* e) { return interesting_bunch.contains(e); });
+ maximal_subsets_iterator first(
+ C, [&interesting_bunch](const UnfoldingEvent* e) { return interesting_bunch.contains(e); });
maximal_subsets_iterator last;
for (; first != last; ++first) {
{
EventSet interesting_bunch{&e3, &e5, &e6};
- maximal_subsets_iterator first(C, [&](const UnfoldingEvent* e) { return interesting_bunch.contains(e); });
+ maximal_subsets_iterator first(
+ C, [&interesting_bunch](const UnfoldingEvent* e) { return interesting_bunch.contains(e); });
maximal_subsets_iterator last;
for (; first != last; ++first) {
REQUIRE(alternative.value().get_events() == EventSet({e0_handle, e7_handle, e9_handle}));
}
}
-}
\ No newline at end of file
+}
std::deque<Transition*> transitions_;
public:
- RecordTrace() = default;
+ // Use rule-of-three, and implicitely disable the move constructor which cannot be 'noexcept' (as required by C++ Core
+ // Guidelines), due to the std::deque member.
+ RecordTrace() = default;
+ RecordTrace(const RecordTrace&) = default;
+ ~RecordTrace() = default;
/** Build a trace that can be replayed from a string representation */
explicit RecordTrace(const char* data);
if (terminate_asap)
::_Exit(0);
}
-void AppSide::handle_fork(const s_mc_message_int_t* msg)
+void AppSide::handle_fork(const s_mc_message_fork_t* msg)
{
int status;
int pid;
struct sockaddr_un addr = {};
addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, 64, "/tmp/simgrid-mc-%" PRIu64, msg->value);
- auto addr_size = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path);
+ std::copy_n(begin(msg->socket_name), MC_SOCKET_NAME_LEN, addr.sun_path);
- xbt_assert(connect(sock, (struct sockaddr*)&addr, addr_size) >= 0,
- "Cannot connect to Checker on %s: %s.", addr.sun_path, strerror(errno));
+ xbt_assert(connect(sock, (struct sockaddr*)&addr, sizeof addr) >= 0, "Cannot connect to Checker on %c%s: %s.",
+ (addr.sun_path[0] ? addr.sun_path[0] : '@'), addr.sun_path + 1, strerror(errno));
channel_.reset_socket(sock);
break;
case MessageType::FORK:
- assert_msg_size("FORK", s_mc_message_int_t);
- handle_fork((s_mc_message_int_t*)message_buffer.data());
+ assert_msg_size("FORK", s_mc_message_fork_t);
+ handle_fork((s_mc_message_fork_t*)message_buffer.data());
break;
case MessageType::WAIT_CHILD:
void handle_deadlock_check(const s_mc_message_t* msg) const;
void handle_simcall_execute(const s_mc_message_simcall_execute_t* message) const;
void handle_finalize(const s_mc_message_int_t* msg) const;
- void handle_fork(const s_mc_message_int_t* msg);
+ void handle_fork(const s_mc_message_fork_t* msg);
void handle_wait_child(const s_mc_message_int_t* msg);
void handle_need_meminfo();
void handle_actors_status() const;
wait_for_requests();
}
-std::unique_ptr<CheckerSide> CheckerSide::clone(int master_socket)
+std::unique_ptr<CheckerSide> CheckerSide::clone(int master_socket, const std::string& master_socket_name)
{
- s_mc_message_int_t m = {};
- m.type = MessageType::FORK;
- m.value = getpid();
+ s_mc_message_fork_t m = {};
+ m.type = MessageType::FORK;
+ xbt_assert(master_socket_name.size() == MC_SOCKET_NAME_LEN);
+ std::copy_n(begin(master_socket_name), MC_SOCKET_NAME_LEN, begin(m.socket_name));
xbt_assert(get_channel().send(m) == 0, "Could not ask the app to fork on need.");
int sock = accept(master_socket, nullptr /* I know who's connecting*/, nullptr);
void wait_for_requests();
/* Create a new CheckerSide by forking the currently existing one, and connect it through the master_socket */
- std::unique_ptr<CheckerSide> clone(int master_socket);
+ std::unique_ptr<CheckerSide> clone(int master_socket, const std::string& master_socket_name);
/** Ask the application to run post-mortem analysis, and maybe to stop ASAP */
void finalize(bool terminate_asap = false);
std::size_t get_buffer_size() const { return sizeof(T); }
operator T() const
{
- static_assert(std::is_trivial<T>::value, "Cannot convert non trivial type");
+ static_assert(std::is_trivial_v<T>, "Cannot convert non trivial type");
return *get_buffer();
}
void clear() { std::memset(&buffer, 0, sizeof buffer); }
#include <array>
#include <cstdint>
+#include <sys/un.h>
// ***** Messages
namespace simgrid::mc {
} // namespace simgrid::mc
constexpr unsigned MC_MESSAGE_LENGTH = 512;
+constexpr unsigned MC_SOCKET_NAME_LEN = sizeof(sockaddr_un::sun_path);
constexpr unsigned SIMCALL_SERIALIZATION_BUFFER_SIZE = 2048;
/** Basic structure for a MC message
xbt_mheap_t mmalloc_default_mdp;
};
+struct s_mc_message_fork_t {
+ simgrid::mc::MessageType type;
+ std::array<char, MC_SOCKET_NAME_LEN> socket_name;
+};
+
struct s_mc_message_simcall_execute_t {
simgrid::mc::MessageType type;
aid_t aid_;
#include "src/mc/sosp/PageStore.hpp"
-using simgrid::mc::PageStore;
-
/***********************************/
// a class to hold the variable used in the test cases
-class helper_tests {
-public:
- static std::size_t pagesize;
- static std::unique_ptr<PageStore> store;
- static void* data;
- static std::array<size_t, 4> pageno;
- static int value;
+class pstore_test_helper {
+ const size_t pagesize = getpagesize();
+ simgrid::mc::PageStore store{50};
+ std::byte* data =
+ static_cast<std::byte*>(mmap(nullptr, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
+ std::array<size_t, 4> pageno = {0, 0, 0, 0};
+ int value = 0;
+
+ void new_content(std::byte* buf, size_t size);
+public:
// member functions used by the test suite(s)
- static void Init();
- static void store_page_once();
- static void store_same_page();
- static void store_new_page();
- static void unref_pages();
- static void reallocate_page();
-
- static void new_content(void* buf, std::size_t size);
+ void init();
+ void store_page_once();
+ void store_same_page();
+ void store_new_page();
+ void unref_pages();
+ void reallocate_page();
};
-// static member data initialization
-std::size_t helper_tests::pagesize = 0;
-std::unique_ptr<PageStore> helper_tests::store = nullptr;
-void* helper_tests::data = nullptr;
-std::array<size_t, 4> helper_tests::pageno = {{0, 0, 0, 0}};
-int helper_tests::value = 0;
-
-void helper_tests::Init()
+void pstore_test_helper::init()
{
- pagesize = (size_t)getpagesize();
- store = std::make_unique<simgrid::mc::PageStore>(50);
- data = mmap(nullptr, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- REQUIRE(store->size() == 0);
+ REQUIRE(data != nullptr);
+ REQUIRE(store.size() == 0);
}
-void helper_tests::store_page_once()
+void pstore_test_helper::store_page_once()
{
new_content(data, pagesize);
- pageno[0] = store->store_page(data);
- REQUIRE(store->get_ref(pageno[0]) == 1);
- const void* copy = store->get_page(pageno[0]);
+ pageno[0] = store.store_page(data);
+ REQUIRE(store.get_ref(pageno[0]) == 1);
+ const auto* copy = store.get_page(pageno[0]);
REQUIRE(::memcmp(data, copy, pagesize) == 0); // The page data should be the same
- REQUIRE(store->size() == 1);
+ REQUIRE(store.size() == 1);
}
-void helper_tests::store_same_page()
+void pstore_test_helper::store_same_page()
{
- pageno[1] = store->store_page(data);
+ pageno[1] = store.store_page(data);
REQUIRE(pageno[0] == pageno[1]); // Page should be the same
- REQUIRE(store->get_ref(pageno[0]) == 2);
- REQUIRE(store->size() == 1);
+ REQUIRE(store.get_ref(pageno[0]) == 2);
+ REQUIRE(store.size() == 1);
}
-void helper_tests::store_new_page()
+void pstore_test_helper::store_new_page()
{
new_content(data, pagesize);
- pageno[2] = store->store_page(data);
+ pageno[2] = store.store_page(data);
REQUIRE(pageno[0] != pageno[2]); // The new page should be different
- REQUIRE(store->size() == 2);
+ REQUIRE(store.size() == 2);
}
-void helper_tests::unref_pages()
+void pstore_test_helper::unref_pages()
{
- store->unref_page(pageno[0]);
- REQUIRE(store->get_ref(pageno[0]) == 1);
- REQUIRE(store->size() == 2);
+ store.unref_page(pageno[0]);
+ REQUIRE(store.get_ref(pageno[0]) == 1);
+ REQUIRE(store.size() == 2);
- store->unref_page(pageno[1]);
- REQUIRE(store->size() == 1);
+ store.unref_page(pageno[1]);
+ REQUIRE(store.size() == 1);
}
-void helper_tests::reallocate_page()
+void pstore_test_helper::reallocate_page()
{
new_content(data, pagesize);
- pageno[3] = store->store_page(data);
+ pageno[3] = store.store_page(data);
REQUIRE(pageno[0] == pageno[3]); // The old page should be reused
- REQUIRE(store->get_ref(pageno[3]) == 1);
- REQUIRE(store->size() == 2);
+ REQUIRE(store.get_ref(pageno[3]) == 1);
+ REQUIRE(store.size() == 2);
}
-void helper_tests::new_content(void* buf, std::size_t size)
+void pstore_test_helper::new_content(std::byte* buf, size_t size)
{
value++;
- ::memset(buf, value, size);
+ std::fill_n(buf, size, static_cast<std::byte>(value));
}
TEST_CASE("MC page store, used during checkpoint", "MC::PageStore")
{
- helper_tests::Init();
+ pstore_test_helper pstore_test;
+ pstore_test.init();
+
INFO("Store page once");
- helper_tests::store_page_once();
+ pstore_test.store_page_once();
INFO("Store the same page");
- helper_tests::store_same_page();
+ pstore_test.store_same_page();
INFO("Store a new page");
- helper_tests::store_new_page();
+ pstore_test.store_new_page();
INFO("Unref pages");
- helper_tests::unref_pages();
+ pstore_test.unref_pages();
INFO("Reallocate pages");
- helper_tests::reallocate_page();
+ pstore_test.reallocate_page();
}
#include <sys/mman.h>
#include <xbt/random.hpp>
-/**************** Class BOOST_tests *************************/
-using simgrid::mc::Region;
class snap_test_helper {
- static simgrid::mc::PageStore page_store_;
- static std::unique_ptr<simgrid::mc::RemoteProcessMemory> memory_;
+ simgrid::mc::PageStore page_store_{500};
+ simgrid::mc::RemoteProcessMemory memory_{getpid(), nullptr};
-public:
- static void init_memory(void* mem, size_t size);
- static void Init();
struct prologue_return {
size_t size;
- void* src;
- void* dstn;
- std::unique_ptr<Region> region0;
- std::unique_ptr<Region> region;
+ std::byte* src;
+ std::byte* dstn;
+ std::unique_ptr<simgrid::mc::Region> region0;
+ std::unique_ptr<simgrid::mc::Region> region;
};
- static prologue_return prologue(int n); // common to the below 5 fxs
- static void read_whole_region();
- static void read_region_parts();
- static void compare_whole_region();
- static void compare_region_parts();
- static void read_pointer();
-
- static void cleanup() { memory_ = nullptr; }
-};
+ prologue_return prologue(int n); // common to the below 5 fxs
+
+ static void init_memory(std::byte* mem, size_t size);
+
+public:
+ void read_whole_region();
+ void read_region_parts();
+ void compare_whole_region();
+ void compare_region_parts();
+ void read_pointer();
-// static member variables init.
-simgrid::mc::PageStore snap_test_helper::page_store_(500);
-std::unique_ptr<simgrid::mc::RemoteProcessMemory> snap_test_helper::memory_ = nullptr;
+ static void basic_requirements();
+};
-void snap_test_helper::init_memory(void* mem, size_t size)
+void snap_test_helper::init_memory(std::byte* mem, size_t size)
{
- auto* dest = static_cast<char*>(mem);
- for (size_t i = 0; i < size; ++i) {
- dest[i] = simgrid::xbt::random::uniform_int(0, 0xff);
- }
+ std::generate_n(mem, size, []() { return static_cast<std::byte>(simgrid::xbt::random::uniform_int(0, 0xff)); });
}
-void snap_test_helper::Init()
+void snap_test_helper::basic_requirements()
{
REQUIRE(xbt_pagesize == getpagesize());
REQUIRE(1 << xbt_pagebits == xbt_pagesize);
-
- memory_ = std::make_unique<simgrid::mc::RemoteProcessMemory>(getpid(), nullptr);
}
snap_test_helper::prologue_return snap_test_helper::prologue(int n)
{
// 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);
+ auto* source =
+ static_cast<std::byte*>(mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
INFO("Could not allocate source memory");
REQUIRE(source != MAP_FAILED);
// Init memory and take snapshots:
init_memory(source, byte_size);
- auto region0 = std::make_unique<simgrid::mc::Region>(page_store_, *memory_.get(), simgrid::mc::RegionType::Data,
- source, byte_size);
+ auto region0 =
+ std::make_unique<simgrid::mc::Region>(page_store_, memory_, simgrid::mc::RegionType::Data, source, byte_size);
for (int i = 0; i < n; i += 2) {
- init_memory((char*)source + i * xbt_pagesize, xbt_pagesize);
+ init_memory(source + i * xbt_pagesize, xbt_pagesize);
}
- auto region = std::make_unique<simgrid::mc::Region>(page_store_, *memory_.get(), simgrid::mc::RegionType::Data,
- source, byte_size);
+ auto region =
+ std::make_unique<simgrid::mc::Region>(page_store_, memory_, simgrid::mc::RegionType::Data, source, byte_size);
- void* destination = mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ auto* destination =
+ static_cast<std::byte*>(mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
INFO("Could not allocate destination memory");
REQUIRE(destination != MAP_FAILED);
}
const int some_global_variable = 42;
-const void* some_global_pointer = &some_global_variable;
+const void* const some_global_pointer = &some_global_variable;
void snap_test_helper::read_pointer()
{
prologue_return ret = prologue(1);
memcpy(ret.src, &some_global_pointer, sizeof(void*));
- const simgrid::mc::Region region2(page_store_, *memory_.get(), simgrid::mc::RegionType::Data, ret.src, ret.size);
+ const simgrid::mc::Region region2(page_store_, memory_, simgrid::mc::RegionType::Data, ret.src, ret.size);
INFO("Mismtach in MC_region_read_pointer()");
REQUIRE(MC_region_read_pointer(®ion2, ret.src) == some_global_pointer);
{
INFO("Sparse snapshot (using pages)");
- snap_test_helper::Init();
+ snap_test_helper::basic_requirements();
+
+ snap_test_helper snap_test;
INFO("Read whole region");
- snap_test_helper::read_whole_region();
+ snap_test.read_whole_region();
INFO("Read region parts");
- snap_test_helper::read_region_parts();
+ snap_test.read_region_parts();
INFO("Compare whole region");
- snap_test_helper::compare_whole_region();
+ snap_test.compare_whole_region();
INFO("Compare region parts");
- snap_test_helper::compare_region_parts();
+ snap_test.compare_region_parts();
INFO("Read pointer");
- snap_test_helper::read_pointer();
-
- snap_test_helper::cleanup();
+ snap_test.read_pointer();
}
host.extension_set<FileDescriptorHostExt>(new FileDescriptorHostExt());
}
-static void on_platform_created()
-{
- for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
- const char* remote_disk_str = host->get_property("remote_disk");
- if (not remote_disk_str)
- continue;
- std::vector<std::string> tokens;
- boost::split(tokens, remote_disk_str, boost::is_any_of(":"));
- std::string mount_point = tokens[0];
- simgrid::s4u::Host* remote_host = simgrid::s4u::Host::by_name_or_null(tokens[2]);
- xbt_assert(remote_host, "You're trying to access a host that does not exist. Please check your platform file");
-
- const simgrid::s4u::Disk* disk = nullptr;
- for (auto const& d : remote_host->get_disks())
- if (d->get_name() == tokens[1]) {
- disk = d;
- break;
- }
-
- xbt_assert(disk, "You're trying to mount a disk that does not exist. Please check your platform file");
- disk->extension<FileSystemDiskExt>()->add_remote_mount(remote_host, mount_point);
- host->add_disk(disk);
-
- XBT_DEBUG("Host '%s' wants to mount a remote disk: %s of %s mounted on %s", host->get_cname(), disk->get_cname(),
- remote_host->get_cname(), mount_point.c_str());
- XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size());
- }
-}
-
-static void on_simulation_end()
-{
- XBT_DEBUG("Simulation is over, time to unregister remote disks if any");
- for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
- const char* remote_disk_str = host->get_property("remote_disk");
- if (remote_disk_str) {
- std::vector<std::string> tokens;
- boost::split(tokens, remote_disk_str, boost::is_any_of(":"));
- XBT_DEBUG("Host '%s' wants to unmount a remote disk: %s of %s mounted on %s", host->get_cname(),
- tokens[1].c_str(), tokens[2].c_str(), tokens[0].c_str());
- host->remove_disk(tokens[1]);
- XBT_DEBUG("Host '%s' now has %zu disks", host->get_cname(), host->get_disks().size());
- }
- }
+ static void on_platform_created()
+ {
+ for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
+ const char* remote_disk_str = host->get_property("remote_disk");
+ if (not remote_disk_str)
+ continue;
+ std::vector<std::string> tokens;
+ boost::split(tokens, remote_disk_str, boost::is_any_of(":"));
+ std::string mount_point = tokens[0];
+ simgrid::s4u::Host* remote_host = simgrid::s4u::Host::by_name_or_null(tokens[2]);
+ xbt_assert(remote_host, "You're trying to access a host that does not exist. Please check your platform file");
+
+ const simgrid::s4u::Disk* disk = nullptr;
+ for (auto const& d : remote_host->get_disks())
+ if (d->get_name() == tokens[1]) {
+ disk = d;
+ break;
+ }
+
+ xbt_assert(disk, "You're trying to mount a disk that does not exist. Please check your platform file");
+ disk->extension<FileSystemDiskExt>()->add_remote_mount(remote_host, mount_point);
+ }
}
/* **************************** Public interface *************************** */
simgrid::s4u::Host::on_creation_cb(&on_host_creation);
}
simgrid::s4u::Engine::on_platform_created_cb(&on_platform_created);
- simgrid::s4u::Engine::on_simulation_end_cb(&on_simulation_end);
}
sg_file_t sg_file_open(const char* fullpath, void* data)
if (activity.get_host() == get_host())
pre_task();
});
- simgrid::s4u::Activity::on_completion_cb([this](simgrid::s4u::Activity const& activity) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec const*>(&activity);
- if (exec == nullptr) // Only Execs are concerned here
- return;
+ simgrid::s4u::Exec::on_completion_cb([this](simgrid::s4u::Exec const& exec) {
// For more than one host (not yet supported), we can access the host via
// simcalls_.front()->issuer->get_iface()->get_host()
- if (exec->get_host() == get_host() && iteration_running) {
- comp_timer += exec->get_finish_time() - exec->get_start_time();
+ if (exec.get_host() == get_host() && iteration_running) {
+ comp_timer += exec.get_finish_time() - exec.get_start_time();
}
});
// FIXME I think that this fires at the same time for all hosts, so when the src sends something,
// the dst will be notified even though it didn't even arrive at the recv yet
- kernel::activity::CommImpl::on_start.connect([this](const kernel::activity::CommImpl& comm) {
- const auto* act = static_cast<kernel::resource::NetworkAction*>(comm.model_action_);
- if ((get_host() == &act->get_src() || get_host() == &act->get_dst()) && iteration_running) {
+ simgrid::s4u::Comm::on_start_cb([this](const s4u::Comm& comm) {
+ if ((get_host() == comm.get_sender()->get_host() || get_host() == comm.get_receiver()->get_host()) &&
+ iteration_running) {
post_task();
}
});
#include <simgrid/s4u/VirtualMachine.hpp>
#include <simgrid/simix.hpp>
+#include "src/kernel/activity/ActivityImpl.hpp"
#include "src/kernel/resource/CpuImpl.hpp"
#include "src/simgrid/module.hpp"
static void on_action_state_change(simgrid::kernel::resource::CpuAction const& action,
simgrid::kernel::resource::Action::State /*previous*/)
{
- for (simgrid::kernel::resource::CpuImpl* const& cpu : action.cpus()) {
+ for (simgrid::kernel::resource::CpuImpl const* cpu : action.cpus()) {
simgrid::s4u::Host* host = cpu->get_iface();
if (host != nullptr) {
// If it's a VM, take the corresponding PM
/* This callback is fired either when the host changes its state (on/off) ("onStateChange") or its speed
* (because the user changed the pstate, or because of external trace events) ("onSpeedChange") */
-static void on_host_change(simgrid::s4u::Host const& host)
+static void on_host_change(simgrid::s4u::Host const& h)
{
- if (dynamic_cast<simgrid::s4u::VirtualMachine const*>(&host)) // Ignore virtual machines
- return;
-
- auto* host_energy = host.extension<HostEnergy>();
+ auto* host = &h;
+ if (const auto* vm = dynamic_cast<simgrid::s4u::VirtualMachine const*>(host)) // Take the PM of virtual machines
+ host = vm->get_pm();
- host_energy->update();
+ host->extension<HostEnergy>()->update();
}
static void on_host_destruction(simgrid::s4u::Host const& host)
used_hosts_energy, total_energy - used_hosts_energy);
}
+static void on_activity_suspend_resume(simgrid::s4u::Activity const& activity)
+{
+ if (auto* action = dynamic_cast<simgrid::kernel::resource::CpuAction*>(activity.get_impl()->model_action_);
+ action != nullptr)
+ on_action_state_change(*action, /*ignored*/ action->get_state());
+}
+
/* **************************** Public interface *************************** */
/** @ingroup plugin_host_energy
HostEnergy::EXTENSION_ID = simgrid::s4u::Host::extension_create<HostEnergy>();
simgrid::s4u::Host::on_creation_cb(&on_creation);
- simgrid::s4u::Host::on_state_change_cb(&on_host_change);
+ simgrid::s4u::Host::on_onoff_cb(&on_host_change);
simgrid::s4u::Host::on_speed_change_cb(&on_host_change);
simgrid::s4u::Host::on_destruction_cb(&on_host_destruction);
+ simgrid::s4u::Host::on_exec_state_change_cb(&on_action_state_change);
+ simgrid::s4u::VirtualMachine::on_suspend_cb(&on_host_change);
+ simgrid::s4u::VirtualMachine::on_resume_cb(&on_host_change);
+ simgrid::s4u::Exec::on_suspend_cb(on_activity_suspend_resume);
+ simgrid::s4u::Exec::on_resume_cb(on_activity_suspend_resume);
simgrid::s4u::Engine::on_simulation_end_cb(&on_simulation_end);
- simgrid::kernel::resource::CpuAction::on_state_change.connect(&on_action_state_change);
// We may only have one actor on a node. If that actor executes something like
// compute -> recv -> compute
- // the recv operation will not trigger a "CpuAction::on_state_change". This means
+ // the recv operation will not trigger a "Host::on_exec_state_change_cb". This means
// that the next trigger would be the 2nd compute, hence ignoring the idle time
// during the recv call. By updating at the beginning of a compute, we can
// fix that. (If the cpu is not idle, this is not required.)
simgrid::s4u::Exec::on_start_cb([](simgrid::s4u::Exec const& activity) {
if (activity.get_host_number() == 1) { // We only run on one host
- simgrid::s4u::Host* host = activity.get_host();
+ simgrid::s4u::Host* host = activity.get_host();
if (const auto* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host))
host = vm->get_pm();
xbt_assert(host != nullptr);
- :cpp:func:`simgrid::s4u::Host::on_creation_cb`: Attach a new extension to the newly created host.
- :cpp:func:`simgrid::s4u::Exec::on_start_cb`: Make note that a new execution started, increasing the load.
- :cpp:func:`simgrid::s4u::Exec::on_completion_cb`: Make note that an execution completed, decreasing the load.
- - :cpp:func:`simgrid::s4u::Host::on_state_change_cb`: Do what is appropriate when the host gets suspended, turned off
- or similar.
+ - :cpp:func:`simgrid::s4u::Host::on_onoff_cb`: Do what is appropriate when the host gets turned off or on.
- :cpp:func:`simgrid::s4u::Host::on_speed_change_cb`: Do what is appropriate when the DVFS is modified.
Note that extensions are automatically destroyed when the host gets destroyed.
XBT_WARN("HostLoad plugin currently does not support executions on several hosts");
}
});
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec const*>(&activity);
- if (exec == nullptr) // Only Execs are concerned here
- return;
- if (exec->get_host_number() == 1) { // We only run on one host
- simgrid::s4u::Host* host = exec->get_host();
+ simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) {
+ if (exec.get_host_number() == 1) { // We only run on one host
+ simgrid::s4u::Host* host = exec.get_host();
if (const auto* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host))
host = vm->get_pm();
xbt_assert(host != nullptr);
XBT_WARN("HostLoad plugin currently does not support executions on several hosts");
}
});
- simgrid::s4u::Host::on_state_change_cb(&on_host_change);
+ simgrid::s4u::Host::on_onoff_cb(&on_host_change);
simgrid::s4u::Host::on_speed_change_cb(&on_host_change);
}
#include "simgrid/Exception.hpp"
#include "simgrid/host.h"
#include "simgrid/plugins/energy.h"
+#include "simgrid/s4u/Comm.hpp"
#include "simgrid/s4u/Engine.hpp"
#include "simgrid/s4u/Link.hpp"
#include "src/kernel/activity/CommImpl.hpp"
XBT_INFO("Total energy over all links: %f", total_energy);
}
-static void on_communication(const simgrid::kernel::activity::CommImpl& comm)
+static void on_communication(const simgrid::s4u::Comm& comm)
{
- for (auto const* link : comm.get_traversed_links()) {
+ auto* pimpl = static_cast<simgrid::kernel::activity::CommImpl*>(comm.get_impl());
+ for (auto const* link : pimpl->get_traversed_links()) {
if (link != nullptr && link->get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI) {
XBT_DEBUG("Update %s on Comm Start/End", link->get_cname());
link->extension<LinkEnergy>()->update();
}
}
}
+
/* **************************** Public interface *************************** */
int sg_link_energy_is_inited()
}
});
- simgrid::s4u::Link::on_state_change_cb([](simgrid::s4u::Link const& link) {
+ simgrid::s4u::Link::on_onoff_cb([](simgrid::s4u::Link const& link) {
if (link.get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI)
link.extension<LinkEnergy>()->update();
});
link.extension<LinkEnergy>()->get_consumed_energy());
});
- simgrid::kernel::activity::CommImpl::on_start.connect(&on_communication);
- simgrid::kernel::activity::CommImpl::on_completion.connect(&on_communication);
+ simgrid::s4u::Comm::on_start_cb(&on_communication);
+ simgrid::s4u::Comm::on_completion_cb(&on_communication);
simgrid::s4u::Engine::on_simulation_end_cb(&on_simulation_end);
}
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <simgrid/plugins/energy.h>
+#include <simgrid/s4u/Comm.hpp>
#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/Link.hpp>
using simgrid::plugin::LinkEnergyWifi;
/* **************************** events callback *************************** */
-static void on_communication(const simgrid::kernel::activity::CommImpl& comm)
+static void on_communication(const simgrid::s4u::Comm& comm)
{
- for (const auto* link : comm.get_traversed_links()) {
+ auto* pimpl = static_cast<simgrid::kernel::activity::CommImpl*>(comm.get_impl());
+ for (auto const* link : pimpl->get_traversed_links()) {
if (link != nullptr && link->get_sharing_policy() == simgrid::s4u::Link::SharingPolicy::WIFI) {
auto* link_energy = link->extension<LinkEnergyWifi>();
XBT_DEBUG("Update %s on Comm Start/End", link->get_cname());
}
});
- simgrid::kernel::activity::CommImpl::on_start.connect(&on_communication);
- simgrid::kernel::activity::CommImpl::on_completion.connect(&on_communication);
+ simgrid::s4u::Comm::on_start_cb(&on_communication);
+ simgrid::s4u::Comm::on_completion_cb(&on_communication);
}
* under the terms of the license (GNU LGPL) which comes with this package. */
#include <simgrid/plugins/load.h>
+#include <simgrid/s4u/Comm.hpp>
#include <simgrid/s4u/Engine.hpp>
#include "src/kernel/activity/CommImpl.hpp"
using simgrid::plugin::LinkLoad;
/* **************************** events callback *************************** */
-static void on_communication(const simgrid::kernel::activity::CommImpl& comm)
+static void on_communication(const simgrid::s4u::Comm& comm)
{
- for (const auto* link : comm.get_traversed_links()) {
+ auto* pimpl = static_cast<simgrid::kernel::activity::CommImpl*>(comm.get_impl());
+ for (auto const* link : pimpl->get_traversed_links()) {
if (link != nullptr && link->get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI) {
auto* link_load = link->extension<LinkLoad>();
XBT_DEBUG("Update %s on Comm Start/End", link->get_cname());
});
// Call this plugin on some of the links' events.
- simgrid::kernel::activity::CommImpl::on_start.connect(&on_communication);
- simgrid::kernel::activity::CommImpl::on_completion.connect(&on_communication);
+ simgrid::s4u::Comm::on_start_cb(&on_communication);
+ simgrid::s4u::Comm::on_completion_cb(&on_communication);
- simgrid::s4u::Link::on_state_change_cb([](simgrid::s4u::Link const& link) {
+ simgrid::s4u::Link::on_onoff_cb([](simgrid::s4u::Link const& link) {
if (link.get_sharing_policy() != simgrid::s4u::Link::SharingPolicy::WIFI) {
auto link_load = link.extension<LinkLoad>();
if (link_load->is_tracked())
#include <simgrid/plugins/operation.hpp>
#include <simgrid/s4u/Comm.hpp>
#include <simgrid/s4u/Exec.hpp>
+#include <simgrid/s4u/Io.hpp>
#include <simgrid/simix.hpp>
#include "src/simgrid/module.hpp"
working_ = false;
count_++;
});
- if (end_func_)
- end_func_(this);
+ for (auto end_func : end_func_handlers_)
+ end_func(this);
Operation::on_end(this);
for (auto const& op : successors_)
op->receive(this);
return;
Operation::inited_ = true;
ExtendedAttributeActivity::EXTENSION_ID = simgrid::s4u::Activity::extension_create<ExtendedAttributeActivity>();
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- activity.extension<ExtendedAttributeActivity>()->operation_->complete();
+ simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) {
+ exec.extension<ExtendedAttributeActivity>()->operation_->complete();
+ });
+ simgrid::s4u::Comm::on_completion_cb([](simgrid::s4u::Comm const& comm) {
+ comm.extension<ExtendedAttributeActivity>()->operation_->complete();
+ });
+ simgrid::s4u::Io::on_completion_cb([](simgrid::s4u::Io const& io) {
+ io.extension<ExtendedAttributeActivity>()->operation_->complete();
});
}
*/
void Operation::on_this_start(const std::function<void(Operation*)>& func)
{
- simgrid::kernel::actor::simcall_answered([this, &func] { start_func_ = func; });
+ simgrid::kernel::actor::simcall_answered([this, &func] { start_func_handlers_.push_back(func); });
}
/** @ingroup plugin_operation
*/
void Operation::on_this_end(const std::function<void(Operation*)>& func)
{
- simgrid::kernel::actor::simcall_answered([this, &func] { end_func_ = func; });
+ simgrid::kernel::actor::simcall_answered([this, &func] { end_func_handlers_.push_back(func); });
}
/** @ingroup plugin_operation
*/
void ExecOp::execute()
{
- if (start_func_)
- start_func_(this);
+ for (auto start_func : start_func_handlers_)
+ start_func(this);
Operation::on_start(this);
kernel::actor::simcall_answered([this] {
working_ = true;
*/
void CommOp::execute()
{
- if (start_func_)
- start_func_(this);
+ for (auto start_func : start_func_handlers_)
+ start_func(this);
Operation::on_start(this);
kernel::actor::simcall_answered([this] {
working_ = true;
return this;
}
+/**
+ * @brief Default constructor.
+ */
+IoOp::IoOp(const std::string& name) : Operation(name) {}
+
+/** @ingroup plugin_operation
+ * @brief Smart Constructor.
+ */
+IoOpPtr IoOp::init(const std::string& name)
+{
+ return IoOpPtr(new IoOp(name));
+}
+
+/** @ingroup plugin_operation
+ * @brief Smart Constructor.
+ */
+IoOpPtr IoOp::init(const std::string& name, double bytes, s4u::Disk* disk, s4u::Io::OpType type)
+{
+ return init(name)->set_bytes(bytes)->set_disk(disk)->set_op_type(type);
+}
+
+/** @ingroup plugin_operation
+ * @param disk The disk to set.
+ * @brief Set a new disk.
+ */
+IoOpPtr IoOp::set_disk(s4u::Disk* disk)
+{
+ kernel::actor::simcall_answered([this, disk] { disk_ = disk; });
+ return this;
+}
+
+/** @ingroup plugin_operation
+ * @param bytes The amount of bytes to set.
+ */
+IoOpPtr IoOp::set_bytes(double bytes)
+{
+ kernel::actor::simcall_answered([this, bytes] { amount_ = bytes; });
+ return this;
+}
+
+/** @ingroup plugin_operation */
+IoOpPtr IoOp::set_op_type(s4u::Io::OpType type)
+{
+ kernel::actor::simcall_answered([this, type] { type_ = type; });
+ return this;
+}
+
+void IoOp::execute()
+{
+ for (auto start_func : start_func_handlers_)
+ start_func(this);
+ Operation::on_start(this);
+ kernel::actor::simcall_answered([this] {
+ working_ = true;
+ queued_execs_ = std::max(queued_execs_ - 1, 0);
+ });
+ s4u::IoPtr io = s4u::Io::init();
+ io->set_name(name_);
+ io->set_size(amount_);
+ io->set_disk(disk_);
+ io->set_op_type(type_);
+ io->start();
+ io->extension_set(new ExtendedAttributeActivity());
+ io->extension<ExtendedAttributeActivity>()->operation_ = this;
+ kernel::actor::simcall_answered([this, io] { current_activity_ = io; });
+}
+
+
} // namespace simgrid::plugins
simgrid::xbt::Extension<simgrid::s4u::Activity, simgrid::plugins::ExtendedAttributeActivity>
--- /dev/null
+#include <simgrid/Exception.hpp>
+#include <simgrid/plugins/photovoltaic.hpp>
+#include <simgrid/s4u/Actor.hpp>
+#include <simgrid/s4u/Engine.hpp>
+#include <simgrid/s4u/Host.hpp>
+#include <simgrid/s4u/VirtualMachine.hpp>
+#include <simgrid/simix.hpp>
+
+#include "src/kernel/resource/CpuImpl.hpp"
+#include "src/simgrid/module.hpp"
+
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+
+SIMGRID_REGISTER_PLUGIN(photovoltaic, "Photovoltaic management", &sg_photovoltaic_plugin_init)
+
+/** @defgroup plugin_photovoltaic plugin_photovoltaic Plugin photovoltaic
+
+ @beginrst
+
+This is the photovoltaic plugin, enabling management of photovoltaic panels on hosts.
+To activate this plugin, first call :cpp:func:`sg_photovoltaic_plugin_init()`.
+
+This plugin allows evaluation of photovoltaic panels power generation during simulation depending on size, solar
+irradiance and conversion factor.
+
+The power model is taken from the paper `"Reinforcement Learning Based Load Balancing for
+Geographically Distributed Data Centres" <https://dro.dur.ac.uk/33395/1/33395.pdf?DDD280+kkgc95+vbdv77>`_ by Max Mackie et. al.
+
+The cost model is taken from the chapter 4 of the thesis `Sizing and Operation of Multi-Energy Hydrogen-Based
+Microgrids <https://tel.archives-ouvertes.fr/tel-02077668/document>`_ by Bei Li.
+
+Photovoltaic Panel properties
+....................
+
+Properties of panels are defined as properties of hosts in the platform XML file.
+
+Here is an example of XML declaration where we consider a host as a photovoltaic panel:
+
+.. code-block:: xml
+
+ <host id="pv_panel" speed="0f">
+ <prop id="photovoltaic_area" value="4" />
+ <prop id="photovoltaic_conversion_efficiency" value="0.2" />
+ </host>
+
+The different properties are:
+
+- ``photovoltaic_area``: Set the area of the panel in m² (default=0)
+- ``photovoltaic_conversion_efficiency``: Set the conversion efficiency of the panel (default=0)
+- ``photovoltaic_solar_irradiance``: Set the initial solar irradiance in W/m² (default=0)
+- ``photovoltaic_min_power``: Set the minimum power of the panel in W (default=-1). Power generation below this value is automatically 0. Value is ignored if negative
+- ``photovoltaic_max_power``: Set the maximal power of the panel in W (default=-1). Power generation above this value is automatically truncated. Value is ignored if negative
+- ``photovoltaic_eval_cost``: Evaluate the cost of the panel during the simulation if set to 1 (defaulf=0)
+- ``photovoltaic_lifespan``: Set the lifespan of the panel in years (default=0)
+- ``photovoltaic_investment_cost``: Set the investment cost of the panel (default=0)
+- ``photovoltaic_maintenance_cost``: Set the maintenance cost of the panel (default=0)
+
+ @endrst
+ */
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(photovoltaic, kernel, "Logging specific to the photovoltaic plugin");
+
+namespace simgrid::plugin {
+class Photovoltaic {
+private:
+ simgrid::s4u::Host* host_ = nullptr;
+
+ double area_m2_ = 0;
+ double conversion_efficiency_ = 0;
+ double solar_irradiance_w_per_m2_ = 0;
+ double min_power_w_ = -1;
+ double max_power_w_ = -1;
+
+ double power_w_ = 0;
+ double last_updated_ = 0;
+
+ bool eval_cost_ = false;
+ double cumulative_cost_ = 0;
+ int lifespan_years_ = 0;
+ double investment_cost_per_w_ = 0;
+ double maintenance_cost_per_wh_ = 0;
+
+ void init_photovoltaic_params();
+ void init_cost_params();
+ void update();
+
+ Photovoltaic* set_area(double a);
+ Photovoltaic* set_conversion_efficiency(double e);
+ Photovoltaic* set_min_power(double p);
+ Photovoltaic* set_max_power(double p);
+ Photovoltaic* set_eval_cost(bool eval);
+ Photovoltaic* set_lifespan(int l);
+ Photovoltaic* set_investment_cost(double c);
+ Photovoltaic* set_maintenance_cost(double c);
+
+public:
+ static simgrid::xbt::Extension<simgrid::s4u::Host, Photovoltaic> EXTENSION_ID;
+
+ explicit Photovoltaic(simgrid::s4u::Host* host);
+ ~Photovoltaic();
+
+ Photovoltaic* set_solar_irradiance(double s);
+
+ double get_power();
+};
+
+Photovoltaic* Photovoltaic::set_area(double a)
+{
+ xbt_assert(a > 0, " : area should be > 0 (provided: %f)", a);
+ simgrid::kernel::actor::simcall_answered([this, a] { area_m2_ = a; });
+ return this;
+}
+
+Photovoltaic* Photovoltaic::set_conversion_efficiency(double e)
+{
+ xbt_assert(e > 0 and e <= 1, " : conversion efficiency should be in [0,1] (provided: %f)", e);
+ simgrid::kernel::actor::simcall_answered([this, e] { conversion_efficiency_ = e; });
+ return this;
+}
+
+Photovoltaic* Photovoltaic::set_solar_irradiance(double s)
+{
+ xbt_assert(s > 0, " : solar irradiance should be > 0 (provided: %f)", s);
+ simgrid::kernel::actor::simcall_answered([this, s] { solar_irradiance_w_per_m2_ = s; });
+ return this;
+}
+
+Photovoltaic* Photovoltaic::set_min_power(double p)
+{
+ simgrid::kernel::actor::simcall_answered([this, p] { min_power_w_ = p; });
+ return this;
+}
+
+Photovoltaic* Photovoltaic::set_max_power(double p)
+{
+ simgrid::kernel::actor::simcall_answered([this, p] { max_power_w_ = p; });
+ return this;
+}
+
+Photovoltaic* Photovoltaic::set_eval_cost(bool e)
+{
+ simgrid::kernel::actor::simcall_answered([this, e] { eval_cost_ = e; });
+ return this;
+}
+
+Photovoltaic* Photovoltaic::set_lifespan(int l)
+{
+ xbt_assert(l > 0, " : lifespan should be > 0 (provided: %d)", l);
+ simgrid::kernel::actor::simcall_answered([this, l] { lifespan_years_ = l; });
+ return this;
+}
+
+Photovoltaic* Photovoltaic::set_investment_cost(double c)
+{
+ xbt_assert(c > 0, " : investment cost should be > 0 (provided: %f)", c);
+ simgrid::kernel::actor::simcall_answered([this, c] { investment_cost_per_w_ = c; });
+ return this;
+}
+
+Photovoltaic* Photovoltaic::set_maintenance_cost(double c)
+{
+ xbt_assert(c > 0, " : maintenance cost hould be > 0 (provided: %f)", c);
+ simgrid::kernel::actor::simcall_answered([this, c] { maintenance_cost_per_wh_ = c; });
+ return this;
+}
+
+double Photovoltaic::get_power()
+{
+ update();
+ return power_w_;
+}
+
+simgrid::xbt::Extension<simgrid::s4u::Host, Photovoltaic> Photovoltaic::EXTENSION_ID;
+
+void Photovoltaic::init_photovoltaic_params()
+{
+ const char* prop_chars;
+ prop_chars = host_->get_property("photovoltaic_area");
+ if (prop_chars)
+ set_area(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
+ prop_chars = host_->get_property("photovoltaic_conversion_efficiency");
+ if (prop_chars)
+ set_conversion_efficiency(
+ xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
+ prop_chars = host_->get_property("photovoltaic_solar_irradiance");
+ if (prop_chars)
+ set_solar_irradiance(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
+ prop_chars = host_->get_property("photovoltaic_min_power");
+ if (prop_chars)
+ set_min_power(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
+ prop_chars = host_->get_property("photovoltaic_max_power");
+ if (prop_chars)
+ set_max_power(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
+ prop_chars = host_->get_property("photovoltaic_eval_cost");
+ if (prop_chars)
+ set_eval_cost(xbt_str_parse_int(prop_chars, ("cannot parse int: " + std::string(prop_chars)).c_str()));
+ prop_chars = host_->get_property("photovoltaic_lifespan");
+ if (prop_chars)
+ set_lifespan(xbt_str_parse_int(prop_chars, ("cannot parse int: " + std::string(prop_chars)).c_str()));
+ prop_chars = host_->get_property("photovoltaic_investment_cost");
+ if (prop_chars)
+ set_investment_cost(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
+ prop_chars = host_->get_property("photovoltaic_maintenance_cost");
+ if (prop_chars)
+ set_maintenance_cost(xbt_str_parse_double(prop_chars, ("cannot parse double: " + std::string(prop_chars)).c_str()));
+ simgrid::kernel::actor::simcall_answered([this] { last_updated_ = simgrid::s4u::Engine::get_clock(); });
+}
+
+void Photovoltaic::update()
+{
+ simgrid::kernel::actor::simcall_answered([this] {
+ double now = simgrid::s4u::Engine::get_clock();
+ if (now <= last_updated_)
+ return;
+ double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_;
+ if (min_power_w_ > 0 and power_w_ < min_power_w_)
+ power_w = 0;
+ if (max_power_w_ > 0 and power_w_ > max_power_w_)
+ power_w = max_power_w_;
+ power_w_ = power_w;
+ if (eval_cost_) {
+ xbt_assert(max_power_w_ > 0, " : max power must be > 0 (provided: %f)", max_power_w_);
+ cumulative_cost_ += max_power_w_ * (now - last_updated_) *
+ (investment_cost_per_w_ / (lifespan_years_ * 8760 * 3600) + maintenance_cost_per_wh_ / 3600);
+ }
+ last_updated_ = now;
+ });
+}
+
+Photovoltaic::Photovoltaic(simgrid::s4u::Host* host) : host_(host)
+{
+ init_photovoltaic_params();
+}
+
+Photovoltaic::~Photovoltaic() = default;
+} // namespace simgrid::plugin
+
+using simgrid::plugin::Photovoltaic;
+
+/* **************************** events callback *************************** */
+
+static void on_creation(simgrid::s4u::Host& host)
+{
+ if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
+ return;
+ host.extension_set(new Photovoltaic(&host));
+}
+
+/* **************************** Public interface *************************** */
+
+static void ensure_plugin_inited()
+{
+ if (not Photovoltaic::EXTENSION_ID.valid())
+ throw simgrid::xbt::InitializationError(
+ "The Photovoltaic plugin is not active. Please call sg_photovoltaic_plugin_init() "
+ "before calling any function related to that plugin.");
+}
+
+/** @ingroup plugin_photovoltaic
+ * @brief Enable photovoltaic plugin.
+ */
+void sg_photovoltaic_plugin_init()
+{
+ if (Photovoltaic::EXTENSION_ID.valid())
+ return;
+ Photovoltaic::EXTENSION_ID = simgrid::s4u::Host::extension_create<Photovoltaic>();
+ simgrid::s4u::Host::on_creation_cb(&on_creation);
+}
+
+/** @ingroup plugin_photovoltaic
+ * @param s The solar irradiance to set in W/m².
+ */
+void sg_photovoltaic_set_solar_irradiance(const_sg_host_t host, double s)
+{
+ ensure_plugin_inited();
+ host->extension<Photovoltaic>()->set_solar_irradiance(s);
+}
+
+/** @ingroup plugin_photovoltaic
+ * @return Power generation in W.
+ */
+double sg_photovoltaic_get_power(const_sg_host_t host)
+{
+ ensure_plugin_inited();
+ return host->extension<Photovoltaic>()->get_power();
+}
\ No newline at end of file
}
}
-static void on_exec_completion(const simgrid::s4u::Activity& e)
+static void on_exec_completion(const simgrid::s4u::Exec& e)
{
- const auto exec = dynamic_cast<simgrid::kernel::activity::ExecImpl*>(e.get_impl());
+ const auto* exec = dynamic_cast<simgrid::kernel::activity::ExecImpl*>(e.get_impl());
if (exec == nullptr)
return;
const simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(exec->get_host());
simgrid::kernel::resource::VirtualMachineImpl::extension_create<DirtyPageTrackingExt>();
simgrid::s4u::VirtualMachine::on_creation_cb(&on_virtual_machine_creation);
simgrid::s4u::Exec::on_start_cb(&on_exec_creation);
- simgrid::s4u::Activity::on_completion_cb(&on_exec_completion);
+ simgrid::s4u::Exec::on_completion_cb(&on_exec_completion);
}
}
namespace s4u {
-xbt::signal<void(Activity&)> Activity::on_veto;
-xbt::signal<void(Activity const&)> Activity::on_completion;
-xbt::signal<void(Activity const&)> Activity::on_suspended;
-xbt::signal<void(Activity const&)> Activity::on_resumed;
-
std::set<Activity*>* Activity::vetoed_activities_ = nullptr;
void Activity::destroy()
});
s4u::Actor::on_host_change(*this, *previous_location);
+ s4u::Actor::on_this_host_change(*this, *previous_location);
}
s4u::Host* Actor::get_host() const
kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
kernel::actor::ActorImpl* target = pimpl_;
s4u::Actor::on_suspend(*this);
+ s4u::Actor::on_this_suspend(*this);
kernel::actor::simcall_blocking([issuer, target]() {
target->suspend();
if (target != issuer) {
{
kernel::actor::simcall_answered([this] { pimpl_->resume(); });
s4u::Actor::on_resume(*this);
+ s4u::Actor::on_this_resume(*this);
}
bool Actor::is_suspended() const
kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
Actor::on_sleep(*issuer->get_ciface());
+ issuer->get_ciface()->on_this_sleep(*issuer->get_ciface());
kernel::actor::simcall_blocking([issuer, duration]() {
if (MC_is_active() || MC_record_replay_is_active()) {
});
Actor::on_wake_up(*issuer->get_ciface());
+ issuer->get_ciface()->on_this_wake_up(*issuer->get_ciface());
}
void yield()
{
kernel::actor::ActorImpl* self = simgrid::kernel::actor::ActorImpl::self();
s4u::Actor::on_suspend(*self->get_ciface());
+ self->get_ciface()->on_this_suspend(*self->get_ciface());
kernel::actor::simcall_blocking([self] { self->suspend(); });
}
XBT_INFO("pimpl_ is null");
xbt_backtrace_display_current();
}
+ if (pimpl_ != nullptr)
+ pimpl_->set_iface(nullptr);
}
void Comm::send(kernel::actor::ActorImpl* sender, const Mailbox* mbox, double task_size, double rate, void* src_buff,
return sender ? sender->get_ciface() : nullptr;
}
+Actor* Comm::get_receiver() const
+{
+ kernel::actor::ActorImplPtr receiver = nullptr;
+ if (pimpl_)
+ receiver = boost::static_pointer_cast<kernel::activity::CommImpl>(pimpl_)->dst_actor_;
+ return receiver ? receiver->get_ciface() : nullptr;
+}
+
bool Comm::is_assigned() const
{
return (pimpl_ && boost::static_pointer_cast<kernel::activity::CommImpl>(pimpl_)->is_assigned()) ||
xbt_assert(src_buff_ == nullptr && dst_buff_ == nullptr,
"Direct host-to-host communications cannot carry any data.");
XBT_DEBUG("host-to-host Comm. Pimpl already created and set, just start it.");
+ on_start(*this);
+ on_this_start(*this);
kernel::actor::simcall_answered([this] {
pimpl_->set_state(kernel::activity::State::READY);
boost::static_pointer_cast<kernel::activity::CommImpl>(pimpl_)->start();
});
} else if (src_buff_ != nullptr) { // Sender side
on_send(*this);
+ on_this_send(*this);
kernel::actor::CommIsendSimcall observer{sender_,
mailbox_->get_impl(),
remains_,
} else if (dst_buff_ != nullptr) { // Receiver side
xbt_assert(not detached_, "Receive cannot be detached");
on_recv(*this);
+ on_this_recv(*this);
kernel::actor::CommIrecvSimcall observer{receiver_,
mailbox_->get_impl(),
static_cast<unsigned char*>(dst_buff_),
if (not detached_) {
pimpl_->set_iface(this);
pimpl_->set_actor(sender_);
+ // Only throw the signal when both sides are here and the status is READY
+ if (pimpl_->get_state() != kernel::activity::State::WAITING) {
+ on_start(*this);
+ on_this_start(*this);
+ }
}
state_ = State::STARTED;
return start()->wait_for(timeout); // In the case of host2host comm, do it in two simcalls
} else if (src_buff_ != nullptr) {
on_send(*this);
+ on_this_send(*this);
send(sender_, mailbox_, remains_, rate_, src_buff_, src_buff_size_, match_fun_, copy_data_function_,
get_data<void>(), timeout);
} else { // Receiver
on_recv(*this);
+ on_this_recv(*this);
recv(receiver_, mailbox_, dst_buff_, &dst_buff_size_, match_fun_, copy_data_function_, get_data<void>(),
timeout, rate_);
}
xbt::signal<void(Disk&)> Disk::on_creation;
xbt::signal<void(Disk const&)> Disk::on_destruction;
-xbt::signal<void(Disk const&)> Disk::on_state_change;
+xbt::signal<void(Disk const&)> Disk::on_onoff;
const std::string& Disk::get_name() const
{
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_exec, s4u_activity, "S4U asynchronous executions");
namespace simgrid::s4u {
-xbt::signal<void(Exec const&)> Exec::on_start;
Exec::Exec(kernel::activity::ExecImplPtr pimpl)
{
state_ = State::STARTED;
on_start(*this);
+ on_this_start(*this);
return this;
}
#ifndef DOXYGEN
xbt::signal<void(Host&)> Host::on_creation;
xbt::signal<void(Host const&)> Host::on_destruction;
-xbt::signal<void(Host const&)> Host::on_state_change;
+xbt::signal<void(Host const&)> Host::on_onoff;
xbt::signal<void(Host const&)> Host::on_speed_change;
+xbt::signal<void(kernel::resource::CpuAction&, kernel::resource::Action::State)> Host::on_exec_state_change;
#endif
Host* Host::set_cpu(kernel::resource::CpuImpl* cpu)
kernel::actor::simcall_answered([this] {
this->pimpl_cpu_->turn_on();
this->pimpl_->turn_on();
- on_state_change(*this);
+ on_onoff(*this);
+ on_this_onoff(*this);
});
}
}
this->pimpl_cpu_->turn_off();
this->pimpl_->turn_off(self);
- on_state_change(*this);
+ on_onoff(*this);
+ on_this_onoff(*this);
});
}
}
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_io, s4u_activity, "S4U asynchronous I/Os");
namespace simgrid::s4u {
-xbt::signal<void(Io const&)> Io::on_start;
Io::Io(kernel::activity::IoImplPtr pimpl)
{
state_ = State::STARTED;
on_start(*this);
+ on_this_start(*this);
return this;
}
xbt::signal<void(Link&)> Link::on_creation;
xbt::signal<void(Link const&)> Link::on_destruction;
-xbt::signal<void(Link const&)> Link::on_state_change;
+xbt::signal<void(Link const&)> Link::on_onoff;
xbt::signal<void(Link const&)> Link::on_bandwidth_change;
xbt::signal<void(kernel::resource::NetworkAction&, kernel::resource::Action::State)>
Link::on_communication_state_change;
XBT_DEBUG("destroy %s", get_cname());
on_vm_destruction(*this);
+ on_this_vm_destruction(*this);
/* Then, destroy the VM object */
kernel::actor::simcall_answered(
[this]() { get_vm_impl()->get_physical_host()->get_impl()->destroy_vm(get_name()); });
#ifndef SMPI_TOPO_HPP_INCLUDED
#define SMPI_TOPO_HPP_INCLUDED
-#include "smpi_comm.hpp"
#include "smpi_status.hpp"
#include <memory>
}
// Recursive template code derived from Matthieu M.
-template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1> class HashValueImpl {
+template <class Tuple, size_t Index = std::tuple_size_v<Tuple> - 1> class HashValueImpl {
public:
static void apply(size_t& seed, Tuple const& tuple)
{
int F2C::add_f()
{
allocate_lookup();
- if (auto loc = smpi_process()->call_location(); loc && loc->linenumber != 0)
+ if (auto const* loc = smpi_process()->call_location(); loc && loc->linenumber != 0)
call_location_= std::string (loc->filename + ":" + std::to_string(loc->linenumber));
my_f2c_id_ = global_f2c_id();
(*f2c_lookup_)[my_f2c_id_] = this;
{sg4::LinkInRoute{link}}, false);
zone->seal();
- sg4::Host::on_state_change_cb([mbox](sg4::Host const& host) {
+ sg4::Host::on_onoff_cb([mbox](sg4::Host const& host) {
XBT_DEBUG("Host %s is now %s", host.get_cname(), host.is_on() ? "ON " : "OFF");
if (not host.is_on()) {
mbox.eager->clear();
}
});
- sg4::Link::on_state_change_cb(
+ sg4::Link::on_onoff_cb(
[](sg4::Link const& lnk) { XBT_DEBUG("Link %s is now %s", lnk.get_cname(), lnk.is_on() ? "ON " : "OFF"); });
e.run_until(end_time);
xbt_assert(argc > 1, "Usage: %s platform_file\n\nExample: %s two_clusters.xml", argv[0], argv[0]);
engine.load_platform(argv[1]);
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec const*>(&activity);
- if (exec == nullptr) // Only Execs are concerned here
- return;
- XBT_INFO("Exec '%s' start time: %f, finish time: %f", exec->get_cname(), exec->get_start_time(),
- exec->get_finish_time());
+ simgrid::s4u::Exec::on_completion_cb([](simgrid::s4u::Exec const& exec) {
+ XBT_INFO("Exec '%s' start time: %f, finish time: %f", exec.get_cname(), exec.get_start_time(),
+ exec.get_finish_time());
});
/* creation of the activities and their dependencies */
static void dump_platform_disks()
{
- for (auto const& h : simgrid::s4u::Engine::get_instance()->get_all_hosts())
- for (auto const& d : h->get_disks()) {
+ for (auto const* h : simgrid::s4u::Engine::get_instance()->get_all_hosts())
+ for (auto* d : h->get_disks()) {
if (h == d->get_host())
XBT_INFO("%s is attached to %s", d->get_cname(), d->get_host()->get_cname());
d->set_property("other usage", "gpfs");
{
XBT_INFO("*** Disk info on %s ***", host->get_cname());
- for (auto const& disk : host->get_disks()) {
+ for (auto const* disk : host->get_disks()) {
const char* mount_name = sg_disk_get_mount_point(disk);
XBT_INFO(" Disk name: %s, mount name: %s", disk->get_cname(), mount_name);
{
XBT_INFO("---- HOSTS and VMS STATUS ----");
XBT_INFO("--- HOSTS ---");
- for (auto const& host : hosts) {
+ for (auto const* host : hosts) {
XBT_INFO("+ Name:%s Load:%f", host->get_cname(), host->get_load());
for (auto const& actor : host->get_all_actors())
XBT_INFO("++ actor: %s", actor->get_cname());
}
XBT_INFO("--- VMS ---");
- for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
- if (auto vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host)) {
+ for (auto const* host : simgrid::s4u::Engine::get_instance()->get_all_hosts()) {
+ if (auto const* vm = dynamic_cast<const simgrid::s4u::VirtualMachine*>(host)) {
XBT_INFO("+ Name:%s Host:%s Load:%f State: %s", vm->get_cname(), vm->get_pm()->get_cname(), vm->get_load(),
simgrid::s4u::VirtualMachine::to_c_str(vm->get_state()));
for (auto const& actor : host->get_all_actors())
{
simgrid::s4u::Host* other_host = simgrid::s4u::Host::by_name("Fafard");
unsigned int first =
- simgrid::s4u::Host::on_state_change.connect([](simgrid::s4u::Host const&) { XBT_INFO("First callback"); });
+ simgrid::s4u::Host::on_onoff.connect([](simgrid::s4u::Host const&) { XBT_INFO("First callback"); });
unsigned int second =
- simgrid::s4u::Host::on_state_change.connect([](simgrid::s4u::Host const&) { XBT_INFO("Second callback"); });
+ simgrid::s4u::Host::on_onoff.connect([](simgrid::s4u::Host const&) { XBT_INFO("Second callback"); });
unsigned int third =
- simgrid::s4u::Host::on_state_change.connect([](simgrid::s4u::Host const&) { XBT_INFO("Third callback"); });
+ simgrid::s4u::Host::on_onoff.connect([](simgrid::s4u::Host const&) { XBT_INFO("Third callback"); });
XBT_INFO("Turning off: Three callbacks should be triggered");
other_host->turn_off();
XBT_INFO("Disconnect the second callback");
- simgrid::s4u::Host::on_state_change.disconnect(second);
+ simgrid::s4u::Host::on_onoff.disconnect(second);
XBT_INFO("Turning on: Two callbacks should be triggered");
other_host->turn_on();
XBT_INFO("Disconnect the first callback");
- simgrid::s4u::Host::on_state_change.disconnect(first);
+ simgrid::s4u::Host::on_onoff.disconnect(first);
XBT_INFO("Turning off: One callback should be triggered");
other_host->turn_off();
XBT_INFO("Disconnect the third callback");
- simgrid::s4u::Host::on_state_change.disconnect(third);
+ simgrid::s4u::Host::on_onoff.disconnect(third);
XBT_INFO("Turning on: No more callbacks");
other_host->turn_on();
}
odr_violation:^cfg_bmf_max_iteration$
# size=40 'cfg_bmf_precision' ../src/kernel/lmm/bmf.hpp:80:47
odr_violation:^cfg_bmf_precision$
+
+# size=56 'on_completion' ../include/simgrid/s4u/Activity.hpp:235:55
+odr_violation:^on_completion$
+# size=56 'on_veto' ../include/simgrid/s4u/Activity.hpp:236:49
+odr_violation:^on_veto$
+# size=56 'on_suspend' ../include/simgrid/s4u/Activity.hpp:237:55
+odr_violation:^on_suspend$
+# size=56 'on_resume' ../include/simgrid/s4u/Activity.hpp:238:55
+odr_violation:^on_resume$
+
+# size=56 'on_start' ../include/simgrid/s4u/Comm.hpp:45:48
+# size=56 'on_start' ../include/simgrid/s4u/Exec.hpp:45:48
+odr_violation:^on_start$
src/plugins/vm/dirty_page_tracking.cpp
src/plugins/battery.cpp
src/plugins/operation.cpp
+ src/plugins/photovoltaic.cpp
)
include/simgrid/plugins/live_migration.h
include/simgrid/plugins/load.h
include/simgrid/plugins/operation.hpp
+ include/simgrid/plugins/photovoltaic.hpp
include/simgrid/plugins/ProducerConsumer.hpp
include/simgrid/instr.h
include/simgrid/mailbox.h
examples/platforms/optorsim/gridpp_grid_2004.conf
examples/platforms/optorsim/lcg_sept2004_grid.conf
examples/platforms/optorsim/transform_optorsim_platform.pl
+ examples/platforms/photovoltaic_platform.xml
examples/platforms/profiles/fafard_state.profile
examples/platforms/profiles/faulty_host.profile
examples/platforms/profiles/ginette_state.profile