void Actor::kill(aid_t pid) // deprecated
{
smx_actor_t killer = SIMIX_process_self();
- smx_actor_t process = SIMIX_process_from_PID(pid);
- if (process != nullptr) {
- simgrid::simix::simcall([killer, process] { SIMIX_process_kill(process, killer); });
+ smx_actor_t victim = SIMIX_process_from_PID(pid);
+ if (victim != nullptr) {
+ simgrid::simix::simcall([killer, victim] { killer->kill(victim); });
} else {
std::ostringstream oss;
oss << "kill: (" << pid << ") - No such actor" << std::endl;
void Actor::kill()
{
smx_actor_t process = SIMIX_process_self();
- simgrid::simix::simcall(
- [this, process] { SIMIX_process_kill(pimpl_, (pimpl_ == simix_global->maestro_process) ? pimpl_ : process); });
+ simgrid::simix::simcall([this, process] {
+ if (pimpl_ == simix_global->maestro_process)
+ pimpl_->exit();
+ else
+ process->kill(pimpl_);
+ });
}
smx_actor_t Actor::get_impl()
void Actor::kill_all()
{
smx_actor_t self = SIMIX_process_self();
- simgrid::simix::simcall([&self] { SIMIX_process_killall(self); });
+ simgrid::simix::simcall([self] { self->kill_all(); });
}
std::unordered_map<std::string, std::string>* Actor::get_properties()
void exit()
{
- smx_actor_t process = SIMIX_process_self();
- simgrid::simix::simcall([process] { SIMIX_process_kill(process, process); });
+ smx_actor_t actor = SIMIX_process_self();
+ simgrid::simix::simcall([actor] { actor->exit(); });
}
void on_exit(std::function<void(int, void*)> fun, void* data)
delete this->context_;
}
+void ActorImpl::exit()
+{
+ context_->iwannadie = true;
+ blocked_ = false;
+ suspended_ = false;
+ exception = nullptr;
+
+ // Forcefully kill the actor if its host is turned off. Not a HostFailureException because you should not survive that
+ if (host_->is_off())
+ this->throw_exception(std::make_exception_ptr(simgrid::kernel::context::StopRequest("host failed")));
+
+ /* destroy the blocking synchro if any */
+ if (waiting_synchro != nullptr) {
+
+ 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();
+ exec->surf_action_->unref();
+ exec->surf_action_ = nullptr;
+ } else if (comm != nullptr) {
+ comms.remove(waiting_synchro);
+ comm->cancel();
+ // Remove first occurrence of &process->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) {
+ if (sleep->surf_action_)
+ sleep->surf_action_->cancel();
+ sleep->post();
+ } else if (raw != nullptr) {
+ SIMIX_synchro_stop_waiting(this, &simcall);
+ } else if (io != nullptr) {
+ io->cancel();
+ } else {
+ simgrid::kernel::activity::ActivityImplPtr activity = waiting_synchro;
+ xbt_die("Activity %s is of unknown type %s", activity->name_.c_str(),
+ simgrid::xbt::demangle(typeid(activity).name()).get());
+ }
+
+ waiting_synchro = nullptr;
+ }
+}
+
+void ActorImpl::kill(smx_actor_t actor)
+{
+ if (actor->finished_) {
+ XBT_DEBUG("Ignoring request to kill process %s@%s that is already dead", actor->get_cname(),
+ actor->host_->get_cname());
+ return;
+ }
+
+ XBT_DEBUG("Actor '%s'@%s is killing actor '%s'@%s", get_cname(), host_->get_cname(), actor->get_cname(),
+ actor->host_->get_cname());
+
+ actor->exit();
+
+ if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), actor) ==
+ end(simix_global->process_to_run) &&
+ actor != this) {
+ XBT_DEBUG("Inserting %s in the to_run list", actor->get_cname());
+ simix_global->process_to_run.push_back(actor);
+ }
+}
+
+void ActorImpl::kill_all()
+{
+ for (auto const& kv : simix_global->process_list)
+ if (kv.second != this)
+ this->kill(kv.second);
+}
+
void ActorImpl::set_kill_time(double kill_time)
{
if (kill_time <= SIMIX_get_clock())
return;
XBT_DEBUG("Set kill time %f for process %s@%s", kill_time, get_cname(), host_->get_cname());
kill_timer = SIMIX_timer_set(kill_time, [this] {
- SIMIX_process_kill(this, nullptr);
+ this->exit();
kill_timer = nullptr;
});
}
simgrid::kernel::actor::ProcessArg arg = ProcessArg(host_, this);
// kill the old process
- SIMIX_process_kill(this, (this == simix_global->maestro_process) ? this : SIMIX_process_self());
+ (this == simix_global->maestro_process) ? this->exit() : SIMIX_process_self()->kill(this);
// start the new process
ActorImplPtr actor =
simix_global->process_to_run.clear();
}
-/**
- * @brief Internal function to kill a SIMIX process.
- *
- * This function may be called when a SIMCALL_PROCESS_KILL simcall occurs,
- * or directly for SIMIX internal purposes.
- *
- * @param actor poor victim
- * @param issuer the actor which has sent the PROCESS_KILL. Important to not schedule twice the same actor.
- */
-void SIMIX_process_kill(smx_actor_t actor, smx_actor_t issuer)
-{
-
- if (actor->finished_) {
- XBT_DEBUG("Ignoring request to kill process %s@%s that is already dead", actor->get_cname(),
- actor->host_->get_cname());
- return;
- }
-
- XBT_DEBUG("Actor '%s'@%s is killing actor '%s'@%s", issuer == nullptr ? "(null)" : issuer->get_cname(),
- (issuer == nullptr || issuer->host_ == nullptr ? "(null)" : issuer->host_->get_cname()), actor->get_cname(),
- actor->host_->get_cname());
-
- actor->context_->iwannadie = true;
- actor->blocked_ = false;
- actor->suspended_ = false;
- actor->exception = nullptr;
-
- // Forcefully kill the actor if its host is turned off. Not an HostFailureException because you should not survive that
- if (actor->host_->is_off())
- actor->throw_exception(std::make_exception_ptr(simgrid::kernel::context::StopRequest("host failed")));
-
- /* destroy the blocking synchro if any */
- if (actor->waiting_synchro != nullptr) {
-
- simgrid::kernel::activity::ExecImplPtr exec =
- boost::dynamic_pointer_cast<simgrid::kernel::activity::ExecImpl>(actor->waiting_synchro);
- simgrid::kernel::activity::CommImplPtr comm =
- boost::dynamic_pointer_cast<simgrid::kernel::activity::CommImpl>(actor->waiting_synchro);
- simgrid::kernel::activity::SleepImplPtr sleep =
- boost::dynamic_pointer_cast<simgrid::kernel::activity::SleepImpl>(actor->waiting_synchro);
- simgrid::kernel::activity::RawImplPtr raw =
- boost::dynamic_pointer_cast<simgrid::kernel::activity::RawImpl>(actor->waiting_synchro);
- simgrid::kernel::activity::IoImplPtr io =
- boost::dynamic_pointer_cast<simgrid::kernel::activity::IoImpl>(actor->waiting_synchro);
-
- if (exec != nullptr) {
- if (exec->surf_action_) {
- exec->surf_action_->cancel();
- exec->surf_action_->unref();
- exec->surf_action_ = nullptr;
- }
- } else if (comm != nullptr) {
- actor->comms.remove(actor->waiting_synchro);
- comm->cancel();
- // Remove first occurrence of &process->simcall:
- auto i = boost::range::find(actor->waiting_synchro->simcalls_, &actor->simcall);
- if (i != actor->waiting_synchro->simcalls_.end())
- actor->waiting_synchro->simcalls_.remove(&actor->simcall);
- } else if (sleep != nullptr) {
- if (sleep->surf_action_)
- sleep->surf_action_->cancel();
- sleep->post();
- } else if (raw != nullptr) {
- SIMIX_synchro_stop_waiting(actor, &actor->simcall);
-
- } else if (io != nullptr) {
- io->cancel();
- } else {
- simgrid::kernel::activity::ActivityImplPtr activity = actor->waiting_synchro;
- xbt_die("Activity %s is of unknown type %s", activity->name_.c_str(),
- simgrid::xbt::demangle(typeid(activity).name()).get());
- }
-
- actor->waiting_synchro = nullptr;
- }
- if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), actor) ==
- end(simix_global->process_to_run) &&
- actor != issuer) {
- XBT_DEBUG("Inserting [%p] %s in the to_run list", actor, actor->get_cname());
- simix_global->process_to_run.push_back(actor);
- }
-}
-
/** @deprecated When this function gets removed, also remove the xbt_ex class, that is only there to help users to
* transition */
void SIMIX_process_throw(smx_actor_t actor, xbt_errcat_t cat, int value, const char* msg)
actor->waiting_synchro = nullptr;
}
-/**
- * @brief Kills all running processes.
- * @param issuer this one will not be killed
- */
-void SIMIX_process_killall(smx_actor_t issuer)
-{
- for (auto const& kv : simix_global->process_list)
- if (kv.second != issuer)
- SIMIX_process_kill(kv.second, issuer);
-}
-
-
void simcall_HANDLER_process_suspend(smx_simcall_t simcall, smx_actor_t actor)
{
smx_activity_t sync_suspend = actor->suspend(simcall->issuer);
std::atomic_int_fast32_t refcount_{0};
public:
- friend void intrusive_ptr_add_ref(ActorImpl* process)
+ friend void intrusive_ptr_add_ref(ActorImpl* actor)
{
// std::memory_order_relaxed ought to be enough here instead of std::memory_order_seq_cst
// But then, we have a threading issue when an actor commits a suicide:
// it seems that in this case, the worker thread kills the last occurrence of the actor
// while usually, the maestro does so. FIXME: we should change how actors suicide
- process->refcount_.fetch_add(1, std::memory_order_seq_cst);
+ actor->refcount_.fetch_add(1, std::memory_order_seq_cst);
}
- friend void intrusive_ptr_release(ActorImpl* process)
+ friend void intrusive_ptr_release(ActorImpl* actor)
{
// inspired from http://www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html
- if (process->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
+ if (actor->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
// Make sure that any changes done on other threads before their acquire are committed before our delete
// http://stackoverflow.com/questions/27751025/why-is-an-acquire-barrier-needed-before-deleting-the-data-in-an-atomically-refer
std::atomic_thread_fence(std::memory_order_acquire);
- delete process;
+ delete actor;
}
}
public:
static ActorImplPtr create(std::string name, simix::ActorCode code, void* data, s4u::Host* host,
std::unordered_map<std::string, std::string>* properties, smx_actor_t parent_actor);
+ void exit();
+ void kill(smx_actor_t actor);
+ void kill_all();
void daemonize();
bool is_daemon() { return daemon_; } /** Whether this actor has been daemonized */
typedef simgrid::kernel::actor::ActorImpl* smx_actor_t;
XBT_PRIVATE void SIMIX_process_runall();
-XBT_PRIVATE void SIMIX_process_kill(smx_actor_t process, smx_actor_t issuer);
-XBT_PRIVATE void SIMIX_process_killall(smx_actor_t issuer);
XBT_PRIVATE void SIMIX_process_cleanup(smx_actor_t arg);
XBT_PRIVATE void SIMIX_process_empty_trash();
XBT_PRIVATE void SIMIX_process_yield(smx_actor_t self);