Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' into MC_LTL
authorMarion Guthmuller <marion.guthmuller@loria.fr>
Wed, 7 Dec 2011 12:12:22 +0000 (13:12 +0100)
committerMarion Guthmuller <marion.guthmuller@loria.fr>
Wed, 7 Dec 2011 12:12:22 +0000 (13:12 +0100)
Conflicts:
buildtools/Cmake/DefinePackages.cmake

buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/Distrib.cmake
examples/msg/token_ring/ring_call.c
examples/msg/token_ring/token_ring.tesh
examples/platforms/generation_scripts/create_hierarchical_clusters.pl [new file with mode: 0755]
examples/platforms/generation_scripts/enhancedDTDwithHierarchicalCluster.pl [new file with mode: 0755]
src/simix/smx_context.c
src/surf/surf_routing_dijkstra.c
src/surf/surf_routing_rulebased.c
src/xbt/parmap.c
src/xbt/parmap_private.h [deleted file]

index e2e3abb..d163aaf 100644 (file)
@@ -16,7 +16,6 @@ set(EXTRA_DIST
        src/xbt/backtrace_windows.c
        src/xbt/backtrace_dummy.c
        src/xbt/setset_private.h
-       src/xbt/parmap_private.h
        src/xbt/automatonparse_promela.c
        src/xbt/mmalloc/attach.c
        src/xbt/mmalloc/detach.c        
index 9aea98e..0e63df6 100644 (file)
@@ -15,7 +15,8 @@ install(DIRECTORY "${CMAKE_HOME_DIRECTORY}/doc/html/"
 )
 
 #### Generate the manpages
-if( NOT MANPAGE_DIR )
+if(NOT WIN32)
+if( NOT MANPAGE_DIR)
        set( MANPAGE_DIR ${CMAKE_BINARY_DIR}/manpages )
 endif( NOT MANPAGE_DIR)
 
@@ -27,6 +28,8 @@ add_custom_target(manpages ALL
 install(FILES ${MANPAGE_DIR}/simgrid_update_xml.1
         DESTINATION $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/usr/share/man/man1)
 
+endif(NOT WIN32)
+
 # binaries
 install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/smpicc
                  ${CMAKE_BINARY_DIR}/bin/smpif2c
index 305945b..8cdf4e9 100644 (file)
 #include "msg/msg.h"
 #include "surf/surf_private.h"
 
-extern routing_global_t global_routing;
-int totalHosts= 0;
-const m_host_t *hosts;
-
-int master(int argc, char *argv[]);
-int slave(int argc, char *argv[]);
+int host(int argc, char *argv[]);
+unsigned int task_comp_size = 50000000;
+unsigned int task_comm_size = 1000000;
+int number_of_hosts;
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(ring,
                              "Messages specific for this msg example");
 
-int master(int argc, char *argv[])
-{
-       m_task_t task_s = NULL;
-       m_task_t task_r = NULL;
-       unsigned int task_comp_size = 50000000;
-       unsigned int task_comm_size = 1000000;
-       char mailbox[80];
-       char buffer[20];
-       int num = atoi(argv[1]);
-
-    sprintf(mailbox, "host%d", num+1);
-    if(num == totalHosts-1)
-       sprintf(mailbox, "host%d", 0);
-    sprintf(buffer, "Token");
-
-    task_s = MSG_task_create(buffer,
-                                                       task_comp_size,
-                                                       task_comm_size,
-                                                       NULL);
-    MSG_task_send(task_s,mailbox);
-    XBT_INFO("Send Data to \"%s\"", mailbox);
-
-       sprintf(mailbox, "host%d", num);
-       MSG_task_receive(&(task_r), mailbox);
-       XBT_INFO("Received \"%s\"", MSG_task_get_name(task_r));
-       return 0;
-}
-
-int slave(int argc, char *argv[])
-{
-       m_task_t task_s = NULL;
-       m_task_t task_r = NULL;
-       unsigned int task_comp_size = 50000000;
-       unsigned int task_comm_size = 1000000;
-       char mailbox[80];
-       char buffer[20];
-       int num = atoi(argv[1]);
-
-       sprintf(mailbox, "host%d", num);
-       MSG_task_receive(&(task_r), mailbox);
-       XBT_INFO("Received \"%s\"", MSG_task_get_name(task_r));
-       sprintf(mailbox, "host%d", num+1);
-       if(num == totalHosts-1)
-               sprintf(mailbox, "host%d", 0);
-       sprintf(buffer, "Token");
-       task_s = MSG_task_create(buffer,
-                                                       task_comp_size,
-                                                       task_comm_size,
-                                                       NULL);
-       MSG_task_send(task_s, mailbox);
-       XBT_INFO("Send Data to \"%s\"", mailbox);
-
-       return 0;
-}
-
-static int surf_parse_bypass_application(void)
+int host(int argc, char *argv[])
 {
-       int i;
-       static int AX_ptr;
-       static int surfxml_bufferstack_size = 2048;
-       static int surfxml_buffer_stack_stack_ptr = 0;
-       static int surfxml_buffer_stack_stack[1024];
-       /* allocating memory to the buffer, I think 2MB should be enough */
-       surfxml_bufferstack = xbt_new0(char, surfxml_bufferstack_size);
-
-       totalHosts = MSG_get_host_number();
-       hosts = MSG_get_host_table();
-
-       /* <platform> */
-       SURFXML_BUFFER_SET(platform_version, "3");
-
-       SURFXML_START_TAG(platform);
-
-       XBT_DEBUG("process : %s en master",MSG_host_get_name(hosts[0]));
-       /*   <process host="host A" function="master"> */
-       SURFXML_BUFFER_SET(process_host, MSG_host_get_name(hosts[0]));
-       SURFXML_BUFFER_SET(process_function, "master");
-       SURFXML_BUFFER_SET(process_start_time, "-1.0");
-       SURFXML_BUFFER_SET(process_kill_time, "-1.0");
-       SURFXML_START_TAG(process);
-
-       /*      <argument value="0"/> */
-       SURFXML_BUFFER_SET(argument_value, "0");
-       SURFXML_START_TAG(argument);
-       SURFXML_END_TAG(argument);
-       SURFXML_END_TAG(process);
-
-       for(i=1;i<totalHosts;i++)
-       {
-       XBT_DEBUG("process : %s en slave",MSG_host_get_name(hosts[i]));
-       /*   <process host="host A" function="slave"> */
-       SURFXML_BUFFER_SET(process_host,MSG_host_get_name(hosts[i]) );
-       SURFXML_BUFFER_SET(process_function, "slave");
-       SURFXML_BUFFER_SET(process_start_time, "-1.0");
-       SURFXML_BUFFER_SET(process_kill_time, "-1.0");
-       SURFXML_START_TAG(process);
-
-       /*      <argument value="num"/> */
-       SURFXML_BUFFER_SET(argument_value, bprintf("%d",i));
-       SURFXML_START_TAG(argument);
-       SURFXML_END_TAG(argument);
-       SURFXML_END_TAG(process);
-       }
-       /* </platform> */
-       SURFXML_END_TAG(platform);
-
-       free(surfxml_bufferstack);
-       return 0;
+  int host_number = atoi(MSG_process_get_name(MSG_process_self()));
+  char mailbox[256];
+  m_task_t task = NULL;
+  _XBT_GNUC_UNUSED int res;
+
+  if (host_number == 0){ //master  send then receive
+    sprintf(mailbox, "%d", host_number+1);
+    task = MSG_task_create("Token", task_comp_size, task_comm_size, NULL);
+    XBT_INFO("Host \"%d\" send '%s' to Host \"%s\"",host_number,task->name,mailbox);
+    MSG_task_send(task, mailbox);
+    task = NULL;
+    res = MSG_task_receive(&(task), MSG_process_get_name(MSG_process_self()));
+    xbt_assert(res == MSG_OK, "MSG_task_get failed");
+    XBT_INFO("Host \"%d\" received \"%s\"",host_number, MSG_task_get_name(task));
+    MSG_task_destroy(task);
+  }
+  else{ //slave receive then send
+    res = MSG_task_receive(&(task), MSG_process_get_name(MSG_process_self()));
+    xbt_assert(res == MSG_OK, "MSG_task_get failed");
+    XBT_INFO("Host \"%d\" received \"%s\"",host_number, MSG_task_get_name(task));
+
+    if(host_number+1 == number_of_hosts )
+      sprintf(mailbox, "0");
+    else
+      sprintf(mailbox, "%d", host_number+1);
+    XBT_INFO("Host \"%d\" send '%s' to Host \"%s\"",host_number,task->name,mailbox);
+    MSG_task_send(task, mailbox);
+  }
+  return 0;
 }
 
 typedef enum {
@@ -136,22 +57,26 @@ typedef enum {
 
 int main(int argc, char **argv)
 {
-       int res;
+       int i,res;
   MSG_global_init(&argc, argv);
   MSG_set_channel_number(MAX_CHANNEL);
   MSG_create_environment(argv[1]);
-
-  MSG_function_register("master", master);
-  MSG_function_register("slave", slave);
-  surf_parse = surf_parse_bypass_application;
-  MSG_launch_application(NULL);
+  m_host_t *host_table =  MSG_get_host_table();
+  number_of_hosts = MSG_get_host_number();
+  MSG_function_register("host", host);
+
+  XBT_INFO("Number of host '%d'",number_of_hosts);
+  for(i = 0 ; i<number_of_hosts; i++)
+  {
+    char* name_host = bprintf("%d",i);
+    MSG_process_create( name_host, host, NULL, host_table[i] );
+    free(name_host);
+  }
+  xbt_free(host_table);
 
   res = MSG_main();
-
   XBT_INFO("Simulation time %g", MSG_get_clock());
-
   MSG_clean();
-
   if (res == MSG_OK)
     return 0;
   else
index 02147a9..274201a 100644 (file)
@@ -1,36 +1,34 @@
 #! ./tesh
 
-! output sort
 $ $SG_TEST_EXENV ${bindir:=.}/token_ring ${srcdir:=.}/two_clusters.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
-> [  0.000000] (0:@) Bypassing the XML parser since surf_parse_open received a NULL pointer. If it is not what you want, go fix your code.
-> [  0.066240] (1:master@bob1.hamburger.edu) Send Data to "host1"
-> [  0.066240] (2:slave@bob3.hamburger.edu) Received "Token"
-> [  0.242880] (2:slave@bob3.hamburger.edu) Send Data to "host2"
-> [  0.242880] (3:slave@alice2.crepe.fr) Received "Token"
-> [  0.309120] (3:slave@alice2.crepe.fr) Send Data to "host3"
-> [  0.309120] (4:slave@alice3.crepe.fr) Received "Token"
-> [  0.485760] (4:slave@alice3.crepe.fr) Send Data to "host4"
-> [  0.485760] (5:slave@bob0.hamburger.edu) Received "Token"
-> [  0.552000] (5:slave@bob0.hamburger.edu) Send Data to "host5"
-> [  0.552000] (6:slave@bob2.hamburger.edu) Received "Token"
-> [  0.618240] (6:slave@bob2.hamburger.edu) Send Data to "host6"
-> [  0.618240] (7:slave@bob4.hamburger.edu) Received "Token"
-> [  0.794880] (7:slave@bob4.hamburger.edu) Send Data to "host7"
-> [  0.794880] (8:slave@alice0.crepe.fr) Received "Token"
-> [  0.861120] (8:slave@alice0.crepe.fr) Send Data to "host8"
-> [  0.861120] (9:slave@alice4.crepe.fr) Received "Token"
-> [  0.927360] (10:slave@alice1.crepe.fr) Received "Token"
-> [  0.927360] (9:slave@alice4.crepe.fr) Send Data to "host9"
+> [  0.000000] (0:@) Number of host '10'
+> [  0.000000] (1:0@bob1.hamburger.edu) Host "0" send 'Token' to Host "1"
+> [  0.066240] (2:1@bob3.hamburger.edu) Host "1" received "Token"
+> [  0.066240] (2:1@bob3.hamburger.edu) Host "1" send 'Token' to Host "2"
+> [  0.242880] (3:2@alice2.crepe.fr) Host "2" received "Token"
+> [  0.242880] (3:2@alice2.crepe.fr) Host "2" send 'Token' to Host "3"
+> [  0.309120] (4:3@alice3.crepe.fr) Host "3" received "Token"
+> [  0.309120] (4:3@alice3.crepe.fr) Host "3" send 'Token' to Host "4"
+> [  0.485760] (5:4@bob0.hamburger.edu) Host "4" received "Token"
+> [  0.485760] (5:4@bob0.hamburger.edu) Host "4" send 'Token' to Host "5"
+> [  0.552000] (6:5@bob2.hamburger.edu) Host "5" received "Token"
+> [  0.552000] (6:5@bob2.hamburger.edu) Host "5" send 'Token' to Host "6"
+> [  0.618240] (7:6@bob4.hamburger.edu) Host "6" received "Token"
+> [  0.618240] (7:6@bob4.hamburger.edu) Host "6" send 'Token' to Host "7"
+> [  0.794880] (8:7@alice0.crepe.fr) Host "7" received "Token"
+> [  0.794880] (8:7@alice0.crepe.fr) Host "7" send 'Token' to Host "8"
+> [  0.861120] (9:8@alice4.crepe.fr) Host "8" received "Token"
+> [  0.861120] (9:8@alice4.crepe.fr) Host "8" send 'Token' to Host "9"
+> [  0.927360] (10:9@alice1.crepe.fr) Host "9" received "Token"
+> [  0.927360] (10:9@alice1.crepe.fr) Host "9" send 'Token' to Host "0"
+> [  1.104000] (1:0@bob1.hamburger.edu) Host "0" received "Token"
 > [  1.104000] (0:@) Simulation time 1.104
-> [  1.104000] (10:slave@alice1.crepe.fr) Send Data to "host0"
-> [  1.104000] (1:master@bob1.hamburger.edu) Received "Token"
 
-! output sort
 $ $SG_TEST_EXENV ${bindir:=.}/token_ring ${srcdir:=.}/two_peers.xml --cfg=coordinates:yes "--log=root.fmt:[%12.6r]%e(%i:%P@%h)%e%m%n"
 > [    0.000000] (0:@) Configuration change: Set 'coordinates' to 'yes'
-> [    0.000000] (0:@) Bypassing the XML parser since surf_parse_open received a NULL pointer. If it is not what you want, go fix your code.
-> [    5.221778] (1:master@peer_100030591) Send Data to "host1"
-> [    5.221778] (2:slave@peer_100036570) Received "Token"
-> [   10.443556] (0:@) Simulation time 10.4436
-> [   10.443556] (1:master@peer_100030591) Received "Token"
-> [   10.443556] (2:slave@peer_100036570) Send Data to "host0"
\ No newline at end of file
+> [    0.000000] (0:@) Number of host '2'
+> [    0.000000] (1:0@peer_100030591) Host "0" send 'Token' to Host "1"
+> [    0.110400] (2:1@peer_100036570) Host "1" received "Token"
+> [    0.110400] (2:1@peer_100036570) Host "1" send 'Token' to Host "0"
+> [    0.220800] (1:0@peer_100030591) Host "0" received "Token"
+> [    0.220800] (0:@) Simulation time 0.2208
\ No newline at end of file
diff --git a/examples/platforms/generation_scripts/create_hierarchical_clusters.pl b/examples/platforms/generation_scripts/create_hierarchical_clusters.pl
new file mode 100755 (executable)
index 0000000..5ddfe9c
--- /dev/null
@@ -0,0 +1,220 @@
+#! /usr/bin/perl
+
+# L.Bobelin (Perl newbie) 25th of November
+# Quick script to generate hierarchical clusters. Usage : <the script> p s d  where :
+# - p : 2^p gives the total number of hosts.
+# - s : cluster size
+# - d : degree of inner nodes.
+#
+# output is the standard one. 
+# 
+#
+#Each node is numbered by a DFS in the tree. Each cluster is numbered by the DFS number of the leaf it is attached to and the number of cluster for each leaf. 
+# Other infos : 
+# - Same bb_lat used for any routers inside (not that complicated to modify too).
+# - constants defined in the first part of the script corresponding to classic cluster parameters. links_bw and links_lat added for the inner tree links
+# - bb_lat and bb_bw used in any backbone of the tree.
+# - fails if you set an obviously too small total number of hosts compared to the cluster size (generates a lot of stuff for nothing actually).
+# 
+
+use Math::BigInt;
+
+$prefix= ""; 
+$suffix= "";
+$bw= "125000000";
+$power= "1000000000";
+$lat= "5E-5";
+$bb_bw= "2250000000";
+$bb_lat= "5E-4"; 
+$links_bw= "2250000000";
+$links_lat= "5E-5";
+$id= "";
+
+$p = $ARGV[0];
+$s = $ARGV[1];
+$d = $ARGV[2];
+
+$p = Math::BigInt->new($p);
+$d = Math::BigInt->new($d);
+$s = Math::BigInt->new($s);
+
+$cabinetnodes= $d;
+$nbsons= $d;
+$radical= "1-" . $s;
+$last=$s;
+
+# Number of clusters to generate ? Update: I hate this bigInt package, the way it behaves is SO stupid 
+$totalnumberofhosts = Math::BigInt->new("2");
+$totalnumberofhosts->bpow($p);
+
+$totalnumberofCluster= $totalnumberofhosts->copy();
+
+$totalnumberofCluster->bdiv($s);
+
+# checking if we have to have something non homogeneous
+if ($totalnumberofhosts->copy()->bmod($s) != 0 ) 
+       {
+               $totalnumberofCluster++;
+               $last= $totalnumberofhosts->copy()->bmod($s);
+       }
+
+# Calculating height
+
+$height= $totalnumberofCluster->copy();
+$height->broot($d);
+
+# Checking if an exact root exists
+if ( $height->bcmp(Math::BigInt->new("1")) != 0 && ($height->copy()->bpow($d))->bcmp($totalnumberofCluster)) { 
+       
+       $height++; #will have to deal with empty set of clusters.       
+       }
+# debug stuff  
+#print "Computed : \n";
+#print STDERR "height: " . $height . "\n";
+#print STDERR "totalnumberofhosts: " . $totalnumberofhosts . "\n";
+#print STDERR "totalnumberofcluster: " .  $totalnumberofCluster . "\n";
+#print STDERR "last cluster size (if equals to cluster size, then all clusters will be homogeneous) : " . $last . "\n";
+
+# Counter for giving unique IDs to ASes.
+$ASnumber;
+$ASnumber = 0;
+
+# Printing preamble
+print "<?xml version='1.0'?>\n";
+print "<!DOCTYPE platform SYSTEM \"http://simgrid.gforge.inria.fr/simgrid.dtd\">\n";
+print "<platform version=\"3\">\n";
+
+       
+# Initiate recursion ...
+&DF_creation(0);
+
+# Closing tag, and then back home
+print "</platform>\n"; 
+
+# Recursive stuff for depth first Se... Creation
+sub DF_creation {
+       my($currDepth) = @_;
+       
+       # Curr AS creation
+       print "<AS id=\"". $prefix . "AS_" . $ASnumber . $suffix . "\"  routing=\"Full\">\n";   
+       
+       # Curr router AS creation stuff
+       print "<AS id=\"". $prefix . "exitAS_" . $ASnumber . $suffix . "\"  routing=\"Full\">\n";                        
+       print " <router id=\"" . $prefix . "router_" . $ASnumber . $suffix . "\"/>\n";
+       print "</AS>\n";
+       # Saving my current number to return it to my father
+       my $toReturn = $ASnumber;
+       $ASnumber++;
+       if ($currDepth<$height && $totalnumberofCluster > 0)
+               {               
+               # Creating current AS inner stuff
+               # I should have a table of sons numbers.
+               my @tsons = ();
+               my $createdSons = 0;
+               for (my $i =1; $i<=$nbsons && $totalnumberofCluster > 0 ; $i++)
+               {
+               #saving this son in my tab ...  recursive call to create ASes and cluster underneath
+               push(@tsons, &DF_creation($currDepth + 1)); 
+               $createdSons++;
+               #               
+               # Creating link to this son
+               print "<link id=\"". $prefix . $tsons[$i-1] . $suffix . "\" bandwidth=\"" . $links_bw . "\" latency=\"" . $links_lat . "\"/>\n";        
+               }
+               # curr backbone creation 
+               print "<link id=\"". $prefix . "bb_" . $toReturn . $suffix . "\" bandwidth=\"" . $bb_bw . "\" latency=\"" . $bb_lat . "\"/>\n";
+               # Full routing AS to AS declaration
+               for (my $i =1; $i<=$createdSons ; $i++)
+               {
+                                       for (my $j =$i+1; $j<=$createdSons ; $j++)
+                                       {
+                                               print  "<ASroute src=\"" . $prefix . "AS_" . $tsons[$i-1] . $suffix . "\"\n";
+                                               print " dst=\"" . $prefix . "AS_" . $tsons[$j-1] . $suffix . "\"\n";
+                                               print " gw_src=\"" . $prefix . "router_" . $tsons[$i-1] . $suffix . "\"\n";
+                                               print " gw_dst=\"" . $prefix . "router_" . $tsons[$j-1] . $suffix . "\"\n";
+                                               print " symmetrical=\"YES\">\n";
+                                               
+                                               print "         <link_ctn id=\"" . $prefix . $tsons[$i-1] . $suffix . "\"/>\n";
+                                               print "         <link_ctn id=\"" . $prefix . "bb_" . $toReturn . $suffix . "\"/>\n"; 
+                                               print "         <link_ctn id=\"" . $prefix . $tsons[$j-1] . $suffix . "\"/>\n";
+                                               print "</ASroute>\n";
+                                       }
+               }
+               # Now routes to the exit AS
+               for (my $i =1; $i<=$createdSons ; $i++)
+               {
+                       print  "<ASroute src=\"" . $prefix . "AS_" . $tsons[$i-1] . $suffix . "\"\n";
+                       print " dst=\"" . $prefix . "exitAS_" . $toReturn . $suffix . "\"\n";
+                       print " gw_src=\"" . $prefix . "router_" . $tsons[$i-1] . $suffix . "\"\n";
+                       print " gw_dst=\"" . $prefix . "router_" . $toReturn . $suffix . "\"\n";
+                       print " symmetrical=\"YES\">\n";                                                
+                       print "         <link_ctn id=\"" . $prefix . $tsons[$i-1] . $suffix . "\"/>\n";
+                       print "         <link_ctn id=\"" . $prefix . "bb_" . $toReturn . $suffix . "\"/>\n"; 
+                       print "</ASroute>\n";                   
+               }
+               print "</AS>\n";
+               # DO I have extra stuff to add ? I don't think so.              
+               return $toReturn;
+               }
+       else { # On leaves, 
+               my $lastNumberOfClusterCreated = 0;     
+               #I must create clusters now
+               for(my $i = 1; $i <= $cabinetnodes && $totalnumberofCluster>0 ; $i++) {
+                       $lastNumberOfClusterCreated++;
+                       if ($totalnumberofCluster==1)
+                       {
+                       print "<cluster id=\"". $prefix . "cl_" . $toReturn . "_" . $i . $suffix . "\" prefix=\"" . $prefix . "c_" . $toReturn . "_" . $i . "-\" suffix=\"" . $suffix . "\" radical=\"1-"
+                               . $last . "\" power=\"" . $power . "\" bw=\"" . $bw . "\" lat=\"" . $lat . "\" bb_bw=\"" . $bb_bw . "\" bb_lat=\"" . $bb_lat . "\"/>\n";        
+                       }
+                       else 
+                       {       
+                       print "<cluster id=\"". $prefix . "cl_" . $toReturn . "_" . $i . $suffix . "\" prefix=\"" . $prefix . "c_" . $toReturn . "_" . $i . "-\" suffix=\"" . $suffix . "\" radical=\""
+                               . $radical . "\" power=\"" . $power . "\" bw=\"" . $bw . "\" lat=\"" . $lat . "\" bb_bw=\"" . $bb_bw . "\" bb_lat=\"" . $bb_lat . "\"/>\n";     
+                       }
+                       $totalnumberofCluster--;
+                       }       
+               # Creating links to clusters 
+               for(my $i = 1; $i <= $lastNumberOfClusterCreated ; $i++) {
+                       print "<link id=\"". $prefix . $toReturn . "_" . $i . $suffix . "\" bandwidth=\"" . $links_bw . "\" latency=\"" . $links_lat . "\"/>\n";
+               }
+
+               # 
+               # curr backbone creation 
+               print "<link id=\"". $prefix . "bb_" . $toReturn . $suffix . "\" bandwidth=\"" . $bb_bw . "\" latency=\"" . $bb_lat . "\"/>\n";
+       
+               # I must create routes between clusters now 
+               for (my $i =1; $i<=$lastNumberOfClusterCreated ; $i++)
+                       {
+                                       for (my $j =$i+1; $j<=$lastNumberOfClusterCreated ; $j++)
+                                       {
+                                               print  "<ASroute src=\"" . $prefix . "cl_" . $toReturn . "_" . $i . $suffix .  "\"\n";
+                                               print " dst=\"" .  $prefix . "cl_" . $toReturn . "_" . $j . $suffix .  "\"\n";
+
+                                               print " gw_src=\"" . $prefix . "c_" . $toReturn . "_" . $i . "-" . $prefix . "cl_" . $toReturn . "_" . $i . $suffix . "_router" . $suffix  ."\"\n";
+                                               print " gw_dst=\"" . $prefix . "c_" . $toReturn . "_" . $j . "-" . $prefix . "cl_" . $toReturn . "_" . $j . $suffix  . "_router" . $suffix . "\"\n";
+                                               print " symmetrical=\"YES\">\n";
+                                               
+                                               print "         <link_ctn id=\"" . $prefix . $toReturn. "_" . $i . $suffix . "\"/>\n";
+                                               print "         <link_ctn id=\"" . $prefix . "bb_" . $toReturn . $suffix . "\"/>\n"; 
+                                               print "         <link_ctn id=\"" . $prefix . $toReturn . "_" . $j . $suffix . "\"/>\n";
+                                               print "</ASroute>\n";
+                                       }
+                       }
+               # Now routes to the exit AS
+               for (my $i =1; $i<=$lastNumberOfClusterCreated ; $i++)
+               {
+                       print  "<ASroute src=\""  . $prefix . "cl_" . $toReturn . "_" . $i . $suffix  . "\"\n";
+                       print " dst=\"" . $prefix . "exitAS_" . $toReturn . $suffix . "\"\n";
+                       # SAME HERE !!
+                       print " gw_src=\"" . $prefix . "c_" . $toReturn . "_" . $i . "-" . $prefix . "cl_" . $toReturn . "_" . $i . $suffix . "_router" . $suffix  ."\"\n";
+                       print " gw_dst=\"" . $prefix . "router_" . $toReturn . $suffix . "\"\n";
+                       print " symmetrical=\"YES\">\n";                                                
+                       print "         <link_ctn id=\"" . $prefix . $toReturn . "_" . $i . $suffix . "\"/>\n";
+                       print "         <link_ctn id=\"" . $prefix . "bb_" . $toReturn . $suffix . "\"/>\n"; 
+                       print "</ASroute>\n";                   
+               }
+               print "</AS>\n";
+       # Should be done with it...
+       return $toReturn;
+       }
+
+}
diff --git a/examples/platforms/generation_scripts/enhancedDTDwithHierarchicalCluster.pl b/examples/platforms/generation_scripts/enhancedDTDwithHierarchicalCluster.pl
new file mode 100755 (executable)
index 0000000..e5c1124
--- /dev/null
@@ -0,0 +1,215 @@
+#! /usr/bin/perl
+
+# L.Bobelin (Perl newbie) 24th of November
+# Quick script to generate hierarchical clusters. Usage : add the special cluster tag (description below) in your "normal" platform file. Then run the script :
+# - First arg : the input file where you midified your cluster tag
+# - Second one : the output file where all the stuff will be generated.
+# Builds a complete tree to access clusters ; each node of the tree is inclosed in an AS, where full routing applies.
+#
+# Number of cluster per leaf is given by cabinetnodes attr.
+#
+#
+# Choosed to modify a cluster tag to allow to give additional informations : 
+# - nbsons : degree of inner  
+# - height : tree heigth
+# - cabinetnodes : cluster per leaf
+# 
+# Each node is numbered by a DFS in the tree. Each cluster is numbered by the DFS number of the leaf it is attached to and the number of cluster for each leaf. 
+# 
+#       
+# Example syntax for hierarchical cluster creation : 
+# <cluster id="AS_cb1" prefix="cb1-" suffix=".dc1.acloud.com" power="5.2297E9" bw="1.25E8" lat="1.0E-4 bb_bw="1.25E9" bb_lat="1.0E-4" radical="0-99" cabinetnodes="4" height="3" nbsons="2" links_lat="1.0E-4" links_bw="1.25E9"/>
+# Other infos : 
+# - special tag has to be on one line because I don't want to bother with parsing issues
+# - Same bb_lat used for any routers inside (not that complicated to modify too)
+# - lame perl ? I'm a script kiddie in perl, it may well be my first perl stuff. 
+# - Don't try to check or validate the modified file with the DTD, of course, as this is not a part of it.
+
+# Counter for giving unique IDs to ASes.
+$ASnumber;
+$ASnumber = 0;
+
+$infile;
+$outfile; 
+
+$infile = $ARGV[0];
+$outfile = $ARGV[1];
+open IN, "$infile" || die "Cannot parse " . $infile . " ...\n";
+open OUT,">$outfile" || die "Cannot use the output file " . $outfile . " ...\n";
+my $line;
+while ($line = <IN>) {
+# looking for good lines. 
+if ($line =~ / cabinetnodes=/) 
+{ #Retrieving informations
+       ($line=~ /cabinetnodes=\"([^\"]*)/);
+       $cabinetnodes= $1;
+       ($line=~ /height=\"([^\"]*)/);
+       $height= $1;
+       ($line=~ /nbsons=\"([^\"]*)/);
+       $nbsons= $1;
+        ($line=~ /id=\"([^\"]*)/);
+       $id= $1;
+       ($line=~ /prefix=\"([^\"]*)/);
+       $prefix= $1; 
+       ($line=~ /suffix=\"([^\"]*)/);
+       $suffix= $1;
+       ($line=~ /bw=\"([^\"]*)/);
+       $bw= $1;
+       ($line=~ /power=\"([^\"]*)/);
+       $power= $1;
+       ($line=~ /lat=\"([^\"]*)/);
+       $lat= $1;
+       ($line=~ /bb_bw=\"([^\"]*)/);
+       $bb_bw= $1;
+       ($line=~ /bb_lat=\"([^\"]*)/);
+       $bb_lat= $1; 
+       ($line=~ /links_bw=\"([^\"]*)/);
+       $links_bw= $1;
+       ($line=~ /links_lat=\"([^\"]*)/);
+       $links_lat= $1;
+       ($line=~ /radical=\"([^\"]*)/);
+       $radical= $1;
+
+       print "Variables read : \n";
+       print "number of clusters in each cabinet: " . $cabinetnodes . "\n";
+       print "Tree heigth: " . $height . "\n";
+       print "Degree of each node: " . $nbsons . "\n";
+       print "General id: ". $id . "\n";
+       print "General prefix: " . $prefix . "\n";
+       print "General suffix: ". $suffix . "\n";
+       print "Bandwidth for cluster inner links: " . $bw . "\n";
+       print "Power for cluster nodes: " . $power . "\n";
+       print "Latency for clusters inner links :" . $lat . "\n";
+       print "Backbone bandwwidth (used in all backbones, including the tree ones):" . $bb_bw . "\n";
+       print "Backbone latency (used in all backbones, including the tree ones):" . $bb_lat . "\n";
+       print "Tree links bandwidth: " . $links_bw . "\n";
+       print "Tree links latency: " . $links_lat . "\n";
+       print "Radical: " . $radical . "\n";
+
+       
+       
+       &DF_creation(0);
+       }
+else {
+print OUT $line;
+}
+} #End while
+close IN;
+close OUT;
+print $infile . " -> " . $outfile . " ... Done.\n";
+
+# Recursive stuff for depth first Se... Creation
+sub DF_creation {
+       my($currDepth) = @_;
+       
+       # Curr AS creation
+       print OUT "<AS id=\"". $prefix . "AS_" . $ASnumber . $suffix . "\"  routing=\"Full\">\n";       
+       
+       # Curr router AS creation stuff
+       print OUT "<AS id=\"". $prefix . "exitAS_" . $ASnumber . $suffix . "\"  routing=\"Full\">\n";                    
+       print OUT "     <router id=\"" . $prefix . "router_" . $ASnumber . $suffix . "\"/>\n";
+       print OUT "</AS>\n";
+       # Saving my current number to return it to my father
+       my $toReturn = $ASnumber;
+       $ASnumber++;
+       if ($currDepth<$height)
+               {                               
+               # Creating current AS inner stuff
+               # I should have a table of sons numbers.
+               my @tsons = ();
+               for (my $i =1; $i<=$nbsons ; $i++)
+               {
+               #saving this son in my tab ...  recursive call to create ASes and cluster underneath
+               push(@tsons, &DF_creation($currDepth + 1)); 
+               #               
+               # Creating link to this son
+               print OUT "<link id=\"". $prefix . $tsons[$i-1] . $suffix . "\" bandwidth=\"" . $links_bw . "\" latency=\"" . $links_lat . "\"/>\n";    
+               }
+               # curr backbone creation 
+               print OUT "<link id=\"". $prefix . "bb_" . $toReturn . $suffix . "\" bandwidth=\"" . $bb_bw . "\" latency=\"" . $bb_lat . "\"/>\n";
+               # Full routing AS to AS declaration
+               for (my $i =1; $i<=$nbsons ; $i++)
+               {
+                                       for (my $j =$i+1; $j<=$nbsons ; $j++)
+                                       {
+                                               print OUT  "<ASroute src=\"" . $prefix . "AS_" . $tsons[$i-1] . $suffix . "\"\n";
+                                               print OUT "     dst=\"" . $prefix . "AS_" . $tsons[$j-1] . $suffix . "\"\n";
+                                               print OUT "     gw_src=\"" . $prefix . "router_" . $tsons[$i-1] . $suffix . "\"\n";
+                                               print OUT "     gw_dst=\"" . $prefix . "router_" . $tsons[$j-1] . $suffix . "\"\n";
+                                               print OUT "     symmetrical=\"YES\">\n";
+                                               
+                                               print OUT "             <link_ctn id=\"" . $prefix . $tsons[$i-1] . $suffix . "\"/>\n";
+                                               print OUT "             <link_ctn id=\"" . $prefix . "bb_" . $toReturn . $suffix . "\"/>\n"; 
+                                               print OUT "             <link_ctn id=\"" . $prefix . $tsons[$j-1] . $suffix . "\"/>\n";
+                                               print OUT "</ASroute>\n";
+                                       }
+               }
+               # Now routes to the exit AS
+               for (my $i =1; $i<=$nbsons ; $i++)
+               {
+                       print OUT  "<ASroute src=\"" . $prefix . "AS_" . $tsons[$i-1] . $suffix . "\"\n";
+                       print OUT "     dst=\"" . $prefix . "exitAS_" . $toReturn . $suffix . "\"\n";
+                       print OUT "     gw_src=\"" . $prefix . "router_" . $tsons[$i-1] . $suffix . "\"\n";
+                       print OUT "     gw_dst=\"" . $prefix . "router_" . $toReturn . $suffix . "\"\n";
+                       print OUT "     symmetrical=\"YES\">\n";                                                
+                       print OUT "             <link_ctn id=\"" . $prefix . $tsons[$i-1] . $suffix . "\"/>\n";
+                       print OUT "             <link_ctn id=\"" . $prefix . "bb_" . $toReturn . $suffix . "\"/>\n"; 
+                       print OUT "</ASroute>\n";                       
+               }
+               print OUT "</AS>\n";
+               # DO I have extra stuff to add ? I don't think so.              
+               return $toReturn;
+               }
+       else { # On leaves, 
+                       
+               #I must create clusters now
+               for(my $i = 1; $i <= $cabinetnodes; $i++) {
+                       print OUT "<cluster id=\"". $prefix . "cluster_" . $toReturn . $i . $suffix . "\" prefix=\"" . $prefix . "c_" . $toReturn. $i . "-\" suffix=\"" . $suffix . "\" radical=\""
+                               . $radical . "\" power=\"" . $power . "\" bw=\"" . $bw . "\" lat=\"" . $lat . "\" bb_bw=\"" . $bb_bw . "\" bb_lat=\"" . $bb_lat . "\"/>\n";     
+                       }       
+               # Creating links to clusters 
+               for(my $i = 1; $i <= $cabinetnodes; $i++) {
+                       print OUT "<link id=\"". $prefix . $toReturn . "_" . $i . $suffix . "\" bandwidth=\"" . $links_bw . "\" latency=\"" . $links_lat . "\"/>\n";
+               }
+
+               # 
+               # curr backbone creation 
+               print OUT "<link id=\"". $prefix . "bb_" . $toReturn . $suffix . "\" bandwidth=\"" . $bb_bw . "\" latency=\"" . $bb_lat . "\"/>\n";
+       
+               # I must create routes between clusters now 
+               for (my $i =1; $i<=$cabinetnodes ; $i++)
+                       {
+                                       for (my $j =$i+1; $j<=$cabinetnodes ; $j++)
+                                       {
+                                               print OUT  "<ASroute src=\"" . $prefix . "cluster_" . $toReturn . $i . $suffix .  "\"\n";
+                                               print OUT "     dst=\"" .  $prefix . "cluster_" . $toReturn . $j . $suffix .  "\"\n";
+
+                                               print OUT "     gw_src=\"" . $prefix . "c_" . $toReturn. $i . "-" . $prefix . "cluster_" . $toReturn . $i . $suffix . "_router" . $suffix  ."\"\n";
+                                               print OUT "     gw_dst=\"" . $prefix . "c_" . $toReturn. $j . "-" . $prefix . "cluster_" . $toReturn . $j . $suffix  . "_router" . $suffix . "\"\n";
+                                               print OUT "     symmetrical=\"YES\">\n";
+                                               
+                                               print OUT "             <link_ctn id=\"" . $prefix . $toReturn. "_" . $i . $suffix . "\"/>\n";
+                                               print OUT "             <link_ctn id=\"" . $prefix . "bb_" . $toReturn . $suffix . "\"/>\n"; 
+                                               print OUT "             <link_ctn id=\"" . $prefix . $toReturn . "_" . $j . $suffix . "\"/>\n";
+                                               print OUT "</ASroute>\n";
+                                       }
+                       }
+               # Now routes to the exit AS
+               for (my $i =1; $i<=$cabinetnodes ; $i++)
+               {
+                       print OUT  "<ASroute src=\""  . $prefix . "cluster_" . $toReturn . $i . $suffix  . "\"\n";
+                       print OUT "     dst=\"" . $prefix . "exitAS_" . $toReturn . $suffix . "\"\n";
+                       # SAME HERE !!
+                       print OUT "     gw_src=\"" . $prefix . "c_" . $toReturn. $i . "-" . $prefix . "cluster_" . $toReturn . $i . $suffix . "_router" . $suffix  ."\"\n";
+                       print OUT "     gw_dst=\"" . $prefix . "router_" . $toReturn . $suffix . "\"\n";
+                       print OUT "     symmetrical=\"YES\">\n";                                                
+                       print OUT "             <link_ctn id=\"" . $prefix . $toReturn . "_" . $i . $suffix . "\"/>\n";
+                       print OUT "             <link_ctn id=\"" . $prefix . "bb_" . $toReturn . $suffix . "\"/>\n"; 
+                       print OUT "</ASroute>\n";                       
+               }
+               print OUT "</AS>\n";
+       # Should be done with it...
+       return $toReturn;
+       }
+
+}
index ec51170..4926372 100644 (file)
@@ -22,12 +22,11 @@ smx_ctx_factory_initializer_t smx_factory_initializer_to_use = NULL;
 int smx_context_stack_size = 128 * 1024;
 
 #ifdef HAVE_THREAD_LOCAL_STORAGE
-__thread smx_context_t smx_current_context;
+static __thread smx_context_t smx_current_context_parallel;
 #else
-smx_context_t smx_current_context; /* define it anyway, will be used in non-parallel mode */
 static xbt_os_thread_key_t smx_current_context_key = 0;
 #endif
-
+static smx_context_t smx_current_context_serial;
 static int smx_parallel_contexts = 1;
 static int smx_parallel_threshold = 2;
 
@@ -182,11 +181,16 @@ XBT_INLINE int SIMIX_context_get_parallel_threshold(void) {
  */
 XBT_INLINE smx_context_t SIMIX_context_get_current(void)
 {
+  if (SIMIX_context_is_parallel()) {
 #ifdef HAVE_THREAD_LOCAL_STORAGE
-  return smx_current_context;
+    return smx_current_context_parallel;
 #else
-  return xbt_os_thread_get_specific(smx_current_context_key);
+    return xbt_os_thread_get_specific(smx_current_context_key);
 #endif
+  }
+  else {
+    return smx_current_context_serial;
+  }
 }
 
 /**
@@ -195,10 +199,15 @@ XBT_INLINE smx_context_t SIMIX_context_get_current(void)
  */
 XBT_INLINE void SIMIX_context_set_current(smx_context_t context)
 {
+  if (SIMIX_context_is_parallel()) {
 #ifdef HAVE_THREAD_LOCAL_STORAGE
-  smx_current_context = context;
+    smx_current_context_parallel = context;
 #else
-  xbt_os_thread_set_specific(smx_current_context_key, context);
+    xbt_os_thread_set_specific(smx_current_context_key, context);
 #endif
+  }
+  else {
+    smx_current_context_serial = context;
+  }
 }
 
index 3450eea..52d4926 100644 (file)
@@ -437,27 +437,27 @@ AS_t model_dijkstracache_create(void)
 
 void model_dijkstra_both_end(AS_t as)
 {
-  as_dijkstra_t THIS = (as_dijkstra_t) as;
+  as_dijkstra_t THIS_AS = (as_dijkstra_t) as;
 
   xbt_node_t node = NULL;
   unsigned int cursor2;
   xbt_dynar_t nodes = NULL;
 
   /* Create the topology graph */
-  if(!THIS->route_graph)
-  THIS->route_graph = xbt_graph_new_graph(1, NULL);
-  if(!THIS->graph_node_map)
-  THIS->graph_node_map = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
+  if(!THIS_AS->route_graph)
+  THIS_AS->route_graph = xbt_graph_new_graph(1, NULL);
+  if(!THIS_AS->graph_node_map)
+  THIS_AS->graph_node_map = xbt_dict_new_homogeneous(&graph_node_map_elem_free);
 
-  if (THIS->cached && !THIS->route_cache)
-  THIS->route_cache = xbt_dict_new_homogeneous(&route_cache_elem_free);
+  if (THIS_AS->cached && !THIS_AS->route_cache)
+  THIS_AS->route_cache = xbt_dict_new_homogeneous(&route_cache_elem_free);
 
   /* Add the loopback if needed */
   if (as->hierarchy == SURF_ROUTING_BASE)
-    add_loopback_dijkstra(THIS);
+    add_loopback_dijkstra(THIS_AS);
 
   /* initialize graph indexes in nodes after graph has been built */
-  nodes = xbt_graph_get_nodes(THIS->route_graph);
+  nodes = xbt_graph_get_nodes(THIS_AS->route_graph);
 
   xbt_dynar_foreach(nodes, cursor2, node) {
     graph_node_data_t data = xbt_graph_node_get_data(node);
index bdefb70..ca0a8aa 100644 (file)
@@ -339,7 +339,7 @@ static void rulebased_get_route_and_latency(AS_t rc,
   } else if (!strcmp(src, dst) && are_processing_units) {
     xbt_dynar_push(route->link_list, &(global_routing->loopback));
     if (lat)
-      *lat += surf_network_model->extension.network.get_link_latency(link);
+      *lat += surf_network_model->extension.network.get_link_latency(global_routing->loopback);
   } else {
     THROWF(arg_error,0,"No route from '%s' to '%s'??",src,dst);
     //xbt_dynar_reset(route->link_list);
index 19dcb58..25de341 100644 (file)
@@ -5,26 +5,62 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 #include "gras_config.h"
 #include <unistd.h>
+
 #ifndef _XBT_WIN32
 #include <sys/syscall.h>
 #endif
 
 #ifdef HAVE_FUTEX_H
-       #include <linux/futex.h>
-#else
-       #include "xbt/xbt_os_thread.h"
+#include <linux/futex.h>
 #endif
-#include <errno.h>
-#include "parmap_private.h"
+
+#include "xbt/parmap.h"
+#include "xbt/log.h"
+#include "xbt/function_types.h"
+#include "xbt/dynar.h"
+#include "xbt/xbt_os_thread.h"
+#include "xbt/sysdep.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_parmap, xbt, "parmap: parallel map");
 XBT_LOG_NEW_SUBCATEGORY(xbt_parmap_unit, xbt_parmap, "parmap unit testing");
 
-static void *_xbt_parmap_worker_main(void *parmap);
+typedef enum {
+  PARMAP_WORK = 0,
+  PARMAP_DESTROY
+} e_xbt_parmap_flag_t;
+
+static void xbt_parmap_start(xbt_parmap_t parmap);
+static void xbt_parmap_signal(xbt_parmap_t parmap);
+static void xbt_parmap_wait(xbt_parmap_t parmap);
+static void xbt_parmap_end(xbt_parmap_t parmap);
+static void *xbt_parmap_worker_main(void *parmap);
+
 #ifdef HAVE_FUTEX_H
-       static void futex_wait(int *uaddr, int val);
-       static void futex_wake(int *uaddr, int val);
+static void futex_wait(int *uaddr, int val);
+static void futex_wake(int *uaddr, int val);
 #endif
+
+/**
+ * \brief Parallel map structure
+ */
+typedef struct s_xbt_parmap {
+  e_xbt_parmap_flag_t status;      /* is the parmap active or being destroyed? */
+
+  int work;                        /* index of the current round (1 is the first) */
+  int done;                        /* number of rounds already done */
+  unsigned int thread_counter;     /* number of threads currently working */
+  unsigned int num_workers;        /* total number of worker threads */
+  unsigned int workers_max_id;     /* id of the next worker thread to create */
+  void_f_pvoid_t fun;              /* function to run in parallel on each element of data */
+  xbt_dynar_t data;                /* parameters to pass to fun in parallel */
+  unsigned int index;              /* index of the next element of data to pick */
+} s_xbt_parmap_t;
+
+/**
+ * \brief Creates a parallel map object
+ * \param num_workers number of worker threads to create
+ * \return the parmap created
+ */
 xbt_parmap_t xbt_parmap_new(unsigned int num_workers)
 {
   unsigned int i;
@@ -34,49 +70,55 @@ xbt_parmap_t xbt_parmap_new(unsigned int num_workers)
 
   /* Initialize the thread pool data structure */
   xbt_parmap_t parmap = xbt_new0(s_xbt_parmap_t, 1);
-#ifdef HAVE_FUTEX_H
-  parmap->sync_event = xbt_new0(s_xbt_event_t, 1);
-#endif
+
   parmap->num_workers = num_workers;
   parmap->status = PARMAP_WORK;
-#ifdef HAVE_FUTEX_H
-  parmap->sync_event->threads_to_wait = num_workers;
-#endif
+
   /* Create the pool of worker threads */
-  for(i=0; i < num_workers; i++){
-    worker = xbt_os_thread_create(NULL, _xbt_parmap_worker_main, parmap, NULL);
+  for (i = 0; i < num_workers; i++) {
+    worker = xbt_os_thread_create(NULL, xbt_parmap_worker_main, parmap, NULL);
     xbt_os_thread_detach(worker);
   }
-#ifdef HAVE_FUTEX_H
-  xbt_event_init(parmap->sync_event);
-#endif
+  xbt_parmap_start(parmap);
   return parmap;
 }
 
+/**
+ * \brief Destroys a parmap
+ * \param parmap the parmap to destroy
+ */
 void xbt_parmap_destroy(xbt_parmap_t parmap)
-{ 
+{
   parmap->status = PARMAP_DESTROY;
-#ifdef HAVE_FUTEX_H
-  xbt_event_signal(parmap->sync_event);
-  xbt_free(parmap->sync_event);
-#endif
+  xbt_parmap_signal(parmap);
   xbt_free(parmap);
 }
 
- void xbt_parmap_apply(xbt_parmap_t parmap, void_f_pvoid_t fun, xbt_dynar_t data)
+/**
+ * \brief Applies a list of tasks in parallel.
+ * \param parmap a parallel map object
+ * \param fun the function to call in parallel
+ * \param data each element of this dynar will be passed as an argument to fun
+ */
+void xbt_parmap_apply(xbt_parmap_t parmap, void_f_pvoid_t fun, xbt_dynar_t data)
 {
   /* Assign resources to worker threads*/
   parmap->fun = fun;
   parmap->data = data;
   parmap->index = 0;
-#ifdef HAVE_FUTEX_H
-  xbt_event_signal(parmap->sync_event);
-#endif
+  xbt_parmap_signal(parmap);
   XBT_DEBUG("Job done");
 }
 
-void* xbt_parmap_next(xbt_parmap_t parmap) {
-
+/**
+ * \brief Returns a next task to process.
+ *
+ * Worker threads call this function to get more work.
+ *
+ * \return the next task to process, or NULL if there is no more work
+ */
+void* xbt_parmap_next(xbt_parmap_t parmap)
+{
   unsigned int index = __sync_fetch_and_add(&parmap->index, 1);
   if (index < xbt_dynar_length(parmap->data)) {
     return xbt_dynar_get_as(parmap->data, index, void*);
@@ -84,11 +126,21 @@ void* xbt_parmap_next(xbt_parmap_t parmap) {
   return NULL;
 }
 
-unsigned long xbt_parmap_get_worker_id(xbt_parmap_t parmap) {
+/**
+ * \brief Returns the worker id of the current thread.
+ * \param parmap a parmap
+ * \return the worker id
+ */
+unsigned long xbt_parmap_get_worker_id(xbt_parmap_t parmap)
+{
   return (unsigned long) xbt_os_thread_get_extra_data();
 }
 
-static void *_xbt_parmap_worker_main(void *arg)
+/**
+ * \brief Main function of a worker thread.
+ * \param arg the parmap
+ */
+static void *xbt_parmap_worker_main(void *arg)
 {
   unsigned int worker_id;
   xbt_parmap_t parmap = (xbt_parmap_t) arg;
@@ -101,9 +153,7 @@ static void *_xbt_parmap_worker_main(void *arg)
   
   /* Worker's main loop */
   while (1) {
-#ifdef HAVE_FUTEX_H
-    xbt_event_wait(parmap->sync_event);
-#endif
+    xbt_parmap_wait(parmap);
     if (parmap->status == PARMAP_WORK) {
 
       XBT_DEBUG("Worker %u got a job", worker_id);
@@ -117,9 +167,7 @@ static void *_xbt_parmap_worker_main(void *arg)
 
     /* We are destroying the parmap */
     } else {
-#ifdef HAVE_FUTEX_H
-      xbt_event_end(parmap->sync_event);
-#endif
+      xbt_parmap_end(parmap);
       XBT_DEBUG("Shutting down worker %u", worker_id);
       return NULL;
     }
@@ -138,49 +186,94 @@ static void futex_wake(int *uaddr, int val)
   XBT_VERB("Waking futex %p", uaddr);
   syscall(SYS_futex, uaddr, FUTEX_WAKE_PRIVATE, val, NULL, NULL, 0);
 }
+#endif
 
-void xbt_event_init(xbt_event_t event)
+/**
+ * \brief Starts the parmap: waits for all workers to be ready and returns.
+ *
+ * This function is called by the controller thread.
+ *
+ * \param parmap a parmap
+ */
+static void xbt_parmap_start(xbt_parmap_t parmap)
 {
-  int myflag = event->done;
-  if(event->thread_counter < event->threads_to_wait)
-    futex_wait(&event->done, myflag);
+#ifdef HAVE_FUTEX_H
+  int myflag = parmap->done;
+  if (parmap->thread_counter < parmap->num_workers) {
+    /* wait for all workers to be ready */
+    futex_wait(&parmap->done, myflag);
+  }
+#endif
 }
 
-void xbt_event_signal(xbt_event_t event)
+/**
+ * \brief Wakes all workers and waits for them to finish the tasks.
+ *
+ * This function is called by the controller thread.
+ *
+ * \param parmap a parmap
+ */
+static void xbt_parmap_signal(xbt_parmap_t parmap)
 {
-  int myflag = event->done;
-  event->thread_counter = 0;
-  event->work++;
-  futex_wake(&event->work, event->threads_to_wait);
-  futex_wait(&event->done, myflag);
+#ifdef HAVE_FUTEX_H
+  int myflag = parmap->done;
+  parmap->thread_counter = 0;
+  parmap->work++;
+
+  /* wake all workers */
+  futex_wake(&parmap->work, parmap->num_workers);
+
+  /* wait for all of them to finish */
+  futex_wait(&parmap->done, myflag);
+#endif
 }
 
-void xbt_event_wait(xbt_event_t event)
+/**
+ * \brief Waits for some work to process.
+ *
+ * This function is called by each worker when it has no more work to do.
+ *
+ * \param parmap a parmap
+ */
+static void xbt_parmap_wait(xbt_parmap_t parmap)
 {
+#ifdef HAVE_FUTEX_H
   int myflag;
   unsigned int mycount;
 
-  myflag = event->work;
-  mycount = __sync_add_and_fetch(&event->thread_counter, 1);
-  if(mycount == event->threads_to_wait){
-    event->done++;
-    futex_wake(&event->done, 1);
+  myflag = parmap->work;
+  mycount = __sync_add_and_fetch(&parmap->thread_counter, 1);
+  if (mycount == parmap->num_workers) {
+    /* all workers have finished, wake the controller */
+    parmap->done++;
+    futex_wake(&parmap->done, 1);
   }
 
-  futex_wait(&event->work, myflag);
+  /* wait for more work */
+  futex_wait(&parmap->work, myflag);
+#endif
 }
 
-void xbt_event_end(xbt_event_t event)
+/**
+ * \brief Ends the parmap: wakes the controller thread when all workers terminate.
+ *
+ * This function is called by all worker threads when they end.
+ *
+ * \param parmap a parmap
+ */
+static void xbt_parmap_end(xbt_parmap_t parmap)
 {
+#ifdef HAVE_FUTEX_H
   unsigned int mycount;
 
-  mycount = __sync_add_and_fetch(&event->thread_counter, 1);
-  if(mycount == event->threads_to_wait){
-    event->done++;
-    futex_wake(&event->done, 1);
+  mycount = __sync_add_and_fetch(&parmap->thread_counter, 1);
+  if (mycount == parmap->num_workers) {
+    /* all workers have finished, wake the controller */
+    parmap->done++;
+    futex_wake(&parmap->done, 1);
   }
-}
 #endif
+}
 
 #ifdef SIMGRID_TEST
 #include "xbt.h"
@@ -189,8 +282,6 @@ void xbt_event_end(xbt_event_t event)
 XBT_TEST_SUITE("parmap", "Parallel Map");
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(xbt_parmap_unit);
 
-
-
 xbt_parmap_t parmap;
 
 void fun(void *arg);
@@ -204,18 +295,19 @@ XBT_TEST_UNIT("basic", test_parmap_basic, "Basic usage")
 {
   xbt_test_add("Create the parmap");
 
-  unsigned long i,j;
+  unsigned long i, j;
   xbt_dynar_t data = xbt_dynar_new(sizeof(void *), NULL);
 
   /* Create the parallel map */
   parmap = xbt_parmap_new(10);
 
-  for(j=0; j < 100; j++){
+  for(j = 0; j < 100; j++) {
     xbt_dynar_push_as(data, void *, (void *)j);
   }
 
-  for(i=0; i < 5; i++)
+  for (i = 0; i < 5; i++) {
     xbt_parmap_apply(parmap, fun, data);
+  }
 
   /* Destroy the parmap */
   xbt_parmap_destroy(parmap);
diff --git a/src/xbt/parmap_private.h b/src/xbt/parmap_private.h
deleted file mode 100644 (file)
index 8b6c1bb..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright (c) 2004, 2005, 2007, 2009, 2010. 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. */
-
-#ifndef _XBT_THREADPOOL_PRIVATE_H
-#define _XBT_THREADPOOL_PRIVATE_H
-
-#include "xbt/parmap.h"
-#include "xbt/xbt_os_thread.h"
-#include "xbt/sysdep.h"
-#include "xbt/dynar.h"
-#include "xbt/log.h"
-#include "xbt/xbt_os_time.h"
-
-typedef enum{
-  PARMAP_WORK = 0,
-  PARMAP_DESTROY
-} e_xbt_parmap_flag_t;
-
-#ifdef HAVE_FUTEX_H
-typedef struct s_xbt_event{
-  int work;
-  int done;
-  unsigned int thread_counter;
-  unsigned int threads_to_wait;
-}s_xbt_event_t, *xbt_event_t;
-
-void xbt_event_init(xbt_event_t event);
-void xbt_event_signal(xbt_event_t event);
-void xbt_event_wait(xbt_event_t event);
-void xbt_event_end(xbt_event_t event);
-#endif
-
-typedef struct s_xbt_parmap {
-  e_xbt_parmap_flag_t status;
-#ifdef HAVE_FUTEX_H
-  xbt_event_t sync_event;
-#endif
-  unsigned int num_workers;
-  unsigned int workers_max_id;
-  void_f_pvoid_t fun;
-  xbt_dynar_t data;
-  unsigned int index;
-} s_xbt_parmap_t;
-
-#endif