Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
New GRAS example: simple/static token ring implementation
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 23 Jun 2005 14:44:38 +0000 (14:44 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 23 Jun 2005 14:44:38 +0000 (14:44 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@1385 48e7efb5-ca39-0410-a469-dd3cf9ba447f

examples/gras/tokenS/.cvsignore [new file with mode: 0644]
examples/gras/tokenS/Makefile.am [new file with mode: 0644]
examples/gras/tokenS/test_rl.in [new file with mode: 0755]
examples/gras/tokenS/test_sg.in [new file with mode: 0755]
examples/gras/tokenS/tokenS.c [new file with mode: 0644]
examples/gras/tokenS/tokenS_deployment.xml [new file with mode: 0644]

diff --git a/examples/gras/tokenS/.cvsignore b/examples/gras/tokenS/.cvsignore
new file mode 100644 (file)
index 0000000..d44a219
--- /dev/null
@@ -0,0 +1,8 @@
+.deps .libs Makefile Makefile.in _*.c tokenS_node tokenS_simulator
+test_sg
+test_rl
+tokenS.Makefile.am
+tokenS.Makefile.local
+tokenS.Makefile.remote
+tokenS.deploy.sh
+tokenS.trace
diff --git a/examples/gras/tokenS/Makefile.am b/examples/gras/tokenS/Makefile.am
new file mode 100644 (file)
index 0000000..294150c
--- /dev/null
@@ -0,0 +1,30 @@
+INCLUDES= -I$(top_srcdir)/include
+TESTS= test_rl test_sg
+EXTRA_DIST=tokenS_deployment.xml $(TESTS)
+
+# AUTOMAKE variable definition
+noinst_PROGRAMS=tokenS_node tokenS_simulator
+
+tokenS_simulator_SOURCES=  _tokenS_simulator.c tokenS.c
+tokenS_simulator_LDADD=    $(top_builddir)/src/libsimgrid.la
+
+tokenS_node_SOURCES=       _tokenS_node.c tokenS.c
+tokenS_node_LDADD=         $(top_builddir)/src/libgras.la
+
+# cleanup temps
+CLEANFILES = _tokenS_simulator.c _tokenS_node.c _tokenS_node.c \
+             tokenS.Makefile.local tokenS.Makefile.remote tokenS.deploy.sh 
+
+MOSTLYCLEANFILES = tokenS.trace
+
+# generate temps
+NAME=tokenS
+PROCESSES=node
+
+$(foreach proc, $(PROCESSES), _$(NAME)_$(proc).c) _$(NAME)_simulator.c: $(srcdir)/$(NAME)_deployment.xml ../../../tools/gras/gras_stub_generator@EXEEXT@
+       [ x@EXEEXT@ = x ] || exenv=wine; $$exenv ../../../tools/gras/gras_stub_generator@EXEEXT@ $(NAME) $(srcdir)/$(NAME)_deployment.xml >/dev/null
+
+../../../tools/gras/gras_stub_generator@EXEEXT@:
+       make -C   ../../../tools/gras/ gras_stub_generator@EXEEXT@
+
+include $(top_srcdir)/acmacro/dist-files.mk
diff --git a/examples/gras/tokenS/test_rl.in b/examples/gras/tokenS/test_rl.in
new file mode 100755 (executable)
index 0000000..b96c7ee
--- /dev/null
@@ -0,0 +1,17 @@
+#! @BASH@ -e
+if [ x@EXEEXT@ = x ] ; then 
+#  exenv="libtool --mode=execute valgrind --db-attach=yes --run-libc-freeres=no "
+#  exenv="libtool --mode=execute valgrind --run-libc-freeres=no "
+  exenv=
+else
+  exenv=wine
+fi
+    
+$exenv ./tokenS_node@EXEEXT@ 4000 127.0.0.1 4010 --create-token $@ &
+# $exenv ./tokenS_node@EXEEXT@ 4010 127.0.0.1 4000 $@ &
+# exit 0
+$exenv ./tokenS_node@EXEEXT@ 4010 127.0.0.1 4020 $@ &
+$exenv ./tokenS_node@EXEEXT@ 4020 127.0.0.1 4030 $@ &
+$exenv ./tokenS_node@EXEEXT@ 4030 127.0.0.1 4040 $@ &
+$exenv ./tokenS_node@EXEEXT@ 4040 127.0.0.1 4050 $@ &
+$exenv ./tokenS_node@EXEEXT@ 4050 127.0.0.1 4000 $@ &
diff --git a/examples/gras/tokenS/test_sg.in b/examples/gras/tokenS/test_sg.in
new file mode 100755 (executable)
index 0000000..efa6f1c
--- /dev/null
@@ -0,0 +1,10 @@
+#! @BASH@
+if [ x@EXEEXT@ = x ] ; then 
+#  exenv="libtool --mode=execute valgrind --run-libc-freeres=no --show-reachable=yes "
+  exenv=
+else
+  exenv=wine
+fi
+
+exec $exenv ./tokenS_simulator@EXEEXT@ @top_srcdir@/examples/msg/small_platform.xml @srcdir@/tokenS_deployment.xml $@
+
diff --git a/examples/gras/tokenS/tokenS.c b/examples/gras/tokenS/tokenS.c
new file mode 100644 (file)
index 0000000..69b6327
--- /dev/null
@@ -0,0 +1,214 @@
+/* $Id$ */
+
+/* stoken - simple/static token ring                                        */
+
+/* Copyright (c) 2005 Alexandre Colucci.                                    */
+/* Copyright (c) 2005 Martin Quinson.                                       */
+/* All rights reserved.                                                     */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+#include "gras.h"
+//#define NBLOOPS 10
+#define NBLOOPS 1000
+
+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[]);
+
+
+/* **********************************************************************
+ * Node code
+ * **********************************************************************/
+
+/* 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 */
+} node_data_t;
+
+
+/* Callback function */
+static int node_cb_stoken_handler(gras_socket_t  expeditor,
+                                 void          *payload_data) {
+                            
+  xbt_error_t errcode;
+  
+  /* 1. Get the payload into the msg variable */
+  int msg=*(int*)payload_data;
+
+  /* 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;
+  if (NBLOOPS >= 1000) {
+    supersteps = 100;
+  } else if (NBLOOPS > 100) {
+    supersteps = 10;
+  } 
+  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)) {
+    VERB3("Got token(%d) from %s remaining_loop=%d", 
+         msg, gras_socket_peer_name(expeditor),globals->remaining_loop);
+  }
+  
+  if (globals->remaining_loop > 0) {
+     
+    msg += 1;
+     
+    /* 5. I forward it to my successor */
+    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 */
+    errcode = gras_msg_send(globals->tosuccessor, 
+                           gras_msgtype_by_name("stoken"), &msg);
+     
+    /* 7. Deal with errors */
+    if (errcode != no_error) {
+      ERROR1("Unable to forward token: %s\n", xbt_error_name(errcode));
+      gras_socket_close(globals->sock);
+      return 1;
+    }
+  
+  }
+             
+  /* DO NOT CLOSE THE expeditor SOCKET since the client socket is
+     reused by our predecessor.
+     Closing this side would thus create troubles */
+  
+  /* 9. Decrease the remaining_loop integer. */
+  globals->remaining_loop -= 1;
+   
+  /* 10. 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 */
+  return 1;
+} /* end_of_node_cb_stoken_handler */
+
+
+int node (int argc,char *argv[]) {
+  xbt_error_t errcode;
+  node_data_t *globals;
+  
+  
+  /* 1. Init the GRAS infrastructure and declare my globals */
+  gras_init(&argc,argv, NULL);
+  globals=gras_userdata_new(node_data_t);
+  
+  
+  /* 2. Get the successor's address. The command line overrides
+        defaults when specified */
+  const char *host = "127.0.0.1";
+  int   myport = 4000;
+  int   peerport = 4000;
+  if (argc >= 4) {
+    myport=atoi(argv[1]);
+    host=argv[2];
+    peerport=atoi(argv[3]);
+  }
+
+  /* 3. Save successor's address in global var */
+  globals->remaining_loop=NBLOOPS;
+  globals->create = 0;
+  globals->tosuccessor = NULL;
+       
+  INFO4("Launch node %d (successor on %s:%d; listening on %d)",
+       gras_os_getpid(), host,peerport, myport);
+
+  /* 4. Create my master socket for listening */
+  if ((errcode=gras_socket_server(myport,&(globals->sock)))) { 
+    CRITICAL1("Error %s encountered while opening the server socket. Bailing out.",
+             xbt_error_name(errcode));
+    return 1;
+  }
+  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);
+
+  if ((errcode=gras_socket_client(host,peerport,
+                                 &(globals->tosuccessor)))) {
+    ERROR1("Unable to connect to the node (got %s). Bailing out.",
+          xbt_error_name(errcode));
+    return 1;
+  } 
+  
+  /* 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 ;) */
+   
+  /* 7. Register my callback */
+  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 */
+  if (argc >= 5 && !strncmp("--create-token", argv[4],strlen(argv[4])))
+    globals->create=1;
+
+  if (globals->create) {
+    int token = 0;
+            
+    globals->remaining_loop = NBLOOPS - 1;
+      
+    INFO3("Create the token (with value %d) and send it to %s:%d",
+         token, host, peerport);
+
+    errcode = gras_msg_send(globals->tosuccessor,
+                           gras_msgtype_by_name("stoken"), &token);
+      
+    if (errcode != no_error) {
+      fprintf(stderr, "Unable send 'stoken' to successor (%s)\n",
+             xbt_error_name(errcode));
+      return 1;
+    }
+  } 
+  
+  /* 8. Wait up to 10 seconds for an incomming message to handle */
+  while (globals->remaining_loop > (globals->create ? -1 : 0)) {
+    errcode = gras_msg_handle(10.0);
+  
+    /* 9. Housekeeping */
+    if (errcode != no_error) {
+      ERROR1("Got error %s in msg_handle", xbt_error_name(errcode));
+      return errcode;
+    }
+       
+    DEBUG1("looping (remaining_loop=%d)", globals->remaining_loop);
+  }
+
+  gras_os_sleep(1.0); /* FIXME: if the sender quited, receive fail */
+
+  /* 9. Free the allocated resources, and shut GRAS down */ 
+  gras_socket_close(globals->sock);
+  gras_socket_close(globals->tosuccessor);
+  free(globals);
+  gras_exit();
+  
+  INFO0("Done");
+  return no_error;
+} /* end_of_node */
diff --git a/examples/gras/tokenS/tokenS_deployment.xml b/examples/gras/tokenS/tokenS_deployment.xml
new file mode 100644 (file)
index 0000000..79723e1
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform_description SYSTEM "surfxml.dtd">
+<platform_description>
+
+ <process host="Tremblay" function="node">
+    <argument value="4000"/>     <!-- port on which I am listening -->
+    <argument value="Fafard"/>   <!-- peer (successor) host -->
+    <argument value="4000"/>     <!-- port on which peer is listening -->
+ </process>
+ <process host="Fafard" function="node">
+    <argument value="4000"/>      <!-- port on which I am listening -->
+    <argument value="Jupiter"/>   <!-- peer (successor) host -->
+    <argument value="4000"/>      <!-- port on which peer is listening -->
+ </process>
+ <process host="Jupiter" function="node">
+    <argument value="4000"/>      <!-- port on which I am listening -->
+    <argument value="Ginette"/>   <!-- peer (successor) host -->
+    <argument value="4000"/>      <!-- port on which peer is listening -->
+ </process>
+ <process host="Ginette" function="node">
+    <argument value="4000"/>      <!-- port on which I am listening -->
+    <argument value="Bourassa"/>  <!-- peer (successor) host -->
+    <argument value="4000"/>      <!-- port on which peer is listening -->
+ </process>
+ <process host="Bourassa" function="node">
+    <argument value="4000"/>      <!-- port on which I am listening -->
+    <argument value="Tremblay"/>  <!-- peer (successor) host -->
+    <argument value="4000"/>      <!-- port on which peer is listening -->
+    <argument value="--create-token"/>   <!-- I'm first client, ie I have to create the token -->
+ </process>
+</platform_description>