Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Action::links() cannot be used for NS3Actions
[simgrid.git] / src / surf / network_interface.cpp
index 37ee98e..c315bb1 100644 (file)
-/* Copyright (c) 2013-2014. The SimGrid Team.
+/* Copyright (c) 2013-2015. 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 <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);
-}
+namespace simgrid {
+  namespace surf {
 
-int sg_link_is_shared(Link *link){
-  return link->isShared();
-}
-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();
-}
-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) {}
-
-         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);
-}
-/*************
- * 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);
-  }
-}
+  /* List of links */
+  std::unordered_map<std::string, LinkImpl*>* LinkImpl::links = new std::unordered_map<std::string, LinkImpl*>();
 
-void net_add_traces(){
-  surf_network_model->addTraces();
+  LinkImpl* LinkImpl::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 LinkImpl::linksCount()
+  {
+    return links->size();
+    }
+    /** @brief Returns a list of all existing links */
+    LinkImpl** LinkImpl::linksList()
+    {
+      LinkImpl** res = xbt_new(LinkImpl*, (int)links->size());
+      int i          = 0;
+      for (auto kv : *links) {
+        res[i] = kv.second;
+        i++;
+      }
+      return res;
+    }
+    /** @brief destructor of the static data */
+    void LinkImpl::linksExit()
+    {
+      for (auto kv : *links)
+        (kv.second)->destroy();
+      delete links;
+    }
+  }
 }
 
 /*********
  * Model *
  *********/
 
-NetworkModel *surf_network_model = NULL;
-
-double NetworkModel::latencyFactor(double /*size*/) {
-  return sg_latency_factor;
-}
+simgrid::surf::NetworkModel *surf_network_model = nullptr;
 
-double NetworkModel::bandwidthFactor(double /*size*/) {
-  return sg_bandwidth_factor;
-}
+namespace simgrid {
+  namespace surf {
 
-double NetworkModel::bandwidthConstraint(double rate, double /*bound*/, double /*size*/) {
-  return rate;
-}
-
-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::nextOccuringEventFull(double now)
+    {
+      double minRes = Model::nextOccuringEventFull(now);
 
-  return minRes;
-}
+      for(auto it(getRunningActionSet()->begin()), itend(getRunningActionSet()->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)
-{
-  surf_callback_emit(networkLinkCreatedCallbacks, this);
-  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)
-{
-  surf_callback_emit(networkLinkCreatedCallbacks, this);
-  if (state_trace)
-    p_stateEvent = tmgr_history_add_trace(history, state_trace, 0.0, 0, this);
+    LinkImpl::LinkImpl(simgrid::surf::NetworkModel* model, const char* name, lmm_constraint_t constraint)
+        : Resource(model, name, constraint), piface_(this)
+    {
 
-  links->insert({name, this});
-  XBT_DEBUG("Create link '%s'",name);
+      if (strcmp(name,"__loopback__"))
+        xbt_assert(not LinkImpl::byName(name), "Link '%s' declared several times in the platform.", name);
 
-}
+      latency_.scale   = 1;
+      bandwidth_.scale = 1;
 
-Link::~Link()
-{
-  surf_callback_emit(networkLinkDestructedCallbacks, this);
-}
+      links->insert({name, this});
+      XBT_DEBUG("Create link '%s'",name);
 
-bool Link::isUsed()
-{
-  return lmm_constraint_used(getModel()->getMaxminSystem(), getConstraint());
-}
+    }
 
-double Link::getLatency()
-{
-  return m_latCurrent;
-}
+    /** @brief use destroy() instead of this destructor */
+    LinkImpl::~LinkImpl()
+    {
+      xbt_assert(currentlyDestroying_, "Don't delete Links directly. Call destroy() instead.");
+    }
+    /** @brief Fire the required callbacks and destroy the object
+     *
+     * Don't delete directly a Link, call l->destroy() instead.
+     */
+    void LinkImpl::destroy()
+    {
+      if (not currentlyDestroying_) {
+        currentlyDestroying_ = true;
+        s4u::Link::onDestruction(this->piface_);
+        delete this;
+      }
+    }
 
-double Link::getBandwidth()
-{
-  return p_power.peak * p_power.scale;
-}
+    bool LinkImpl::isUsed()
+    {
+      return lmm_constraint_used(model()->getMaxminSystem(), constraint());
+    }
 
-bool Link::isShared()
-{
-  return lmm_constraint_is_shared(getConstraint());
-}
+    double LinkImpl::latency()
+    {
+      return latency_.peak * latency_.scale;
+    }
 
-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 LinkImpl::bandwidth()
+    {
+      return bandwidth_.peak * bandwidth_.scale;
+    }
 
+    int LinkImpl::sharingPolicy()
+    {
+      return lmm_constraint_sharing_policy(constraint());
+    }
 
+    void LinkImpl::turnOn()
+    {
+      if (isOff()) {
+        Resource::turnOn();
+        s4u::Link::onStateChange(this->piface_);
+      }
+    }
+    void LinkImpl::turnOff()
+    {
+      if (isOn()) {
+        Resource::turnOff();
+        s4u::Link::onStateChange(this->piface_);
+      }
+    }
+    void LinkImpl::setStateTrace(tmgr_trace_t trace)
+    {
+      xbt_assert(stateEvent_ == nullptr, "Cannot set a second state trace to Link %s", cname());
+      stateEvent_ = future_evt_set->add_trace(trace, this);
+    }
+    void LinkImpl::setBandwidthTrace(tmgr_trace_t trace)
+    {
+      xbt_assert(bandwidth_.event == nullptr, "Cannot set a second bandwidth trace to Link %s", cname());
+      bandwidth_.event = future_evt_set->add_trace(trace, this);
+    }
+    void LinkImpl::setLatencyTrace(tmgr_trace_t trace)
+    {
+      xbt_assert(latency_.event == nullptr, "Cannot set a second latency trace to Link %s", cname());
+      latency_.event = future_evt_set->add_trace(trace, this);
+    }
 
-/**********
- * Action *
- **********/
 
-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);
+    /**********
+     * Action *
+     **********/
+
+    void NetworkAction::setState(Action::State state)
+    {
+      Action::setState(state);
+      s4u::Link::onCommunicationStateChange(this);
+    }
+
+    /** @brief returns a list of all Links that this action is using */
+    std::list<LinkImpl*> NetworkAction::links()
+    {
+      std::list<LinkImpl*> retlist;
+      lmm_system_t sys = getModel()->getMaxminSystem();
+      int llen         = lmm_get_number_of_cnst_from_var(sys, variable_);
+
+      for (int i = 0; i < llen; i++) {
+        /* Beware of composite actions: ptasks put links and cpus together */
+        // extra pb: we cannot dynamic_cast from void*...
+        Resource* resource = static_cast<Resource*>(lmm_constraint_id(lmm_get_cnst_from_var(sys, getVariable(), i)));
+        LinkImpl* link     = dynamic_cast<LinkImpl*>(resource);
+        if (link != nullptr)
+          retlist.push_back(link);
+      }
+
+      return retlist;
+    }
+  }
 }
 
 #endif /* NETWORK_INTERFACE_CPP_ */