Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Revert "actually fix the memleak around smpi's process_data" and "try to plug a memleak"
[simgrid.git] / src / s4u / s4u_actor.cpp
index f3f5ab0..5e07894 100644 (file)
@@ -7,11 +7,12 @@
 
 #include "simgrid/s4u/Actor.hpp"
 #include "simgrid/s4u/Comm.hpp"
+#include "simgrid/s4u/Exec.hpp"
 #include "simgrid/s4u/Host.hpp"
 #include "simgrid/s4u/Mailbox.hpp"
 
 #include "src/kernel/context/Context.hpp"
-#include "src/simix/smx_private.h"
+#include "src/simix/smx_private.hpp"
 
 #include <sstream>
 
@@ -20,6 +21,8 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor, "S4U actors");
 namespace simgrid {
 namespace s4u {
 
+simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> s4u::Actor::onCreation;
+
 // ***** Actor creation *****
 ActorPtr Actor::self()
 {
@@ -46,12 +49,10 @@ ActorPtr Actor::createActor(const char* name, s4u::Host* host, const char* funct
 
 void intrusive_ptr_add_ref(Actor* actor)
 {
-  xbt_assert(actor != nullptr);
   intrusive_ptr_add_ref(actor->pimpl_);
 }
 void intrusive_ptr_release(Actor* actor)
 {
-  xbt_assert(actor != nullptr);
   intrusive_ptr_release(actor->pimpl_);
 }
 
@@ -61,6 +62,11 @@ void Actor::join() {
   simcall_process_join(this->pimpl_, -1);
 }
 
+void Actor::join(double timeout)
+{
+  simcall_process_join(this->pimpl_, timeout);
+}
+
 void Actor::setAutoRestart(bool autorestart) {
   simgrid::simix::kernelImmediate([this, autorestart]() { pimpl_->auto_restart = autorestart; });
 }
@@ -70,9 +76,28 @@ void Actor::onExit(int_f_pvoid_pvoid_t fun, void* data)
   simcall_process_on_exit(pimpl_, fun, data);
 }
 
+/** @brief Moves the actor to another host
+ *
+ * If the actor is currently blocked on an execution activity, the activity is also
+ * migrated to the new host. If it's blocked on another kind of activity, an error is
+ * raised as the mandated code is not written yet. Please report that bug if you need it.
+ *
+ * Asynchronous activities started by the actor are not migrated automatically, so you have
+ * to take care of this yourself (only you knows which ones should be migrated).
+ */
 void Actor::migrate(Host* new_host)
 {
-  simgrid::simix::kernelImmediate([this, new_host]() { pimpl_->new_host = new_host; });
+  simgrid::simix::kernelImmediate([this, new_host]() {
+    if (pimpl_->waiting_synchro != nullptr) {
+      // The actor is blocked on an activity. If it's an exec, migrate it too.
+      // FIXME: implement the migration of other kind of activities
+      simgrid::kernel::activity::ExecImplPtr exec =
+          boost::dynamic_pointer_cast<simgrid::kernel::activity::ExecImpl>(pimpl_->waiting_synchro);
+      xbt_assert(exec.get() != nullptr, "We can only migrate blocked actors when they are blocked on executions.");
+      exec->migrate(new_host);
+    }
+    SIMIX_process_change_host(this->pimpl_, new_host);
+  });
 }
 
 s4u::Host* Actor::getHost()
@@ -85,14 +110,14 @@ void Actor::daemonize()
   simgrid::simix::kernelImmediate([this]() { pimpl_->daemonize(); });
 }
 
-const char* Actor::getCname()
+const simgrid::xbt::string& Actor::getName() const
 {
-  return this->pimpl_->name.c_str();
+  return this->pimpl_->getName();
 }
 
-simgrid::xbt::string Actor::getName()
+const char* Actor::getCname() const
 {
-  return this->pimpl_->name;
+  return this->pimpl_->getCname();
 }
 
 aid_t Actor::getPid()
@@ -107,12 +132,17 @@ aid_t Actor::getPpid()
 
 void Actor::suspend()
 {
+  if (TRACE_actor_is_enabled())
+    simgrid::instr::Container::byName(instr_pid(this))->getState("MSG_PROCESS_STATE")->pushEvent("suspend");
+
   simcall_process_suspend(pimpl_);
 }
 
 void Actor::resume()
 {
   simgrid::simix::kernelImmediate([this] { pimpl_->resume(); });
+  if (TRACE_actor_is_enabled())
+    simgrid::instr::Container::byName(instr_pid(this))->getState("MSG_PROCESS_STATE")->popEvent();
 }
 
 int Actor::isSuspended()
@@ -173,6 +203,11 @@ void Actor::killAll(int resetPid)
   simcall_process_killall(resetPid);
 }
 
+std::map<std::string, std::string>* Actor::getProperties()
+{
+  return simgrid::simix::kernelImmediate([this] { return this->pimpl_->getProperties(); });
+}
+
 /** Retrieve the property value (or nullptr if not set) */
 const char* Actor::getProperty(const char* key)
 {
@@ -214,6 +249,11 @@ void sleep_for(double duration)
     simcall_process_sleep(duration);
 }
 
+void yield()
+{
+  simgrid::simix::kernelImmediate([] { /* do nothing*/ });
+}
+
 XBT_PUBLIC(void) sleep_until(double timeout)
 {
   double now = SIMIX_get_clock();
@@ -223,10 +263,45 @@ XBT_PUBLIC(void) sleep_until(double timeout)
 
 void execute(double flops)
 {
-  smx_activity_t s = simcall_execution_start(nullptr,flops,1.0/*priority*/,0./*bound*/);
+  smx_activity_t s = simcall_execution_start(nullptr, flops, 1.0 /*priority*/, 0. /*bound*/, getHost());
+  simcall_execution_wait(s);
+}
+
+void execute(double flops, double priority)
+{
+  smx_activity_t s = simcall_execution_start(nullptr, flops, 1 / priority /*priority*/, 0. /*bound*/, getHost());
   simcall_execution_wait(s);
 }
 
+void parallel_execute(int host_nb, sg_host_t* host_list, double* flops_amount, double* bytes_amount, double timeout)
+{
+  smx_activity_t s =
+      simcall_execution_parallel_start(nullptr, host_nb, host_list, flops_amount, bytes_amount, -1, timeout);
+  simcall_execution_wait(s);
+}
+
+void parallel_execute(int host_nb, sg_host_t* host_list, double* flops_amount, double* bytes_amount)
+{
+  smx_activity_t s = simcall_execution_parallel_start(nullptr, host_nb, host_list, flops_amount, bytes_amount, -1, -1);
+  simcall_execution_wait(s);
+}
+
+ExecPtr exec_init(double flops_amount)
+{
+  ExecPtr res        = ExecPtr(new Exec());
+  res->host_         = getHost();
+  res->flops_amount_ = flops_amount;
+  res->setRemains(flops_amount);
+  return res;
+}
+
+ExecPtr exec_async(double flops)
+{
+  ExecPtr res = exec_init(flops);
+  res->start();
+  return res;
+}
+
 void* recv(MailboxPtr chan) // deprecated
 {
   return chan->get();
@@ -269,7 +344,12 @@ aid_t getPpid()
 
 std::string getName()
 {
-  return SIMIX_process_self()->name;
+  return SIMIX_process_self()->getName();
+}
+
+const char* getCname()
+{
+  return SIMIX_process_self()->getCname();
 }
 
 Host* getHost()
@@ -279,6 +359,10 @@ Host* getHost()
 
 void suspend()
 {
+  if (TRACE_actor_is_enabled())
+    instr::Container::byName(getName() + "-" + std::to_string(getPid()))
+        ->getState("MSG_PROCESS_STATE")
+        ->pushEvent("suspend");
   simcall_process_suspend(SIMIX_process_self());
 }
 
@@ -286,6 +370,9 @@ void resume()
 {
   smx_actor_t process = SIMIX_process_self();
   simgrid::simix::kernelImmediate([process] { process->resume(); });
+
+  if (TRACE_actor_is_enabled())
+    instr::Container::byName(getName() + "-" + std::to_string(getPid()))->getState("MSG_PROCESS_STATE")->popEvent();
 }
 
 bool isSuspended()
@@ -305,10 +392,13 @@ void onExit(int_f_pvoid_pvoid_t fun, void* data)
   simcall_process_on_exit(SIMIX_process_self(), fun, data);
 }
 
+/** @brief Moves the current actor to another host
+ *
+ * @see simgrid::s4u::Actor::migrate() for more information
+ */
 void migrate(Host* new_host)
 {
-  smx_actor_t process = SIMIX_process_self();
-  simgrid::simix::kernelImmediate([process, new_host] { process->new_host = new_host; });
+  SIMIX_process_self()->iface()->migrate(new_host);
 }
 }
 }