Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fullduplex support
authorschnorr <schnorr@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 9 Aug 2010 15:51:17 +0000 (15:51 +0000)
committerschnorr <schnorr@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 9 Aug 2010 15:51:17 +0000 (15:51 +0000)
details:
- added by Pedro
- LV08 model accepts a new option 'fullduplex',
  enabling a more realistic TCP behavior
- more details on the FAQ (that will be updated soon)

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@8134 48e7efb5-ca39-0410-a469-dd3cf9ba447f

21 files changed:
examples/msg/gtnets/gtnets.c
examples/msg/tracing/ms.c
include/msg/msg.h
src/include/simix/simix.h
src/include/surf/maxmin.h
src/include/surf/surf.h
src/instr/interface.c
src/msg/task.c
src/simix/smx_action.c
src/simix/smx_network.c
src/surf/gtnets/gtnets_interface.cc
src/surf/gtnets/gtnets_interface.h
src/surf/gtnets/gtnets_simulator.cc
src/surf/gtnets/gtnets_simulator.h
src/surf/maxmin.c
src/surf/network.c
src/surf/network_gtnets.c
src/surf/network_private.h
src/surf/surf_config.c
src/surf/surf_private.h
src/surf/workstation.c

index b6f07ac..196bd1b 100644 (file)
@@ -56,17 +56,16 @@ int master(int argc, char *argv[])
   /* slave name */
   slavename = argv[2];
   id = atoi(argv[3]);
-  sprintf(id_alias, "%d", id);
+  sprintf(id_alias, "flow_%d", id);
   slavenames[id] = slavename;
-
-  TRACE_category (slavename);
+  TRACE_category (id_alias);
 
   masternames[id] = MSG_host_get_name(MSG_host_self());
 
   {                             /*  Task creation.  */
     char sprintf_buffer[64] = "Task_0";
     todo = MSG_task_create(sprintf_buffer, 0, task_comm_size, NULL);
-    TRACE_msg_set_task_category(todo,slavename);
+    TRACE_msg_set_task_category(todo,id_alias);
     //keep track of running tasks
     gl_task_array[id] = todo;
     gl_data_size[id] = task_comm_size;
@@ -77,6 +76,7 @@ int master(int argc, char *argv[])
   }
 
   /* time measurement */
+  sprintf(id_alias, "%d", id);
   start_time = MSG_get_clock();
   MSG_task_send(todo, id_alias);
   end_time = MSG_get_clock();
@@ -98,6 +98,7 @@ int slave(int argc, char *argv[])
   m_task_t task = NULL;
   int a;
   int id = 0;
+  int limited_latency=0;
   double remaining = 0;
   char id_alias[10];
 
@@ -122,18 +123,29 @@ int slave(int argc, char *argv[])
     for (id = 0; id < NTASKS; id++) {
       if (gl_task_array[id] == NULL) {
       } else if (gl_task_array[id] == task) {
-        INFO5
+         limited_latency = MSG_task_is_latency_bounded(gl_task_array[id]);
+          if(limited_latency){
+                 INFO1("WARNING FLOW[%d] is limited by latency!!", id);
+          }
+         INFO5
           ("===> Estimated Bw of FLOW[%d] : %f ;  message from %s to %s  with remaining : %f",
            id, gl_data_size[id] / elapsed_time, masternames[id],
            slavenames[id], 0.0);
       } else {
         remaining = MSG_task_get_remaining_communication(gl_task_array[id]);
+       limited_latency = MSG_task_is_latency_bounded(gl_task_array[id]);
+
+        if(limited_latency){
+         INFO1("WARNING FLOW[%d] is limited by latency!!", id);
+        }
         INFO5
           ("===> Estimated Bw of FLOW[%d] : %f ;  message from %s to %s  with remaining : %f",
            id, (gl_data_size[id] - remaining) / elapsed_time, masternames[id],
            slavenames[id], remaining);
       }
+
     }
+       TRACE_mark ("endmark", "finished");
   }  
 
   MSG_task_destroy(task);
index 51e460f..d63b04d 100644 (file)
@@ -28,6 +28,7 @@ int master(int argc, char *argv[])
   //setting the variable "is_master" (previously declared) to value 1
   TRACE_host_variable_set ("is_master", 1);
 
+  TRACE_mark ("msmark", "start_send_tasks");
   int i;
   for (i = 0; i < number_of_tasks; i++) {
     m_task_t task=NULL;
@@ -41,6 +42,7 @@ int master(int argc, char *argv[])
     TRACE_msg_set_task_category (task, "compute");
     MSG_task_send(task, "master_mailbox");
   }
+  TRACE_mark ("msmark", "finish_send_tasks");
   
    for (i = 0; i < slaves_count; i++) { 
      m_task_t finalize = MSG_task_create ("finalize", 0, 0, 0);
@@ -120,6 +122,9 @@ int main(int argc, char *argv[])
   TRACE_host_variable_declare ("task_creation");
   TRACE_host_variable_declare ("task_computation");
 
+  //declaring user markers
+  TRACE_declare_mark ("msmark");
+
   //declaring user categories
   TRACE_category ("compute");
   TRACE_category ("finalize");
index 11faa2b..20a767d 100644 (file)
@@ -155,6 +155,7 @@ XBT_PUBLIC(MSG_error_t) MSG_get_errno(void);
 XBT_PUBLIC(double) MSG_task_get_compute_duration(m_task_t task);
 XBT_PUBLIC(double) MSG_task_get_remaining_computation(m_task_t task);
 XBT_PUBLIC(double) MSG_task_get_remaining_communication(m_task_t task);
+XBT_PUBLIC(int)    MSG_task_is_latency_bounded(m_task_t task);
 XBT_PUBLIC(double) MSG_task_get_data_size(m_task_t task);
 
 
index ab92846..325a5df 100644 (file)
@@ -184,6 +184,7 @@ XBT_INLINE XBT_PUBLIC(void) SIMIX_unregister_action_to_semaphore(smx_action_t ac
 
 
 XBT_PUBLIC(double) SIMIX_action_get_remains(smx_action_t action);
+XBT_PUBLIC(int) SIMIX_action_is_latency_bounded(smx_action_t action);
 
 XBT_PUBLIC(e_surf_action_state_t) SIMIX_action_get_state(smx_action_t action);
 
@@ -216,6 +217,7 @@ XBT_PUBLIC(void*) SIMIX_rdv_get_data(smx_rdv_t rdv);
 XBT_INLINE XBT_PUBLIC(void) SIMIX_communication_cancel(smx_comm_t comm);
 XBT_PUBLIC(void) SIMIX_communication_destroy(smx_comm_t comm);
 XBT_PUBLIC(double) SIMIX_communication_get_remains(smx_comm_t comm);
+XBT_PUBLIC(int)    SIMIX_communication_is_latency_bounded(smx_comm_t comm);
 XBT_PUBLIC(void *) SIMIX_communication_get_data(smx_comm_t comm);
 
 XBT_PUBLIC(void *) SIMIX_communication_get_src_buf(smx_comm_t comm);
index 5fb85ba..0de4266 100644 (file)
@@ -68,6 +68,8 @@ XBT_PUBLIC(void) lmm_expand(lmm_system_t sys, lmm_constraint_t cnst,
      lmm_constraint_t lmm_get_next_active_constraint(lmm_system_t sys,
                                                      lmm_constraint_t cnst);
 
+     XBT_PUBLIC(int) lmm_is_variable_limited_by_latency(lmm_variable_t var);
+
      void *lmm_constraint_id(lmm_constraint_t cnst);
      void *lmm_variable_id(lmm_variable_t var);
 
index 63aa9fa..d32041f 100644 (file)
@@ -77,6 +77,8 @@ XBT_PUBLIC(void) model_help(const char* category, s_surf_model_description_t * t
                                   the task is completed) */
        double remains;          /**< How much of that cost remains to
                                 * be done in the currently running task */
+       int latency_limited;          /**< Set to 1 if is limited by latency, 0 otherwise */
+
        double start;            /**< start time  */
        double finish;           /**< finish time : this is modified during the run
                                 * and fluctuates until the task is completed */
@@ -253,6 +255,7 @@ XBT_PUBLIC_DATA(routing_t) used_routing;
        void (*set_max_duration) (surf_action_t action, double duration);/**< Set the max duration of an action*/
        void (*set_priority) (surf_action_t action, double priority);/**< Set the priority of an action */
        double (*get_remains) (surf_action_t action);/**< Get the remains of an action */
+       int (*get_latency_limited) (surf_action_t action);/**< Return 1 if action is limited by latency, 0 otherwise */
 
        xbt_dict_t resource_set;
 
index 88a0576..1d87e24 100644 (file)
@@ -4,11 +4,12 @@
 /* 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 "instr/private.h"
-
+#include "simgrid_config.h"
 
 #ifdef HAVE_TRACING
 
+#include "instr/private.h"
+
 XBT_LOG_NEW_DEFAULT_CATEGORY(tracing,"Tracing Interface");
 
 static xbt_dict_t defined_types;
index 3479e47..01bd7e0 100644 (file)
  *  <em>message size</em> and some <em>private data</em>.
  */
 
+#ifdef HAVE_RUBY /* FIXME: KILLME */
+XBT_LOG_EXTERNAL_CATEGORY(ruby);
+#endif
+
+
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(msg_task, msg,
+                                "Logging specific to MSG (task)");
+
 /********************************* Task **************************************/
 /** \ingroup m_task_management
  * \brief Creates a new #m_task_t.
@@ -230,8 +239,6 @@ double MSG_task_get_remaining_computation(m_task_t task)
   }
 }
 
-
-
 /** \ingroup m_task_management
  * \brief Returns the total amount received by a task #m_task_t.
  *
@@ -240,10 +247,22 @@ double MSG_task_get_remaining_communication(m_task_t task)
 {
   xbt_assert0((task != NULL)
               && (task->simdata != NULL), "Invalid parameter");
-
+  DEBUG1("calling SIMIX_communication_get_remains(%p)", task->simdata->comm);
   return SIMIX_communication_get_remains(task->simdata->comm);
 }
 
+/** \ingroup m_task_management
+ * \brief Return 1 if communication task is limited by latency, 0 otherwise
+ *
+ */
+int MSG_task_is_latency_bounded(m_task_t task)
+{
+         xbt_assert0((task != NULL)
+                     && (task->simdata != NULL), "Invalid parameter");
+       DEBUG1("calling SIMIX_communication_is_latency_bounded(%p)", task->simdata->comm);
+       return SIMIX_communication_is_latency_bounded(task->simdata->comm);
+}
+
 /** \ingroup m_task_management
  * \brief Returns the size of the data attached to a task #m_task_t.
  *
index 7386751..ce3ba8a 100644 (file)
@@ -374,6 +374,12 @@ XBT_INLINE double SIMIX_action_get_remains(smx_action_t action)
   return surf_workstation_model->get_remains(action->surf_action);
 }
 
+XBT_INLINE int SIMIX_action_is_latency_bounded(smx_action_t action)
+{
+  xbt_assert0((action != NULL), "Invalid parameter");
+  return surf_workstation_model->get_latency_limited(action->surf_action);
+}
+
 smx_action_t SIMIX_action_parallel_execute(char *name, int host_nb,
                                            smx_host_t * host_list,
                                            double *computation_amount,
index fb73403..d0e9d70 100644 (file)
@@ -11,6 +11,7 @@
 
 /* Pimple to get an histogram of message sizes in the simulation */
 xbt_dict_t msg_sizes = NULL;
+xbt_dict_t latency_limited_dict = NULL;
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_network, simix,
                                 "Logging specific to SIMIX (network)");
@@ -160,6 +161,13 @@ smx_comm_t SIMIX_communication_new(smx_comm_type_t type)
 void SIMIX_communication_destroy(smx_comm_t comm)
 {
   VERB2("Destroy communication %p; refcount initially %d",comm,comm->refcount);
+
+  //save is latency limited flag to use afterwards
+  if (latency_limited_dict == NULL)
+         latency_limited_dict = xbt_dict_new();
+  DEBUG2("adding key %p with latency limited value %d to the dict", comm, SIMIX_action_is_latency_bounded(comm->act));
+  xbt_dicti_set(latency_limited_dict, comm, SIMIX_action_is_latency_bounded(comm->act));
+
   comm->refcount--;
   if(comm->refcount > 0)
     return;
@@ -184,6 +192,8 @@ void SIMIX_communication_destroy(smx_comm_t comm)
       comm->dst_timeout = NULL;
     }
 
+
+
   xbt_free(comm);
 }
 
@@ -248,7 +258,7 @@ static XBT_INLINE void SIMIX_communication_cleanup(smx_comm_t comm)
   if (!SIMIX_host_get_state(SIMIX_host_self())){
     if(comm->rdv)
       SIMIX_rdv_remove(comm->rdv, comm);
-    SIMIX_communication_destroy(comm);
+         SIMIX_communication_destroy(comm);
     THROW0(host_error, 0, "Host failed");
   } else if (SIMIX_action_get_state(comm->act) == SURF_ACTION_FAILED){
     SIMIX_communication_destroy(comm);
@@ -343,9 +353,32 @@ XBT_INLINE void SIMIX_communication_cancel(smx_comm_t comm)
  */
 XBT_INLINE double SIMIX_communication_get_remains(smx_comm_t comm)
 {
+  DEBUG1("calling SIMIX_action_get_remains(%p)", comm->act);
   return SIMIX_action_get_remains(comm->act);
 }  
 
+/**
+ *  \brief verify if communication is latency bounded
+ *  \param comm The communication
+ */
+XBT_INLINE int SIMIX_communication_is_latency_bounded(smx_comm_t comm)
+{
+  //try to find comm on the list of finished flows
+  uintptr_t key = 0;
+  uintptr_t data = 0;
+  xbt_dict_cursor_t cursor;
+  xbt_dict_foreach(latency_limited_dict,cursor,key,data) {
+    DEBUG2("comparing key=%p with comm=%p", key, comm);
+       if(comm == key){
+               DEBUG2("key %p found, return value latency limited value %d", key, data);
+               return (int)data;
+       }
+  }
+
+  DEBUG1("calling SIMIX_action_is_latency_bounded(%p)", comm->act);
+  return SIMIX_action_is_latency_bounded(comm->act);
+}
+
 /******************************************************************************/
 /*                    SIMIX_network_copy_data callbacks                       */
 /******************************************************************************/
index 7ff053c..7f06cf7 100644 (file)
@@ -22,13 +22,17 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_network_gtnets_interface, surf_network_gtne
 
 
 // initialize the GTNetS interface and environment
-int gtnets_initialize(){
-
+int gtnets_initialize(int wsize){
   DEBUG0("Using logging.");
-
   xbt_assert0(!gtnets_sim, "gtnets already initialized");
 
-  gtnets_sim = new GTSim();
+  if(wsize > 0){
+       INFO1("TCP window maximum size : %d", wsize);
+       gtnets_sim = new GTSim(wsize);
+  }else{
+       gtnets_sim = new GTSim(wsize);
+  }
+
   return 0;
 }
 
@@ -89,7 +93,7 @@ double gtnets_get_time_to_next_flow_completion(){
 }
 
 // run until a flow completes (returns that flow's metadata)
-int gtnets_run_until_next_flow_completion(void ***metadata, int *number_of_flows){
+double gtnets_run_until_next_flow_completion(void ***metadata, int *number_of_flows){
   ofstream file;
   streambuf* sbuf;
   double value;
@@ -109,7 +113,7 @@ int gtnets_run_until_next_flow_completion(void ***metadata, int *number_of_flows
          cout.rdbuf(sbuf);
          file.close();
   }
-  return value;
+  return (double) value;
 }
 
 // get the total received in bytes using the TCPServer object totRx field
index 10a358c..9b5bbd8 100644 (file)
 extern "C" {
 #endif
 
-  int gtnets_initialize();
+  int gtnets_initialize(int wsize);
   int gtnets_add_link(int id, double bandwidth, double latency);
   int gtnets_add_route(int src, int dst, int *links, int nlink);
   int gtnets_add_router(int id);
   int gtnets_add_onehop_route(int src, int dst, int link);
   int gtnets_create_flow(int src, int dst, long datasize, void *metadata);
   double gtnets_get_time_to_next_flow_completion();
-  int gtnets_run_until_next_flow_completion(void ***metadata,
+  double gtnets_run_until_next_flow_completion(void ***metadata,
                                             int *number_of_flows);
   double gtnets_get_flow_rx(void *metadata);
 
index e7a3089..a2955fe 100644 (file)
@@ -28,6 +28,76 @@ static int meta_flg = 0;
 
 void static tcp_sent_callback(void* action, double completion_time);
 
+
+// Constructor.
+// TODO: check the default values.
+GTSim::GTSim(int WindowSize){
+  int wsize = WindowSize;
+  is_topology_ = 0;
+  nflow_ = 0;
+  jitter_ = 0;
+  jitter_seed_ = 10;
+
+  // EXTRACTED FROM GTNETS SOURCE CODE COMMENTS
+  //  REDQueue::REDQueue(
+  //     DCount_t in_w_q, Count_t in_min_th, Count_t in_max_th,
+  //     Count_t in_limit, DCount_t in_max_p, Count_t in_mean_pktsize) : iface(nil)
+  // Set default values.
+  //Doc:Desc This constructor the critical RED parameters and builds a
+  //Doc:Desc correspoding RED queue
+  //Doc:Arg1 weight of the queue
+  //Doc:Arg2 minimum threshold
+  //Doc:Arg3 maximum threshold
+  //Doc:Arg4 Limit/max size for the queue
+  //Doc:Arg5 maximum value for mark/drop probability
+  //Doc:Arg6 Average packet size
+
+  //Default Parameters
+  //REDQueue *default_red_queue_ = new REDQueue(0.002, 2500, 7500, 30000, 0.10, 500);
+  //Same as above
+  //REDQueue *default_red_queue_ = new REDQueue();
+
+  //See for details of how those values are calucated below
+  //[1] Sally Floyd and Van Jacobson, "Random Early Detection Gateways with Congestion Avoidance",
+  //    IEEE/ACM Transactions on Networking, vol. 1, n. 4, august 1993.
+  //
+  //[2] Kostas Pentikousis, "Active Queue Management", ACM Crossroads, vol. 7, n. 5,
+  //    mid-summer 2001
+  //
+  //[3] Stefann De Cnodder, Omar Ecoumi, Kenny Paulwels, "RED behavior with different packet sizes",
+  //    5th IEEE Symposium on Computers and Communication, (ISCC 2000)
+  //
+  //[4] http://www.opalsoft.net/qos/DS-26.htm
+  //
+  //short explanation:
+  // q_weight = fixed to 0.002 in most literature
+  // min_bytes = max / 3 = 16,666,666
+  // max_bytes = mean_bw * max_tolerable_latency, set to 1e8 * 0.5 = 50,000,000
+  // limit_bytes = 8 * max = 400,000,000
+  // prob = follow most literature 0.02
+  // avgpkt = fixed to the same TCP segment size, 1000 Bytes
+  //
+  // burst = (2*(min+max))/(3*avgpkt) ***DON'T USED BY GTNetS***
+  REDQueue *default_red_queue_ = new REDQueue(0.002, 16666666, 50000000, 400000000, 0.02, 1000);
+
+  Queue::Default(*default_red_queue_);
+  delete default_red_queue_;
+
+  cout << "Set default window size to " << wsize << endl;
+  TCP::DefaultAdvWin(wsize);
+  TCP::DefaultSegSize(1000);
+  TCP::DefaultTxBuffer(128000);
+  TCP::DefaultRxBuffer(128000);
+
+  sim_ = new Simulator();
+  sim_->verbose=false;
+  topo_ = new GTNETS_Topology();
+
+  // Manual routing
+  rm_ = new RoutingManual();
+  Routing::SetRouting(rm_);
+}
+
 // Constructor.
 // TODO: check the default values.
 GTSim::GTSim(){
index 9a88c74..8f81453 100644 (file)
@@ -35,6 +35,7 @@ class GTSim {
 
 public:
   GTSim();
+  GTSim(int WindowSize);
   ~GTSim();
 public:
   int add_link(int id, double bandwidth, double latency);
index 027fca4..c35b519 100644 (file)
@@ -723,6 +723,12 @@ XBT_INLINE lmm_constraint_t lmm_get_next_active_constraint(lmm_system_t sys,
   return xbt_swag_getNext(cnst, (sys->active_constraint_set).offset);
 }
 
+XBT_INLINE int lmm_is_variable_limited_by_latency(lmm_variable_t var)
+{
+  return (double_equals(var->bound, var->value));
+}
+
+
 /** \brief Update the constraint set propagating recursively to
  *  other constraints so the system should not be entirely computed.
  *
index 0acac74..867736f 100644 (file)
@@ -20,6 +20,7 @@ double sg_bandwidth_factor = 1.0;  /* default value; can be set by model or from
 double sg_weight_S_parameter = 0.0;/* default value; can be set by model or from command line */
 
 double sg_tcp_gamma = 0.0;
+int sg_network_fullduplex = 1;
 
 
 /******************************************************************************/
@@ -257,6 +258,11 @@ static void net_action_recycle(surf_action_t action)
   return;
 }
 
+static int net_get_link_latency(surf_action_t action)
+{
+  return action->latency_limited;
+}
+
 static double net_action_get_remains(surf_action_t action)
 {
   return action->remains;
@@ -277,6 +283,11 @@ static double net_share_resources(double now)
 #define VARIABLE(action) (*((lmm_variable_t*)(((char *) (action)) + xbt_swag_offset(s_action, variable)  )))
 
   xbt_swag_foreach(action, running_actions) {
+       if( lmm_is_variable_limited_by_latency(action->variable) ){
+               (action->generic_action).latency_limited = 1;
+       }else{
+               (action->generic_action).latency_limited = 0;
+       }
     if (action->latency > 0) {
       if (min < 0)
         min = action->latency;
@@ -400,11 +411,18 @@ static void net_update_resource_state(void *id,
       if (action->rate < 0)
         lmm_update_variable_bound(network_maxmin_system, action->variable,
                                   sg_tcp_gamma / (2.0 * action->lat_current));
-      else
+      else{
         lmm_update_variable_bound(network_maxmin_system, action->variable,
                                   min(action->rate,
                                       sg_tcp_gamma / (2.0 *
                                                       action->lat_current)));
+
+        if(action->rate < sg_tcp_gamma / (2.0 * action->lat_current) ){
+               INFO0("Flow is limited BYBANDWIDTH");
+        }else{
+               INFO1("Flow is limited BYLATENCY, latency of flow is %f",action->lat_current);
+        }
+      }
       if (!(action->suspended))
         lmm_update_variable_weight(network_maxmin_system, action->variable,
                                    action->weight);
@@ -442,6 +460,7 @@ static void net_update_resource_state(void *id,
   return;
 }
 
+
 static surf_action_t net_communicate(const char *src_name, const char *dst_name,
                                  int src, int dst, double size, double rate)
 {
@@ -454,6 +473,13 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name,
      Add a link_CM02_t *link and a int link_nb to network_card_CM02_t. It will represent local links for this node
      Use the cluster_id for ->id */
   xbt_dynar_t route = used_routing->get_route(src, dst);
+  xbt_dynar_t back_route = NULL;
+  int constraints_per_variable = 0;
+
+  if( sg_network_fullduplex == 1){
+         back_route = used_routing->get_route(dst, src);
+  }
+
   /* LARGE PLATFORMS HACK:
      total_route_size = route_size + src->link_nb + dst->nb */
 
@@ -473,6 +499,7 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name,
   action =
     surf_action_new(sizeof(s_surf_action_network_CM02_t), size,
                     surf_network_model, failed);
+  (action->generic_action).latency_limited = 0;
 
   xbt_swag_insert(action, action->generic_action.state_set);
   action->rate = rate;
@@ -499,14 +526,18 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name,
 
   /* LARGE PLATFORMS HACK:
      lmm_variable_new(..., total_route_size) */
+  if(back_route != NULL){
+         constraints_per_variable = xbt_dynar_length(route)+xbt_dynar_length(back_route);
+  }else{
+         constraints_per_variable = xbt_dynar_length(route);
+  }
+
   if (action->latency > 0)
     action->variable =
-      lmm_variable_new(network_maxmin_system, action, 0.0, -1.0,
-                       xbt_dynar_length(route));
+      lmm_variable_new(network_maxmin_system, action, 0.0, -1.0,constraints_per_variable);
   else
     action->variable =
-      lmm_variable_new(network_maxmin_system, action, 1.0, -1.0,
-                       xbt_dynar_length(route));
+      lmm_variable_new(network_maxmin_system, action, 1.0, -1.0,constraints_per_variable);
 
   if (action->rate < 0) {
     if (action->lat_current > 0)
@@ -530,7 +561,14 @@ static surf_action_t net_communicate(const char *src_name, const char *dst_name,
     lmm_expand(network_maxmin_system, link->lmm_resource.constraint,
                action->variable, 1.0);
   }
-  /* LARGE PLATFORMS HACK:
+
+  if( sg_network_fullduplex == 1){
+         DEBUG1("Fullduplex active adding backward flow using 5%c", '%');
+         xbt_dynar_foreach(back_route, i, link) {
+                 lmm_expand(network_maxmin_system, link->lmm_resource.constraint,
+               action->variable, .05);
+         }
+  }  /* LARGE PLATFORMS HACK:
      expand also with src->link and dst->link */
 
   /* saving the src and dst of this communication */
@@ -548,11 +586,6 @@ static double net_get_link_bandwidth(const void *link)
   return lmm->power.peak * lmm->power.scale;
 }
 
-static double net_get_link_latency(const void *link)
-{
-  return ((link_CM02_t) link)->lat_current;
-}
-
 static int net_link_shared(const void *link)
 {
   return lmm_constraint_is_shared(((surf_resource_lmm_t) link)->constraint);
@@ -638,6 +671,7 @@ static void surf_network_model_init_internal(void)
   surf_network_model->action_cancel = net_action_cancel;
   surf_network_model->action_recycle = net_action_recycle;
   surf_network_model->get_remains = net_action_get_remains;
+  surf_network_model->get_latency_limited = net_get_link_latency;
 
   surf_network_model->model_private->resource_used = net_resource_used;
   surf_network_model->model_private->share_resources = net_share_resources;
@@ -655,7 +689,6 @@ static void surf_network_model_init_internal(void)
   surf_network_model->extension.network.communicate = net_communicate;
   surf_network_model->extension.network.get_link_bandwidth =
     net_get_link_bandwidth;
-  surf_network_model->extension.network.get_link_latency = net_get_link_latency;
   surf_network_model->extension.network.link_shared = net_link_shared;
   surf_network_model->extension.network.create_resource = network_create_resource;
   surf_network_model->extension.network.add_traces = net_add_traces;
index 11e6089..feaa165 100644 (file)
@@ -21,13 +21,43 @@ static void link_new(char *name, double bw, double lat, xbt_dict_t props)
 {
   static int link_count = -1;
   network_link_GTNETS_t gtnets_link;
+  int tmp_idsrc=-1;
+  int tmp_iddst=-1;
+  char *name_friend;
+  char *name_normal;
 
   if (xbt_dict_get_or_null(surf_network_model->resource_set, name)) {
     return;
   }
 
+  DEBUG1("Scanning link name %s", name);
+  sscanf(name, "%d_%d", &tmp_idsrc, &tmp_iddst);
+  DEBUG2("Link name split into %d and %d", tmp_idsrc, tmp_iddst);
+
+  xbt_assert0( (tmp_idsrc!=-1)&&(tmp_idsrc!=-1), "You need to respect fullduplex convention x_y for xml link id.");
+
+  name_normal = (char *)calloc(strlen(name), sizeof(char));
+  name_friend = (char *)calloc(strlen(name), sizeof(char));
+
+  if(tmp_idsrc < tmp_iddst){
+         sprintf(name_normal, "%d_%d", tmp_idsrc, tmp_iddst);
+         sprintf(name_friend, "%d_%d", tmp_iddst, tmp_idsrc);
+  }else{
+         sprintf(name_normal, "%d_%d", tmp_iddst, tmp_idsrc);
+         sprintf(name_friend, "%d_%d", tmp_idsrc, tmp_iddst);
+  }
+
+  gtnets_link = xbt_dict_get_or_null(surf_network_model->resource_set, name_normal);
+
+  if (gtnets_link) {
+    DEBUG3("Link already added as friend normal=%s friend=%s (#%d)", name_normal, name_friend, ((network_link_GTNETS_t)gtnets_link)->id );
+    return;
+  }
+
   link_count++;
 
+  DEBUG4("Adding new link, linkid %d, name %s, latency %g, bandwidth %g", link_count, name, lat, bw);
+
   if (gtnets_add_link(link_count, bw, lat)) {
     xbt_assert0(0, "Cannot create GTNetS link");
   }
@@ -42,7 +72,10 @@ static void link_new(char *name, double bw, double lat, xbt_dict_t props)
 #ifdef HAVE_TRACING
   TRACE_surf_link_declaration (name, bw, lat);
 #endif
-  xbt_dict_set(surf_network_model->resource_set, name, gtnets_link,
+  xbt_dict_set(surf_network_model->resource_set, name_normal, gtnets_link,
+               surf_resource_free);
+
+  xbt_dict_set(surf_network_model->resource_set, name_friend, gtnets_link,
                surf_resource_free);
 }
 
@@ -122,6 +155,7 @@ static void create_gtnets_topology()
 
   xbt_dict_foreach(onelink_routes, cursor, key, data){
        s_onelink_t link = (s_onelink_t) data;
+
        DEBUG3("Link (#%d), src (#%d), dst (#%d)", ((network_link_GTNETS_t)(link->link_ptr))->id , link->src_id, link->dst_id);
     DEBUG0("Calling one link route");
     if(used_routing->is_router(link->src_id)){
@@ -337,11 +371,6 @@ static int action_is_suspended(surf_action_t action)
 
 static void finalize(void)
 {
-  xbt_dict_free(&surf_network_model->resource_set);
-
-  surf_model_exit(surf_network_model);
-  surf_network_model = NULL;
-
   gtnets_finalize();
 }
 
@@ -371,13 +400,17 @@ static void surf_network_model_init_internal(void)
   surf_network_model->extension.network.communicate = communicate;
 
   /* Added the initialization for GTNetS interface */
-  if (gtnets_initialize()) {
+  if (gtnets_initialize(sg_tcp_gamma)) {
     xbt_assert0(0, "Impossible to initialize GTNetS interface");
   }
 
   routing_model_create(sizeof(network_link_GTNETS_t), NULL);
 }
 
+static int get_latency_limited(surf_action_t action){
+       return 0;
+}
+
 #ifdef HAVE_GTNETS
 void surf_network_model_init_GTNETS(const char *filename)
 {
@@ -387,6 +420,8 @@ void surf_network_model_init_GTNETS(const char *filename)
   define_callbacks(filename);
   xbt_dynar_push(model_list, &surf_network_model);
 
+  surf_network_model->get_latency_limited = get_latency_limited;
+
   if(sg_gtnets_jitter > 0.0){
          gtnets_set_jitter(sg_gtnets_jitter);
          gtnets_set_jitter_seed(sg_gtnets_jitter_seed);
index dd9a6f2..db5364e 100644 (file)
@@ -27,6 +27,7 @@ typedef struct surf_action_network_CM02 {
   double weight;
   lmm_variable_t variable;
   double rate;
+  int latency_limited;
   int suspended;
 
   int src;  /* saving source id for tracing */
index 62eaa26..8b20806 100644 (file)
@@ -152,6 +152,11 @@ static void _surf_cfg_cb_model_check(const char *name, int pos) {
   xbt_dict_preinit();
 }
 
+static void _surf_cfg_cb__surf_network_fullduplex(const char *name, int pos)
+{
+       sg_network_fullduplex = xbt_cfg_get_int(_surf_cfg_set, name);
+}
+
 #ifdef HAVE_GTNETS
 static void _surf_cfg_cb__gtnets_jitter(const char *name, int pos){
        sg_gtnets_jitter = xbt_cfg_get_double(_surf_cfg_set, name);
@@ -260,6 +265,11 @@ void surf_config_init(int *argc, char **argv)
                      "Activate the model-checking of the \"simulated\" system (EXPERIMENTAL -- msg only for now)",
                      xbt_cfgelm_int, &default_value_int, 0, 1, _surf_cfg_cb_model_check, NULL);
 
+    default_value_int = 0;
+    xbt_cfg_register(&_surf_cfg_set, "fullduplex",
+                    "Update the constraint set propagating recursively to others constraints",
+                    xbt_cfgelm_int, &default_value_int, 0, 1, _surf_cfg_cb__surf_network_fullduplex, NULL);
+
 #ifdef HAVE_GTNETS
     xbt_cfg_register(&_surf_cfg_set, "gtnets_jitter",
                      "Double value to oscillate the link latency, uniformly in random interval [-latency*gtnets_jitter,latency*gtnets_jitter)", xbt_cfgelm_double,
index c64d330..61a374b 100644 (file)
@@ -3,7 +3,6 @@
 
 /* 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. */
-
 #ifndef _SURF_SURF_PRIVATE_H
 #define _SURF_SURF_PRIVATE_H
 
@@ -23,6 +22,7 @@ extern double sg_latency_factor;
 extern double sg_bandwidth_factor;
 extern double sg_weight_S_parameter;
 extern int sg_maxmin_selective_update;
+extern int sg_network_fullduplex;
 #ifdef HAVE_GTNETS
   extern double sg_gtnets_jitter;
   extern int sg_gtnets_jitter_seed;
index 1fddb31..4363239 100644 (file)
@@ -184,6 +184,14 @@ static void ws_action_set_priority(surf_action_t action, double priority)
     DIE_IMPOSSIBLE;
 }
 
+static int ws_get_latency_limited(surf_action_t action)
+{
+  if (action->model_type == surf_network_model)
+    return surf_network_model->get_latency_limited(action);
+  INFO0("You tried to ask if a non network action is limited by latency, aborting...");
+  DIE_IMPOSSIBLE;
+}
+
 static double ws_action_get_remains(surf_action_t action)
 {
   if (action->model_type == surf_network_model)
@@ -291,6 +299,7 @@ static void surf_workstation_model_init_internal(void)
   surf_workstation_model->set_max_duration = ws_action_set_max_duration;
   surf_workstation_model->set_priority = ws_action_set_priority;
   surf_workstation_model->get_remains = ws_action_get_remains;
+  surf_workstation_model->get_latency_limited = ws_get_latency_limited;
 
   surf_workstation_model->extension.workstation.execute = ws_execute;
   surf_workstation_model->extension.workstation.sleep = ws_action_sleep;