Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Document the token ring example
[simgrid.git] / examples / gras / tokenS / tokenS.c
index 05b373c..de1399d 100644 (file)
  
 #include "gras.h"
  
-#define NBLOOPS 100
+#define NBLOOPS 3
+/*#define NBLOOPS 30000*/
 
 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[]);
 
@@ -31,32 +27,34 @@ 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;
 
 
 /* Callback function */
-static int node_cb_stoken_handler(gras_socket_t  expeditor,
-                                 void          *payload_data) {
+static int node_cb_stoken_handler(gras_msg_cb_ctx_t ctx, void *payload) {
   
   xbt_ex_t e;
   
-  /* 1. Get the payload into the msg variable */
-  int msg=*(int*)payload_data;
+  /* 1. Get the payload into the msg variable, and retrieve my caller */
+  int msg=*(int*)payload;
+  gras_socket_t expeditor = gras_msg_cb_ctx_from(ctx);
+
 
   /* 2. Retrieve the node's state (globals) */
   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) {
     supersteps = 10;
-  } 
+  } else if (NBLOOPS <=10) {
+    supersteps = 1;
+  }
   if (globals->create && (! (globals->remaining_loop % supersteps))) {
     INFO1("Begin a new loop. Still to do: %d", globals->remaining_loop);
   } else if (! (globals->remaining_loop % supersteps)) {
@@ -64,23 +62,20 @@ static int node_cb_stoken_handler(gras_socket_t  expeditor,
          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");
@@ -92,25 +87,26 @@ static int node_cb_stoken_handler(gras_socket_t  expeditor,
      reused by our predecessor.
      Closing this side would thus create troubles */
   
-  /* 9. Decrease the remaining_loop integer. */
+  /* 7. Decrease the remaining_loop integer. */
   globals->remaining_loop -= 1;
    
-  /* 10. 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);
   }
 
-  /* 11. 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;
   
   const char *host;
   int   myport;
   int   peerport;
+    
+  xbt_ex_t e;
   
   /* 1. Init the GRAS infrastructure and declare my globals */
   gras_init(&argc,argv);
@@ -132,29 +128,25 @@ int node (int argc,char *argv[]) {
   globals->remaining_loop=NBLOOPS;
   globals->create = 0;
   globals->tosuccessor = NULL;
-       
-  INFO4("Launch node %d (successor on %s:%d; listening on %d)",
+
+  if (!gras_os_getpid() % 100)
+  INFO4("Launch node %ld (successor on %s:%d; listening on %d)",
        gras_os_getpid(), host,peerport, myport);
 
   /* 4. Create my master socket for listening */
   globals->sock = gras_socket_server(myport);
   gras_os_sleep(1.0); /* Make sure all server sockets are created */
 
-
   /* 5. Create socket to the successor on the ring */
   DEBUG2("Connect to my successor on %s:%d",host,peerport);
 
   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 */
@@ -169,8 +161,12 @@ int node (int argc,char *argv[]) {
     INFO3("Create the token (with value %d) and send it to %s:%d",
          token, host, peerport);
 
-    gras_msg_send(globals->tosuccessor,
-                 gras_msgtype_by_name("stoken"), &token);
+    TRY {        
+      gras_msg_send(globals->tosuccessor,
+                 gras_msgtype_by_name("stoken"), &token);
+    } CATCH(e) {
+      RETHROW0("Unable to send the freshly created token: %s");
+    }
   } 
   
   /* 8. Wait up to 10 seconds for an incomming message to handle */