From: mquinson Date: Wed, 26 Apr 2006 16:37:55 +0000 (+0000) Subject: Document the token ring example X-Git-Tag: v3.3~3168 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/34b70d7b1ff96044e40daa4b42712cfd9f7c1684?hp=c6c66880378f9cfc2376913f4263f95d4bf28b69 Document the token ring example git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2190 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/doc/module-gras.doc b/doc/module-gras.doc index f2451f08f3..5c3d672290 100644 --- a/doc/module-gras.doc +++ b/doc/module-gras.doc @@ -51,6 +51,7 @@ - \ref GRAS_ex_ping - \ref GRAS_ex_mmrpc + - \ref GRAS_ex_token - \ref GRAS_ex_timer @{ */ @@ -117,11 +118,13 @@ - \ref GRAS_ex_ping - \ref GRAS_ex_mmrpc + - \ref GRAS_ex_token - \ref GRAS_ex_timer \htmlonly \endhtmlonly @@ -419,6 +422,73 @@ [Back to \ref GRAS_ex_ping_toc] */ +--------------------------------------------------------------------- +--------------------- Simple Token Ring ----------------------------- +--------------------------------------------------------------------- + +/** \page GRAS_ex_token Token Ring example + + 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. + + 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. + + - \ref GRAS_ex_stoken_deploy + - \ref GRAS_ex_stoken_global + - \ref GRAS_ex_stoken_callback + - \ref GRAS_ex_stoken_main + + \section GRAS_ex_stoken_deploy 1) Deployment file + + Here is the deployment file: + \include examples/gras/tokenS/tokenS_deployment.xml + + 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. + + \section GRAS_ex_stoken_global 2) Global definition + + 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 \ref GRAS_globals section. + + \dontinclude examples/gras/tokenS/tokenS.c + \skip typedef + \until } + + \section GRAS_ex_stoken_callback 3) The callback + + Even if this is the core of this algorithm, this function is quite + straightforward. + + \skip node_cb_stoken_handler + \until end_of_node_cb_stoken_handler + + \section GRAS_ex_stoken_main 4) The main function + + 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 + gras_msg_handle() as long as the planned amount of ring loops are not + performed. + + \skip node + \until end_of_node + +*/ + --------------------------------------------------------------------- -------------------------- MM RPC ----------------------------------- --------------------------------------------------------------------- diff --git a/examples/gras/tokenS/tokenS.c b/examples/gras/tokenS/tokenS.c index aafde91e46..de1399d24a 100644 --- a/examples/gras/tokenS/tokenS.c +++ b/examples/gras/tokenS/tokenS.c @@ -16,11 +16,6 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(Token,"Messages specific to this example"); -/* register messages which may be sent */ -static void register_messages(void) { - gras_msgtype_declare("stoken", gras_datadesc_by_name("int")); -} - /* Function prototypes */ int node (int argc,char *argv[]); @@ -32,9 +27,9 @@ int node (int argc,char *argv[]); /* Global private data */ typedef struct { gras_socket_t sock; /* server socket on which I hear */ - int remaining_loop; /* loop to do until done */ - int create; /* I have to create the token */ - gras_socket_t tosuccessor; /* how to connect to next peer on ring */ + int remaining_loop; /* number of loops to do until done */ + int create; /* whether I have to create the token */ + gras_socket_t tosuccessor; /* how to connect to the successor on ring */ } node_data_t; @@ -52,7 +47,7 @@ static int node_cb_stoken_handler(gras_msg_cb_ctx_t ctx, void *payload) { node_data_t *globals=(node_data_t*)gras_userdata_get(); /* 3. Log which predecessor connected */ - int supersteps = 1; + int supersteps = 1; /* only log every superstep loop */ if (NBLOOPS >= 1000) { supersteps = 100; } else if (NBLOOPS >= 100) { @@ -67,23 +62,20 @@ static int node_cb_stoken_handler(gras_msg_cb_ctx_t ctx, void *payload) { msg, gras_socket_peer_name(expeditor),globals->remaining_loop); } + /* 4. If the right shouldn't be stopped yet */ if (globals->remaining_loop > 0) { - msg += 1; - /* 5. I forward it to my successor */ - DEBUG3("Send token(%d) to %s:%d", - msg, + DEBUG3("Send token(%d) to %s:%d", msg, gras_socket_peer_name(globals->tosuccessor), gras_socket_peer_port(globals->tosuccessor)); - - /* 6. Send it as payload of a stoken message to the successor */ + /* 5. Send the token as payload of a stoken message to the successor */ TRY { gras_msg_send(globals->tosuccessor, gras_msgtype_by_name("stoken"), &msg); - /* 7. Deal with errors */ + /* 6. Deal with errors */ } CATCH(e) { gras_socket_close(globals->sock); RETHROW0("Unable to forward token: %s"); @@ -95,19 +87,18 @@ static int node_cb_stoken_handler(gras_msg_cb_ctx_t ctx, void *payload) { reused by our predecessor. Closing this side would thus create troubles */ - /* 8. Decrease the remaining_loop integer. */ + /* 7. Decrease the remaining_loop integer. */ globals->remaining_loop -= 1; - /* 9. Repport the hop number to the user at the end */ + /* 8. Repport the hop number to the user at the end */ if (globals->remaining_loop == -1 && globals->create) { INFO1("Shut down the token-ring. There was %d hops.",msg); } - /* 10. Tell GRAS that we consummed this message */ + /* 9. Tell GRAS that we consummed this message */ return 1; } /* end_of_node_cb_stoken_handler */ - int node (int argc,char *argv[]) { node_data_t *globals; @@ -151,15 +142,11 @@ int node (int argc,char *argv[]) { globals->tosuccessor = gras_socket_client(host,peerport); - /* 6. Register the known messages. This function is called twice here, - but it's because this file also acts as regression test. - No need to do so yourself of course. */ - register_messages(); - register_messages(); /* just to make sure it works ;) */ + /* 6. Register the known messages. */ + gras_msgtype_declare("stoken", gras_datadesc_by_name("int")); /* 7. Register my callback */ - gras_cb_register(gras_msgtype_by_name("stoken"),&node_cb_stoken_handler); - + gras_cb_register(gras_msgtype_by_name("stoken"),&node_cb_stoken_handler); /* 8. One node has to create the token at startup. It's specified by a command line argument */ diff --git a/examples/gras/tokenS/tokenS_deployment.xml b/examples/gras/tokenS/tokenS_deployment.xml index f14432441f..01f9538a86 100644 --- a/examples/gras/tokenS/tokenS_deployment.xml +++ b/examples/gras/tokenS/tokenS_deployment.xml @@ -1,36 +1,30 @@ - - + - - - - + + + - - - + + - - - + + - - - + + - - - + +