for (auto const& kv : links_)
if (kv.second)
kv.second->destroy();
- actors_to_run_.clear();
- actors_that_ran_.clear();
+
+ /* Free the remaining data structures */
+#if SIMGRID_HAVE_MC
+ xbt_dynar_free(&actors_vector_);
+ xbt_dynar_free(&dead_actors_vector_);
+#endif
}
void EngineImpl::load_deployment(const std::string& file) const
actors_to_run_.clear();
}
+actor::ActorImpl* EngineImpl::get_actor_by_pid(aid_t pid)
+{
+ auto item = actor_list_.find(pid);
+ if (item != actor_list_.end())
+ return item->second;
+
+ // Search the trash
+ for (auto& a : actors_to_destroy_)
+ if (a.get_pid() == pid)
+ return &a;
+ 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()
{
return true;
}
-void EngineImpl::rm_daemon(actor::ActorImpl* actor)
+void EngineImpl::remove_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.");
actors_to_run_.push_back(actor);
}
}
+void EngineImpl::empty_trash()
+{
+ while (not actors_to_destroy_.empty()) {
+ actor::ActorImpl* actor = &actors_to_destroy_.front();
+ actors_to_destroy_.pop_front();
+ XBT_DEBUG("Getting rid of %s (refcount: %d)", actor->get_cname(), actor->get_refcount());
+ intrusive_ptr_release(actor);
+ }
+#if SIMGRID_HAVE_MC
+ xbt_dynar_reset(dead_actors_vector_);
+#endif
+}
+
+void EngineImpl::display_all_actor_status() const
+{
+ XBT_INFO("%zu actors are still running, waiting for something.", actor_list_.size());
+ /* List the actors and their state */
+ XBT_INFO("Legend of the following listing: \"Actor <pid> (<name>@<host>): <status>\"");
+ for (auto const& kv : actor_list_) {
+ actor::ActorImpl* actor = kv.second;
+
+ if (actor->waiting_synchro_) {
+ const char* synchro_description = "unknown";
+
+ if (boost::dynamic_pointer_cast<kernel::activity::ExecImpl>(actor->waiting_synchro_) != nullptr)
+ synchro_description = "execution";
+
+ if (boost::dynamic_pointer_cast<kernel::activity::CommImpl>(actor->waiting_synchro_) != nullptr)
+ synchro_description = "communication";
+
+ if (boost::dynamic_pointer_cast<kernel::activity::SleepImpl>(actor->waiting_synchro_) != nullptr)
+ synchro_description = "sleeping";
+
+ if (boost::dynamic_pointer_cast<kernel::activity::RawImpl>(actor->waiting_synchro_) != nullptr)
+ synchro_description = "synchronization";
+
+ 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(),
+ 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_);
+ } 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()
{
} while (execute_tasks());
/* If only daemon actors remain, cancel their actions, mark them to die and reschedule them */
- if (simix_global->process_list.size() == daemons_.size())
+ if (actor_list_.size() == daemons_.size())
for (auto const& dmon : daemons_) {
XBT_DEBUG("Kill %s", dmon->get_cname());
simix_global->maestro_->kill(dmon);
}
time = timer::Timer::next();
- if (time > -1.0 || not simix_global->process_list.empty()) {
+ if (time > -1.0 || not actor_list_.empty()) {
XBT_DEBUG("Calling surf_solve");
time = surf_solve(time);
XBT_DEBUG("Moving time ahead : %g", time);
} while (again);
/* Clean actors to destroy */
- simix_global->empty_trash();
+ empty_trash();
- XBT_DEBUG("### time %f, #actors %zu, #to_run %zu", time, simix_global->process_list.size(), actors_to_run_.size());
+ XBT_DEBUG("### time %f, #actors %zu, #to_run %zu", time, actor_list_.size(), actors_to_run_.size());
- if (time < 0. && actors_to_run_.empty() && not simix_global->process_list.empty()) {
- if (simix_global->process_list.size() <= daemons_.size()) {
+ if (time < 0. && actors_to_run_.empty() && not actor_list_.empty()) {
+ if (actor_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 {
XBT_CRITICAL("Oops! Deadlock or code not perfectly clean.");
}
- simix_global->display_all_actor_status();
+ display_all_actor_status();
simgrid::s4u::Engine::on_deadlock();
- for (auto const& kv : simix_global->process_list) {
+ for (auto const& kv : actor_list_) {
XBT_DEBUG("Kill %s", kv.second->get_cname());
simix_global->maestro_->kill(kv.second);
}
}
} while (time > -1.0 || has_actors_to_run());
- if (not simix_global->process_list.empty())
+ if (not actor_list_.empty())
THROW_IMPOSSIBLE;
simgrid::s4u::Engine::on_simulation_end();
#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/NetZone.hpp>
#include <simgrid/simix.hpp>
+#include <xbt/dynar.h>
#include <xbt/functional.hpp>
+#include "src/kernel/activity/ExecImpl.hpp"
+#include "src/kernel/activity/IoImpl.hpp"
+#include "src/kernel/activity/MailboxImpl.hpp"
+#include "src/kernel/activity/SleepImpl.hpp"
+#include "src/kernel/activity/SynchroRaw.hpp"
+#include "src/kernel/actor/ActorImpl.hpp"
+
+#include <boost/intrusive/list.hpp>
#include <map>
+#include <mutex>
#include <set>
#include <string>
#include <unordered_map>
+#include <vector>
namespace simgrid {
namespace kernel {
std::set<actor::ActorImpl*> daemons_;
std::vector<actor::ActorImpl*> actors_to_run_;
std::vector<actor::ActorImpl*> actors_that_ran_;
+ std::map<aid_t, actor::ActorImpl*> actor_list_;
+ boost::intrusive::list<actor::ActorImpl,
+ boost::intrusive::member_hook<actor::ActorImpl, boost::intrusive::list_member_hook<>,
+ &actor::ActorImpl::kernel_destroy_list_hook>>
+ actors_to_destroy_;
+#if SIMGRID_HAVE_MC
+ /* MCer cannot read members actor_list_ and actors_to_destroy_ above in the remote process, so we copy the info it
+ * needs in a dynar.
+ * FIXME: This is supposed to be a temporary hack.
+ * A better solution would be to change the split between MCer and MCed, where the responsibility
+ * to compute the list of the enabled transitions goes to the MCed.
+ * That way, the MCer would not need to have the list of actors on its side.
+ * These info could be published by the MCed to the MCer in a way inspired of vd.so
+ */
+ xbt_dynar_t actors_vector_ = xbt_dynar_new(sizeof(actor::ActorImpl*), nullptr);
+ xbt_dynar_t dead_actors_vector_ = xbt_dynar_new(sizeof(actor::ActorImpl*), nullptr);
+#endif
std::vector<xbt::Task<void()>> tasks;
std::vector<xbt::Task<void()>> tasksTemp;
+ std::mutex mutex_;
friend s4u::Engine;
public:
return res->second;
}
void add_daemon(actor::ActorImpl* d) { daemons_.insert(d); }
- void rm_daemon(actor::ActorImpl* d);
- void add_actor_to_run_list(actor::ActorImpl* a);
- void add_actor_to_run_list_no_check(actor::ActorImpl* a);
+ void remove_daemon(actor::ActorImpl* d);
+ void add_actor_to_run_list(actor::ActorImpl* actor);
+ void add_actor_to_run_list_no_check(actor::ActorImpl* actor);
+ void add_actor_to_destroy_list(actor::ActorImpl& actor) { actors_to_destroy_.push_back(actor); }
+
bool has_actors_to_run() { return not actors_to_run_.empty(); }
const actor::ActorImpl* get_first_actor_to_run() const { return actors_to_run_.front(); }
const actor::ActorImpl* get_actor_to_run_at(unsigned long int i) const { return actors_to_run_[i]; }
- unsigned long int get_actor_to_run_count() { return actors_to_run_.size(); }
+ unsigned long int get_actor_to_run_count() const { return actors_to_run_.size(); }
+ size_t get_actor_count() const { return actor_list_.size(); }
+ actor::ActorImpl* get_actor_by_pid(aid_t pid);
+ void add_actor(aid_t pid, actor::ActorImpl* actor) { actor_list_[pid] = actor; }
+ void remove_actor(aid_t pid) { actor_list_.erase(pid); }
+
+#if SIMGRID_HAVE_MC
+ xbt_dynar_t get_actors_vector() const { return actors_vector_; }
+ xbt_dynar_t get_dead_actors_vector() const { return dead_actors_vector_; }
+ void reset_actor_dynar() { xbt_dynar_reset(actors_vector_); }
+ void add_actor_to_dynar(actor::ActorImpl* actor) { xbt_dynar_push_as(actors_vector_, actor::ActorImpl*, actor); }
+ void add_dead_actor_to_dynar(actor::ActorImpl* actor)
+ {
+ xbt_dynar_push_as(dead_actors_vector_, actor::ActorImpl*, actor);
+ }
+#endif
+ const std::map<aid_t, actor::ActorImpl*>& get_actor_list() const { return actor_list_; }
const std::vector<actor::ActorImpl*>& get_actors_to_run() const { return actors_to_run_; }
const std::vector<actor::ActorImpl*>& get_actors_that_ran() const { return actors_that_ran_; }
+ std::mutex& get_mutex() { return mutex_; }
bool execute_tasks();
void add_task(xbt::Task<void()>&& t) { tasks.push_back(std::move(t)); }
void wake_all_waiting_actors() const;
+ /**
+ * Garbage collection
+ *
+ * Should be called some time to time to free the memory allocated for actors that have finished (or killed).
+ */
+ void empty_trash();
void display_all_actor_status() const;
void run_all_actors();
}
ActorImpl* ActorImpl::by_pid(aid_t pid)
{
- auto item = simix_global->process_list.find(pid);
- if (item != simix_global->process_list.end())
- return item->second;
-
- // Search the trash
- for (auto& a : simix_global->actors_to_destroy)
- if (a.get_pid() == pid)
- return &a;
- return nullptr; // Not found, even in the trash
+ return EngineImpl::get_instance()->get_actor_by_pid(pid);
}
ActorImpl* ActorImpl::self()
ActorImplPtr ActorImpl::attach(const std::string& name, void* data, s4u::Host* host)
{
// This is mostly a copy/paste from create(), it'd be nice to share some code between those two functions.
-
+ auto* engine = EngineImpl::get_instance();
XBT_DEBUG("Attach actor %s on host '%s'", name.c_str(), host->get_cname());
if (not host->is_on()) {
host->get_impl()->add_actor(actor);
/* Now insert it in the global actor list and in the actors to run list */
- simix_global->process_list[actor->get_pid()] = actor;
- EngineImpl::get_instance()->add_actor_to_run_list_no_check(actor);
+ engine->add_actor(actor->get_pid(), actor);
+ engine->add_actor_to_run_list_no_check(actor);
intrusive_ptr_add_ref(actor);
auto* context = dynamic_cast<context::AttachContext*>(actor->context_.get());
void ActorImpl::cleanup_from_simix()
{
- const std::lock_guard<std::mutex> lock(simix_global->mutex);
- simix_global->process_list.erase(pid_);
+ auto* engine = EngineImpl::get_instance();
+ const std::lock_guard<std::mutex> lock(engine->get_mutex());
+ engine->remove_actor(pid_);
if (host_ && host_actor_list_hook.is_linked())
host_->get_impl()->remove_actor(this);
- if (not smx_destroy_list_hook.is_linked()) {
+ if (not kernel_destroy_list_hook.is_linked()) {
#if SIMGRID_HAVE_MC
- xbt_dynar_push_as(simix_global->dead_actors_vector, ActorImpl*, this);
+ engine->add_dead_actor_to_dynar(this);
#endif
- simix_global->actors_to_destroy.push_back(*this);
+ engine->add_actor_to_destroy_list(*this);
}
}
void ActorImpl::kill_all() const
{
- for (auto const& kv : simix_global->process_list)
+ for (auto const& kv : EngineImpl::get_instance()->get_actor_list())
if (kv.second != this)
this->kill(kv.second);
}
{
if (daemon_) {
daemon_ = false;
- EngineImpl::get_instance()->rm_daemon(this);
+ EngineImpl::get_instance()->remove_daemon(this);
}
}
ActorImpl* ActorImpl::start(const ActorCode& code)
{
xbt_assert(code && host_ != nullptr, "Invalid parameters");
+ auto* engine = EngineImpl::get_instance();
if (not host_->is_on()) {
XBT_WARN("Cannot launch actor '%s' on failed host '%s'", name_.c_str(), host_->get_cname());
/* Add the actor to its host's actor list */
host_->get_impl()->add_actor(this);
- simix_global->process_list[pid_] = this;
+ engine->add_actor(pid_, this);
/* Now insert it in the global actor list and in the actor to run list */
- EngineImpl::get_instance()->add_actor_to_run_list_no_check(this);
+ engine->add_actor_to_run_list_no_check(this);
return this;
}
int SIMIX_process_count() // XBT_ATTRIB_DEPRECATED_v329
{
- return simix_global->process_list.size();
+ return simgrid::kernel::EngineImpl::get_instance()->get_actor_list().size();
}
void* SIMIX_process_self_get_data() // XBT_ATTRIB_DEPRECATED_v329
double get_kill_time() const;
void set_kill_time(double kill_time);
boost::intrusive::list_member_hook<> host_actor_list_hook; /* simgrid::surf::HostImpl::actor_list_ */
- boost::intrusive::list_member_hook<> smx_destroy_list_hook; /* simix_global->actors_to_destroy */
+ boost::intrusive::list_member_hook<> kernel_destroy_list_hook; /* EngineImpl actors_to_destroy */
boost::intrusive::list_member_hook<> smx_synchro_hook; /* {mutex,cond,sem}->sleeping */
const xbt::string& get_name() const { return name_; }
}
}
#if SIMGRID_HAVE_MC
- xbt_dynar_reset(simix_global->actors_vector);
- for (std::pair<const aid_t, smx_actor_t> const& kv : simix_global->process_list) {
+ engine->reset_actor_dynar();
+ for (auto const& kv : engine->get_actor_list()) {
auto actor = kv.second;
if (actor->simcall_.observer_ != nullptr)
actor->simcall_.mc_max_consider_ = actor->simcall_.observer_->get_max_consider();
- xbt_dynar_push_as(simix_global->actors_vector, smx_actor_t, actor);
+ engine->add_actor_to_dynar(actor);
}
#endif
}
* This is implemented by:
*
* - `model_checker->process.smx_process_infos`
- * (copy of `simix_global->process_list`);
+ * (copy of `EngineImpl::actor_list_`);
*
* - `model_checker->process.smx_old_process_infos`
- * (copy of `simix_global->actors_to_destroy`);
+ * (copy of `EngineImpl::actors_to_destroy_`);
*
* - `model_checker->hostnames`.
*
#include "src/mc/remote/AppSide.hpp"
#include "src/internal_config.h"
+#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/actor/ActorImpl.hpp"
#include "src/kernel/actor/SimcallObserver.hpp"
#include "src/mc/mc_base.hpp"
xbt_assert(errno == 0 && raise(SIGSTOP) == 0, "Could not wait for the model-checker (errno = %d: %s)", errno,
strerror(errno));
- s_mc_message_initial_addresses_t message{
- MessageType::INITIAL_ADDRESSES, mmalloc_preinit(), simgrid::kernel::actor::get_maxpid_addr(),
- simgrid::simix::simix_global_get_actors_addr(), simgrid::simix::simix_global_get_dead_actors_addr()};
+ s_mc_message_initial_addresses_t message{MessageType::INITIAL_ADDRESSES, mmalloc_preinit(),
+ kernel::actor::get_maxpid_addr(), simix::simix_global_get_actors_addr(),
+ simix::simix_global_get_dead_actors_addr()};
xbt_assert(instance_->channel_.send(message) == 0, "Could not send the initial message with addresses.");
instance_->handle_messages();
void AppSide::handle_deadlock_check(const s_mc_message_t*) const
{
+ const auto& actor_list = kernel::EngineImpl::get_instance()->get_actor_list();
bool deadlock = false;
- if (not simix_global->process_list.empty()) {
+ if (not actor_list.empty()) {
deadlock = true;
- for (auto const& kv : simix_global->process_list)
- if (simgrid::mc::actor_is_enabled(kv.second)) {
+ for (auto const& kv : actor_list)
+ if (mc::actor_is_enabled(kv.second)) {
deadlock = false;
break;
}
void AppSide::handle_actor_enabled(const s_mc_message_actor_enabled_t* msg) const
{
- bool res = simgrid::mc::actor_is_enabled(kernel::actor::ActorImpl::by_pid(msg->aid));
+ bool res = mc::actor_is_enabled(kernel::actor::ActorImpl::by_pid(msg->aid));
s_mc_message_int_t answer{MessageType::ACTOR_ENABLED_REPLY, res};
channel_.send(answer);
}
XBT_DEBUG("Finalize (terminate = %d)", (int)terminate_asap);
if (not terminate_asap) {
if (XBT_LOG_ISENABLED(mc_client, xbt_log_priority_debug))
- simix_global->display_all_actor_status();
+ kernel::EngineImpl::get_instance()->display_all_actor_status();
#if HAVE_SMPI
XBT_DEBUG("Smpi_enabled: %d", (int)smpi_enabled());
if (smpi_enabled())
std::vector<s_stack_region_t> stack_areas_;
std::vector<IgnoredHeapRegion> ignored_heap_;
-public:
- // object info
- // TODO, make private (first, objectify simgrid::mc::ObjectInformation*)
- std::vector<std::shared_ptr<ObjectInformation>> object_infos;
- std::shared_ptr<ObjectInformation> binary_info;
-
// Copies of MCed SMX data structures
- /** Copy of `simix_global->process_list`
+ /** Copy of `EngineImpl::actor_list_`
*
- * See mc_smx.c.
+ * See mc_smx.cpp.
*/
std::vector<ActorInformation> smx_actors_infos;
- /** Copy of `simix_global->actors_to_destroy`
+ /** Copy of `EngineImpl::actors_to_destroy_`
*
- * See mc_smx.c.
+ * See mc_smx.cpp.
*/
std::vector<ActorInformation> smx_dead_actors_infos;
-private:
/** State of the cache (which variables are up to date) */
int cache_flags_ = RemoteProcess::cache_none;
public:
+ // object info
+ // TODO, make private (first, objectify simgrid::mc::ObjectInformation*)
+ std::vector<std::shared_ptr<ObjectInformation>> object_infos;
+ std::shared_ptr<ObjectInformation> binary_info;
+
/** Address of the heap structure in the MCed process. */
RemotePtr<s_xbt_mheap_t> heap_address;
#include "msg_private.hpp"
#include "simgrid/Exception.hpp"
#include "simgrid/s4u/Host.hpp"
-#include "src/simix/smx_private.hpp"
+#include "src/kernel/EngineImpl.hpp"
/******************************** Process ************************************/
/** @brief Creates and runs a new #msg_process_t.
xbt_dynar_t MSG_processes_as_dynar() // XBT_ATTRIB_DEPRECATED_v330
{
xbt_dynar_t res = xbt_dynar_new(sizeof(smx_actor_t), nullptr);
- for (auto const& kv : simix_global->process_list) {
+ for (auto const& kv : simgrid::kernel::EngineImpl::get_instance()->get_actor_list()) {
smx_actor_t actor = kv.second;
xbt_dynar_push(res, &actor);
}
#include "simgrid/simix.h"
#include "src/instr/instr_private.hpp"
#include "src/kernel/EngineImpl.hpp"
-#include "src/simix/smx_private.hpp" // For access to simix_global->process_list
#include "src/surf/network_interface.hpp"
#include "surf/surf.hpp" // routing_platf. FIXME:KILLME. SOON
#include <simgrid/Exception.hpp>
void Engine::initialize(int* argc, char** argv)
{
xbt_assert(Engine::instance_ == nullptr, "It is currently forbidden to create more than one instance of s4u::Engine");
+ Engine::instance_ = this;
instr::init();
SIMIX_global_init(argc, argv);
- Engine::instance_ = this;
}
Engine::Engine(std::string name) : pimpl(new kernel::EngineImpl())
size_t Engine::get_actor_count() const
{
- return simix_global->process_list.size();
+ return pimpl->get_actor_count();
}
std::vector<ActorPtr> Engine::get_all_actors() const
{
std::vector<ActorPtr> actor_list;
- for (auto const& kv : simix_global->process_list) {
+ for (auto const& kv : pimpl->get_actor_list()) {
actor_list.push_back(kv.second->get_iface());
}
return actor_list;
std::vector<ActorPtr> Engine::get_filtered_actors(const std::function<bool(ActorPtr)>& filter) const
{
std::vector<ActorPtr> actor_list;
- for (auto const& kv : simix_global->process_list) {
+ for (auto const& kv : pimpl->get_actor_list()) {
if (filter(kv.second->get_iface()))
actor_list.push_back(kv.second->get_iface());
}
#include "simgrid/sg_config.hpp"
#include "src/kernel/EngineImpl.hpp"
-#include "src/kernel/activity/ExecImpl.hpp"
-#include "src/kernel/activity/IoImpl.hpp"
-#include "src/kernel/activity/MailboxImpl.hpp"
-#include "src/kernel/activity/SleepImpl.hpp"
-#include "src/kernel/activity/SynchroRaw.hpp"
#include "src/mc/mc_record.hpp"
#include "src/mc/mc_replay.hpp"
#include "src/simix/smx_private.hpp"
xbt_dynar_t simix_global_get_actors_addr()
{
#if SIMGRID_HAVE_MC
- return simix_global->actors_vector;
+ return kernel::EngineImpl::get_instance()->get_actors_vector();
#else
xbt_die("This function is intended to be used when compiling with MC");
#endif
xbt_dynar_t simix_global_get_dead_actors_addr()
{
#if SIMGRID_HAVE_MC
- return simix_global->dead_actors_vector;
+ return kernel::EngineImpl::get_instance()->get_dead_actors_vector();
#else
xbt_die("This function is intended to be used when compiling with MC");
#endif
if (simgrid::simix::cfg_verbose_exit) {
XBT_INFO("CTRL-C pressed. The current status will be displayed before exit (disable that behavior with option "
"'debug/verbose-exit').");
- simix_global->display_all_actor_status();
+ simgrid::kernel::EngineImpl::get_instance()->display_all_actor_status();
} else {
XBT_INFO("CTRL-C pressed, exiting. Hiding the current process status since 'debug/verbose-exit' is set to false.");
}
namespace simgrid {
namespace simix {
-void Global::empty_trash()
-{
- while (not actors_to_destroy.empty()) {
- kernel::actor::ActorImpl* actor = &actors_to_destroy.front();
- actors_to_destroy.pop_front();
- XBT_DEBUG("Getting rid of %s (refcount: %d)", actor->get_cname(), actor->get_refcount());
- intrusive_ptr_release(actor);
- }
-#if SIMGRID_HAVE_MC
- xbt_dynar_reset(dead_actors_vector);
-#endif
-}
-
-void Global::display_all_actor_status() const
-{
- XBT_INFO("%zu actors are still running, waiting for something.", process_list.size());
- /* List the actors and their state */
- XBT_INFO("Legend of the following listing: \"Actor <pid> (<name>@<host>): <status>\"");
- for (auto const& kv : process_list) {
- kernel::actor::ActorImpl* actor = kv.second;
-
- if (actor->waiting_synchro_) {
- const char* synchro_description = "unknown";
-
- if (boost::dynamic_pointer_cast<kernel::activity::ExecImpl>(actor->waiting_synchro_) != nullptr)
- synchro_description = "execution";
-
- if (boost::dynamic_pointer_cast<kernel::activity::CommImpl>(actor->waiting_synchro_) != nullptr)
- synchro_description = "communication";
-
- if (boost::dynamic_pointer_cast<kernel::activity::SleepImpl>(actor->waiting_synchro_) != nullptr)
- synchro_description = "sleeping";
-
- if (boost::dynamic_pointer_cast<kernel::activity::RawImpl>(actor->waiting_synchro_) != nullptr)
- synchro_description = "synchronization";
-
- 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(),
- 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_);
- } 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_));
- }
- }
-}
} // namespace simix
} // namespace simgrid
}
#if HAVE_SMPI
- if (not simix_global->process_list.empty()) {
+ if (not engine->get_actor_list().empty()) {
if (smpi_process()->initialized()) {
xbt_die("Process exited without calling MPI_Finalize - Killing simulation");
} else {
/* Kill all processes (but maestro) */
simix_global->maestro_->kill_all();
engine->run_all_actors();
- simix_global->empty_trash();
+ engine->empty_trash();
/* Exit the SIMIX network module */
SIMIX_mailbox_exit();
delete simgrid::kernel::timer::kernel_timers().top().second;
simgrid::kernel::timer::kernel_timers().pop();
}
- /* Free the remaining data structures */
- simix_global->actors_to_destroy.clear();
- simix_global->process_list.clear();
-
-#if SIMGRID_HAVE_MC
- xbt_dynar_free(&simix_global->actors_vector);
- xbt_dynar_free(&simix_global->dead_actors_vector);
-#endif
/* Let's free maestro now */
delete simix_global->maestro_;
void SIMIX_display_process_status() // XBT_ATTRIB_DEPRECATED_v329
{
- simix_global->display_all_actor_status();
+ simgrid::kernel::EngineImpl::get_instance()->display_all_actor_status();
}
int SIMIX_is_maestro()
#include "src/kernel/actor/ActorImpl.hpp"
#include "src/kernel/context/Context.hpp"
-#include <boost/intrusive/list.hpp>
-#include <mutex>
-#include <unordered_map>
-#include <vector>
-
/********************************** Simix Global ******************************/
namespace simgrid {
class Global {
public:
- /**
- * Garbage collection
- *
- * Should be called some time to time to free the memory allocated for actors that have finished (or killed).
- */
- void empty_trash();
- void display_all_actor_status() const;
kernel::context::ContextFactory* context_factory = nullptr;
- std::map<aid_t, kernel::actor::ActorImpl*> process_list;
- boost::intrusive::list<kernel::actor::ActorImpl,
- boost::intrusive::member_hook<kernel::actor::ActorImpl, boost::intrusive::list_member_hook<>,
- &kernel::actor::ActorImpl::smx_destroy_list_hook>>
- actors_to_destroy;
-#if SIMGRID_HAVE_MC
- /* MCer cannot read members process_list and actors_to_destroy above in the remote process, so we copy the info it
- * needs in a dynar.
- * FIXME: This is supposed to be a temporary hack.
- * A better solution would be to change the split between MCer and MCed, where the responsibility
- * to compute the list of the enabled transitions goes to the MCed.
- * That way, the MCer would not need to have the list of actors on its side.
- * These info could be published by the MCed to the MCer in a way inspired of vd.so
- */
- xbt_dynar_t actors_vector = xbt_dynar_new(sizeof(kernel::actor::ActorImpl*), nullptr);
- xbt_dynar_t dead_actors_vector = xbt_dynar_new(sizeof(kernel::actor::ActorImpl*), nullptr);
-#endif
kernel::actor::ActorImpl* maestro_ = nullptr;
- std::mutex mutex;
};
}
}
#include "simgrid/kernel/routing/NetPoint.hpp"
#include "simgrid/s4u/Engine.hpp"
#include "simgrid/s4u/Host.hpp"
+#include "src/kernel/EngineImpl.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
-#include "src/simix/smx_private.hpp"
#include <string>
for (auto const& actor : actor_list_)
msg += "\n\t" + std::string(actor.get_name());
- simix_global->display_all_actor_status();
+ kernel::EngineImpl::get_instance()->display_all_actor_status();
xbt_die("%s", msg.c_str());
}
for (auto const& arg : actors_at_boot_)