X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/1c3328f8047e2e5602ed3cd87044ce274e9ff978..3a2e010df11371c99e2cbe15ed44f63e50863535:/src/kernel/EngineImpl.cpp diff --git a/src/kernel/EngineImpl.cpp b/src/kernel/EngineImpl.cpp index 1e2c129a2b..f2ce40346a 100644 --- a/src/kernel/EngineImpl.cpp +++ b/src/kernel/EngineImpl.cpp @@ -41,6 +41,8 @@ EngineImpl::~EngineImpl() for (auto const& kv : links_) if (kv.second) kv.second->destroy(); + actors_to_run_.clear(); + actors_that_ran_.clear(); } void EngineImpl::load_deployment(const std::string& file) const @@ -96,6 +98,20 @@ void EngineImpl::wake_all_waiting_actors() const } } } +/** + * @brief Executes the actors in actors_to_run. + * + * The actors in actors_to_run are run (in parallel if possible). On exit, actors_to_run is empty, and actors_that_ran + * contains the list of actors that just ran. The two lists are swapped so, be careful when using them before and after + * a call to this function. + */ +void EngineImpl::run_all_actors() +{ + simix_global->context_factory->run_all(); + + actors_to_run_.swap(actors_that_ran_); + actors_to_run_.clear(); +} /** Execute all the tasks that are queued, e.g. `.then()` callbacks of futures. */ bool EngineImpl::execute_tasks() @@ -119,6 +135,29 @@ bool EngineImpl::execute_tasks() return true; } +void EngineImpl::rm_daemon(actor::ActorImpl* actor) +{ + auto it = daemons_.find(actor); + xbt_assert(it != daemons_.end(), "The dying daemon is not a daemon after all. Please report that bug."); + daemons_.erase(it); +} + +void EngineImpl::add_actor_to_run_list_no_check(actor::ActorImpl* actor) +{ + XBT_DEBUG("Inserting [%p] %s(%s) in the to_run list", actor, actor->get_cname(), actor->get_host()->get_cname()); + actors_to_run_.push_back(actor); +} + +void EngineImpl::add_actor_to_run_list(actor::ActorImpl* actor) +{ + if (std::find(begin(actors_to_run_), end(actors_to_run_), actor) != end(actors_to_run_)) { + XBT_DEBUG("Actor %s is already in the to_run list", actor->get_cname()); + } else { + XBT_DEBUG("Inserting [%p] %s(%s) in the to_run list", actor, actor->get_cname(), actor->get_host()->get_cname()); + actors_to_run_.push_back(actor); + } +} + void EngineImpl::run() { if (MC_record_replay_is_active()) { @@ -129,7 +168,7 @@ void EngineImpl::run() double time = 0; do { - XBT_DEBUG("New Schedule Round; size(queue)=%zu", simix_global->actors_to_run.size()); + XBT_DEBUG("New Schedule Round; size(queue)=%zu", actors_to_run_.size()); if (cfg_breakpoint >= 0.0 && surf_get_clock() >= cfg_breakpoint) { XBT_DEBUG("Breakpoint reached (%g)", cfg_breakpoint.get()); @@ -143,11 +182,11 @@ void EngineImpl::run() execute_tasks(); - while (not simix_global->actors_to_run.empty()) { - XBT_DEBUG("New Sub-Schedule Round; size(queue)=%zu", simix_global->actors_to_run.size()); + while (not actors_to_run_.empty()) { + XBT_DEBUG("New Sub-Schedule Round; size(queue)=%zu", actors_to_run_.size()); - /* Run all processes that are ready to run, possibly in parallel */ - simix_global->run_all_actors(); + /* Run all actors that are ready to run, possibly in parallel */ + run_all_actors(); /* answer sequentially and in a fixed arbitrary order all the simcalls that were issued during that sub-round */ @@ -211,7 +250,7 @@ void EngineImpl::run() * That would thus be a pure waste of time. */ - for (auto const& actor : simix_global->actors_that_ran) { + for (auto const& actor : actors_that_ran_) { if (actor->simcall_.call_ != simix::Simcall::NONE) { actor->simcall_handle(0); } @@ -222,9 +261,9 @@ void EngineImpl::run() wake_all_waiting_actors(); } while (execute_tasks()); - /* If only daemon processes remain, cancel their actions, mark them to die and reschedule them */ - if (simix_global->process_list.size() == simix_global->daemons.size()) - for (auto const& dmon : simix_global->daemons) { + /* If only daemon actors remain, cancel their actions, mark them to die and reschedule them */ + if (simix_global->process_list.size() == daemons_.size()) + for (auto const& dmon : daemons_) { XBT_DEBUG("Kill %s", dmon->get_cname()); simix_global->maestro_->kill(dmon); } @@ -239,7 +278,7 @@ void EngineImpl::run() /* Notify all the hosts that have failed */ /* FIXME: iterate through the list of failed host and mark each of them */ - /* as failed. On each host, signal all the running processes with host_fail */ + /* 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: bool again = false; @@ -253,11 +292,10 @@ void EngineImpl::run() /* Clean actors to destroy */ simix_global->empty_trash(); - 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, #actors %zu, #to_run %zu", time, simix_global->process_list.size(), actors_to_run_.size()); - 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()) { + if (time < 0. && actors_to_run_.empty() && not simix_global->process_list.empty()) { + if (simix_global->process_list.size() <= 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 { @@ -270,7 +308,7 @@ void EngineImpl::run() simix_global->maestro_->kill(kv.second); } } - } while (time > -1.0 || not simix_global->actors_to_run.empty()); + } while (time > -1.0 || has_actors_to_run()); if (not simix_global->process_list.empty()) THROW_IMPOSSIBLE;