void (*SMPI_switch_data_segment)(simgrid::s4u::ActorPtr) = nullptr;
-bool _sg_do_verbose_exit = true;
-static void inthandler(int)
+namespace simgrid {
+namespace simix {
+simgrid::config::Flag<double> cfg_verbose_exit{
+ "debug/verbose-exit", {"verbose-exit"}, "Display the actor status at exit", true};
+}
+} // namespace simgrid
+XBT_ATTRIB_NORETURN static void inthandler(int)
{
- if ( _sg_do_verbose_exit ) {
- XBT_INFO("CTRL-C pressed. The current status will be displayed before exit (disable that behavior with option 'verbose-exit').");
- SIMIX_display_process_status();
+ 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_display_process_status();
}
else {
- XBT_INFO("CTRL-C pressed, exiting. Hiding the current process status since 'verbose-exit' is set to false.");
+ XBT_INFO("CTRL-C pressed, exiting. Hiding the current process status since 'debug/verbose-exit' is set to false.");
}
exit(1);
}
namespace simgrid {
namespace simix {
-Timer* Timer::set(double date, void (*callback)(void*), void* arg)
-{
- Timer* timer = new Timer(date, simgrid::xbt::make_task([callback, arg]() { callback(arg); }));
- timer->handle_ = simix_timers.emplace(std::make_pair(date, timer));
- return timer;
-}
-
-Timer* Timer::set(double date, simgrid::xbt::Task<void()> callback)
+Timer* Timer::set(double date, simgrid::xbt::Task<void()>&& callback)
{
Timer* timer = new Timer(date, std::move(callback));
timer->handle_ = simix_timers.emplace(std::make_pair(date, timer));
delete this;
}
+/** Execute all the tasks that are queued, e.g. `.then()` callbacks of futures. */
+bool Global::execute_tasks()
+{
+ xbt_assert(tasksTemp.empty());
+
+ if (tasks.empty())
+ return false;
+
+ 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 Global::empty_trash()
{
while (not actors_to_destroy.empty()) {
intrusive_ptr_release(actor);
}
#if SIMGRID_HAVE_MC
- xbt_dynar_reset(simix_global->dead_actors_vector);
+ xbt_dynar_reset(dead_actors_vector);
#endif
}
/**
- * @brief Executes the actors in simix_global->actors_to_run.
+ * @brief Executes the actors in actors_to_run.
*
- * The actors in simix_global->actors_to_run are run (in parallel if possible). On exit, simix_global->actors_to_run
- * is empty, and simix_global->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.
+ * 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 Global::run_all_actors()
{
SIMIX_context_runall();
- simix_global->actors_to_run.swap(simix_global->actors_that_ran);
- simix_global->actors_to_run.clear();
+ actors_to_run.swap(actors_that_ran);
+ actors_to_run.clear();
}
-simgrid::config::Flag<double> breakpoint{"simix/breakpoint",
- "When non-negative, raise a SIGTRAP after given (simulated) time", -1.0};
+simgrid::config::Flag<double> cfg_breakpoint{
+ "debug/breakpoint", {"simix/breakpoint"}, "When non-negative, raise a SIGTRAP after given (simulated) time", -1.0};
}
}
#endif
if (simix_global == nullptr) {
- simix_global = std::unique_ptr<simgrid::simix::Global>(new simgrid::simix::Global());
- simix_global->maestro_process = nullptr;
+ surf_init(argc, argv); /* Initialize SURF structures */
- surf_init(argc, argv); /* Initialize SURF structures */
+ simix_global.reset(new simgrid::simix::Global());
+ simix_global->maestro_process = nullptr;
SIMIX_context_mod_init();
// Either create a new context with maestro or create
sg_platf_init();
simgrid::s4u::on_platform_created.connect(surf_presolve);
- simgrid::s4u::Storage::on_creation.connect([](simgrid::s4u::Storage& storage) {
+ simgrid::s4u::Storage::on_creation.connect([](simgrid::s4u::Storage const& storage) {
sg_storage_t s = simgrid::s4u::Storage::by_name(storage.get_name());
xbt_assert(s != nullptr, "Storage not found for name %s", storage.get_cname());
});
}
- if (simgrid::config::get_value<bool>("clean-atexit"))
+ if (simgrid::config::get_value<bool>("debug/clean-atexit"))
atexit(SIMIX_clean);
-
- if (_sg_cfg_exit_asap)
- exit(0);
}
int smx_cleaned = 0;
#endif
/* Let's free maestro now */
- delete simix_global->maestro_process->context_;
- simix_global->maestro_process->context_ = nullptr;
delete simix_global->maestro_process;
simix_global->maestro_process = nullptr;
XBT_DEBUG("Handling the processes whose action failed (if any)");
while ((action = model->extract_failed_action())) {
XBT_DEBUG(" Handling Action %p",action);
- SIMIX_simcall_exit(static_cast<simgrid::kernel::activity::ActivityImpl*>(action->get_data()));
+ if (action->get_activity() != nullptr)
+ simgrid::kernel::activity::ActivityImplPtr(action->get_activity())->post();
}
XBT_DEBUG("Handling the processes whose action terminated normally (if any)");
while ((action = model->extract_done_action())) {
XBT_DEBUG(" Handling Action %p",action);
- if (action->get_data() == nullptr)
+ if (action->get_activity() == nullptr)
XBT_DEBUG("probably vcpu's action %p, skip", action);
else
- SIMIX_simcall_exit(static_cast<simgrid::kernel::activity::ActivityImpl*>(action->get_data()));
+ simgrid::kernel::activity::ActivityImplPtr(action->get_activity())->post();
}
}
}
// FIXME: make the timers being real callbacks (i.e. provide dispatchers that read and expand the args)
smx_timer_t timer = simgrid::simix::simix_timers.top().second;
simgrid::simix::simix_timers.pop();
- try {
- timer->callback();
- } catch (...) {
- xbt_die("Exception thrown ouf of timer callback");
- }
+ timer->callback();
delete timer;
}
return result;
}
-/** Execute all the tasks that are queued
- *
- * e.g. `.then()` callbacks of futures.
- **/
-static bool SIMIX_execute_tasks()
-{
- xbt_assert(simix_global->tasksTemp.empty());
-
- if (simix_global->tasks.empty())
- return false;
-
- do {
- // We don't want the callbacks to modify the vector we are iterating over:
- simix_global->tasks.swap(simix_global->tasksTemp);
-
- // Execute all the queued tasks:
- for (auto& task : simix_global->tasksTemp)
- task();
-
- simix_global->tasksTemp.clear();
- } while (not simix_global->tasks.empty());
-
- return true;
-}
-
/**
* @ingroup SIMIX_API
* @brief Run the main simulation loop.
do {
XBT_DEBUG("New Schedule Round; size(queue)=%zu", simix_global->actors_to_run.size());
- if (simgrid::simix::breakpoint >= 0.0 && surf_get_clock() >= simgrid::simix::breakpoint) {
- XBT_DEBUG("Breakpoint reached (%g)", simgrid::simix::breakpoint.get());
- simgrid::simix::breakpoint = -1.0;
+ if (simgrid::simix::cfg_breakpoint >= 0.0 && surf_get_clock() >= simgrid::simix::cfg_breakpoint) {
+ XBT_DEBUG("Breakpoint reached (%g)", simgrid::simix::cfg_breakpoint.get());
+ simgrid::simix::cfg_breakpoint = -1.0;
#ifdef SIGTRAP
std::raise(SIGTRAP);
#else
#endif
}
- SIMIX_execute_tasks();
+ simix_global->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());
}
}
- SIMIX_execute_tasks();
+ simix_global->execute_tasks();
do {
SIMIX_wake_processes();
- } while (SIMIX_execute_tasks());
+ } while (simix_global->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())
bool again = false;
do {
again = SIMIX_execute_timers();
- if (SIMIX_execute_tasks())
+ if (simix_global->execute_tasks())
again = true;
SIMIX_wake_processes();
} while (again);
smx_timer_t SIMIX_timer_set(double date, void (*callback)(void*), void *arg)
{
- return simgrid::simix::Timer::set(date, callback, arg);
+ return simgrid::simix::Timer::set(date, std::bind(callback, arg));
}
-smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task<void()> callback)
+smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task<void()>&& callback) // deprecated
{
- smx_timer_t timer = new simgrid::simix::Timer(date, std::move(callback));
- timer->handle_ = simgrid::simix::simix_timers.emplace(std::make_pair(date, timer));
- return timer;
+ return simgrid::simix::Timer::set(date, std::move(callback));
}
/** @brief cancels a timer that was added earlier */
if (process->waiting_synchro) {
const char* synchro_description = "unknown";
+ // we don't care about the Activity type to get its name, use RawImpl
+ const char* name =
+ boost::static_pointer_cast<simgrid::kernel::activity::ActivityImpl_T<simgrid::kernel::activity::RawImpl>>(
+ process->waiting_synchro)
+ ->get_cname();
if (boost::dynamic_pointer_cast<simgrid::kernel::activity::ExecImpl>(process->waiting_synchro) != nullptr)
synchro_description = "execution";
XBT_INFO("Process %ld (%s@%s): waiting for %s synchro %p (%s) in state %d to finish", process->get_pid(),
process->get_cname(), process->get_host()->get_cname(), synchro_description,
- process->waiting_synchro.get(), process->waiting_synchro->get_cname(),
- (int)process->waiting_synchro->state_);
+ process->waiting_synchro.get(), name, (int)process->waiting_synchro->state_);
}
else {
XBT_INFO("Process %ld (%s@%s)", process->get_pid(), process->get_cname(), process->get_host()->get_cname());