From 1bbfe6dff09cff639aaab8fd2898678a5a630c2b Mon Sep 17 00:00:00 2001 From: mquinson Date: Wed, 21 Apr 2004 18:44:57 +0000 Subject: [PATCH] [Data description] - register init/exit functions within gras module mecanism - send/receive function. Convertion is not implemented, but short-cutted if not needed. struct/array elements are sent one by one (instead of block-wise), but nobody really cares (yet). Get a prototype before optimizing. - tests (using a file socket) for DD send/receive on: - base types: int, float - array: fixed size, string (ie ref to dynamic string) - structure: homogeneous, heterogeneous - chained list, graph with cycle Believe it or not, valgrind is not too unhappy with the results. The cycle happily segfaults, but the others are ok. And I'm sick of pointers for now. [Transport] [File plugin] - Bugfix when using a filename explicitely (instead of '-') git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@82 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- UNIMPLEMENTED | 26 + changelog | 42 ++ configure | 2 +- cruft/doc/tmpl/comm_socks.sgml | 5 +- include/datadesc.h | 11 + include/error.h | 12 +- src/gras/DataDesc/cbps.c | 68 ++- src/gras/DataDesc/datadesc.c | 91 +++- src/gras/DataDesc/datadesc_interface.h | 5 +- src/gras/DataDesc/datadesc_private.h | 35 +- src/gras/DataDesc/ddt_create.c | 31 +- src/gras/DataDesc/ddt_declare.c | 24 +- src/gras/DataDesc/ddt_remote.c | 48 +- src/gras/DataDesc/ddt_use.c | 577 ++++++++++++++++++++- src/gras/Makefile.am | 3 +- src/gras/Transport/transport_plugin_file.c | 28 +- src/xbt/module.c | 4 +- src/xbt/set.c | 8 +- testsuite/Makefile.am | 5 +- testsuite/gras/datadesc_usage.c | 400 ++++++++++++++ testsuite/xbt/dynar_string.c | 15 +- 21 files changed, 1294 insertions(+), 146 deletions(-) create mode 100644 UNIMPLEMENTED create mode 100644 changelog create mode 100644 testsuite/gras/datadesc_usage.c diff --git a/UNIMPLEMENTED b/UNIMPLEMENTED new file mode 100644 index 0000000000..6561e1d459 --- /dev/null +++ b/UNIMPLEMENTED @@ -0,0 +1,26 @@ +- gras_dd_convert_elm + gras_datadesc_cpy + +- callback en reception ?? + +- Virer cat ignored + +gras_ddt_new_ignored : Pas portable (taille) => virer cat? + +gras_ddt_new_parse +gras_ddt_new_from_nws + + + +gras_trp_select [SG] + +gras_trp_sg_socket_client +gras_trp_sg_socket_server +gras_trp_sg_socket_close +gras_trp_sg_select +gras_trp_sg_bloc_send +gras_trp_sg_bloc_recv +gras_trp_sg_flush + +tcp->incoming_socks +sock specific tcp (buffsize) inutile diff --git a/changelog b/changelog new file mode 100644 index 0000000000..a0910cf715 --- /dev/null +++ b/changelog @@ -0,0 +1,42 @@ +2004-04-19 Martin Quinson + [Data description] + - register init/exit functions within gras module mecanism + - send/receive function. + Convertion is not implemented, but short-cutted if not needed. + struct/array elements are sent one by one (instead of block-wise), but + nobody really cares (yet). Get a prototype before optimizing. + - tests (using a file socket) for DD send/receive on: + - base types: int, float + - array: fixed size, string (ie ref to dynamic string) + - structure: homogeneous, heterogeneous + - chained list, graph with cycle + Believe it or not, valgrind is not too unhappy with the results. The + cycle happily segfaults, but the others are ok. And I'm sick of pointers + for now. + [Transport] + [File plugin] + - Bugfix when using a filename explicitely (instead of '-') + [SG plugin] + - Porting to new standards. + [SG select] + - Porting to new standards. + +2004-04-09 Martin Quinson + [Transport plugins] + - factorize more code between RL and SG in socket creation + - Complete the implementation and tests of: + o TCP + o file (only in RL, and mainly for debugging) + + I lost 3 days to design a portable address resolver, and then decided + that the prototype mainly have to run on my box. + Addressing portability too early may be like optimizing too early :-/ + [Tests] + - use gras_init in the Tests instead of the crappy parse_log_opt + (the latter function is removed) + [Conditional execution] + - New functions: gras_if_RL/gras_if_SG (basic support for this) + [Code reorganisation] + - Get rid of libgrasutils.a since it makes more trouble than it solves. + Build examples against the RL library, since there is no way to disable + its creation for now. diff --git a/configure b/configure index bfd4563a87..c5892ff6aa 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac Revision: 1.5 . +# From configure.ac Revision: 1.6 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for GRAS 0.0.040304. # diff --git a/cruft/doc/tmpl/comm_socks.sgml b/cruft/doc/tmpl/comm_socks.sgml index e918bf5898..6bc7b7d6ce 100644 --- a/cruft/doc/tmpl/comm_socks.sgml +++ b/cruft/doc/tmpl/comm_socks.sgml @@ -21,10 +21,10 @@ Open/close sockets, and get info on peer. @host: @Param2: -@bufSize: @dst: @Returns: +@bufSize: @sock: @@ -34,9 +34,10 @@ Open/close sockets, and get info on peer. @Param1: -@bufSize: @dst: @Returns: + +@bufSize: diff --git a/include/datadesc.h b/include/datadesc.h index a8cfa40023..f50c9c4ae3 100644 --- a/include/datadesc.h +++ b/include/datadesc.h @@ -45,6 +45,12 @@ typedef struct s_gras_datadesc_type gras_datadesc_type_t; ***********************************************/ long int gras_datadesc_get_id_from_name(const char *name); +gras_error_t gras_datadesc_by_name(const char *name, + gras_datadesc_type_t **type); +gras_error_t gras_datadesc_by_id (long int code, + gras_datadesc_type_t **type); +#define gras_datadesc_by_code(a,b) gras_datadesc_by_id(a,b) + /********************************************* **** DataDesc callback persistent states **** *********************************************/ @@ -170,6 +176,11 @@ gras_datadesc_declare_array_cb(const char *name, gras_datadesc_type_cb_void_t post, long int *code); +/******************************* + **** About data convertion **** + *******************************/ +int gras_arch_selfid(void); /* ID of this arch */ + /**************************** **** Parse C statements **** ****************************/ diff --git a/include/error.h b/include/error.h index 58c89adf37..49b91bcc95 100644 --- a/include/error.h +++ b/include/error.h @@ -52,11 +52,19 @@ typedef enum { /*@observer@*/ const char *gras_error_name(gras_error_t errcode); -#define TRY(a) if ((errcode=a) != no_error) return errcode +#define TRY(a) do { \ + if ((errcode=a) != no_error) { \ + fprintf (stderr, "%s:%d: '%s' error raising...\n", \ + __FILE__,__LINE__, \ + gras_error_name(errcode)); \ + return errcode; \ + } } while (0) + #define TRYCATCH(a,b) if ((errcode=a) != no_error && errcode !=b) return errcode #define TRYFAIL(a) do { \ if ((errcode=a) != no_error) { \ - fprintf(stderr,"Got '%s' error !\n", \ + fprintf(stderr,"%s:%d: Got '%s' error !\n", \ + __FILE__,__LINE__, \ gras_error_name(errcode)); \ fflush(stdout); \ abort(); \ diff --git a/src/gras/DataDesc/cbps.c b/src/gras/DataDesc/cbps.c index 02e320ee3e..1c801fcd27 100644 --- a/src/gras/DataDesc/cbps.c +++ b/src/gras/DataDesc/cbps.c @@ -19,15 +19,42 @@ struct s_gras_dd_cbps { gras_dict_t *space; gras_dynar_t *stack; gras_dynar_t *globals; - }; +gras_error_t +gras_dd_cbps_new(gras_dd_cbps_t **dst) { + gras_error_t errcode; + gras_dd_cbps_t *res; + + if (!(res=malloc(sizeof(gras_dd_cbps_t)))) + RAISE_MALLOC; + + TRY(gras_dict_new(&(res->space))); + /* FIXME:leaking on content of dynars*/ + TRY(gras_dynar_new(&(res->stack), sizeof(gras_dynar_t*), NULL)); + TRY(gras_dynar_new(&(res->globals), sizeof(char*), NULL)); + + *dst = res; + return no_error; +} + +void +gras_dd_cbps_free(gras_dd_cbps_t **state) { + + gras_dict_free ( &( (*state)->space ) ); + gras_dynar_free( (*state)->stack ); + gras_dynar_free( (*state)->globals ); + + free(*state); + *state = NULL; +} + /** * gras_dd_cbps_push: * - * Declare a new element in the PS, and give it a value. If an element of that name already exists, - * it becomes masked by the one given here, and will be seable again only after a pop to remove the - * value this push adds. + * Declare a new element in the PS, and give it a value. If an element of that + * name already exists, it is masked by the one given here, and will be + * seeable again only after a pop to remove the value this push adds. */ void gras_dd_cbps_push(gras_dd_cbps_t *ps, @@ -60,8 +87,9 @@ gras_dd_cbps_push(gras_dd_cbps_t *ps, /** * gras_dd_cbps_pop: * - * Retrieve an element from the PS, and remove it from the PS. If it's not present in the current block, - * it will fail (with abort) and not search in upper blocks since this denotes a programmation error. + * Retrieve an element from the PS, and remove it from the PS. If it's not + * present in the current block, it will fail (with abort) and not search + * in upper blocks since this denotes a programmation error. */ void * gras_dd_cbps_pop (gras_dd_cbps_t *ps, @@ -112,11 +140,14 @@ gras_dd_cbps_pop (gras_dd_cbps_t *ps, /** * gras_dd_cbps_set: * - * Change the value of an element in the PS. If it's not present in the current block, look in the upper ones. - * If it's not present in any of them, look in the globals (FIXME: which no function of this API allows to set). + * Change the value of an element in the PS. + * If it's not present in the current block, look in the upper ones. + * If it's not present in any of them, look in the globals + * (FIXME: which no function of this API allows to set). * If not present there neither, the code may segfault (Oli?). * - * Once a reference to an element of that name is found somewhere in the PS, its value is changed. + * Once a reference to an element of that name is found somewhere in the PS, + * its value is changed. */ void gras_dd_cbps_set (gras_dd_cbps_t *ps, @@ -149,9 +180,11 @@ gras_dd_cbps_set (gras_dd_cbps_t *ps, /** * gras_dd_cbps_get: * - * Get the value of an element in the PS without modifying it. + * Get the value of an element in the PS without modifying it. + * (note that you get the content of the data struct and not a copy to it) * If it's not present in the current block, look in the upper ones. - * If it's not present in any of them, look in the globals (FIXME: which no function of this API allows to set). + * If it's not present in any of them, look in the globals + * (FIXME: which no function of this API allows to set). * If not present there neither, the code may segfault (Oli?). */ void * @@ -180,11 +213,13 @@ gras_dd_cbps_get (gras_dd_cbps_t *ps, * * Begins a new block. * - * Blocks are usefull to remove a whole set of declarations you don't even know. + * Blocks are usefull to remove a whole set of declarations you don't even know * - * For example, they constitute a very elegent solution to recursive data structures. - * push/pop may be used in some cases for that, but if your recursive data struct contains - * other structs needing themselves callbacks, you have to use block_{begin,end} to do the trick. + * E.g., they constitute an elegent solution to recursive data structures. + * + * push/pop may be used in some cases for that, but if your recursive data + * struct contains other structs needing themselves callbacks, you have to + * use block_{begin,end} to do the trick. */ void @@ -211,7 +246,6 @@ gras_dd_cbps_block_end(gras_dd_cbps_t *ps) { gras_dynar_pop(ps->stack, &p_dynar); gras_dynar_foreach(p_dynar, cursor, name) { - /* inline the code of _gs_vars_pop(p_vars, name), which was used only once */ gras_dynar_t *p_dynar_elm = NULL; gras_dd_cbps_elm_t *p_elm = NULL; @@ -227,7 +261,7 @@ gras_dd_cbps_block_end(gras_dd_cbps_t *ps) { free(p_elm); free(name); } - + gras_dynar_free_container(p_dynar); } diff --git a/src/gras/DataDesc/datadesc.c b/src/gras/DataDesc/datadesc.c index 984df708ad..1154629173 100644 --- a/src/gras/DataDesc/datadesc.c +++ b/src/gras/DataDesc/datadesc.c @@ -28,7 +28,9 @@ _strlen_cb(void *vars, /** * gras_datadesc_init: * - * Initialize the datadesc module + * Initialize the datadesc module. + * FIXME: We assume that when neither signed nor unsigned is given, + * that means signed. To be checked by configure. **/ void gras_datadesc_init(void) { @@ -36,88 +38,129 @@ gras_datadesc_init(void) { gras_datadesc_type_t *ddt; /* What to add */ gras_datadesc_type_t *elm; /* element of ddt when needed */ + /* only initialize once */ + if (gras_datadesc_set_local != NULL) + return; + VERB0("Initializing DataDesc"); TRYFAIL(gras_set_new(&gras_datadesc_set_local)); TRYFAIL(gras_ddt_new_scalar("signed char", - gras_ddt_scalar_char, e_gras_dd_scalar_encoding_sint, + gras_ddt_scalar_char, + e_gras_dd_scalar_encoding_sint, + NULL, &ddt)); + TRYFAIL(gras_ddt_new_scalar("char", + gras_ddt_scalar_char, + e_gras_dd_scalar_encoding_sint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); TRYFAIL(gras_ddt_new_scalar("unsigned char", - gras_ddt_scalar_char, e_gras_dd_scalar_encoding_uint, + gras_ddt_scalar_char, + e_gras_dd_scalar_encoding_uint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); TRYFAIL(gras_ddt_new_scalar("signed short int", - gras_ddt_scalar_short, e_gras_dd_scalar_encoding_sint, + gras_ddt_scalar_short, + e_gras_dd_scalar_encoding_sint, + NULL, &ddt)); + TRYFAIL(gras_ddt_register(ddt)); + TRYFAIL(gras_ddt_new_scalar("short int", + gras_ddt_scalar_short, + e_gras_dd_scalar_encoding_sint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); - TRYFAIL(gras_ddt_new_scalar("unsigned short int", - gras_ddt_scalar_short, e_gras_dd_scalar_encoding_uint, + gras_ddt_scalar_short, + e_gras_dd_scalar_encoding_uint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); TRYFAIL(gras_ddt_new_scalar("signed int", - gras_ddt_scalar_int, e_gras_dd_scalar_encoding_sint, + gras_ddt_scalar_int, + e_gras_dd_scalar_encoding_sint, + NULL, &ddt)); + TRYFAIL(gras_ddt_register(ddt)); + TRYFAIL(gras_ddt_new_scalar("int", + gras_ddt_scalar_int, + e_gras_dd_scalar_encoding_sint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); - TRYFAIL(gras_ddt_new_scalar("unsigned int", - gras_ddt_scalar_int, e_gras_dd_scalar_encoding_uint, + gras_ddt_scalar_int, + e_gras_dd_scalar_encoding_uint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); TRYFAIL(gras_ddt_new_scalar("signed long int", - gras_ddt_scalar_long, e_gras_dd_scalar_encoding_sint, + gras_ddt_scalar_long, + e_gras_dd_scalar_encoding_sint, + NULL, &ddt)); + TRYFAIL(gras_ddt_register(ddt)); + TRYFAIL(gras_ddt_new_scalar("long int", + gras_ddt_scalar_long, + e_gras_dd_scalar_encoding_sint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); - TRYFAIL(gras_ddt_new_scalar("unsigned long int", - gras_ddt_scalar_long, e_gras_dd_scalar_encoding_uint, + gras_ddt_scalar_long, + e_gras_dd_scalar_encoding_uint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); TRYFAIL(gras_ddt_new_scalar("signed long long int", - gras_ddt_scalar_long_long, e_gras_dd_scalar_encoding_sint, + gras_ddt_scalar_long_long, + e_gras_dd_scalar_encoding_sint, + NULL, &ddt)); + TRYFAIL(gras_ddt_register(ddt)); + TRYFAIL(gras_ddt_new_scalar("long long int", + gras_ddt_scalar_long_long, + e_gras_dd_scalar_encoding_sint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); - TRYFAIL(gras_ddt_new_scalar("unsigned long long int", - gras_ddt_scalar_long_long, e_gras_dd_scalar_encoding_uint, + gras_ddt_scalar_long_long, + e_gras_dd_scalar_encoding_uint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); TRYFAIL(gras_ddt_new_scalar("data pointer", - gras_ddt_scalar_pdata, e_gras_dd_scalar_encoding_uint, + gras_ddt_scalar_pdata, + e_gras_dd_scalar_encoding_uint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); - TRYFAIL(gras_ddt_new_scalar("function pointer", - gras_ddt_scalar_pfunc, e_gras_dd_scalar_encoding_uint, + gras_ddt_scalar_pfunc, + e_gras_dd_scalar_encoding_uint, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); TRYFAIL(gras_ddt_new_scalar("float", - gras_ddt_scalar_float, e_gras_dd_scalar_encoding_float, + gras_ddt_scalar_float, + e_gras_dd_scalar_encoding_float, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); TRYFAIL(gras_ddt_new_scalar("double", - gras_ddt_scalar_float, e_gras_dd_scalar_encoding_float, + gras_ddt_scalar_float, + e_gras_dd_scalar_encoding_float, NULL,&ddt)); TRYFAIL(gras_ddt_register(ddt)); - TRYFAIL(gras_ddt_get_by_name("unsigned char",&elm)); - TRYFAIL(gras_ddt_new_array("string", elm, 0, _strlen_cb, NULL, &ddt)); + TRYFAIL(gras_datadesc_by_name("char",&elm)); + TRYFAIL(gras_ddt_new_array("char array", elm, -1, _strlen_cb, NULL, &ddt)); + TRYFAIL(gras_ddt_register(ddt)); + + elm=ddt; + TRYFAIL(gras_ddt_new_ref("string", elm, NULL, NULL, &ddt)); TRYFAIL(gras_ddt_register(ddt)); } @@ -130,9 +173,7 @@ void gras_datadesc_exit(void) { VERB0("Exiting DataDesc"); gras_set_free(&gras_datadesc_set_local); + gras_datadesc_set_local = NULL; } -/*** - *** BOOTSTRAPING FUNCTIONS: known within GRAS only - ***/ diff --git a/src/gras/DataDesc/datadesc_interface.h b/src/gras/DataDesc/datadesc_interface.h index 85fb1d7a82..2c81d88caf 100644 --- a/src/gras/DataDesc/datadesc_interface.h +++ b/src/gras/DataDesc/datadesc_interface.h @@ -13,8 +13,6 @@ #ifndef GRAS_DATADESC_INTERFACE_H #define GRAS_DATADESC_INTERFACE_H -#include "gras_private.h" - void gras_datadesc_init(void); void gras_datadesc_exit(void); @@ -35,7 +33,8 @@ gras_datadesc_send(gras_socket_t *sock, gras_datadesc_type_t *type, void *src); /* Receive (and convert) stuff */ gras_error_t -gras_datadesc_recv(gras_socket_t *sock, gras_datadesc_type_t *type, void **dst); +gras_datadesc_recv(gras_socket_t *sock, gras_datadesc_type_t *type, + int r_arch, void **dst); /* -- */ diff --git a/src/gras/DataDesc/datadesc_private.h b/src/gras/DataDesc/datadesc_private.h index be6971f969..8eef386803 100644 --- a/src/gras/DataDesc/datadesc_private.h +++ b/src/gras/DataDesc/datadesc_private.h @@ -69,14 +69,14 @@ extern const gras_arch_sizes_t gras_arch_sizes[gras_arch_count]; typedef enum e_gras_datadesc_type_category { e_gras_datadesc_type_cat_undefined = 0, - e_gras_datadesc_type_cat_scalar, - e_gras_datadesc_type_cat_struct, - e_gras_datadesc_type_cat_union, - e_gras_datadesc_type_cat_ref, /* ref to an uniq element */ - e_gras_datadesc_type_cat_array, - e_gras_datadesc_type_cat_ignored, - - e_gras_datadesc_type_cat_invalid + e_gras_datadesc_type_cat_scalar = 1, + e_gras_datadesc_type_cat_struct = 2, + e_gras_datadesc_type_cat_union = 3, + e_gras_datadesc_type_cat_ref = 4, /* ref to an uniq element */ + e_gras_datadesc_type_cat_array = 5, + e_gras_datadesc_type_cat_ignored = 6, + + e_gras_datadesc_type_cat_invalid = 7 } gras_datadesc_type_category_t; @@ -134,7 +134,7 @@ typedef struct s_gras_dd_cat_struct { * Specific fields of a union */ typedef struct s_gras_dd_cat_union { - gras_datadesc_type_cb_int_t field_count; + gras_datadesc_type_cb_int_t selector; gras_dynar_t *fields; /* elm type = gras_dd_cat_field_t */ } gras_dd_cat_union_t; @@ -147,7 +147,7 @@ typedef struct s_gras_dd_cat_ref { int code; /* callback used to return the referenced type number */ - gras_datadesc_type_cb_int_t discriminant; + gras_datadesc_type_cb_int_t selector; } gras_dd_cat_ref_t; @@ -284,5 +284,20 @@ gras_ddt_new_from_nws(const char *name, size_t howmany, gras_datadesc_type_t **dst); +/**************************************************** + * Callback persistant state constructor/destructor * + ****************************************************/ +gras_error_t +gras_dd_cbps_new(gras_dd_cbps_t **dst); +void +gras_dd_cbps_free(gras_dd_cbps_t **state); + +/*************** + * Convertions * + ***************/ +gras_error_t +gras_dd_convert_elm(gras_datadesc_type_t *type, + int r_arch, + void *src, void *dst); #endif /* GRAS_DATADESC_PRIVATE_H */ diff --git a/src/gras/DataDesc/ddt_create.c b/src/gras/DataDesc/ddt_create.c index 626b98c406..1d871ce88c 100644 --- a/src/gras/DataDesc/ddt_create.c +++ b/src/gras/DataDesc/ddt_create.c @@ -22,6 +22,9 @@ gras_ddt_new(const char *name, memset(res, 0, sizeof(res)); res->name = strdup(name); + res->name_len = strlen(name); + res->pre = NULL; + res->post = NULL; *dst=res; return no_error; @@ -175,7 +178,7 @@ gras_ddt_new_struct_append(gras_datadesc_type_t *struct_type, field->pre = pre; field->post = post; - TRY(gras_dynar_push(struct_type->category.struct_data.fields, field)); + TRY(gras_dynar_push(struct_type->category.struct_data.fields, &field)); for (arch=0; archsize[arch] = field->offset[arch] + field_type->size[arch]; @@ -193,7 +196,7 @@ gras_ddt_new_struct_append(gras_datadesc_type_t *struct_type, */ gras_error_t gras_ddt_new_union(const char *name, - gras_datadesc_type_cb_int_t field_count, + gras_datadesc_type_cb_int_t selector, gras_datadesc_type_cb_void_t post, gras_datadesc_type_t **dst) { @@ -201,7 +204,7 @@ gras_ddt_new_union(const char *name, gras_datadesc_type_t *res; int arch; - gras_assert0(field_count, + gras_assert0(selector, "Attempt to creat an union without field_count function"); TRY(gras_ddt_new(name,dst)); @@ -216,7 +219,7 @@ gras_ddt_new_union(const char *name, TRY(gras_dynar_new(&(res->category.union_data.fields), sizeof(gras_dd_cat_field_t*), &gras_dd_cat_field_free)); - res->category.union_data.field_count = field_count; + res->category.union_data.selector = selector; res->pre = NULL; res->post = post; @@ -254,7 +257,7 @@ gras_ddt_new_union_append(gras_datadesc_type_t *union_type, field->pre = pre; field->post = post; - TRY(gras_dynar_push(union_type->category.union_data.fields, field)); + TRY(gras_dynar_push(union_type->category.union_data.fields, &field)); for (arch=0; archsize[arch] = max(union_type->size[arch], field_type->size[arch]); @@ -273,31 +276,33 @@ gras_ddt_new_union_append(gras_datadesc_type_t *union_type, gras_error_t gras_ddt_new_ref(const char *name, gras_datadesc_type_t *referenced_type, - gras_datadesc_type_cb_int_t discriminant, + gras_datadesc_type_cb_int_t selector, gras_datadesc_type_cb_void_t post, gras_datadesc_type_t **dst) { gras_error_t errcode; gras_datadesc_type_t *res; + gras_datadesc_type_t *pointer_type; int arch; - gras_assert0(discriminant || referenced_type, - "Attempt to create a generic reference without discriminant"); + gras_assert0(selector || referenced_type, + "Attempt to create a generic reference without selector"); TRY(gras_ddt_new(name,dst)); res=*dst; - /* FIXME: Size from bootstraping */ + TRY(gras_datadesc_by_name("data pointer", &pointer_type)); + for (arch=0; archsize[arch] = 0; - res->alignment[arch] = 0; - res->aligned_size[arch] = 0; + res->size[arch] = pointer_type->size[arch]; + res->alignment[arch] = pointer_type->alignment[arch]; + res->aligned_size[arch] = pointer_type->aligned_size[arch]; } res->category_code = e_gras_datadesc_type_cat_ref; res->category.ref_data.code = referenced_type ? referenced_type->code : -1; - res->category.ref_data.discriminant = discriminant; + res->category.ref_data.selector = selector; res->pre = NULL; res->post = post; diff --git a/src/gras/DataDesc/ddt_declare.c b/src/gras/DataDesc/ddt_declare.c index 2572e57262..4001167c33 100644 --- a/src/gras/DataDesc/ddt_declare.c +++ b/src/gras/DataDesc/ddt_declare.c @@ -34,10 +34,8 @@ gras_datadesc_declare_struct_add_name_cb(long int struct_code, gras_datadesc_type_t *struct_type; gras_datadesc_type_t *field_type; - TRY(gras_set_get_by_id(gras_datadesc_set_local,struct_code, - (gras_set_elm_t**)struct_type)); - TRY(gras_set_get_by_name(gras_datadesc_set_local,field_type_name, - (gras_set_elm_t**)field_type)); + TRY(gras_datadesc_by_id(struct_code,&struct_type)); + TRY(gras_datadesc_by_name(field_type_name,&field_type)); TRY(gras_ddt_new_struct_append(struct_type, field_name, field_type, @@ -55,10 +53,8 @@ gras_datadesc_declare_struct_add_code_cb(long int struct_code, gras_datadesc_type_t *struct_type; gras_datadesc_type_t *field_type; - TRY(gras_set_get_by_id(gras_datadesc_set_local,struct_code, - (gras_set_elm_t**)struct_type)); - TRY(gras_set_get_by_id(gras_datadesc_set_local,field_code, - (gras_set_elm_t**)field_type)); + TRY(gras_datadesc_by_id(struct_code,&struct_type)); + TRY(gras_datadesc_by_id(field_code, &field_type)); TRY(gras_ddt_new_struct_append(struct_type, field_name, field_type, @@ -90,10 +86,8 @@ gras_datadesc_declare_union_add_name_cb(long int union_code gras_datadesc_type_t *union_type; gras_datadesc_type_t *field_type; - TRY(gras_set_get_by_id(gras_datadesc_set_local,union_code, - (gras_set_elm_t**)union_type)); - TRY(gras_set_get_by_name(gras_datadesc_set_local,field_type_name, - (gras_set_elm_t**)field_type)); + TRY(gras_datadesc_by_id (union_code, &union_type)); + TRY(gras_datadesc_by_name(field_type_name, &field_type)); TRY(gras_ddt_new_union_append(union_type, field_name, field_type, @@ -111,10 +105,8 @@ gras_datadesc_declare_union_add_code_cb(long int union_code gras_datadesc_type_t *union_type; gras_datadesc_type_t *field_type; - TRY(gras_set_get_by_id(gras_datadesc_set_local,union_code, - (gras_set_elm_t**)union_type)); - TRY(gras_set_get_by_id(gras_datadesc_set_local,field_code, - (gras_set_elm_t**)field_type)); + TRY(gras_datadesc_by_id(union_code, &union_type)); + TRY(gras_datadesc_by_id(field_code, &field_type)); TRY(gras_ddt_new_union_append(union_type, field_name, field_type, diff --git a/src/gras/DataDesc/ddt_remote.c b/src/gras/DataDesc/ddt_remote.c index 6d45998bab..b3c72cba9d 100644 --- a/src/gras/DataDesc/ddt_remote.c +++ b/src/gras/DataDesc/ddt_remote.c @@ -45,21 +45,51 @@ gras_error_t gras_ddt_register(gras_datadesc_type_t *type) { } /** - * gras_ddt_get_by_name: + * gras_datadesc_by_name: * * Retrieve a type from its name */ -gras_error_t gras_ddt_get_by_name(const char *name, - gras_datadesc_type_t **type) { - return gras_set_get_by_name(gras_datadesc_set_local,name,(gras_set_elm_t**)type); +gras_error_t gras_datadesc_by_name(const char *name, + gras_datadesc_type_t **type) { + return gras_set_get_by_name(gras_datadesc_set_local, + name,(gras_set_elm_t**)type); } /** - * gras_ddt_get_by_code: + * gras_datadesc_by_id: * - * Retrieve a type from its name + * Retrieve a type from its code + */ +gras_error_t gras_datadesc_by_id(long int code, + gras_datadesc_type_t **type) { + return gras_set_get_by_id(gras_datadesc_set_local, + code,(gras_set_elm_t**)type); +} + +/** + * gras_dd_convert_elm: + * + * Convert the element described by @type comming from architecture @r_arch. + * The data to be converted is stored in @src, and is to be stored in @dst. + * Both pointers may be the same location if no resizing is needed. + */ +gras_error_t +gras_dd_convert_elm(gras_datadesc_type_t *type, + int r_arch, + void *src, void *dst) { + + if (r_arch != GRAS_THISARCH) + RAISE_UNIMPLEMENTED; + + return no_error; +} + +/** + * gras_arch_selfid: + * + * returns the ID of the architecture the process is running on */ -gras_error_t gras_ddt_get_by_code(int code, - gras_datadesc_type_t **type) { - return gras_set_get_by_id(gras_datadesc_set_local,code,(gras_set_elm_t**)type); +int +gras_arch_selfid(void) { + return GRAS_THISARCH; } diff --git a/src/gras/DataDesc/ddt_use.c b/src/gras/DataDesc/ddt_use.c index f4f6c346f0..ebad12795c 100644 --- a/src/gras/DataDesc/ddt_use.c +++ b/src/gras/DataDesc/ddt_use.c @@ -10,7 +10,124 @@ #include "DataDesc/datadesc_private.h" -//GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(use,DataDesc); +GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(use,DataDesc); + +static const char *gras_datadesc_cat_names[9] = { + "undefined", + "scalar", "struct", "union", "ref", "array", "ignored", + "invalid"}; + +static gras_datadesc_type_t *int_type = NULL; +static gras_datadesc_type_t *pointer_type = NULL; +static gras_error_t gras_dd_send_int(gras_socket_t *sock, int i); +static gras_error_t gras_dd_recv_int(gras_socket_t *sock, int r_arch, int *i); + +static gras_error_t +gras_dd_alloc_ref(gras_dict_t *refs, long int size, + char **r_ref, long int r_len, + char **l_ref); +static int +gras_dd_is_r_null(char **r_ptr, long int length); + +static gras_error_t +gras_datadesc_send_rec(gras_socket_t *sock, + gras_dd_cbps_t *state, + gras_dict_t *refs, + gras_datadesc_type_t *type, + char *data); +static gras_error_t +gras_datadesc_recv_rec(gras_socket_t *sock, + gras_dd_cbps_t *state, + gras_dict_t *refs, + gras_datadesc_type_t *type, + int r_arch, + char **r_data, + long int r_lgr, + char **dst); + + +static gras_error_t +gras_dd_send_int(gras_socket_t *sock,int i) { + gras_error_t errcode; + + if (!int_type) + TRY(gras_datadesc_by_name("int", &int_type)); + + DEBUG1("send_int(%d)",i); + return gras_trp_chunk_send(sock, (char*)&i, int_type->size[GRAS_THISARCH]); +} + +static gras_error_t +gras_dd_recv_int(gras_socket_t *sock, int r_arch, int *i) { + gras_error_t errcode; + + if (!int_type) + TRY(gras_datadesc_by_name("int", &int_type)); + + if (int_type->size[GRAS_THISARCH] >= int_type->size[r_arch]) { + TRY(gras_trp_chunk_recv(sock, (char*)i, int_type->size[r_arch])); + TRY(gras_dd_convert_elm(int_type,r_arch, i,i)); + } else { + void *ptr = NULL; + ptr = malloc((size_t)int_type->size[r_arch]); + TRY(gras_trp_chunk_recv(sock, (char*)ptr, int_type->size[r_arch])); + TRY(gras_dd_convert_elm(int_type,r_arch, ptr,i)); + free(ptr); + } + DEBUG1("recv_int(%d)",*i); + + return no_error; +} + +/* + * Note: here we suppose that the remote NULL is a sequence + * of 'length' bytes set to 0. + * FIXME: Check in configure? + */ +static int +gras_dd_is_r_null(char **r_ptr, long int length) { + int i; + + for (i=0; isize[r_arch] */ + char **l_ref) { + char *l_data = NULL; + gras_error_t errcode; + + gras_assert1(size>0,"Cannot allocate %d bytes!", size); + if (! (l_data = malloc((size_t)size)) ) + RAISE_MALLOC; + + *l_ref = l_data; + DEBUG2("l_data=%p, &l_data=%p",l_data,&l_data); + + DEBUG3("alloc_ref: r_ref=%p; *r_ref=%p, r_len=%d", + r_ref, r_ref?*r_ref:NULL, r_len); + if (r_ref && !gras_dd_is_r_null( r_ref, r_len)) { + void *ptr = malloc(sizeof(void *)); + if (!ptr) + RAISE_MALLOC; + // memcpy(ptr,&l_data, sizeof(void *)); + memcpy(ptr,l_ref, sizeof(void *)); + + DEBUG2("Insert %p under %p",*(void**)ptr, *(void**)r_ref); + /* FIXME: Leaking on the ptr. Do I really need to copy it? */ + TRY(gras_dict_insert_ext(refs,(const char *) r_ref, r_len, ptr, NULL)); + } + return no_error; +} /** * gras_datadesc_get_id_from_name: @@ -23,7 +140,7 @@ gras_datadesc_get_id_from_name(const char *name) { gras_error_t errcode; gras_datadesc_type_t *type; - errcode = gras_ddt_get_by_name(name,&type); + errcode = gras_datadesc_by_name(name,&type); if (errcode != no_error) return -1; return type->code; @@ -48,14 +165,20 @@ int gras_datadesc_type_cmp(const gras_datadesc_type_t *d1, if (!d1 && !d2) return 0; if ( d1 && !d2) return -1; - if (d1->size != d2->size ) return d1->size > d2->size ? 1 : -1; - if (d1->alignment != d2->alignment) return d1->alignment > d2->alignment ? 1 : -1; - if (d1->aligned_size != d2->aligned_size) return d1->aligned_size > d2->aligned_size ? 1 : -1; + if (d1->size != d2->size ) + return d1->size > d2->size ? 1 : -1; + if (d1->alignment != d2->alignment) + return d1->alignment > d2->alignment ? 1 : -1; + if (d1->aligned_size != d2->aligned_size) + return d1->aligned_size > d2->aligned_size ? 1 : -1; - if (d1->category_code != d2->category_code) return d1->category_code > d2->category_code ? 1 : -1; + if (d1->category_code != d2->category_code) + return d1->category_code > d2->category_code ? 1 : -1; - if (d1->pre != d2->pre) return d1->pre > d2->pre ? 1 : -1; - if (d1->post != d2->post) return d1->post > d2->post ? 1 : -1; + if (d1->pre != d2->pre) + return d1->pre > d2->pre ? 1 : -1; + if (d1->post != d2->post) + return d1->post > d2->post ? 1 : -1; switch (d1->category_code) { case e_gras_datadesc_type_cat_scalar: @@ -73,8 +196,8 @@ int gras_datadesc_type_cmp(const gras_datadesc_type_t *d1, gras_dynar_foreach(d1->category.struct_data.fields, cpt, field1) { gras_dynar_get(d2->category.struct_data.fields, cpt, field2); - gras_ddt_get_by_code(field1->code,&field_desc_1); /* FIXME: errcode ignored */ - gras_ddt_get_by_code(field2->code,&field_desc_2); + gras_datadesc_by_id(field1->code,&field_desc_1); /* FIXME: errcode ignored */ + gras_datadesc_by_id(field2->code,&field_desc_2); ret = gras_datadesc_type_cmp(field_desc_1,field_desc_2); if (ret) return ret; @@ -83,8 +206,8 @@ int gras_datadesc_type_cmp(const gras_datadesc_type_t *d1, break; case e_gras_datadesc_type_cat_union: - if (d1->category.union_data.field_count != d2->category.union_data.field_count) - return d1->category.union_data.field_count > d2->category.union_data.field_count ? 1 : -1; + if (d1->category.union_data.selector != d2->category.union_data.selector) + return d1->category.union_data.selector > d2->category.union_data.selector ? 1 : -1; if (gras_dynar_length(d1->category.union_data.fields) != gras_dynar_length(d2->category.union_data.fields)) @@ -95,8 +218,8 @@ int gras_datadesc_type_cmp(const gras_datadesc_type_t *d1, gras_dynar_foreach(d1->category.union_data.fields, cpt, field1) { gras_dynar_get(d2->category.union_data.fields, cpt, field2); - gras_ddt_get_by_code(field1->code,&field_desc_1); /* FIXME: errcode ignored */ - gras_ddt_get_by_code(field2->code,&field_desc_2); + gras_datadesc_by_id(field1->code,&field_desc_1); /* FIXME: errcode ignored */ + gras_datadesc_by_id(field2->code,&field_desc_2); ret = gras_datadesc_type_cmp(field_desc_1,field_desc_2); if (ret) return ret; @@ -106,8 +229,8 @@ int gras_datadesc_type_cmp(const gras_datadesc_type_t *d1, case e_gras_datadesc_type_cat_ref: - if (d1->category.ref_data.discriminant != d2->category.ref_data.discriminant) - return d1->category.ref_data.discriminant > d2->category.ref_data.discriminant ? 1 : -1; + if (d1->category.ref_data.selector != d2->category.ref_data.selector) + return d1->category.ref_data.selector > d2->category.ref_data.selector ? 1 : -1; if (d1->category.ref_data.code != d2->category.ref_data.code) return d1->category.ref_data.code > d2->category.ref_data.code ? 1 : -1; @@ -138,31 +261,439 @@ int gras_datadesc_type_cmp(const gras_datadesc_type_t *d1, /** * gras_datadesc_cpy: * - * Copy the data pointed by src and described by type to a new location, and store a pointer to it in dst. + * Copy the data pointed by src and described by type + * to a new location, and store a pointer to it in dst. * */ -gras_error_t gras_datadesc_cpy(gras_datadesc_type_t *type, void *src, void **dst) { +gras_error_t gras_datadesc_cpy(gras_datadesc_type_t *type, + void *src, + void **dst) { RAISE_UNIMPLEMENTED; } +static gras_error_t +gras_datadesc_send_rec(gras_socket_t *sock, + gras_dd_cbps_t *state, + gras_dict_t *refs, + gras_datadesc_type_t *type, + char *data) { + + gras_error_t errcode; + int cpt; + gras_datadesc_type_t *sub_type; /* type on which we recurse */ + + VERB2("Send a %s (%s)", + type->name, gras_datadesc_cat_names[type->category_code]); + + if (type->pre) { + type->pre(state,type,data); + } + + switch (type->category_code) { + case e_gras_datadesc_type_cat_scalar: + TRY(gras_trp_chunk_send(sock, data, type->size[GRAS_THISARCH])); + break; + + case e_gras_datadesc_type_cat_struct: { + gras_dd_cat_struct_t struct_data; + gras_dd_cat_field_t *field; + char *field_data; + + struct_data = type->category.struct_data; + VERB1(">> Send all fields of the structure %s",type->name); + gras_dynar_foreach(struct_data.fields, cpt, field) { + field_data = data; + field_data += field->offset[GRAS_THISARCH]; + + TRY(gras_datadesc_by_id(field->code, &sub_type)); + + if (field->pre) + field->pre(state,sub_type,field_data); + + TRY(gras_datadesc_send_rec(sock,state,refs,sub_type, field_data)); + + if (field->post) + field->post(state,sub_type,field_data); + } + VERB1("<< Sent all fields of the structure %s", type->name); + + break; + } + + case e_gras_datadesc_type_cat_union: { + gras_dd_cat_union_t union_data; + gras_dd_cat_field_t *field; + int field_num; + + union_data = type->category.union_data; + + /* retrieve the field number */ + field_num = union_data.selector(state, type, data); + + gras_assert1(field_num > 0, + "union field selector of %s gave a negative value", + type->name); + + gras_assert3(field_num < gras_dynar_length(union_data.fields), + "union field selector of %s returned %d but there is only %d fields", + type->name, field_num, gras_dynar_length(union_data.fields)); + + /* Send the field number */ + TRY(gras_dd_send_int(sock, field_num)); + + /* Send the content */ + gras_dynar_get(union_data.fields, field_num, field); + TRY(gras_datadesc_by_id(field->code, &sub_type)); + + if (field->pre) + field->pre(state,sub_type,data); + + TRY(gras_datadesc_send_rec(sock,state,refs, sub_type, data)); + + if (field->post) + field->post(state,sub_type,data); + + break; + } + + case e_gras_datadesc_type_cat_ref: { + gras_dd_cat_ref_t ref_data; + int ref_code; + + void **ref=(void**)data; + void *dummy; + + ref_data = type->category.ref_data; + + /* Detect the referenced type and send it to peer if needed */ + ref_code = ref_data.code; + if (ref_code < 0) { + ref_code = ref_data.selector(state,type,data); + TRY(gras_dd_send_int(sock, ref_code)); + } + + /* Send the actual value of the pointer for cycle handling */ + if (!pointer_type) + TRY(gras_datadesc_by_name("data pointer", &pointer_type)); + TRY(gras_trp_chunk_send(sock, (char*)data, + pointer_type->size[GRAS_THISARCH])); + + /* Send the pointed data only if not already sent */ + if (*(void**)data == NULL) { + VERB0("Not sending NULL referenced data"); + break; + } + errcode = gras_dict_retrieve_ext(refs,(char*)ref, sizeof(void*), &dummy); + if (errcode == mismatch_error) { + VERB1("Sending data referenced at %p", *ref); + TRY(gras_dict_insert_ext(refs, (char*)ref, sizeof(void*), ref, NULL)); + TRY(gras_datadesc_by_id(ref_code, &sub_type)); + TRY(gras_datadesc_send_rec(sock,state,refs, sub_type, *ref)); + + } else if (errcode == no_error) { + VERB1("Not sending data referenced at %p (already done)", *ref); + } else { + return errcode; + } + + break; + } + + case e_gras_datadesc_type_cat_array: { + gras_dd_cat_array_t array_data; + long int count; + char *ptr=data; + long int elm_size; + + array_data = type->category.array_data; + + /* determine and send the element count */ + count = array_data.fixed_size; + if (count <= 0) { + count = array_data.dynamic_size(state,type,data); + gras_assert1(count >=0, + "Invalid (negative) array size for type %s",type->name); + TRY(gras_dd_send_int(sock, count)); + } + + /* send the content */ + TRY(gras_datadesc_by_id(array_data.code, &sub_type)); + elm_size = sub_type->aligned_size[GRAS_THISARCH]; + for (cpt=0; cptpost) { + type->post(state,type,data); + } + + return no_error; +} + /** * gras_datadesc_send: * * Copy the data pointed by src and described by type to the socket * */ -gras_error_t gras_datadesc_send(gras_socket_t *sock, gras_datadesc_type_t *type, void *src) { +gras_error_t gras_datadesc_send(gras_socket_t *sock, + gras_datadesc_type_t *type, + void *src) { - RAISE_UNIMPLEMENTED; + gras_error_t errcode; + gras_dd_cbps_t *state = NULL; + gras_dict_t *refs; /* all references already sent */ + + TRY(gras_dict_new(&refs)); + TRY(gras_dd_cbps_new(&state)); + + errcode = gras_datadesc_send_rec(sock,state,refs,type,(char*)src); + + gras_dict_free(&refs); + gras_dd_cbps_free(&state); + + return errcode; +} + +/** + * gras_datadesc_recv_rec: + * + * Do the data reception job recursively. + */ +gras_error_t +gras_datadesc_recv_rec(gras_socket_t *sock, + gras_dd_cbps_t *state, + gras_dict_t *refs, + gras_datadesc_type_t *type, + int r_arch, + char **r_data, + long int r_lgr, + char **dst) { + + gras_error_t errcode; + char *l_data = *dst; /* dereference to avoid typo */ + int cpt; + gras_datadesc_type_t *sub_type; + + VERB1("Recv a %s", type->name); + + switch (type->category_code) { + case e_gras_datadesc_type_cat_scalar: + if (!l_data) { + TRY(gras_dd_alloc_ref(refs,type->size[GRAS_THISARCH],r_data,r_lgr, dst)); + l_data = *dst; + } + + if (type->size[GRAS_THISARCH] >= type->size[r_arch]) { + TRY(gras_trp_chunk_recv(sock, (char*)l_data, type->size[r_arch])); + TRY(gras_dd_convert_elm(type,r_arch, l_data,l_data)); + } else { + void *ptr = NULL; + ptr = malloc((size_t)type->size[r_arch]); + TRY(gras_trp_chunk_recv(sock, (char*)ptr, type->size[r_arch])); + TRY(gras_dd_convert_elm(type,r_arch, ptr,l_data)); + free(ptr); + } + break; + + case e_gras_datadesc_type_cat_struct: { + gras_dd_cat_struct_t struct_data; + gras_dd_cat_field_t *field; + + struct_data = type->category.struct_data; + + if (!l_data) { + TRY(gras_dd_alloc_ref(refs,type->size[GRAS_THISARCH],r_data,r_lgr, dst)); + l_data = *dst; + } + + VERB1(">> Receive all fields of the structure %s",type->name); + gras_dynar_foreach(struct_data.fields, cpt, field) { + char *field_data = l_data + field->offset[GRAS_THISARCH]; + + TRY(gras_datadesc_by_id(field->code, &sub_type)); + + TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type, + r_arch,NULL,0, + &field_data)); + } + VERB1("<< Received all fields of the structure %s", type->name); + + break; + } + + case e_gras_datadesc_type_cat_union: { + gras_dd_cat_union_t union_data; + gras_dd_cat_field_t *field; + int field_num; + + union_data = type->category.union_data; + + if (!l_data) { + TRY(gras_dd_alloc_ref(refs,type->size[GRAS_THISARCH],r_data,r_lgr, dst)); + l_data = *dst; + } + + /* retrieve the field number */ + TRY(gras_dd_recv_int(sock, r_arch, &field_num)); + if (field_num < 0) + RAISE1(mismatch_error, + "Received union field for %s is negative", type->name); + if (field_num < gras_dynar_length(union_data.fields)) + RAISE3(mismatch_error, + "Received union field for %s is %d but there is only %d fields", + type->name, field_num, gras_dynar_length(union_data.fields)); + + /* Recv the content */ + gras_dynar_get(union_data.fields, field_num, field); + TRY(gras_datadesc_by_id(field->code, &sub_type)); + + TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type, + r_arch,NULL,0, + dst)); + break; + } + + case e_gras_datadesc_type_cat_ref: { + char **r_ref = NULL; + char **l_ref = NULL; + gras_dd_cat_ref_t ref_data; + int ref_code; + + ref_data = type->category.ref_data; + + /* Get the referenced type locally or from peer */ + ref_code = ref_data.code; + if (ref_code < 0) + TRY(gras_dd_recv_int(sock, r_arch, &ref_code)); + + /* Get the actual value of the pointer for cycle handling */ + if (!pointer_type) + TRY(gras_datadesc_by_name("data pointer", &pointer_type)); + + if (! (r_ref = malloc((size_t)pointer_type->size[r_arch])) ) + RAISE_MALLOC; + TRY(gras_trp_chunk_recv(sock, (char*)r_ref, + pointer_type->size[r_arch])); + + if (!l_data) { + TRY(gras_dd_alloc_ref(refs,type->size[GRAS_THISARCH],r_data,r_lgr, dst)); + l_data = *dst; + } + + /* Receive the pointed data only if not already sent */ + if (gras_dd_is_r_null(r_ref, pointer_type->size[r_arch])) { + VERB1("Not receiving data remotely referenced at %p since it's NULL", + *(void **)r_ref); + *(void**)l_data = NULL; + break; + } + errcode = gras_dict_retrieve_ext(refs, + (char*)r_ref, pointer_type->size[r_arch], + (void**)&l_ref); + + + if (errcode == mismatch_error) { + void *l_referenced=NULL; + VERB1("Receiving data remotely referenced at %p", *(void**)r_ref); + + TRY(gras_datadesc_by_id(ref_code, &sub_type)); + // DEBUG2("l_ref= %p; &l_ref=%p",l_referenced,&l_referenced); + TRY(gras_datadesc_recv_rec(sock,state,refs, sub_type, + r_arch,r_ref,pointer_type->size[r_arch], + (char**)&l_referenced)); + *(void**)l_data=l_referenced; + + } else if (errcode == no_error) { + VERB1("NOT receiving data remotely referenced at %p (already done). ", + *(void**)r_ref); + + VERB2("l_ref=%p; *l_ref=%p", l_ref,*l_ref); + + *(void**)l_data=*l_ref; + + } else { + return errcode; + } + VERB1("*l_data=%p",*(void**)l_data); + break; + } + + case e_gras_datadesc_type_cat_array: { + gras_dd_cat_array_t array_data; + int count; + char *ptr; + long int elm_size; + + array_data = type->category.array_data; + /* determine element count locally or from peer */ + count = array_data.fixed_size; + if (count <= 0) + TRY(gras_dd_recv_int(sock, r_arch, &count)); + if (count < 0) + RAISE1(mismatch_error, + "Invalid (negative) array size for type %s",type->name); + + /* receive the content */ + TRY(gras_datadesc_by_id(array_data.code, &sub_type)); + elm_size = sub_type->aligned_size[GRAS_THISARCH]; + + if (!l_data) { + TRY(gras_dd_alloc_ref(refs,elm_size*count,r_data,r_lgr, dst)); + l_data = *dst; + } + + ptr = l_data; + for (cpt=0; cptplugin=trp; - DEBUG3("in=%c out=%c accept=%c", - (*dst)->incoming?'y':'n', - (*dst)->outgoing?'y':'n', - (*dst)->accepting?'y':'n'); - if (strcmp("-", path)) { - (*dst)->sd = open(path, O_RDONLY ); + (*dst)->sd = open(path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP ); if ( (*dst)->sd < 0) { RAISE2(system_error, @@ -122,11 +117,12 @@ gras_socket_client_from_file(const char*path, (*dst)->sd = 1; /* stdout */ } - DEBUG4("sd=%d in=%c out=%c accept=%c", - (*dst)->sd, - (*dst)->incoming?'y':'n', - (*dst)->outgoing?'y':'n', - (*dst)->accepting?'y':'n'); + DEBUG5("sock_client_from_file(%s): sd=%d in=%c out=%c accept=%c", + path, + (*dst)->sd, + (*dst)->incoming?'y':'n', + (*dst)->outgoing?'y':'n', + (*dst)->accepting?'y':'n'); /* register socket */ errcode = gras_dynar_push(_gras_trp_sockets,dst); if (errcode != no_error) { @@ -161,7 +157,7 @@ gras_socket_server_from_file(const char*path, if (strcmp("-", path)) { - (*dst)->sd = open(path, O_WRONLY ); + (*dst)->sd = open(path, O_RDONLY ); if ( (*dst)->sd < 0) { RAISE2(system_error, @@ -200,14 +196,14 @@ void gras_trp_file_close(gras_socket_t *sock){ } else if (sock->sd == 1) { DEBUG0("Do not close stdout"); } else { - DEBUG1("close file connection %d\n", sock->sd); + DEBUG1("close file connection %d", sock->sd); /* forget about the socket */ FD_CLR(sock->sd, &(specific->incoming_socks)); /* close the socket */ if(close(sock->sd) < 0) { - WARNING2("error while closing file %d: %s\n", + WARNING2("error while closing file %d: %s", sock->sd, strerror(errno)); } } @@ -228,8 +224,8 @@ gras_trp_file_chunk_send(gras_socket_t *sock, while (size) { int status = 0; + DEBUG3("write(%d, %p, %ld);", sock->sd, data, (size_t)size); status = write(sock->sd, data, (size_t)size); - DEBUG3("write(%d, %p, %ld);\n", sock->sd, data, size); if (status == -1) { RAISE4(system_error,"write(%d,%p,%d) failed: %s", @@ -265,7 +261,7 @@ gras_trp_file_chunk_recv(gras_socket_t *sock, int status = 0; status = read(sock->sd, data, (size_t)size); - DEBUG3("read(%d, %p, %ld);\n", sock->sd, data, size); + DEBUG3("read(%d, %p, %ld);", sock->sd, data, size); if (status == -1) { RAISE4(system_error,"read(%d,%p,%d) failed: %s", diff --git a/src/xbt/module.c b/src/xbt/module.c index 65638c8629..290488eb66 100644 --- a/src/xbt/module.c +++ b/src/xbt/module.c @@ -58,17 +58,17 @@ gras_init_defaultlog(int argc,char **argv, const char *defaultlog) { /** init other submodules */ gras_trp_init(); + gras_datadesc_init(); } /** * gras_exit: - * @argc: - * @argv: * * Finalize the gras mecanisms. */ void gras_exit(){ gras_trp_exit(); + gras_datadesc_exit(); gras_log_exit(); } diff --git a/src/xbt/set.c b/src/xbt/set.c index d452b1a64e..94280a1ee7 100644 --- a/src/xbt/set.c +++ b/src/xbt/set.c @@ -94,7 +94,7 @@ gras_error_t gras_set_add (gras_set_t *set, elm->ID = gras_dynar_length( set->dynar ); TRY(gras_dict_insert_ext(set->dict, elm->name, elm->name_len, elm, free_func)); TRY(gras_dynar_set(set->dynar, elm->ID, &elm)); - DEBUG2("Insertion of key %s (id %d)", elm->name, elm->ID); + DEBUG2("Insertion of key '%s' (id %d)", elm->name, elm->ID); return no_error; } @@ -146,10 +146,14 @@ gras_error_t gras_set_get_by_name_ext(gras_set_t *set, gras_error_t gras_set_get_by_id (gras_set_t *set, int id, /* OUT */gras_set_elm_t **dst) { + DEBUG2("Lookup type of id %d (of %d)", + id, gras_dynar_length(set->dynar)); if (id < gras_dynar_length(set->dynar) && id >= 0) { gras_dynar_get(set->dynar,id,dst); - + DEBUG3("Lookup type of id %d (of %d): %s", + id, gras_dynar_length(set->dynar), (*dst)->name); + } else { DEBUG1("Cannot get ID %d: out of bound", id); return mismatch_error; diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 606e2a9164..edd33a868b 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -17,7 +17,8 @@ core_tests = \ RL_tests = \ trp_tcp_client trp_tcp_server \ - trp_file_client trp_file_server + trp_file_client trp_file_server \ + datadesc_usage # gs_example_send gs_example_receive SG_tests = @@ -53,6 +54,8 @@ trp_tcp_server_LDADD= $(LDADD_RL) trp_file_client_LDADD= $(LDADD_RL) trp_file_server_LDADD= $(LDADD_RL) +datadesc_usage_LDADD= $(LDADD_RL) + #gs_example_send_LDADD= $(LDADD_UTILS) #gs_example_receive_LDADD= $(LDADD_UTILS) diff --git a/testsuite/gras/datadesc_usage.c b/testsuite/gras/datadesc_usage.c new file mode 100644 index 0000000000..2a6507bf26 --- /dev/null +++ b/testsuite/gras/datadesc_usage.c @@ -0,0 +1,400 @@ +/* $Id$ */ + +/* datadesc: test of data description (using file transport). */ + +/* Authors: Martin Quinson */ +/* Copyright (C) 2004 the OURAGAN project. */ + +/* 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 +#include + +#include "../DataDesc/datadesc_interface.h" +GRAS_LOG_NEW_DEFAULT_CATEGORY(test); + +gras_error_t +write_read(gras_datadesc_type_t *type,void *src, void *dst); + +gras_error_t +write_read(gras_datadesc_type_t *type,void *src, void *dst) { + gras_error_t errcode; + gras_socket_t *sock; + + /* write */ + TRY(gras_socket_client_from_file("datadesc_usage.out",&sock)); + TRY(gras_datadesc_send(sock, type, src)); + gras_socket_close(&sock); + + /* read */ + TRY(gras_socket_server_from_file("datadesc_usage.out",&sock)); + TRY(gras_datadesc_recv(sock, type, gras_arch_selfid(), dst)); + gras_socket_close(&sock); + + return no_error; +} + +gras_error_t test_int(void); +gras_error_t test_float(void); +gras_error_t test_array(void); +gras_error_t test_intref(void); +gras_error_t test_string(void); + +gras_error_t test_homostruct(void); +gras_error_t test_hetestruct(void); +gras_error_t test_nestedstruct(void); +gras_error_t test_chain_list(void); +gras_error_t test_graph(void); + +gras_error_t test_int(void) { + gras_error_t errcode; + gras_datadesc_type_t *type; + int i=5,*j=NULL; + + INFO0("==== Test on integer ===="); + TRY(gras_datadesc_by_name("int", &type)); + TRY(write_read(type, (void*)&i,(void**) &j)); + gras_assert(i == *j); + free(j); + return no_error; +} +gras_error_t test_float(void) { + gras_error_t errcode; + gras_datadesc_type_t *type; + float i=5.0,*j=NULL; + + INFO0("==== Test on float ===="); + TRY(gras_datadesc_by_name("float", &type)); + TRY(write_read(type, (void*)&i,(void**) &j)); + gras_assert(i == *j); + free(j); + return no_error; +} + +#define SIZE 5 +typedef int array[SIZE]; +gras_error_t test_array(void) { + gras_error_t errcode; + gras_datadesc_type_t *int_type; + gras_datadesc_type_t *my_type; + + array i,*j; + long int code; + int cpt; + + INFO0("==== Test on fixed array ===="); + for (cpt=0; cpta = rand(); i->b = rand(); + i->c = rand(); i->d = rand(); + j = NULL; + + TRY(write_read(my_type, (void*)i, (void**)&j)); + gras_assert(i->a == j->a); + gras_assert(i->b == j->b); + gras_assert(i->c == j->c); + gras_assert(i->d == j->d); + + free(i); + free(j); + return no_error; +} + +/*** + *** heterogeneous struct + ***/ +typedef struct { + unsigned char c1; + unsigned long int l1; + unsigned char c2; + unsigned long int l2; +} hetestruct; +gras_error_t test_hetestruct(void) { + gras_error_t errcode; + gras_datadesc_type_t *my_type; + long int my_code; + hetestruct *i, *j; + + INFO0("==== Test on heterogeneous structure ===="); + /* create descriptor */ + TRY(gras_datadesc_declare_struct("hetestruct",&my_code)); + TRY(gras_datadesc_declare_struct_add_name(my_code,"c1","unsigned char")); + TRY(gras_datadesc_declare_struct_add_name(my_code,"l1","unsigned long int")); + TRY(gras_datadesc_declare_struct_add_name(my_code,"c2","unsigned char")); + TRY(gras_datadesc_declare_struct_add_name(my_code,"l2","unsigned long int")); + TRY(gras_datadesc_by_code(my_code, &my_type)); + + /* init a value, exchange it and check its validity*/ + if (! (i=malloc(sizeof(hetestruct))) ) + RAISE_MALLOC; + i->c1 = 's'; i->l1 = 123455; + i->c2 = 'e'; i->l2 = 774531; + j = NULL; + + TRY(write_read(my_type, (void*)i, (void**)&j)); + gras_assert(i->c1 == j->c1); + gras_assert(i->c2 == j->c2); + gras_assert(i->l1 == j->l1); + gras_assert(i->l2 == j->l2); + + free(i); + free(j); + return no_error; +} + +/*** + *** nested struct + ***/ +typedef struct { + hetestruct hete; + homostruct homo; +} nestedstruct; +gras_error_t test_nestedstruct(void) { + gras_error_t errcode; + gras_datadesc_type_t *my_type; + long int my_code; + nestedstruct *i, *j; + + INFO0("==== Test on nested structures ===="); + /* create descriptor */ + TRY(gras_datadesc_declare_struct("nestedstruct",&my_code)); + TRY(gras_datadesc_declare_struct_add_name(my_code,"hete","hetestruct")); + TRY(gras_datadesc_declare_struct_add_name(my_code,"homo","homostruct")); + TRY(gras_datadesc_by_code(my_code, &my_type)); + + /* init a value, exchange it and check its validity*/ + if (! (i=malloc(sizeof(nestedstruct))) ) + RAISE_MALLOC; + i->homo.a = rand(); i->homo.b = rand(); + i->homo.c = rand(); i->homo.d = rand(); + i->hete.c1 = 's'; i->hete.l1 = 123455; + i->hete.c2 = 'e'; i->hete.l2 = 774531; + j = NULL; + + TRY(write_read(my_type, (void*)i, (void**)&j)); + gras_assert(i->homo.a == j->homo.a); + gras_assert(i->homo.b == j->homo.b); + gras_assert(i->homo.c == j->homo.c); + gras_assert(i->homo.d == j->homo.d); + gras_assert(i->hete.c1 == j->hete.c1); + gras_assert(i->hete.c2 == j->hete.c2); + gras_assert(i->hete.l1 == j->hete.l1); + gras_assert(i->hete.l2 == j->hete.l2); + + free(i); + free(j); + return no_error; +} + +/*** + *** chained list + ***/ +typedef struct s_chained_list chained_list_t; +struct s_chained_list { + int v; + chained_list_t *l; +}; +chained_list_t *cons(int v, chained_list_t *l); +void list_free(chained_list_t *l); +int list_eq(chained_list_t*i,chained_list_t*j); +chained_list_t * cons(int v, chained_list_t *l) { + chained_list_t *nl = malloc(sizeof (chained_list_t)); + + nl->v = v; + nl->l = l; + + return nl; +} +void list_free(chained_list_t*l) { + if (l) { + list_free(l->l); + free(l); + } +} +int list_eq(chained_list_t*i,chained_list_t*j) { + if (!i || !j) return i == j; + if (i->v != j->v) + return 0; + return list_eq(i->l, j->l); +} +gras_error_t test_chain_list(void) { + gras_error_t errcode; + gras_datadesc_type_t *my_type,*ref_my_type; + long int my_code; + long int ref_my_code; + chained_list_t *i, *j; + + INFO0("==== Test on chained list ===="); + /* create descriptor */ + TRY(gras_datadesc_declare_struct("chained_list_t",&my_code)); + TRY(gras_datadesc_by_code(my_code, &my_type)); + + TRY(gras_datadesc_declare_ref("chained_list_t*",my_type,&ref_my_code)); + + TRY(gras_datadesc_declare_struct_add_name(my_code,"v","int")); + TRY(gras_datadesc_declare_struct_add_code(my_code,"l",ref_my_code)); + + TRY(gras_datadesc_by_code(ref_my_code, &ref_my_type)); + + /* init a value, exchange it and check its validity*/ + i = cons( rand(), cons( rand() , cons( rand(), NULL))); + j = NULL; + + TRY(write_read(my_type, (void*)i, (void**)&j)); + gras_assert(list_eq(i,j)); + + list_free(i); + list_free(j); + return no_error; +} +/*** + *** graph + ***/ +gras_error_t test_graph(void) { + gras_error_t errcode; + gras_datadesc_type_t *my_type; + chained_list_t *i, *j; + + INFO0("==== Test on graph (cyclique chained list) ===="); + TRY(gras_datadesc_by_name("chained_list_t*", &my_type)); + + /* init a value, exchange it and check its validity*/ + i = cons( rand(), cons( rand() , cons( rand(), NULL))); + i->l->l->l = i->l; + j = NULL; + + TRY(write_read(my_type, (void*)&i, (void**)&j)); + INFO1("j=%p" ,j); + INFO1("j->l=%p" ,j->l); + INFO1("j->l->l=%p" ,j->l->l); + INFO1("j->l->l->l=%p",j->l->l->l); + gras_assert4(j->l->l->l == j->l, + "Received list is not cyclic. j->l=%p != j->l->l->l=%p\n" + "j=%p; &j=%p", + j->l,j->l->l->l, + j ,&j); + i->l->l->l = NULL; + j->l->l->l = NULL; + gras_assert(list_eq(i,j)); + + list_free(i); + list_free(j); + return no_error; +} + +/**** PBIO *****/ +typedef struct { /* structure presented in the IEEE article */ + int Cnstatv; + double Cstatev[12]; + int Cnprops; + double Cprops[110]; + int Cndi[4], Cnshr, Cnpt; + double Cdtime, Ctime[2]; + int Cntens; + double Cdfgrd0[3][373], Cdfgrd1[3][3], Cstress[106], Cddsdde[106][106]; +} KSdata1; + +int main(int argc,char *argv[]) { + gras_error_t errcode; + + gras_init_defaultlog(argc,argv, + "DataDesc.thresh=verbose" + " test.thresh=debug" + // " set.thresh=debug" + ); + + /* + TRYFAIL(test_int()); + TRYFAIL(test_float()); + TRYFAIL(test_array()); + TRYFAIL(test_intref()); + TRYFAIL(test_string()); + + TRYFAIL(test_homostruct()); + TRYFAIL(test_hetestruct()); + TRYFAIL(test_nestedstruct()); + */ + TRYFAIL(test_chain_list()); + TRYFAIL(test_graph()); + + return 0; +} diff --git a/testsuite/xbt/dynar_string.c b/testsuite/xbt/dynar_string.c index 7c755d95ee..48522cbb7b 100644 --- a/testsuite/xbt/dynar_string.c +++ b/testsuite/xbt/dynar_string.c @@ -23,7 +23,7 @@ void free_string(void *d){ int main(int argc,char *argv[]) { gras_dynar_t *d; gras_error_t errcode; - int cpt,i; + int cpt; char buf[1024]; char *s1,*s2; @@ -31,7 +31,7 @@ int main(int argc,char *argv[]) { fprintf(stderr,"==== Traverse the empty dynar\n"); TRYFAIL(gras_dynar_new(&d,sizeof(char *),&free_string)); - gras_dynar_foreach(d,cpt,i){ + gras_dynar_foreach(d,cpt,s1){ fprintf(stderr, "Damnit, there is something in the empty dynar\n"); abort(); @@ -74,13 +74,22 @@ int main(int argc,char *argv[]) { gras_dynar_free(d); - fprintf(stderr,"==== Unshift/pop %d strings\n",NB_ELEM); + fprintf(stderr,"==== Unshift, traverse and pop %d strings\n",NB_ELEM); TRYFAIL(gras_dynar_new(&d,sizeof(char**),&free_string)); for (cpt=0; cpt< NB_ELEM; cpt++) { sprintf(buf,"%d",cpt); s1=strdup(buf); TRYFAIL(gras_dynar_unshift(d,&s1)); } + gras_dynar_foreach(d,cpt,s1) { + sprintf(buf,"%d",NB_ELEM - cpt -1); + if (strcmp(buf,s1)) { + fprintf(stderr, + "The retrieved value is not the same than the injected one (%s!=%s)\n", + buf,s1); + abort(); + } + } for (cpt=0; cpt< NB_ELEM; cpt++) { sprintf(buf,"%d",cpt); gras_dynar_pop(d,&s2); -- 2.20.1