Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
snake_casing the dirty page tracking plugin
[simgrid.git] / src / surf / plugins / link_energy.cpp
index f3b3055..0640a88 100644 (file)
@@ -1,18 +1,15 @@
-/* Copyright (c) 2017. The SimGrid Team. All rights reserved.               */
+/* Copyright (c) 2017-2018. 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/energy.h"
 #include "simgrid/s4u/Engine.hpp"
-#include "simgrid/simix.hpp"
 #include "src/surf/network_interface.hpp"
+#include "surf/surf.hpp"
+
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
 
 /** @addtogroup SURF_plugin_energy
 
@@ -52,7 +49,7 @@ public:
   ~LinkEnergy();
 
   void initWattsRangeList();
-  double getTotalEnergy();
+  double getConsumedEnergy();
   void update();
 
 private:
@@ -105,12 +102,12 @@ void LinkEnergy::initWattsRangeList()
     boost::split(current_power_values, current_power_values_str, boost::is_any_of(":"));
     xbt_assert(current_power_values.size() == 2,
                "Power properties incorrectly defined - could not retrieve idle and busy power values for link %s",
-               this->link_->getCname());
+               this->link_->get_cname());
 
     /* min_power corresponds to the idle power (link load = 0) */
     /* max_power is the power consumed at 100% link load       */
-    char* idleMsg = bprintf("Invalid idle power value for link%s", this->link_->getCname());
-    char* busyMsg = bprintf("Invalid busy power value for %s", this->link_->getCname());
+    char* idleMsg = bprintf("Invalid idle power value for link%s", this->link_->get_cname());
+    char* busyMsg = bprintf("Invalid busy power value for %s", this->link_->get_cname());
 
     idle_ = xbt_str_parse_double((current_power_values.at(0)).c_str(), idleMsg);
     busy_ = xbt_str_parse_double((current_power_values.at(1)).c_str(), busyMsg);
@@ -135,9 +132,10 @@ double LinkEnergy::getPower()
   return idle_ + dynamic_power;
 }
 
-double LinkEnergy::getTotalEnergy()
+double LinkEnergy::getConsumedEnergy()
 {
-  update();
+  if (lastUpdated_ < surf_get_clock()) // We need to simcall this as it modifies the environment
+    simgrid::simix::kernelImmediate(std::bind(&LinkEnergy::update, this));
   return this->totalEnergy_;
 }
 }
@@ -146,15 +144,16 @@ double LinkEnergy::getTotalEnergy()
 using simgrid::plugin::LinkEnergy;
 
 /* **************************** events  callback *************************** */
-static void onCommunicate(simgrid::surf::NetworkAction* action, simgrid::s4u::Host* src, simgrid::s4u::Host* dst)
+static void onCommunicate(simgrid::kernel::resource::NetworkAction* action, simgrid::s4u::Host* src,
+                          simgrid::s4u::Host* dst)
 {
   XBT_DEBUG("onCommunicate is called");
-  for (simgrid::surf::LinkImpl* link : action->links()) {
+  for (simgrid::kernel::resource::LinkImpl* link : action->links()) {
 
     if (link == nullptr)
       continue;
 
-    XBT_DEBUG("Update link %s", link->getCname());
+    XBT_DEBUG("Update link %s", link->get_cname());
     LinkEnergy* link_energy = link->piface_.extension<LinkEnergy>();
     link_energy->initWattsRangeList();
     link_energy->update();
@@ -163,21 +162,22 @@ static void onCommunicate(simgrid::surf::NetworkAction* action, simgrid::s4u::Ho
 
 static void onSimulationEnd()
 {
-  std::vector<simgrid::s4u::Link*> links;
-  simgrid::s4u::Engine::getInstance()->getLinkList(&links);
+  std::vector<simgrid::s4u::Link*> links = simgrid::s4u::Engine::get_instance()->get_all_links();
 
   double total_energy = 0.0; // Total dissipated energy (whole platform)
   for (const auto link : links) {
-    double link_energy = link->extension<LinkEnergy>()->getTotalEnergy();
-    if (strcmp(link->getCname(), "__loopback__"))
-      XBT_INFO("Link '%s' total consumption: %f", link->getCname(), link_energy);
+    double link_energy = link->extension<LinkEnergy>()->getConsumedEnergy();
     total_energy += link_energy;
   }
 
   XBT_INFO("Total energy over all links: %f", total_energy);
 }
 /* **************************** Public interface *************************** */
-SG_BEGIN_DECL()
+
+int sg_link_energy_is_inited()
+{
+  return LinkEnergy::EXTENSION_ID.valid();
+}
 /** \ingroup SURF_plugin_energy
  * \brief Enable energy plugin
  * \details Enable energy plugin to get joules consumption of each cpu. You should call this function before
@@ -190,6 +190,8 @@ void sg_link_energy_plugin_init()
     return;
   LinkEnergy::EXTENSION_ID = simgrid::s4u::Link::extension_create<LinkEnergy>();
 
+  xbt_assert(sg_host_count() == 0, "Please call sg_link_energy_plugin_init() before initializing the platform.");
+
   simgrid::s4u::Link::onCreation.connect([](simgrid::s4u::Link& link) {
     link.extension_set(new LinkEnergy(&link));
   });
@@ -199,18 +201,30 @@ void sg_link_energy_plugin_init()
   });
 
   simgrid::s4u::Link::onDestruction.connect([](simgrid::s4u::Link& link) {
-    link.extension<LinkEnergy>()->update();
+    if (strcmp(link.get_cname(), "__loopback__"))
+      XBT_INFO("Energy consumption of link '%s': %f Joules", link.get_cname(),
+               link.extension<LinkEnergy>()->getConsumedEnergy());
   });
 
-  simgrid::s4u::Link::onCommunicationStateChange.connect([](simgrid::surf::NetworkAction* action) {
-    for (simgrid::surf::LinkImpl* link : action->links()) {
+  simgrid::s4u::Link::onCommunicationStateChange.connect([](simgrid::kernel::resource::NetworkAction* action) {
+    for (simgrid::kernel::resource::LinkImpl* link : action->links()) {
       if (link != nullptr)
         link->piface_.extension<LinkEnergy>()->update();
     }
   });
 
   simgrid::s4u::Link::onCommunicate.connect(&onCommunicate);
-  simgrid::s4u::onSimulationEnd.connect(&onSimulationEnd);
+  simgrid::s4u::on_simulation_end.connect(&onSimulationEnd);
 }
 
-SG_END_DECL()
+/** @ingroup plugin_energy
+ *  @brief Returns the total energy consumed by the link so far (in Joules)
+ *
+ *  Please note that since the consumption is lazily updated, it may require a simcall to update it.
+ *  The result is that the actor requesting this value will be interrupted,
+ *  the value will be updated in kernel mode before returning the control to the requesting actor.
+ */
+double sg_link_get_consumed_energy(sg_link_t link)
+{
+  return link->extension<LinkEnergy>()->getConsumedEnergy();
+}