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.
-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-*
+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.
Kernel:
- optimize an internal datastructure (use a set instead of a list for ongoing activities),
- 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
bool has_no_successor() const { return successors_.empty(); }
const std::set<ActivityPtr>& get_dependencies() const { return dependencies_; }
const std::vector<ActivityPtr>& get_successors() const { return successors_; }
+ virtual void fire_this_completion() const = 0;
protected:
Activity() = default;
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;
+ static xbt::signal<void(Activity const&)> on_suspend;
+ static xbt::signal<void(Activity const&)> on_resume;
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); }
+ static void on_suspend_cb(const std::function<void(Activity const&)>& cb)
+ {
+ on_suspend.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); }
+ static void on_resume_cb(const std::function<void(Activity const&)>& cb)
+ {
+ on_resume.connect(cb);
+ }
+
+ XBT_ATTRIB_DEPRECATED_v334("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_v334("Please use on_resume_cb() instead") static void on_resumed_cb(
+ const std::function<void(Activity const&)>& cb)
+ {
+ on_resume.connect(cb);
+ }
XBT_ATTRIB_DEPRECATED_v334("All start() are vetoable now. Please use start() ") void vetoable_start()
{
// released by the on_completion() callbacks.
ActivityPtr keepalive(this);
state_ = state;
- on_completion(*this);
+ fire_this_completion();
if (state == State::FINISHED)
release_dependencies();
}
std::string tracing_category_ = "";
public:
+ inline static xbt::signal<void(AnyActivity const&)> on_completion;
+ /*! Add a callback fired when the activity completes (either normally, cancelled or failed) */
+ static void on_completion_cb(const std::function<void(AnyActivity const&)>& cb) { on_completion.connect(cb); }
+
AnyActivity* add_successor(ActivityPtr a)
{
Activity::add_successor(a);
AnyActivity* set_tracing_category(const std::string& 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
#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::Activity::on_suspend_cb(on_activity_suspend_resume);
+ s4u::Activity::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::Activity::on_completion_cb([](const s4u::Activity&) {
- Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->pop_event();
+
+ 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) {
+ 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")->pop_event();
+ Container::by_name(c.get_destination()->get_name())->get_state("HOST_STATE")->pop_event();
+ } else
+ Container::by_name(pid)->get_state("ACTOR_STATE")->pop_event();
});
- s4u::Comm::on_send_cb([](s4u::Comm const&) {
- Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("send");
+ s4u::Comm::on_send_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("send");
+ else
+ Container::by_name(pid)->get_state("ACTOR_STATE")->push_event("send");
});
- s4u::Comm::on_recv_cb([](s4u::Comm const&) {
- Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("receive");
+ s4u::Comm::on_recv_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_destination()->get_name())->get_state("HOST_STATE")->push_event("receive");
+ else
+ Container::by_name(pid)->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();
});
}
}
}
- 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();
}
{
s4u::Host::on_state_change_cb(host_state_change);
s4u::Exec::on_start_cb(add_active_exec);
- s4u::Activity::on_completion_cb(remove_active_exec);
+ s4u::Exec::on_completion_cb(remove_active_exec);
- s4u::Activity::on_resumed_cb(add_active_activity);
- s4u::Activity::on_suspended_cb(remove_active_activity);
+ s4u::Activity::on_resume_cb(add_active_activity);
+ s4u::Activity::on_suspend_cb(remove_active_activity);
}
double VMModel::next_occurring_event(double now)
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;
+xbt::signal<void(Activity const&)> Activity::on_suspend;
+xbt::signal<void(Activity const&)> Activity::on_resume;
std::set<Activity*>* Activity::vetoed_activities_ = nullptr;