Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
TOCs update
[simgrid.git] / doc / gtut-tour-05-globals.doc
1 /**
2 @page GRAS_tut_tour_globals Lesson 5: Using globals in processes
3
4 \section GRAS_tut_tour_globals_toc Table of Contents
5  - \ref GRAS_tut_tour_globals_intro
6  - \ref GRAS_tut_tour_globals_use
7  - \ref GRAS_tut_tour_callback_pitfall
8  - \ref GRAS_tut_tour_callback_recap
9     
10 <hr>
11
12 \section GRAS_tut_tour_globals_intro Introduction
13
14 Callbacks are great to express your processes as state machines, but they
15 pose another problem: callbacks don't have acces to the variable declared
16 within the scope of the process' main function (of course). You should
17 however resist to the temptation to declare globals outside of the scope of
18 the functions, or you won't be able to use more than one process of each
19 type in the simulation. Remember, all gras processes run as thread
20 within the same naming space in SG so your globals will be shared between
21 the several instances of your process, leading to bad problems.
22
23 Instead, you you have to put all globals in a structure, and let GRAS handle
24 it with the gras_userdata_* functions (there is only 3 of them ;). 
25
26 \section GRAS_tut_tour_globals_use Putting globals into action
27
28 We will now modify the example to add a "kill" message, and let the server
29 loop on incoming messages until it gets such a message. We only need a
30 boolean, so the structure is quite simple: 
31 \dontinclude 05-globals.c
32 \skip struct
33 \until server_data
34  
35 Then, we need to create this structure in the process main function. We
36 could use either gras_userdata_new() or gras_userdata_set(). The former is an
37 helper macro mallocing the space needed by the structure and passing it to
38 gras using the latter function. If you go for gras_userdata_set(), you
39 should pass it a pointer to your data you want to retrieve afterward.
40
41 \dontinclude 05-globals.c
42 \skip userdata_new
43 \until userdata_new
44
45 Once you declared a global that way, retriving this (for example in a
46 callback) is really easy:
47 \dontinclude 05-globals.c
48 \skip userdata_get
49 \until userdata_get
50
51 We can now write the callback, which simply retrive the globals and change
52 the value of the <tt>kileld</tt> field.
53 \dontinclude 05-globals.c
54 \skip kill_cb
55 \until end_of_kill_callback
56
57 And we replace the single gras_msg_handle() of the server main function by a
58 loop:
59 \skip while
60 \until }
61
62 \section GRAS_tut_tour_callback_pitfall Common pitfall of globals
63
64 There is an error that I do myself every other day using globals in GRAS.
65 This is to write something like:
66 \verbatim int server(int argc, char *argv[]) {
67   server_data_t globals=gras_user_new(server_data_t);
68   /* other variable definition */
69   
70   gras_init(&argc, argv);
71   
72   /* rest of the code */
73 }\endverbatim
74
75 The problem is that you call gras_userdata_new() before gras_init(). Doing so,
76 embarass GRAS since it does not have its internal buffer initialized yet,
77 and cannot store your data anywhere. That is why doing so triggers an error
78 at run time.
79
80 \section GRAS_tut_tour_callback_recap Recaping everything together
81
82 The whole program now reads:
83 \include 05-globals.c
84
85 And here is the output (unchanged wrt previous version):
86 \include 05-globals.output
87
88 That's it, we're done. We have a server able to handle any number of
89 messages, which the client can stop remotely properly. That's already
90 something, hu?
91
92 Go to \ref GRAS_tut_tour_logs
93
94 */