Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
one step toward a live migration plugin
authorFrederic Suter <frederic.suter@cc.in2p3.fr>
Mon, 18 Dec 2017 23:16:43 +0000 (00:16 +0100)
committerFrederic Suter <frederic.suter@cc.in2p3.fr>
Mon, 18 Dec 2017 23:51:47 +0000 (00:51 +0100)
have dirty page tracking in a separate plugin (kernel) and stop have
dirty page stuff when VM and Migration are not used.

Indeed, this plugin is only needed if vm have to be migrated live. In
that case, one should:
 1) #include "simgrid/plugins/live_migration.h"
 2) call "MSG/sg_vm_live_migration_plugin_init() right after the
    initialization of the simulation (MSG_init or s4u::Engine)

15 files changed:
examples/msg/cloud-capping/cloud-capping.c
examples/msg/cloud-masterworker/cloud-masterworker.c
examples/msg/cloud-migration/cloud-migration.c
include/simgrid/plugins/live_migration.h [new file with mode: 0644]
include/simgrid/s4u/VirtualMachine.hpp
src/msg/msg_gos.cpp
src/msg/msg_private.hpp
src/msg/msg_task.cpp
src/msg/msg_vm.cpp
src/plugins/vm/VirtualMachineImpl.cpp
src/plugins/vm/VirtualMachineImpl.hpp
src/plugins/vm/s4u_VirtualMachine.cpp
src/surf/plugins/dirty_page_tracking.cpp [new file with mode: 0644]
teshsuite/msg/cloud-simple/cloud-simple.c
tools/cmake/DefinePackages.cmake

index 4471034..5ef1028 100644 (file)
@@ -4,6 +4,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "simgrid/msg.h"
+#include "simgrid/plugins/live_migration.h"
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
 
@@ -296,6 +297,7 @@ int main(int argc, char *argv[])
 {
   /* Get the arguments */
   MSG_init(&argc, argv);
+  MSG_vm_live_migration_plugin_init();
 
   /* load the platform file */
   xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/small_platform.xml\n", argv[0], argv[0]);
index 12044ad..07c7556 100644 (file)
@@ -4,6 +4,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "simgrid/msg.h"
+#include "simgrid/plugins/live_migration.h"
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
 
@@ -175,6 +176,8 @@ int main(int argc, char *argv[])
   const int nb_workers = 2;
 
   MSG_init(&argc, argv);
+  MSG_vm_live_migration_plugin_init();
+
   xbt_assert(argc >1,"Usage: %s example/platforms/cluster.xml\n", argv[0]);
 
   /* Load the platform file */
index 5fd2143..2c13261 100644 (file)
@@ -5,6 +5,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "simgrid/msg.h"
+#include "simgrid/plugins/live_migration.h"
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
 
@@ -123,6 +124,7 @@ int main(int argc, char *argv[])
 {
   /* Get the arguments */
   MSG_init(&argc, argv);
+  MSG_vm_live_migration_plugin_init();
 
   /* load the platform file */
   MSG_create_environment(argv[1]);
diff --git a/include/simgrid/plugins/live_migration.h b/include/simgrid/plugins/live_migration.h
new file mode 100644 (file)
index 0000000..e61bdb7
--- /dev/null
@@ -0,0 +1,24 @@
+/* Copyright (c) 2017. The SimGrid Team.
+ * All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#ifndef SIMGRID_PLUGINS_LIVE_MIGRATION_H_
+#define SIMGRID_PLUGINS_LIVE_MIGRATION_H_
+
+#include <simgrid/forward.h>
+#include <xbt/base.h>
+
+SG_BEGIN_DECL()
+
+XBT_PUBLIC(void) sg_vm_live_migration_plugin_init();
+XBT_PUBLIC(void) sg_vm_start_dirty_page_tracking(sg_vm_t vm);
+XBT_PUBLIC(void) sg_vm_stop_dirty_page_tracking(sg_vm_t vm);
+XBT_PUBLIC(double) sg_vm_lookup_computed_flops(sg_vm_t vm);
+
+#define MSG_vm_live_migration_plugin_init() sg_vm_live_migration_plugin_init()
+
+SG_END_DECL()
+
+#endif
index 8dcfe49..a655e49 100644 (file)
@@ -63,9 +63,6 @@ public:
 
   /* FIXME: protect me */
   simgrid::vm::VirtualMachineImpl* pimpl_vm_ = nullptr;
-
-  static simgrid::xbt::signal<void(s4u::VirtualMachine&)> onCreation;
-  static simgrid::xbt::signal<void(s4u::VirtualMachine&)> onDestruction;
 };
 }
 } // namespace simgrid::s4u
index e5dc660..ad50af0 100644 (file)
@@ -22,14 +22,7 @@ extern "C" {
  */
 msg_error_t MSG_task_execute(msg_task_t task)
 {
-  /* TODO: add this to other locations */
-  msg_host_t host = MSG_process_get_host(MSG_process_self());
-  MSG_host_add_task(host, task);
-
-  msg_error_t ret = MSG_parallel_task_execute(task);
-
-  MSG_host_del_task(host, task);
-  return ret;
+  return MSG_parallel_task_execute(task);
 }
 
 /** \ingroup msg_task_usage
index 9eb7d1c..49328ac 100644 (file)
@@ -99,9 +99,6 @@ XBT_PRIVATE smx_actor_t MSG_process_create_from_SIMIX(const char* name, std::fun
                                                       smx_actor_t parent_process);
 XBT_PRIVATE void MSG_comm_copy_data_from_SIMIX(smx_activity_t comm, void* buff, size_t buff_size);
 
-XBT_PRIVATE void MSG_host_add_task(msg_host_t host, msg_task_t task);
-XBT_PRIVATE void MSG_host_del_task(msg_host_t host, msg_task_t task);
-
 /********** Tracing **********/
 /* declaration of instrumentation functions from msg_task_instr.c */
 XBT_PRIVATE void TRACE_msg_set_task_category(msg_task_t task, const char* category);
index b71d7fa..ae1f59c 100644 (file)
@@ -219,7 +219,6 @@ msg_error_t MSG_task_cancel(msg_task_t task)
   simdata_task_t simdata = task->simdata;
   if (simdata->compute) {
     simcall_execution_cancel(simdata->compute);
-    MSG_host_del_task(MSG_process_get_host(MSG_process_self()), task);
   } else if (simdata->comm) {
     simcall_comm_cancel(simdata->comm);
   }
index 34ab03d..e876a26 100644 (file)
@@ -11,8 +11,8 @@
 
 #include <xbt/ex.hpp>
 
+#include "simgrid/plugins/live_migration.h"
 #include "src/instr/instr_private.hpp"
-#include "src/msg/msg_private.hpp"
 #include "src/plugins/vm/VirtualMachineImpl.hpp"
 #include "src/plugins/vm/VmHostExt.hpp"
 
 
 extern "C" {
 
-struct s_dirty_page {
-  double prev_clock     = 0.0;
-  double prev_remaining = 0.0;
-  msg_task_t task       = nullptr;
-};
-typedef s_dirty_page* dirty_page_t;
-
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_vm, msg, "Cloud-oriented parts of the MSG API");
 
 const char* MSG_vm_get_name(msg_vm_t vm)
@@ -334,116 +327,6 @@ static int migration_rx_fun(int argc, char *argv[])
   return 0;
 }
 
-static void start_dirty_page_tracking(msg_vm_t vm)
-{
-  vm->pimpl_vm_->dp_enabled = true;
-  if (vm->pimpl_vm_->dp_objs.empty())
-    return;
-
-  for (auto const& elm : vm->pimpl_vm_->dp_objs) {
-    dirty_page_t dp    = elm.second;
-    double remaining   = MSG_task_get_flops_amount(dp->task);
-    dp->prev_clock = MSG_get_clock();
-    dp->prev_remaining = remaining;
-    XBT_DEBUG("%s@%s remaining %f", elm.first.c_str(), vm->getCname(), remaining);
-  }
-}
-
-static void stop_dirty_page_tracking(msg_vm_t vm)
-{
-  vm->pimpl_vm_->dp_enabled = false;
-}
-
-static double get_computed(const std::string& key, msg_vm_t vm, dirty_page_t dp, double remaining, double clock)
-{
-  double computed = dp->prev_remaining - remaining;
-  double duration = clock - dp->prev_clock;
-
-  XBT_DEBUG("%s@%s: computed %f ops (remaining %f -> %f) in %f secs (%f -> %f)", key.c_str(), vm->getCname(), computed,
-            dp->prev_remaining, remaining, duration, dp->prev_clock, clock);
-
-  return computed;
-}
-
-static double lookup_computed_flop_counts(msg_vm_t vm, int stage_for_fancy_debug, int stage2_round_for_fancy_debug)
-{
-  double total = 0;
-
-  for (auto const& elm : vm->pimpl_vm_->dp_objs) {
-    const std::string& key = elm.first;
-    dirty_page_t dp  = elm.second;
-    double remaining       = MSG_task_get_flops_amount(dp->task);
-
-    double clock = MSG_get_clock();
-
-    total += get_computed(key, vm, dp, remaining, clock);
-
-    dp->prev_remaining = remaining;
-    dp->prev_clock = clock;
-  }
-
-  total += vm->pimpl_vm_->dp_updated_by_deleted_tasks;
-
-  XBT_DEBUG("mig-stage%d.%d: computed %f flop_counts (including %f by deleted tasks)", stage_for_fancy_debug,
-            stage2_round_for_fancy_debug, total, vm->pimpl_vm_->dp_updated_by_deleted_tasks);
-
-  vm->pimpl_vm_->dp_updated_by_deleted_tasks = 0;
-
-  return total;
-}
-
-// TODO Is this code redundant with the information provided by
-// msg_process_t MSG_process_create(const char *name, xbt_main_func_t code, void *data, msg_host_t host)
-/** @brief take care of the dirty page tracking, in case we're adding a task to a migrating VM */
-void MSG_host_add_task(msg_host_t host, msg_task_t task)
-{
-  simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
-  if (vm == nullptr)
-    return;
-
-  double remaining = MSG_task_get_flops_amount(task);
-  std::string key  = simgrid::xbt::string_printf("%s-%p", task->name, task);
-
-  dirty_page_t dp = new s_dirty_page;
-  dp->task = task;
-  if (vm->pimpl_vm_->dp_enabled) {
-    dp->prev_clock = MSG_get_clock();
-    dp->prev_remaining = remaining;
-  }
-  vm->pimpl_vm_->dp_objs.insert({key, dp});
-  XBT_DEBUG("add %s on %s (remaining %f, dp_enabled %d)", key.c_str(), host->getCname(), remaining,
-            vm->pimpl_vm_->dp_enabled);
-}
-
-void MSG_host_del_task(msg_host_t host, msg_task_t task)
-{
-  simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(host);
-  if (vm == nullptr)
-    return;
-
-  std::string key = simgrid::xbt::string_printf("%s-%p", task->name, task);
-  dirty_page_t dp = nullptr;
-  auto dp_obj     = vm->pimpl_vm_->dp_objs.find(key);
-  if (dp_obj != vm->pimpl_vm_->dp_objs.end())
-    dp = dp_obj->second;
-  xbt_assert(dp && dp->task == task);
-
-  /* If we are in the middle of dirty page tracking, we record how much computation has been done until now, and keep
-   * the information for the lookup_() function that will called soon. */
-  if (vm->pimpl_vm_->dp_enabled) {
-    double remaining = MSG_task_get_flops_amount(task);
-    double clock = MSG_get_clock();
-    double updated = get_computed(key, vm, dp, remaining, clock); // was host instead of vm
-
-    vm->pimpl_vm_->dp_updated_by_deleted_tasks += updated;
-  }
-
-  vm->pimpl_vm_->dp_objs.erase(key);
-  delete dp;
-
-  XBT_DEBUG("del %s on %s", key.c_str(), host->getCname());
-}
-
 static sg_size_t send_migration_data(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm, sg_size_t size,
                                      const std::string& mbox, int stage, int stage2_round, double mig_speed,
                                      double timeout)
@@ -537,7 +420,7 @@ static int migration_tx_fun(int argc, char *argv[])
 
   /* Stage1: send all memory pages to the destination. */
   XBT_DEBUG("mig-stage1: remaining_size %zu", remaining_size);
-  start_dirty_page_tracking(ms->vm);
+  sg_vm_start_dirty_page_tracking(ms->vm);
 
   double computed_during_stage1 = 0;
   double clock_prev_send        = MSG_get_clock();
@@ -548,7 +431,7 @@ static int migration_tx_fun(int argc, char *argv[])
     XBT_VERB("Stage 1: Gonna send %llu bytes", ramsize);
     sg_size_t sent = send_migration_data(ms->vm, ms->src_pm, ms->dst_pm, ramsize, ms->mbox, 1, 0, mig_speed, -1);
     remaining_size -= sent;
-    computed_during_stage1 = lookup_computed_flop_counts(ms->vm, 1, 0);
+    computed_during_stage1 = sg_vm_lookup_computed_flops(ms->vm);
 
     if (sent < ramsize) {
       XBT_VERB("mig-stage1: timeout, force moving to stage 3");
@@ -559,7 +442,7 @@ static int migration_tx_fun(int argc, char *argv[])
   } catch (xbt_ex& e) {
     // hostfailure (if you want to know whether this is the SRC or the DST check directly in send_migration_data code)
     // Stop the dirty page tracking an return (there is no memory space to release)
-    stop_dirty_page_tracking(ms->vm);
+    sg_vm_stop_dirty_page_tracking(ms->vm);
     return 0;
   }
 
@@ -586,7 +469,7 @@ static int migration_tx_fun(int argc, char *argv[])
         /* just after stage1, nothing has been updated. But, we have to send the data updated during stage1 */
         updated_size = get_updated_size(computed_during_stage1, dp_rate, dp_cap);
       } else {
-        double computed = lookup_computed_flop_counts(ms->vm, 2, stage2_round);
+        double computed = sg_vm_lookup_computed_flops(ms->vm);
         updated_size    = get_updated_size(computed, dp_rate, dp_cap);
       }
 
@@ -610,7 +493,7 @@ static int migration_tx_fun(int argc, char *argv[])
         // hostfailure (if you want to know whether this is the SRC or the DST check directly in send_migration_data
         // code)
         // Stop the dirty page tracking an return (there is no memory space to release)
-        stop_dirty_page_tracking(ms->vm);
+        sg_vm_stop_dirty_page_tracking(ms->vm);
         return 0;
       }
       double clock_post_send = MSG_get_clock();
@@ -632,7 +515,7 @@ static int migration_tx_fun(int argc, char *argv[])
                  updated_size, (clock_post_send - clock_prev_send));
         remaining_size -= sent;
 
-        double computed = lookup_computed_flop_counts(ms->vm, 2, stage2_round);
+        double computed = sg_vm_lookup_computed_flops(ms->vm);
         updated_size    = get_updated_size(computed, dp_rate, dp_cap);
         remaining_size += updated_size;
         break;
@@ -647,7 +530,7 @@ static int migration_tx_fun(int argc, char *argv[])
   pimpl->setState(SURF_VM_STATE_RUNNING); // FIXME: this bypass of the checks in suspend() is not nice
   pimpl->isMigrating = false;             // FIXME: this bypass of the checks in suspend() is not nice
   pimpl->suspend(SIMIX_process_self());
-  stop_dirty_page_tracking(ms->vm);
+  sg_vm_stop_dirty_page_tracking(ms->vm);
 
   try {
     XBT_DEBUG("Stage 3: Gonna send %zu bytes", remaining_size);
index 87e2bad..8b5f1c8 100644 (file)
@@ -22,17 +22,17 @@ void surf_vm_model_init_HL13()
   }
 }
 
-namespace simgrid {
-namespace vm {
 
 /*************
  * Callbacks *
  *************/
 
-simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmCreation;
-simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmDestruction;
-simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmStateChange;
+simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> simgrid::vm::VirtualMachineImpl::onVmCreation;
+simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> simgrid::vm::VirtualMachineImpl::onVmDestruction;
+simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> simgrid::vm::VirtualMachineImpl::onVmStateChange;
 
+namespace simgrid {
+namespace vm {
 /*********
  * Model *
  *********/
@@ -125,6 +125,7 @@ VirtualMachineImpl::VirtualMachineImpl(simgrid::s4u::VirtualMachine* piface, sim
   action_ = host_PM->pimpl_cpu->execution_start(0, coreAmount);
 
   XBT_VERB("Create VM(%s)@PM(%s)", piface->getCname(), hostPM_->getCname());
+  onVmCreation(this);
 }
 
 /** @brief A physical host does not disappear in the current SimGrid code, but a VM may disappear during a simulation */
@@ -136,20 +137,6 @@ VirtualMachineImpl::~VirtualMachineImpl()
   if (iter != allVms_.end())
     allVms_.erase(iter);
 
-  /* dirty page tracking */
-  unsigned int size          = dp_objs.size();
-  static bool already_warned = false;
-  if (size > 0 && not already_warned) {
-    auto front = dp_objs.begin();
-    XBT_WARN("Dirty page tracking: %u pending task(s) on a destroyed VM (first one is %s).\n"
-             "If you don't understand why your task was not properly removed, please report that bug.\n"
-             "This is a known bug if you turned the host off during the VM execution.\n"
-             "Please remind us of that problem at some point: our code base is not ready to fix this harmless issue in "
-             "2016, sorry.",
-             size, (xbt_log_no_loc ? "(name hidden)" : front->first.c_str()));
-    already_warned = true;
-  }
-
   /* Free the cpu_action of the VM. */
   XBT_ATTRIB_UNUSED int ret = action_->unref();
   xbt_assert(ret == 1, "Bug: some resource still remains");
index 0dda5ea..553fffa 100644 (file)
@@ -21,25 +21,6 @@ typedef struct s_dirty_page* dirty_page_t;
 namespace simgrid {
 namespace vm {
 
-/*************
- * Callbacks *
- *************/
-
-/** @ingroup SURF_callbacks
- * @brief Callbacks fired after VM creation. Signature: `void(VirtualMachine*)`
- */
-extern XBT_PRIVATE simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmCreation;
-
-/** @ingroup SURF_callbacks
- * @brief Callbacks fired after VM destruction. Signature: `void(VirtualMachine*)`
- */
-extern XBT_PRIVATE simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmDestruction;
-
-/** @ingroup SURF_callbacks
- * @brief Callbacks after VM State changes. Signature: `void(VirtualMachine*)`
- */
-extern XBT_PRIVATE simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmStateChange;
-
 /************
  * Resource *
  ************/
@@ -48,7 +29,7 @@ extern XBT_PRIVATE simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)>
  * @brief SURF VM interface class
  * @details A VM represent a virtual machine
  */
-XBT_PUBLIC_CLASS VirtualMachineImpl : public surf::HostImpl
+XBT_PUBLIC_CLASS VirtualMachineImpl : public surf::HostImpl, public simgrid::xbt::Extendable<VirtualMachineImpl>
 {
   friend simgrid::s4u::VirtualMachine;
 
@@ -82,17 +63,29 @@ public:
   /* The vm object of the lower layer */
   surf::Action* action_ = nullptr;
 
-  /* Dirty pages stuff */
-  std::unordered_map<std::string, dirty_page_t> dp_objs;
-  bool dp_enabled                    = false;
-  double dp_updated_by_deleted_tasks = 0;
-
   e_surf_vm_state_t getState();
   void setState(e_surf_vm_state_t state);
   static std::deque<s4u::VirtualMachine*> allVms_;
   int coreAmount() { return coreAmount_; }
 
   bool isMigrating = false;
+  /*************
+   * Callbacks *
+   *************/
+  /** @ingroup SURF_callbacks
+   * @brief Callbacks fired after VM creation. Signature: `void(VirtualMachine*)`
+   */
+  static simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmCreation;
+
+  /** @ingroup SURF_callbacks
+   * @brief Callbacks fired after VM destruction. Signature: `void(VirtualMachine*)`
+   */
+  static simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmDestruction;
+
+  /** @ingroup SURF_callbacks
+   * @brief Callbacks after VM State changes. Signature: `void(VirtualMachine*)`
+   */
+  static simgrid::xbt::signal<void(simgrid::vm::VirtualMachineImpl*)> onVmStateChange;
 
 private:
   simgrid::s4u::Host* hostPM_;
index a4f2022..3ee05b2 100644 (file)
@@ -176,11 +176,5 @@ void VirtualMachine::setParameters(vm_params_t params)
   simgrid::simix::kernelImmediate([this, params] { pimpl_vm_->setParams(params); });
 }
 
-/*************
- * Callbacks *
- *************/
-simgrid::xbt::signal<void(s4u::VirtualMachine&)> VirtualMachine::onCreation;
-simgrid::xbt::signal<void(s4u::VirtualMachine&)> VirtualMachine::onDestruction;
-
 } // namespace simgrid
 } // namespace s4u
diff --git a/src/surf/plugins/dirty_page_tracking.cpp b/src/surf/plugins/dirty_page_tracking.cpp
new file mode 100644 (file)
index 0000000..e923f55
--- /dev/null
@@ -0,0 +1,120 @@
+/* Copyright (c) 2017. The SimGrid Team. All rights reserved.          */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "simgrid/plugins/live_migration.h"
+#include "simgrid/s4u.hpp"
+#include "src/plugins/vm/VirtualMachineImpl.hpp"
+#include <map>
+
+namespace simgrid {
+namespace vm {
+class VmDirtyPageTrackingExt {
+  bool dp_tracking = false;
+  std::map<kernel::activity::ExecImplPtr, double> dp_objs;
+  double dp_updated_by_deleted_tasks = 0;
+
+public:
+  void startTracking();
+  void stopTracking() { dp_tracking = false; }
+  bool isTracking() { return dp_tracking; }
+  void track(kernel::activity::ExecImplPtr exec, double amount) { dp_objs.insert({exec, amount}); }
+  void untrack(kernel::activity::ExecImplPtr exec) { dp_objs.erase(exec); }
+  double getStoredRemains(kernel::activity::ExecImplPtr exec) { return dp_objs.at(exec); }
+  void updateDirtyPageCount(double delta) { dp_updated_by_deleted_tasks += delta; }
+  double computedFlopsLookup();
+
+  static simgrid::xbt::Extension<VirtualMachineImpl, VmDirtyPageTrackingExt> EXTENSION_ID;
+  virtual ~VmDirtyPageTrackingExt() = default;
+  VmDirtyPageTrackingExt()          = default;
+};
+
+simgrid::xbt::Extension<VirtualMachineImpl, VmDirtyPageTrackingExt> VmDirtyPageTrackingExt::EXTENSION_ID;
+
+void VmDirtyPageTrackingExt::startTracking()
+{
+  dp_tracking = true;
+  for (auto const& elm : dp_objs)
+    dp_objs[elm.first] = elm.first->remains();
+}
+
+double VmDirtyPageTrackingExt::computedFlopsLookup()
+{
+  double total = 0;
+
+  for (auto const& elm : dp_objs) {
+    total += elm.second - elm.first->remains();
+    dp_objs[elm.first] = elm.first->remains();
+  }
+  total += dp_updated_by_deleted_tasks;
+
+  dp_updated_by_deleted_tasks = 0;
+
+  return total;
+}
+}
+}
+
+static void onVirtualMachineCreation(simgrid::vm::VirtualMachineImpl* vm)
+{
+  vm->extension_set<simgrid::vm::VmDirtyPageTrackingExt>(new simgrid::vm::VmDirtyPageTrackingExt());
+}
+
+static void onExecCreation(simgrid::kernel::activity::ExecImplPtr exec)
+{
+  simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(exec->host_);
+  if (vm == nullptr)
+    return;
+
+  if (vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->isTracking()) {
+    vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->track(exec, exec->remains());
+  } else {
+    vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->track(exec, 0.0);
+  }
+}
+
+static void onExecDestruction(simgrid::kernel::activity::ExecImplPtr exec)
+{
+  simgrid::s4u::VirtualMachine* vm = dynamic_cast<simgrid::s4u::VirtualMachine*>(exec->host_);
+  if (vm == nullptr)
+    return;
+
+  /* If we are in the middle of dirty page tracking, we record how much computation has been done until now, and keep
+   * the information for the lookup_() function that will called soon. */
+  if (vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->isTracking()) {
+    double delta =
+        vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->getStoredRemains(exec) - exec->remains();
+    vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->updateDirtyPageCount(delta);
+  }
+  vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->untrack(exec);
+}
+
+SG_BEGIN_DECL()
+
+void sg_vm_live_migration_plugin_init()
+{
+  if (not simgrid::vm::VmDirtyPageTrackingExt::EXTENSION_ID.valid()) {
+    simgrid::vm::VmDirtyPageTrackingExt::EXTENSION_ID =
+        simgrid::vm::VirtualMachineImpl::extension_create<simgrid::vm::VmDirtyPageTrackingExt>();
+    simgrid::vm::VirtualMachineImpl::onVmCreation.connect(&onVirtualMachineCreation);
+    simgrid::kernel::activity::ExecImpl::onCreation.connect(&onExecCreation);
+    simgrid::kernel::activity::ExecImpl::onDestruction.connect(&onExecDestruction);
+  }
+}
+
+void sg_vm_start_dirty_page_tracking(sg_vm_t vm)
+{
+  vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->startTracking();
+}
+
+void sg_vm_stop_dirty_page_tracking(sg_vm_t vm)
+{
+  vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->stopTracking();
+}
+
+double sg_vm_lookup_computed_flops(sg_vm_t vm)
+{
+  return vm->pimpl_vm_->extension<simgrid::vm::VmDirtyPageTrackingExt>()->computedFlopsLookup();
+}
+SG_END_DECL()
index ad7b095..bd71be2 100644 (file)
@@ -4,6 +4,8 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "simgrid/msg.h"
+#include "simgrid/plugins/live_migration.h"
+
 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
 
 static int computation_fun(int argc, char* argv[])
@@ -263,6 +265,7 @@ int main(int argc, char* argv[])
 {
   /* Get the arguments */
   MSG_init(&argc, argv);
+  sg_vm_live_migration_plugin_init();
 
   /* load the platform file */
   const char* platform = "../../platforms/small_platform.xml";
index 38517be..92cf23e 100644 (file)
@@ -340,6 +340,7 @@ set(SURF_SRC
   src/surf/network_cm02.cpp
   src/surf/network_constant.cpp
   src/surf/network_interface.cpp
+  src/surf/plugins/dirty_page_tracking.cpp
   src/surf/plugins/host_energy.cpp
   src/surf/plugins/link_energy.cpp
   src/surf/plugins/host_load.cpp
@@ -667,6 +668,7 @@ set(headers_to_install
   include/simgrid/chrono.hpp
   include/simgrid/plugins/energy.h
   include/simgrid/plugins/file_system.h
+  include/simgrid/plugins/live_migration.h
   include/simgrid/plugins/load.h
   include/simgrid/instr.h
   include/simgrid/msg.h
@@ -695,8 +697,6 @@ set(headers_to_install
   include/simgrid/s4u/Storage.hpp  
   include/simgrid/s4u/VirtualMachine.hpp  
   include/simgrid/s4u.hpp
-  include/simgrid/plugins/energy.h
-  include/simgrid/plugins/load.h
   include/smpi/mpi.h
   include/smpi/smpi.h
   include/smpi/smpi_main.h