Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Update with Ghislain's publication.
[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 BEWARE, the gras_userdata_new expects the pointed type, not the
46 pointer type. As you can see, in our example, you should pass
47 server_data_t to the macro, even if the global variable is later
48 defined as being of type server_data_t*.
49
50 Once you declared a global that way, retriving this (for example in a
51 callback) is really easy:
52 \dontinclude 05-globals.c
53 \skip userdata_get
54 \until userdata_get
55
56 We can now write the callback, which simply retrive the globals and change
57 the value of the <tt>kileld</tt> field.
58 \dontinclude 05-globals.c
59 \skip kill_cb
60 \until end_of_kill_callback
61
62 And we replace the single gras_msg_handle() of the server main function by a
63 loop:
64 \skip while
65 \until }
66
67 Please note that in our example, only one process creates a global
68 structure. But this is naturally completely ok to have several
69 processes creating their globals this way. Each of these globals will
70 be separated, so process A cannot access globals defined by process B.
71 Maybe this implies that the name "globals" is a bit misleading. It
72 should be "process state" or something similar.
73
74 \section GRAS_tut_tour_callback_pitfall Common pitfall of globals
75
76 There is an error that I do myself every other day using globals in GRAS.
77 This is to write something like:
78 \verbatim int server(int argc, char *argv[]) {
79   server_data_t globals=gras_user_new(server_data_t);
80   /* other variable definition */
81   
82   gras_init(&argc, argv);
83   
84   /* rest of the code */
85 }\endverbatim
86
87 The problem is that you call gras_userdata_new() before gras_init(). Doing so,
88 embarass GRAS since it does not have its internal buffer initialized yet,
89 and cannot store your data anywhere. That is why doing so triggers an error
90 at run time.
91
92 Also, as noted above, the gras_userdata_new expects the pointed type,
93 not the pointer type. As you can see, in our example, you should pass
94 server_data_t to the macro, even if the global variable is later
95 defined as being of type server_data_t*.
96
97
98 \section GRAS_tut_tour_callback_recap Recaping everything together
99
100 The whole program now reads:
101 \include 05-globals.c
102
103 And here is the output (unchanged wrt previous version):
104 \include 05-globals.output
105
106 That's it, we're done. We have a server able to handle any number of
107 messages, which the client can stop remotely properly. That's already
108 something, hu?
109
110 Go to \ref GRAS_tut_tour_logs
111
112 */