From: Frederic Suter Date: Mon, 8 Apr 2019 07:03:16 +0000 (+0200) Subject: Merge branch 'master' of https://framagit.org/simgrid/simgrid X-Git-Tag: v3.22.2~163 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/b830103bb89748d30c84ff7a0e88ca821d2d78b7?hp=6cf57242a375fb0186c9eefcf46fcff848d54b19 Merge branch 'master' of https://framagit.org/simgrid/simgrid --- diff --git a/src/kernel/activity/ActivityImpl.cpp b/src/kernel/activity/ActivityImpl.cpp index 54540506b1..c5f3524539 100644 --- a/src/kernel/activity/ActivityImpl.cpp +++ b/src/kernel/activity/ActivityImpl.cpp @@ -4,6 +4,7 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include "src/kernel/activity/ActivityImpl.hpp" +#include "src/simix/smx_private.hpp" XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_process); @@ -17,6 +18,12 @@ ActivityImpl::~ActivityImpl() XBT_DEBUG("Destroy activity %p", this); } +void ActivityImpl::register_simcall(smx_simcall_t simcall) +{ + simcalls_.push_back(simcall); + simcall->issuer->waiting_synchro = this; +} + void ActivityImpl::clean_action() { if (surf_action_) { diff --git a/src/kernel/activity/ActivityImpl.hpp b/src/kernel/activity/ActivityImpl.hpp index 0d16180e30..d99f965dd2 100644 --- a/src/kernel/activity/ActivityImpl.hpp +++ b/src/kernel/activity/ActivityImpl.hpp @@ -35,6 +35,7 @@ public: virtual void post() = 0; // What to do when a simcall terminates virtual void finish() = 0; + virtual void register_simcall(smx_simcall_t simcall); virtual void clean_action(); virtual double get_remaining() const; // boost::intrusive_ptr support: diff --git a/src/kernel/activity/CommImpl.cpp b/src/kernel/activity/CommImpl.cpp index ae219f6e45..9817117bc7 100644 --- a/src/kernel/activity/CommImpl.cpp +++ b/src/kernel/activity/CommImpl.cpp @@ -189,8 +189,7 @@ void simcall_HANDLER_comm_wait(smx_simcall_t simcall, simgrid::kernel::activity: /* Associate this simcall to the wait synchro */ XBT_DEBUG("simcall_HANDLER_comm_wait, %p", comm); - comm->simcalls_.push_back(simcall); - simcall->issuer->waiting_synchro = comm; + comm->register_simcall(simcall); if (MC_is_active() || MC_record_replay_is_active()) { int idx = SIMCALL_GET_MC_VALUE(simcall); diff --git a/src/kernel/activity/ExecImpl.cpp b/src/kernel/activity/ExecImpl.cpp index a2ca6a8f6e..8e1c3e808a 100644 --- a/src/kernel/activity/ExecImpl.cpp +++ b/src/kernel/activity/ExecImpl.cpp @@ -20,8 +20,7 @@ void simcall_HANDLER_execution_wait(smx_simcall_t simcall, simgrid::kernel::acti XBT_DEBUG("Wait for execution of synchro %p, state %d", synchro, (int)synchro->state_); /* Associate this simcall to the synchro */ - synchro->simcalls_.push_back(simcall); - simcall->issuer->waiting_synchro = synchro; + synchro->register_simcall(simcall); /* set surf's synchro */ if (MC_is_active() || MC_record_replay_is_active()) { diff --git a/src/kernel/activity/IoImpl.cpp b/src/kernel/activity/IoImpl.cpp index 7c23fbb623..b7c10da2c8 100644 --- a/src/kernel/activity/IoImpl.cpp +++ b/src/kernel/activity/IoImpl.cpp @@ -18,15 +18,10 @@ void simcall_HANDLER_io_wait(smx_simcall_t simcall, simgrid::kernel::activity::I XBT_DEBUG("Wait for execution of synchro %p, state %d", synchro, (int)synchro->state_); /* Associate this simcall to the synchro */ - synchro->simcalls_.push_back(simcall); - simcall->issuer->waiting_synchro = synchro; + synchro->register_simcall(simcall); - /* set surf's synchro */ - if (MC_is_active() || MC_record_replay_is_active()) { + if (MC_is_active() || MC_record_replay_is_active()) synchro->state_ = SIMIX_DONE; - synchro->finish(); - return; - } /* If the synchro is already finished then perform the error handling */ if (synchro->state_ != SIMIX_RUNNING) diff --git a/src/kernel/actor/ActorImpl.cpp b/src/kernel/actor/ActorImpl.cpp index 407d18ae00..ee02c16871 100644 --- a/src/kernel/actor/ActorImpl.cpp +++ b/src/kernel/actor/ActorImpl.cpp @@ -198,34 +198,22 @@ void ActorImpl::exit() /* destroy the blocking synchro if any */ if (waiting_synchro != nullptr) { + waiting_synchro->cancel(); + waiting_synchro->state_ = SIMIX_FAILED; activity::ExecImplPtr exec = boost::dynamic_pointer_cast(waiting_synchro); activity::CommImplPtr comm = boost::dynamic_pointer_cast(waiting_synchro); - activity::SleepImplPtr sleep = boost::dynamic_pointer_cast(waiting_synchro); - activity::RawImplPtr raw = boost::dynamic_pointer_cast(waiting_synchro); - activity::IoImplPtr io = boost::dynamic_pointer_cast(waiting_synchro); - if (exec != nullptr && exec->surf_action_) { - exec->cancel(); + if (exec != nullptr) { exec->clean_action(); } else if (comm != nullptr) { comms.remove(waiting_synchro); - comm->cancel(); // Remove first occurrence of &actor->simcall: auto i = boost::range::find(waiting_synchro->simcalls_, &simcall); if (i != waiting_synchro->simcalls_.end()) waiting_synchro->simcalls_.remove(&simcall); - } else if (sleep != nullptr) { - sleep->cancel(); - sleep->finish(); - } else if (raw != nullptr) { - raw->finish(); - } else if (io != nullptr) { - io->cancel(); - io->finish(); } else { - simgrid::kernel::activity::ActivityImplPtr activity = waiting_synchro; - xbt_die("Activity is of unknown type %s", simgrid::xbt::demangle(typeid(activity).name()).get()); + activity::ActivityImplPtr(waiting_synchro)->finish(); } waiting_synchro = nullptr; diff --git a/src/simix/popping.cpp b/src/simix/popping.cpp index c482ab8923..21a1331021 100644 --- a/src/simix/popping.cpp +++ b/src/simix/popping.cpp @@ -22,12 +22,6 @@ void SIMIX_simcall_answer(smx_simcall_t simcall) } } -void SIMIX_simcall_exit(smx_activity_t activity) -{ - if (activity != nullptr) // When migrating, the surf activity is disconnected from its simix activity before cancel - activity->post(); -} - void SIMIX_run_kernel(std::function const* code) { (*code)(); @@ -35,7 +29,7 @@ void SIMIX_run_kernel(std::function const* code) /** Kernel code for run_blocking * - * The implementtion looks a lot like SIMIX_run_kernel ^^ + * The implementation looks a lot like SIMIX_run_kernel ^^ * * However, this `run_blocking` is blocking so the process will not be woken * up until `SIMIX_simcall_answer(simcall)`` is called by the kernel. diff --git a/src/simix/popping_private.hpp b/src/simix/popping_private.hpp index b6a60d9669..be180ac81b 100644 --- a/src/simix/popping_private.hpp +++ b/src/simix/popping_private.hpp @@ -58,7 +58,6 @@ struct s_smx_simcall { XBT_PRIVATE void SIMIX_simcall_answer(smx_simcall_t simcall); XBT_PRIVATE void SIMIX_simcall_handle(smx_simcall_t simcall, int value); -XBT_PRIVATE void SIMIX_simcall_exit(smx_activity_t synchro); XBT_PRIVATE const char* SIMIX_simcall_name(e_smx_simcall_t kind); XBT_PRIVATE void SIMIX_run_kernel(std::function const* code); XBT_PRIVATE void SIMIX_run_blocking(std::function const* code); diff --git a/src/simix/smx_global.cpp b/src/simix/smx_global.cpp index bcca356024..4b132db5d6 100644 --- a/src/simix/smx_global.cpp +++ b/src/simix/smx_global.cpp @@ -138,6 +138,28 @@ void Timer::remove() 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()) { @@ -313,7 +335,8 @@ static void SIMIX_wake_processes() 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(action->get_activity()); + 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())) { @@ -321,7 +344,7 @@ static void SIMIX_wake_processes() if (action->get_activity() == nullptr) XBT_DEBUG("probably vcpu's action %p, skip", action); else - SIMIX_simcall_exit(action->get_activity()); + simgrid::kernel::activity::ActivityImplPtr(action->get_activity())->post(); } } } @@ -345,31 +368,6 @@ static bool SIMIX_execute_timers() 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. @@ -396,7 +394,7 @@ void SIMIX_run() #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()); @@ -472,10 +470,10 @@ void SIMIX_run() } } - 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()) @@ -500,7 +498,7 @@ void SIMIX_run() bool again = false; do { again = SIMIX_execute_timers(); - if (SIMIX_execute_tasks()) + if (simix_global->execute_tasks()) again = true; SIMIX_wake_processes(); } while (again); diff --git a/src/simix/smx_private.hpp b/src/simix/smx_private.hpp index d6a15bb23b..c26de3558a 100644 --- a/src/simix/smx_private.hpp +++ b/src/simix/smx_private.hpp @@ -24,6 +24,7 @@ class Global { friend XBT_PUBLIC bool simgrid::s4u::this_actor::is_maestro(); public: + bool execute_tasks(); /** * Garbage collection *