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) {
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,
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) {
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;
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;
}
-/** 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) {
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.
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,
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;
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.
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.
*/
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
*/
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
&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;
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,
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
* @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,
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;
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) {
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);
}
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);
}
}
+/** \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;
/* 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);
}
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;
#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,
#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 */
#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:
*
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 */
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;
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;
+}
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 */
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;
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;
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 */
unsigned long int expSize,
unsigned long int msgSize);
+xbt_dynar_t gras_socketset_get(void); /* FIXME:KILLME */
+
#endif /* GRAS_TRP_PRIVATE_H */
#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
* **************************************************************************/
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 ));
}
/* 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);
* **************************************************************************/
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;
}
/* 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);
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);
}
/* 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 */
"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;
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());
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);
}
}
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;
}
#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 */
--- /dev/null
+/* $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 */
#ifndef VIRTU_RL_H
#define VIRTU_RL_H
-#include "gras/Virtu/virtu_interface.h"
+#include "gras/Virtu/virtu_private.h"
#endif /* VIRTU_RL_H */
#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
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();