Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
std::unordered_map are sufficient, no need for boost here
[simgrid.git] / src / surf / network_interface.cpp
index 3daac06..6a0a74a 100644 (file)
 /* 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 <algorithm>
+
 #include "network_interface.hpp"
 #include "simgrid/sg_config.h"
 
 #ifndef NETWORK_INTERFACE_CPP_
 #define NETWORK_INTERFACE_CPP_
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf,
-                                "Logging specific to the SURF network module");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf, "Logging specific to the SURF network module");
 
 /*********
  * C API *
  *********/
-SG_BEGIN_DECL()
-const char* sg_link_name(Link *link) {
-  return link->getName();
-}
-Link * sg_link_by_name(const char* name) {
-  return Link::byName(name);
-}
 
-int sg_link_is_shared(Link *link){
-  return link->sharingPolicy();
-}
-double sg_link_bandwidth(Link *link){
-  return link->getBandwidth();
-}
-double sg_link_latency(Link *link){
-  return link->getLatency();
-}
-void* sg_link_data(Link *link) {
-       return link->getData();
-}
-void sg_link_data_set(Link *link,void *data) {
-       link->setData(data);
-}
-int sg_link_amount(void) {
-       return Link::linksAmount();
-}
-Link** sg_link_list(void) {
-       return Link::linksList();
-}
-void sg_link_exit(void) {
-       Link::linksExit();
+extern "C" {
+
+  const char* sg_link_name(Link *link) {
+    return link->getName();
+  }
+  Link * sg_link_by_name(const char* name) {
+    return Link::byName(name);
+  }
+
+  int sg_link_is_shared(Link *link){
+    return link->sharingPolicy();
+  }
+  double sg_link_bandwidth(Link *link){
+    return link->getBandwidth();
+  }
+  double sg_link_latency(Link *link){
+    return link->getLatency();
+  }
+  void* sg_link_data(Link *link) {
+    return link->getData();
+  }
+  void sg_link_data_set(Link *link,void *data) {
+    link->setData(data);
+  }
+  int sg_link_count() {
+    return Link::linksCount();
+  }
+  Link** sg_link_list() {
+    return Link::linksList();
+  }
+  void sg_link_exit() {
+    Link::linksExit();
+  }
+
 }
-SG_END_DECL()
+
 /*****************
  * List of links *
  *****************/
 
-boost::unordered_map<std::string,Link *> *Link::links = new boost::unordered_map<std::string,Link *>();
-Link *Link::byName(const char* name) {
-         Link * res = NULL;
-         try {
-                 res = links->at(name);
-         } catch (std::out_of_range& e) {}
+namespace simgrid {
+  namespace surf {
 
-         return res;
-}
-/** @brief Returns the amount of links in the platform */
-int Link::linksAmount() {
-         return links->size();
-}
-/** @brief Returns a list of all existing links */
-Link **Link::linksList() {
-         Link **res = xbt_new(Link*, (int)links->size());
-         int i=0;
-         for (auto kv : *links) {
-                 res[i++] = kv.second;
-         }
-         return res;
-}
-/** @brief destructor of the static data */
-void Link::linksExit() {
-       for (auto kv : *links)
-               delete (kv.second);
-       delete links;
-}
-/*************
- * Callbacks *
- *************/
-
-surf_callback(void, Link*) networkLinkCreatedCallbacks;
-surf_callback(void, Link*) networkLinkDestructedCallbacks;
-surf_callback(void, Link*, e_surf_resource_state_t, e_surf_resource_state_t) networkLinkStateChangedCallbacks;
-surf_callback(void, NetworkAction*, e_surf_action_state_t, e_surf_action_state_t) networkActionStateChangedCallbacks;
-surf_callback(void, NetworkAction*, RoutingEdge *src, RoutingEdge *dst, double size, double rate) networkCommunicateCallbacks;
-
-void netlink_parse_init(sg_platf_link_cbarg_t link){
-  if (link->policy == SURF_LINK_FULLDUPLEX) {
-    char *link_id;
-    link_id = bprintf("%s_UP", link->id);
-    surf_network_model->createLink(link_id,
-                      link->bandwidth,
-                      link->bandwidth_trace,
-                      link->latency,
-                      link->latency_trace,
-                      link->state,
-                      link->state_trace, link->policy, link->properties);
-    xbt_free(link_id);
-    link_id = bprintf("%s_DOWN", link->id);
-    surf_network_model->createLink(link_id,
-                      link->bandwidth,
-                      link->bandwidth_trace,
-                      link->latency,
-                      link->latency_trace,
-                      link->state,
-                      link->state_trace, link->policy, link->properties);
-    xbt_free(link_id);
-  } else {
-         surf_network_model->createLink(link->id,
-                         link->bandwidth,
-                         link->bandwidth_trace,
-                         link->latency,
-                         link->latency_trace,
-                         link->state,
-                         link->state_trace, link->policy, link->properties);
-  }
-}
+    std::unordered_map<std::string,Link *> *Link::links = new std::unordered_map<std::string,Link *>();
+    Link *Link::byName(const char* name) {
+      if (links->find(name) == links->end())
+        return nullptr;
+      return  links->at(name);
+    }
+    /** @brief Returns the amount of links in the platform */
+    int Link::linksCount() {
+      return links->size();
+    }
+    /** @brief Returns a list of all existing links */
+    Link **Link::linksList() {
+      Link **res = xbt_new(Link*, (int)links->size());
+      int i=0;
+      for (auto kv : *links) {
+        res[i++] = kv.second;
+      }
+      return res;
+    }
+    /** @brief destructor of the static data */
+    void Link::linksExit() {
+      for (auto kv : *links)
+        (kv.second)->destroy();
+      delete links;
+    }
 
-void net_add_traces(){
-  surf_network_model->addTraces();
+    /*************
+     * Callbacks *
+     *************/
+
+    simgrid::xbt::signal<void(Link*)> Link::onCreation;
+    simgrid::xbt::signal<void(Link*)> Link::onDestruction;
+    simgrid::xbt::signal<void(Link*)> Link::onStateChange;
+
+    simgrid::xbt::signal<void(NetworkAction*, Action::State, Action::State)> networkActionStateChangedCallbacks;
+    simgrid::xbt::signal<void(NetworkAction*, kernel::routing::NetCard *src, kernel::routing::NetCard *dst)> Link::onCommunicate;
+
+  }
 }
 
 /*********
  * Model *
  *********/
 
-NetworkModel *surf_network_model = NULL;
+simgrid::surf::NetworkModel *surf_network_model = nullptr;
 
-double NetworkModel::latencyFactor(double /*size*/) {
-  return sg_latency_factor;
-}
-
-double NetworkModel::bandwidthFactor(double /*size*/) {
-  return sg_bandwidth_factor;
-}
-
-double NetworkModel::bandwidthConstraint(double rate, double /*bound*/, double /*size*/) {
-  return rate;
-}
+namespace simgrid {
+  namespace surf {
 
-double NetworkModel::shareResourcesFull(double now)
-{
-  NetworkAction *action = NULL;
-  ActionList *runningActions = surf_network_model->getRunningActionSet();
-  double minRes;
+    NetworkModel::~NetworkModel()
+    {
+      lmm_system_free(maxminSystem_);
+      xbt_heap_free(actionHeap_);
+      delete modifiedSet_;
+    }
 
-  minRes = shareResourcesMaxMin(runningActions, surf_network_model->p_maxminSystem, surf_network_model->f_networkSolve);
+    double NetworkModel::latencyFactor(double /*size*/) {
+      return sg_latency_factor;
+    }
 
-  for(ActionList::iterator it(runningActions->begin()), itend(runningActions->end())
-       ; it != itend ; ++it) {
-      action = static_cast<NetworkAction*>(&*it);
-#ifdef HAVE_LATENCY_BOUND_TRACKING
-    if (lmm_is_variable_limited_by_latency(action->getVariable())) {
-      action->m_latencyLimited = 1;
-    } else {
-      action->m_latencyLimited = 0;
+    double NetworkModel::bandwidthFactor(double /*size*/) {
+      return sg_bandwidth_factor;
     }
-#endif
-    if (action->m_latency > 0) {
-      minRes = (minRes < 0) ? action->m_latency : min(minRes, action->m_latency);
+
+    double NetworkModel::bandwidthConstraint(double rate, double /*bound*/, double /*size*/) {
+      return rate;
     }
-  }
 
-  XBT_DEBUG("Min of share resources %f", minRes);
+    double NetworkModel::next_occuring_event_full(double now)
+    {
+      ActionList *runningActions = surf_network_model->getRunningActionSet();
+      double minRes = shareResourcesMaxMin(runningActions, surf_network_model->maxminSystem_, surf_network_model->f_networkSolve);
 
-  return minRes;
-}
+      for(ActionList::iterator it(runningActions->begin()), itend(runningActions->end())
+          ; it != itend ; ++it) {
+        NetworkAction *action = static_cast<NetworkAction*>(&*it);
+        if (action->latency_ > 0)
+          minRes = (minRes < 0) ? action->latency_ : std::min(minRes, action->latency_);
+      }
 
-/************
- * Resource *
- ************/
+      XBT_DEBUG("Min of share resources %f", minRes);
 
-Link::Link(NetworkModel *model, const char *name, xbt_dict_t props)
-: Resource(model, name, props)
-, p_latEvent(NULL)
-{
-  links->insert({name, this});
+      return minRes;
+    }
 
-  XBT_DEBUG("Create link '%s'",name);
-}
+    /************
+     * Resource *
+     ************/
 
-Link::Link(NetworkModel *model, const char *name, xbt_dict_t props,
-                                lmm_constraint_t constraint,
-                            tmgr_history_t history,
-                            tmgr_trace_t state_trace)
-: Resource(model, name, props, constraint),
-  p_latEvent(NULL)
-{
-  if (state_trace)
-    p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, this);
+    Link::Link(simgrid::surf::NetworkModel *model, const char *name, xbt_dict_t props)
+    : Resource(model, name),
+      PropertyHolder(props)
+    {
+      links->insert({name, this});
 
-  links->insert({name, this});
-  XBT_DEBUG("Create link '%s'",name);
+      m_latency.scale = 1;
+      m_bandwidth.scale = 1;
+      XBT_DEBUG("Create link '%s'",name);
+    }
 
-}
+    Link::Link(simgrid::surf::NetworkModel *model, const char *name, xbt_dict_t props, lmm_constraint_t constraint)
+    : Resource(model, name, constraint),
+      PropertyHolder(props)
+    {
+      if (strcmp(name,"__loopback__"))
+        xbt_assert(!Link::byName(name), "Link '%s' declared several times in the platform.", name);
 
-Link::~Link()
-{
-  surf_callback_emit(networkLinkDestructedCallbacks, this);
-}
+      m_latency.scale = 1;
+      m_bandwidth.scale = 1;
 
-bool Link::isUsed()
-{
-  return lmm_constraint_used(getModel()->getMaxminSystem(), getConstraint());
-}
+      links->insert({name, this});
+      XBT_DEBUG("Create link '%s'",name);
 
-double Link::getLatency()
-{
-  return m_latCurrent;
-}
+    }
 
-double Link::getBandwidth()
-{
-  return p_power.peak * p_power.scale;
-}
+    /** @brief use destroy() instead of this destructor */
+    Link::~Link() {
+      xbt_assert(currentlyDestroying_, "Don't delete Links directly. Call destroy() instead.");
+    }
+    /** @brief Fire the require callbacks and destroy the object
+     *
+     * Don't delete directly an Link, call l->destroy() instead.
+     */
+    void Link::destroy()
+    {
+      if (!currentlyDestroying_) {
+        currentlyDestroying_ = true;
+        onDestruction(this);
+        delete this;
+      }
+    }
 
-int Link::sharingPolicy()
-{
-  return lmm_constraint_sharing_policy(getConstraint());
-}
+    bool Link::isUsed()
+    {
+      return lmm_constraint_used(getModel()->getMaxminSystem(), getConstraint());
+    }
 
-void Link::setState(e_surf_resource_state_t state){
-  e_surf_resource_state_t old = Resource::getState();
-  Resource::setState(state);
-  surf_callback_emit(networkLinkStateChangedCallbacks, this, old, state);
-}
+    double Link::getLatency()
+    {
+      return m_latency.peak * m_latency.scale;
+    }
+
+    double Link::getBandwidth()
+    {
+      return m_bandwidth.peak * m_bandwidth.scale;
+    }
+
+    int Link::sharingPolicy()
+    {
+      return lmm_constraint_sharing_policy(getConstraint());
+    }
+
+    void Link::turnOn(){
+      if (isOff()) {
+        Resource::turnOn();
+        onStateChange(this);
+      }
+    }
+    void Link::turnOff(){
+      if (isOn()) {
+        Resource::turnOff();
+        onStateChange(this);
+      }
+    }
+    void Link::setStateTrace(tmgr_trace_t trace) {
+      xbt_assert(m_stateEvent==nullptr,"Cannot set a second state trace to Link %s", getName());
+      m_stateEvent = future_evt_set->add_trace(trace, 0.0, this);
+    }
+    void Link::setBandwidthTrace(tmgr_trace_t trace)
+    {
+      xbt_assert(m_bandwidth.event==nullptr,"Cannot set a second bandwidth trace to Link %s", getName());
+      m_bandwidth.event = future_evt_set->add_trace(trace, 0.0, this);
+    }
+    void Link::setLatencyTrace(tmgr_trace_t trace)
+    {
+      xbt_assert(m_latency.event==nullptr,"Cannot set a second latency trace to Link %s", getName());
+      m_latency.event = future_evt_set->add_trace(trace, 0.0, this);
+    }
 
 
+    /**********
+     * Action *
+     **********/
 
-/**********
- * Action *
- **********/
+    void NetworkAction::setState(Action::State state){
+      Action::State old = getState();
+      Action::setState(state);
+      networkActionStateChangedCallbacks(this, old, state);
+    }
 
-void NetworkAction::setState(e_surf_action_state_t state){
-  e_surf_action_state_t old = getState();
-  Action::setState(state);
-  surf_callback_emit(networkActionStateChangedCallbacks, this, old, state);
+  }
 }
 
 #endif /* NETWORK_INTERFACE_CPP_ */