Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into 'master'
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Fri, 20 Sep 2019 12:57:08 +0000 (14:57 +0200)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Fri, 20 Sep 2019 12:57:08 +0000 (14:57 +0200)
NS-3: unblock the number of communications + detect when several flows are simultaneously finishing

See merge request simgrid/simgrid!17

1  2 
src/surf/network_ns3.cpp

diff --combined src/surf/network_ns3.cpp
@@@ -17,6 -17,7 +17,7 @@@
  #include <ns3/ipv4-address-helper.h>
  #include <ns3/packet-sink-helper.h>
  #include <ns3/point-to-point-helper.h>
+ #include <ns3/application-container.h>
  
  #include "network_ns3.hpp"
  #include "ns3/ns3_simulator.hpp"
@@@ -39,6 -40,7 +40,7 @@@ std::vector<std::string> IPV4addr
   *****************/
  
  extern std::map<std::string, SgFlow*> flow_from_sock;
+ extern std::map<std::string, ns3::ApplicationContainer> sink_from_sock;
  
  static ns3::InternetStackHelper stack;
  static ns3::NodeContainer nodes;
@@@ -165,7 -167,7 +167,7 @@@ NetworkNS3Model::NetworkNS3Model() : Ne
    });
    surf::on_cluster.connect(&clusterCreation_cb);
  
 -  s4u::on_platform_created.connect(&postparse_cb);
 +  s4u::Engine::on_platform_created.connect(&postparse_cb);
    s4u::NetZone::on_route_creation.connect(&routeCreation_cb);
  }
  
@@@ -190,34 -192,22 +192,22 @@@ Action* NetworkNS3Model::communicate(s4
  
  double NetworkNS3Model::next_occuring_event(double now)
  {
-   double time_to_next_flow_completion;
+   double time_to_next_flow_completion = 0.0;
    XBT_DEBUG("ns3_next_occuring_event");
  
    //get the first relevant value from the running_actions list
    if (get_started_action_set()->empty() || now == 0.0)
      return -1.0;
  
-   bool ns3_processed_all_finished_flows;
-   do {
-     double delta = surf_get_clock() + now - ns3::Simulator::Now().GetSeconds();
-     ns3_simulator(delta);
-     time_to_next_flow_completion = ns3::Simulator::Now().GetSeconds() - surf_get_clock();
-     // NS3 stops as soon as it detects that a flow is finished.
-     // However, to stop NS3 in a consistant state for the current simulated time,
-     // we need to make sure that NS3 detects all the flows finishing at the current time.
-     ns3_processed_all_finished_flows = true;
-     // A flow that has 0 remaining_ is finishing at the current simulated time.
-     // However, NS3 hadn't notice it yet if finished_ == false.
-     for (const auto& elm : flow_from_sock) {
-       SgFlow* sgFlow = elm.second;
-       if(!sgFlow->finished_ && sgFlow->remaining_ == 0){
-         ns3_processed_all_finished_flows = false;
-         break;
-       }
-     }
-   } while (!ns3_processed_all_finished_flows || double_equals(time_to_next_flow_completion, 0, sg_surf_precision));
+   XBT_DEBUG("doing a ns3 simulation for a duration of %f", now);
+   ns3_simulator(now);  
+   time_to_next_flow_completion = ns3::Simulator::Now().GetSeconds() - surf_get_clock();
+   // NS-3 stops as soon as a flow ends,
+   // but it does not process the other flows that may finish at the same (simulated) time.
+   // If another flow ends at the same time, time_to_next_flow_completion = 0
+   if(double_equals(time_to_next_flow_completion, 0, sg_surf_precision))
+     time_to_next_flow_completion = 0.0; 
+  
    XBT_DEBUG("min       : %f", now);
    XBT_DEBUG("ns3  time : %f", ns3::Simulator::Now().GetSeconds());
    XBT_DEBUG("surf time : %f", surf_get_clock());
@@@ -245,7 -235,13 +235,13 @@@ void NetworkNS3Model::update_actions_st
      SgFlow* sgFlow            = elm.second;
      NetworkNS3Action * action = sgFlow->action_;
      XBT_DEBUG("Processing socket %p (action %p)",sgFlow,action);
-     action->set_remains(action->get_cost() - sgFlow->sent_bytes_);
+     // Because NS3 stops as soon as a flow is finished, the other flows that ends at the same time may remains in an inconsistant state
+     // (i.e. remains_ == 0 but finished_ == false).
+     // However, SimGrid considers sometimes that an action with remains_ == 0 is finished.
+     // Thus, to avoid inconsistencies between SimGrid and NS3, set remains to 0 only when the flow is finished in NS3
+     int remains = action->get_cost() - sgFlow->sent_bytes_;
+     if(remains > 0)
+       action->set_remains(remains);
  
      if (TRACE_is_enabled() && action->get_state() == kernel::resource::Action::State::STARTED) {
        double data_delta_sent = sgFlow->sent_bytes_ - action->last_sent_;
      if(sgFlow->finished_){
        socket_to_destroy.push_back(ns3_socket);
        XBT_DEBUG("Destroy socket %p of action %p", ns3_socket.c_str(), action);
+       action->set_remains(0);
        action->finish(kernel::resource::Action::State::FINISHED);
      } else {
        XBT_DEBUG("Socket %p sent %u bytes out of %u (%u remaining)", ns3_socket.c_str(), sgFlow->sent_bytes_,
      }
      delete flow;
      flow_from_sock.erase(ns3_socket);
+     sink_from_sock.erase(ns3_socket);
    }
  }
  
@@@ -335,17 -333,22 +333,22 @@@ NetworkNS3Action::NetworkNS3Action(Mode
  
    XBT_DEBUG("ns3: Create flow of %.0f Bytes from %u to %u with Interface %s", totalBytes, node1, node2, addr.c_str());
    ns3::PacketSinkHelper sink("ns3::TcpSocketFactory", ns3::InetSocketAddress(ns3::Ipv4Address::GetAny(), port_number));
-   sink.Install(dst_node);
+   ns3::ApplicationContainer apps = sink.Install(dst_node);
  
    ns3::Ptr<ns3::Socket> sock = ns3::Socket::CreateSocket(src_node, ns3::TcpSocketFactory::GetTypeId());
  
    flow_from_sock.insert({transform_socket_ptr(sock), new SgFlow(totalBytes, this)});
+   sink_from_sock.insert({transform_socket_ptr(sock), apps});
  
    sock->Bind(ns3::InetSocketAddress(port_number));
  
    ns3::Simulator::ScheduleNow(&start_flow, sock, addr.c_str(), port_number);
  
    port_number++;
+   if(port_number > 65000){
+     port_number = 1025;
+     XBT_WARN("Too many connections! Port number is saturated. Trying to use the oldest ports.");
+   }
    xbt_assert(port_number <= 65000, "Too many connections! Port number is saturated.");
  
    s4u::Link::on_communicate(*this, src, dst);