Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Split gtut in several pages, add lesson 5
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sun, 16 Jul 2006 11:00:10 +0000 (11:00 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sun, 16 Jul 2006 11:00:10 +0000 (11:00 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2586 48e7efb5-ca39-0410-a469-dd3cf9ba447f

15 files changed:
doc/Doxyfile.in
doc/Makefile.am
doc/gtut-files/1-bones.output
doc/gtut-files/3-args.output
doc/gtut-files/4-callback.c
doc/gtut-files/4-callback.output
doc/gtut-files/5-globals.c [new file with mode: 0644]
doc/gtut-files/5-globals.output [new file with mode: 0644]
doc/gtut-files/Makefile
doc/gtut-tour-1-bones.doc [new file with mode: 0644]
doc/gtut-tour-2-simple.doc [new file with mode: 0644]
doc/gtut-tour-3-args.doc [new file with mode: 0644]
doc/gtut-tour-4-callback.doc [new file with mode: 0644]
doc/gtut-tour-5-globals.doc [new file with mode: 0644]
doc/gtut-tour.doc

index be6ecea..290202f 100644 (file)
@@ -407,8 +407,13 @@ INPUT                  = @srcdir@/index.doc \
                          @srcdir@/module-sd.doc \
                         \
                         @srcdir@/gtut-main.doc \
                          @srcdir@/module-sd.doc \
                         \
                         @srcdir@/gtut-main.doc \
-                               @srcdir@/gtut-introduction.doc \
-                               @srcdir@/gtut-tour.doc \
+                           @srcdir@/gtut-introduction.doc \
+                           @srcdir@/gtut-tour.doc \
+                               @srcdir@/gtut-tour-1-bones.doc \
+                               @srcdir@/gtut-tour-2-simple.doc \
+                               @srcdir@/gtut-tour-3-args.doc \
+                               @srcdir@/gtut-tour-4-callback.doc \
+                               @srcdir@/gtut-tour-5-globals.doc \
                         \
                          ./logcategories.doc \
                         \
                         \
                          ./logcategories.doc \
                         \
index c0661e8..fe67e0c 100644 (file)
@@ -34,7 +34,7 @@ html: Doxyfile ./logcategories.doc simgrid_modules.map $(PNGS) $(DOCSOURCES)
        @top_srcdir@/tools/doxygen/index_create.pl simgrid.tag index-API.doc
        @top_srcdir@/tools/doxygen/toc_create.pl \
           @srcdir@/FAQ.doc @srcdir@/index.doc @srcdir@/contrib.doc \
        @top_srcdir@/tools/doxygen/index_create.pl simgrid.tag index-API.doc
        @top_srcdir@/tools/doxygen/toc_create.pl \
           @srcdir@/FAQ.doc @srcdir@/index.doc @srcdir@/contrib.doc \
-          @srcdir@/gtut-introduction.doc @srcdir@/gtut-tour.doc
+          @srcdir@/gtut-introduction.doc
        : # Second pass
        doxygen Doxyfile >/dev/null
        : # Post-processing
        : # Second pass
        doxygen Doxyfile >/dev/null
        : # Post-processing
index 014775c..046ad73 100644 (file)
@@ -1,7 +1,7 @@
 $ ./test_client
 $ ./test_client
-[blaise:client:(22033) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(6328) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
 $ ./test_server
 $ ./test_server
-[blaise:server:(22036) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(6331) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
 $ ./test_simulator platform.xml test.xml
 [Jacquelin:server:(1) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
 [Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
 $ ./test_simulator platform.xml test.xml
 [Jacquelin:server:(1) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
 [Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
index d284cc7..42084bc 100644 (file)
@@ -1,9 +1,9 @@
 $ ./test_server 12345 & ./test_client 127.0.0.1 12345
 Client ready; listening on 1024
 That's it, we sent the data to the server on 127.0.0.1
 $ ./test_server 12345 & ./test_client 127.0.0.1 12345
 Client ready; listening on 1024
 That's it, we sent the data to the server on 127.0.0.1
-[blaise:client:(23315) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(6454) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
 Cool, we received the message from 127.0.0.1:1024.
 Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23313) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(6452) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
 $ ./test_simulator platform.xml test.xml
 Client ready; listening on 1024
 That's it, we sent the data to the server on Jacquelin
 $ ./test_simulator platform.xml test.xml
 Client ready; listening on 1024
 That's it, we sent the data to the server on Jacquelin
index 15fbb14..1749ef2 100644 (file)
@@ -11,7 +11,6 @@ int server_hello_cb(gras_msg_cb_ctx_t ctx, void *payload) {
 
 int server(int argc, char *argv[]) {
   gras_socket_t mysock;   /* socket on which I listen */
 
 int server(int argc, char *argv[]) {
   gras_socket_t mysock;   /* socket on which I listen */
-  gras_socket_t toclient; /* socket used to write to the client */
   
   gras_init(&argc,argv);
 
   
   gras_init(&argc,argv);
 
index 2391af1..36c3e29 100644 (file)
@@ -1,9 +1,9 @@
 $ ./test_server 12345 & ./test_client 127.0.0.1 12345
 Client ready; listening on 1024
 That's it, we sent the data to the server on 127.0.0.1
 $ ./test_server 12345 & ./test_client 127.0.0.1 12345
 Client ready; listening on 1024
 That's it, we sent the data to the server on 127.0.0.1
-[blaise:client:(19066) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(7454) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
 Cool, we received the message from 127.0.0.1:1024.
 Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(19064) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(7452) 0.000004] gras/gras.c:79: [gras/INFO] Exiting GRAS
 $ ./test_simulator platform.xml test.xml
 Client ready; listening on 1024
 That's it, we sent the data to the server on Jacquelin
 $ ./test_simulator platform.xml test.xml
 Client ready; listening on 1024
 That's it, we sent the data to the server on Jacquelin
diff --git a/doc/gtut-files/5-globals.c b/doc/gtut-files/5-globals.c
new file mode 100644 (file)
index 0000000..3f551f4
--- /dev/null
@@ -0,0 +1,78 @@
+#include <gras.h>
+
+typedef struct {
+   int killed;
+} *server_data_t;
+   
+
+int server_kill_cb(gras_msg_cb_ctx_t ctx, void *payload) {
+  gras_socket_t client = gras_msg_cb_ctx_from(ctx);
+  server_data_t *globals=(server_data_t*)gras_userdata_get();
+   
+  fprintf(stderr,"Argh, killed by %s:%d! Bye folks...\n",
+         gras_socket_peer_name(client), gras_socket_peer_port(client));
+  
+  globals->killed = 1;
+   
+  return 1;
+} /* end_of_kill_callback */
+
+int server_hello_cb(gras_msg_cb_ctx_t ctx, void *payload) {
+  gras_socket_t client = gras_msg_cb_ctx_from(ctx);
+
+  fprintf(stderr,"Cool, we received the message from %s:%d.\n",
+         gras_socket_peer_name(client), gras_socket_peer_port(client));
+  
+  return 1;
+} /* end_of_hello_callback */
+
+int server(int argc, char *argv[]) {
+  gras_socket_t mysock;   /* socket on which I listen */
+  server_data_t globals;
+  
+  gras_init(&argc,argv);
+
+  globals=gras_userdata_new(server_data_t);
+  globals->killed=0;
+
+  gras_msgtype_declare("hello", NULL);
+  gras_msgtype_declare("kill", NULL);
+  mysock = gras_socket_server(atoi(argv[1]));
+   
+  gras_cb_register(gras_msgtype_by_name("hello"),&server_hello_cb);   
+  gras_cb_register(gras_msgtype_by_name("kill"),&server_kill_cb);
+
+  while (!globals->killed) {
+     gras_msg_handle(-1); /* blocking */
+  }
+    
+  gras_exit();
+  return 0;
+}
+
+int client(int argc, char *argv[]) {
+  gras_socket_t mysock;   /* socket on which I listen */
+  gras_socket_t toserver; /* socket used to write to the server */
+
+  gras_init(&argc,argv);
+
+  gras_msgtype_declare("hello", NULL);
+  gras_msgtype_declare("kill", NULL);
+  mysock = gras_socket_server_range(1024, 10000, 0, 0);
+  
+  fprintf(stderr,"Client ready; listening on %d\n", gras_socket_my_port(mysock));
+  
+  gras_os_sleep(1.5); /* sleep 1 second and half */
+  toserver = gras_socket_client(argv[1], atoi(argv[2]));
+  
+  gras_msg_send(toserver,gras_msgtype_by_name("hello"), NULL);
+  fprintf(stderr,"we sent the data to the server on %s. Let's do it again for fun\n", gras_socket_peer_name(toserver));
+  gras_msg_send(toserver,gras_msgtype_by_name("hello"), NULL);
+   
+  fprintf(stderr,"Ok. Enough. Have a rest, and then kill the server\n");
+  gras_os_sleep(5); /* sleep 1 second and half */
+  gras_msg_send(toserver,gras_msgtype_by_name("kill"), NULL);
+
+  gras_exit();
+  return 0;
+}
diff --git a/doc/gtut-files/5-globals.output b/doc/gtut-files/5-globals.output
new file mode 100644 (file)
index 0000000..d212c62
--- /dev/null
@@ -0,0 +1,22 @@
+$ ./test_server 12345 & ./test_client 127.0.0.1 12345
+Client ready; listening on 1024
+we sent the data to the server on 127.0.0.1. Let's do it again for fun
+Ok. Enough. Have a rest, and then kill the server
+Cool, we received the message from 127.0.0.1:1024.
+[blaise:client:(18581) 0.000005] gras/gras.c:79: [gras/INFO] Exiting GRAS
+Cool, we received the message from 127.0.0.1:1024.
+Argh, killed by 127.0.0.1:1024! Bye folks...
+$ ./test_simulator platform.xml test.xml
+Client ready; listening on 1024
+we sent the data to the server on Jacquelin. Let's do it again for fun
+Cool, we received the message from Boivin:1024.
+Ok. Enough. Have a rest, and then kill the server
+Cool, we received the message from Boivin:1024.
+[Boivin:client:(2) 0.000000] gras/gras.c:79: [gras/INFO] Exiting GRAS
+Argh, killed by Boivin:1024! Bye folks...
+[0.000000] msg/global.c:478: [msg_kernel/INFO] Oops ! Deadlock or code not perfectly clean.
+[0.000000] msg/global.c:293: [msg_kernel/INFO] MSG: 1 processes are still running, waiting for something.
+[0.000000] msg/global.c:295: [msg_kernel/INFO] MSG: <process>(<pid>) on <host>: <status>.
+[0.000000] msg/global.c:309: [msg_kernel/INFO] MSG:  server(1) on Jacquelin: [blocked]         Listening on channel 0
+[0.000000] msg/global.c:486: [msg_kernel/INFO] Return a Warning.
+$
index d762cd3..3e31aa6 100644 (file)
@@ -1,7 +1,8 @@
 # This works mainly on my box for now
 export LD_LIBRARY_PATH=$(GRAS_ROOT)/lib
 
 # This works mainly on my box for now
 export LD_LIBRARY_PATH=$(GRAS_ROOT)/lib
 
-all: 1-bones.output 2-simple.output 3-args.output 4-callback.output
+all: 1-bones.output 2-simple.output 3-args.output 4-callback.output \
+     5-globals.output
 
 veryclean: clean
        rm *.output
 
 veryclean: clean
        rm *.output
@@ -90,3 +91,25 @@ clean::
        if [ -e 4-callback.mk ] ; then make -f 4-callback.mk clean; fi
        rm -f _4-callback_client.c _4-callback_server.c _4-callback_simulator.c 4-callback.trace 4-callback.mk
 
        if [ -e 4-callback.mk ] ; then make -f 4-callback.mk clean; fi
        rm -f _4-callback_client.c _4-callback_server.c _4-callback_simulator.c 4-callback.trace 4-callback.mk
 
+# Lesson 5: globals
+########################################
+
+5-globals.output: 5-globals_client 5-globals_server 5-globals_simulator
+       echo '$$ ./test_server 12345 & ./test_client 127.0.0.1 12345'  > $@ 
+       ./5-globals_server 12345                                      >> $@ 2>&1&
+       ./5-globals_client 127.0.0.1 12345                            >> $@ 2>&1
+       sleep 1
+       echo '$$ ./test_simulator platform.xml test.xml'              >> $@
+       ./5-globals_simulator gtut-platform.xml 3-args.xml            >> $@ 2>&1
+       echo '$$'                                                     >> $@ 
+
+5-globals_client 5-globals_server 5-globals_simulator: _5-globals_client.c _5-globals_server.c _5-globals_simulator.c
+       make -f 5-globals.mk
+
+_5-globals_client.c _5-globals_server.c _5-globals_simulator.c: 5-globals.c 3-args.xml
+       ../../tools/gras/gras_stub_generator 5-globals 3-args.xml >/dev/null
+
+clean::
+       if [ -e 5-globals.mk ] ; then make -f 5-globals.mk clean; fi
+       rm -f _5-globals_client.c _5-globals_server.c _5-globals_simulator.c 5-globals.trace 5-globals.mk
+
diff --git a/doc/gtut-tour-1-bones.doc b/doc/gtut-tour-1-bones.doc
new file mode 100644 (file)
index 0000000..cd8a02b
--- /dev/null
@@ -0,0 +1,184 @@
+
+/** 
+@page GRAS_tut_tour_setup Lesson 1: Setting up your own project
+
+Any GRAS project should be constituted of at least 3 files, and possibly
+much more.
+
+  - <tt>&lt;project&gt;.c</tt>: A source file providing the source code of your
+    processes.
+    
+  - <tt>&lt;platform&gt;.xml</tt>: A platform description file. It describes
+    the virtual platform you want to run your application onto following the
+    SurfXML formatting so that the simulator can parse it. This file is only
+    needed in SG, and you don't need any to run on real platforms (of
+    course). The simplest is to use one of the pre-existing one.
+    
+  - <tt>&lt;project&gt;.xml</tt>: A deployment file. It describes which of
+    your processes to start, on which machine and with which arguments.
+    
+  - A makefile is often needed, too, even if it's not mandatory.
+
+If we start a project called <tt>test</tt>, we have to write 3 files:
+<tt>test.c</tt>, <tt>platform.xml</tt> and <tt>test.xml</tt>
+
+\section GRAS_tut_tour_setup_C The C source file
+
+Let's look at the C source file first. It should contain one main function
+for each type of processes in your overlay. Let's assume that you want to
+code a simple client/server communication. For this, the source file should
+read as:
+
+\verbatim #include <gras.h>
+
+int client(int argc, char *argv[]) {
+  ...
+}
+
+int server(int argc, char *argv[]) {
+  ...
+}
+\endverbatim
+
+Note that each of the processes's main function have the exact same
+prototype of the classical <tt>main()</tt> function in C. 
+
+This is on purpose, each of them can assume this role when running in RL.
+But you shouldn't write a main() function yourself since all processes will
+run as threads within the same regular process in simulation mode. That is
+why the real <tt>main</tt> function of GRAS programs are generated
+automatically. This will be detailled in time (section \ref
+GRAS_tut_tour_setup_glue), but for now just note the similarity between the
+"main" functions you have to write for each processes and a "real main"
+function.
+
+Then, each process must initialize the GRAS framework at the beginning (with
+\ref gras_init) and should finalize it at the end (with \ref gras_exit). 
+
+You should pass to \ref gras_init the <tt>argc</tt> and <tt>argv</tt> you
+received in your "main" function so that the users of your application can
+pass some configuration flags to the framework.
+
+It is not enough to have one of the processes initializing the framework
+since in RL, each of them will run on a different host. If you use some AMOK
+modules, you have to initialize them in each process too.
+
+The source file then reads: \include 1-bones.c
+
+That's it. You have a working GRAS application with two processes. They
+don't do anything useful, but that's a beginning. Let's see how to bring
+them to life.
+
+\section GRAS_tut_tour_setup_plat The platform file
+
+The platform file is used by the simulator to know about the existing hosts
+and their interactions. Its exact syntax is at the same time very simple and
+a bit beyond the topic of this document. Here is a very simple example
+describin two hosts named <i>Jacquelin</i> and <i>Boivin</i> and how they
+are interconnected.
+
+\include gtut-platform.xml
+
+At this point, you should not try to write your own platform file, but use
+one of the existing ones. There is a few of them in the examples/msg
+directory of the project. The only information we need from those files are
+the names of the existing hosts. It will be mandatory to write the
+deployment file.
+
+\section GRAS_tut_tour_setup_deploy The deployment file
+
+This file explains which of your processes should be started on the
+different hosts. It is mainly used in simulation. In real life, you will
+have to start your processes manually (see below). We we dream of a system
+able to apply a deployment file in real life and TakTuk may be the right
+tool for this, but this is still to be done.
+
+Here is an example of such file, describing that a <tt>server</tt> process
+must be started onto the <tt>Jacquelin</tt> host and a <tt>client</tt>
+process must be started on the <tt>Boivin</tt> host.
+
+\include test.xml
+
+Actually, you should write such a file also if you only plan to use GRAS in
+RL since this file is also used to glue your code to GRAS, as explained in
+the next section.
+
+\section GRAS_tut_tour_setup_glue Glueing things together
+
+As explained above, you shouldn't write any real <tt>main</tt> function
+since its content depends on whether you run in RL ou in SG. Instead, you
+use a tool <tt>gras_stub_generator</tt> to get the proper glue around your
+code generated. If you installed SimGrid in a regular place, this program is
+now in your path. Its source resides in the tools/gras/ directory of the
+archive, if you wonder.
+
+Here is the calling syntax:    
+\verbatim gras_stub_generator <project_name> <deployment_file.xml>\endverbatim
+
+It parses the deployment file (called <tt>test.xml</tt> in our example),
+searching for all the kind of processes you have in your project. It
+then generates the following C files:
+
+ - a <tt>_&lt;project_name&gt;_&lt;process_kind&gt;.c</tt> file for each process kind you
+   have.\n
+   They are used to launch your project in real life. They
+   contain a main() in charge of initializing the GRAS infrastructure and
+   launching your code afterward.
+ - a <tt>_&lt;project_name&gt;_simulator.c</tt> file.\n
+   This file is suited to the simulation mode. It contains a main()
+   function initializing the simulator and launching your project within.
+ - a <tt>&lt;project_name&gt;.mk</tt> file.\n
+   This is a makefile to regenerate any files on need. See next section.
+
+In our example, we will thus obtain <tt>_test_server.c</tt>,
+<tt>_test_client.c</tt>, <tt>_test_simulator.c</tt> and <tt>test.mk</tt>.
+
+There is a pitfall: no verification is made on your actual source code, so
+if you have a typo on the process name in the deployment file, the generated
+code will be wrong, and the linker will spit error messages at you. Also
+remember that those names are in fact C function names, so they are
+case-sensitive.
+
+\section GRAS_tut_tour_setup_make A typical Makefile
+
+Now, we want to compile all the source files to build the actual binaries.
+It can be done manually, but it is much more convenient to use a makefile.
+Fortunately, gras_stub_generator generates a makefile for you under the name
+<tt>&lt;project&gt;.mk</tt>. This file is sufficient for now. To compile our test
+application, just type:
+\verbatim make -f test.mk \endverbatim
+
+You may want to rename this file to Makefile so that typing <tt>make</tt>
+without argument becomes sufficient. In any case, do not edit this file
+without renaming it, or your changes will get overwritten at the next glue
+generation.
+
+If you already have a Makefile (or a Makefile.am for automake users), you
+can also add the following chunk at the end of your file:
+\verbatim NAME=your_project_name
+ PROCESSES=list of processes type in your project
+
+ $(foreach proc, $(PROCESSES), _$(NAME)_$(proc).c) _$(NAME)_simulator.c: $(NAME).c $(NAME)_deployment.xml
+        path/to/gras_stub_generator $(NAME) $(NAME)_deployment.xml >/dev/null
+\endverbatim
+
+A simpler solution in our example would be to add:
+\verbatim _test_client.c _test_server.c _test_simulator.c: test.c test.xml
+        path/to/gras_stub_generator test test.xml >/dev/null
+\endverbatim
+
+\section GRAS_tut_tour_setup_start Actually running the processes
+
+There is nothing to know to start your processes in RL. Simply call the
+generated binaries, and that's it. To start the simulation, simply call:
+\verbatim ./<project>_simulator platform.xml deployment.xml\endverbatim
+
+Here is an example of execution: \include 1-bones.output
+
+That's it. You are done with this lesson and can now write, build and
+execute GRAS applications as long as they don't do anything ;) Move
+to the next lessons to add some flesh on these bones.
+
+\ref GRAS_tut_tour_simpleexchange
+
+*/
diff --git a/doc/gtut-tour-2-simple.doc b/doc/gtut-tour-2-simple.doc
new file mode 100644 (file)
index 0000000..b7bb396
--- /dev/null
@@ -0,0 +1,117 @@
+
+/** 
+@page GRAS_tut_tour_simpleexchange Lesson 2: Exchanging simple messages
+
+\section GRAS_tut_tour_simpleexchange_msgtype Declaring the messages to be exchanged
+
+We will now see how to exchange messages between hosts. As explained in
+section \ref GRAS_tut_intro_model, every GRAS message is (strongly) typed. A
+message type is described by its name and the datatype of the data it can
+convey. Each process which may exchange a given type of message should
+declare it before sending or receiving it. If the description used by the
+sender doesn't match the one used by the receiver, you'll get into trouble.
+Fortunately, such discrepency will be detected in SG.
+
+We won't convey any payload in this lesson, so we just have to give the name
+of message to declare them:
+\dontinclude 2-simple.c
+\skip gras_msgtype_declare
+\until gras_msgtype_declare
+
+Remember that all processes should declare the message types they use.
+
+\section GRAS_tut_tour_simpleexchange_socks Identifying peers you want to communicate with
+
+Then, you need to specify with who you want to communicate. This is done
+by opening sockets. GRAS sockets are loosely inspirated by the regular BSD
+sockets, but with several simplifications.
+
+If you want to eventually receive messages, you have to open a so-called
+<i>server socket</i>. Actually, any GRAS process should open a server socket
+since it will allows to identify it uniquely in the system. A socket is
+defined by an host name and a port number (just like with BSD sockets).
+
+Since server socket are on the current host, opening a socket to receive
+messages on the port 12345 is as easy as:
+\skip gras_socket_server
+\until gras_socket_server
+
+Hardcoding port numbers that way may lead to difficulties on RL (at least)
+since at most one process can listen on a given port. So, if you can, prefer
+the \ref gras_socket_server_range, which picks a working port from a range
+of value. Of course, if you want your processes to find each others, at
+least one port must be hardcoded in the system. Then, any other processes
+contact the one listening on that port, which acts as a coordinator.
+
+Our client should also open a server socket, but the picked port don't
+matter, so we use:
+\skip gras_socket_server
+\until gras_socket_server
+
+It will select a port between 1024 (ports below 1024 are reserved under
+UNIX) and 10000. You can safely ignore the two last arguments for now and
+pass 0.
+
+So, you now know how to create sockets allowing to receive messages. To send
+messages, you have to create a so-called <i>client socket</i>. For this, use
+\ref gras_socket_client with the hostname and the port of the process you
+want to contact as arguments. Our client should simply do:
+
+\dontinclude 2-simple.c
+\skip socket_client
+\until socket_client
+
+The corresponding server socket must be opened before any client socket can
+connect to it. It is thus safe to add a little delay before creating the
+client socket. But you cannot use the classical sleep() function for this,
+or you will delay the simulator in SG, not your processes. Use \ref
+gras_os_sleep instead.
+
+\section GRAS_tut_tour_simpleexchange_exchange Actually exchanging messages
+
+GRAS offers a plenty of ways to communicate. The simple one is to use \ref
+gras_msg_send on the sender side, and \ref gras_msg_wait on the receiver side.
+
+\ref gras_msg_send expects 3 arguments: the socket on which to send the
+message, the message type, and a pointer to the actual content of the
+message. The simplest way to retrive a message type from its name is to use
+\ref gras_msgtype_by_name. Since we don't have any payload, this becomes:
+
+\dontinclude 2-simple.c
+\skip msg_send
+\until msg_send
+
+\ref gras_msg_wait accepts 4 arguments. The first one is the delay you are
+disposed to wait for messages, while the the type of message you are
+expecting. Then come output arguments. The third argument should be the
+address of a gras_socket_t variable which will indicate who wrote the
+message you received while the last argument is where to put the payload.
+
+Since our server is willing to wait up to 60 seconds for a message, the
+following will do it:
+\dontinclude 2-simple.c
+\skip msg_wait
+\until msg_wait
+
+\section GRAS_tut_tour_simpleexchange_recaping Recaping everything together
+
+Here is the complete code of this example. Note the use of the functions
+\ref gras_socket_my_port, \ref gras_socket_peer_name and \ref
+gras_socket_peer_port to retrieve information about who you are connected to.
+
+\include 2-simple.c
+
+Here is the output of the simulator. Note that \ref gras_socket_peer_port
+actually returns the port number of the <i>server</i> of the peer. This may
+sound a bit strange to BSD experts, but it is actually really useful: you
+can store this value, and contact your peer afterward passing this number to
+\ref gras_socket_client .
+\include 2-simple.output
+
+Here we are, you now know how to exchange messages between peers. There is
+still a large room for improvement, such as adding payload to messages. But
+there some little things you should know before we speak of payloads.
+
+\ref GRAS_tut_tour_args
+
+*/
diff --git a/doc/gtut-tour-3-args.doc b/doc/gtut-tour-3-args.doc
new file mode 100644 (file)
index 0000000..9ea0056
--- /dev/null
@@ -0,0 +1,42 @@
+
+/** 
+@page GRAS_tut_tour_args Lesson 3: Passing arguments to the processes (in SG)
+
+The most problematic issue with the code of previous lesson is that it does
+not work in RL since we hardcoded the server hostname in the client code. We
+will thus learn you how to pass arguments to your processes to overcome this
+situation.
+
+\section GRAS_tut_tour_args_use Using command line arguments from user code
+
+In RL, the situation is quite simple: we just have to use the command line
+arguments as we would do in a usual C program. In the server, only change
+concern the opennong of the master socket:
+\dontinclude 3-args.c
+\skip gras_socket_server
+\until gras_socket_server
+
+In the client, we only need to change the way we open the client socket:
+\skip gras_socket_client
+\until gras_socket_client
+
+The rest of the program remains inchanged. 
+
+\section GRAS_tut_tour_args_sg Passing command line arguments in deployment files
+
+At this point, the problem is to pass arguments to the processes in SG.
+Fortunately, it is quite simple. You just have to edit your deployment file
+so that it reads: \include 3-args.xml
+The syntax should be self-explanatory at this point.
+
+\section GRAS_tut_tour_args_recap Recaping everything together
+
+The whole program now reads:
+\include 3-args.c
+
+And here is the output:
+\include 3-args.output
+
+\ref GRAS_tut_tour_callbacks
+
+*/
diff --git a/doc/gtut-tour-4-callback.doc b/doc/gtut-tour-4-callback.doc
new file mode 100644 (file)
index 0000000..82ff587
--- /dev/null
@@ -0,0 +1,76 @@
+
+/** 
+@page GRAS_tut_tour_callbacks Lesson 4: Attaching callbacks to messages
+
+Our program is well and good, but if we had to write a longer program,
+explicitely waiting for messages of a given type would not be really
+practical. To add some more dynamism, what we want to do is to attach
+callbacks to the several messages types, and tell GRAS that we are ready to
+deal with new messages. That's what we will do now.
+
+\section GRAS_tut_tour_callbacks_declare Declaring callbacks
+
+First of all, we define the callback we want to attach to the arrival of the
+"hello" message on the server. Its signature is fixed: it accepts two
+arguments of relative types <tt>gras_msg_cb_ctx_t ctx</tt> and <tt>void
+*</tt>. The first one is a working context we should pass to GRAS when
+speaking about the message we are handling while the second is the payload.
+The callbackreturns an integer indicating whether we managed to deal with
+the message. I admit that this semantic is a bit troublesome, it should be 0
+if we managed to deal properly with the message to mimic "main()" semantic.
+That's historical, but I may change this in the future (no worry, I'll add
+backward compatibility solutions). Here is the actual code of our callback:
+
+\dontinclude 4-callback.c
+\skip gras_msg_cb_ctx_t 
+\until end_of_callback
+
+\section GRAS_tut_tour_callbacks_attach Attaching callbacks
+
+Then, we have to change the server code to use this callback instead of
+gras_msg_wait. This simply done by a construct like the following:
+
+\skip cb_register
+\until cb_register
+
+\section GRAS_tut_tour_callbacks_handle Handling incoming messages
+
+Once the callback is declared and attached, the server simply has to call
+\ref gras_msg_handle to tell GRAS it's ready to handle for incoming
+messages. The only argument is the maximum delay we are disposed to wait for
+a message. If the delay is negative, the process will block until a message
+arrives. With delay=0, the process just polls for already arrived messages,
+but do not wait at all if none arrived yet. If the delay is greater than 0,
+the process will wait for at most that amount of seconds. If a message
+arrives in the meanwhile, it won't even wait that long. 
+
+Sometimes, you want to handle all messages arriving in a given period
+without really knowing how much messages will come (this is often the case
+during the initialization phase of an algorithm). In that case, use \ref
+gras_msg_handleall . It has the same prototype than \ref gras_msg_handle,
+but waits exactly the passed delay, dealing with all the messages arriving
+in the meanwhile.
+
+We have no such needs in our example, so the code simply reads:
+\skip handle
+\until handle
+
+\section GRAS_tut_tour_callback_recap Recaping everything together
+
+The whole program now reads:
+\include 4-callback.c
+
+And here is the output (unchanged wrt previous version):
+\include 4-callback.output
+
+Our little example turns slowly to a quite advanced GRAS program. It entails
+most of the mecanism most program will use. 
+
+There is one last thing you should know about callbacks: you can stack them,
+ie attach several callbacks to the same message. GRAS will pass it to the
+lastly attached first, and if the return value is 0, it will pass it also to
+the next one, and so on. I'm not sure there is any sensible use of this
+feature, but it's possible ;)
+
+\ref GRAS_tut_tour_globals
+*/
diff --git a/doc/gtut-tour-5-globals.doc b/doc/gtut-tour-5-globals.doc
new file mode 100644 (file)
index 0000000..641cecd
--- /dev/null
@@ -0,0 +1,82 @@
+/**
+@page GRAS_tut_tour_globals Lesson 5: Using globals in processes
+
+Callbacks are great to express your processes as state machines, but they
+pose another problem: callbacks don't have acces to the variable declared
+within the scope of the process' main function (of course). You should
+however resist to the temptation to declare globals outside of the scope of
+the functions, or you won't be able to use more than one process of each
+type in the simulation. Remember, all gras processes run as thread
+within the same naming space in SG so your globals will be shared between
+the several instances of your process, leading to bad problems.
+
+Instead, you you have to put all globals in a structure, and let GRAS handle
+it with the gras_userdata_* functions (there is only 3 of them ;). 
+
+We will now modify the example to add a "kill" message, and let the server
+loop on incoming messages until it gets such a message. We only need a
+boolean, so the structure is quite simple: 
+\dontinclude 5-globals.c
+\skip struct
+\until server_data
+Then, we need to create this structure in the process main function. We
+could use either gras_userdata_new() or gras_userdata_set(). The former is an
+helper macro mallocing the space needed by the structure and passing it to
+gras using the latter function. If you go for gras_userdata_set(), you
+should pass it a pointer to your data you want to retrieve afterward.
+
+\dontinclude 5-globals.c
+\skip userdata_new
+\until userdata_new
+
+Once you declared a global that way, retriving this (for example in a
+callback) is really easy:
+\dontinclude 5-globals.c
+\skip userdata_get
+\until userdata_get
+
+We can now write the callback, which simply retrive the globals and change
+the value of the <tt>kileld</tt> field.
+\dontinclude 5-globals.c
+\skip kill_cb
+\until end_of_kill_callback
+
+And we replace the single gras_msg_handle() of the server main function by a
+loop:
+\skip while
+\until }
+
+\section GRAS_tut_tour_callback_pitfall Common pitfall of globals
+
+There is an error that I do myself every other day using globals in GRAS.
+This is to write something like:
+\verbatim int server(int argc, char *argv[]) {
+  server_data_t globals=gras_user_new(server_data_t);
+  /* other variable definition */
+  
+  gras_init(&argc, argv);
+  
+  /* rest of the code */
+}\endverbatim
+
+The problem is that you call gras_userdata_new() before gras_init(). Doing so,
+embarass GRAS since it does not have its internal buffer initialized yet,
+and cannot store your data anywhere. That is why doing so triggers an error
+at run time.
+
+\section GRAS_tut_tour_callback_recap Recaping everything together
+
+The whole program now reads:
+\include 5-globals.c
+
+And here is the output (unchanged wrt previous version):
+\include 5-globals.output
+
+That's it, we're done. We have a server able to handle any number of
+messages, which the client can stop remotely properly. That's already
+something, hu?
+
+\ref GRAS_tut_tour_timer
+
+*/
index efd7935..8db2d2f 100644 (file)
 /** 
 @page GRAS_tut_tour GRAS initiatic tour
 
 /** 
 @page GRAS_tut_tour GRAS initiatic tour
 
-On this page, you will learn all you need to write your own GRAS
-applications, from the installation of the framework to the use of all
-features available in GRAS.
-
-\htmlinclude .gtut-tour.doc.toc
-   
-<hr>
-\section GRAS_tut_tour_install Lesson 0: Installing GRAS
-
-Since GRAS is technically part of the SimGrid project, you have to install
-SimGrid to install GRAS. Doing so is explained in the relevant FAQ section
-(\ref faq_installation). 
-
-Newcommers should install the stable release from the tarball, since the cvs
-snapshots may suffer from (additionnal;) stability issues. Only go for the CVS if you
-really need features not present in the stable releases yet.
-
-<hr>
-\section GRAS_tut_tour_setup Lesson 1: Setting up your own project
-
-Any GRAS project should be constituted of at least 3 files, and possibly
-much more.
-
-  - <tt>&lt;project&gt;.c</tt>: A source file providing the source code of your
-    processes.
-    
-  - <tt>&lt;platform&gt;.xml</tt>: A platform description file. It describes
-    the virtual platform you want to run your application onto following the
-    SurfXML formatting so that the simulator can parse it. This file is only
-    needed in SG, and you don't need any to run on real platforms (of
-    course). The simplest is to use one of the pre-existing one.
-    
-  - <tt>&lt;project&gt;.xml</tt>: A deployment file. It describes which of
-    your processes to start, on which machine and with which arguments.
-    
-  - A makefile is often needed, too, even if it's not mandatory.
-
-If we start a project called <tt>test</tt>, we have to write 3 files:
-<tt>test.c</tt>, <tt>platform.xml</tt> and <tt>test.xml</tt>
-
-\subsection GRAS_tut_tour_setup_C The C source file
-
-Let's look at the C source file first. It should contain one main function
-for each type of processes in your overlay. Let's assume that you want to
-code a simple client/server communication. For this, the source file should
-read as:
-
-\verbatim #include <gras.h>
-
-int client(int argc, char *argv[]) {
-  ...
-}
-
-int server(int argc, char *argv[]) {
-  ...
-}
-\endverbatim
-
-Note that each of the processes's main function have the exact same
-prototype of the classical <tt>main()</tt> function in C. 
-
-This is on purpose, each of them can assume this role when running in RL.
-But you shouldn't write a main() function yourself since all processes will
-run as threads within the same regular process in simulation mode. That is
-why the real <tt>main</tt> function of GRAS programs are generated
-automatically. This will be detailled in time (section \ref
-GRAS_tut_tour_setup_glue), but for now just note the similarity between the
-"main" functions you have to write for each processes and a "real main"
-function.
-
-Then, each process must initialize the GRAS framework at the beginning (with
-\ref gras_init) and should finalize it at the end (with \ref gras_exit). 
-
-You should pass to \ref gras_init the <tt>argc</tt> and <tt>argv</tt> you
-received in your "main" function so that the users of your application can
-pass some configuration flags to the framework.
-
-It is not enough to have one of the processes initializing the framework
-since in RL, each of them will run on a different host. If you use some AMOK
-modules, you have to initialize them in each process too.
-
-The source file then reads: \include 1-bones.c
-
-That's it. You have a working GRAS application with two processes. They
-don't do anything useful, but that's a beginning. Let's see how to bring
-them to life.
-
-\subsection GRAS_tut_tour_setup_plat The platform file
-
-The platform file is used by the simulator to know about the existing hosts
-and their interactions. Its exact syntax is at the same time very simple and
-a bit beyond the topic of this document. Here is a very simple example
-describin two hosts named <i>Jacquelin</i> and <i>Boivin</i> and how they
-are interconnected.
-
-\include gtut-platform.xml
-
-At this point, you should not try to write your own platform file, but use
-one of the existing ones. There is a few of them in the examples/msg
-directory of the project. The only information we need from those files are
-the names of the existing hosts. It will be mandatory to write the
-deployment file.
-
-\subsection GRAS_tut_tour_setup_deploy The deployment file
-
-This file explains which of your processes should be started on the
-different hosts. It is mainly used in simulation. In real life, you will
-have to start your processes manually (see below). We we dream of a system
-able to apply a deployment file in real life and TakTuk may be the right
-tool for this, but this is still to be done.
-
-Here is an example of such file, describing that a <tt>server</tt> process
-must be started onto the <tt>Jacquelin</tt> host and a <tt>client</tt>
-process must be started on the <tt>Boivin</tt> host.
-
-\include test.xml
-
-Actually, you should write such a file also if you only plan to use GRAS in
-RL since this file is also used to glue your code to GRAS, as explained in
-the next section.
-
-\subsection GRAS_tut_tour_setup_glue Glueing things together
-
-As explained above, you shouldn't write any real <tt>main</tt> function
-since its content depends on whether you run in RL ou in SG. Instead, you
-use a tool <tt>gras_stub_generator</tt> to get the proper glue around your
-code generated. If you installed SimGrid in a regular place, this program is
-now in your path. Its source resides in the tools/gras/ directory of the
-archive, if you wonder.
-
-Here is the calling syntax:    
-\verbatim gras_stub_generator <project_name> <deployment_file.xml>\endverbatim
-
-It parses the deployment file (called <tt>test.xml</tt> in our example),
-searching for all the kind of processes you have in your project. It
-then generates the following C files:
-
- - a <tt>_&lt;project_name&gt;_&lt;process_kind&gt;.c</tt> file for each process kind you
-   have.\n
-   They are used to launch your project in real life. They
-   contain a main() in charge of initializing the GRAS infrastructure and
-   launching your code afterward.
- - a <tt>_&lt;project_name&gt;_simulator.c</tt> file.\n
-   This file is suited to the simulation mode. It contains a main()
-   function initializing the simulator and launching your project within.
- - a <tt>&lt;project_name&gt;.mk</tt> file.\n
-   This is a makefile to regenerate any files on need. See next section.
-
-In our example, we will thus obtain <tt>_test_server.c</tt>,
-<tt>_test_client.c</tt>, <tt>_test_simulator.c</tt> and <tt>test.mk</tt>.
-
-There is a pitfall: no verification is made on your actual source code, so
-if you have a typo on the process name in the deployment file, the generated
-code will be wrong, and the linker will spit error messages at you. Also
-remember that those names are in fact C function names, so they are
-case-sensitive.
-
-\subsection GRAS_tut_tour_setup_make A typical Makefile
-
-Now, we want to compile all the source files to build the actual binaries.
-It can be done manually, but it is much more convenient to use a makefile.
-Fortunately, gras_stub_generator generates a makefile for you under the name
-<tt>&lt;project&gt;.mk</tt>. This file is sufficient for now. To compile our test
-application, just type:
-\verbatim make -f test.mk \endverbatim
-
-You may want to rename this file to Makefile so that typing <tt>make</tt>
-without argument becomes sufficient. In any case, do not edit this file
-without renaming it, or your changes will get overwritten at the next glue
-generation.
-
-If you already have a Makefile (or a Makefile.am for automake users), you
-can also add the following chunk at the end of your file:
-\verbatim NAME=your_project_name
- PROCESSES=list of processes type in your project
-
- $(foreach proc, $(PROCESSES), _$(NAME)_$(proc).c) _$(NAME)_simulator.c: $(NAME).c $(NAME)_deployment.xml
-        path/to/gras_stub_generator $(NAME) $(NAME)_deployment.xml >/dev/null
-\endverbatim
-
-A simpler solution in our example would be to add:
-\verbatim _test_client.c _test_server.c _test_simulator.c: test.c test.xml
-        path/to/gras_stub_generator test test.xml >/dev/null
-\endverbatim
-
-
-
-\subsection GRAS_tut_tour_setup_start Actually running the processes
-
-There is nothing to know to start your processes in RL. Simply call the
-generated binaries, and that's it. To start the simulation, simply call:
-\verbatim ./<project>_simulator platform.xml deployment.xml\endverbatim
-
-Here is an example of execution: \include 1-bones.output
-
-That's it. You are done with this lesson and can now write, build and
-execute GRAS applications as long as they don't do anything ;) Simply read on
-to add some flesh on these bones.
-
-(back to the top of the \ref GRAS_tut_tour)
-<hr>
-
-\section GRAS_tut_tour_simpleexchange Lesson 2: Exchanging simple messages
-
-\subsection GRAS_tut_tour_simpleexchange_msgtype Declaring the messages to be exchanged
-
-We will now see how to exchange messages between hosts. As explained in
-section \ref GRAS_tut_intro_model, every GRAS message is (strongly) typed. A
-message type is described by its name and the datatype of the data it can
-convey. Each process which may exchange a given type of message should
-declare it before sending or receiving it. If the description used by the
-sender doesn't match the one used by the receiver, you'll get into trouble.
-Fortunately, such discrepency will be detected in SG.
-
-We won't convey any payload in this lesson, so we just have to give the name
-of message to declare them:
-\dontinclude 2-simple.c
-\skip gras_msgtype_declare
-\until gras_msgtype_declare
-
-Remember that all processes should declare the message types they use.
-
-\subsection GRAS_tut_tour_simpleexchange_socks Identifying peers you want to communicate with
-
-Then, you need to specify with who you want to communicate. This is done
-by opening sockets. GRAS sockets are loosely inspirated by the regular BSD
-sockets, but with several simplifications.
-
-If you want to eventually receive messages, you have to open a so-called
-<i>server socket</i>. Actually, any GRAS process should open a server socket
-since it will allows to identify it uniquely in the system. A socket is
-defined by an host name and a port number (just like with BSD sockets).
-
-Since server socket are on the current host, opening a socket to receive
-messages on the port 12345 is as easy as:
-\skip gras_socket_server
-\until gras_socket_server
-
-Hardcoding port numbers that way may lead to difficulties on RL (at least)
-since at most one process can listen on a given port. So, if you can, prefer
-the \ref gras_socket_server_range, which picks a working port from a range
-of value. Of course, if you want your processes to find each others, at
-least one port must be hardcoded in the system. Then, any other processes
-contact the one listening on that port, which acts as a coordinator.
-
-Our client should also open a server socket, but the picked port don't
-matter, so we use:
-\skip gras_socket_server
-\until gras_socket_server
-
-It will select a port between 1024 (ports below 1024 are reserved under
-UNIX) and 10000. You can safely ignore the two last arguments for now and
-pass 0.
-
-So, you now know how to create sockets allowing to receive messages. To send
-messages, you have to create a so-called <i>client socket</i>. For this, use
-\ref gras_socket_client with the hostname and the port of the process you
-want to contact as arguments. Our client should simply do:
-
-\dontinclude 2-simple.c
-\skip socket_client
-\until socket_client
-
-The corresponding server socket must be opened before any client socket can
-connect to it. It is thus safe to add a little delay before creating the
-client socket. But you cannot use the classical sleep() function for this,
-or you will delay the simulator in SG, not your processes. Use \ref
-gras_os_sleep instead.
-
-\subsection GRAS_tut_tour_simpleexchange_exchange Actually exchanging messages
-
-GRAS offers a plenty of ways to communicate. The simple one is to use \ref
-gras_msg_send on the sender side, and \ref gras_msg_wait on the receiver side.
-
-\ref gras_msg_send expects 3 arguments: the socket on which to send the
-message, the message type, and a pointer to the actual content of the
-message. The simplest way to retrive a message type from its name is to use
-\ref gras_msgtype_by_name. Since we don't have any payload, this becomes:
-
-\dontinclude 2-simple.c
-\skip msg_send
-\until msg_send
-
-\ref gras_msg_wait accepts 4 arguments. The first one is the delay you are
-disposed to wait for messages, while the the type of message you are
-expecting. Then come output arguments. The third argument should be the
-address of a gras_socket_t variable which will indicate who wrote the
-message you received while the last argument is where to put the payload.
-
-Since our server is willing to wait up to 60 seconds for a message, the
-following will do it:
-\dontinclude 2-simple.c
-\skip msg_wait
-\until msg_wait
-
-\subsection GRAS_tut_tour_simpleexchange_recaping Recaping everything together
-
-Here is the complete code of this example. Note the use of the functions
-\ref gras_socket_my_port, \ref gras_socket_peer_name and \ref
-gras_socket_peer_port to retrieve information about who you are connected to.
-
-\include 2-simple.c
-
-Here is the output of the simulator. Note that \ref gras_socket_peer_port
-actually returns the port number of the <i>server</i> of the peer. This may
-sound a bit strange to BSD experts, but it is actually really useful: you
-can store this value, and contact your peer afterward passing this number to
-\ref gras_socket_client .
-\include 2-simple.output
-
-Here we are, you now know how to exchange messages between peers. There is
-still a large room for improvement, such as adding payload to messages.
-
-
-(back to the top of the \ref GRAS_tut_tour)
-<hr>
-\section GRAS_tut_tour_args Lesson 3: Passing arguments to the processes (in SG)
-
-The most problematic issue with the code of previous lesson is that it does
-not work in RL since we hardcoded the server hostname in the client code. We
-will thus learn you how to pass arguments to your processes to overcome this
-situation.
-
-\subsection GRAS_tut_tour_args_use Using command line arguments from user code
-
-In RL, the situation is quite simple: we just have to use the command line
-arguments as we would do in a usual C program. In the server, only change
-concern the opennong of the master socket:
-\dontinclude 3-args.c
-\skip gras_socket_server
-\until gras_socket_server
-
-In the client, we only need to change the way we open the client socket:
-\skip gras_socket_client
-\until gras_socket_client
-
-The rest of the program remains inchanged. 
-
-\subsection GRAS_tut_tour_args_sg Passing command line arguments in deployment files
-
-At this point, the problem is to pass arguments to the processes in SG.
-Fortunately, it is quite simple. You just have to edit your deployment file
-so that it reads: \include 3-args.xml
-The syntax should be self-explanatory at this point.
-
-\subsection GRAS_tut_tour_args_recap Recaping everything together
-
-The whole program now reads:
-\include 3-args.c
-
-And here is the output:
-\include 3-args.output
-
-(back to the top of the \ref GRAS_tut_tour)
-<hr>
-
-\section GRAS_tut_tour_callbacks Lesson 4: Attaching callbacks to messages
-
-Our program is well and good, but if we had to write a longer message,
-explicitely waiting for messages of a given type would not be really
-practical. To add some more dynamism, what we want to do is to attach
-callbacks to the several messages types, and tell GRAS that we are ready to
-deal with new messages. That's what we will do now.
-
-\subsection GRAS_tut_tour_callbacks_declare Declaring callbacks
-
-First of all, we define the callback we want to attach to the arrival of the
-"hello" message on the server. Its signature is fixed: it accepts two
-arguments of relative types <tt>gras_msg_cb_ctx_t ctx</tt> and <tt>void
-*</tt>. The first one is a working context we should pass to GRAS when
-speaking about the message we are handling while the second is the payload.
-The callbackreturns an integer indicating whether we managed to deal with
-the message. I admit that this semantic is a bit troublesome, it should be 0
-if we managed to deal properly with the message to mimic "main()" semantic.
-That's historical, but I may change this in the future (no worry, I'll add
-backward compatibility solutions). Here is the actual code of our callback:
-
-\dontinclude 4-callback.c
-\skip gras_msg_cb_ctx_t 
-\until end_of_callback
-
-\subsection GRAS_tut_tour_callbacks_attach Attaching callbacks
-
-Then, we have to change the server code to use this callback instead of
-gras_msg_wait. This simply done by a construct like the following:
-
-\skip cb_register
-\until cb_register
-
-\subsection GRAS_tut_tour_callbacks_handle Handling incoming messages
-
-Once the callback is declared and attached, the server simply has to call
-\ref gras_msg_handle to tell GRAS it's ready to handle for incoming
-messages. The only argument is the maximum delay we are disposed to wait for
-a message. If the delay is negative, the process will block until a message
-arrives. With delay=0, the process just polls for already arrived messages,
-but do not wait at all if none arrived yet. If the delay is greater than 0,
-the process will wait for at most that amount of seconds. If a message
-arrives in the meanwhile, it won't even wait that long. 
-
-Sometimes, you want to handle all messages arriving in a given period
-without really knowing how much messages will come (this is often the case
-during the initialization phase of an algorithm). In that case, use \ref
-gras_msg_handleall . It has the same prototype than \ref gras_msg_handle,
-but waits exactly the passed delay, dealing with all the messages arriving
-in the meanwhile.
-
-We have no such needs in our example, so the code simply reads:
-\skip handle
-\until handle
-
-\subsection GRAS_tut_tour_callback_recap Recaping everything together
-
-The whole program now reads:
-\include 4-callback.c
-
-And here is the output (unchanged wrt previous version):
-\include 4-callback.output
-
-Our little example turns slowly to a quite advanced GRAS program. It entails
-most of the mecanism most program will use.
-
-(back to the top of the \ref GRAS_tut_tour)
+During this tour, you will learn all you need to write your own GRAS
+applications, from the installation of the framework to the use of (almost)
+all features available in GRAS.
+
+    \htmlonly <!-- 
+      DOXYGEN_NAVBAR_CHILD "0: Installing"=GRAS_tut_tour_install.html
+      DOXYGEN_NAVBAR_CHILD "1: Setup a project"=GRAS_tut_tour_setup.html
+      DOXYGEN_NAVBAR_CHILD "2: Simple messaging"=GRAS_tut_tour_simpleexchange.html
+      DOXYGEN_NAVBAR_CHILD "3: Process args"=GRAS_tut_tour_args.html
+      DOXYGEN_NAVBAR_CHILD "4: Callbacks"=GRAS_tut_tour_callbacks.html
+      DOXYGEN_NAVBAR_CHILD "5: Callbacks"=GRAS_tut_tour_globals.html
+    --> \endhtmlonly
+
+ - \ref GRAS_tut_tour_install
+ - \ref GRAS_tut_tour_setup
+ - \ref GRAS_tut_tour_simpleexchange
+ - \ref GRAS_tut_tour_args
+ - \ref GRAS_tut_tour_callbacks
+ - \ref GRAS_tut_tour_globals
 <hr>
 
 
 \section GRAS_tut_tour_todo TODO
 
 <hr>
 
 
 \section GRAS_tut_tour_todo TODO
 
+Unfortunately, the tour is not terminated yet, and here are some ideas of
+missing missi^W lessons:
+
 - Lesson 5: Globals (for a kill message)
 - Lesson 6: Timers
 - Lesson 7: Using logs
 - Lesson 5: Globals (for a kill message)
 - Lesson 6: Timers
 - Lesson 7: Using logs
@@ -446,3 +46,17 @@ most of the mecanism most program will use.
 - Lesson   : Doing proper modules
 
 */
 - Lesson   : Doing proper modules
 
 */
+
+/** 
+@page GRAS_tut_tour_install Lesson 0: Installing GRAS
+
+Since GRAS is technically part of the SimGrid project, you have to install
+SimGrid to install GRAS. Doing so is explained in the relevant FAQ section
+(\ref faq_installation). 
+
+Newcommers should install the stable release from the tarball, since the cvs
+snapshots may suffer from (additionnal;) stability issues. Only go for the
+CVS if you really need features not present in the stable releases yet (or
+if you plan to help us improving the tool, what is always welcomed).
+
+*/