Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Introduce ActorIDTrait to split ActorImpl apart
[simgrid.git] / src / kernel / EngineImpl.cpp
index 3ef95ec49dfc025e077b49808465fd5e8989111b..76a938dd96b2e41e87a43d183ec5be1410f2f288 100644 (file)
@@ -44,15 +44,6 @@ config::Flag<double> cfg_breakpoint{"debug/breakpoint",
                                     "When non-negative, raise a SIGTRAP after given (simulated) time", -1.0};
 config::Flag<bool> cfg_verbose_exit{"debug/verbose-exit", "Display the actor status at exit", true};
 
-xbt_dynar_t get_actors_addr()
-{
-#if SIMGRID_HAVE_MC
-  return EngineImpl::get_instance()->get_actors_vector();
-#else
-  xbt_die("This function is intended to be used when compiling with MC");
-#endif
-}
-
 constexpr std::initializer_list<std::pair<const char*, context::ContextFactoryInitializer>> context_factories = {
 #if HAVE_RAW_CONTEXTS
     {"raw", &context::raw_factory},
@@ -209,9 +200,9 @@ void EngineImpl::initialize(int* argc, char** argv)
   EngineImpl::instance_ = this;
 #if SIMGRID_HAVE_MC
   // The communication initialization is done ASAP, as we need to get some init parameters from the MC for different
-  // layers. But simix_global needs to be created, as we send the address of some of its fields to the MC that wants to
+  // layers. But instance_ needs to be created, as we send the address of some of its fields to the MC that wants to
   // read them directly.
-  simgrid::mc::AppSide::initialize();
+  simgrid::mc::AppSide::initialize(actors_vector_);
 #endif
 
   if (xbt_initialized == 0) {
@@ -342,6 +333,12 @@ void EngineImpl::shutdown()
 
 void EngineImpl::seal_platform() const
 {
+  /* Seal only once */
+  static bool sealed = false;
+  if (sealed)
+    return;
+  sealed = true;
+
   /* sealing resources before run: links */
   for (auto const& kv : links_)
     kv.second->get_iface()->seal();
@@ -454,7 +451,11 @@ void EngineImpl::wake_all_waiting_actors() const
  */
 void EngineImpl::run_all_actors()
 {
-  instance_->get_context_factory()->run_all();
+  instance_->get_context_factory()->run_all(actors_to_run_);
+
+  for (auto const& actor : actors_to_run_)
+    if (actor->to_be_freed())
+      actor->cleanup_from_kernel();
 
   actors_to_run_.swap(actors_that_ran_);
   actors_to_run_.clear();
@@ -473,27 +474,6 @@ actor::ActorImpl* EngineImpl::get_actor_by_pid(aid_t pid)
   return nullptr; // Not found, even in the trash
 }
 
-/** Execute all the tasks that are queued, e.g. `.then()` callbacks of futures. */
-bool EngineImpl::execute_tasks()
-{
-  if (tasks.empty())
-    return false;
-
-  std::vector<xbt::Task<void()>> tasksTemp;
-  do {
-    // We don't want the callbacks to modify the vector we are iterating over:
-    tasks.swap(tasksTemp);
-
-    // Execute all the queued tasks:
-    for (auto& task : tasksTemp)
-      task();
-
-    tasksTemp.clear();
-  } while (not tasks.empty());
-
-  return true;
-}
-
 void EngineImpl::remove_daemon(actor::ActorImpl* actor)
 {
   auto it = daemons_.find(actor);
@@ -690,6 +670,15 @@ void EngineImpl::run(double max_date)
 {
   seal_platform();
 
+  if (MC_is_active()) {
+#if SIMGRID_HAVE_MC
+    mc::AppSide::get()->main_loop();
+#else
+    xbt_die("MC_is_active() is not supposed to return true in non-MC settings");
+#endif
+    THROW_IMPOSSIBLE; // main_loop never returns
+  }
+
   if (MC_record_replay_is_active()) {
     mc::RecordTrace::replay(MC_record_path());
     empty_trash();
@@ -712,8 +701,6 @@ void EngineImpl::run(double max_date)
 #endif
     }
 
-    execute_tasks();
-
     while (not actors_to_run_.empty()) {
       XBT_DEBUG("New Sub-Schedule Round; size(queue)=%zu", actors_to_run_.size());
 
@@ -743,16 +730,11 @@ void EngineImpl::run(double max_date)
        *   and would thus be a pure waste of time.
        */
 
-      for (auto const& actor : actors_that_ran_) {
-        if (actor->simcall_.call_ != simix::Simcall::Type::NONE) {
+      for (auto const& actor : actors_that_ran_)
+        if (actor->simcall_.call_ != actor::Simcall::Type::NONE)
           actor->simcall_handle(0);
-        }
-      }
 
-      execute_tasks();
-      do {
-        wake_all_waiting_actors();
-      } while (execute_tasks());
+      wake_all_waiting_actors();
 
       /* If only daemon actors remain, cancel their actions, mark them to die and reschedule them */
       if (actor_list_.size() == daemons_.size())
@@ -779,12 +761,10 @@ void EngineImpl::run(double max_date)
     /* FIXME: iterate through the list of failed host and mark each of them */
     /* as failed. On each host, signal all the running actors with host_fail */
 
-    // Execute timers and tasks until there isn't anything to be done:
+    // Execute timers until there isn't anything to be done:
     bool again = false;
     do {
       again = timer::Timer::execute_all();
-      if (execute_tasks())
-        again = true;
       wake_all_waiting_actors();
     } while (again);