From 4baeceb26e6cfc594ba0bd184ee0a755e47a2a85 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Tue, 14 Dec 2021 21:10:18 +0100 Subject: [PATCH] New signal: Activity::on_veto, to detect when an activity fails to start --- ChangeLog | 5 +++-- .../cpp/exec-dependent/s4u-exec-dependent.cpp | 17 ++++++++++++++++- .../cpp/exec-dependent/s4u-exec-dependent.tesh | 4 +++- include/simgrid/s4u/Activity.hpp | 11 +++++++++-- include/simgrid/s4u/Exec.hpp | 2 ++ src/s4u/s4u_Activity.cpp | 2 ++ 6 files changed, 35 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index c71fe262d2..9ef1ed5374 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,8 +2,9 @@ SimGrid (3.29.1) NOT RELEASED YET (v3.30 expected December 21. 2021, 15:59 UTC) -Engine: - - New function: run_until(date) allowing to split the simulation. +S4U: + - New function: Engine::run_until(date), to split the simulation. + - New signal: Activity::on_veto, to detect when an activity fails to start. SMPI: - Dynamic costs for MPI operations: New API to allow users to dynamically diff --git a/examples/cpp/exec-dependent/s4u-exec-dependent.cpp b/examples/cpp/exec-dependent/s4u-exec-dependent.cpp index db155eb4d8..ada7e5e899 100644 --- a/examples/cpp/exec-dependent/s4u-exec-dependent.cpp +++ b/examples/cpp/exec-dependent/s4u-exec-dependent.cpp @@ -21,7 +21,7 @@ static void worker() pending_execs.push_back(first_parent); simgrid::s4u::ExecPtr second_parent = simgrid::s4u::this_actor::exec_init(2 * computation_amount); pending_execs.push_back(second_parent); - simgrid::s4u::ExecPtr child = simgrid::s4u::this_actor::exec_init(computation_amount); + simgrid::s4u::ExecPtr child = simgrid::s4u::Exec::init()->set_flops_amount(computation_amount); pending_execs.push_back(child); // Name the activities (for logging purposes only) @@ -54,6 +54,21 @@ int main(int argc, char* argv[]) simgrid::s4u::Actor::create("worker", e.host_by_name("Fafard"), worker); + simgrid::s4u::Activity::on_veto.connect([&e](simgrid::s4u::Activity& a) { + auto& exec = static_cast(a); + + // First display the situation + XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(), + (exec.dependencies_solved() ? "solved" : "NOT solved"), + (exec.is_assigned() ? "assigned" : "NOT assigned")); + + // In this simple case, we just assign the child task to a resource when its dependencies are solved + if (exec.dependencies_solved() && not exec.is_assigned()) { + XBT_INFO("Activity %s's dependencies are resolved. Let's assign it to Fafard.", exec.get_cname()); + exec.set_host(e.host_by_name("Fafard")); + } + }); + e.run(); XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock()); diff --git a/examples/cpp/exec-dependent/s4u-exec-dependent.tesh b/examples/cpp/exec-dependent/s4u-exec-dependent.tesh index c27d3ffc4e..a376e10d03 100644 --- a/examples/cpp/exec-dependent/s4u-exec-dependent.tesh +++ b/examples/cpp/exec-dependent/s4u-exec-dependent.tesh @@ -1,10 +1,12 @@ #!/usr/bin/env tesh -! output sort $ ${bindir:=.}/s4u-exec-dependent ${platfdir}/small_platform.xml --log=s4u_activity.t:verbose "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" +> [ 0.000000] (1:worker@Fafard) Activity 'child' vetoed. Dependencies: NOT solved; Ressources: NOT assigned > [ 2.000000] (1:worker@Fafard) Remove a dependency from 'parent 1' on 'child' > [ 2.000000] (1:worker@Fafard) Exec 'parent 1' is complete > [ 3.000000] (1:worker@Fafard) Remove a dependency from 'parent 2' on 'child' +> [ 3.000000] (1:worker@Fafard) Activity 'child' vetoed. Dependencies: solved; Ressources: NOT assigned +> [ 3.000000] (1:worker@Fafard) Activity child's dependencies are resolved. Let's assign it to Fafard. > [ 3.000000] (1:worker@Fafard) 'child' is assigned to a resource and all dependencies are solved. Let's start > [ 3.000000] (1:worker@Fafard) Exec 'parent 2' is complete > [ 4.000000] (1:worker@Fafard) Exec 'child' is complete diff --git a/include/simgrid/s4u/Activity.hpp b/include/simgrid/s4u/Activity.hpp index 0e165e7187..ff42c98447 100644 --- a/include/simgrid/s4u/Activity.hpp +++ b/include/simgrid/s4u/Activity.hpp @@ -36,12 +36,13 @@ public: // enum class State { ... } XBT_DECLARE_ENUM_CLASS(State, INITED, STARTING, STARTED, FAILED, CANCELED, FINISHED); + virtual bool is_assigned() const = 0; + virtual bool dependencies_solved() const { return dependencies_.empty(); } + protected: Activity() = default; virtual ~Activity() = default; - virtual bool is_assigned() const = 0; - virtual bool dependencies_solved() { return dependencies_.empty(); } virtual void complete(Activity::State state) { state_ = state; @@ -88,12 +89,18 @@ protected: } public: + /*! Signal fired each time that the activity fails to start because of a veto (e.g., unsolved dependency or no + * resource assigned) */ + static xbt::signal on_veto; + void vetoable_start() { state_ = State::STARTING; if (dependencies_solved() && is_assigned()) { XBT_CVERB(s4u_activity, "'%s' is assigned to a resource and all dependencies are solved. Let's start", get_cname()); start(); + } else { + on_veto(*this); } } diff --git a/include/simgrid/s4u/Exec.hpp b/include/simgrid/s4u/Exec.hpp index 3aa140021c..e6b18d0cae 100644 --- a/include/simgrid/s4u/Exec.hpp +++ b/include/simgrid/s4u/Exec.hpp @@ -46,7 +46,9 @@ public: Exec(Exec const&) = delete; Exec& operator=(Exec const&) = delete; #endif + /*! Signal fired each time that an execution actually starts (no veto) */ static xbt::signal on_start; + /*! Signal fired each time that an execution terminates (either normally, cancelled or failed) */ static xbt::signal on_completion; static ExecPtr init(); diff --git a/src/s4u/s4u_Activity.cpp b/src/s4u/s4u_Activity.cpp index d07506a910..000e1b5a3c 100644 --- a/src/s4u/s4u_Activity.cpp +++ b/src/s4u/s4u_Activity.cpp @@ -19,6 +19,8 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_activity, s4u, "S4U activities"); namespace simgrid { namespace s4u { +xbt::signal Activity::on_veto; + void Activity::wait_until(double time_limit) { double now = Engine::get_clock(); -- 2.20.1