examples/s4u/basic/s4u-basic_deployment
examples/s4u/basic/s4u-basic_function
examples/s4u/dht-chord/s4u-dht-chord
+examples/s4u/energy-link/s4u-energy-link
examples/s4u/io/s4u-io
examples/s4u/mutex/s4u-mutex
examples/s4u/plugin-hostload/s4u-plugin-hostload
else()
message(FATAL_ERROR
"The compiler ${CMAKE_CXX_COMPILER} (v${CMAKE_CXX_COMPILER_VERSION}) has no C++11 support. "
- "Please use a decent C++ compiler.")
+ "Please install a decent C++ compiler (remove CMakeCache.txt once it's installed).")
endif()
### And we need C11 standard, too
- make -C org all sync
- git commit -a && git push
- Announce the release
+ - Document the tag on https://github.com/simgrid/simgrid/releases
- Mail the simgrid-user mailing list
- the NEWS chunk in the mail;
- the ChangeLog chunk as attachment
<prop id="watt_per_state" value="100.0:200.0, 93.0:170.0, 90.0:150.0" />
<prop id="watt_off" value="10" />
</host>
-
- <link id="bus" bandwidth="100kBps" latency="0"/>
+
+ <link id="bus" bandwidth="100kBps" latency="0" sharing_policy="SHARED">
+<!-- REALISTIC VALUES <prop id="watt_range" value="10.3581:10.7479" /> -->
+<!-- IREALISTIC VALUES FOR THE TEST --> <prop id="watt_range" value="1:3" />
+ </link>
<route src="MyHost1" dst="MyHost2">
<link_ctn id="bus"/>
</route>
actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend actor-priority
app-masterworker app-pingpong app-token-ring
async-wait async-waitany async-waitall
+ energy-link
plugin-hostload io mutex)
add_executable (s4u-${example} ${example}/s4u-${example}.cpp)
target_link_libraries(s4u-${example} simgrid)
actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend
app-bittorrent app-masterworker app-pingpong app-token-ring
async-wait async-waitall async-waitany actor-priority
- dht-chord plugin-hostload io mutex)
+ dht-chord
+ energy-link
+ plugin-hostload io mutex)
ADD_TESH_FACTORIES(s4u-${example} "thread;ucontext;raw;boost" --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_HOME_DIRECTORY}/examples/s4u/${example} s4u-${example}.tesh)
endforeach()
--- /dev/null
+/* 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/energy.h"
+#include "xbt/log.h"
+#include <simgrid/s4u.hpp>
+
+#include <random>
+
+/* Parameters of the random generation of the flow size */
+static const unsigned long int min_size = 1e6;
+static const unsigned long int max_size = 1e9;
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_energyconsumption, "Messages specific for this s4u example");
+
+static void sender(std::vector<std::string> args)
+{
+ xbt_assert(args.size() == 2, "The master function expects 2 arguments.");
+ int flow_amount = std::stoi(args.at(0));
+ double comm_size = std::stod(args.at(1));
+ XBT_INFO("Send %.0f bytes, in %d flows", comm_size, flow_amount);
+
+ simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::byName(std::string("message"));
+
+ simgrid::s4u::this_actor::sleep_for(10);
+
+ /* - Send the task to the @ref worker */
+ char* payload = bprintf("%f", comm_size);
+
+ if (flow_amount == 1) {
+ mailbox->put(payload, comm_size);
+ } else {
+ // Start all comms in parallel
+ std::vector<simgrid::s4u::CommPtr> comms;
+ for (int i = 0; i < flow_amount; i++)
+ comms.push_back(mailbox->put_async(const_cast<char*>("message"), comm_size));
+
+ // And now, wait for all comms. Manually since wait_all is not part of this_actor yet
+ for (int i = 0; i < flow_amount; i++) {
+ simgrid::s4u::CommPtr comm = comms.at(i);
+ comm->wait();
+ }
+ comms.clear();
+ }
+ XBT_INFO("sender done.");
+}
+
+static void receiver(std::vector<std::string> args)
+{
+ int flow_amount = std::stoi(args.at(0));
+
+ XBT_INFO("Receiving %d flows ...", flow_amount);
+
+ simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::byName(std::string("message"));
+
+ if (flow_amount == 1) {
+ void* res = mailbox->get();
+ xbt_free(res);
+ } else {
+ void* ignored;
+
+ // Start all comms in parallel
+ std::vector<simgrid::s4u::CommPtr> comms;
+ for (int i = 0; i < flow_amount; i++)
+ comms.push_back(mailbox->get_async(&ignored));
+
+ // And now, wait for all comms. Manually since wait_all is not part of this_actor yet
+ for (int i = 0; i < flow_amount; i++)
+ comms.at(i)->wait();
+ comms.clear();
+ }
+ XBT_INFO("receiver done.");
+}
+
+int main(int argc, char* argv[])
+{
+
+ simgrid::s4u::Engine* e = new simgrid::s4u::Engine(&argc, argv);
+
+ /* Check if we got --NS3 on the command line, and activate ecofen if so */
+ bool NS3 = false;
+ for (int i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "--NS3") == 0)
+ NS3 = true;
+ if (NS3) // Found the --NS3 parameter previously; shift the rest of the line
+ argv[i] = argv[i + 1];
+ }
+ if (NS3) {
+ xbt_die("No Ecofen in this build");
+ // XBT_INFO("Activating the Ecofen energy plugin");
+ // ns3_link_energy_plugin_init();
+ // xbt_cfg_set_parse("network/model:NS3");
+ // argc -= 1; // We removed it from the parameters
+ } else {
+ XBT_INFO("Activating the SimGrid link energy plugin");
+ sg_link_energy_plugin_init();
+ }
+
+ xbt_assert(argc > 1, "\nUsage: %s platform_file [flowCount [datasize]] [--NS3]\n"
+ "\tExample: %s s4uplatform.xml \n"
+ "\tIf you add NS3 as last parameter, this will try to activate the ecofen plugin.\n"
+ "\tWithout it, it will use the SimGrid link energy plugin.\n",
+ argv[0], argv[0]);
+ e->loadPlatform(argv[1]);
+
+ /* prepare to launch the actors */
+ std::vector<std::string> argSender;
+ std::vector<std::string> argReceiver;
+ if (argc > 2) {
+ argSender.push_back(argv[2]); // Take the amount of flows from the command line
+ argReceiver.push_back(argv[2]);
+ } else {
+ argSender.push_back("1"); // Default value
+ argReceiver.push_back("1");
+ }
+ if (argc > 3) {
+ if (strcmp(argv[3], "random") == 0) { // We're asked to get a random size
+ /* Initialize the random number generator */
+ std::random_device rd;
+ std::default_random_engine generator(rd());
+
+ /* Distribution on which to apply the generator */
+ std::uniform_int_distribution<unsigned long int> distribution(min_size, max_size);
+
+ char* size = bprintf("%lu", distribution(generator));
+ argSender.push_back(std::string(size));
+ xbt_free(size);
+ } else { // Not "random" ? Then it should be the size to use
+ argSender.push_back(argv[3]); // Take the datasize from the command line
+ }
+ } else { // No parameter at all? Then use the default value
+ argSender.push_back("25000");
+ }
+ simgrid::s4u::Actor::createActor("sender", simgrid::s4u::Host::by_name("MyHost1"), sender, argSender);
+ simgrid::s4u::Actor::createActor("receiver", simgrid::s4u::Host::by_name("MyHost2"), receiver, argReceiver);
+
+ /* And now, launch the simulation */
+ e->run();
+
+ return 0;
+}
--- /dev/null
+#! ./tesh
+
+p Testing the mechanism for computing link energy consumption (using CM02 as a network model)
+
+$ ${bindir:=.}/s4u-energy-link$EXEEXT ${srcdir:=.}/../platforms/energy_platform.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 SimGrid link energy plugin
+> [ 0.000000] (1:sender@MyHost1) Send 25000 bytes, in 1 flows
+> [ 0.000000] (2:receiver@MyHost2) Receiving 1 flows ...
+> [ 10.250000] (2:receiver@MyHost2) receiver done.
+> [ 10.250000] (1:sender@MyHost1) sender done.
+> [ 10.250000] (0:maestro@) Link 'bus' total consumption: 10.750000
+> [ 10.250000] (0:maestro@) Total energy over all links: 10.750000
+
+p And now test with 500000 bytes
+
+$ ${bindir:=.}/s4u-energy-link$EXEEXT ${srcdir:=.}/../platforms/energy_platform.xml 1 50000000 "--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 SimGrid link energy plugin
+> [ 0.000000] (1:sender@MyHost1) Send 50000000 bytes, in 1 flows
+> [ 0.000000] (2:receiver@MyHost2) Receiving 1 flows ...
+> [510.000000] (2:receiver@MyHost2) receiver done.
+> [510.000000] (1:sender@MyHost1) sender done.
+> [510.000000] (0:maestro@) Link 'bus' total consumption: 1510.000000
+> [510.000000] (0:maestro@) Total energy over all links: 1510.000000
+
XBT_PUBLIC(double) sg_host_get_wattmax_at(sg_host_t host, int pstate);
XBT_PUBLIC(double) sg_host_get_current_consumption(sg_host_t host);
+XBT_PUBLIC(void) sg_link_energy_plugin_init();
+XBT_PUBLIC(double) sg_link_get_consumed_energy(sg_link_t link);
+
#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_wattmin_at(host,pstate) sg_host_get_wattmin_at(host,pstate)
* <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
* <platform version="4">
*
- * <!-- Start a process called 'master' on the host called 'Tremblay' -->
- * <process host="Tremblay" function="master">
+ * <!-- Start an actor called 'master' on the host called 'Tremblay' -->
+ * <actor host="Tremblay" function="master">
* <!-- Here come the parameter that you want to feed to this instance of master -->
* <argument value="20"/> <!-- argv[1] -->
* <argument value="50000000"/> <!-- argv[2] -->
* <argument value="1000000"/> <!-- argv[3] -->
* <argument value="5"/> <!-- argv[4] -->
- * </process>
+ * </actor>
*
- * <!-- Start a process called 'worker' on the host called 'Jupiter' -->
- * <process host="Jupiter" function="worker"/> <!-- Don't provide any parameter ->>
+ * <!-- Start an actor called 'worker' on the host called 'Jupiter' -->
+ * <actor host="Jupiter" function="worker"/> <!-- Don't provide any parameter ->>
*
* </platform>
* @endcode
/** Create an actor using code
*
* Using this constructor, move-only type can be used. The consequence is
- * that we cannot copy the value and restart the process in its initial
+ * that we cannot copy the value and restart the actor in its initial
* state. In order to use auto-restart, an explicit `function` must be passed
* instead.
*/
static ActorPtr createActor(const char* name, s4u::Host* host, const char* function, std::vector<std::string> args);
// ***** Methods *****
- /** This actor will be automatically terminated when the last non-daemon process finishes **/
+ /** This actor will be automatically terminated when the last non-daemon actor finishes **/
void daemonize();
/** Retrieves the name of that actor as a C++ string */
/** Suspend an actor by suspending the task on which it was waiting for the completion. */
void suspend();
- /** Resume a suspended process by resuming the task on which it was waiting for the completion. */
+ /** Resume a suspended actor by resuming the task on which it was waiting for the completion. */
void resume();
- /** Returns true if the process is suspended. */
+ /** Returns true if the actor is suspended. */
int isSuspended();
/** If set to true, the actor will automatically restart when its host reboots */
void setAutoRestart(bool autorestart);
/** Add a function to the list of "on_exit" functions for the current actor. The on_exit functions are the functions
- * executed when your actor is killed. You should use them to free the data used by your process.
+ * executed when your actor is killed. You should use them to free the data used by your actor.
*/
void onExit(int_f_pvoid_pvoid_t fun, void* data);
/** @brief Returns the name of the current actor as a C string. */
XBT_PUBLIC(const char*) getCname();
-/** @brief Returns the name of the host on which the process is running. */
+/** @brief Returns the name of the host on which the actor is running. */
XBT_PUBLIC(Host*) getHost();
/** @brief Suspend the actor. */
size_t getHostCount();
void getHostList(std::vector<Host*> * whereTo);
+ size_t getLinkCount();
+ void getLinkList(std::vector<Link*> * list);
/** @brief Run the simulation */
void run();
#define S4U_LINK_HPP_
#include <simgrid/link.h>
-#include <xbt/base.h>
-#include <xbt/signal.hpp>
-
#include <string>
#include <unordered_map>
+#include <xbt/Extendable.hpp>
+#include <xbt/base.h>
+#include <xbt/signal.hpp>
/***********
* Classes *
};
namespace s4u {
/** @brief A Link represents the network facilities between [hosts](\ref simgrid::s4u::Host) */
-XBT_PUBLIC_CLASS Link
+XBT_PUBLIC_CLASS Link : public simgrid::xbt::Extendable<Link>
{
friend simgrid::surf::LinkImpl;
*/
int sharingPolicy();
+ /** @brief Returns the current load (in flops per second) */
+ double getUsage();
+
/** @brief Check if the Link is used */
bool isUsed();
void setLatencyTrace(tmgr_trace_t trace); /*< setup the trace file with latency events (peak latency changes due to
external load). Trace must contain absolute values */
+ const char* getProperty(const char* key);
+ void setProperty(std::string key, std::string value);
+
/* The signals */
/** @brief Callback signal fired when a new Link is created */
static simgrid::xbt::signal<void(s4u::Link&)> onCreation;
for (auto const& kv : host_list)
list->push_back(kv.second);
}
+/** @brief Returns the amount of links in the platform */
+size_t Engine::getLinkCount()
+{
+ return simgrid::surf::LinkImpl::linksCount();
+}
+/** @brief Fills the passed list with all hosts found in the platform */
+void Engine::getLinkList(std::vector<Link*>* list)
+{
+ simgrid::surf::LinkImpl::linksList(list);
+}
void Engine::run() {
if (MC_is_active()) {
return this->pimpl_->sharingPolicy();
}
+double Link::getUsage()
+{
+ return lmm_constraint_get_usage(this->pimpl_->constraint());
+}
+
void Link::turnOn()
{
simgrid::simix::kernelImmediate([this]() {
});
}
+const char* Link::getProperty(const char* key)
+{
+ return this->pimpl_->getProperty(key);
+}
+void Link::setProperty(std::string key, std::string value)
+{
+ simgrid::simix::kernelImmediate([this, key, value] { this->pimpl_->setProperty(key, value); });
+}
+
/*************
* Callbacks *
*************/
{
return links->size();
}
+ void LinkImpl::linksList(std::vector<s4u::Link*>* linkList)
+ {
+ for (auto const& kv : *links) {
+ linkList->push_back(&kv.second->piface_);
+ }
+ }
+
/** @brief Returns a list of all existing links */
LinkImpl** LinkImpl::linksList()
{
static LinkImpl* byName(std::string name);
static int linksCount();
static LinkImpl** linksList();
+ static void linksList(std::vector<s4u::Link*>* linkList);
static void linksExit();
};
--- /dev/null
+/* 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/energy.h"
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/simix.hpp"
+#include "src/surf/network_interface.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
+
+
+ This is the energy plugin, enabling to account for the dissipated energy in the simulated platform.
+
+ The energy consumption of a link depends directly on its current traffic load. Specify that consumption in your
+ platform file as follows:
+
+ \verbatim
+ <link id="SWITCH1" bandwidth="125000000" latency="5E-5" sharing_policy="SHARED" >
+ <prop id="watts" value="100.0:200.0" />
+ <prop id="watt_off" value="10" />
+ </link>
+ \endverbatim
+
+ The first property means that when your link is switched on, but without anything to do, it will dissipate 100 Watts.
+ If it's fully loaded, it will dissipate 200 Watts. If its load is at 50%, then it will dissipate 150 Watts.
+ The second property means that when your host is turned off, it will dissipate only 10 Watts (please note that these
+ values are arbitrary).
+
+ To simulate the energy-related elements, first call the simgrid#energy#sg_link_energy_plugin_init() before your
+ #MSG_init(),
+ and then use the following function to retrieve the consumption of a given link: MSG_link_get_consumed_energy().
+ */
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(link_energy, surf, "Logging specific to the SURF LinkEnergy plugin");
+
+namespace simgrid {
+namespace plugin {
+
+class LinkPowerRange {
+public:
+ double idle;
+ double busy;
+
+ LinkPowerRange(double idle, double busy) : idle(idle), busy(busy) {}
+};
+
+class LinkEnergy {
+public:
+ static simgrid::xbt::Extension<simgrid::s4u::Link, LinkEnergy> EXTENSION_ID;
+
+ explicit LinkEnergy(simgrid::s4u::Link* ptr);
+ ~LinkEnergy();
+
+ double getALinkTotalPower();
+ void initWattsRangeList();
+ double getTotalEnergy();
+ void update();
+
+private:
+ double getPower();
+
+ simgrid::s4u::Link* link{};
+
+ std::vector<LinkPowerRange> power_range_watts_list{};
+
+ double total_energy{0.0};
+ double last_updated{0.0}; /*< Timestamp of the last energy update event*/
+};
+
+simgrid::xbt::Extension<simgrid::s4u::Link, LinkEnergy> LinkEnergy::EXTENSION_ID;
+
+LinkEnergy::LinkEnergy(simgrid::s4u::Link* ptr) : link(ptr), last_updated(surf_get_clock())
+{
+}
+
+LinkEnergy::~LinkEnergy() = default;
+
+void LinkEnergy::update()
+{
+ double power = getPower();
+ double now = surf_get_clock();
+ total_energy += power * (now - last_updated);
+ last_updated = now;
+}
+
+void LinkEnergy::initWattsRangeList()
+{
+
+ if (!power_range_watts_list.empty())
+ return;
+
+ const char* all_power_values_str = this->link->getProperty("watt_range");
+
+ if (all_power_values_str == nullptr)
+ return;
+
+ 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() == 2, "Power properties incorrectly defined - "
+ "could not retrieve idle and busy power values for link %s",
+ this->link->getCname());
+
+ /* min_power corresponds to the idle power (link load = 0) */
+ /* max_power is the power consumed at 100% link load */
+ char* idle = bprintf("Invalid idle power value for link%s", this->link->getCname());
+ char* busy = bprintf("Invalid busy power value for %s", this->link->getCname());
+
+ double idleVal = xbt_str_parse_double((current_power_values.at(0)).c_str(), idle);
+
+ double busyVal = xbt_str_parse_double((current_power_values.at(1)).c_str(), busy);
+
+ this->power_range_watts_list.push_back(LinkPowerRange(idleVal, busyVal));
+
+ xbt_free(idle);
+ xbt_free(busy);
+ update();
+ }
+}
+
+double LinkEnergy::getPower()
+{
+
+ if (power_range_watts_list.empty())
+ return 0.0;
+
+ auto range = power_range_watts_list[0];
+
+ double busy = range.busy;
+ double idle = range.idle;
+
+ double power_slope = busy - idle;
+
+ double normalized_link_usage = link->getUsage() / link->bandwidth();
+ double dynamic_power = power_slope * normalized_link_usage;
+
+ return idle + dynamic_power;
+}
+
+double LinkEnergy::getTotalEnergy()
+{
+ update();
+ return this->total_energy;
+}
+}
+}
+
+using simgrid::plugin::LinkEnergy;
+
+/* **************************** events callback *************************** */
+static void onCreation(simgrid::s4u::Link& link)
+{
+ XBT_DEBUG("onCreation is called for link: %s", link.getCname());
+ link.extension_set(new LinkEnergy(&link));
+}
+
+static void onCommunicate(simgrid::surf::NetworkAction* action, simgrid::s4u::Host* src, simgrid::s4u::Host* dst)
+{
+ XBT_DEBUG("onCommunicate is called");
+ for (simgrid::surf::LinkImpl* link : action->links()) {
+
+ if (link == nullptr)
+ continue;
+
+ XBT_DEBUG("Update link %s", link->getCname());
+ // Get the link_energy extension for the relevant link
+ LinkEnergy* link_energy = link->piface_.extension<LinkEnergy>();
+ link_energy->initWattsRangeList();
+ link_energy->update();
+ }
+}
+
+static void onActionStateChange(simgrid::surf::NetworkAction* action)
+{
+ XBT_DEBUG("onActionStateChange is called");
+ for (simgrid::surf::LinkImpl* link : action->links()) {
+
+ if (link == nullptr)
+ continue;
+
+ // Get the link_energy extension for the relevant link
+ LinkEnergy* link_energy = link->piface_.extension<LinkEnergy>();
+ link_energy->update();
+ }
+}
+
+static void onLinkStateChange(simgrid::s4u::Link& link)
+{
+ XBT_DEBUG("onLinkStateChange is called for link: %s", link.getCname());
+
+ LinkEnergy* link_energy = link.extension<LinkEnergy>();
+ link_energy->update();
+}
+
+static void onLinkDestruction(simgrid::s4u::Link& link)
+{
+ XBT_DEBUG("onLinkDestruction is called for link: %s", link.getCname());
+
+ LinkEnergy* link_energy = link.extension<LinkEnergy>();
+ link_energy->update();
+}
+
+static void computeAndDisplayTotalEnergy()
+{
+ std::vector<simgrid::s4u::Link*> link_list;
+ simgrid::s4u::Engine::getInstance()->getLinkList(&link_list);
+ double total_energy = 0.0; // Total dissipated energy (whole platform)
+ for (const auto link : link_list) {
+ LinkEnergy* link_energy = link->extension<LinkEnergy>();
+
+ double a_link_total_energy = link_energy->getTotalEnergy();
+ total_energy += a_link_total_energy;
+ const char* name = link->getCname();
+ if (strcmp(name, "__loopback__"))
+ XBT_INFO("Link '%s' total consumption: %f", name, a_link_total_energy);
+ }
+
+ XBT_INFO("Total energy over all links: %f", total_energy);
+}
+
+static void onSimulationEnd()
+{
+ computeAndDisplayTotalEnergy();
+}
+/* **************************** Public interface *************************** */
+SG_BEGIN_DECL()
+/** \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
+ * #MSG_init().
+ */
+void sg_link_energy_plugin_init()
+{
+
+ if (LinkEnergy::EXTENSION_ID.valid())
+ return;
+ LinkEnergy::EXTENSION_ID = simgrid::s4u::Link::extension_create<LinkEnergy>();
+
+ simgrid::s4u::Link::onCreation.connect(&onCreation);
+ simgrid::s4u::Link::onStateChange.connect(&onLinkStateChange);
+ simgrid::s4u::Link::onDestruction.connect(&onLinkDestruction);
+ simgrid::s4u::Link::onCommunicationStateChange.connect(&onActionStateChange);
+ simgrid::s4u::Link::onCommunicate.connect(&onCommunicate);
+ simgrid::s4u::onSimulationEnd.connect(&onSimulationEnd);
+}
+
+SG_END_DECL()
src/surf/network_constant.cpp
src/surf/network_interface.cpp
src/surf/plugins/host_energy.cpp
+ src/surf/plugins/link_energy.cpp
src/surf/plugins/host_load.cpp
src/surf/PropertyHolder.cpp
src/surf/sg_platf.cpp