Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
the on_exit() of each actor is also executed when the simulation deadlocks
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Wed, 6 May 2020 20:27:27 +0000 (22:27 +0200)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Wed, 6 May 2020 20:27:27 +0000 (22:27 +0200)
ChangeLog
examples/s4u/actor-exiting/s4u-actor-exiting.cpp
examples/s4u/actor-exiting/s4u-actor-exiting.tesh
include/simgrid/s4u/Actor.hpp
include/simgrid/s4u/Engine.hpp
src/simix/smx_global.cpp

index 6b6b66c..6b426d9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,6 +17,9 @@ Important user-visible changes:
    these values if needed. Network and routing models already providing separate
    loopbacks (clusters and such) are not impacted by this change.
 
    these values if needed. Network and routing models already providing separate
    loopbacks (clusters and such) are not impacted by this change.
 
+S4U:
+ - the on_exit() of each actor is also executed when the simulation deadlocks.
+
 General:
  - LTO is now enabled for Intel/clang compilers.
  - LTO behavior on GCC can be parameterized using LTO_EXTRA_FLAG in cmake.
 General:
  - LTO is now enabled for Intel/clang compilers.
  - LTO behavior on GCC can be parameterized using LTO_EXTRA_FLAG in cmake.
index dfd0f80..aa2215b 100644 (file)
@@ -40,12 +40,32 @@ static void actor_a()
   // Register a lambda function to be executed once it stops
   simgrid::s4u::this_actor::on_exit([](bool /*failed*/) { XBT_INFO("I stop now"); });
 
   // Register a lambda function to be executed once it stops
   simgrid::s4u::this_actor::on_exit([](bool /*failed*/) { XBT_INFO("I stop now"); });
 
-  simgrid::s4u::this_actor::execute(1e9);
+  simgrid::s4u::this_actor::sleep_for(1);
 }
 
 static void actor_b()
 {
 }
 
 static void actor_b()
 {
-  simgrid::s4u::this_actor::execute(2e9);
+  simgrid::s4u::this_actor::sleep_for(2);
+}
+
+static void actor_c()
+{
+  // Register a lambda function to be executed once it stops
+  simgrid::s4u::this_actor::on_exit([](bool failed) {
+    if (failed) {
+      XBT_INFO("I was killed!");
+      if (xbt_log_no_loc)
+        XBT_INFO("The backtrace would be displayed here if --log=no_loc would not have been passed");
+      else
+        xbt_backtrace_display_current();
+    } else
+      XBT_INFO("Exiting gracefully.");
+  });
+
+  simgrid::s4u::this_actor::sleep_for(3);
+  XBT_INFO("And now, induce a deadlock by waiting for a message that will never come\n\n");
+  simgrid::s4u::Mailbox::by_name("nobody")->get();
+  xbt_die("Receiving is not supposed to succeed when nobody is sending");
 }
 
 int main(int argc, char* argv[])
 }
 
 int main(int argc, char* argv[])
@@ -65,6 +85,7 @@ int main(int argc, char* argv[])
   /* Create some actors */
   simgrid::s4u::Actor::create("A", simgrid::s4u::Host::by_name("Tremblay"), actor_a);
   simgrid::s4u::Actor::create("B", simgrid::s4u::Host::by_name("Fafard"), actor_b);
   /* Create some actors */
   simgrid::s4u::Actor::create("A", simgrid::s4u::Host::by_name("Tremblay"), actor_a);
   simgrid::s4u::Actor::create("B", simgrid::s4u::Host::by_name("Fafard"), actor_b);
+  simgrid::s4u::Actor::create("C", simgrid::s4u::Host::by_name("Ginette"), actor_c);
 
   e.run(); /* - Run the simulation */
 
 
   e.run(); /* - Run the simulation */
 
index e59ceb8..dbbf4db 100644 (file)
@@ -1,8 +1,19 @@
 #!/usr/bin/env tesh
 
 #!/usr/bin/env tesh
 
-$ ${bindir:=.}/s4u-actor-exiting ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
-> [ 10.194200] (A@Tremblay) I stop now
-> [ 10.194200] (maestro@) Actor A terminates now
-> [ 26.213694] (maestro@) Actor A gets destroyed now
-> [ 26.213694] (maestro@) Actor B terminates now
-> [ 26.213694] (maestro@) Actor B gets destroyed now
+$ ${bindir:=.}/s4u-actor-exiting ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n" --log=no_loc
+> [  1.000000] (A@Tremblay) I stop now
+> [  1.000000] (maestro@) Actor A terminates now
+> [  2.000000] (maestro@) Actor A gets destroyed now
+> [  2.000000] (maestro@) Actor B terminates now
+> [  3.000000] (maestro@) Actor B gets destroyed now
+> [  3.000000] (C@Ginette) And now, induce a deadlock by waiting for a message that will never come
+> 
+> 
+> [  3.000000] (maestro@) Oops! Deadlock or code not perfectly clean.
+> [  3.000000] (maestro@) 1 actors are still running, waiting for something.
+> [  3.000000] (maestro@) Legend of the following listing: "Actor <pid> (<name>@<host>): <status>"
+> [  3.000000] (maestro@) Actor 3 (C@Ginette): waiting for communication activity 0xdeadbeef () in state 0 to finish
+> [  3.000000] (C@Ginette) I was killed!
+> [  3.000000] (C@Ginette) The backtrace would be displayed here if --log=no_loc would not have been passed
+> [  3.000000] (maestro@) Actor C terminates now
+> [  3.000000] (maestro@) Actor C gets destroyed now
index 6d8ef15..a8c3da8 100644 (file)
@@ -367,7 +367,7 @@ XBT_PUBLIC void exit();
  * blocking functions forbidden in this setting, but also modifications to the global state.
  *
  * The parameter of on_exit's callbacks denotes whether or not the actor's execution failed.
  * blocking functions forbidden in this setting, but also modifications to the global state.
  *
  * The parameter of on_exit's callbacks denotes whether or not the actor's execution failed.
- * It will be set to true if the actor was killed or failed because of an exception,
+ * It will be set to true if the actor was killed or failed because of an exception or if the simulation deadlocked,
  * while it will remain to false if the actor terminated gracefully.
  */
 
  * while it will remain to false if the actor terminated gracefully.
  */
 
index fc1c747..7294e60 100644 (file)
@@ -181,7 +181,8 @@ public:
   /** Callback fired when the time jumps into the future */
   static xbt::signal<void(double)> on_time_advance;
 
   /** Callback fired when the time jumps into the future */
   static xbt::signal<void(double)> on_time_advance;
 
-  /** Callback fired when the time cannot advance because of inter-actors deadlock */
+  /** Callback fired when the time cannot advance because of inter-actors deadlock. Note that the on_exit of each actor
+   * is also executed on deadlock. */
   static xbt::signal<void(void)> on_deadlock;
 
 private:
   static xbt::signal<void(void)> on_deadlock;
 
 private:
index 20b1f4a..36454f6 100644 (file)
@@ -251,8 +251,9 @@ void Global::display_all_actor_status()
         synchro_description = "I/O";
 
       XBT_INFO("Actor %ld (%s@%s): waiting for %s activity %p (%s) in state %d to finish", actor->get_pid(),
         synchro_description = "I/O";
 
       XBT_INFO("Actor %ld (%s@%s): waiting for %s activity %p (%s) in state %d to finish", actor->get_pid(),
-               actor->get_cname(), actor->get_host()->get_cname(), synchro_description, actor->waiting_synchro.get(),
-               name, (int)actor->waiting_synchro->state_);
+               actor->get_cname(), actor->get_host()->get_cname(), synchro_description,
+               (xbt_log_no_loc ? (void*)0xDEADBEEF : actor->waiting_synchro.get()), name,
+               (int)actor->waiting_synchro->state_);
     } else {
       XBT_INFO("Actor %ld (%s@%s)", actor->get_pid(), actor->get_cname(), actor->get_host()->get_cname());
     }
     } else {
       XBT_INFO("Actor %ld (%s@%s)", actor->get_pid(), actor->get_cname(), actor->get_host()->get_cname());
     }
@@ -548,19 +549,26 @@ void SIMIX_run()
 
     XBT_DEBUG("### time %f, #processes %zu, #to_run %zu", time, simix_global->process_list.size(),
               simix_global->actors_to_run.size());
 
     XBT_DEBUG("### time %f, #processes %zu, #to_run %zu", time, simix_global->process_list.size(),
               simix_global->actors_to_run.size());
-  } while (time > -1.0 || not simix_global->actors_to_run.empty());
 
 
-  if (not simix_global->process_list.empty()) {
-    if (simix_global->process_list.size() <= simix_global->daemons.size()) {
-      XBT_CRITICAL("Oops! Daemon actors cannot do any blocking activity (communications, synchronization, etc) "
-                   "once the simulation is over. Please fix your on_exit() functions.");
-    } else {
-      XBT_CRITICAL("Oops! Deadlock or code not perfectly clean.");
+    if (time < 0. && simix_global->actors_to_run.empty() && not simix_global->process_list.empty()) {
+      if (simix_global->process_list.size() <= simix_global->daemons.size()) {
+        XBT_CRITICAL("Oops! Daemon actors cannot do any blocking activity (communications, synchronization, etc) "
+                     "once the simulation is over. Please fix your on_exit() functions.");
+      } else {
+        XBT_CRITICAL("Oops! Deadlock or code not perfectly clean.");
+      }
+      simix_global->display_all_actor_status();
+      simgrid::s4u::Engine::on_deadlock();
+      for (auto const& kv : simix_global->process_list) {
+        XBT_DEBUG("Kill %s", kv.second->get_cname());
+        simix_global->maestro_->kill(kv.second);
+      }
     }
     }
-    simix_global->display_all_actor_status();
-    simgrid::s4u::Engine::on_deadlock();
-    xbt_abort();
-  }
+  } while (time > -1.0 || not simix_global->actors_to_run.empty());
+
+  if (not simix_global->process_list.empty())
+    THROW_IMPOSSIBLE;
+
   simgrid::s4u::Engine::on_simulation_end();
 }
 
   simgrid::s4u::Engine::on_simulation_end();
 }