#include "src/surf/surf_interface.hpp"
#ifdef HAVE_SMPI
-#include "src/smpi/private.h"
+#include "src/smpi/private.hpp"
#endif
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_process, simix, "Logging specific to SIMIX (process)");
}
}
+ActorImpl* ActorImpl::restart(ActorImpl* issuer)
+{
+ XBT_DEBUG("Restarting process %s on %s", cname(), host->getCname());
+
+ // retrieve the arguments of the old process
+ // FIXME: Factorize this with SIMIX_host_add_auto_restart_process ?
+ simgrid::simix::ProcessArg arg;
+ arg.name = name;
+ arg.code = code;
+ arg.host = host;
+ arg.kill_time = SIMIX_timer_get_date(kill_timer);
+ arg.data = userdata;
+ arg.properties = nullptr;
+ arg.auto_restart = auto_restart;
+
+ // kill the old process
+ SIMIX_process_kill(this, issuer);
+
+ // start the new process
+ ActorImpl* actor = simix_global->create_process_function(arg.name.c_str(), std::move(arg.code), arg.data, arg.host,
+ arg.properties, nullptr);
+ if (arg.kill_time >= 0)
+ simcall_process_set_kill_time(actor, arg.kill_time);
+ if (arg.auto_restart)
+ simcall_process_auto_restart_set(actor, arg.auto_restart);
+
+ return actor;
+}
+
+smx_activity_t ActorImpl::suspend(ActorImpl* issuer)
+{
+ if (suspended) {
+ XBT_DEBUG("Actor '%s' is already suspended", name.c_str());
+ return nullptr;
+ }
+
+ suspended = 1;
+
+ /* If we are suspending another actor that is waiting on a sync, suspend its synchronization. */
+ if (this != issuer) {
+ if (waiting_synchro)
+ waiting_synchro->suspend();
+ /* If the other actor is not waiting, its suspension is delayed to when the actor is rescheduled. */
+
+ return nullptr;
+ } else {
+ return SIMIX_execution_start(this, "suspend", 0.0, 1.0, 0.0);
+ }
+}
+
void ActorImpl::resume()
{
XBT_IN("process = %p", this);
if (context->iwannadie) {
- XBT_VERB("Ignoring request to suspend a process that is currently dying.");
+ XBT_VERB("Ignoring request to suspend an actor that is currently dying.");
return;
}
return;
suspended = 0;
- /* resume the synchronization that was blocking the resumed process. */
+ /* resume the synchronization that was blocking the resumed actor. */
if (waiting_synchro)
waiting_synchro->resume();
XBT_OUT();
}
+smx_activity_t ActorImpl::sleep(double duration)
+{
+ if (host->isOff())
+ THROWF(host_error, 0, "Host %s failed, you cannot sleep there.", host->getCname());
+
+ simgrid::kernel::activity::SleepImpl* synchro = new simgrid::kernel::activity::SleepImpl();
+ synchro->host = host;
+ synchro->surf_sleep = host->pimpl_cpu->sleep(duration);
+ synchro->surf_sleep->setData(synchro);
+ XBT_DEBUG("Create sleep synchronization %p", synchro);
+
+ return synchro;
+}
+
void create_maestro(std::function<void()> code)
{
smx_actor_t maestro = nullptr;
maestro = new simgrid::simix::ActorImpl();
maestro->pid = simix_process_maxpid++;
maestro->name = "";
- maestro->data = nullptr;
+ maestro->userdata = nullptr;
if (not code) {
maestro->context = SIMIX_context_new(std::function<void()>(), nullptr, maestro);
xbt_dict_t properties, smx_actor_t parent_process)
{
- XBT_DEBUG("Start process %s on host '%s'", name, host->cname());
+ XBT_DEBUG("Start process %s on host '%s'", name, host->getCname());
if (host->isOff()) {
- XBT_WARN("Cannot launch process '%s' on failed host '%s'", name, host->cname());
+ XBT_WARN("Cannot launch process '%s' on failed host '%s'", name, host->getCname());
return nullptr;
}
process->pid = simix_process_maxpid++;
process->name = simgrid::xbt::string(name);
process->host = host;
- process->data = data;
+ process->userdata = data;
process->simcall.issuer = process;
if (parent_process != nullptr) {
/* Now insert it in the global process list and in the process to run list */
simix_global->process_list[process->pid] = process;
- XBT_DEBUG("Inserting %s(%s) in the to_run list", process->cname(), host->cname());
+ XBT_DEBUG("Inserting %s(%s) in the to_run list", process->cname(), host->getCname());
xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
intrusive_ptr_add_ref(process);
process->pid = simix_process_maxpid++;
process->name = std::string(name);
process->host = host;
- process->data = data;
+ process->userdata = data;
process->simcall.issuer = process;
if (parent_process != nullptr) {
/* Now insert it in the global process list and in the process to run list */
simix_global->process_list[process->pid] = process;
- XBT_DEBUG("Inserting %s(%s) in the to_run list", process->cname(), host->cname());
+ XBT_DEBUG("Inserting %s(%s) in the to_run list", process->cname(), host->getCname());
xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
/* Tracing the process creation */
*/
void SIMIX_process_kill(smx_actor_t process, smx_actor_t issuer) {
- XBT_DEBUG("Killing process %s@%s", process->cname(), process->host->cname());
+ XBT_DEBUG("Killing process %s@%s", process->cname(), process->host->getCname());
process->context->iwannadie = 1;
process->blocked = 0;
void simcall_HANDLER_process_suspend(smx_simcall_t simcall, smx_actor_t process)
{
- smx_activity_t sync_suspend = SIMIX_process_suspend(process, simcall->issuer);
+ smx_activity_t sync_suspend = process->suspend(simcall->issuer);
if (process != simcall->issuer) {
SIMIX_simcall_answer(simcall);
/* If we are suspending ourselves, then just do not finish the simcall now */
}
-smx_activity_t SIMIX_process_suspend(smx_actor_t process, smx_actor_t issuer)
-{
- if (process->suspended) {
- XBT_DEBUG("Process '%s' is already suspended", process->name.c_str());
- return nullptr;
- }
-
- process->suspended = 1;
-
- /* If we are suspending another process that is waiting on a sync, suspend its synchronization. */
- if (process != issuer) {
-
- if (process->waiting_synchro)
- process->waiting_synchro->suspend();
- /* If the other process is not waiting, its suspension is delayed to when the process is rescheduled. */
-
- return nullptr;
- } else {
- return SIMIX_execution_start(process, "suspend", 0.0, 1.0, 0.0);
- }
-}
-
int SIMIX_process_get_maxpid() {
return simix_process_maxpid;
}
if (not self) {
return nullptr;
}
- return self->data;
+ return self->getUserData();
}
void SIMIX_process_self_set_data(void *data)
{
- smx_actor_t self = SIMIX_process_self();
-
- SIMIX_process_set_data(self, data);
+ SIMIX_process_self()->setUserData(data);
}
-void SIMIX_process_set_data(smx_actor_t process, void *data)
-{
- process->data = data;
-}
/* needs to be public and without simcall because it is called
by exceptions and logging events */
smx_activity_t SIMIX_process_join(smx_actor_t issuer, smx_actor_t process, double timeout)
{
- smx_activity_t res = SIMIX_process_sleep(issuer, timeout);
+ smx_activity_t res = issuer->sleep(timeout);
intrusive_ptr_add_ref(res.get());
/* We are leaking the process here, but if we don't take the ref, we get a "use after free".
* The correct solution would be to derivate the type SynchroSleep into a SynchroProcessJoin,
SIMIX_simcall_answer(simcall);
return;
}
- smx_activity_t sync = SIMIX_process_sleep(simcall->issuer, duration);
+ smx_activity_t sync = simcall->issuer->sleep(duration);
sync->simcalls.push_back(simcall);
simcall->issuer->waiting_synchro = sync;
}
-smx_activity_t SIMIX_process_sleep(smx_actor_t process, double duration)
-{
- sg_host_t host = process->host;
-
- if (host->isOff())
- THROWF(host_error, 0, "Host %s failed, you cannot sleep there.", host->cname());
-
- simgrid::kernel::activity::SleepImpl* synchro = new simgrid::kernel::activity::SleepImpl();
- synchro->host = host;
- synchro->surf_sleep = host->pimpl_cpu->sleep(duration);
- synchro->surf_sleep->setData(synchro);
- XBT_DEBUG("Create sleep synchronization %p", synchro);
-
- return synchro;
-}
-
void SIMIX_process_sleep_destroy(smx_activity_t synchro)
{
XBT_DEBUG("Destroy sleep synchro %p", synchro.get());
SIMIX_process_on_exit_runall(self);
/* Add the process to the list of process to restart, only if the host is down */
if (self->auto_restart && self->host->isOff()) {
- SIMIX_host_add_auto_restart_process(self->host, self->cname(),
- self->code, self->data,
- SIMIX_timer_get_date(self->kill_timer),
- self->properties,
- self->auto_restart);
+ SIMIX_host_add_auto_restart_process(self->host, self->cname(), self->code, self->userdata,
+ SIMIX_timer_get_date(self->kill_timer), self->properties, self->auto_restart);
}
- XBT_DEBUG("Process %s@%s is dead", self->cname(), self->host->cname());
+ XBT_DEBUG("Process %s@%s is dead", self->cname(), self->host->getCname());
self->context->stop();
}
XBT_DEBUG("Hey! I'm suspended.");
xbt_assert(self->exception != nullptr, "Gasp! This exception may be lost by subsequent calls.");
self->suspended = 0;
- SIMIX_process_suspend(self, self);
+ self->suspend(self);
}
if (self->exception != nullptr) {
}
smx_actor_t simcall_HANDLER_process_restart(smx_simcall_t simcall, smx_actor_t process) {
- return SIMIX_process_restart(process, simcall->issuer);
-}
-/** @brief Restart a process, starting it again from the beginning. */
-smx_actor_t SIMIX_process_restart(smx_actor_t process, smx_actor_t issuer) {
- XBT_DEBUG("Restarting process %s on %s", process->cname(), process->host->cname());
-
- //retrieve the arguments of the old process
- //FIXME: Factorize this with SIMIX_host_add_auto_restart_process ?
- simgrid::simix::ProcessArg arg;
- arg.name = process->name;
- arg.code = process->code;
- arg.host = process->host;
- arg.kill_time = SIMIX_timer_get_date(process->kill_timer);
- arg.data = process->data;
- arg.properties = nullptr;
- arg.auto_restart = process->auto_restart;
-
- //kill the old process
- SIMIX_process_kill(process, issuer);
-
- //start the new process
- smx_actor_t actor = simix_global->create_process_function(arg.name.c_str(), std::move(arg.code), arg.data, arg.host,
- arg.properties, nullptr);
- if (arg.kill_time >= 0)
- simcall_process_set_kill_time(actor, arg.kill_time);
- if (arg.auto_restart)
- simcall_process_auto_restart_set(actor, arg.auto_restart);
-
- return actor;
+ return process->restart(simcall->issuer);
}
+/** @brief Restart a process, starting it again from the beginning. */
/**
* \ingroup simix_process_management
* \brief Creates and runs a new SIMIX process.
*
* \param name a name for the process. It is for user-level information and can be nullptr.
* \param code the main function of the process
- * \param data a pointer to any data one may want to attach to the new object. It is for user-level information and can be nullptr.
+ * \param data a pointer to any data one may want to attach to the new object. It is for user-level information and can
+ * be nullptr.
* It can be retrieved with the function \ref simcall_process_get_data.
* \param host where the new agent is executed.
* \param kill_time time when the process is killed