Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Use std::vector instead of dynar in simix_global (process_{to_run,that_ran}).
[simgrid.git] / src / simix / ActorImpl.cpp
index a33bfac..e3f5d1d 100644 (file)
@@ -5,12 +5,12 @@
 
 #include <exception>
 #include <functional>
+#include <map>
 #include <string>
 #include <utility>
 
 #include <boost/range/algorithm.hpp>
 
-#include "xbt/dict.h"
 #include "xbt/ex.hpp"
 #include "xbt/functional.hpp"
 #include "xbt/log.h"
@@ -79,8 +79,9 @@ void SIMIX_process_cleanup(smx_actor_t process)
   xbt_os_mutex_acquire(simix_global->mutex);
 
   /* cancel non-blocking communications */
-  smx_activity_t synchro = process->comms.front();
   while (not process->comms.empty()) {
+    smx_activity_t synchro = process->comms.front();
+    process->comms.pop_front();
     simgrid::kernel::activity::CommImplPtr comm =
         boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro);
 
@@ -104,8 +105,6 @@ void SIMIX_process_cleanup(smx_actor_t process)
     } else {
       xbt_die("Communication synchro %p is in my list but I'm not the sender nor the receiver", synchro.get());
     }
-    process->comms.pop_front();
-    synchro = process->comms.front();
     comm->cancel();
   }
 
@@ -141,7 +140,6 @@ namespace simix {
 ActorImpl::~ActorImpl()
 {
   delete this->context;
-  xbt_dict_free(&this->properties);
 }
 
 static int dying_daemon(void* exit_status, void* data)
@@ -167,7 +165,7 @@ void ActorImpl::daemonize()
   }
 }
 
-ActorImpl* ActorImpl::restart(ActorImpl* issuer)
+simgrid::s4u::Actor* ActorImpl::restart()
 {
   XBT_DEBUG("Restarting process %s on %s", cname(), host->getCname());
 
@@ -183,7 +181,7 @@ ActorImpl* ActorImpl::restart(ActorImpl* issuer)
   arg.auto_restart = auto_restart;
 
   // kill the old process
-  SIMIX_process_kill(this, issuer);
+  SIMIX_process_kill(this, (this == simix_global->maestro_process) ? this : SIMIX_process_self());
 
   // start the new process
   ActorImpl* actor = simix_global->create_process_function(arg.name.c_str(), std::move(arg.code), arg.data, arg.host,
@@ -193,7 +191,7 @@ ActorImpl* ActorImpl::restart(ActorImpl* issuer)
   if (arg.auto_restart)
     actor->auto_restart = arg.auto_restart;
 
-  return actor;
+  return actor->ciface();
 }
 
 smx_activity_t ActorImpl::suspend(ActorImpl* issuer)
@@ -265,8 +263,7 @@ void create_maestro(std::function<void()> code)
   } else {
     if (not simix_global)
       xbt_die("simix is not initialized, please call MSG_init first");
-    maestro->context =
-      simix_global->context_factory->create_maestro(code, maestro);
+    maestro->context = simix_global->context_factory->create_maestro(code, maestro);
   }
 
   maestro->simcall.issuer = maestro;
@@ -292,7 +289,7 @@ void SIMIX_maestro_create(void (*code)(void*), void* data)
  * \return the process created
  */
 smx_actor_t SIMIX_process_create(const char* name, std::function<void()> code, void* data, simgrid::s4u::Host* host,
-                                 xbt_dict_t properties, smx_actor_t parent_process)
+                                 std::map<std::string, std::string>* properties, smx_actor_t parent_process)
 {
 
   XBT_DEBUG("Start process %s on host '%s'", name, host->getCname());
@@ -332,7 +329,9 @@ smx_actor_t SIMIX_process_create(const char* name, std::function<void()> code, v
   process->context = SIMIX_context_new(std::move(code), simix_global->cleanup_process_function, process);
 
   /* Add properties */
-  process->properties = properties;
+  if (properties != nullptr)
+    for (auto kv : *properties)
+      process->setProperty(kv.first, kv.second);
 
   /* Make sure that the process is initialized for simix, in case we are called from the Host::onCreation signal */
   if (host->extension<simgrid::simix::Host>() == nullptr)
@@ -346,7 +345,7 @@ smx_actor_t SIMIX_process_create(const char* name, std::function<void()> code, v
   /* 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->getCname());
-  xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
+  simix_global->process_to_run.push_back(process);
   intrusive_ptr_add_ref(process);
 
   /* Tracing the process creation */
@@ -355,8 +354,8 @@ smx_actor_t SIMIX_process_create(const char* name, std::function<void()> code, v
   return process;
 }
 
-smx_actor_t SIMIX_process_attach(const char* name, void* data, const char* hostname, xbt_dict_t properties,
-                                 smx_actor_t parent_process)
+smx_actor_t SIMIX_process_attach(const char* name, void* data, const char* hostname,
+                                 std::map<std::string, std::string>* properties, smx_actor_t parent_process)
 {
   // This is mostly a copy/paste from SIMIX_process_new(),
   // it'd be nice to share some code between those two functions.
@@ -365,8 +364,7 @@ smx_actor_t SIMIX_process_attach(const char* name, void* data, const char* hostn
   XBT_DEBUG("Attach process %s on host '%s'", name, hostname);
 
   if (host->isOff()) {
-    XBT_WARN("Cannot launch process '%s' on failed host '%s'",
-      name, hostname);
+    XBT_WARN("Cannot launch process '%s' on failed host '%s'", name, hostname);
     return nullptr;
   }
 
@@ -398,11 +396,12 @@ smx_actor_t SIMIX_process_attach(const char* name, void* data, const char* hostn
   XBT_VERB("Create context %s", process->name.c_str());
   if (not simix_global)
     xbt_die("simix is not initialized, please call MSG_init first");
-  process->context = simix_global->context_factory->attach(
-    simix_global->cleanup_process_function, process);
+  process->context = simix_global->context_factory->attach(simix_global->cleanup_process_function, process);
 
   /* Add properties */
-  process->properties = properties;
+  if (properties != nullptr)
+    for (auto kv : *properties)
+      process->setProperty(kv.first, kv.second);
 
   /* Add the process to it's host process list */
   xbt_swag_insert(process, host->extension<simgrid::simix::Host>()->process_list);
@@ -410,7 +409,7 @@ smx_actor_t SIMIX_process_attach(const char* name, void* data, const char* hostn
   /* 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->getCname());
-  xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
+  simix_global->process_to_run.push_back(process);
 
   /* Tracing the process creation */
   TRACE_msg_process_create(process->cname(), process->pid, process->host);
@@ -454,10 +453,8 @@ void SIMIX_process_runall()
 {
   SIMIX_context_runall();
 
-  xbt_dynar_t tmp = simix_global->process_that_ran;
-  simix_global->process_that_ran = simix_global->process_to_run;
-  simix_global->process_to_run = tmp;
-  xbt_dynar_reset(simix_global->process_to_run);
+  simix_global->process_to_run.swap(simix_global->process_that_ran);
+  simix_global->process_to_run.clear();
 }
 
 void simcall_HANDLER_process_kill(smx_simcall_t simcall, smx_actor_t process) {
@@ -525,9 +522,11 @@ void SIMIX_process_kill(smx_actor_t process, smx_actor_t issuer) {
 
     process->waiting_synchro = nullptr;
   }
-  if (not xbt_dynar_member(simix_global->process_to_run, &(process)) && process != issuer) {
+  if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), process) ==
+          end(simix_global->process_to_run) &&
+      process != issuer) {
     XBT_DEBUG("Inserting %s in the to_run list", process->name.c_str());
-    xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
+    simix_global->process_to_run.push_back(process);
   }
 }
 
@@ -564,9 +563,11 @@ void SIMIX_process_throw(smx_actor_t process, xbt_errcat_t cat, int value, const
         boost::dynamic_pointer_cast<simgrid::kernel::activity::SleepImpl>(process->waiting_synchro);
     if (sleep != nullptr) {
       SIMIX_process_sleep_destroy(process->waiting_synchro);
-      if (not xbt_dynar_member(simix_global->process_to_run, &(process)) && process != SIMIX_process_self()) {
+      if (std::find(begin(simix_global->process_to_run), end(simix_global->process_to_run), process) ==
+              end(simix_global->process_to_run) &&
+          process != SIMIX_process_self()) {
         XBT_DEBUG("Inserting %s in the to_run list", process->name.c_str());
-        xbt_dynar_push_as(simix_global->process_to_run, smx_actor_t, process);
+        simix_global->process_to_run.push_back(process);
       }
     }
 
@@ -723,7 +724,12 @@ smx_activity_t SIMIX_process_join(smx_actor_t issuer, smx_actor_t process, doubl
    * The C API should first be properly replaced with the C++ one, which is a fair amount of work.
    */
   intrusive_ptr_add_ref(process);
-  SIMIX_process_on_exit(process, (int_f_pvoid_pvoid_t)SIMIX_process_join_finish, &*res);
+  SIMIX_process_on_exit(process,
+                        [](void*, void* arg) {
+                          return simgrid::simix::kernelImmediate(
+                              [&] { return SIMIX_process_join_finish(SMX_EXIT_SUCCESS, arg); });
+                        },
+                        &*res);
   return res;
 }
 
@@ -782,7 +788,8 @@ void SIMIX_process_yield(smx_actor_t 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->userdata,
-                                          SIMIX_timer_get_date(self->kill_timer), self->properties, self->auto_restart);
+                                          SIMIX_timer_get_date(self->kill_timer), self->getProperties(),
+                                          self->auto_restart);
     }
     XBT_DEBUG("Process %s@%s is dead", self->cname(), self->host->getCname());
     self->context->stop();
@@ -815,7 +822,7 @@ void SIMIX_process_exception_terminate(xbt_ex_t * e)
 }
 
 /** @brief Returns the list of processes to run. */
-xbt_dynar_t SIMIX_process_get_runnable()
+const std::vector<smx_actor_t>& simgrid::simix::process_get_runnable()
 {
   return simix_global->process_to_run;
 }
@@ -823,9 +830,8 @@ xbt_dynar_t SIMIX_process_get_runnable()
 /** @brief Returns the process from PID. */
 smx_actor_t SIMIX_process_from_PID(aid_t PID)
 {
-  if (simix_global->process_list.find(PID) == simix_global->process_list.end())
-    return nullptr;
-  return simix_global->process_list.at(PID);
+  auto process = simix_global->process_list.find(PID);
+  return process == simix_global->process_list.end() ? nullptr : process->second;
 }
 
 /** @brief returns a dynar containing all currently existing processes */
@@ -882,9 +888,8 @@ void SIMIX_process_auto_restart_set(smx_actor_t process, int auto_restart) {
  * \param properties the properties of the process
  * \param auto_restart either it is autorestarting or not.
  */
-extern "C"
-smx_actor_t simcall_process_create(const char* name, xbt_main_func_t code, void* data, sg_host_t host, int argc,
-                                   char** argv, xbt_dict_t properties)
+extern "C" smx_actor_t simcall_process_create(const char* name, xbt_main_func_t code, void* data, sg_host_t host,
+                                              int argc, char** argv, std::map<std::string, std::string>* properties)
 {
   if (name == nullptr)
     name = "";
@@ -897,7 +902,7 @@ smx_actor_t simcall_process_create(const char* name, xbt_main_func_t code, void*
 }
 
 smx_actor_t simcall_process_create(const char* name, std::function<void()> code, void* data, sg_host_t host,
-                                   xbt_dict_t properties)
+                                   std::map<std::string, std::string>* properties)
 {
   if (name == nullptr)
     name = "";