* 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);
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_) {
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<ActivityImpl> support:
/* 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);
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()) {
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)
/* 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<activity::ExecImpl>(waiting_synchro);
activity::CommImplPtr comm = boost::dynamic_pointer_cast<activity::CommImpl>(waiting_synchro);
- activity::SleepImplPtr sleep = boost::dynamic_pointer_cast<activity::SleepImpl>(waiting_synchro);
- activity::RawImplPtr raw = boost::dynamic_pointer_cast<activity::RawImpl>(waiting_synchro);
- activity::IoImplPtr io = boost::dynamic_pointer_cast<activity::IoImpl>(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;
}
}
-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<void()> const* code)
{
(*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.
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<void()> const* code);
XBT_PRIVATE void SIMIX_run_blocking(std::function<void()> const* code);
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()) {
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())) {
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();
}
}
}
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.
#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);
friend XBT_PUBLIC bool simgrid::s4u::this_actor::is_maestro();
public:
+ bool execute_tasks();
/**
* Garbage collection
*