#include <simgrid/s4u/Host.hpp>
#include <simgrid/sg_config.hpp>
+#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v332)
+#include <simgrid/simix.h>
+
#include "mc/mc.h"
#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/resource/StandardLinkImpl.hpp"
"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},
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) {
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();
*/
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();
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);
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_));
+ actor->simcall_.get_cname());
}
}
}
{
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();
#endif
}
- execute_tasks();
-
while (not actors_to_run_.empty()) {
XBT_DEBUG("New Sub-Schedule Round; size(queue)=%zu", actors_to_run_.size());
* and would thus be a pure waste of time.
*/
- for (auto const& actor : actors_that_ran_) {
- if (actor->simcall_.call_ != simix::Simcall::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())
/* 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);