Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
New functionality: possibility for libraries to register globals on each process...
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sun, 13 Feb 2005 16:30:30 +0000 (16:30 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sun, 13 Feb 2005 16:30:30 +0000 (16:30 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@996 48e7efb5-ca39-0410-a469-dd3cf9ba447f

17 files changed:
src/gras/DataDesc/ddt_create.c
src/gras/Msg/msg.c
src/gras/Msg/msg_interface.h
src/gras/Msg/msg_private.h
src/gras/Transport/sg_transport.c
src/gras/Transport/transport.c
src/gras/Transport/transport_interface.h
src/gras/Transport/transport_plugin_sg.c
src/gras/Transport/transport_private.h
src/gras/Virtu/process.c
src/gras/Virtu/rl_process.c
src/gras/Virtu/sg_process.c
src/gras/Virtu/virtu_interface.h
src/gras/Virtu/virtu_private.h [new file with mode: 0644]
src/gras/Virtu/virtu_rl.h
src/gras/Virtu/virtu_sg.h
src/gras/gras.c

index ebb8df9..84cc102 100644 (file)
@@ -123,7 +123,7 @@ void gras_dd_cat_field_free(void *f) {
   XBT_OUT;
 }
 
-/** Create a new struct and give a pointer to it */
+/** \brief Declare a new structure description */
 gras_datadesc_type_t 
   gras_datadesc_struct(const char            *name) {
 
@@ -155,7 +155,7 @@ gras_datadesc_type_t
   return res;
 }
 
-/** Append a field to the struct */
+/** \brief Append a new field to a structure description */
 void
 gras_datadesc_struct_append(gras_datadesc_type_t struct_type,
                            const char          *name,
@@ -217,7 +217,9 @@ gras_datadesc_struct_append(gras_datadesc_type_t struct_type,
   XBT_OUT;
 }
 
-/** No new field can be added afterward, and it is mandatory to close the structure before using it.
+/** \brief Close a structure description
+ * 
+ * No new field can be added afterward, and it is mandatory to close the structure before using it.
  */
 void
 gras_datadesc_struct_close(gras_datadesc_type_t struct_type) {
@@ -256,14 +258,10 @@ gras_datadesc_cycle_unset(gras_datadesc_type_t ddt) {
   ddt->cycle = 0;
 }
 
-/**
- * gras_datadesc_union:
- *
- * Create a new union and give a pointer to it 
- */
+/** \brief Declare a new union description */
 gras_datadesc_type_t 
-gras_datadesc_union(const char                   *name,
-                   gras_datadesc_type_cb_int_t   selector) {
+  gras_datadesc_union(const char                   *name,
+                     gras_datadesc_type_cb_int_t   selector) {
 
   gras_datadesc_type_t res;
   int arch;
@@ -300,15 +298,10 @@ gras_datadesc_union(const char                   *name,
   return res;
 }
 
-/**
- * gras_datadesc_union_append:
- *
- * Append a field to the union
- */
-void
-gras_datadesc_union_append(gras_datadesc_type_t  union_type,
-                          const char           *name,
-                          gras_datadesc_type_t  field_type) {
+/** \brief Append a new field to an union description */
+void gras_datadesc_union_append(gras_datadesc_type_t  union_type,
+                               const char           *name,
+                               gras_datadesc_type_t  field_type) {
 
   gras_dd_cat_field_t field;
   int arch;
@@ -343,12 +336,16 @@ gras_datadesc_union_append(gras_datadesc_type_t  union_type,
 }
 
 
-/** No new field can be added afterward, and it is mandatory to close the union before using it.*/
+/** \brief Close an union description 
+ *
+ * No new field can be added afterward, and it is mandatory to close the union before using it.
+ */
 void
 gras_datadesc_union_close(gras_datadesc_type_t union_type) {
    union_type->category.union_data.closed = 1;
 }
 
+/** \brief Declare a new type being a reference to the one passed in arg */
 gras_datadesc_type_t 
   gras_datadesc_ref(const char           *name,
                    gras_datadesc_type_t  referenced_type) {
@@ -386,7 +383,8 @@ gras_datadesc_type_t
 
   return res;
 }
-/**
+/** \brief Declare a new type being a generic reference.
+ * 
  * The callback passed in argument is to be used to select which type is currently used.
  * So, when GRAS wants to send a generic reference, it passes the current data to the selector 
  * callback and expects it to return the type description to use. 
@@ -429,9 +427,7 @@ gras_datadesc_type_t
   return res;
 }
 
-/*
- * Create a new array and give a pointer to it 
- */
+/** \brief Declare a new type being an array of fixed size and content */
 gras_datadesc_type_t 
   gras_datadesc_array_fixed(const char           *name,
                            gras_datadesc_type_t  element_type,
@@ -472,13 +468,11 @@ gras_datadesc_type_t
 
   return res;
 }
-/*
- * Create a new array and give a pointer to it 
- */
-gras_datadesc_type_t 
-  gras_datadesc_array_dyn(const char                  *name,
-                         gras_datadesc_type_t         element_type,
-                         gras_datadesc_type_cb_int_t  dynamic_size) {
+
+/** \brief Declare a new type being an array of fixed size, but accepting several content types. */
+gras_datadesc_type_t gras_datadesc_array_dyn(const char                 *name,
+                                            gras_datadesc_type_t        element_type,
+                                            gras_datadesc_type_cb_int_t dynamic_size) {
 
   gras_datadesc_type_t res;
   int arch;
@@ -520,7 +514,8 @@ gras_datadesc_type_t
   return res;
 }
 
-/**
+/** \brief Declare a new type being an array which size can be found with \ref gras_cbps_i_pop 
+ * 
  * Most of the time, you want to include a reference in your structure which
  * is a pointer to a dynamic array whose size is fixed by another field of 
  * your structure.
index 13f8155..50c529f 100644 (file)
@@ -19,6 +19,35 @@ xbt_set_t _gras_msgtype_set = NULL;
 static char GRAS_header[6];
 static char *make_namev(const char *name, short int ver);
 
+/*
+ * Creating procdata for this module
+ */
+static void *gras_msg_procdata_new() {
+   gras_msg_procdata_t res = xbt_new(s_gras_msg_procdata_t,1);
+   
+   res->msg_queue = xbt_dynar_new(sizeof(gras_msg_t),     NULL);
+   res->cbl_list  = xbt_dynar_new(sizeof(gras_cblist_t *),gras_cbl_free);
+   
+   return (void*)res;
+}
+
+/*
+ * Freeing procdata for this module
+ */
+static void gras_msg_procdata_free(void *data) {
+   gras_msg_procdata_t res = (gras_msg_procdata_t)data;
+   
+   xbt_dynar_free(&( res->msg_queue ));
+   xbt_dynar_free(&( res->cbl_list ));
+}
+
+/*
+ * Module registration
+ */
+void gras_msg_register() {
+   gras_procdata_add("gras_msg",gras_msg_procdata_new, gras_msg_procdata_free);
+}
+
 /*
  * Initialize this submodule.
  */
@@ -76,7 +105,8 @@ static char *make_namev(const char *name, short int ver) {
   return namev;
 }
 
-/**
+/** @brief declare a new message type of the given name. It only accepts the given datadesc as payload
+ *
  * @param name: name as it should be used for logging messages (must be uniq)
  * @param payload: datadescription of the payload
  */
@@ -85,7 +115,8 @@ void gras_msgtype_declare(const char           *name,
    gras_msgtype_declare_v(name, 0, payload);
 }
 
-/**
+/** @brief declare a new versionned message type of the given name and payload
+ *
  * @param name: name as it should be used for logging messages (must be uniq)
  * @param version: something like versionning symbol
  * @param payload: datadescription of the payload
@@ -133,15 +164,12 @@ gras_msgtype_declare_v(const char           *name,
               &gras_msgtype_free);
 }
 
-/*
- * Retrieve a msgtype description from its name
- */
+/** @brief retrive an existing message type from its name. */
 gras_msgtype_t gras_msgtype_by_name (const char *name) {
   return gras_msgtype_by_namev(name,0);
 }
-/*
- * Retrieve a msgtype description from its name and version
- */
+
+/** @brief retrive an existing message type from its name and version. */
 gras_msgtype_t gras_msgtype_by_namev(const char      *name,
                                     short int        version) {
   gras_msgtype_t res;
@@ -161,9 +189,8 @@ gras_msgtype_t gras_msgtype_by_namev(const char      *name,
   return res;
 }
 
-/*
- * Send the given message on the given socket 
- */
+/** \brief Send the data pointed by \a payload as a message of type
+ * \a msgtype to the peer \a sock */
 xbt_error_t
 gras_msg_send(gras_socket_t   sock,
              gras_msgtype_t  msgtype,
@@ -244,7 +271,8 @@ gras_msg_recv(gras_socket_t    sock,
   return no_error;
 }
 
-/**
+/** \brief Waits for a message to come in over a given socket. 
+ *
  * @param timeout: How long should we wait for this message.
  * @param msgt_want: type of awaited msg
  * @param[out] expeditor: where to create a socket to answer the incomming message
@@ -252,7 +280,7 @@ gras_msg_recv(gras_socket_t    sock,
  * @return the error code (or no_error).
  *
  * Every message of another type received before the one waited will be queued
- * and used by subsequent call to this function or MsgHandle().
+ * and used by subsequent call to this function or gras_msg_handle().
  */
 xbt_error_t
 gras_msg_wait(double           timeout,    
@@ -265,7 +293,7 @@ gras_msg_wait(double           timeout,
   int payload_size_got;
   xbt_error_t errcode;
   double start, now;
-  gras_procdata_t *pd=gras_procdata_get();
+  gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_get("gras_msg");
   int cpt;
   gras_msg_t msg;
   
@@ -317,12 +345,12 @@ gras_msg_wait(double           timeout,
   RAISE_IMPOSSIBLE;
 }
 
-/**
+/** @brief Handle an incomming message or timer (or wait up to \a timeOut seconds)
+ *
  * @param timeOut: How long to wait for incoming messages
  * @return the error code (or no_error).
  *
- * Waits up to \a timeOut seconds to see if a message comes in; if so, calls the
- * registered listener for that message (see \ref gras_cb_register()).
+ * Messages are passed to the callbacks.
  */
 xbt_error_t 
 gras_msg_handle(double timeOut) {
@@ -336,11 +364,9 @@ gras_msg_handle(double timeOut) {
   int             payload_size;
   gras_msgtype_t  msgtype;
 
-  gras_procdata_t*pd=gras_procdata_get();
+  gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_get("gras_msg");
   gras_cblist_t  *list;
-  gras_cb_t       cb;
-
-
+  gras_msg_cb_t       cb;
 
   VERB1("Handling message within the next %.2fs",timeOut);
   
@@ -372,8 +398,8 @@ gras_msg_handle(double timeOut) {
   }
   
   xbt_dynar_foreach(list->cbs,cpt,cb) { 
-    INFO3("Use the callback #%d (@%p) for incomming msg %s",
-         cpt+1,cb,msgtype->name);
+    VERB3("Use the callback #%d (@%p) for incomming msg %s",
+          cpt+1,cb,msgtype->name);
     if ((*cb)(expeditor,payload)) {
       /* cb handled the message */
       xbt_free(payload);
@@ -395,10 +421,16 @@ gras_cbl_free(void *data){
   }
 }
 
+/** \brief Bind the given callback to the given message type 
+ *
+ * Several callbacks can be attached to a given message type. The lastly added one will get the message first, and 
+ * if it returns false, the message will be passed to the second one. 
+ * And so on until one of the callbacks accepts the message.
+ */
 void
 gras_cb_register(gras_msgtype_t msgtype,
-                gras_cb_t cb) {
-  gras_procdata_t *pd=gras_procdata_get();
+                gras_msg_cb_t cb) {
+  gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_get("gras_msg");
   gras_cblist_t *list=NULL;
   int cpt;
 
@@ -416,7 +448,7 @@ gras_cb_register(gras_msgtype_t msgtype,
     /* First cb? Create room */
     list = xbt_new(gras_cblist_t,1);
     list->id = msgtype->code;
-    list->cbs = xbt_dynar_new(sizeof(gras_cb_t), NULL);
+    list->cbs = xbt_dynar_new(sizeof(gras_msg_cb_t), NULL);
     xbt_dynar_push(pd->cbl_list,&list);
   }
 
@@ -424,13 +456,14 @@ gras_cb_register(gras_msgtype_t msgtype,
   xbt_dynar_insert_at(list->cbs,0,&cb);
 }
 
+/** \brief Unbind the given callback from the given message type */
 void
 gras_cb_unregister(gras_msgtype_t msgtype,
-                  gras_cb_t cb) {
+                  gras_msg_cb_t cb) {
 
-  gras_procdata_t *pd=gras_procdata_get();
+  gras_msg_procdata_t pd=(gras_msg_procdata_t)gras_libdata_get("gras_msg");
   gras_cblist_t *list;
-  gras_cb_t cb_cpt;
+  gras_msg_cb_t cb_cpt;
   int cpt;
   int found = 0;
 
index 9c98503..28816ec 100644 (file)
 #ifndef GRAS_MSG_INTERFACE_H
 #define GRAS_MSG_INTERFACE_H
 
-/* gras_msg_t is dereferenced to be stored in procdata, living in Virtu */
+#include "gras/transport.h"
+
+/*
+ * Data of this module specific to each process 
+ * (used by sg_process.c to check some usual errors at the end of the simulation)
+ * FIXME: it could be cleaned up ?
+ */
 typedef struct {
-  gras_socket_t   expeditor;
-  gras_msgtype_t  type;
-  void           *payload;
-  int             payload_size;
-} gras_msg_t;
+  /*queue of msgs storing the ones got while msg_wait'ing for something else */
+  xbt_dynar_t msg_queue; /* elm type: gras_msg_t */
+
+  /* registered callbacks for each message */
+  xbt_dynar_t cbl_list; /* elm type: gras_cblist_t */
+
+} s_gras_msg_procdata_t,*gras_msg_procdata_t;
+
 
 xbt_error_t gras_msg_send_namev(gras_socket_t  sock, 
                                 const char    *namev, 
@@ -26,6 +35,5 @@ xbt_error_t gras_msg_send_namev(gras_socket_t  sock,
 
 #define GRAS_PROTOCOL_VERSION '\0';
 
-typedef struct s_gras_cblist gras_cblist_t;
-void gras_cbl_free(void *); /* virtu use that to free the memory at the end */
+
 #endif  /* GRAS_MSG_INTERFACE_H */
index 74917ae..b812469 100644 (file)
 
 #include "gras/Msg/msg_interface.h"
 
+
+/** @brief Message instance */
+typedef struct {
+  gras_socket_t   expeditor;
+  gras_msgtype_t  type;
+  void           *payload;
+  int             payload_size;
+} gras_msg_t;
+
 /**
  * gras_msgtype_t:
  *
@@ -63,6 +72,24 @@ struct s_gras_cblist {
   xbt_dynar_t cbs; /* of gras_msg_cb_t */
 };
 
+typedef struct s_gras_cblist gras_cblist_t;
+void gras_cbl_free(void *); /* used to free the memory at the end */
 void gras_cblist_free(void *cbl);
 
+
+/* ********* *
+ * * TIMER * *
+ * ********* */
+typedef void (*void_f_void_t)(void);
+  
+typedef struct {
+  double expiry;
+  double period;
+  void_f_void_t action;
+  int repeat;
+} *gras_timer_t;
+
+extern xbt_dynar_t _gras_timers;
+
+
 #endif  /* GRAS_MESSAGE_PRIVATE_H */
index 279642c..d9575ba 100644 (file)
@@ -31,7 +31,7 @@ gras_trp_select(double timeout,
 
   xbt_error_t errcode;
   double startTime=gras_os_time();
-  gras_procdata_t *pd=gras_procdata_get();
+  gras_trp_procdata_t pd=(gras_trp_procdata_t)gras_libdata_get("gras_trp");
   gras_trp_sg_sock_data_t *sockdata;
   gras_trp_plugin_t *trp;
 
index 9aec730..a1788a2 100644 (file)
@@ -418,3 +418,37 @@ xbt_error_t gras_socket_raw_recv(gras_socket_t peer,
   xbt_free(chunk);
   return no_error;/* gras_socket_raw_exchange(peer,0,timeout,expSize,msgSize);    */
 }
+
+/*
+ * Creating procdata for this module
+ */
+static void *gras_trp_procdata_new() {
+   gras_trp_procdata_t res = xbt_new(s_gras_trp_procdata_t,1);
+   
+   res->sockets   = xbt_dynar_new(sizeof(gras_socket_t*), NULL);
+   
+   return (void*)res;
+}
+
+/*
+ * Freeing procdata for this module
+ */
+static void gras_trp_procdata_free(void *data) {
+   gras_trp_procdata_t res = (gras_trp_procdata_t)data;
+   
+   xbt_dynar_free(&( res->sockets ));
+}
+
+/*
+ * Module registration
+ */
+void gras_trp_register() {
+   gras_procdata_add("gras_trp",gras_trp_procdata_new, gras_trp_procdata_free);
+}
+
+
+xbt_dynar_t 
+gras_socketset_get(void) {
+   /* FIXME: KILLME */
+   return ((gras_trp_procdata_t) gras_libdata_get("gras_trp"))->sockets;
+}
index 8768045..b481a3a 100644 (file)
@@ -77,4 +77,15 @@ xbt_error_t
 gras_trp_plugin_get_by_name(const char *name,
                            gras_trp_plugin_t **dst);
 
+/* Data of this module specific to each process
+ * (used by sg_process.c to cleanup the SG channel cruft)
+ */
+typedef struct {
+   /* SG only elements. In RL, they are part of the OS ;) */
+   int chan;    /* Formated messages channel */
+   int rawChan; /* Unformated echange channel */
+   xbt_dynar_t sockets; /* all sockets known to this process */
+   
+} s_gras_trp_procdata_t,*gras_trp_procdata_t;
+
 #endif /* GRAS_TRP_INTERFACE_H */
index e849299..44dbade 100644 (file)
@@ -153,7 +153,7 @@ xbt_error_t gras_trp_sg_socket_server(gras_trp_plugin_t *self,
   xbt_error_t errcode;
 
   gras_hostdata_t *hd=(gras_hostdata_t *)MSG_host_get_data(MSG_host_self());
-  gras_procdata_t *pd=gras_procdata_get();
+  gras_trp_procdata_t pd=(gras_trp_procdata_t)gras_libdata_get("gras_trp");
   gras_sg_portrec_t pr;
   gras_trp_sg_sock_data_t *data;
   
@@ -259,7 +259,7 @@ xbt_error_t gras_trp_sg_chunk_send(gras_socket_t sock,
 xbt_error_t gras_trp_sg_chunk_recv(gras_socket_t sock,
                                    char *data,
                                    long int size){
-  gras_procdata_t *pd=gras_procdata_get();
+  gras_trp_procdata_t pd=(gras_trp_procdata_t)gras_libdata_get("gras_trp");
 
   m_task_t task=NULL;
   sg_task_data_t *task_data;
@@ -302,7 +302,7 @@ xbt_error_t gras_socket_raw_exchange(gras_socket_t peer,
   char name[256];
   gras_trp_sg_sock_data_t *sock_data = (gras_trp_sg_sock_data_t *)peer->data;
   
-  gras_procdata_t *pd=gras_procdata_get();
+  gras_trp_procdata_t pd=(gras_trp_procdata_t)gras_libdata_get("gras_trp");
   double startTime;
   
   startTime=gras_os_time(); /* used only in sender mode */
index 630d887..8c3a3a1 100644 (file)
@@ -93,4 +93,6 @@ xbt_error_t gras_socket_raw_exchange(gras_socket_t peer,
                                      unsigned long int expSize,
                                      unsigned long int msgSize);
 
+xbt_dynar_t gras_socketset_get(void); /* FIXME:KILLME */
+
 #endif /* GRAS_TRP_PRIVATE_H */
index e18b3f2..27b401a 100644 (file)
 #include "gras/transport.h"
 #include "gras/datadesc.h"
 #include "gras/messages.h"
+#include "gras_modinter.h"
 
-#include "gras/Virtu/virtu_interface.h"
-#include "gras/Msg/msg_interface.h" /* FIXME: Get rid of this cyclic */
+#include "gras/Virtu/virtu_private.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(process,gras,"Process manipulation code");
 
+
+/* Functions to handle gras_procdata_t->libdata cells*/
+typedef struct {
+   char *name;
+   pvoid_f_void_t *creator;
+   void_f_pvoid_t *destructor;
+} s_gras_procdata_fabric_t, *gras_procdata_fabric_t;
+
+static xbt_dynar_t _gras_procdata_fabrics = NULL; /* content: s_gras_procdata_fabric_t */
+
+static void gras_procdata_fabric_free(void *fab) {
+   free( ((gras_procdata_fabric_t)fab)->name );
+}
+
+/** @brief declare the functions in charge of creating/destructing the procdata of a module
+ *  
+ *  This is intended to be called from the gras_<module>_register function.
+ */
+void gras_procdata_add(const char *name, pvoid_f_void_t creator,void_f_pvoid_t destructor) {
+   
+   gras_procdata_fabric_t fab;
+   
+   if (!_gras_procdata_fabrics) {
+      /* create the dynar if needed */
+      _gras_procdata_fabrics = xbt_dynar_new(sizeof(s_gras_procdata_fabric_t),
+                                            gras_procdata_fabric_free);
+   }
+   
+   fab=xbt_dynar_push_ptr(_gras_procdata_fabrics);
+   
+   fab->name       = xbt_strdup(name);
+   fab->creator    = creator;
+   fab->destructor = destructor;
+}
+
 /* **************************************************************************
  * Process data
  * **************************************************************************/
@@ -33,25 +68,50 @@ void gras_userdata_set(void *ud) {
   pd->userdata = ud;
 }
 
+void *gras_libdata_get(const char *name) {
+  gras_procdata_t *pd=gras_procdata_get();
+  void *res;
+  xbt_error_t errcode;
+   
+  errcode = xbt_dict_get(pd->libdata, name, &res);
+  xbt_assert2(errcode == no_error, 
+             "Cannot retrive the libdata associated to %s: %s",
+             name, xbt_error_name(errcode));
+   
+  return res;
+}
+
 void
 gras_procdata_init() {
   gras_procdata_t *pd=gras_procdata_get();
+  s_gras_procdata_fabric_t fab;
+   
+  int cursor;
+   
+  xbt_error_t errcode;
+  void *data;
+
   pd->userdata  = NULL;
-  pd->msg_queue = xbt_dynar_new(sizeof(gras_msg_t),     NULL);
-  pd->cbl_list  = xbt_dynar_new(sizeof(gras_cblist_t *),gras_cbl_free);
-  pd->sockets   = xbt_dynar_new(sizeof(gras_socket_t*), NULL);
+  pd->libdata   = xbt_dict_new();
+   
+  xbt_dynar_foreach(_gras_procdata_fabrics,cursor,fab){
+     
+     xbt_assert1(fab.name,"Name of fabric #%d is NULL!",cursor);
+     DEBUG1("Create the procdata for %s",fab.name);
+     /* Check for our own errors */
+     errcode = xbt_dict_get(pd->libdata, fab.name, &data);
+     xbt_assert1(errcode == mismatch_error,
+                "MayDay: two modules use '%s' as libdata name", fab.name);
+     
+     /* Add the data in place */
+     xbt_dict_set(pd->libdata, fab.name, (fab.creator)(), fab.destructor);
+
+  }
 }
 
 void
 gras_procdata_exit() {
   gras_procdata_t *pd=gras_procdata_get();
 
-  xbt_dynar_free(&( pd->msg_queue ));
-  xbt_dynar_free(&( pd->cbl_list ));
-  xbt_dynar_free(&( pd->sockets ));
-}
-
-xbt_dynar_t 
-gras_socketset_get(void) {
-   return gras_procdata_get()->sockets;
+  xbt_dict_free(&( pd->libdata ));
 }
index f256d98..ae191c3 100644 (file)
@@ -7,6 +7,7 @@
 /* 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_modinter.h" /* module initialization interface */
 #include "gras/Virtu/virtu_rl.h"
 
 XBT_LOG_EXTERNAL_CATEGORY(process);
@@ -31,7 +32,7 @@ xbt_error_t gras_process_exit() {
  * **************************************************************************/
 
 gras_procdata_t *gras_procdata_get(void) {
-  xbt_assert0(_gras_procdata,"Run gras_process_init!");
+  xbt_assert0(_gras_procdata,"Run gras_process_init (ie, gras_init)!");
 
   return _gras_procdata;
 }
index ce1c279..838a74c 100644 (file)
@@ -7,7 +7,10 @@
 /* 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_modinter.h" /* module initialization interface */
 #include "gras/Virtu/virtu_sg.h"
+#include "gras/Msg/msg_interface.h" /* For some checks at simulation end */
+#include "gras/Transport/transport_interface.h" /* For some checks at simulation end */
 
 XBT_LOG_EXTERNAL_CATEGORY(process);
 XBT_LOG_DEFAULT_CATEGORY(process);
@@ -16,17 +19,18 @@ xbt_error_t
 gras_process_init() {
   xbt_error_t errcode;
   gras_hostdata_t *hd=(gras_hostdata_t *)MSG_host_get_data(MSG_host_self());
-  gras_procdata_t *pd;
+  gras_procdata_t *pd=xbt_new(gras_procdata_t,1);
+  gras_trp_procdata_t trp_pd;
   gras_sg_portrec_t prraw,pr;
   int i;
   
-  pd=xbt_new(gras_procdata_t,1);
-
   if (MSG_process_set_data(MSG_process_self(),(void*)pd) != MSG_OK)
     return unknown_error;
+   
   gras_procdata_init();
 
   if (!hd) {
+    /* First process on this host */
     hd=xbt_new(gras_hostdata_t,1);
     hd->ports = xbt_dynar_new(sizeof(gras_sg_portrec_t),NULL);
 
@@ -37,13 +41,14 @@ gras_process_init() {
   }
   
   /* take a free channel for this process */
+  trp_pd = (gras_trp_procdata_t)gras_libdata_get("gras_trp");
   for (i=0; i<XBT_MAX_CHANNEL && hd->proc[i]; i++);
   if (i == XBT_MAX_CHANNEL) 
     RAISE2(system_error,
           "GRAS: Can't add a new process on %s, because all channel are already in use. Please increase MAX CHANNEL (which is %d for now) and recompile GRAS\n.",
            MSG_host_get_name(MSG_host_self()),XBT_MAX_CHANNEL);
 
-  pd->chan = i;
+  trp_pd->chan = i;
   hd->proc[ i ] = MSG_process_self_PID();
 
   /* regiter it to the ports structure */
@@ -59,11 +64,11 @@ gras_process_init() {
           "GRAS: Can't add a new process on %s, because all channel are already in use. Please increase MAX CHANNEL (which is %d for now) and recompile GRAS\n.",
            MSG_host_get_name(MSG_host_self()),XBT_MAX_CHANNEL);
   }
-  pd->rawChan = i;
+  trp_pd->rawChan = i;
 
   hd->proc[ i ] = MSG_process_self_PID();
 
-  /* regiter it to the ports structure */
+  /* register it to the ports structure */
   prraw.port = -1;
   prraw.tochan = i;
   prraw.raw = 1;
@@ -78,17 +83,18 @@ gras_process_init() {
 xbt_error_t
 gras_process_exit() {
   gras_hostdata_t *hd=(gras_hostdata_t *)MSG_host_get_data(MSG_host_self());
-  gras_procdata_t *pd=gras_procdata_get();
+  gras_msg_procdata_t msg_pd=(gras_msg_procdata_t)gras_libdata_get("gras_msg");
+  gras_trp_procdata_t trp_pd=(gras_trp_procdata_t)gras_libdata_get("gras_trp");
   int myPID=MSG_process_self_PID();
   int cpt;
   gras_sg_portrec_t pr;
 
-  xbt_assert0(hd && pd,"Run gras_process_init!!");
+  xbt_assert0(hd,"Run gras_process_init (ie, gras_init)!!");
 
   INFO2("GRAS: Finalizing process '%s' (%d)",
        MSG_process_get_name(MSG_process_self()),MSG_process_self_PID());
 
-  if (xbt_dynar_length(pd->msg_queue))
+  if (xbt_dynar_length(msg_pd->msg_queue))
     WARN1("process %d terminated, but some messages are still queued",
          MSG_process_self_PID());
 
@@ -97,7 +103,7 @@ gras_process_exit() {
       hd->proc[cpt] = 0;
 
   xbt_dynar_foreach(hd->ports, cpt, pr) {
-    if (pr.port == pd->chan || pr.port == pd->rawChan) {
+    if (pr.port == trp_pd->chan || pr.port == trp_pd->rawChan) {
       xbt_dynar_cursor_rm(hd->ports, &cpt);
     }
   }
@@ -113,7 +119,7 @@ gras_procdata_t *gras_procdata_get(void) {
   gras_procdata_t *pd=
     (gras_procdata_t *)MSG_process_get_data(MSG_process_self());
 
-  xbt_assert0(pd,"Run gras_process_init!");
+  xbt_assert0(pd,"Run gras_process_init! (ie, gras_init)");
 
   return pd;
 }
index 2a5ebd8..178a39b 100644 (file)
 #include "xbt/log.h"
 #include "xbt/error.h"
 #include "xbt/dynar.h"
+#include "xbt/dict.h"
 #include "gras/virtu.h"
 #include "gras/process.h"
 
-/**
- * gras_process_data_t:
- *
- * Data for each process 
- */
-typedef struct {
-  /*queue of msgs storing the ones got while msg_wait'ing for something else */
-  xbt_dynar_t msg_queue; /* elm type: gras_msg_t */
-
-  /* registered callbacks for each message */
-  xbt_dynar_t cbl_list; /* elm type: gras_cblist_t */
-   
-  /* SG only elements. In RL, they are part of the OS ;) */
-  int chan;    /* Formated messages channel */
-  int rawChan; /* Unformated echange channel */
-  xbt_dynar_t sockets; /* all sockets known to this process */
-
-  /* globals of the process */
-  void *userdata;               
-} gras_procdata_t;
-
-/* Access */
-xbt_dynar_t gras_socketset_get(void);
-
-/* FIXME: mv to _private? */
-gras_procdata_t *gras_procdata_get(void);
-void gras_procdata_init(void);
-void gras_procdata_exit(void);
+/* declare a new process specific data 
+   (used by gras_<module>_register to make sure that gras_process_init will create it) */
+
+typedef void* (pvoid_f_void_t)(void); /* FIXME: find a better place for it */
+
+void gras_procdata_add(const char *name, pvoid_f_void_t creator,void_f_pvoid_t destructor);
+void *gras_libdata_get(const char *name);
+
 #endif  /* GRAS_VIRTU_INTERFACE_H */
diff --git a/src/gras/Virtu/virtu_private.h b/src/gras/Virtu/virtu_private.h
new file mode 100644 (file)
index 0000000..0a677a9
--- /dev/null
@@ -0,0 +1,30 @@
+/* $Id$ */
+
+/* virtu[alization] - speciafic parts for each OS and for SG                */
+
+/* module's private interface.                                              */
+
+/* Copyright (c) 2004 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. */
+
+
+#ifndef GRAS_VIRTU_PRIVATE_H
+#define GRAS_VIRTU_PRIVATE_H
+
+#include "gras/Virtu/virtu_interface.h"
+
+/** @brief Data for each process */
+typedef struct {
+  /* globals of the process */
+  void *userdata;
+
+  /* data specific to each process for each module. 
+     Registered with gras_procdata_add(), retrieved with gras_libdata_get() */
+  xbt_dict_t libdata;
+} gras_procdata_t;
+
+gras_procdata_t *gras_procdata_get(void);
+
+#endif  /* GRAS_VIRTU_PRIVATE_H */
index 29019aa..0a30c4a 100644 (file)
@@ -10,6 +10,6 @@
 #ifndef VIRTU_RL_H
 #define VIRTU_RL_H
 
-#include "gras/Virtu/virtu_interface.h"
+#include "gras/Virtu/virtu_private.h"
 
 #endif /* VIRTU_RL_H */
index 53c0bd1..45ffaad 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef VIRTU_SG_H
 #define VIRTU_SG_H
 
-#include "gras/Virtu/virtu_interface.h"
+#include "gras/Virtu/virtu_private.h"
 #include "msg/msg.h" /* SimGrid header */
 
 #define XBT_MAX_CHANNEL 10
index 5c9140e..d3b2288 100644 (file)
@@ -24,9 +24,27 @@ static int gras_running_process = 0;
 void gras_init(int *argc,char **argv, const char *defaultlog) {
 
   INFO0("Initialize GRAS");
+  
+  /* First initialize the XBT */
   xbt_init_defaultlog(argc,argv,defaultlog);
-  gras_process_init(); /* calls procdata_init, which calls dynar_new */
-  /** init other submodules */
+   
+  
+  /* module registrations: 
+   *    - declare process specific data we need (without creating them) 
+   */
+  if (gras_running_process == 0) {
+     gras_trp_register();
+     gras_msg_register();
+  }
+   
+  /*
+   * Initialize the process specific stuff
+   */
+  gras_process_init(); /* calls procdata_init, which creates process specific data for each module */
+  
+  /*
+   * Initialize the global stuff if it's not the first process created
+   */
   if (gras_running_process++ == 0) {
     gras_msg_init();
     gras_trp_init();