Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Massive file renaming (stupid CVS) so that we can have more than 9 lessons and still...
[simgrid.git] / doc / gtut-tour-05-globals.doc
diff --git a/doc/gtut-tour-05-globals.doc b/doc/gtut-tour-05-globals.doc
new file mode 100644 (file)
index 0000000..b0bb570
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+@page GRAS_tut_tour_globals Lesson 5: Using globals in processes
+
+\section GRAS_tut_tour_globals_toc Table of Contents
+ - \ref GRAS_tut_tour_globals_intro
+ - \ref GRAS_tut_tour_globals_use
+ - \ref GRAS_tut_tour_callback_pitfall
+ - \ref GRAS_tut_tour_callback_recap
+    
+<hr>
+
+\section GRAS_tut_tour_globals_intro Introduction
+
+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 ;). 
+
+\section GRAS_tut_tour_globals_use Putting globals into action
+
+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 05-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 05-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 05-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 05-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 05-globals.c
+
+And here is the output (unchanged wrt previous version):
+\include 05-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?
+
+Go to \ref GRAS_tut_tour_logs
+
+*/