-/* Copyright (c) 2016-2021. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2016-2022. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "mc/mc.h"
#include "src/kernel/EngineImpl.hpp"
+#include "src/kernel/resource/StandardLinkImpl.hpp"
#include "src/kernel/resource/profile/Profile.hpp"
#include "src/mc/mc_record.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/smpi/include/smpi_actor.hpp"
-#include "src/surf/network_interface.hpp"
#include "src/surf/xml/platf.hpp"
-#include "xbt/xbt_modinter.h" /* whether initialization was already done */
+#include "xbt/xbt_modinter.h" /* whether initialization was already done */
#include <boost/algorithm/string/predicate.hpp>
#ifndef _WIN32
/* register a function to be called by SURF after the environment creation */
sg_platf_init();
- s4u::Engine::on_platform_created.connect([this]() { this->presolve(); });
+ s4u::Engine::on_platform_created_cb([this]() { this->presolve(); });
if (config::get_value<bool>("debug/clean-atexit"))
atexit(shutdown);
instance_->empty_trash();
/* Let's free maestro now */
- instance_->destroy_maestro();
+ delete instance_->maestro_;
+ instance_->maestro_ = nullptr;
/* Finish context module and SURF */
instance_->destroy_context_factory();
instance_ = nullptr;
}
+void EngineImpl::seal_platform() const
+{
+ /* sealing resources before run: links */
+ for (auto const& kv : links_)
+ kv.second->get_iface()->seal();
+ /* seal netzone root, recursively seal children netzones, hosts and disks */
+ netzone_root_->seal();
+}
+
void EngineImpl::load_platform(const std::string& platf)
{
double start = xbt_os_time();
XBT_DEBUG("Handling the failed actions (if any)");
while (auto* action = model->extract_failed_action()) {
XBT_DEBUG(" Handling Action %p", action);
- if (action->get_activity() != nullptr)
+ if (action->get_activity() != nullptr) {
+ // If nobody told the interface that the activity has failed, that's because no actor waits on it (maestro
+ // started it). SimDAG I see you!
+ if (action->get_activity()->get_actor() == maestro_)
+ action->get_activity()->get_iface()->complete(s4u::Activity::State::FAILED);
+
activity::ActivityImplPtr(action->get_activity())->post();
+ }
}
XBT_DEBUG("Handling the terminated actions (if any)");
while (auto* action = model->extract_done_action()) {
XBT_DEBUG(" Handling Action %p", action);
if (action->get_activity() == nullptr)
XBT_DEBUG("probably vcpu's action %p, skip", action);
- else
+ else {
+ // If nobody told the interface that the activity is finished, that's because no actor waits on it (maestro
+ // started it). SimDAG I see you!
+ action->get_activity()->set_finish_time(action->get_finish_time());
+
+ if (action->get_activity()->get_actor() == maestro_)
+ action->get_activity()->get_iface()->complete(s4u::Activity::State::FINISHED);
+
activity::ActivityImplPtr(action->get_activity())->post();
+ }
}
}
}
if (boost::dynamic_pointer_cast<kernel::activity::IoImpl>(actor->waiting_synchro_) != nullptr)
synchro_description = "I/O";
- XBT_INFO("Actor %ld (%s@%s): waiting for %s activity %#zx (%s) in state %d to finish", actor->get_pid(),
+ XBT_INFO("Actor %ld (%s@%s): waiting for %s activity %#zx (%s) in state %s to finish", actor->get_pid(),
actor->get_cname(), actor->get_host()->get_cname(), synchro_description,
(xbt_log_no_loc ? (size_t)0xDEADBEEF : (size_t)actor->waiting_synchro_.get()),
- actor->waiting_synchro_->get_cname(), (int)actor->waiting_synchro_->state_);
+ actor->waiting_synchro_->get_cname(), actor->waiting_synchro_->get_state_str());
} else {
XBT_INFO("Actor %ld (%s@%s) simcall %s", actor->get_pid(), actor->get_cname(), actor->get_host()->get_cname(),
SIMIX_simcall_name(actor->simcall_));
void EngineImpl::run(double max_date)
{
+ seal_platform();
+
if (MC_record_replay_is_active()) {
mc::replay(MC_record_path());
empty_trash();
}
double elapsed_time = -1;
+ const std::set<s4u::Activity*>* vetoed_activities = s4u::Activity::get_vetoed_activities();
do {
XBT_DEBUG("New Schedule Round; size(queue)=%zu", actors_to_run_.size());
next_time = std::min(next_time, max_date);
}
- if (next_time > -1.0 || not actor_list_.empty()) {
- XBT_DEBUG("Calling solve(%g) %g", next_time, NOW);
- elapsed_time = solve(next_time);
- XBT_DEBUG("Moving time ahead. NOW=%g; elapsed: %g", NOW, elapsed_time);
- } else {
- elapsed_time = -1;
- }
+ XBT_DEBUG("Calling solve(%g) %g", next_time, NOW);
+ elapsed_time = solve(next_time);
+ XBT_DEBUG("Moving time ahead. NOW=%g; elapsed: %g", NOW, elapsed_time);
/* Notify all the hosts that have failed */
/* FIXME: iterate through the list of failed host and mark each of them */
/* Clean actors to destroy */
empty_trash();
- XBT_DEBUG("### elapsed time %f, #actors %zu, #to_run %zu", elapsed_time, actor_list_.size(), actors_to_run_.size());
+ XBT_DEBUG("### elapsed time %f, #actors %zu, #to_run %zu, #vetoed %d", elapsed_time, actor_list_.size(),
+ actors_to_run_.size(), (vetoed_activities == nullptr ? -1 : static_cast<int>(vetoed_activities->size())));
if (elapsed_time < 0. && actors_to_run_.empty() && not actor_list_.empty()) {
if (actor_list_.size() <= daemons_.size()) {
maestro_->kill(kv.second);
}
}
- } while ((elapsed_time > -1.0 && not double_equals(max_date, NOW, 0.00001)) || has_actors_to_run());
+ } while ((vetoed_activities == nullptr || vetoed_activities->empty()) &&
+ ((elapsed_time > -1.0 && not double_equals(max_date, NOW, 0.00001)) || has_actors_to_run()));
- if (not actor_list_.empty() && max_date < 0)
+ if (not actor_list_.empty() && max_date < 0 && not(vetoed_activities == nullptr || vetoed_activities->empty()))
THROW_IMPOSSIBLE;
simgrid::s4u::Engine::on_simulation_end();