Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
removing ApplicationHandler ruby Class, keeping only C Handler to create Process
authorcoldpeace <coldpeace@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Wed, 3 Mar 2010 17:15:01 +0000 (17:15 +0000)
committercoldpeace <coldpeace@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Wed, 3 Mar 2010 17:15:01 +0000 (17:15 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7179 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/bindings/ruby/MasterSlave.rb
src/bindings/ruby/rb_application_handler.c
src/bindings/ruby/rb_msg_process.c
src/bindings/ruby/simgrid.rb
src/bindings/ruby/simgrid_ruby.c
src/bindings/ruby/small_platform 2.xml [deleted file]
src/bindings/ruby/small_platform.xml [deleted file]

index e945b7a..5d047ee 100644 (file)
@@ -78,7 +78,7 @@ if (ARGV.length == 2)
        MSG.deployApplication(ARGV[1])
 else 
        MSG.createEnvironment("platform.xml")
-       MSG.deployApplication("deploy.xml")
+       MSG.deployApplication("deploy2.xml")
   #Thread.list.each {|t| p t}
 end
 
index 1514d9d..42fa57d 100644 (file)
  */
 #include "bindings/ruby_bindings.h"
 #include "surf/surfxml_parse.h"
+#include "msg/private.h" /* s_simdata_process_t */
+
+// XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ruby,bindings,"Ruby Bindings");
+
+// Used to instanciate the Process
+
+static  VALUE args;
+static  VALUE prop;
+static  VALUE function_name;
+static  VALUE host_name; 
+
+
+
+static VALUE rb_process_instance(VALUE fct_name,VALUE arguments,VALUE properties) {
+  ruby_init();
+  ruby_init_loadpath();
+  char * p_className = RSTRING(fct_name)->ptr; // name of process is the one of the class
+  return rb_funcall(rb_const_get(rb_cObject, rb_intern(p_className)),rb_intern("new"),3,fct_name,arguments,properties);
+}
+
+static void rb_process_create_with_args(VALUE fct_name,VALUE arguments,VALUE properties,VALUE ht_name) {
+  
+  VALUE ruby_process = rb_process_instance(fct_name,arguments,properties);
+  m_process_t process; // Native Process to Create
+  const char * name ; // Name of C Native Processs
+
+  if(!fct_name)
+    rb_raise(rb_eRuntimeError,"Internal error: Process name cannot be NULL");
+
+  // Allocate the data for the simulation
+  process = xbt_new0(s_m_process_t,1);
+  process->simdata = xbt_new0(s_simdata_process_t,1);
+  // Do we Really Need to Create Ruby Process Instance , >> process is already a Ruby Process !! So..Keep on ;)
+  // Bind The Ruby Process instance to The Native Process
+  rb_process_bind(ruby_process,process);
+  name = RSTRING(fct_name)->ptr;
+  process->name = xbt_strdup(name);
+  // Host
+  m_host_t host = MSG_get_host_by_name(RSTRING(ht_name)->ptr);
+  process->simdata->m_host = host;
+  
+  //Data_Get_Struct(host,s_m_host_t,process->simdata->m_host);
+
+  if(!(process->simdata->m_host)) { // Not Binded
+    free(process->simdata);
+    free(process->data);
+    free(process);
+    rb_raise(rb_eRuntimeError,"Host not bound while creating native process");
+  }
+  process->simdata->PID = msg_global->PID++; //  msg_global ??
+
+/*
+  DEBUG7("fill in process %s/%s (pid=%d) %p (sd=%p , host=%p, host->sd=%p)",
+      process->name , process->simdata->m_host->name,process->simdata->PID,
+      process,process->simdata, process->simdata->m_host,
+      process->simdata->m_host->simdata);
+*/
+
+printf("fill in process %s/%s (pid=%d) %p (sd=%p , host=%p, host->sd=%p)\n",
+      process->name , process->simdata->m_host->name,process->simdata->PID,
+      process,process->simdata, process->simdata->m_host,
+      process->simdata->m_host->simdata);
+
+  /* FIXME: that's mainly for debugging. We could only allocate this if XBT_LOG_ISENABLED(ruby,debug) is true since I guess this leaks */
+  char **argv=xbt_new(char*,2);
+  argv[0] = bprintf("%s@%s",process->name,process->simdata->m_host->simdata->smx_host->name);
+  argv[1] = NULL;
+  process->simdata->s_process =
+      SIMIX_process_create(process->name,
+          (xbt_main_func_t)ruby_process,
+          (void *) process,
+          process->simdata->m_host->simdata->smx_host->name,
+          1,argv,NULL);
+
+ // DEBUG1("context created (s_process=%p)",process->simdata->s_process);
+ printf("context created (s_process=%p)\n",process->simdata->s_process);
+
+  if (SIMIX_process_self()) { // SomeOne Created Me !!
+    process->simdata->PPID = MSG_process_get_PID(SIMIX_process_self()->data);
+  } else {
+    process->simdata->PPID = -1;
+  }
+  process->simdata->last_errno = MSG_OK;
+  // let's Add the Process to the list of the Simulation's Processes
+  xbt_fifo_unshift(msg_global->process_list,process);
+}
+
+
 
-static VALUE application_handler_class; // The Current Instance of ApplicationHandler Class
 
 void rb_application_handler_on_start_document(void) {
-  application_handler_class = rb_funcall3(rb_const_get(rb_cObject, rb_intern("ApplicationHandler")),  rb_intern("new"), 0, 0);
+  
+   args = rb_ary_new();  // Max lenght = 16 ?!
+   prop = rb_ary_new();
 }
 
 void rb_application_handler_on_end_document(void) {
-  application_handler_class = Qnil;
+  //application_handler_class = Qnil;
+  args = Qnil;
+  prop = Qnil;
+  function_name = Qnil;
+  host_name = Qnil;
+  
 }
 
 void rb_application_handler_on_begin_process(void) {
-  VALUE hostName = rb_str_new2(A_surfxml_process_host);
-  VALUE function = rb_str_new2(A_surfxml_process_function);
-  rb_funcall(application_handler_class,rb_intern("onBeginProcess"),2,hostName,function);
+  
+  host_name = rb_str_new2(A_surfxml_process_host);;
+  function_name = rb_str_new2(A_surfxml_process_function);
+  
 }
 
 void rb_application_handler_on_process_arg(void) {
+  
   VALUE arg = rb_str_new2(A_surfxml_argument_value);
-  rb_funcall(application_handler_class,rb_intern("onProcessArg"),1,arg);
+  rb_ary_push(args,arg);
 }
 
 void rb_application_handler_on_property(void) {
   VALUE id = rb_str_new2(A_surfxml_prop_id);
   VALUE val =  rb_str_new2(A_surfxml_prop_value);
-  rb_funcall(application_handler_class,rb_intern("onProperty"),2,id,val);
+  int i_id = NUM2INT (id);
+  rb_ary_store(prop,i_id,val);
+
 }
 
 
 void rb_application_handler_on_end_process(void) {
-  rb_funcall(application_handler_class,rb_intern("onEndProcess"),0);
+
+  rb_process_create_with_args(function_name,args,prop,host_name);
+    
 }
+
+
index b0bd1ee..b4fa038 100644 (file)
@@ -88,65 +88,6 @@ void rb_process_bind(VALUE ruby_process,m_process_t process) {
 }
 
 
-// processCreate
-// FIXME: don't mess with MSG internals here, use MSG_process_create_with_arguments()
-
-void rb_process_create(VALUE class,VALUE ruby_process,VALUE host) {
-  VALUE rbName;      // Name of ruby Process instance
-  m_process_t process; // Native Process to Create
-  const char * name ; // Name of C Native Process
-  rbName = rb_process_getName(ruby_process);
-
-  if(!rbName)
-    rb_raise(rb_eRuntimeError,"Internal error: Process name cannot be NULL");
-
-  // Allocate the data for the simulation
-  process = xbt_new0(s_m_process_t,1);
-  process->simdata = xbt_new0(s_simdata_process_t,1);
-  // Do we Really Need to Create Ruby Process Instance , >> process is already a Ruby Process !! So..Keep on ;)
-  // Bind The Ruby Process instance to The Native Process
-  rb_process_bind(ruby_process,process);
-  name = RSTRING(rbName)->ptr;
-  process->name = xbt_strdup(name);
-  Data_Get_Struct(host,s_m_host_t,process->simdata->m_host);
-
-  if(!(process->simdata->m_host)) { // Not Binded
-    free(process->simdata);
-    free(process->data);
-    free(process);
-    rb_raise(rb_eRuntimeError,"Host not bound while creating native process");
-  }
-  process->simdata->PID = msg_global->PID++; //  msg_global ??
-
-  DEBUG7("fill in process %s/%s (pid=%d) %p (sd=%p , host=%p, host->sd=%p)",
-      process->name , process->simdata->m_host->name,process->simdata->PID,
-      process,process->simdata, process->simdata->m_host,
-      process->simdata->m_host->simdata);
-
-  /* FIXME: that's mainly for debugging. We could only allocate this if XBT_LOG_ISENABLED(ruby,debug) is true since I guess this leaks */
-  char **argv=xbt_new(char*,2);
-  argv[0] = bprintf("%s@%s",process->name,process->simdata->m_host->simdata->smx_host->name);
-  argv[1] = NULL;
-  process->simdata->s_process =
-      SIMIX_process_create(process->name,
-          (xbt_main_func_t)ruby_process,
-          (void *) process,
-          process->simdata->m_host->simdata->smx_host->name,
-          1,argv,NULL);
-
-  DEBUG1("context created (s_process=%p)",process->simdata->s_process);
-
-  if (SIMIX_process_self()) { // SomeOne Created Me !!
-    process->simdata->PPID = MSG_process_get_PID(SIMIX_process_self()->data);
-  } else {
-    process->simdata->PPID = -1;
-  }
-  process->simdata->last_errno = MSG_OK;
-  // let's Add the Process to the list of the Simulation's Processes
-  xbt_fifo_unshift(msg_global->process_list,process);
-}
-
-
 // Process Management
 void rb_process_suspend(VALUE class,VALUE ruby_process) {
 
index 2cfeacf..5c96cdb 100644 (file)
@@ -52,83 +52,31 @@ class MSG::Process < Thread
   @@nextProcessId = 0
 
 # Attributes
-  attr_reader :bind, :id            # Read only
-  attr_accessor :name, :properties, :pargs  # R/W
+  attr_reader :bind, :id ,:name           # Read only
+  attr_accessor :properties, :pargs  # R/W
   
-# Initialize : Used from ApplicationHandler to fill it in
-  def initialize(*args)
-    # FIXME: use only one variante (the one with 3 args) and kill the others
+
+    def initialize(*args)
+      super(){
+       
+     raise "Bad Number Of arguments to create a a Ruby Process (name,args,prop) " if args.size < 3
+     
     @schedBegin = Semaphore.new(0)
     @schedEnd = Semaphore.new(0)    
-    @properties = Hash.new()
-    @id = @@nextProcessId++
+    #@properties = Hash.new()
+    @id = @@nextProcessId
+    @@nextProcessId += 1
+    @name = args[0]
+    @pargs = args[1]
+    @properties = args[2]
     
-    argc = args.size
-
-    if argc == 0 # Default initializer
-      super() {
-        @id = 0
-        @bind = 0
-        @name = ""
-        @pargs = Array.new()
-        start()
-        MSG::debug "Initializer without any argument"
-      }
-       
-    # 2 arguments: (HostName,Name) Or (Host , Name)
-    elsif argc == 2   
-      super(){
-        MSG::debug "Initilize with 2 args"
-        type = args[0].type()
-        if ( type.to_s == "String")
-          host = Host.getByName(args[0])
-        elsif ( type.to_s == "MSG::Host")
-          host = args[0]
-        else 
-          raise "first argument of type "+args[0].type().to_s+", but expecting either String or MSG::Host"
-        end
-        if $DEBUG
-          puts host
-        end
-        raise "Process name cannot be null" if args[1].empty?
-        @name = args[1] 
-        if $DEBUG
-          puts @name
-        end
-        @pargs = Array.new()    # No Args[] Passed in Arguments
-        start()
-        createProcess(self,host)
+     start()
+      
       }
-       
-    # 3 arguments: (hostName,Name,args[]) or (Host,Name,args[])
-    elsif argc == 3  
-      super(){
-       MSG::debug "Initilize with 3 args"
-        type = args[0].type()
-        if ( type.to_s == "String")
-          host = Host.getByName(args[0])
-        elsif ( type.to_s == "MSG::Host")
-          host = args[0]
-        else 
-          raise "first argument of type "+args[0].type().to_s+", but expecting either String or MSG::Host"
-        end
-        if $DEBUG
-          puts host
-        end
       
-        raise "Process name cannot be null" if args[1].empty?
-        @name = args[1]
-        type = args[2].type()
-        raise "Third argument should be an Array" if type != "Array"
-        @pargs = args[3]
-        createProcess(self,host)  
-        
-          }
-  else 
-    raise "Bad number of argument: Expecting either 1, 2 or 3, but got "+argc.to_s
-  end
     end
-  
+    
+    
   # main
   def main(args) 
     # To be overriden by childs
@@ -145,31 +93,14 @@ class MSG::Process < Thread
     @schedEnd.release
   end
     
-  def processList() (KILLME?)
-    Thread.list.each {|t| p t}
-  end
-  
-  #Get Own ID (KILLME?)
-  def getID()
-    return @id
-  end
-  
-  #Get a Process ID (KILLME?)
-  def processID(process)
-    return process.id
-  end
-  
-  #Get Own Name (KILLME?)
-  def getName()
-    return @name
-  end
+
   
-  #Get Bind (KILLME?)
+  #Get Bind ( Used > Native to Ruby)
   def getBind()
     return @bind
   end
   
-  #Get Binds (KILLME?)
+  #Get Binds (Used > Ruby to Native)
   def setBind(bind)
     @bind = bind
   end
@@ -210,46 +141,6 @@ class MSG::Process < Thread
 # The Rest of Methods !!! To be Continued ...
 end
 
-#########################################################################
-# Class ApplicationHandler
-#########################################################################
-class ApplicationHandler
-  def initialize()
-    @hostName = nil
-    @function = nil
-  end
-  
-  def onBeginProcess(hostName,function)
-    @args = Array.new
-    @properties = Hash.new
-    
-    @hostName = hostName
-    @function = function
-      
-    MSG::debug("onBeginProcess("+hostName+","+function+")")
-  end
-
-  def onProperty(id,value)
-    @properties[id] = value
-  end
-  
-  def onProcessArg(arg)
-    @args.push(arg)
-  end
-
-  def onEndProcess()
-    # must be in C, called from a callback to the FlexML parser 
-    # newInstance must take args and hostname as argument to initialize everything, *and* bind it to C element
-    # Allows to mark all attributes of process (but properties) to read-only
-    process = MSG::rubyNewInstance(@function) 
-    process.pargs = @args
-    process.name = @function
-    host = MSG::Host.getByName(@hostName)
-    MSG::processCreate(process,host)
-    process.properties = @properties
-  end
-end
 #########################
 # Main chunck 
 #########################
index c02fd55..c8984e5 100644 (file)
@@ -16,7 +16,6 @@ VALUE rb_msg;
 VALUE rb_task;
 VALUE rb_host;
 
-
 //Init Msg  From Ruby
 static void msg_init(VALUE Class,VALUE args)
 {
@@ -99,7 +98,6 @@ static void msg_deployApplication(VALUE class,VALUE deploymentFile ) {
   surf_parse_reset_parser();
   surfxml_add_callback(STag_surfxml_process_cb_list,
       rb_application_handler_on_begin_process);
-
   surfxml_add_callback(ETag_surfxml_argument_cb_list,
       rb_application_handler_on_process_arg);
 
@@ -114,6 +112,7 @@ static void msg_deployApplication(VALUE class,VALUE deploymentFile ) {
   if(surf_parse())
     rb_raise(rb_eRuntimeError,"surf_parse() failed");
   surf_parse_close();
+  
   rb_application_handler_on_end_document();
 
   DEBUG1("Deploy Application(%s)...Done",dep_file);
@@ -176,7 +175,6 @@ void Init_simgrid_ruby() {
   rb_define_module_function(rb_msg,"rubyNewInstanceArgs",(rb_meth)msg_new_ruby_instance_with_args,2);
 
   // Associated Process Methods
-  rb_define_module_function(rb_msg,"processCreate",(rb_meth)rb_process_create,2);
   rb_define_method(rb_msg,"processSuspend",(rb_meth)rb_process_suspend,1);
   rb_define_method(rb_msg,"processResume",(rb_meth)rb_process_resume,1);
   rb_define_method(rb_msg,"processIsSuspend",(rb_meth)rb_process_isSuspended,1);
diff --git a/src/bindings/ruby/small_platform 2.xml b/src/bindings/ruby/small_platform 2.xml
deleted file mode 100644 (file)
index 3fa9afd..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version='1.0'?>
-<!DOCTYPE platform SYSTEM "simgrid.dtd">
-<platform version="2">
-  <!-- ljlkj -->
-  <host id="Tremblay" power="98095000"/>
-  <host id="Jupiter" power="76296000"/>
-  <host id="Fafard" power="76296000"/>
-  <host id="Ginette" power="48492000"/>
-  <host id="Bourassa" power="48492000"/>
-  <link id="6" bandwidth="41279125" latency="5.9904e-05"/>
-  <link id="11" bandwidth="252750" latency="0.00570455"/>
-  <link id="3" bandwidth="34285625" latency="0.000514433"/>
-  <link id="7" bandwidth="11618875" latency="0.00018998"/>
-  <link id="9" bandwidth="7209750" latency="0.001461517"/>
-  <link id="12" bandwidth="1792625" latency="0.007877863"/>
-  <link id="2" bandwidth="118682500" latency="0.000136931"/>
-  <link id="8" bandwidth="8158000" latency="0.000270544"/>
-  <link id="1" bandwidth="34285625" latency="0.000514433"/>
-  <link id="4" bandwidth="10099625" latency="0.00047978"/>
-  <link id="0" bandwidth="41279125" latency="5.9904e-05"/>
-  <link id="10" bandwidth="4679750" latency="0.000848712"/>
-  <link id="5" bandwidth="27946250" latency="0.000278066"/>
-  <link id="loopback" bandwidth="498000000" latency="0.000015" sharing_policy="FATPIPE"/>
-  <route src="Tremblay" dst="Tremblay"><link:ctn id="loopback"/></route>
-  <route src="Jupiter" dst="Jupiter"><link:ctn id="loopback"/></route>
-  <route src="Fafard" dst="Fafard"><link:ctn id="loopback"/></route>
-  <route src="Ginette" dst="Ginette"><link:ctn id="loopback"/></route>
-  <route src="Bourassa" dst="Bourassa"><link:ctn id="loopback"/></route>
-  <route src="Tremblay" dst="Jupiter">
-    <link:ctn id="9"/>
-  </route>
-  <route src="Tremblay" dst="Fafard">
-    <link:ctn id="4"/><link:ctn id="3"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="8"/>
-  </route>
-  <route src="Tremblay" dst="Ginette">
-    <link:ctn id="4"/><link:ctn id="3"/><link:ctn id="5"/>
-  </route>
-  <route src="Tremblay" dst="Bourassa">
-    <link:ctn id="4"/><link:ctn id="3"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="6"/><link:ctn id="7"/>
-  </route>
-  <route src="Jupiter" dst="Tremblay">
-    <link:ctn id="9"/>
-  </route>
-  <route src="Jupiter" dst="Fafard">
-    <link:ctn id="9"/><link:ctn id="4"/><link:ctn id="3"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="8"/>
-  </route>
-  <route src="Jupiter" dst="Ginette">
-    <link:ctn id="9"/><link:ctn id="4"/><link:ctn id="3"/><link:ctn id="5"/>
-  </route>
-  <route src="Jupiter" dst="Bourassa">
-    <link:ctn id="9"/><link:ctn id="4"/><link:ctn id="3"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="6"/><link:ctn id="7"/>
-  </route>
-  <route src="Fafard" dst="Tremblay">
-    <link:ctn id="8"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="3"/><link:ctn id="4"/>
-  </route>
-  <route src="Fafard" dst="Jupiter">
-    <link:ctn id="8"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="3"/><link:ctn id="4"/><link:ctn id="9"/>
-  </route>
-  <route src="Fafard" dst="Ginette">
-    <link:ctn id="8"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="5"/>
-  </route>
-  <route src="Fafard" dst="Bourassa">
-    <link:ctn id="8"/><link:ctn id="6"/><link:ctn id="7"/>
-  </route>
-  <route src="Ginette" dst="Tremblay">
-    <link:ctn id="5"/><link:ctn id="3"/><link:ctn id="4"/>
-  </route>
-  <route src="Ginette" dst="Jupiter">
-    <link:ctn id="5"/><link:ctn id="3"/><link:ctn id="4"/><link:ctn id="9"/>
-  </route>
-  <route src="Ginette" dst="Fafard">
-    <link:ctn id="5"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="8"/>
-  </route>
-  <route src="Ginette" dst="Bourassa">
-    <link:ctn id="5"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="6"/><link:ctn id="7"/>
-  </route>
-  <route src="Bourassa" dst="Tremblay">
-    <link:ctn id="7"/><link:ctn id="6"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="3"/><link:ctn id="4"/>
-  </route>
-  <route src="Bourassa" dst="Jupiter">
-    <link:ctn id="7"/><link:ctn id="6"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="3"/><link:ctn id="4"/><link:ctn id="9"/>
-  </route>
-  <route src="Bourassa" dst="Fafard">
-    <link:ctn id="7"/><link:ctn id="6"/><link:ctn id="8"/>
-  </route>
-  <route src="Bourassa" dst="Ginette">
-    <link:ctn id="7"/><link:ctn id="6"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="5"/>
-  </route>
-</platform>
diff --git a/src/bindings/ruby/small_platform.xml b/src/bindings/ruby/small_platform.xml
deleted file mode 100644 (file)
index 3fa9afd..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version='1.0'?>
-<!DOCTYPE platform SYSTEM "simgrid.dtd">
-<platform version="2">
-  <!-- ljlkj -->
-  <host id="Tremblay" power="98095000"/>
-  <host id="Jupiter" power="76296000"/>
-  <host id="Fafard" power="76296000"/>
-  <host id="Ginette" power="48492000"/>
-  <host id="Bourassa" power="48492000"/>
-  <link id="6" bandwidth="41279125" latency="5.9904e-05"/>
-  <link id="11" bandwidth="252750" latency="0.00570455"/>
-  <link id="3" bandwidth="34285625" latency="0.000514433"/>
-  <link id="7" bandwidth="11618875" latency="0.00018998"/>
-  <link id="9" bandwidth="7209750" latency="0.001461517"/>
-  <link id="12" bandwidth="1792625" latency="0.007877863"/>
-  <link id="2" bandwidth="118682500" latency="0.000136931"/>
-  <link id="8" bandwidth="8158000" latency="0.000270544"/>
-  <link id="1" bandwidth="34285625" latency="0.000514433"/>
-  <link id="4" bandwidth="10099625" latency="0.00047978"/>
-  <link id="0" bandwidth="41279125" latency="5.9904e-05"/>
-  <link id="10" bandwidth="4679750" latency="0.000848712"/>
-  <link id="5" bandwidth="27946250" latency="0.000278066"/>
-  <link id="loopback" bandwidth="498000000" latency="0.000015" sharing_policy="FATPIPE"/>
-  <route src="Tremblay" dst="Tremblay"><link:ctn id="loopback"/></route>
-  <route src="Jupiter" dst="Jupiter"><link:ctn id="loopback"/></route>
-  <route src="Fafard" dst="Fafard"><link:ctn id="loopback"/></route>
-  <route src="Ginette" dst="Ginette"><link:ctn id="loopback"/></route>
-  <route src="Bourassa" dst="Bourassa"><link:ctn id="loopback"/></route>
-  <route src="Tremblay" dst="Jupiter">
-    <link:ctn id="9"/>
-  </route>
-  <route src="Tremblay" dst="Fafard">
-    <link:ctn id="4"/><link:ctn id="3"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="8"/>
-  </route>
-  <route src="Tremblay" dst="Ginette">
-    <link:ctn id="4"/><link:ctn id="3"/><link:ctn id="5"/>
-  </route>
-  <route src="Tremblay" dst="Bourassa">
-    <link:ctn id="4"/><link:ctn id="3"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="6"/><link:ctn id="7"/>
-  </route>
-  <route src="Jupiter" dst="Tremblay">
-    <link:ctn id="9"/>
-  </route>
-  <route src="Jupiter" dst="Fafard">
-    <link:ctn id="9"/><link:ctn id="4"/><link:ctn id="3"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="8"/>
-  </route>
-  <route src="Jupiter" dst="Ginette">
-    <link:ctn id="9"/><link:ctn id="4"/><link:ctn id="3"/><link:ctn id="5"/>
-  </route>
-  <route src="Jupiter" dst="Bourassa">
-    <link:ctn id="9"/><link:ctn id="4"/><link:ctn id="3"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="6"/><link:ctn id="7"/>
-  </route>
-  <route src="Fafard" dst="Tremblay">
-    <link:ctn id="8"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="3"/><link:ctn id="4"/>
-  </route>
-  <route src="Fafard" dst="Jupiter">
-    <link:ctn id="8"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="3"/><link:ctn id="4"/><link:ctn id="9"/>
-  </route>
-  <route src="Fafard" dst="Ginette">
-    <link:ctn id="8"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="5"/>
-  </route>
-  <route src="Fafard" dst="Bourassa">
-    <link:ctn id="8"/><link:ctn id="6"/><link:ctn id="7"/>
-  </route>
-  <route src="Ginette" dst="Tremblay">
-    <link:ctn id="5"/><link:ctn id="3"/><link:ctn id="4"/>
-  </route>
-  <route src="Ginette" dst="Jupiter">
-    <link:ctn id="5"/><link:ctn id="3"/><link:ctn id="4"/><link:ctn id="9"/>
-  </route>
-  <route src="Ginette" dst="Fafard">
-    <link:ctn id="5"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="8"/>
-  </route>
-  <route src="Ginette" dst="Bourassa">
-    <link:ctn id="5"/><link:ctn id="2"/><link:ctn id="0"/><link:ctn id="1"/><link:ctn id="6"/><link:ctn id="7"/>
-  </route>
-  <route src="Bourassa" dst="Tremblay">
-    <link:ctn id="7"/><link:ctn id="6"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="3"/><link:ctn id="4"/>
-  </route>
-  <route src="Bourassa" dst="Jupiter">
-    <link:ctn id="7"/><link:ctn id="6"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="3"/><link:ctn id="4"/><link:ctn id="9"/>
-  </route>
-  <route src="Bourassa" dst="Fafard">
-    <link:ctn id="7"/><link:ctn id="6"/><link:ctn id="8"/>
-  </route>
-  <route src="Bourassa" dst="Ginette">
-    <link:ctn id="7"/><link:ctn id="6"/><link:ctn id="1"/><link:ctn id="0"/><link:ctn id="2"/><link:ctn id="5"/>
-  </route>
-</platform>