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 bae76b8..c315bb1 100644 (file)
 #ifndef NETWORK_INTERFACE_CPP_
 #define NETWORK_INTERFACE_CPP_
 
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf,
-                                "Logging specific to the SURF network module");
-
-/*********
- * C API *
- *********/
-
-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_amount(void) {
-       return Link::linksAmount();
-}
-Link** sg_link_list(void) {
-       return Link::linksList();
-}
-void sg_link_exit(void) {
-       Link::linksExit();
-}
-
-}
-
-/*****************
- * List of links *
- *****************/
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network, surf, "Logging specific to the SURF network module");
 
 namespace simgrid {
-namespace surf {
+  namespace surf {
 
-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) {}
+  /* List of links */
+  std::unordered_map<std::string, LinkImpl*>* LinkImpl::links = new std::unordered_map<std::string, LinkImpl*>();
 
-         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)
-               (kv.second)->destroy();
-       delete links;
-}
-
-/*************
- * Callbacks *
- *************/
-
-simgrid::xbt::signal<void(simgrid::surf::Link*)> Link::onCreation;
-simgrid::xbt::signal<void(simgrid::surf::Link*)> Link::onDestruction;
-simgrid::xbt::signal<void(simgrid::surf::Link*, int, int)> Link::onStateChange; // signature: wasOn, currentlyOn
-
-simgrid::xbt::signal<void(simgrid::surf::NetworkAction*, e_surf_action_state_t, e_surf_action_state_t)> networkActionStateChangedCallbacks;
-simgrid::xbt::signal<void(simgrid::surf::NetworkAction*, simgrid::surf::NetCard *src, simgrid::surf::NetCard *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->initiallyOn,
-                      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->initiallyOn,
-                      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->initiallyOn,
-                         link->state_trace, link->policy, link->properties);
+  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;
+    }
   }
 }
 
@@ -141,140 +56,162 @@ void netlink_parse_init(sg_platf_link_cbarg_t link){
  * Model *
  *********/
 
-simgrid::surf::NetworkModel *surf_network_model = NULL;
+simgrid::surf::NetworkModel *surf_network_model = nullptr;
 
 namespace simgrid {
-namespace surf {
+  namespace surf {
 
-double NetworkModel::latencyFactor(double /*size*/) {
-  return sg_latency_factor;
-}
-
-double NetworkModel::bandwidthFactor(double /*size*/) {
-  return sg_bandwidth_factor;
-}
+    NetworkModel::~NetworkModel()
+    {
+      lmm_system_free(maxminSystem_);
+      xbt_heap_free(actionHeap_);
+      delete modifiedSet_;
+    }
 
-double NetworkModel::bandwidthConstraint(double rate, double /*bound*/, double /*size*/) {
-  return rate;
-}
+    double NetworkModel::latencyFactor(double /*size*/) {
+      return sg_latency_factor;
+    }
 
-double NetworkModel::shareResourcesFull(double now)
-{
-  NetworkAction *action = NULL;
-  ActionList *runningActions = surf_network_model->getRunningActionSet();
-  double minRes;
-
-  minRes = shareResourcesMaxMin(runningActions, surf_network_model->p_maxminSystem, surf_network_model->f_networkSolve);
-
-  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 : std::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(simgrid::surf::NetworkModel *model, const char *name, xbt_dict_t props)
-: Resource(model, name),
-  PropertyHolder(props)
-{
-  links->insert({name, this});
+      return minRes;
+    }
 
-  XBT_DEBUG("Create link '%s'",name);
-}
+    /************
+     * Resource *
+     ************/
 
-Link::Link(simgrid::surf::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, constraint),
-  PropertyHolder(props)
-{
-  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;
 
-/** @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;
-       }
-}
+      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_speed.peak * p_speed.scale;
-}
+    bool LinkImpl::isUsed()
+    {
+      return lmm_constraint_used(model()->getMaxminSystem(), constraint());
+    }
 
-int Link::sharingPolicy()
-{
-  return lmm_constraint_sharing_policy(getConstraint());
-}
+    double LinkImpl::latency()
+    {
+      return latency_.peak * latency_.scale;
+    }
 
-void Link::turnOn(){
-  if (isOff()) {
-    Resource::turnOn();
-    onStateChange(this, 0, 1);
-  }
-}
-void Link::turnOff(){
-  if (isOn()) {
-    Resource::turnOff();
-    onStateChange(this, 1, 0);
-  }
-}
+    double LinkImpl::bandwidth()
+    {
+      return bandwidth_.peak * bandwidth_.scale;
+    }
 
-/**********
- * Action *
- **********/
+    int LinkImpl::sharingPolicy()
+    {
+      return lmm_constraint_sharing_policy(constraint());
+    }
 
-void NetworkAction::setState(e_surf_action_state_t state){
-  e_surf_action_state_t old = getState();
-  Action::setState(state);
-  networkActionStateChangedCallbacks(this, old, state);
-}
+    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(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_ */