1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
<html xmlns="http://www.w3.org/1999/xhtml">
4
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
5
<title>SimGrid: Token Ring example</title>
6
<link href="tabs.css" rel="stylesheet" type="text/css"/>
7
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
8
<link href="simgrid.css" rel="stylesheet" type="text/css">
11
<!-- Generated by Doxygen 1.7.4 -->
14
<table cellspacing="0" cellpadding="0">
16
<tr style="height: 56px;">
17
<td style="padding-left: 0.5em;">
18
<div id="projectname">SimGrid <span id="projectnumber">3.7.1</span></div>
19
<div id="projectbrief">Scalable simulation of distributed systems</div>
25
<div id="navrow1" class="tabs">
27
<li><a href="index.html"><span>Main Page</span></a></li>
28
<li class="current"><a href="use.html"><span>Using SimGrid</span></a></li>
29
<li><a href="http://gforge.inria.fr/projects/simgrid"><span>Forge</span></a></li>
30
<li><a href="http://simgrid.gforge.inria.fr/"><span>Website</span></a></li>
31
<li><a href="pages.html"><span>Documentation index</span></a></li>
32
<li><a href="FAQ.html"><span>FAQ</span></a></li>
34
<div class="tabs_group_use">
36
<li><a href="install.html"><span>Installing SimGrid</span></a></li>
37
<li class="current"><a href="modules.html"><span>Modules API</span></a></li>
38
<li><a href="options.html"><span>Options & configurations</span></a></li>
39
<li><a href="platform.html"><span>Platform Description</span></a></li>
40
<li><a href="tracing.html"><span>Tracing Simulations</span></a></li>
41
<li><a href="bindings.html"><span>Bindings</span></a></li>
42
<li><a href="pls.html"><span>Packet-Level Simulation</span></a></li>
47
<!-- POST-PROCESSED TABS -->
50
<li> <a href="group__API__index.html"><span>Full Index</span></a></li>
51
<li> <a href="group__XBT__API.html"><span>XBT</span></a></li>
52
<li> <a href="group__MSG__API.html"><span>MSG</span></a></li>
53
<li> <a href="group__SIMIX__API.html"><span>SIMIX</span></a></li>
54
<li class="current"> <a href="group__GRAS__API.html"><span>GRAS</span></a></li>
55
<li> <a href="group__AMOK__API.html"><span>AMOK</span></a></li>
56
<li> <a href="group__SMPI__API.html"><span>SMPI</span></a></li>
57
<li> <a href="group__SD__API.html"><span>SimDag</span></a></li>
58
<li> <a href="group__SURF__API.html"><span>SURF</span></a></li>
59
<li> <a href="group__TRACE__API.html"><span>TRACE</span></a></li>
63
<li> <a href="group__GRAS__comm.html"><span>Communication facilities</span></a></li>
64
<li> <a href="group__GRAS__run.html"><span>Virtualization</span></a></li>
65
<li class="current"> <a href="group__GRAS__ex.html"><span>Examples</span></a></li>
66
<li> <a href="group__GRAS__tut.html"><span>Tutorial</span></a></li>
70
<li> <a href="group__GRAS__ex__ping.html"><span>Ping-Pong</span></a></li>
71
<li class="current"> <a href="group__GRAS__ex__token.html"><span>Token Ring example</span></a></li>
72
<li> <a href="group__GRAS__ex__mmrpc.html"><span>A simple RPC for matrix multiplication</span></a></li>
73
<li> <a href="group__GRAS__ex__timer.html"><span>Some timer games</span></a></li>
79
<!-- END OF POST-PROCESSED TABS -->
82
<div class="headertitle">
83
<div class="title">Token Ring example</div> </div>
84
<div class="ingroups"><a class="el" href="group__GRAS__ex.html">Examples</a></div></div>
85
<div class="contents">
86
<table class="memberdecls">
88
<p>This example implements the token ring algorithm. It involves several nodes arranged in a ring (each of them have a left and a right neighbour) and exchanging a "token". This algorithm is one of the solution to ensure the mutual exclusion between distributed processes. There is only one token at any time, so the process in its possession is ensured to be the only one having it. So, if there is an action you want all processes to do alternativly, but you cannot afford to have two processes doing it at the same time, let the process having the token doing it.</p>
89
<p>Actually, there is a lot of different token ring algorithms in the litterature, so this example implements one of them: the simplest one. The ring is static (no new node can join it, and you'll get trouble if one node dies or leaves), and nothing is done for the case in which the token is lost.</p>
91
<li><a class="el" href="group__GRAS__ex__token.html#GRAS_ex_stoken_deploy">1) Deployment file</a></li>
92
<li><a class="el" href="group__GRAS__ex__token.html#GRAS_ex_stoken_global">2) Global definition</a></li>
93
<li><a class="el" href="group__GRAS__ex__token.html#GRAS_ex_stoken_callback">3) The callback</a></li>
94
<li><a class="el" href="group__GRAS__ex__token.html#GRAS_ex_stoken_main">4) The main function</a></li>
96
<h2><a class="anchor" id="GRAS_ex_stoken_deploy"></a>
97
1) Deployment file</h2>
98
<p>Here is the deployment <a href="file:">file:</a> </p>
99
<div class="fragment"><pre class="fragment"><?xml version=<span class="stringliteral">'1.0'</span>?>
100
<!DOCTYPE platform SYSTEM <span class="stringliteral">"http://simgrid.gforge.inria.fr/simgrid.dtd"</span>>
101
<platform version=<span class="stringliteral">"3"</span>>
103
<process host=<span class="stringliteral">"Tremblay"</span> function=<span class="stringliteral">"node"</span>>
104
<argument value=<span class="stringliteral">"4000"</span>/> <!-- port on which I am listening -->
105
<argument value=<span class="stringliteral">"Fafard"</span>/><argument value=<span class="stringliteral">"4000"</span>/> <!-- peer (successor) host <span class="keywordtype">id</span> and port-->
106
<argument value="--create-token"/> <!-- I'm first client, ie I have to create the token -->
109
<process host="Fafard" function="node">
110
<argument value="4000"/> <!-- port on which I am listening -->
111
<argument value="Jupiter"/><argument value="4000"/><!-- peer (successor) host <span class="keywordtype">id</span> and port-->
114
<process host="Jupiter" function="node">
115
<argument value="4000"/> <!-- port on which I am listening -->
116
<argument value="Ginette"/><argument value="4000"/> <!-- peer (successor) host <span class="keywordtype">id</span> and port-->
119
<process host="Ginette" function="node">
120
<argument value="4000"/> <!-- port on which I am listening -->
121
<argument value="Bourassa"/><argument value="4000"/><!-- peer (successor) host <span class="keywordtype">id</span> and port-->
124
<process host="Bourassa" function="node">
125
<argument value="4000"/> <!-- port on which I am listening -->
126
<argument value="Tremblay"/><argument value="4000"/><!-- peer (successor) host <span class="keywordtype">id</span> and port-->
130
</pre></div><p>The neighbour of each node is given at startup as command line argument. Moreover, one of the nodes is instructed by a specific argument (the one on Tremblay here) to create the token at the begining of the algorithm.</p>
131
<h2><a class="anchor" id="GRAS_ex_stoken_global"></a>
132
2) Global definition</h2>
133
<p>The token is incarned by a specific message, which circulates from node to node (the payload is an integer incremented at each hop). So, the most important part of the code is the message callback, which forwards the message to the next node. That is why we have to store all variable in a global, as explained in the <a class="el" href="group__GRAS__globals.html">Globals</a> section.</p>
134
<div class="fragment"><pre class="fragment"><span class="keyword">typedef</span> <span class="keyword">struct </span>{
135
<a class="code" href="group__XBT__sock__create.html#ga490f317ed9bc4b6d7f0b78bf91e6f184" title="Opaque type describing a socket.">xbt_socket_t</a> sock; <span class="comment">/* server socket on which I hear */</span>
136
<span class="keywordtype">int</span> remaining_loop; <span class="comment">/* number of loops to do until done */</span>
137
<span class="keywordtype">int</span> create; <span class="comment">/* whether I have to create the token */</span>
138
<a class="code" href="group__XBT__sock__create.html#ga490f317ed9bc4b6d7f0b78bf91e6f184" title="Opaque type describing a socket.">xbt_socket_t</a> tosuccessor; <span class="comment">/* how to connect to the successor on ring */</span>
139
<span class="keywordtype">double</span> start_time; <span class="comment">/* to measure the elapsed time. Only used by the </span>
140
<span class="comment"> node that creates the token */</span>
143
<h2><a class="anchor" id="GRAS_ex_stoken_callback"></a>
145
<p>Even if this is the core of this algorithm, this function is quite straightforward.</p>
146
<p><div class="fragment"><pre class="fragment"><span class="keyword">static</span> <span class="keywordtype">int</span> node_cb_stoken_handler(<a class="code" href="structs__gras__msg__cb__ctx.html">gras_msg_cb_ctx_t</a> ctx, <span class="keywordtype">void</span> *payload)
148
<span class="comment">/* 1. Get the payload into the msg variable, and retrieve my caller */</span>
149
<span class="keywordtype">int</span> msg = *(<span class="keywordtype">int</span> *) payload;
150
<a class="code" href="group__XBT__sock__create.html#ga490f317ed9bc4b6d7f0b78bf91e6f184" title="Opaque type describing a socket.">xbt_socket_t</a> expeditor = <a class="code" href="group__GRAS__msg__cb.html#ga06d07c39a4ab161ef6307f5b947f7687" title="Retrieve the expeditor of the message.">gras_msg_cb_ctx_from</a>(ctx);
153
<span class="comment">/* 2. Retrieve the node's state (globals) */</span>
154
node_data_t *globals = (node_data_t *) <a class="code" href="group__GRAS__globals.html#ga32fe737117c1ab1f3acbfbbce4190fa6" title="Get the data associated with the current process.">gras_userdata_get</a>();
156
<span class="comment">/* 3. Log which predecessor connected */</span>
157
<span class="keywordtype">int</span> supersteps = 1; <span class="comment">/* only log every superstep loop */</span>
158
<span class="keywordflow">if</span> (NBLOOPS >= 1000) {
160
} <span class="keywordflow">else</span> <span class="keywordflow">if</span> (NBLOOPS >= 100) {
162
} <span class="keywordflow">else</span> <span class="keywordflow">if</span> (NBLOOPS <= 10) {
165
<span class="keywordflow">if</span> (globals->create && (!(globals->remaining_loop % supersteps))) {
166
<a class="code" href="group__XBT__log.html#ga57f4469c36aeb5f44b5786882b364af8" title="Log an event at the INFO priority on the default category with these args.">XBT_INFO</a>(<span class="stringliteral">"Begin a new loop. Still to do: %d"</span>, globals->remaining_loop);
167
} <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!(globals->remaining_loop % supersteps)) {
168
<a class="code" href="group__XBT__log.html#gab9815968eb142e81c5e661ececb1f0f3" title="Log an event at the VERB priority on the default category with these args.">XBT_VERB</a>(<span class="stringliteral">"Got token(%d) from %s remaining_loop=%d"</span>,
169
msg, <a class="code" href="group__XBT__sock__info.html#ga333dd4cc354fc99c54661967b58efe27">xbt_socket_peer_name</a>(expeditor), globals->remaining_loop);
172
<span class="comment">/* 4. If the right shouldn't be stopped yet */</span>
173
<span class="keywordflow">if</span> (globals->remaining_loop > 0) {
176
<a class="code" href="group__XBT__log.html#gaec7da836fa1482fcda89227dfb1284d9" title="Log an event at the DEBUG priority on the default category with these args.">XBT_DEBUG</a>(<span class="stringliteral">"Send token(%d) to %s:%d"</span>, msg,
177
<a class="code" href="group__XBT__sock__info.html#ga333dd4cc354fc99c54661967b58efe27">xbt_socket_peer_name</a>(globals->tosuccessor),
178
<a class="code" href="group__XBT__sock__info.html#ga261ce2b45f820b18c6cf9efc46257f13" title="Get the port number on which this socket is connected on remote side.">xbt_socket_peer_port</a>(globals->tosuccessor));
180
<span class="comment">/* 5. Send the token as payload of a stoken message to the successor */</span>
181
<a class="code" href="group__XBT__ex.html#gad2746371528bdf15c3910b7bf217dac0" title="Introduce a block where exception may be dealed with.">TRY</a> {
182
<a class="code" href="group__GRAS__msg__exchange.html#ga4530e0a98262b6371dc30aa76df1f21a" title="Send the data pointed by payload as a message msgname on the sock.">gras_msg_send</a>(globals->tosuccessor, <span class="stringliteral">"stoken"</span>, &msg);
184
<span class="comment">/* 6. Deal with errors */</span>
186
<a class="code" href="group__XBT__ex.html#ga070f91546c08b1e31c1d7184c3c9b345" title="like CATCH(e) but without argument">CATCH_ANONYMOUS</a> {
187
<a class="code" href="group__GRAS__sock__create.html#gabdbbaf32ef66a8006ceb812393cbe591" title="Close socket.">gras_socket_close</a>(globals->sock);
188
<a class="code" href="group__XBT__ex.html#ga4826ac71c1c4d2ec13eeac8320898dc9" title="like THROWF, but adding some details to the message of an existing exception">RETHROWF</a>(<span class="stringliteral">"Unable to forward token: %s"</span>);
193
<span class="comment">/* DO NOT CLOSE THE expeditor SOCKET since the client socket is</span>
194
<span class="comment"> reused by our predecessor.</span>
195
<span class="comment"> Closing this side would thus create troubles */</span>
197
<span class="comment">/* 7. Decrease the remaining_loop integer. */</span>
198
globals->remaining_loop -= 1;
200
<span class="comment">/* 8. Repport the hop number to the user at the end */</span>
201
<span class="keywordflow">if</span> (globals->remaining_loop == -1 && globals->create) {
202
<span class="keywordtype">double</span> elapsed = <a class="code" href="group__GRAS__virtu.html#ga690fb7390ae0f7a8622dd36c4f2854ce" title="Get the current time.">gras_os_time</a>() - globals->start_time;
203
<a class="code" href="group__XBT__log.html#ga57f4469c36aeb5f44b5786882b364af8" title="Log an event at the INFO priority on the default category with these args.">XBT_INFO</a>(<span class="stringliteral">"Shut down the token-ring. There was %d hops."</span>, msg);
204
<a class="code" href="group__XBT__log.html#gab9815968eb142e81c5e661ececb1f0f3" title="Log an event at the VERB priority on the default category with these args.">XBT_VERB</a>(<span class="stringliteral">"Elapsed time: %g"</span>, elapsed);
207
<span class="comment">/* 9. Tell GRAS that we consummed this message */</span>
208
<span class="keywordflow">return</span> 0;
209
} <span class="comment">/* end_of_node_cb_stoken_handler */</span>
211
<h2><a class="anchor" id="GRAS_ex_stoken_main"></a>
212
4) The main function</h2>
213
<p>This function is splited in two parts: The first one performs all the needed initialisations (points 1-7) while the end (point 8. below) calls <a class="el" href="group__GRAS__msg__exchange.html#ga734f74309ee66358e60f6926084e46c5" title="Handle an incoming message or timer (or wait up to timeOut seconds)">gras_msg_handle()</a> as long as the planned amount of ring loops are not performed.</p>
214
<p><div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> node(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[])
216
node_data_t *globals;
218
<span class="keyword">const</span> <span class="keywordtype">char</span> *host;
219
<span class="keywordtype">int</span> myport;
220
<span class="keywordtype">int</span> peerport;
222
<span class="comment">/* 1. Init the GRAS infrastructure and declare my globals */</span>
223
<a class="code" href="group__GRAS__API.html#ga2f7e006b4b7297a5d8979e299ddf9112" title="Initialize the gras mechanisms.">gras_init</a>(&argc, argv);
224
globals = <a class="code" href="group__GRAS__globals.html#ga7d5d5973e9d4f19b415d6c7aa8787844" title="Malloc and set the data associated with the current process.">gras_userdata_new</a>(node_data_t);
227
<span class="comment">/* 2. Get the successor's address. The command line overrides</span>
228
<span class="comment"> defaults when specified */</span>
229
host = <span class="stringliteral">"127.0.0.1"</span>;
232
<span class="keywordflow">if</span> (argc >= 4) {
233
myport = atoi(argv[1]);
235
peerport = atoi(argv[3]);
238
<span class="comment">/* 3. Save successor's address in global var */</span>
239
globals->remaining_loop = NBLOOPS;
240
globals->create = 0;
241
globals->tosuccessor = NULL;
243
<span class="keywordflow">if</span> (!<a class="code" href="group__GRAS__virtu.html#ga19eab254893273bc41d1a1db30cf4d80" title="get process identification">gras_os_getpid</a>() % 100 || <a class="code" href="group__GRAS__emul.html#ga7536bfeabf829c3af4e4bbd062ae68a5" title="Returns true only if the program runs on real life.">gras_if_RL</a>())
244
<a class="code" href="group__XBT__log.html#ga57f4469c36aeb5f44b5786882b364af8" title="Log an event at the INFO priority on the default category with these args.">XBT_INFO</a>(<span class="stringliteral">"Launch node listening on %d (successor on %s:%d)"</span>,
245
myport, host, peerport);
247
<span class="comment">/* 4. Register the known messages. */</span>
248
<a class="code" href="group__GRAS__msg__decl.html#ga7857c6d519073e49604d59fa957bdc4d" title="declare a new message type of the given name. It only accepts the given datadesc as payload...">gras_msgtype_declare</a>(<span class="stringliteral">"stoken"</span>, <a class="code" href="group__XBT__dd__basic.html#gaf4b2d699b60f60645c04e294337d93cd" title="Search a type description from its name.">xbt_datadesc_by_name</a>(<span class="stringliteral">"int"</span>));
250
<span class="comment">/* 5. Create my master socket for listening */</span>
251
globals->sock = <a class="code" href="group__GRAS__sock__create.html#gafaf3628fe9e0afd023b7c29a167cce75" title="Simply create a server socket (to ear from remote hosts speaking to you)">gras_socket_server</a>(myport);
252
<a class="code" href="group__GRAS__virtu.html#ga759c02d11cdd774f4c2c3ce0a7aa876c" title="sleeps for the given amount of time.">gras_os_sleep</a>(1.0); <span class="comment">/* Make sure all server sockets are created */</span>
254
<span class="comment">/* 6. Create socket to the successor on the ring */</span>
255
<a class="code" href="group__XBT__log.html#gaec7da836fa1482fcda89227dfb1284d9" title="Log an event at the DEBUG priority on the default category with these args.">XBT_DEBUG</a>(<span class="stringliteral">"Connect to my successor on %s:%d"</span>, host, peerport);
257
globals->tosuccessor = <a class="code" href="group__GRAS__sock__create.html#ga1dad2be5438de05743501352f144fad5" title="Simply create a client socket (to speak to a remote host)">gras_socket_client</a>(host, peerport);
259
<span class="comment">/* 7. Register my callback */</span>
260
<a class="code" href="group__GRAS__msg__cb.html#gada679e069d5516d632542a963a5e921c" title="Bind the given callback to the given message type (described by its name)">gras_cb_register</a>(<span class="stringliteral">"stoken"</span>, &node_cb_stoken_handler);
262
<span class="comment">/* 8. One node has to create the token at startup. </span>
263
<span class="comment"> It's specified by a command line argument */</span>
264
<span class="keywordflow">if</span> (argc >= 5
265
&& !strncmp(<span class="stringliteral">"--create-token"</span>, argv[4], strlen(<span class="stringliteral">"--create-token"</span>)))
266
globals->create = 1;
268
<span class="keywordflow">if</span> (globals->create) {
269
<span class="keywordtype">int</span> token = 0;
271
globals->start_time = <a class="code" href="group__GRAS__virtu.html#ga690fb7390ae0f7a8622dd36c4f2854ce" title="Get the current time.">gras_os_time</a>();
273
globals->remaining_loop = NBLOOPS - 1;
275
<a class="code" href="group__XBT__log.html#ga57f4469c36aeb5f44b5786882b364af8" title="Log an event at the INFO priority on the default category with these args.">XBT_INFO</a>(<span class="stringliteral">"Create the token (with value %d) and send it to %s:%d"</span>,
276
token, host, peerport);
278
<a class="code" href="group__XBT__ex.html#gad2746371528bdf15c3910b7bf217dac0" title="Introduce a block where exception may be dealed with.">TRY</a> {
279
<a class="code" href="group__GRAS__msg__exchange.html#ga4530e0a98262b6371dc30aa76df1f21a" title="Send the data pointed by payload as a message msgname on the sock.">gras_msg_send</a>(globals->tosuccessor, <span class="stringliteral">"stoken"</span>, &token);
281
<a class="code" href="group__XBT__ex.html#ga070f91546c08b1e31c1d7184c3c9b345" title="like CATCH(e) but without argument">CATCH_ANONYMOUS</a> {
282
<a class="code" href="group__XBT__ex.html#ga4826ac71c1c4d2ec13eeac8320898dc9" title="like THROWF, but adding some details to the message of an existing exception">RETHROWF</a>(<span class="stringliteral">"Unable to send the freshly created token: %s"</span>);
286
<span class="comment">/* 8. Wait up to 10 seconds for an incoming message to handle */</span>
287
<span class="keywordflow">while</span> (globals->remaining_loop > (globals->create ? -1 : 0)) {
288
<a class="code" href="group__GRAS__msg__exchange.html#ga734f74309ee66358e60f6926084e46c5" title="Handle an incoming message or timer (or wait up to timeOut seconds)">gras_msg_handle</a>(-1);
290
<a class="code" href="group__XBT__log.html#gaec7da836fa1482fcda89227dfb1284d9" title="Log an event at the DEBUG priority on the default category with these args.">XBT_DEBUG</a>(<span class="stringliteral">"looping (remaining_loop=%d)"</span>, globals->remaining_loop);
293
<a class="code" href="group__GRAS__virtu.html#ga759c02d11cdd774f4c2c3ce0a7aa876c" title="sleeps for the given amount of time.">gras_os_sleep</a>(1.0); <span class="comment">/* FIXME: if the sender quited, receive fail */</span>
295
<span class="comment">/* 9. Free the allocated resources, and shut GRAS down */</span>
296
<a class="code" href="group__GRAS__sock__create.html#gabdbbaf32ef66a8006ceb812393cbe591" title="Close socket.">gras_socket_close</a>(globals->sock);
297
<a class="code" href="group__GRAS__sock__create.html#gabdbbaf32ef66a8006ceb812393cbe591" title="Close socket.">gras_socket_close</a>(globals->tosuccessor);
299
<a class="code" href="group__GRAS__API.html#gaee47a46ba8da34d67242a80552252dbe" title="Finalize the gras mechanisms.">gras_exit</a>();
301
<span class="keywordflow">return</span> 0;
302
} <span class="comment">/* end_of_node */</span>
311
<a href="index.html"><b>
312
Back to the main Simgrid Documentation page</b></a>
315
<small>The version of <a href="http://simgrid.gforge.inria.fr">SimGrid</a> documented here is v3.7.1.<br/>
316
Documentation of other versions can be found in their respective
317
archive files (directory doc/html).
320
<small>Generated by <a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a> </small>