Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'klement/simgrid-klement' into master
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Thu, 8 Oct 2020 08:08:33 +0000 (10:08 +0200)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Thu, 8 Oct 2020 08:08:33 +0000 (10:08 +0200)
ChangeLog
MANIFEST.in
examples/platforms/wifi_energy.xml [new file with mode: 0644]
examples/s4u/CMakeLists.txt
examples/s4u/energy-wifi/s4u-energy-wifi.cpp [new file with mode: 0644]
examples/s4u/energy-wifi/s4u-energy-wifi.tesh [new file with mode: 0644]
include/simgrid/plugins/energy.h
src/plugins/link_energy_wifi.cpp [new file with mode: 0644]
src/surf/network_wifi.cpp
src/surf/network_wifi.hpp
tools/cmake/DefinePackages.cmake

index a2e17e2..f1cf894 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -21,8 +21,13 @@ Important user-visible changes:
    src/dest, and communicator information). This may change simulation times
    for very small message sizes, but should be more realistic.
 
+Documentation:
+ - New examples: wifi networks, and communication suspend
+
 S4U:
  - the on_exit() of each actor is also executed when the simulation deadlocks.
+ - New functions: s4u::Activity:: suspend(), resume() and is_suspended()
+   An example is provided for s4u::Comm but it should work with Exec and Io.
 
 SMPI:
  - Update proxy apps coverage of new ECP apps: 60+ apps now tested nightly on
@@ -65,6 +70,7 @@ Fixed bugs (FG#.. -> FramaGit bugs; FG!.. -> FG merge requests)
  - FG!24: Documentation and fix for xbt/random
  - FG!35: Add a modeling hint for parallel links in doc
  - FG!36: [xbt/random] Read/Write the state of the RNG
+ - FG#54: How to suspend a comm?
  - GF#18137: Allow different stack sizes?
  - GH#128: Parallelization of simulation with --cfg=contexts/nthreads
  - GH#139: Allow pthread creation in SMPI
@@ -72,6 +78,7 @@ Fixed bugs (FG#.. -> FramaGit bugs; FG!.. -> FG merge requests)
  - GH#346: [SMPI] error while loading shared libraries: libsimgrid.so
  - GH!337: Fix link_energy plugin for wifi platforms
  - GH!339: Add Mailbox set_receiver method to python binding
+ - GH!344: Cast hugepages macros parameters to int64
 
 ----------------------------------------------------------------------------
 
index ff8677f..1ab01b9 100644 (file)
@@ -427,6 +427,8 @@ include examples/s4u/energy-link/s4u-energy-link.cpp
 include examples/s4u/energy-link/s4u-energy-link.tesh
 include examples/s4u/energy-vm/s4u-energy-vm.cpp
 include examples/s4u/energy-vm/s4u-energy-vm.tesh
+include examples/s4u/energy-wifi/s4u-energy-wifi.cpp
+include examples/s4u/energy-wifi/s4u-energy-wifi.tesh
 include examples/s4u/engine-filtering/s4u-engine-filtering.cpp
 include examples/s4u/engine-filtering/s4u-engine-filtering.tesh
 include examples/s4u/exec-async/s4u-exec-async.cpp
@@ -1959,6 +1961,7 @@ include examples/platforms/two_hosts_profiles.xml
 include examples/platforms/two_peers.xml
 include examples/platforms/vivaldi.xml
 include examples/platforms/wifi.xml
+include examples/platforms/wifi_energy.xml
 include examples/python/CMakeLists.txt
 include examples/python/actor-create/actor-create_d.xml
 include examples/python/actor-lifetime/actor-lifetime_d.xml
@@ -2343,6 +2346,7 @@ include src/plugins/host_dvfs.cpp
 include src/plugins/host_energy.cpp
 include src/plugins/host_load.cpp
 include src/plugins/link_energy.cpp
+include src/plugins/link_energy_wifi.cpp
 include src/plugins/vm/VirtualMachineImpl.cpp
 include src/plugins/vm/VirtualMachineImpl.hpp
 include src/plugins/vm/VmHostExt.cpp
diff --git a/examples/platforms/wifi_energy.xml b/examples/platforms/wifi_energy.xml
new file mode 100644 (file)
index 0000000..3da00ae
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
+<platform version="4.1">
+  <zone id="world" routing="Full">
+    <zone id="WIFI zone" routing="Cluster">
+    
+        <link id="AP1" sharing_policy="WIFI" bandwidth="54Mbps" latency="0ms">
+          <prop id="wifi_watt_values" value="0:1:1:0"/>
+         <prop id="control_duration" value="0"/>
+        </link>
+        <host id="Station 1" speed="100.0Mf,50.0Mf,20.0Mf" />
+          <host_link id="Station 1" up="AP1" down="AP1"/>
+       <host id="Station 2" speed="100.0Mf,50.0Mf,20.0Mf" />
+          <host_link id="Station 2" up="AP1" down="AP1"/>
+       <router id="router"/>
+
+    </zone>
+  </zone>
+</platform>    
+    
index 21c1aa1..8b51493 100644 (file)
@@ -66,7 +66,7 @@ foreach (example actor-create actor-daemon actor-exiting actor-join actor-kill
                  comm-dependent
                  cloud-capping cloud-migration cloud-simple
                  dht-chord dht-kademlia
-                 energy-exec energy-boot energy-link energy-vm energy-exec-ptask
+                 energy-exec energy-boot energy-link energy-vm energy-exec-ptask energy-wifi
                  engine-filtering
                  exec-async exec-basic exec-dvfs exec-ptask exec-remote exec-waitany exec-waitfor exec-dependent
                  maestro-set
diff --git a/examples/s4u/energy-wifi/s4u-energy-wifi.cpp b/examples/s4u/energy-wifi/s4u-energy-wifi.cpp
new file mode 100644 (file)
index 0000000..62cb239
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * Test the wifi energy plugin
+ * Desactivate cross-factor to get round values
+ * Launch with: ./test test_platform_2STA.xml --cfg=plugin:link_energy_wifi --cfg=network/crosstraffic:0
+ */
+
+#include "simgrid/plugins/energy.h"
+#include "simgrid/s4u/Activity.hpp"
+#include "simgrid/s4u/Actor.hpp"
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/s4u/Host.hpp"
+#include "simgrid/s4u/Link.hpp"
+#include "simgrid/s4u/Mailbox.hpp"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(test_wifi, "Wifi energy demo");
+
+static void sender()
+{
+  // start sending after 5 seconds
+  simgrid::s4u::this_actor::sleep_until(5);
+
+  std::string mbName = "MailBoxRCV";
+  simgrid::s4u::Mailbox *dst = simgrid::s4u::Mailbox::by_name(mbName);
+
+  int size = 6750000;
+
+  XBT_INFO("SENDING 1 msg of size %d to %s", size, mbName.c_str());
+  static char message[] = "message";
+  dst->put(message, size);
+  XBT_INFO("finished sending");
+}
+
+static void receiver()
+{
+  std::string mbName = "MailBoxRCV";
+  XBT_INFO("RECEIVING on mb %s", mbName.c_str());
+  simgrid::s4u::Mailbox *myBox = simgrid::s4u::Mailbox::by_name(mbName);
+  myBox->get();
+
+  XBT_INFO("received all messages");
+}
+
+int main(int argc, char** argv)
+{
+  simgrid::s4u::Engine engine(&argc, argv);
+  sg_wifi_energy_plugin_init();
+  engine.load_platform(argv[1]);
+
+  // setup WiFi bandwidths
+  auto* l = simgrid::s4u::Link::by_name("AP1");
+  l->set_host_wifi_rate(simgrid::s4u::Host::by_name("Station 1"), 0);
+  l->set_host_wifi_rate(simgrid::s4u::Host::by_name("Station 2"), 0);
+
+  // create the two actors for the test
+  simgrid::s4u::Actor::create("act0", simgrid::s4u::Host::by_name("Station 1"), sender);
+  simgrid::s4u::Actor::create("act1", simgrid::s4u::Host::by_name("Station 2"), receiver);
+
+  engine.run();
+
+  return 0;
+}
diff --git a/examples/s4u/energy-wifi/s4u-energy-wifi.tesh b/examples/s4u/energy-wifi/s4u-energy-wifi.tesh
new file mode 100644 (file)
index 0000000..3df3c43
--- /dev/null
@@ -0,0 +1,13 @@
+#!/usr/bin/env tesh
+
+p Testing the mechanism for computing link energy consumption (using CM02 as a network model)
+
+$ ${bindir:=.}/s4u-energy-wifi ${platfdir}/wifi_energy.xml  "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:CM02 --cfg=network/crosstraffic:no
+> [  0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02'
+> [  0.000000] (0:maestro@) Configuration change: Set 'network/crosstraffic' to 'no'
+> [  0.000000] (0:maestro@) Activating the wifi_energy plugin.
+> [  0.000000] (2:act1@Station 2) RECEIVING on mb MailBoxRCV
+> [  5.000000] (1:act0@Station 1) SENDING 1 msg of size 6750000 to MailBoxRCV
+> [  7.000000] (2:act1@Station 2) received all messages
+> [  7.000000] (1:act0@Station 1) finished sending
+> [  7.000000] (0:maestro@) Link AP1 destroyed, consumed: 6.000000 J dyn: 6.000000 stat: 0.000000 durIdle: 5.000000 durTxRx: 2.000000
index ea436c6..a9f4ae1 100644 (file)
@@ -26,6 +26,8 @@ XBT_PUBLIC double sg_link_get_consumed_energy(const_sg_link_t link);
 
 XBT_PUBLIC int sg_link_energy_is_inited();
 
+XBT_PUBLIC void sg_wifi_energy_plugin_init();
+
 #define MSG_host_energy_plugin_init() sg_host_energy_plugin_init()
 #define MSG_host_get_consumed_energy(host) sg_host_get_consumed_energy(host)
 #define MSG_host_get_idle_consumption_at(host,pstate) sg_host_get_idle_consumption_at((host), (pstate))
diff --git a/src/plugins/link_energy_wifi.cpp b/src/plugins/link_energy_wifi.cpp
new file mode 100644 (file)
index 0000000..9ca5de4
--- /dev/null
@@ -0,0 +1,349 @@
+/* Copyright (c) 2017-2020. 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/Exception.hpp"
+#include "simgrid/plugins/energy.h"
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/s4u/Host.hpp"
+#include "simgrid/s4u/Link.hpp"
+#include "src/surf/network_interface.hpp"
+#include "src/surf/network_wifi.hpp"
+#include "src/surf/surf_interface.hpp"
+#include "surf/surf.hpp"
+#include "src/kernel/lmm/maxmin.hpp"
+#include "xbt/config.hpp"
+
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <map>
+
+SIMGRID_REGISTER_PLUGIN(link_energy_wifi, "Energy wifi test", &sg_wifi_energy_plugin_init);
+/** @degroup plugin_link_energy_wifi Plugin WiFi energy
+ * 
+ * This is the WiFi energy plugin, accounting for the dissipated energy of WiFi links.
+ */
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(link_energy_wifi, surf, "Logging specific to the link energy wifi plugin");
+
+namespace simgrid {
+namespace plugin {
+
+class XBT_PRIVATE LinkEnergyWifi {
+
+public:
+  static simgrid::xbt::Extension<simgrid::s4u::Link, LinkEnergyWifi> EXTENSION_ID;
+
+  explicit LinkEnergyWifi(simgrid::s4u::Link* ptr) : link_(ptr) {}
+
+  ~LinkEnergyWifi() = default;
+  LinkEnergyWifi()  = delete;
+
+  /**
+   * Update the energy consumed by link_ when transmissions start or end
+   */
+  void update(const simgrid::kernel::resource::NetworkAction &);
+  
+  /**
+   * Update the energy consumed when link_ is destroyed
+   */
+  void update_destroy();
+
+  /**
+   * Fetches energy consumption values from the platform file.
+   * The user can specify:
+   *  - wifi_watt_values: energy consumption in each state (IDLE:Tx:Rx:SLEEP)
+   *      default: 0.82:1.14:0.94:0.10
+   *  - controlDuration: duration of active beacon transmissions per second
+   *      default: 0.0036
+   */
+  void init_watts_range_list();
+
+  double get_consumed_energy(void) { return eDyn_ + eStat_; }
+  /** Get the dynamic part of the energy for this link */
+  double get_energy_dynamic(void) { return eDyn_; }
+  double get_energy_static(void) { return eStat_; }
+  double get_duration_comm(void) { return dur_TxRx_; }
+  double get_duration_idle(void) { return dur_idle_; }
+
+  /** Set the power consumed by this link while idle */
+  void set_power_idle(double value) { pIdle_ = value; }
+  /** Set the power consumed by this link while transmitting */
+  void set_power_tx(double value) { pTx_ = value; }
+  /** Set the power consumed by this link while receiving */
+  void set_power_rx(double value) { pRx_ = value; }
+  /** Set the power consumed by this link while sleeping */
+  void set_power_sleep(double value) { pSleep_ = value; }
+
+private:
+  // associative array keeping size of data already sent for a given flow (required for interleaved actions)
+  std::map<simgrid::kernel::resource::NetworkWifiAction*, std::pair<int, double>> flowTmp{};
+
+  // WiFi link the plugin instance is attached to
+  s4u::Link* link_{};
+
+  // dynamic energy accumulated since the simulation start (active durations consumption)
+  double eDyn_{0.0};
+  // static energy (no activity consumption)
+  double eStat_{0.0};
+
+  // duration since previous energy update
+  double prev_update_{0.0};
+
+  // Same energy calibration values as ns3 by default
+  // https://www.nsnam.org/docs/release/3.30/doxygen/classns3_1_1_wifi_radio_energy_model.html#details
+  double pIdle_{0.82};
+  double pTx_{1.14};
+  double pRx_{0.94};
+  double pSleep_{0.10};
+
+  // constant taking beacons into account (can be specified by the user)
+  double control_duration_{0.0036};
+
+  // Measurements for report
+  double dur_TxRx_{0}; // Duration of transmission
+  double dur_idle_{0}; // Duration of idle time
+  bool valuesInit_{false};
+};
+
+xbt::Extension<s4u::Link, LinkEnergyWifi> LinkEnergyWifi::EXTENSION_ID;
+
+void LinkEnergyWifi::update_destroy()
+{
+  simgrid::kernel::resource::NetworkWifiLink* wifi_link =
+    static_cast<simgrid::kernel::resource::NetworkWifiLink*>(link_->get_impl());
+  double duration = surf_get_clock() - prev_update_;
+  prev_update_    = surf_get_clock();
+
+  dur_idle_ += duration;
+
+  // add IDLE energy usage, as well as beacons consumption since previous update
+  eDyn_ += duration * control_duration_ * wifi_link->get_host_count() * pRx_;
+  eStat_ += (duration - (duration * control_duration_)) * pIdle_ * (wifi_link->get_host_count() + 1);
+
+  XBT_DEBUG("finish eStat_ += %f * %f * (%d+1) | eStat = %f", duration, pIdle_, wifi_link->get_host_count(), eStat_);
+}
+
+void LinkEnergyWifi::update(const simgrid::kernel::resource::NetworkAction&)
+{
+  init_watts_range_list();
+
+  double duration = surf_get_clock() - prev_update_;
+  prev_update_    = surf_get_clock();
+
+  // we don't update for null durations
+  if(duration < 1e-6)
+    return;
+
+  simgrid::kernel::resource::NetworkWifiLink* wifi_link =
+      static_cast<simgrid::kernel::resource::NetworkWifiLink*>(link_->get_impl());
+  
+  const kernel::lmm::Variable* var;
+  const kernel::lmm::Element* elem = nullptr;
+
+  /**
+   * We update the energy consumed by each flow active on the link since the previous update.
+   * To do this, we need to know how much time each flow has been effectively sending data on the WiFi link since the previous update (durUsage). 
+   * We compute this value using the size of the flow, 
+   * the amount of data already spent (using flowTmp), 
+   * as well as the bandwidth used by the flow since the previous update (using LMM variables)
+   * Since flows are sharing the medium, the total active duration on the link is equal to the transmission/reception duration used by the flow with the longest active time since the previous update 
+   */
+  double durUsage = 0;
+  while((var = wifi_link->get_constraint()->get_variable(&elem))) {
+    auto* action = static_cast<kernel::resource::NetworkWifiAction*>(var->get_id());
+    XBT_DEBUG("cost: %f action value: %f link rate 1: %f link rate 2: %f", action->get_cost(), action->get_variable()->get_value(), wifi_link->get_host_rate(&action->get_src()),wifi_link->get_host_rate(&action->get_dst()));
+    action->get_variable();
+    
+    double du = 0; // durUsage on the current flow
+    std::map<simgrid::kernel::resource::NetworkWifiAction *, std::pair<int, double>>::iterator it;
+
+    if(action->get_variable()->get_value()) {
+      it = flowTmp.find(action);
+      
+      // if the flow has not been registered, initialize it: 0 bytes sent, and not updated since its creation timestamp
+      if(it == flowTmp.end())
+        flowTmp[action] = std::pair<int,double>(0, action->get_start_time());
+
+      it = flowTmp.find(action);
+
+      /**
+       * The active duration of the link is equal to the amount of data it had to send divided by the bandwidth on the link.
+       * If this is longer than the duration since the previous update, active duration = now - previous_update
+       */
+      du = (action->get_cost()-it->second.first) / action->get_variable()->get_value();
+
+      if(du > surf_get_clock()-it->second.second)
+        du = surf_get_clock()-it->second.second;
+
+      // if the flow has been more active than the others
+      if(du > durUsage)
+        durUsage = du;
+
+      // update the amount of data already sent by the flow
+      it->second.first += du*action->get_variable()->get_value();
+      it->second.second =  surf_get_clock();
+
+      // important: if the transmission finished, remove it (needed for performance and multi-message flows)
+      if(it->second.first >= action->get_cost())
+        flowTmp.erase (it);
+    }
+  }
+
+  XBT_DEBUG("durUsage: %f", durUsage);
+
+  // beacons cost
+  eDyn_ += duration * control_duration_ * wifi_link->get_host_count() * pRx_;
+
+  /**
+   * Same principle as ns3:
+   *  - if tx or rx, update P_{dyn}
+   *  - if idle i.e. get_usage = 0, update P_{stat}
+   * P_{tot} = P_{dyn}+P_{stat}
+   */
+  if(link_->get_usage()){
+    eDyn_ += /*duration * */ durUsage * ((wifi_link->get_host_count() * pRx_) + pTx_);
+    eStat_ += (duration - durUsage) * pIdle_ * (wifi_link->get_host_count() + 1);
+    XBT_DEBUG("eDyn +=  %f * ((%d * %f) + %f) | eDyn = %f (durusage =%f)", durUsage, wifi_link->get_host_count(), pRx_,
+              pTx_, eDyn_, durUsage);
+    dur_TxRx_ += duration;
+  }else{
+    dur_idle_ += duration;
+    eStat_ += (duration - (duration * control_duration_)) * pIdle_ * (wifi_link->get_host_count() + 1);
+  }
+
+  XBT_DEBUG("eStat_ += %f * %f * (%d+1) | eStat = %f", duration, pIdle_, wifi_link->get_host_count(), eStat_);
+}
+
+void LinkEnergyWifi::init_watts_range_list()
+{
+  if (valuesInit_)
+    return;
+  valuesInit_                      = true;
+
+  /* beacons factor
+  Set to 0 if you do not want to compute beacons,
+  otherwise to the duration of beacons transmissions per second
+  */
+  const char* beacons_factor = this->link_->get_property("control_duration");
+  if(beacons_factor != nullptr) {
+    try {
+      control_duration_ = std::stod(beacons_factor);
+    } catch (const std::invalid_argument&) {
+      throw std::invalid_argument(std::string("Invalid beacons factor value for link ") + this->link_->get_cname());
+    }
+  }
+
+  const char* all_power_values_str = this->link_->get_property("wifi_watt_values");
+  if (all_power_values_str != nullptr)
+  {
+    std::vector<std::string> all_power_values;
+    boost::split(all_power_values, all_power_values_str, boost::is_any_of(","));
+
+    for (auto current_power_values_str : all_power_values) {
+      /* retrieve the power values associated */
+      std::vector<std::string> current_power_values;
+      boost::split(current_power_values, current_power_values_str, boost::is_any_of(":"));
+      xbt_assert(current_power_values.size() == 4,
+                "Power properties incorrectly defined - could not retrieve idle, Tx, Rx, Sleep power values for link %s",
+                this->link_->get_cname());
+
+      /* min_power corresponds to the idle power (link load = 0) */
+      /* max_power is the power consumed at 100% link load       */
+      try {
+        pSleep_ = std::stod(current_power_values.at(3));
+      } catch (const std::invalid_argument&) {
+        throw std::invalid_argument(std::string("Invalid idle power value for link ") + this->link_->get_cname());
+      }
+      try {
+        pRx_ = std::stod(current_power_values.at(2));
+      } catch (const std::invalid_argument&) {
+        throw std::invalid_argument(std::string("Invalid idle power value for link ") + this->link_->get_cname());
+      }
+      try {
+        pTx_ = std::stod(current_power_values.at(1));
+      } catch (const std::invalid_argument&) {
+        throw std::invalid_argument(std::string("Invalid idle power value for link ") + this->link_->get_cname());
+      }
+      try {
+        pIdle_ = std::stod(current_power_values.at(0));
+      } catch (const std::invalid_argument&) {
+        throw std::invalid_argument(std::string("Invalid busy power value for link ") + this->link_->get_cname());
+      }
+
+      XBT_DEBUG("Values aa initialized with: pSleep=%f pIdle=%f pTx=%f pRx=%f", pSleep_, pIdle_, pTx_, pRx_);
+    }
+  }
+}
+
+} // namespace plugin
+} // namespace simgrid
+
+using simgrid::plugin::LinkEnergyWifi;
+
+void sg_wifi_energy_plugin_init()
+{
+  if (LinkEnergyWifi::EXTENSION_ID.valid())
+    return;
+
+  XBT_INFO("Activating the wifi_energy plugin.");
+  LinkEnergyWifi::EXTENSION_ID = simgrid::s4u::Link::extension_create<LinkEnergyWifi>();
+
+  /**
+   * Attaching to events:
+   * - on_creation to initialize the plugin
+   * - on_destruction to produce final energy results
+   * - on_communication_state_change: to account the energy when communications are updated
+   * - on_communicate: ''
+   */
+  simgrid::s4u::Link::on_creation.connect([](simgrid::s4u::Link& link) {
+    // verify the link is appropriate to WiFi energy computations
+    if (link.get_sharing_policy() == simgrid::s4u::Link::SharingPolicy::WIFI) {
+      XBT_DEBUG("Wifi Link: %s, initialization of wifi energy plugin", link.get_cname());
+      LinkEnergyWifi* plugin = new LinkEnergyWifi(&link);
+      link.extension_set(plugin);
+    } else {
+      XBT_DEBUG("Not Wifi Link: %s, wifi energy on link not computed", link.get_cname());
+    }
+  });
+
+  simgrid::s4u::Link::on_destruction.connect([](simgrid::s4u::Link const& link) {
+    // output energy values if WiFi link
+    if (link.get_sharing_policy() == simgrid::s4u::Link::SharingPolicy::WIFI) {
+      link.extension<LinkEnergyWifi>()->update_destroy();
+      XBT_INFO(
+          "Link %s destroyed, consumed: %f J dyn: %f stat: %f durIdle: %f durTxRx: %f", link.get_cname(),
+          link.extension<LinkEnergyWifi>()->get_consumed_energy(),
+          link.extension<LinkEnergyWifi>()->get_energy_dynamic(), link.extension<LinkEnergyWifi>()->get_energy_static(),
+          link.extension<LinkEnergyWifi>()->get_duration_idle(), link.extension<LinkEnergyWifi>()->get_duration_comm());
+    }
+  });
+
+  simgrid::s4u::Link::on_communication_state_change.connect(
+      [](simgrid::kernel::resource::NetworkAction const& action, simgrid::kernel::resource::Action::State previous) {
+        // update WiFi links encountered during the communication
+        for (simgrid::kernel::resource::LinkImpl* link : action.get_links()) {
+          if (link != nullptr && link->get_sharing_policy() == simgrid::s4u::Link::SharingPolicy::WIFI) {
+            link->get_iface()->extension<LinkEnergyWifi>()->update(action);
+          }
+        }
+      });
+
+  simgrid::s4u::Link::on_communicate.connect([](const simgrid::kernel::resource::NetworkAction& action) {
+    const simgrid::kernel::resource::NetworkWifiAction* actionWifi = dynamic_cast<const simgrid::kernel::resource::NetworkWifiAction*>(&action);
+
+    if(actionWifi == nullptr) 
+      return;
+
+    auto link_src  = actionWifi->get_src_link();
+    auto link_dst = actionWifi->get_dst_link();
+
+    if(link_src != nullptr)
+      link_src->get_iface()->extension<LinkEnergyWifi>()->update(action);
+    if(link_dst != nullptr)
+      link_dst->get_iface()->extension<LinkEnergyWifi>()->update(action);
+
+  });
+
+}
index 76f2f57..838c150 100644 (file)
@@ -62,9 +62,14 @@ s4u::Link::SharingPolicy NetworkWifiLink::get_sharing_policy()
   return s4u::Link::SharingPolicy::WIFI;
 }
 
+int NetworkWifiLink::get_host_count()
+{
+  return host_rates_.size();
+}
+
 void NetworkWifiLink::refresh_decay_bandwidths(){
   // Compute number of STAtion on the Access Point
-  size_t nSTA = host_rates_.size();
+  int nSTA = get_host_count();
 
   std::vector<Metric> new_bandwidths;
   for (auto bandwidth : bandwidths_){
index 08699dc..8ef62e8 100644 (file)
@@ -55,6 +55,7 @@ public:
   void set_latency(double) override { THROW_UNIMPLEMENTED; }
   void refresh_decay_bandwidths();
   bool toggle_decay_model();
+  int get_host_count();
 };
 
 class NetworkWifiAction : public NetworkCm02Action {
index 78a29f2..dfa77b2 100644 (file)
@@ -374,6 +374,7 @@ set(PLUGINS_SRC
   src/plugins/host_dvfs.cpp
   src/plugins/host_energy.cpp
   src/plugins/link_energy.cpp
+  src/plugins/link_energy_wifi.cpp
   src/plugins/host_load.cpp
   src/plugins/file_system/s4u_FileSystem.cpp
   src/plugins/vm/VirtualMachineImpl.hpp
@@ -1211,6 +1212,7 @@ set(PLATFORMS_EXAMPLES
   examples/platforms/two_hosts_platform_with_availability_included.xml
   examples/platforms/two_peers.xml
   examples/platforms/vivaldi.xml
+  examples/platforms/wifi_energy.xml
   examples/platforms/wifi.xml
   )