Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Activity refactoring
authorSUTER Frederic <frederic.suter@cc.in2p3.fr>
Wed, 22 Dec 2021 10:18:22 +0000 (11:18 +0100)
committerSUTER Frederic <frederic.suter@cc.in2p3.fr>
Wed, 22 Dec 2021 10:20:34 +0000 (11:20 +0100)
Move on_completion signal, complete method, and actor_ + piface_ field
from Exec/Comm/Io to Actitity.

this implies to modifies all the callbacks on Exec::on_completion to
filter out other types of activities

24 files changed:
examples/cpp/dag-failure/s4u-dag-failure.cpp
examples/cpp/dag-io/s4u-dag-io.cpp
examples/cpp/dag-simple/s4u-dag-simple.cpp
include/simgrid/s4u/Activity.hpp
include/simgrid/s4u/Comm.hpp
include/simgrid/s4u/Exec.hpp
include/simgrid/s4u/Io.hpp
src/instr/instr_platform.cpp
src/kernel/EngineImpl.cpp
src/kernel/activity/ActivityImpl.hpp
src/kernel/activity/CommImpl.hpp
src/kernel/activity/ExecImpl.cpp
src/kernel/activity/ExecImpl.hpp
src/kernel/activity/IoImpl.cpp
src/kernel/activity/IoImpl.hpp
src/kernel/resource/VirtualMachineImpl.cpp
src/plugins/host_dvfs.cpp
src/plugins/host_load.cpp
src/plugins/vm/dirty_page_tracking.cpp
src/s4u/s4u_Activity.cpp
src/s4u/s4u_Comm.cpp
src/s4u/s4u_Exec.cpp
src/s4u/s4u_Io.cpp
teshsuite/s4u/dependencies/dependencies.cpp

index 992ad5e..a3da8aa 100644 (file)
@@ -18,16 +18,19 @@ int main(int argc, char** argv)
 
   auto* faulty = e.host_by_name("Faulty Host");
   auto* safe   = e.host_by_name("Safe Host");
-  sg4::Exec::on_completion.connect([](sg4::Exec const& exec) {
-    if (exec.get_state() == sg4::Activity::State::FINISHED)
-      XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(),
-               exec.get_finish_time());
-    if (exec.get_state() == sg4::Activity::State::FAILED) {
-      if (exec.is_parallel())
-        XBT_INFO("Activity '%s' has failed. %.f %% remain to be done", exec.get_cname(),
-                 100 * exec.get_remaining_ratio());
+  sg4::Activity::on_completion.connect([](sg4::Activity& activity) {
+    auto* exec = dynamic_cast<simgrid::s4u::Exec*>(&activity);
+    if (exec == nullptr) // Only Execs are concerned here
+      return;
+    if (exec->get_state() == sg4::Activity::State::FINISHED)
+      XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
+               exec->get_finish_time());
+    if (exec->get_state() == sg4::Activity::State::FAILED) {
+      if (exec->is_parallel())
+        XBT_INFO("Activity '%s' has failed. %.f %% remain to be done", exec->get_cname(),
+                 100 * exec->get_remaining_ratio());
       else
-        XBT_INFO("Activity '%s' has failed. %.f flops remain to be done", exec.get_cname(), exec.get_remaining());
+        XBT_INFO("Activity '%s' has failed. %.f flops remain to be done", exec->get_cname(), exec->get_remaining());
     }
   });
 
index 74f3d35..12077c7 100644 (file)
@@ -24,9 +24,12 @@ int main(int argc, char* argv[])
              (a.dependencies_solved() ? "solved" : "NOT solved"), (a.is_assigned() ? "assigned" : "NOT assigned"));
   });
 
-  simgrid::s4u::Exec::on_completion.connect([](simgrid::s4u::Exec const& exec) {
-    XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(),
-             exec.get_finish_time());
+  simgrid::s4u::Activity::on_completion.connect([](simgrid::s4u::Activity& activity) {
+    auto* exec = dynamic_cast<simgrid::s4u::Exec*>(&activity);
+    if (exec == nullptr) // Only Execs are concerned here
+      return;
+    XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
+             exec->get_finish_time());
   });
 
   // Create a small DAG: parent->write_output->read_input->child
index 5bad702..f3fa340 100644 (file)
@@ -26,9 +26,12 @@ int main(int argc, char* argv[])
              (exec.is_assigned() ? "assigned" : "NOT assigned"));
   });
 
-  simgrid::s4u::Exec::on_completion.connect([](simgrid::s4u::Exec const& exec) {
-    XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec.get_cname(), exec.get_start_time(),
-             exec.get_finish_time());
+  simgrid::s4u::Activity::on_completion.connect([](simgrid::s4u::Activity& activity) {
+    auto* exec = dynamic_cast<simgrid::s4u::Exec*>(&activity);
+    if (exec == nullptr) // Only Execs are concerned here
+      return;
+    XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
+             exec->get_finish_time());
   });
 
   // Define an amount of work that should take 1 second to execute.
index d64f99a..d9f0958 100644 (file)
@@ -43,13 +43,6 @@ protected:
   Activity()  = default;
   virtual ~Activity() = default;
 
-  virtual void complete(Activity::State state)
-  {
-    state_ = state;
-    if (state == State::FINISHED)
-      release_dependencies();
-  }
-
   void release_dependencies()
   {
     while (not successors_.empty()) {
@@ -94,6 +87,8 @@ public:
   /*! Signal fired each time that the activity fails to start because of a veto (e.g., unsolved dependency or no
    * resource assigned) */
   static xbt::signal<void(Activity&)> on_veto;
+  /*! Signal fired when theactivity completes  (either normally, cancelled or failed) */
+  static xbt::signal<void(Activity&)> on_completion;
 
   void vetoable_start()
   {
@@ -108,6 +103,14 @@ public:
     }
   }
 
+  void complete(Activity::State state)
+  {
+    state_ = state;
+    if (state == State::FINISHED)
+      release_dependencies();
+    on_completion(*this);
+  }
+
   static std::set<Activity*>* get_vetoed_activities() { return vetoed_activities_; }
   static void set_vetoed_activities(std::set<Activity*>* whereto) { vetoed_activities_ = whereto; }
 
index b42d1e9..8a5fe9f 100644 (file)
@@ -37,9 +37,6 @@ class XBT_PUBLIC Comm : public Activity_T<Comm> {
 
   Comm() = default;
 
-protected:
-  void complete(Activity::State state) override;
-
 public:
 #ifndef DOXYGEN
   friend Mailbox; // Factory of comms
index 4f3ea0f..09af6ea 100644 (file)
@@ -40,7 +40,6 @@ class XBT_PUBLIC Exec : public Activity_T<Exec> {
 protected:
   explicit Exec(kernel::activity::ExecImplPtr pimpl);
 
-  void complete(Activity::State state) override;
   void reset();
 
 public:
@@ -50,8 +49,6 @@ public:
 #endif
   /*! Signal fired each time that an execution actually starts (no veto) */
   static xbt::signal<void(Exec const&)> on_start;
-  /*! Signal fired each time that an execution terminates (either normally, cancelled or failed) */
-  static xbt::signal<void(Exec const&)> on_completion;
 
   static ExecPtr init();
   Exec* start() override;
index 841f18b..8dc9f06 100644 (file)
@@ -28,13 +28,10 @@ class XBT_PUBLIC Io : public Activity_T<Io> {
 protected:
   explicit Io(kernel::activity::IoImplPtr pimpl);
 
-  void complete(Activity::State state) override;
-
 public:
   enum class OpType { READ, WRITE };
 
   static xbt::signal<void(Io const&)> on_start;
-  static xbt::signal<void(Io const&)> on_completion;
 
   static IoPtr init();
   Io* start() override;
index 8853454..801cd44 100644 (file)
@@ -467,7 +467,7 @@ void define_callbacks()
     s4u::Exec::on_start.connect([](s4u::Exec const&) {
       Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("execute");
     });
-    s4u::Exec::on_completion.connect([](s4u::Exec const&) {
+    s4u::Activity::on_completion.connect([](s4u::Activity&) {
       Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->pop_event();
     });
     s4u::Comm::on_send.connect([](s4u::Comm const&) {
@@ -476,9 +476,6 @@ void define_callbacks()
     s4u::Comm::on_recv.connect([](s4u::Comm const&) {
       Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->push_event("receive");
     });
-    s4u::Comm::on_completion.connect([](s4u::Comm const&) {
-      Container::by_name(instr_pid(*s4u::Actor::self()))->get_state("ACTOR_STATE")->pop_event();
-    });
     s4u::Actor::on_host_change.connect(on_actor_host_change);
   }
 
@@ -488,7 +485,7 @@ void define_callbacks()
           ->get_state("MPI_STATE")
           ->push_event("computing", new CpuTIData("compute", exec.get_cost()));
     });
-    s4u::Exec::on_completion.connect([](s4u::Exec const&) {
+    s4u::Activity::on_completion.connect([](s4u::Activity&) {
       Container::by_name(std::string("rank-") + std::to_string(s4u::Actor::self()->get_pid()))
           ->get_state("MPI_STATE")
           ->pop_event();
index 5e3dfeb..24116e2 100644 (file)
@@ -419,13 +419,8 @@ void EngineImpl::wake_all_waiting_actors() const
       if (action->get_activity() != nullptr) {
         // If nobody told the interface that the activity has failed, that's because no actor waits on it (maestro
         // started it). SimDAG I see you!
-        auto* exec = dynamic_cast<activity::ExecImpl*>(action->get_activity());
-        if (exec != nullptr && exec->get_actor() == maestro_)
-          exec->get_iface()->complete(s4u::Activity::State::FAILED);
-
-        auto* io = dynamic_cast<activity::IoImpl*>(action->get_activity());
-        if (io != nullptr && io->get_actor() == maestro_)
-          io->get_iface()->complete(s4u::Activity::State::FAILED);
+        if (action->get_activity()->get_actor() == maestro_)
+          action->get_activity()->get_iface()->complete(s4u::Activity::State::FAILED);
 
         activity::ActivityImplPtr(action->get_activity())->post();
       }
index 5370636..5ba6e15 100644 (file)
@@ -33,6 +33,8 @@ public:
   State state_   = State::WAITING;      /* State of the activity */
   std::list<smx_simcall_t> simcalls_;   /* List of simcalls waiting for this activity */
   resource::Action* surf_action_ = nullptr;
+  actor::ActorImpl* actor_       = nullptr;
+  s4u::Activity* piface_         = nullptr;
 
 protected:
   void inline set_name(const std::string& name)
@@ -46,6 +48,12 @@ public:
   const std::string& get_name() const { return name_; }
   const char* get_cname() const { return name_.c_str(); }
 
+  void set_actor(actor::ActorImpl* actor) { actor_ = actor; }
+  actor::ActorImpl* get_actor() const { return actor_; }
+
+  void set_iface(s4u::Activity* iface) { piface_ = iface; }
+  s4u::Activity* get_iface() { return piface_; }
+
   virtual bool test();
   virtual void wait_for(actor::ActorImpl* issuer, double timeout);
   virtual ActivityImpl& set_timeout(double) { THROW_UNIMPLEMENTED; }
index b190e8e..a71052f 100644 (file)
@@ -26,7 +26,6 @@ class XBT_PUBLIC CommImpl : public ActivityImpl_T<CommImpl> {
   MailboxImpl* mbox_ = nullptr; /* Rendez-vous where the comm is queued */
   s4u::Host* from_   = nullptr; /* Pre-determined only for direct host-to-host communications */
   s4u::Host* to_     = nullptr; /* Otherwise, computed at start() time from the actors */
-  s4u::Comm* piface_ = nullptr;
 
 public:
   enum class Type { SEND, RECEIVE };
@@ -36,8 +35,6 @@ public:
   explicit CommImpl(Type type) : type_(type) {}
   CommImpl(s4u::Host* from, s4u::Host* to, double bytes);
 
-  void set_iface(s4u::Comm* piface) { piface_ = piface; }
-  s4u::Comm* get_iface() const { return piface_; }
   CommImpl& set_size(double size);
   CommImpl& set_src_buff(unsigned char* buff, size_t size);
   CommImpl& set_dst_buff(unsigned char* buff, size_t* size);
index 84ec670..d5a019c 100644 (file)
@@ -26,7 +26,7 @@ ExecImpl::ExecImpl()
   piface_                = new s4u::Exec(this);
   actor::ActorImpl* self = actor::ActorImpl::self();
   if (self) {
-    actor_ = self;
+    set_actor(self);
     self->activities_.emplace_back(this);
   }
 }
@@ -158,8 +158,8 @@ void ExecImpl::post()
 
   clean_action();
   timeout_detector_.reset();
-  if (actor_) {
-    actor_->activities_.remove(this);
+  if (get_actor() != nullptr) {
+    get_actor()->activities_.remove(this);
   }
   if (state_ != State::FAILED && cb_id_ >= 0)
     s4u::Host::on_state_change.disconnect(cb_id_);
@@ -171,7 +171,7 @@ void ExecImpl::set_exception(actor::ActorImpl* issuer)
 {
   switch (state_) {
     case State::FAILED:
-      piface_->complete(s4u::Activity::State::FAILED);
+      static_cast<s4u::Exec*>(get_iface())->complete(s4u::Activity::State::FAILED);
       if (issuer->get_host()->is_on())
         issuer->exception_ = std::make_exception_ptr(HostFailureException(XBT_THROW_POINT, "Host failed"));
       else /* else, the actor will be killed with no possibility to survive */
index 9ce7ef5..c5780a2 100644 (file)
@@ -18,7 +18,6 @@ namespace activity {
 class XBT_PUBLIC ExecImpl : public ActivityImpl_T<ExecImpl> {
   std::unique_ptr<resource::Action, std::function<void(resource::Action*)>> timeout_detector_{
       nullptr, [](resource::Action* a) { a->unref(); }};
-  actor::ActorImpl* actor_            = nullptr;
   double sharing_penalty_             = 1.0;
   double bound_                       = 0.0;
   double start_time_                  = -1.0;
@@ -26,13 +25,10 @@ class XBT_PUBLIC ExecImpl : public ActivityImpl_T<ExecImpl> {
   std::vector<s4u::Host*> hosts_;
   std::vector<double> flops_amounts_;
   std::vector<double> bytes_amounts_;
-  s4u::Exec* piface_;
   int cb_id_ = -1; // callback id from Host::on_state_change.connect()
 
 public:
   ExecImpl();
-  s4u::Exec* get_iface() { return piface_; }
-  actor::ActorImpl* get_actor() { return actor_; }
 
   ExecImpl& set_timeout(double timeout) override;
   ExecImpl& set_bound(double bound);
index a6dcf3a..874ea95 100644 (file)
@@ -28,7 +28,7 @@ IoImpl::IoImpl()
   piface_ = new s4u::Io(this);
   actor::ActorImpl* self = actor::ActorImpl::self();
   if (self) {
-    actor_ = self;
+    set_actor(self);
     self->activities_.emplace_back(this);
   }
 }
@@ -118,7 +118,7 @@ void IoImpl::set_exception(actor::ActorImpl* issuer)
   switch (state_) {
     case State::FAILED:
       issuer->context_->set_wannadie();
-      piface_->complete(s4u::Activity::State::FAILED);
+      static_cast<s4u::Io*>(get_iface())->complete(s4u::Activity::State::FAILED);
       issuer->exception_ = std::make_exception_ptr(StorageFailureException(XBT_THROW_POINT, "Storage failed"));
       break;
     case State::CANCELED:
index ed3c705..c03f48c 100644 (file)
@@ -14,18 +14,14 @@ namespace kernel {
 namespace activity {
 
 class XBT_PUBLIC IoImpl : public ActivityImpl_T<IoImpl> {
-  actor::ActorImpl* actor_            = nullptr;
   resource::DiskImpl* disk_           = nullptr;
   double sharing_penalty_             = 1.0;
   sg_size_t size_                     = 0;
   s4u::Io::OpType type_               = s4u::Io::OpType::READ;
   sg_size_t performed_ioops_          = 0;
   resource::Action* timeout_detector_ = nullptr;
-  s4u::Io* piface_;
 public:
   IoImpl();
-  s4u::Io* get_iface() { return piface_; }
-  actor::ActorImpl* get_actor() { return actor_; }
 
   IoImpl& set_sharing_penalty(double sharing_penalty);
   IoImpl& set_timeout(double timeout) override;
index 054ac5c..de7fddb 100644 (file)
@@ -75,9 +75,12 @@ static void add_active_exec(s4u::Exec const& task)
   }
 }
 
-static void remove_active_exec(s4u::Exec const& task)
+static void remove_active_exec(s4u::Activity& task)
 {
-  const s4u::VirtualMachine* vm = dynamic_cast<s4u::VirtualMachine*>(task.get_host());
+  auto* exec = dynamic_cast<s4u::Exec*>(&task);
+  if (exec == nullptr)
+    return;
+  const s4u::VirtualMachine* vm = dynamic_cast<s4u::VirtualMachine*>(exec->get_host());
   if (vm != nullptr) {
     VirtualMachineImpl* vm_impl = vm->get_vm_impl();
     vm_impl->remove_active_exec();
@@ -115,7 +118,7 @@ VMModel::VMModel(const std::string& name) : HostModel(name)
 {
   s4u::Host::on_state_change.connect(host_state_change);
   s4u::Exec::on_start.connect(add_active_exec);
-  s4u::Exec::on_completion.connect(remove_active_exec);
+  s4u::Activity::on_completion.connect(remove_active_exec);
   activity::ActivityImpl::on_resumed.connect(add_active_activity);
   activity::ActivityImpl::on_suspended.connect(remove_active_activity);
 }
index c51a26d..bc6203b 100644 (file)
@@ -299,11 +299,14 @@ public:
       if (activity.get_host() == get_host())
         pre_task();
     });
-    simgrid::s4u::Exec::on_completion.connect([this](simgrid::s4u::Exec const& activity) {
+    simgrid::s4u::Activity::on_completion.connect([this](simgrid::s4u::Activity& activity) {
+      auto* exec = dynamic_cast<simgrid::s4u::Exec*>(&activity);
+      if (exec == nullptr) // Only Execs are concerned here
+        return;
       // For more than one host (not yet supported), we can access the host via
       // simcalls_.front()->issuer->get_iface()->get_host()
-      if (activity.get_host() == get_host() && iteration_running) {
-        comp_timer += activity.get_finish_time() - activity.get_start_time();
+      if (exec->get_host() == get_host() && iteration_running) {
+        comp_timer += exec->get_finish_time() - exec->get_start_time();
       }
     });
     // FIXME I think that this fires at the same time for all hosts, so when the src sends something,
index 278dab8..545befb 100644 (file)
@@ -249,16 +249,18 @@ void sg_host_load_plugin_init()
       XBT_WARN("HostLoad plugin currently does not support executions on several hosts");
     }
   });
-  simgrid::s4u::Exec::on_completion.connect([](simgrid::s4u::Exec const& activity) {
-    if (activity.get_host_number() == 1) { // We only run on one host
-      simgrid::s4u::Host* host         = activity.get_host();
+  simgrid::s4u::Activity::on_completion.connect([](simgrid::s4u::Activity& activity) {
+    auto* exec = dynamic_cast<simgrid::s4u::Exec*>(&activity);
+    if (exec == nullptr) // Only Execs are concerned here
+      return;
+    if (exec->get_host_number() == 1) { // We only run on one host
+      simgrid::s4u::Host* host               = exec->get_host();
       const simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
       if (vm != nullptr)
         host = vm->get_pm();
       xbt_assert(host != nullptr);
       host->extension<HostLoad>()->update();
-    }
-    else { // This runs on multiple hosts
+    } else { // This runs on multiple hosts
       XBT_WARN("HostLoad plugin currently does not support executions on several hosts");
     }
   });
index 501e3be..c128303 100644 (file)
@@ -92,9 +92,11 @@ static void on_exec_creation(simgrid::s4u::Exec const& e)
   }
 }
 
-static void on_exec_completion(simgrid::s4u::Exec const& e)
+static void on_exec_completion(simgrid::s4u::Activity& e)
 {
-  auto exec                              = static_cast<simgrid::kernel::activity::ExecImpl*>(e.get_impl());
+  auto exec = dynamic_cast<simgrid::kernel::activity::ExecImpl*>(e.get_impl());
+  if (exec == nullptr)
+    return;
   const simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(exec->get_host());
   if (vm == nullptr)
     return;
@@ -115,7 +117,7 @@ void sg_vm_dirty_page_tracking_init()
         simgrid::kernel::resource::VirtualMachineImpl::extension_create<DirtyPageTrackingExt>();
     simgrid::s4u::VirtualMachine::on_creation.connect(&on_virtual_machine_creation);
     simgrid::s4u::Exec::on_start.connect(&on_exec_creation);
-    simgrid::s4u::Exec::on_completion.connect(&on_exec_completion);
+    simgrid::s4u::Activity::on_completion.connect(&on_exec_completion);
   }
 }
 
index b5c7478..1ea5899 100644 (file)
@@ -20,6 +20,7 @@ namespace simgrid {
 namespace s4u {
 
 xbt::signal<void(Activity&)> Activity::on_veto;
+xbt::signal<void(Activity&)> Activity::on_completion;
 
 std::set<Activity*>* Activity::vetoed_activities_ = nullptr;
 
index c58896f..2b4bcd6 100644 (file)
@@ -23,12 +23,6 @@ xbt::signal<void(Comm const&)> Comm::on_send;
 xbt::signal<void(Comm const&)> Comm::on_recv;
 xbt::signal<void(Comm const&)> Comm::on_completion;
 
-void Comm::complete(Activity::State state)
-{
-  Activity::complete(state);
-  on_completion(*this);
-}
-
 Comm::~Comm()
 {
   if (state_ == State::STARTED && not detached_ &&
@@ -163,6 +157,7 @@ CommPtr Comm::set_payload_size(uint64_t bytes)
 CommPtr Comm::sendto_init(Host* from, Host* to)
 {
   CommPtr res(new Comm());
+  res->sender_ = kernel::actor::ActorImpl::self();
   res->from_ = from;
   res->to_   = to;
 
@@ -212,8 +207,11 @@ Comm* Comm::start()
   if (suspended_)
     pimpl_->suspend();
 
-  if (not detached_)
-    static_cast<kernel::activity::CommImpl*>(pimpl_.get())->set_iface(this);
+  if (not detached_) {
+    pimpl_->set_iface(this);
+    pimpl_->set_actor(sender_);
+  }
+
   state_ = State::STARTED;
   return this;
 }
index 06440b4..4efdc11 100644 (file)
@@ -17,18 +17,12 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_exec, s4u_activity, "S4U asynchronous execut
 namespace simgrid {
 namespace s4u {
 xbt::signal<void(Exec const&)> Exec::on_start;
-xbt::signal<void(Exec const&)> Exec::on_completion;
 
 Exec::Exec(kernel::activity::ExecImplPtr pimpl)
 {
   pimpl_ = pimpl;
 }
 
-void Exec::complete(Activity::State state)
-{
-  Activity::complete(state);
-  on_completion(*this);
-}
 void Exec::reset()
 {
   boost::static_pointer_cast<kernel::activity::ExecImpl>(pimpl_)->reset();
@@ -45,7 +39,7 @@ ExecPtr Exec::init()
     }
   });
   pimpl->set_cb_id(cb_id);
-  return ExecPtr(pimpl->get_iface());
+  return ExecPtr(static_cast<Exec*>(pimpl->get_iface()));
 }
 
 Exec* Exec::start()
index ea8960b..83c8a1d 100644 (file)
 namespace simgrid {
 namespace s4u {
 xbt::signal<void(Io const&)> Io::on_start;
-xbt::signal<void(Io const&)> Io::on_completion;
 
 Io::Io(kernel::activity::IoImplPtr pimpl)
 {
   pimpl_ = pimpl;
 }
 
-void Io::complete(Activity::State state)
-{
-  Activity::complete(state);
-  on_completion(*this);
-}
-
 IoPtr Io::init()
 {
   auto pimpl = kernel::activity::IoImplPtr(new kernel::activity::IoImpl());
-  return IoPtr(pimpl->get_iface());
+  return IoPtr(static_cast<Io*>(pimpl->get_iface()));
 }
 
 Io* Io::start()
index 697c512..6a9cf63 100644 (file)
@@ -13,9 +13,12 @@ int main(int argc, char** argv)
   xbt_assert(argc > 1, "Usage: %s platform_file\n\nExample: %s two_clusters.xml", argv[0], argv[0]);
   e.load_platform(argv[1]);
 
-  simgrid::s4u::Exec::on_completion.connect([](simgrid::s4u::Exec const& exec) {
-    XBT_INFO("Exec '%s' start time: %f, finish time: %f", exec.get_cname(), exec.get_start_time(),
-             exec.get_finish_time());
+  simgrid::s4u::Activity::on_completion.connect([](simgrid::s4u::Activity& activity) {
+    auto* exec = dynamic_cast<simgrid::s4u::Exec*>(&activity);
+    if (exec == nullptr) // Only Execs are concerned here
+      return;
+    XBT_INFO("Exec '%s' start time: %f, finish time: %f", exec->get_cname(), exec->get_start_time(),
+             exec->get_finish_time());
   });
 
   /* creation of the activities and their dependencies */