From 3c79423e7376662ff7bcfa809c4803564cf82acb Mon Sep 17 00:00:00 2001 From: mquinson Date: Sun, 13 Feb 2005 16:30:30 +0000 Subject: [PATCH] New functionality: possibility for libraries to register globals on each process. Just like userdata, but in a dictionnary to let them all coexist. Todo: change it to a xbt_set_t so that performance don't suffer. Use it in gras (msg and trp). Plus some little doxygen cleanups git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@996 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- src/gras/DataDesc/ddt_create.c | 59 +++++++-------- src/gras/Msg/msg.c | 91 ++++++++++++++++-------- src/gras/Msg/msg_interface.h | 24 ++++--- src/gras/Msg/msg_private.h | 27 +++++++ src/gras/Transport/sg_transport.c | 2 +- src/gras/Transport/transport.c | 34 +++++++++ src/gras/Transport/transport_interface.h | 11 +++ src/gras/Transport/transport_plugin_sg.c | 6 +- src/gras/Transport/transport_private.h | 2 + src/gras/Virtu/process.c | 86 ++++++++++++++++++---- src/gras/Virtu/rl_process.c | 3 +- src/gras/Virtu/sg_process.c | 28 +++++--- src/gras/Virtu/virtu_interface.h | 37 +++------- src/gras/Virtu/virtu_private.h | 30 ++++++++ src/gras/Virtu/virtu_rl.h | 2 +- src/gras/Virtu/virtu_sg.h | 2 +- src/gras/gras.c | 22 +++++- 17 files changed, 336 insertions(+), 130 deletions(-) create mode 100644 src/gras/Virtu/virtu_private.h diff --git a/src/gras/DataDesc/ddt_create.c b/src/gras/DataDesc/ddt_create.c index ebb8df9ea1..84cc1023db 100644 --- a/src/gras/DataDesc/ddt_create.c +++ b/src/gras/DataDesc/ddt_create.c @@ -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. diff --git a/src/gras/Msg/msg.c b/src/gras/Msg/msg.c index 13f8155193..50c529f1db 100644 --- a/src/gras/Msg/msg.c +++ b/src/gras/Msg/msg.c @@ -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; diff --git a/src/gras/Msg/msg_interface.h b/src/gras/Msg/msg_interface.h index 9c98503096..28816ec3f0 100644 --- a/src/gras/Msg/msg_interface.h +++ b/src/gras/Msg/msg_interface.h @@ -12,13 +12,22 @@ #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 */ diff --git a/src/gras/Msg/msg_private.h b/src/gras/Msg/msg_private.h index 74917aeff8..b8124694a5 100644 --- a/src/gras/Msg/msg_private.h +++ b/src/gras/Msg/msg_private.h @@ -28,6 +28,15 @@ #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 */ diff --git a/src/gras/Transport/sg_transport.c b/src/gras/Transport/sg_transport.c index 279642c227..d9575baced 100644 --- a/src/gras/Transport/sg_transport.c +++ b/src/gras/Transport/sg_transport.c @@ -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; diff --git a/src/gras/Transport/transport.c b/src/gras/Transport/transport.c index 9aec7307e3..a1788a2b91 100644 --- a/src/gras/Transport/transport.c +++ b/src/gras/Transport/transport.c @@ -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; +} diff --git a/src/gras/Transport/transport_interface.h b/src/gras/Transport/transport_interface.h index 8768045658..b481a3a6a7 100644 --- a/src/gras/Transport/transport_interface.h +++ b/src/gras/Transport/transport_interface.h @@ -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 */ diff --git a/src/gras/Transport/transport_plugin_sg.c b/src/gras/Transport/transport_plugin_sg.c index e849299a16..44dbade782 100644 --- a/src/gras/Transport/transport_plugin_sg.c +++ b/src/gras/Transport/transport_plugin_sg.c @@ -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 */ diff --git a/src/gras/Transport/transport_private.h b/src/gras/Transport/transport_private.h index 630d887a27..8c3a3a1907 100644 --- a/src/gras/Transport/transport_private.h +++ b/src/gras/Transport/transport_private.h @@ -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 */ diff --git a/src/gras/Virtu/process.c b/src/gras/Virtu/process.c index e18b3f29c5..27b401a91b 100644 --- a/src/gras/Virtu/process.c +++ b/src/gras/Virtu/process.c @@ -13,12 +13,47 @@ #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__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 )); } diff --git a/src/gras/Virtu/rl_process.c b/src/gras/Virtu/rl_process.c index f256d9824a..ae191c35c3 100644 --- a/src/gras/Virtu/rl_process.c +++ b/src/gras/Virtu/rl_process.c @@ -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; } diff --git a/src/gras/Virtu/sg_process.c b/src/gras/Virtu/sg_process.c index ce1c279b04..838a74c864 100644 --- a/src/gras/Virtu/sg_process.c +++ b/src/gras/Virtu/sg_process.c @@ -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; iproc[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; } diff --git a/src/gras/Virtu/virtu_interface.h b/src/gras/Virtu/virtu_interface.h index 2a5ebd86b0..178a39b424 100644 --- a/src/gras/Virtu/virtu_interface.h +++ b/src/gras/Virtu/virtu_interface.h @@ -16,35 +16,16 @@ #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__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 index 0000000000..0a677a9718 --- /dev/null +++ b/src/gras/Virtu/virtu_private.h @@ -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 */ diff --git a/src/gras/Virtu/virtu_rl.h b/src/gras/Virtu/virtu_rl.h index 29019aa8af..0a30c4a19a 100644 --- a/src/gras/Virtu/virtu_rl.h +++ b/src/gras/Virtu/virtu_rl.h @@ -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 */ diff --git a/src/gras/Virtu/virtu_sg.h b/src/gras/Virtu/virtu_sg.h index 53c0bd1c6d..45ffaad804 100644 --- a/src/gras/Virtu/virtu_sg.h +++ b/src/gras/Virtu/virtu_sg.h @@ -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 diff --git a/src/gras/gras.c b/src/gras/gras.c index 5c9140e3c0..d3b228847a 100644 --- a/src/gras/gras.c +++ b/src/gras/gras.c @@ -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(); -- 2.20.1